diff options
author | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2006-11-22 13:06:44 -0500 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2006-11-22 13:06:44 -0500 |
commit | 0bd2af46839ad6262d25714a6ec0365db9d6b98f (patch) | |
tree | dcced72d230d69fd0c5816ac6dd03ab84799a93e /drivers | |
parent | e138a5d2356729b8752e88520cc1525fae9794ac (diff) | |
parent | f26b90440cd74c78fe10c9bd5160809704a9627c (diff) |
Merge ../scsi-rc-fixes-2.6
Diffstat (limited to 'drivers')
619 files changed, 12792 insertions, 6356 deletions
diff --git a/drivers/Kconfig b/drivers/Kconfig index 263e86ddc1a4..f39463418904 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig | |||
@@ -14,6 +14,10 @@ source "drivers/pnp/Kconfig" | |||
14 | 14 | ||
15 | source "drivers/block/Kconfig" | 15 | source "drivers/block/Kconfig" |
16 | 16 | ||
17 | # misc before ide - BLK_DEV_SGIIOC4 depends on SGI_IOC4 | ||
18 | |||
19 | source "drivers/misc/Kconfig" | ||
20 | |||
17 | source "drivers/ide/Kconfig" | 21 | source "drivers/ide/Kconfig" |
18 | 22 | ||
19 | source "drivers/scsi/Kconfig" | 23 | source "drivers/scsi/Kconfig" |
@@ -52,8 +56,6 @@ source "drivers/w1/Kconfig" | |||
52 | 56 | ||
53 | source "drivers/hwmon/Kconfig" | 57 | source "drivers/hwmon/Kconfig" |
54 | 58 | ||
55 | source "drivers/misc/Kconfig" | ||
56 | |||
57 | source "drivers/mfd/Kconfig" | 59 | source "drivers/mfd/Kconfig" |
58 | 60 | ||
59 | source "drivers/media/Kconfig" | 61 | source "drivers/media/Kconfig" |
diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index 98099de59b45..6bcd9e8e7bcb 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c | |||
@@ -85,6 +85,8 @@ struct acpi_memory_device { | |||
85 | struct list_head res_list; | 85 | struct list_head res_list; |
86 | }; | 86 | }; |
87 | 87 | ||
88 | static int acpi_hotmem_initialized; | ||
89 | |||
88 | static acpi_status | 90 | static acpi_status |
89 | acpi_memory_get_resource(struct acpi_resource *resource, void *context) | 91 | acpi_memory_get_resource(struct acpi_resource *resource, void *context) |
90 | { | 92 | { |
@@ -414,7 +416,7 @@ static int acpi_memory_device_add(struct acpi_device *device) | |||
414 | /* Set the device state */ | 416 | /* Set the device state */ |
415 | mem_device->state = MEMORY_POWER_ON_STATE; | 417 | mem_device->state = MEMORY_POWER_ON_STATE; |
416 | 418 | ||
417 | printk(KERN_INFO "%s \n", acpi_device_name(device)); | 419 | printk(KERN_DEBUG "%s \n", acpi_device_name(device)); |
418 | 420 | ||
419 | return result; | 421 | return result; |
420 | } | 422 | } |
@@ -438,6 +440,15 @@ static int acpi_memory_device_start (struct acpi_device *device) | |||
438 | struct acpi_memory_device *mem_device; | 440 | struct acpi_memory_device *mem_device; |
439 | int result = 0; | 441 | int result = 0; |
440 | 442 | ||
443 | /* | ||
444 | * Early boot code has recognized memory area by EFI/E820. | ||
445 | * If DSDT shows these memory devices on boot, hotplug is not necessary | ||
446 | * for them. So, it just returns until completion of this driver's | ||
447 | * start up. | ||
448 | */ | ||
449 | if (!acpi_hotmem_initialized) | ||
450 | return 0; | ||
451 | |||
441 | mem_device = acpi_driver_data(device); | 452 | mem_device = acpi_driver_data(device); |
442 | 453 | ||
443 | if (!acpi_memory_check_device(mem_device)) { | 454 | if (!acpi_memory_check_device(mem_device)) { |
@@ -537,6 +548,7 @@ static int __init acpi_memory_device_init(void) | |||
537 | return -ENODEV; | 548 | return -ENODEV; |
538 | } | 549 | } |
539 | 550 | ||
551 | acpi_hotmem_initialized = 1; | ||
540 | return 0; | 552 | return 0; |
541 | } | 553 | } |
542 | 554 | ||
diff --git a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c index e9ee4c52a5f6..c7ac9297a204 100644 --- a/drivers/acpi/asus_acpi.c +++ b/drivers/acpi/asus_acpi.c | |||
@@ -138,6 +138,7 @@ struct asus_hotk { | |||
138 | S2x, //S200 (J1 reported), Victor MP-XP7210 | 138 | S2x, //S200 (J1 reported), Victor MP-XP7210 |
139 | W1N, //W1000N | 139 | W1N, //W1000N |
140 | W5A, //W5A | 140 | W5A, //W5A |
141 | W3V, //W3030V | ||
141 | xxN, //M2400N, M3700N, M5200N, M6800N, S1300N, S5200N | 142 | xxN, //M2400N, M3700N, M5200N, M6800N, S1300N, S5200N |
142 | //(Centrino) | 143 | //(Centrino) |
143 | END_MODEL | 144 | END_MODEL |
@@ -376,6 +377,17 @@ static struct model_data model_conf[END_MODEL] = { | |||
376 | .display_get = "\\ADVG"}, | 377 | .display_get = "\\ADVG"}, |
377 | 378 | ||
378 | { | 379 | { |
380 | .name = "W3V", | ||
381 | .mt_mled = "MLED", | ||
382 | .mt_wled = "WLED", | ||
383 | .mt_lcd_switch = xxN_PREFIX "_Q10", | ||
384 | .lcd_status = "\\BKLT", | ||
385 | .brightness_set = "SPLV", | ||
386 | .brightness_get = "GPLV", | ||
387 | .display_set = "SDSP", | ||
388 | .display_get = "\\INFB"}, | ||
389 | |||
390 | { | ||
379 | .name = "xxN", | 391 | .name = "xxN", |
380 | .mt_mled = "MLED", | 392 | .mt_mled = "MLED", |
381 | /* WLED present, but not controlled by ACPI */ | 393 | /* WLED present, but not controlled by ACPI */ |
@@ -555,11 +567,11 @@ static int | |||
555 | write_led(const char __user * buffer, unsigned long count, | 567 | write_led(const char __user * buffer, unsigned long count, |
556 | char *ledname, int ledmask, int invert) | 568 | char *ledname, int ledmask, int invert) |
557 | { | 569 | { |
558 | int value; | 570 | int rv, value; |
559 | int led_out = 0; | 571 | int led_out = 0; |
560 | 572 | ||
561 | count = parse_arg(buffer, count, &value); | 573 | rv = parse_arg(buffer, count, &value); |
562 | if (count > 0) | 574 | if (rv > 0) |
563 | led_out = value ? 1 : 0; | 575 | led_out = value ? 1 : 0; |
564 | 576 | ||
565 | hotk->status = | 577 | hotk->status = |
@@ -572,7 +584,7 @@ write_led(const char __user * buffer, unsigned long count, | |||
572 | printk(KERN_WARNING "Asus ACPI: LED (%s) write failed\n", | 584 | printk(KERN_WARNING "Asus ACPI: LED (%s) write failed\n", |
573 | ledname); | 585 | ledname); |
574 | 586 | ||
575 | return count; | 587 | return rv; |
576 | } | 588 | } |
577 | 589 | ||
578 | /* | 590 | /* |
@@ -607,20 +619,18 @@ static int | |||
607 | proc_write_ledd(struct file *file, const char __user * buffer, | 619 | proc_write_ledd(struct file *file, const char __user * buffer, |
608 | unsigned long count, void *data) | 620 | unsigned long count, void *data) |
609 | { | 621 | { |
610 | int value; | 622 | int rv, value; |
611 | 623 | ||
612 | count = parse_arg(buffer, count, &value); | 624 | rv = parse_arg(buffer, count, &value); |
613 | if (count > 0) { | 625 | if (rv > 0) { |
614 | if (!write_acpi_int | 626 | if (!write_acpi_int |
615 | (hotk->handle, hotk->methods->mt_ledd, value, NULL)) | 627 | (hotk->handle, hotk->methods->mt_ledd, value, NULL)) |
616 | printk(KERN_WARNING | 628 | printk(KERN_WARNING |
617 | "Asus ACPI: LED display write failed\n"); | 629 | "Asus ACPI: LED display write failed\n"); |
618 | else | 630 | else |
619 | hotk->ledd_status = (u32) value; | 631 | hotk->ledd_status = (u32) value; |
620 | } else if (count < 0) | 632 | } |
621 | printk(KERN_WARNING "Asus ACPI: Error reading user input\n"); | 633 | return rv; |
622 | |||
623 | return count; | ||
624 | } | 634 | } |
625 | 635 | ||
626 | /* | 636 | /* |
@@ -761,12 +771,12 @@ static int | |||
761 | proc_write_lcd(struct file *file, const char __user * buffer, | 771 | proc_write_lcd(struct file *file, const char __user * buffer, |
762 | unsigned long count, void *data) | 772 | unsigned long count, void *data) |
763 | { | 773 | { |
764 | int value; | 774 | int rv, value; |
765 | 775 | ||
766 | count = parse_arg(buffer, count, &value); | 776 | rv = parse_arg(buffer, count, &value); |
767 | if (count > 0) | 777 | if (rv > 0) |
768 | set_lcd_state(value); | 778 | set_lcd_state(value); |
769 | return count; | 779 | return rv; |
770 | } | 780 | } |
771 | 781 | ||
772 | static int read_brightness(void) | 782 | static int read_brightness(void) |
@@ -830,18 +840,15 @@ static int | |||
830 | proc_write_brn(struct file *file, const char __user * buffer, | 840 | proc_write_brn(struct file *file, const char __user * buffer, |
831 | unsigned long count, void *data) | 841 | unsigned long count, void *data) |
832 | { | 842 | { |
833 | int value; | 843 | int rv, value; |
834 | 844 | ||
835 | count = parse_arg(buffer, count, &value); | 845 | rv = parse_arg(buffer, count, &value); |
836 | if (count > 0) { | 846 | if (rv > 0) { |
837 | value = (0 < value) ? ((15 < value) ? 15 : value) : 0; | 847 | value = (0 < value) ? ((15 < value) ? 15 : value) : 0; |
838 | /* 0 <= value <= 15 */ | 848 | /* 0 <= value <= 15 */ |
839 | set_brightness(value); | 849 | set_brightness(value); |
840 | } else if (count < 0) { | ||
841 | printk(KERN_WARNING "Asus ACPI: Error reading user input\n"); | ||
842 | } | 850 | } |
843 | 851 | return rv; | |
844 | return count; | ||
845 | } | 852 | } |
846 | 853 | ||
847 | static void set_display(int value) | 854 | static void set_display(int value) |
@@ -880,15 +887,12 @@ static int | |||
880 | proc_write_disp(struct file *file, const char __user * buffer, | 887 | proc_write_disp(struct file *file, const char __user * buffer, |
881 | unsigned long count, void *data) | 888 | unsigned long count, void *data) |
882 | { | 889 | { |
883 | int value; | 890 | int rv, value; |
884 | 891 | ||
885 | count = parse_arg(buffer, count, &value); | 892 | rv = parse_arg(buffer, count, &value); |
886 | if (count > 0) | 893 | if (rv > 0) |
887 | set_display(value); | 894 | set_display(value); |
888 | else if (count < 0) | 895 | return rv; |
889 | printk(KERN_WARNING "Asus ACPI: Error reading user input\n"); | ||
890 | |||
891 | return count; | ||
892 | } | 896 | } |
893 | 897 | ||
894 | typedef int (proc_readfunc) (char *page, char **start, off_t off, int count, | 898 | typedef int (proc_readfunc) (char *page, char **start, off_t off, int count, |
@@ -1097,6 +1101,8 @@ static int asus_model_match(char *model) | |||
1097 | return A4G; | 1101 | return A4G; |
1098 | else if (strncmp(model, "W1N", 3) == 0) | 1102 | else if (strncmp(model, "W1N", 3) == 0) |
1099 | return W1N; | 1103 | return W1N; |
1104 | else if (strncmp(model, "W3V", 3) == 0) | ||
1105 | return W3V; | ||
1100 | else if (strncmp(model, "W5A", 3) == 0) | 1106 | else if (strncmp(model, "W5A", 3) == 0) |
1101 | return W5A; | 1107 | return W5A; |
1102 | else | 1108 | else |
@@ -1200,9 +1206,10 @@ static int asus_hotk_get_info(void) | |||
1200 | hotk->methods->mt_wled = NULL; | 1206 | hotk->methods->mt_wled = NULL; |
1201 | /* L5D's WLED is not controlled by ACPI */ | 1207 | /* L5D's WLED is not controlled by ACPI */ |
1202 | else if (strncmp(string, "M2N", 3) == 0 || | 1208 | else if (strncmp(string, "M2N", 3) == 0 || |
1209 | strncmp(string, "W3V", 3) == 0 || | ||
1203 | strncmp(string, "S1N", 3) == 0) | 1210 | strncmp(string, "S1N", 3) == 0) |
1204 | hotk->methods->mt_wled = "WLED"; | 1211 | hotk->methods->mt_wled = "WLED"; |
1205 | /* M2N and S1N have a usable WLED */ | 1212 | /* M2N, S1N and W3V have a usable WLED */ |
1206 | else if (asus_info) { | 1213 | else if (asus_info) { |
1207 | if (strncmp(asus_info->oem_table_id, "L1", 2) == 0) | 1214 | if (strncmp(asus_info->oem_table_id, "L1", 2) == 0) |
1208 | hotk->methods->mled_status = NULL; | 1215 | hotk->methods->mled_status = NULL; |
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 9810e2a55d0a..026e40755cdd 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
@@ -64,6 +64,7 @@ extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir); | |||
64 | 64 | ||
65 | static int acpi_battery_add(struct acpi_device *device); | 65 | static int acpi_battery_add(struct acpi_device *device); |
66 | static int acpi_battery_remove(struct acpi_device *device, int type); | 66 | static int acpi_battery_remove(struct acpi_device *device, int type); |
67 | static int acpi_battery_resume(struct acpi_device *device, int status); | ||
67 | 68 | ||
68 | static struct acpi_driver acpi_battery_driver = { | 69 | static struct acpi_driver acpi_battery_driver = { |
69 | .name = ACPI_BATTERY_DRIVER_NAME, | 70 | .name = ACPI_BATTERY_DRIVER_NAME, |
@@ -71,6 +72,7 @@ static struct acpi_driver acpi_battery_driver = { | |||
71 | .ids = ACPI_BATTERY_HID, | 72 | .ids = ACPI_BATTERY_HID, |
72 | .ops = { | 73 | .ops = { |
73 | .add = acpi_battery_add, | 74 | .add = acpi_battery_add, |
75 | .resume = acpi_battery_resume, | ||
74 | .remove = acpi_battery_remove, | 76 | .remove = acpi_battery_remove, |
75 | }, | 77 | }, |
76 | }; | 78 | }; |
@@ -753,6 +755,18 @@ static int acpi_battery_remove(struct acpi_device *device, int type) | |||
753 | return 0; | 755 | return 0; |
754 | } | 756 | } |
755 | 757 | ||
758 | /* this is needed to learn about changes made in suspended state */ | ||
759 | static int acpi_battery_resume(struct acpi_device *device, int state) | ||
760 | { | ||
761 | struct acpi_battery *battery; | ||
762 | |||
763 | if (!device) | ||
764 | return -EINVAL; | ||
765 | |||
766 | battery = device->driver_data; | ||
767 | return acpi_battery_check(battery); | ||
768 | } | ||
769 | |||
756 | static int __init acpi_battery_init(void) | 770 | static int __init acpi_battery_init(void) |
757 | { | 771 | { |
758 | int result; | 772 | int result; |
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index e5d796362854..e6d4b084dca2 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -45,206 +45,143 @@ ACPI_MODULE_NAME("acpi_ec") | |||
45 | #define ACPI_EC_DRIVER_NAME "ACPI Embedded Controller Driver" | 45 | #define ACPI_EC_DRIVER_NAME "ACPI Embedded Controller Driver" |
46 | #define ACPI_EC_DEVICE_NAME "Embedded Controller" | 46 | #define ACPI_EC_DEVICE_NAME "Embedded Controller" |
47 | #define ACPI_EC_FILE_INFO "info" | 47 | #define ACPI_EC_FILE_INFO "info" |
48 | |||
49 | /* EC status register */ | ||
48 | #define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */ | 50 | #define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */ |
49 | #define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */ | 51 | #define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */ |
50 | #define ACPI_EC_FLAG_BURST 0x10 /* burst mode */ | 52 | #define ACPI_EC_FLAG_BURST 0x10 /* burst mode */ |
51 | #define ACPI_EC_FLAG_SCI 0x20 /* EC-SCI occurred */ | 53 | #define ACPI_EC_FLAG_SCI 0x20 /* EC-SCI occurred */ |
52 | #define ACPI_EC_EVENT_OBF 0x01 /* Output buffer full */ | 54 | |
53 | #define ACPI_EC_EVENT_IBE 0x02 /* Input buffer empty */ | 55 | /* EC commands */ |
54 | #define ACPI_EC_DELAY 50 /* Wait 50ms max. during EC ops */ | ||
55 | #define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ | ||
56 | #define ACPI_EC_UDELAY 100 /* Poll @ 100us increments */ | ||
57 | #define ACPI_EC_UDELAY_COUNT 1000 /* Wait 10ms max. during EC ops */ | ||
58 | #define ACPI_EC_COMMAND_READ 0x80 | 56 | #define ACPI_EC_COMMAND_READ 0x80 |
59 | #define ACPI_EC_COMMAND_WRITE 0x81 | 57 | #define ACPI_EC_COMMAND_WRITE 0x81 |
60 | #define ACPI_EC_BURST_ENABLE 0x82 | 58 | #define ACPI_EC_BURST_ENABLE 0x82 |
61 | #define ACPI_EC_BURST_DISABLE 0x83 | 59 | #define ACPI_EC_BURST_DISABLE 0x83 |
62 | #define ACPI_EC_COMMAND_QUERY 0x84 | 60 | #define ACPI_EC_COMMAND_QUERY 0x84 |
63 | #define EC_POLL 0xFF | 61 | |
64 | #define EC_INTR 0x00 | 62 | /* EC events */ |
63 | enum { | ||
64 | ACPI_EC_EVENT_OBF_1 = 1, /* Output buffer full */ | ||
65 | ACPI_EC_EVENT_IBF_0, /* Input buffer empty */ | ||
66 | }; | ||
67 | |||
68 | #define ACPI_EC_DELAY 50 /* Wait 50ms max. during EC ops */ | ||
69 | #define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ | ||
70 | #define ACPI_EC_UDELAY 100 /* Poll @ 100us increments */ | ||
71 | #define ACPI_EC_UDELAY_COUNT 1000 /* Wait 10ms max. during EC ops */ | ||
72 | |||
73 | enum { | ||
74 | EC_INTR = 1, /* Output buffer full */ | ||
75 | EC_POLL, /* Input buffer empty */ | ||
76 | }; | ||
77 | |||
65 | static int acpi_ec_remove(struct acpi_device *device, int type); | 78 | static int acpi_ec_remove(struct acpi_device *device, int type); |
66 | static int acpi_ec_start(struct acpi_device *device); | 79 | static int acpi_ec_start(struct acpi_device *device); |
67 | static int acpi_ec_stop(struct acpi_device *device, int type); | 80 | static int acpi_ec_stop(struct acpi_device *device, int type); |
68 | static int acpi_ec_intr_add(struct acpi_device *device); | 81 | static int acpi_ec_add(struct acpi_device *device); |
69 | static int acpi_ec_poll_add(struct acpi_device *device); | ||
70 | 82 | ||
71 | static struct acpi_driver acpi_ec_driver = { | 83 | static struct acpi_driver acpi_ec_driver = { |
72 | .name = ACPI_EC_DRIVER_NAME, | 84 | .name = ACPI_EC_DRIVER_NAME, |
73 | .class = ACPI_EC_CLASS, | 85 | .class = ACPI_EC_CLASS, |
74 | .ids = ACPI_EC_HID, | 86 | .ids = ACPI_EC_HID, |
75 | .ops = { | 87 | .ops = { |
76 | .add = acpi_ec_intr_add, | 88 | .add = acpi_ec_add, |
77 | .remove = acpi_ec_remove, | 89 | .remove = acpi_ec_remove, |
78 | .start = acpi_ec_start, | 90 | .start = acpi_ec_start, |
79 | .stop = acpi_ec_stop, | 91 | .stop = acpi_ec_stop, |
80 | }, | 92 | }, |
81 | }; | 93 | }; |
82 | union acpi_ec { | ||
83 | struct { | ||
84 | u32 mode; | ||
85 | acpi_handle handle; | ||
86 | unsigned long uid; | ||
87 | unsigned long gpe_bit; | ||
88 | struct acpi_generic_address status_addr; | ||
89 | struct acpi_generic_address command_addr; | ||
90 | struct acpi_generic_address data_addr; | ||
91 | unsigned long global_lock; | ||
92 | } common; | ||
93 | |||
94 | struct { | ||
95 | u32 mode; | ||
96 | acpi_handle handle; | ||
97 | unsigned long uid; | ||
98 | unsigned long gpe_bit; | ||
99 | struct acpi_generic_address status_addr; | ||
100 | struct acpi_generic_address command_addr; | ||
101 | struct acpi_generic_address data_addr; | ||
102 | unsigned long global_lock; | ||
103 | unsigned int expect_event; | ||
104 | atomic_t leaving_burst; /* 0 : No, 1 : Yes, 2: abort */ | ||
105 | atomic_t pending_gpe; | ||
106 | struct semaphore sem; | ||
107 | wait_queue_head_t wait; | ||
108 | } intr; | ||
109 | |||
110 | struct { | ||
111 | u32 mode; | ||
112 | acpi_handle handle; | ||
113 | unsigned long uid; | ||
114 | unsigned long gpe_bit; | ||
115 | struct acpi_generic_address status_addr; | ||
116 | struct acpi_generic_address command_addr; | ||
117 | struct acpi_generic_address data_addr; | ||
118 | unsigned long global_lock; | ||
119 | struct semaphore sem; | ||
120 | } poll; | ||
121 | }; | ||
122 | 94 | ||
123 | static int acpi_ec_poll_wait(union acpi_ec *ec, u8 event); | ||
124 | static int acpi_ec_intr_wait(union acpi_ec *ec, unsigned int event); | ||
125 | static int acpi_ec_poll_read(union acpi_ec *ec, u8 address, u32 * data); | ||
126 | static int acpi_ec_intr_read(union acpi_ec *ec, u8 address, u32 * data); | ||
127 | static int acpi_ec_poll_write(union acpi_ec *ec, u8 address, u8 data); | ||
128 | static int acpi_ec_intr_write(union acpi_ec *ec, u8 address, u8 data); | ||
129 | static int acpi_ec_poll_query(union acpi_ec *ec, u32 * data); | ||
130 | static int acpi_ec_intr_query(union acpi_ec *ec, u32 * data); | ||
131 | static void acpi_ec_gpe_poll_query(void *ec_cxt); | ||
132 | static void acpi_ec_gpe_intr_query(void *ec_cxt); | ||
133 | static u32 acpi_ec_gpe_poll_handler(void *data); | ||
134 | static u32 acpi_ec_gpe_intr_handler(void *data); | ||
135 | static acpi_status __init | ||
136 | acpi_fake_ecdt_poll_callback(acpi_handle handle, | ||
137 | u32 Level, void *context, void **retval); | ||
138 | |||
139 | static acpi_status __init | ||
140 | acpi_fake_ecdt_intr_callback(acpi_handle handle, | ||
141 | u32 Level, void *context, void **retval); | ||
142 | |||
143 | static int __init acpi_ec_poll_get_real_ecdt(void); | ||
144 | static int __init acpi_ec_intr_get_real_ecdt(void); | ||
145 | /* If we find an EC via the ECDT, we need to keep a ptr to its context */ | 95 | /* If we find an EC via the ECDT, we need to keep a ptr to its context */ |
146 | static union acpi_ec *ec_ecdt; | 96 | struct acpi_ec { |
97 | acpi_handle handle; | ||
98 | unsigned long uid; | ||
99 | unsigned long gpe_bit; | ||
100 | unsigned long command_addr; | ||
101 | unsigned long data_addr; | ||
102 | unsigned long global_lock; | ||
103 | struct semaphore sem; | ||
104 | unsigned int expect_event; | ||
105 | atomic_t leaving_burst; /* 0 : No, 1 : Yes, 2: abort */ | ||
106 | wait_queue_head_t wait; | ||
107 | } *ec_ecdt; | ||
147 | 108 | ||
148 | /* External interfaces use first EC only, so remember */ | 109 | /* External interfaces use first EC only, so remember */ |
149 | static struct acpi_device *first_ec; | 110 | static struct acpi_device *first_ec; |
150 | static int acpi_ec_poll_mode = EC_INTR; | 111 | static int acpi_ec_mode = EC_INTR; |
151 | 112 | ||
152 | /* -------------------------------------------------------------------------- | 113 | /* -------------------------------------------------------------------------- |
153 | Transaction Management | 114 | Transaction Management |
154 | -------------------------------------------------------------------------- */ | 115 | -------------------------------------------------------------------------- */ |
155 | 116 | ||
156 | static u32 acpi_ec_read_status(union acpi_ec *ec) | 117 | static inline u8 acpi_ec_read_status(struct acpi_ec *ec) |
157 | { | 118 | { |
158 | u32 status = 0; | 119 | return inb(ec->command_addr); |
159 | |||
160 | acpi_hw_low_level_read(8, &status, &ec->common.status_addr); | ||
161 | return status; | ||
162 | } | 120 | } |
163 | 121 | ||
164 | static int acpi_ec_wait(union acpi_ec *ec, u8 event) | 122 | static inline u8 acpi_ec_read_data(struct acpi_ec *ec) |
165 | { | 123 | { |
166 | if (acpi_ec_poll_mode) | 124 | return inb(ec->data_addr); |
167 | return acpi_ec_poll_wait(ec, event); | ||
168 | else | ||
169 | return acpi_ec_intr_wait(ec, event); | ||
170 | } | 125 | } |
171 | 126 | ||
172 | static int acpi_ec_poll_wait(union acpi_ec *ec, u8 event) | 127 | static inline void acpi_ec_write_cmd(struct acpi_ec *ec, u8 command) |
173 | { | 128 | { |
174 | u32 acpi_ec_status = 0; | 129 | outb(command, ec->command_addr); |
175 | u32 i = ACPI_EC_UDELAY_COUNT; | 130 | } |
176 | 131 | ||
177 | if (!ec) | 132 | static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data) |
178 | return -EINVAL; | 133 | { |
134 | outb(data, ec->data_addr); | ||
135 | } | ||
179 | 136 | ||
180 | /* Poll the EC status register waiting for the event to occur. */ | 137 | static int acpi_ec_check_status(u8 status, u8 event) |
138 | { | ||
181 | switch (event) { | 139 | switch (event) { |
182 | case ACPI_EC_EVENT_OBF: | 140 | case ACPI_EC_EVENT_OBF_1: |
183 | do { | 141 | if (status & ACPI_EC_FLAG_OBF) |
184 | acpi_hw_low_level_read(8, &acpi_ec_status, | 142 | return 1; |
185 | &ec->common.status_addr); | ||
186 | if (acpi_ec_status & ACPI_EC_FLAG_OBF) | ||
187 | return 0; | ||
188 | udelay(ACPI_EC_UDELAY); | ||
189 | } while (--i > 0); | ||
190 | break; | 143 | break; |
191 | case ACPI_EC_EVENT_IBE: | 144 | case ACPI_EC_EVENT_IBF_0: |
192 | do { | 145 | if (!(status & ACPI_EC_FLAG_IBF)) |
193 | acpi_hw_low_level_read(8, &acpi_ec_status, | 146 | return 1; |
194 | &ec->common.status_addr); | ||
195 | if (!(acpi_ec_status & ACPI_EC_FLAG_IBF)) | ||
196 | return 0; | ||
197 | udelay(ACPI_EC_UDELAY); | ||
198 | } while (--i > 0); | ||
199 | break; | 147 | break; |
200 | default: | 148 | default: |
201 | return -EINVAL; | 149 | break; |
202 | } | 150 | } |
203 | 151 | ||
204 | return -ETIME; | 152 | return 0; |
205 | } | 153 | } |
206 | static int acpi_ec_intr_wait(union acpi_ec *ec, unsigned int event) | ||
207 | { | ||
208 | int result = 0; | ||
209 | |||
210 | 154 | ||
211 | ec->intr.expect_event = event; | 155 | static int acpi_ec_wait(struct acpi_ec *ec, u8 event) |
212 | smp_mb(); | 156 | { |
157 | int i = (acpi_ec_mode == EC_POLL) ? ACPI_EC_UDELAY_COUNT : 0; | ||
158 | long time_left; | ||
213 | 159 | ||
214 | switch (event) { | 160 | ec->expect_event = event; |
215 | case ACPI_EC_EVENT_IBE: | 161 | if (acpi_ec_check_status(acpi_ec_read_status(ec), event)) { |
216 | if (~acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) { | 162 | ec->expect_event = 0; |
217 | ec->intr.expect_event = 0; | 163 | return 0; |
218 | return 0; | ||
219 | } | ||
220 | break; | ||
221 | default: | ||
222 | break; | ||
223 | } | 164 | } |
224 | 165 | ||
225 | result = wait_event_timeout(ec->intr.wait, | 166 | do { |
226 | !ec->intr.expect_event, | 167 | if (acpi_ec_mode == EC_POLL) { |
168 | udelay(ACPI_EC_UDELAY); | ||
169 | } else { | ||
170 | time_left = wait_event_timeout(ec->wait, | ||
171 | !ec->expect_event, | ||
227 | msecs_to_jiffies(ACPI_EC_DELAY)); | 172 | msecs_to_jiffies(ACPI_EC_DELAY)); |
228 | 173 | if (time_left > 0) { | |
229 | ec->intr.expect_event = 0; | 174 | ec->expect_event = 0; |
230 | smp_mb(); | 175 | return 0; |
231 | 176 | } | |
232 | /* | 177 | } |
233 | * Verify that the event in question has actually happened by | 178 | if (acpi_ec_check_status(acpi_ec_read_status(ec), event)) { |
234 | * querying EC status. Do the check even if operation timed-out | 179 | ec->expect_event = 0; |
235 | * to make sure that we did not miss interrupt. | ||
236 | */ | ||
237 | switch (event) { | ||
238 | case ACPI_EC_EVENT_OBF: | ||
239 | if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_OBF) | ||
240 | return 0; | 180 | return 0; |
241 | break; | 181 | } |
182 | } while (--i > 0); | ||
242 | 183 | ||
243 | case ACPI_EC_EVENT_IBE: | 184 | ec->expect_event = 0; |
244 | if (~acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) | ||
245 | return 0; | ||
246 | break; | ||
247 | } | ||
248 | 185 | ||
249 | return -ETIME; | 186 | return -ETIME; |
250 | } | 187 | } |
@@ -254,272 +191,150 @@ static int acpi_ec_intr_wait(union acpi_ec *ec, unsigned int event) | |||
254 | * Note: samsung nv5000 doesn't work with ec burst mode. | 191 | * Note: samsung nv5000 doesn't work with ec burst mode. |
255 | * http://bugzilla.kernel.org/show_bug.cgi?id=4980 | 192 | * http://bugzilla.kernel.org/show_bug.cgi?id=4980 |
256 | */ | 193 | */ |
257 | int acpi_ec_enter_burst_mode(union acpi_ec *ec) | 194 | int acpi_ec_enter_burst_mode(struct acpi_ec *ec) |
258 | { | 195 | { |
259 | u32 tmp = 0; | 196 | u8 tmp = 0; |
260 | int status = 0; | 197 | u8 status = 0; |
261 | 198 | ||
262 | 199 | ||
263 | status = acpi_ec_read_status(ec); | 200 | status = acpi_ec_read_status(ec); |
264 | if (status != -EINVAL && !(status & ACPI_EC_FLAG_BURST)) { | 201 | if (status != -EINVAL && !(status & ACPI_EC_FLAG_BURST)) { |
265 | status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); | 202 | status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); |
266 | if (status) | 203 | if (status) |
267 | goto end; | 204 | goto end; |
268 | acpi_hw_low_level_write(8, ACPI_EC_BURST_ENABLE, | 205 | acpi_ec_write_cmd(ec, ACPI_EC_BURST_ENABLE); |
269 | &ec->common.command_addr); | 206 | status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1); |
270 | status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); | 207 | tmp = acpi_ec_read_data(ec); |
271 | acpi_hw_low_level_read(8, &tmp, &ec->common.data_addr); | ||
272 | if (tmp != 0x90) { /* Burst ACK byte */ | 208 | if (tmp != 0x90) { /* Burst ACK byte */ |
273 | return -EINVAL; | 209 | return -EINVAL; |
274 | } | 210 | } |
275 | } | 211 | } |
276 | 212 | ||
277 | atomic_set(&ec->intr.leaving_burst, 0); | 213 | atomic_set(&ec->leaving_burst, 0); |
278 | return 0; | 214 | return 0; |
279 | end: | 215 | end: |
280 | ACPI_EXCEPTION ((AE_INFO, status, "EC wait, burst mode"); | 216 | ACPI_EXCEPTION((AE_INFO, status, "EC wait, burst mode")); |
281 | return -1; | 217 | return -1; |
282 | } | 218 | } |
283 | 219 | ||
284 | int acpi_ec_leave_burst_mode(union acpi_ec *ec) | 220 | int acpi_ec_leave_burst_mode(struct acpi_ec *ec) |
285 | { | 221 | { |
286 | int status = 0; | 222 | u8 status = 0; |
287 | 223 | ||
288 | 224 | ||
289 | status = acpi_ec_read_status(ec); | 225 | status = acpi_ec_read_status(ec); |
290 | if (status != -EINVAL && (status & ACPI_EC_FLAG_BURST)){ | 226 | if (status != -EINVAL && (status & ACPI_EC_FLAG_BURST)){ |
291 | status = acpi_ec_wait(ec, ACPI_EC_FLAG_IBF); | 227 | status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); |
292 | if(status) | 228 | if(status) |
293 | goto end; | 229 | goto end; |
294 | acpi_hw_low_level_write(8, ACPI_EC_BURST_DISABLE, &ec->common.command_addr); | 230 | acpi_ec_write_cmd(ec, ACPI_EC_BURST_DISABLE); |
295 | acpi_ec_wait(ec, ACPI_EC_FLAG_IBF); | 231 | acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); |
296 | } | 232 | } |
297 | atomic_set(&ec->intr.leaving_burst, 1); | 233 | atomic_set(&ec->leaving_burst, 1); |
298 | return 0; | 234 | return 0; |
299 | end: | 235 | end: |
300 | ACPI_EXCEPTION((AE_INFO, status, "EC leave burst mode"); | 236 | ACPI_EXCEPTION((AE_INFO, status, "EC leave burst mode")); |
301 | return -1; | 237 | return -1; |
302 | } | 238 | } |
303 | #endif /* ACPI_FUTURE_USAGE */ | 239 | #endif /* ACPI_FUTURE_USAGE */ |
304 | 240 | ||
305 | static int acpi_ec_read(union acpi_ec *ec, u8 address, u32 * data) | 241 | static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command, |
306 | { | 242 | const u8 *wdata, unsigned wdata_len, |
307 | if (acpi_ec_poll_mode) | 243 | u8 *rdata, unsigned rdata_len) |
308 | return acpi_ec_poll_read(ec, address, data); | ||
309 | else | ||
310 | return acpi_ec_intr_read(ec, address, data); | ||
311 | } | ||
312 | static int acpi_ec_write(union acpi_ec *ec, u8 address, u8 data) | ||
313 | { | ||
314 | if (acpi_ec_poll_mode) | ||
315 | return acpi_ec_poll_write(ec, address, data); | ||
316 | else | ||
317 | return acpi_ec_intr_write(ec, address, data); | ||
318 | } | ||
319 | static int acpi_ec_poll_read(union acpi_ec *ec, u8 address, u32 * data) | ||
320 | { | 244 | { |
321 | acpi_status status = AE_OK; | 245 | int result; |
322 | int result = 0; | ||
323 | u32 glk = 0; | ||
324 | 246 | ||
247 | acpi_ec_write_cmd(ec, command); | ||
325 | 248 | ||
326 | if (!ec || !data) | 249 | for (; wdata_len > 0; wdata_len --) { |
327 | return -EINVAL; | 250 | result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); |
328 | 251 | if (result) | |
329 | *data = 0; | 252 | return result; |
330 | 253 | acpi_ec_write_data(ec, *(wdata++)); | |
331 | if (ec->common.global_lock) { | ||
332 | status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); | ||
333 | if (ACPI_FAILURE(status)) | ||
334 | return -ENODEV; | ||
335 | } | 254 | } |
336 | 255 | ||
337 | if (down_interruptible(&ec->poll.sem)) { | 256 | if (command == ACPI_EC_COMMAND_WRITE) { |
338 | result = -ERESTARTSYS; | 257 | result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); |
339 | goto end_nosem; | 258 | if (result) |
259 | return result; | ||
340 | } | 260 | } |
341 | |||
342 | acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, | ||
343 | &ec->common.command_addr); | ||
344 | result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); | ||
345 | if (result) | ||
346 | goto end; | ||
347 | |||
348 | acpi_hw_low_level_write(8, address, &ec->common.data_addr); | ||
349 | result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); | ||
350 | if (result) | ||
351 | goto end; | ||
352 | |||
353 | acpi_hw_low_level_read(8, data, &ec->common.data_addr); | ||
354 | |||
355 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n", | ||
356 | *data, address)); | ||
357 | |||
358 | end: | ||
359 | up(&ec->poll.sem); | ||
360 | end_nosem: | ||
361 | if (ec->common.global_lock) | ||
362 | acpi_release_global_lock(glk); | ||
363 | |||
364 | return result; | ||
365 | } | ||
366 | |||
367 | static int acpi_ec_poll_write(union acpi_ec *ec, u8 address, u8 data) | ||
368 | { | ||
369 | int result = 0; | ||
370 | acpi_status status = AE_OK; | ||
371 | u32 glk = 0; | ||
372 | 261 | ||
262 | for (; rdata_len > 0; rdata_len --) { | ||
263 | result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1); | ||
264 | if (result) | ||
265 | return result; | ||
373 | 266 | ||
374 | if (!ec) | 267 | *(rdata++) = acpi_ec_read_data(ec); |
375 | return -EINVAL; | ||
376 | |||
377 | if (ec->common.global_lock) { | ||
378 | status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); | ||
379 | if (ACPI_FAILURE(status)) | ||
380 | return -ENODEV; | ||
381 | } | ||
382 | |||
383 | if (down_interruptible(&ec->poll.sem)) { | ||
384 | result = -ERESTARTSYS; | ||
385 | goto end_nosem; | ||
386 | } | 268 | } |
387 | |||
388 | acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, | ||
389 | &ec->common.command_addr); | ||
390 | result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); | ||
391 | if (result) | ||
392 | goto end; | ||
393 | |||
394 | acpi_hw_low_level_write(8, address, &ec->common.data_addr); | ||
395 | result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); | ||
396 | if (result) | ||
397 | goto end; | ||
398 | |||
399 | acpi_hw_low_level_write(8, data, &ec->common.data_addr); | ||
400 | result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); | ||
401 | if (result) | ||
402 | goto end; | ||
403 | 269 | ||
404 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Wrote [%02x] to address [%02x]\n", | 270 | return 0; |
405 | data, address)); | ||
406 | |||
407 | end: | ||
408 | up(&ec->poll.sem); | ||
409 | end_nosem: | ||
410 | if (ec->common.global_lock) | ||
411 | acpi_release_global_lock(glk); | ||
412 | |||
413 | return result; | ||
414 | } | 271 | } |
415 | 272 | ||
416 | static int acpi_ec_intr_read(union acpi_ec *ec, u8 address, u32 * data) | 273 | static int acpi_ec_transaction(struct acpi_ec *ec, u8 command, |
274 | const u8 *wdata, unsigned wdata_len, | ||
275 | u8 *rdata, unsigned rdata_len) | ||
417 | { | 276 | { |
418 | int status = 0; | 277 | int status; |
419 | u32 glk; | 278 | u32 glk; |
420 | 279 | ||
421 | 280 | if (!ec || (wdata_len && !wdata) || (rdata_len && !rdata)) | |
422 | if (!ec || !data) | ||
423 | return -EINVAL; | 281 | return -EINVAL; |
424 | 282 | ||
425 | *data = 0; | 283 | if (rdata) |
284 | memset(rdata, 0, rdata_len); | ||
426 | 285 | ||
427 | if (ec->common.global_lock) { | 286 | if (ec->global_lock) { |
428 | status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); | 287 | status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); |
429 | if (ACPI_FAILURE(status)) | 288 | if (ACPI_FAILURE(status)) |
430 | return -ENODEV; | 289 | return -ENODEV; |
431 | } | 290 | } |
291 | down(&ec->sem); | ||
432 | 292 | ||
433 | WARN_ON(in_interrupt()); | 293 | status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); |
434 | down(&ec->intr.sem); | ||
435 | |||
436 | status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); | ||
437 | if (status) { | 294 | if (status) { |
438 | printk(KERN_DEBUG PREFIX "read EC, IB not empty\n"); | 295 | printk(KERN_DEBUG PREFIX "read EC, IB not empty\n"); |
439 | goto end; | 296 | goto end; |
440 | } | 297 | } |
441 | acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, | ||
442 | &ec->common.command_addr); | ||
443 | status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); | ||
444 | if (status) { | ||
445 | printk(KERN_DEBUG PREFIX "read EC, IB not empty\n"); | ||
446 | } | ||
447 | 298 | ||
448 | acpi_hw_low_level_write(8, address, &ec->common.data_addr); | 299 | status = acpi_ec_transaction_unlocked(ec, command, |
449 | status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); | 300 | wdata, wdata_len, |
450 | if (status) { | 301 | rdata, rdata_len); |
451 | printk(KERN_DEBUG PREFIX "read EC, OB not full\n"); | ||
452 | goto end; | ||
453 | } | ||
454 | acpi_hw_low_level_read(8, data, &ec->common.data_addr); | ||
455 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n", | ||
456 | *data, address)); | ||
457 | 302 | ||
458 | end: | 303 | end: |
459 | up(&ec->intr.sem); | 304 | up(&ec->sem); |
460 | 305 | ||
461 | if (ec->common.global_lock) | 306 | if (ec->global_lock) |
462 | acpi_release_global_lock(glk); | 307 | acpi_release_global_lock(glk); |
463 | 308 | ||
464 | return status; | 309 | return status; |
465 | } | 310 | } |
466 | 311 | ||
467 | static int acpi_ec_intr_write(union acpi_ec *ec, u8 address, u8 data) | 312 | static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 *data) |
468 | { | 313 | { |
469 | int status = 0; | 314 | int result; |
470 | u32 glk; | 315 | u8 d; |
471 | |||
472 | |||
473 | if (!ec) | ||
474 | return -EINVAL; | ||
475 | |||
476 | if (ec->common.global_lock) { | ||
477 | status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); | ||
478 | if (ACPI_FAILURE(status)) | ||
479 | return -ENODEV; | ||
480 | } | ||
481 | |||
482 | WARN_ON(in_interrupt()); | ||
483 | down(&ec->intr.sem); | ||
484 | |||
485 | status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); | ||
486 | if (status) { | ||
487 | printk(KERN_DEBUG PREFIX "write EC, IB not empty\n"); | ||
488 | } | ||
489 | acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, | ||
490 | &ec->common.command_addr); | ||
491 | status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); | ||
492 | if (status) { | ||
493 | printk(KERN_DEBUG PREFIX "write EC, IB not empty\n"); | ||
494 | } | ||
495 | |||
496 | acpi_hw_low_level_write(8, address, &ec->common.data_addr); | ||
497 | status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); | ||
498 | if (status) { | ||
499 | printk(KERN_DEBUG PREFIX "write EC, IB not empty\n"); | ||
500 | } | ||
501 | |||
502 | acpi_hw_low_level_write(8, data, &ec->common.data_addr); | ||
503 | 316 | ||
504 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Wrote [%02x] to address [%02x]\n", | 317 | result = acpi_ec_transaction(ec, ACPI_EC_COMMAND_READ, |
505 | data, address)); | 318 | &address, 1, &d, 1); |
506 | 319 | *data = d; | |
507 | up(&ec->intr.sem); | 320 | return result; |
508 | 321 | } | |
509 | if (ec->common.global_lock) | ||
510 | acpi_release_global_lock(glk); | ||
511 | 322 | ||
512 | return status; | 323 | static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data) |
324 | { | ||
325 | u8 wdata[2] = { address, data }; | ||
326 | return acpi_ec_transaction(ec, ACPI_EC_COMMAND_WRITE, | ||
327 | wdata, 2, NULL, 0); | ||
513 | } | 328 | } |
514 | 329 | ||
515 | /* | 330 | /* |
516 | * Externally callable EC access functions. For now, assume 1 EC only | 331 | * Externally callable EC access functions. For now, assume 1 EC only |
517 | */ | 332 | */ |
518 | int ec_read(u8 addr, u8 * val) | 333 | int ec_read(u8 addr, u8 *val) |
519 | { | 334 | { |
520 | union acpi_ec *ec; | 335 | struct acpi_ec *ec; |
521 | int err; | 336 | int err; |
522 | u32 temp_data; | 337 | u8 temp_data; |
523 | 338 | ||
524 | if (!first_ec) | 339 | if (!first_ec) |
525 | return -ENODEV; | 340 | return -ENODEV; |
@@ -539,7 +354,7 @@ EXPORT_SYMBOL(ec_read); | |||
539 | 354 | ||
540 | int ec_write(u8 addr, u8 val) | 355 | int ec_write(u8 addr, u8 val) |
541 | { | 356 | { |
542 | union acpi_ec *ec; | 357 | struct acpi_ec *ec; |
543 | int err; | 358 | int err; |
544 | 359 | ||
545 | if (!first_ec) | 360 | if (!first_ec) |
@@ -554,255 +369,106 @@ int ec_write(u8 addr, u8 val) | |||
554 | 369 | ||
555 | EXPORT_SYMBOL(ec_write); | 370 | EXPORT_SYMBOL(ec_write); |
556 | 371 | ||
557 | static int acpi_ec_query(union acpi_ec *ec, u32 * data) | 372 | extern int ec_transaction(u8 command, |
558 | { | 373 | const u8 *wdata, unsigned wdata_len, |
559 | if (acpi_ec_poll_mode) | 374 | u8 *rdata, unsigned rdata_len) |
560 | return acpi_ec_poll_query(ec, data); | ||
561 | else | ||
562 | return acpi_ec_intr_query(ec, data); | ||
563 | } | ||
564 | static int acpi_ec_poll_query(union acpi_ec *ec, u32 * data) | ||
565 | { | 375 | { |
566 | int result = 0; | 376 | struct acpi_ec *ec; |
567 | acpi_status status = AE_OK; | ||
568 | u32 glk = 0; | ||
569 | |||
570 | |||
571 | if (!ec || !data) | ||
572 | return -EINVAL; | ||
573 | |||
574 | *data = 0; | ||
575 | |||
576 | if (ec->common.global_lock) { | ||
577 | status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); | ||
578 | if (ACPI_FAILURE(status)) | ||
579 | return -ENODEV; | ||
580 | } | ||
581 | 377 | ||
582 | /* | 378 | if (!first_ec) |
583 | * Query the EC to find out which _Qxx method we need to evaluate. | 379 | return -ENODEV; |
584 | * Note that successful completion of the query causes the ACPI_EC_SCI | ||
585 | * bit to be cleared (and thus clearing the interrupt source). | ||
586 | */ | ||
587 | if (down_interruptible(&ec->poll.sem)) { | ||
588 | result = -ERESTARTSYS; | ||
589 | goto end_nosem; | ||
590 | } | ||
591 | |||
592 | acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, | ||
593 | &ec->common.command_addr); | ||
594 | result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); | ||
595 | if (result) | ||
596 | goto end; | ||
597 | |||
598 | acpi_hw_low_level_read(8, data, &ec->common.data_addr); | ||
599 | if (!*data) | ||
600 | result = -ENODATA; | ||
601 | 380 | ||
602 | end: | 381 | ec = acpi_driver_data(first_ec); |
603 | up(&ec->poll.sem); | ||
604 | end_nosem: | ||
605 | if (ec->common.global_lock) | ||
606 | acpi_release_global_lock(glk); | ||
607 | 382 | ||
608 | return result; | 383 | return acpi_ec_transaction(ec, command, wdata, |
384 | wdata_len, rdata, rdata_len); | ||
609 | } | 385 | } |
610 | static int acpi_ec_intr_query(union acpi_ec *ec, u32 * data) | ||
611 | { | ||
612 | int status = 0; | ||
613 | u32 glk; | ||
614 | |||
615 | 386 | ||
616 | if (!ec || !data) | 387 | EXPORT_SYMBOL(ec_transaction); |
617 | return -EINVAL; | ||
618 | *data = 0; | ||
619 | |||
620 | if (ec->common.global_lock) { | ||
621 | status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); | ||
622 | if (ACPI_FAILURE(status)) | ||
623 | return -ENODEV; | ||
624 | } | ||
625 | 388 | ||
626 | down(&ec->intr.sem); | 389 | static int acpi_ec_query(struct acpi_ec *ec, u8 *data) |
390 | { | ||
391 | int result; | ||
392 | u8 d; | ||
627 | 393 | ||
628 | status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); | 394 | if (!ec || !data) |
629 | if (status) { | 395 | return -EINVAL; |
630 | printk(KERN_DEBUG PREFIX "query EC, IB not empty\n"); | ||
631 | goto end; | ||
632 | } | ||
633 | /* | ||
634 | * Query the EC to find out which _Qxx method we need to evaluate. | ||
635 | * Note that successful completion of the query causes the ACPI_EC_SCI | ||
636 | * bit to be cleared (and thus clearing the interrupt source). | ||
637 | */ | ||
638 | acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, | ||
639 | &ec->common.command_addr); | ||
640 | status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); | ||
641 | if (status) { | ||
642 | printk(KERN_DEBUG PREFIX "query EC, OB not full\n"); | ||
643 | goto end; | ||
644 | } | ||
645 | 396 | ||
646 | acpi_hw_low_level_read(8, data, &ec->common.data_addr); | 397 | /* |
647 | if (!*data) | 398 | * Query the EC to find out which _Qxx method we need to evaluate. |
648 | status = -ENODATA; | 399 | * Note that successful completion of the query causes the ACPI_EC_SCI |
400 | * bit to be cleared (and thus clearing the interrupt source). | ||
401 | */ | ||
649 | 402 | ||
650 | end: | 403 | result = acpi_ec_transaction(ec, ACPI_EC_COMMAND_QUERY, NULL, 0, &d, 1); |
651 | up(&ec->intr.sem); | 404 | if (result) |
405 | return result; | ||
652 | 406 | ||
653 | if (ec->common.global_lock) | 407 | if (!d) |
654 | acpi_release_global_lock(glk); | 408 | return -ENODATA; |
655 | 409 | ||
656 | return status; | 410 | *data = d; |
411 | return 0; | ||
657 | } | 412 | } |
658 | 413 | ||
659 | /* -------------------------------------------------------------------------- | 414 | /* -------------------------------------------------------------------------- |
660 | Event Management | 415 | Event Management |
661 | -------------------------------------------------------------------------- */ | 416 | -------------------------------------------------------------------------- */ |
662 | 417 | ||
663 | union acpi_ec_query_data { | 418 | struct acpi_ec_query_data { |
664 | acpi_handle handle; | 419 | acpi_handle handle; |
665 | u8 data; | 420 | u8 data; |
666 | }; | 421 | }; |
667 | 422 | ||
668 | static void acpi_ec_gpe_query(void *ec_cxt) | 423 | static void acpi_ec_gpe_query(void *ec_cxt) |
669 | { | 424 | { |
670 | if (acpi_ec_poll_mode) | 425 | struct acpi_ec *ec = (struct acpi_ec *)ec_cxt; |
671 | acpi_ec_gpe_poll_query(ec_cxt); | 426 | u8 value = 0; |
672 | else | 427 | static char object_name[8]; |
673 | acpi_ec_gpe_intr_query(ec_cxt); | ||
674 | } | ||
675 | |||
676 | static void acpi_ec_gpe_poll_query(void *ec_cxt) | ||
677 | { | ||
678 | union acpi_ec *ec = (union acpi_ec *)ec_cxt; | ||
679 | u32 value = 0; | ||
680 | static char object_name[5] = { '_', 'Q', '0', '0', '\0' }; | ||
681 | const char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7', | ||
682 | '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' | ||
683 | }; | ||
684 | |||
685 | 428 | ||
686 | if (!ec_cxt) | 429 | if (!ec) |
687 | goto end; | 430 | goto end; |
688 | 431 | ||
689 | if (down_interruptible (&ec->poll.sem)) { | 432 | value = acpi_ec_read_status(ec); |
690 | return; | 433 | |
691 | } | ||
692 | acpi_hw_low_level_read(8, &value, &ec->common.command_addr); | ||
693 | up(&ec->poll.sem); | ||
694 | |||
695 | /* TBD: Implement asynch events! | ||
696 | * NOTE: All we care about are EC-SCI's. Other EC events are | ||
697 | * handled via polling (yuck!). This is because some systems | ||
698 | * treat EC-SCIs as level (versus EDGE!) triggered, preventing | ||
699 | * a purely interrupt-driven approach (grumble, grumble). | ||
700 | */ | ||
701 | if (!(value & ACPI_EC_FLAG_SCI)) | 434 | if (!(value & ACPI_EC_FLAG_SCI)) |
702 | goto end; | 435 | goto end; |
703 | 436 | ||
704 | if (acpi_ec_query(ec, &value)) | 437 | if (acpi_ec_query(ec, &value)) |
705 | goto end; | 438 | goto end; |
706 | 439 | ||
707 | object_name[2] = hex[((value >> 4) & 0x0F)]; | 440 | snprintf(object_name, 8, "_Q%2.2X", value); |
708 | object_name[3] = hex[(value & 0x0F)]; | ||
709 | |||
710 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s\n", object_name)); | ||
711 | 441 | ||
712 | acpi_evaluate_object(ec->common.handle, object_name, NULL, NULL); | 442 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s", object_name)); |
713 | 443 | ||
714 | end: | 444 | acpi_evaluate_object(ec->handle, object_name, NULL, NULL); |
715 | acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); | ||
716 | } | ||
717 | static void acpi_ec_gpe_intr_query(void *ec_cxt) | ||
718 | { | ||
719 | union acpi_ec *ec = (union acpi_ec *)ec_cxt; | ||
720 | u32 value; | ||
721 | int result = -ENODATA; | ||
722 | static char object_name[5] = { '_', 'Q', '0', '0', '\0' }; | ||
723 | const char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7', | ||
724 | '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' | ||
725 | }; | ||
726 | 445 | ||
727 | |||
728 | if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_SCI) | ||
729 | result = acpi_ec_query(ec, &value); | ||
730 | |||
731 | if (result) | ||
732 | goto end; | ||
733 | |||
734 | object_name[2] = hex[((value >> 4) & 0x0F)]; | ||
735 | object_name[3] = hex[(value & 0x0F)]; | ||
736 | |||
737 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s\n", object_name)); | ||
738 | |||
739 | acpi_evaluate_object(ec->common.handle, object_name, NULL, NULL); | ||
740 | end: | 446 | end: |
741 | atomic_dec(&ec->intr.pending_gpe); | 447 | acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); |
742 | return; | ||
743 | } | 448 | } |
744 | 449 | ||
745 | static u32 acpi_ec_gpe_handler(void *data) | 450 | static u32 acpi_ec_gpe_handler(void *data) |
746 | { | 451 | { |
747 | if (acpi_ec_poll_mode) | ||
748 | return acpi_ec_gpe_poll_handler(data); | ||
749 | else | ||
750 | return acpi_ec_gpe_intr_handler(data); | ||
751 | } | ||
752 | static u32 acpi_ec_gpe_poll_handler(void *data) | ||
753 | { | ||
754 | acpi_status status = AE_OK; | 452 | acpi_status status = AE_OK; |
755 | union acpi_ec *ec = (union acpi_ec *)data; | 453 | u8 value; |
756 | 454 | struct acpi_ec *ec = (struct acpi_ec *)data; | |
757 | if (!ec) | ||
758 | return ACPI_INTERRUPT_NOT_HANDLED; | ||
759 | |||
760 | acpi_disable_gpe(NULL, ec->common.gpe_bit, ACPI_ISR); | ||
761 | |||
762 | status = acpi_os_execute(OSL_EC_POLL_HANDLER, acpi_ec_gpe_query, ec); | ||
763 | |||
764 | if (status == AE_OK) | ||
765 | return ACPI_INTERRUPT_HANDLED; | ||
766 | else | ||
767 | return ACPI_INTERRUPT_NOT_HANDLED; | ||
768 | } | ||
769 | static u32 acpi_ec_gpe_intr_handler(void *data) | ||
770 | { | ||
771 | acpi_status status = AE_OK; | ||
772 | u32 value; | ||
773 | union acpi_ec *ec = (union acpi_ec *)data; | ||
774 | |||
775 | if (!ec) | ||
776 | return ACPI_INTERRUPT_NOT_HANDLED; | ||
777 | 455 | ||
778 | acpi_clear_gpe(NULL, ec->common.gpe_bit, ACPI_ISR); | 456 | acpi_clear_gpe(NULL, ec->gpe_bit, ACPI_ISR); |
779 | value = acpi_ec_read_status(ec); | 457 | value = acpi_ec_read_status(ec); |
780 | 458 | ||
781 | switch (ec->intr.expect_event) { | 459 | if (acpi_ec_mode == EC_INTR) { |
782 | case ACPI_EC_EVENT_OBF: | 460 | if (acpi_ec_check_status(value, ec->expect_event)) { |
783 | if (!(value & ACPI_EC_FLAG_OBF)) | 461 | ec->expect_event = 0; |
784 | break; | 462 | wake_up(&ec->wait); |
785 | ec->intr.expect_event = 0; | 463 | } |
786 | wake_up(&ec->intr.wait); | ||
787 | break; | ||
788 | case ACPI_EC_EVENT_IBE: | ||
789 | if ((value & ACPI_EC_FLAG_IBF)) | ||
790 | break; | ||
791 | ec->intr.expect_event = 0; | ||
792 | wake_up(&ec->intr.wait); | ||
793 | break; | ||
794 | default: | ||
795 | break; | ||
796 | } | 464 | } |
797 | 465 | ||
798 | if (value & ACPI_EC_FLAG_SCI) { | 466 | if (value & ACPI_EC_FLAG_SCI) { |
799 | atomic_add(1, &ec->intr.pending_gpe); | 467 | status = acpi_os_execute(OSL_EC_BURST_HANDLER, acpi_ec_gpe_query, ec); |
800 | status = acpi_os_execute(OSL_EC_BURST_HANDLER, | ||
801 | acpi_ec_gpe_query, ec); | ||
802 | return status == AE_OK ? | 468 | return status == AE_OK ? |
803 | ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED; | 469 | ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED; |
804 | } | 470 | } |
805 | acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_ISR); | 471 | acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_ISR); |
806 | return status == AE_OK ? | 472 | return status == AE_OK ? |
807 | ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED; | 473 | ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED; |
808 | } | 474 | } |
@@ -833,7 +499,7 @@ acpi_ec_space_handler(u32 function, | |||
833 | void *handler_context, void *region_context) | 499 | void *handler_context, void *region_context) |
834 | { | 500 | { |
835 | int result = 0; | 501 | int result = 0; |
836 | union acpi_ec *ec = NULL; | 502 | struct acpi_ec *ec = NULL; |
837 | u64 temp = *value; | 503 | u64 temp = *value; |
838 | acpi_integer f_v = 0; | 504 | acpi_integer f_v = 0; |
839 | int i = 0; | 505 | int i = 0; |
@@ -843,18 +509,16 @@ acpi_ec_space_handler(u32 function, | |||
843 | return AE_BAD_PARAMETER; | 509 | return AE_BAD_PARAMETER; |
844 | 510 | ||
845 | if (bit_width != 8 && acpi_strict) { | 511 | if (bit_width != 8 && acpi_strict) { |
846 | printk(KERN_WARNING PREFIX | ||
847 | "acpi_ec_space_handler: bit_width should be 8\n"); | ||
848 | return AE_BAD_PARAMETER; | 512 | return AE_BAD_PARAMETER; |
849 | } | 513 | } |
850 | 514 | ||
851 | ec = (union acpi_ec *)handler_context; | 515 | ec = (struct acpi_ec *)handler_context; |
852 | 516 | ||
853 | next_byte: | 517 | next_byte: |
854 | switch (function) { | 518 | switch (function) { |
855 | case ACPI_READ: | 519 | case ACPI_READ: |
856 | temp = 0; | 520 | temp = 0; |
857 | result = acpi_ec_read(ec, (u8) address, (u32 *) & temp); | 521 | result = acpi_ec_read(ec, (u8) address, (u8 *) &temp); |
858 | break; | 522 | break; |
859 | case ACPI_WRITE: | 523 | case ACPI_WRITE: |
860 | result = acpi_ec_write(ec, (u8) address, (u8) temp); | 524 | result = acpi_ec_write(ec, (u8) address, (u8) temp); |
@@ -905,20 +569,20 @@ static struct proc_dir_entry *acpi_ec_dir; | |||
905 | 569 | ||
906 | static int acpi_ec_read_info(struct seq_file *seq, void *offset) | 570 | static int acpi_ec_read_info(struct seq_file *seq, void *offset) |
907 | { | 571 | { |
908 | union acpi_ec *ec = (union acpi_ec *)seq->private; | 572 | struct acpi_ec *ec = (struct acpi_ec *)seq->private; |
909 | 573 | ||
910 | 574 | ||
911 | if (!ec) | 575 | if (!ec) |
912 | goto end; | 576 | goto end; |
913 | 577 | ||
914 | seq_printf(seq, "gpe bit: 0x%02x\n", | 578 | seq_printf(seq, "gpe bit: 0x%02x\n", |
915 | (u32) ec->common.gpe_bit); | 579 | (u32) ec->gpe_bit); |
916 | seq_printf(seq, "ports: 0x%02x, 0x%02x\n", | 580 | seq_printf(seq, "ports: 0x%02x, 0x%02x\n", |
917 | (u32) ec->common.status_addr.address, | 581 | (u32) ec->command_addr, |
918 | (u32) ec->common.data_addr.address); | 582 | (u32) ec->data_addr); |
919 | seq_printf(seq, "use global lock: %s\n", | 583 | seq_printf(seq, "use global lock: %s\n", |
920 | ec->common.global_lock ? "yes" : "no"); | 584 | ec->global_lock ? "yes" : "no"); |
921 | acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); | 585 | acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); |
922 | 586 | ||
923 | end: | 587 | end: |
924 | return 0; | 588 | return 0; |
@@ -929,7 +593,7 @@ static int acpi_ec_info_open_fs(struct inode *inode, struct file *file) | |||
929 | return single_open(file, acpi_ec_read_info, PDE(inode)->data); | 593 | return single_open(file, acpi_ec_read_info, PDE(inode)->data); |
930 | } | 594 | } |
931 | 595 | ||
932 | static const struct file_operations acpi_ec_info_ops = { | 596 | static struct file_operations acpi_ec_info_ops = { |
933 | .open = acpi_ec_info_open_fs, | 597 | .open = acpi_ec_info_open_fs, |
934 | .read = seq_read, | 598 | .read = seq_read, |
935 | .llseek = seq_lseek, | 599 | .llseek = seq_lseek, |
@@ -978,101 +642,35 @@ static int acpi_ec_remove_fs(struct acpi_device *device) | |||
978 | Driver Interface | 642 | Driver Interface |
979 | -------------------------------------------------------------------------- */ | 643 | -------------------------------------------------------------------------- */ |
980 | 644 | ||
981 | static int acpi_ec_poll_add(struct acpi_device *device) | 645 | static int acpi_ec_add(struct acpi_device *device) |
982 | { | 646 | { |
983 | int result = 0; | 647 | int result = 0; |
984 | acpi_status status = AE_OK; | 648 | acpi_status status = AE_OK; |
985 | union acpi_ec *ec = NULL; | 649 | struct acpi_ec *ec = NULL; |
986 | 650 | ||
987 | 651 | ||
988 | if (!device) | 652 | if (!device) |
989 | return -EINVAL; | 653 | return -EINVAL; |
990 | 654 | ||
991 | ec = kmalloc(sizeof(union acpi_ec), GFP_KERNEL); | 655 | ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL); |
992 | if (!ec) | 656 | if (!ec) |
993 | return -ENOMEM; | 657 | return -ENOMEM; |
994 | memset(ec, 0, sizeof(union acpi_ec)); | 658 | memset(ec, 0, sizeof(struct acpi_ec)); |
995 | 659 | ||
996 | ec->common.handle = device->handle; | 660 | ec->handle = device->handle; |
997 | ec->common.uid = -1; | 661 | ec->uid = -1; |
998 | init_MUTEX(&ec->poll.sem); | 662 | init_MUTEX(&ec->sem); |
999 | strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME); | 663 | if (acpi_ec_mode == EC_INTR) { |
1000 | strcpy(acpi_device_class(device), ACPI_EC_CLASS); | 664 | atomic_set(&ec->leaving_burst, 1); |
1001 | acpi_driver_data(device) = ec; | 665 | init_waitqueue_head(&ec->wait); |
1002 | |||
1003 | /* Use the global lock for all EC transactions? */ | ||
1004 | acpi_evaluate_integer(ec->common.handle, "_GLK", NULL, | ||
1005 | &ec->common.global_lock); | ||
1006 | |||
1007 | /* XXX we don't test uids, because on some boxes ecdt uid = 0, see: | ||
1008 | http://bugzilla.kernel.org/show_bug.cgi?id=6111 */ | ||
1009 | if (ec_ecdt) { | ||
1010 | acpi_remove_address_space_handler(ACPI_ROOT_OBJECT, | ||
1011 | ACPI_ADR_SPACE_EC, | ||
1012 | &acpi_ec_space_handler); | ||
1013 | |||
1014 | acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit, | ||
1015 | &acpi_ec_gpe_handler); | ||
1016 | |||
1017 | kfree(ec_ecdt); | ||
1018 | } | 666 | } |
1019 | |||
1020 | /* Get GPE bit assignment (EC events). */ | ||
1021 | /* TODO: Add support for _GPE returning a package */ | ||
1022 | status = | ||
1023 | acpi_evaluate_integer(ec->common.handle, "_GPE", NULL, | ||
1024 | &ec->common.gpe_bit); | ||
1025 | if (ACPI_FAILURE(status)) { | ||
1026 | ACPI_EXCEPTION((AE_INFO, status, "Obtaining GPE bit")); | ||
1027 | result = -ENODEV; | ||
1028 | goto end; | ||
1029 | } | ||
1030 | |||
1031 | result = acpi_ec_add_fs(device); | ||
1032 | if (result) | ||
1033 | goto end; | ||
1034 | |||
1035 | printk(KERN_INFO PREFIX "%s [%s] (gpe %d) polling mode.\n", | ||
1036 | acpi_device_name(device), acpi_device_bid(device), | ||
1037 | (u32) ec->common.gpe_bit); | ||
1038 | |||
1039 | if (!first_ec) | ||
1040 | first_ec = device; | ||
1041 | |||
1042 | end: | ||
1043 | if (result) | ||
1044 | kfree(ec); | ||
1045 | |||
1046 | return result; | ||
1047 | } | ||
1048 | static int acpi_ec_intr_add(struct acpi_device *device) | ||
1049 | { | ||
1050 | int result = 0; | ||
1051 | acpi_status status = AE_OK; | ||
1052 | union acpi_ec *ec = NULL; | ||
1053 | |||
1054 | |||
1055 | if (!device) | ||
1056 | return -EINVAL; | ||
1057 | |||
1058 | ec = kmalloc(sizeof(union acpi_ec), GFP_KERNEL); | ||
1059 | if (!ec) | ||
1060 | return -ENOMEM; | ||
1061 | memset(ec, 0, sizeof(union acpi_ec)); | ||
1062 | |||
1063 | ec->common.handle = device->handle; | ||
1064 | ec->common.uid = -1; | ||
1065 | atomic_set(&ec->intr.pending_gpe, 0); | ||
1066 | atomic_set(&ec->intr.leaving_burst, 1); | ||
1067 | init_MUTEX(&ec->intr.sem); | ||
1068 | init_waitqueue_head(&ec->intr.wait); | ||
1069 | strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME); | 667 | strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME); |
1070 | strcpy(acpi_device_class(device), ACPI_EC_CLASS); | 668 | strcpy(acpi_device_class(device), ACPI_EC_CLASS); |
1071 | acpi_driver_data(device) = ec; | 669 | acpi_driver_data(device) = ec; |
1072 | 670 | ||
1073 | /* Use the global lock for all EC transactions? */ | 671 | /* Use the global lock for all EC transactions? */ |
1074 | acpi_evaluate_integer(ec->common.handle, "_GLK", NULL, | 672 | acpi_evaluate_integer(ec->handle, "_GLK", NULL, |
1075 | &ec->common.global_lock); | 673 | &ec->global_lock); |
1076 | 674 | ||
1077 | /* XXX we don't test uids, because on some boxes ecdt uid = 0, see: | 675 | /* XXX we don't test uids, because on some boxes ecdt uid = 0, see: |
1078 | http://bugzilla.kernel.org/show_bug.cgi?id=6111 */ | 676 | http://bugzilla.kernel.org/show_bug.cgi?id=6111 */ |
@@ -1081,7 +679,7 @@ static int acpi_ec_intr_add(struct acpi_device *device) | |||
1081 | ACPI_ADR_SPACE_EC, | 679 | ACPI_ADR_SPACE_EC, |
1082 | &acpi_ec_space_handler); | 680 | &acpi_ec_space_handler); |
1083 | 681 | ||
1084 | acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit, | 682 | acpi_remove_gpe_handler(NULL, ec_ecdt->gpe_bit, |
1085 | &acpi_ec_gpe_handler); | 683 | &acpi_ec_gpe_handler); |
1086 | 684 | ||
1087 | kfree(ec_ecdt); | 685 | kfree(ec_ecdt); |
@@ -1090,10 +688,10 @@ static int acpi_ec_intr_add(struct acpi_device *device) | |||
1090 | /* Get GPE bit assignment (EC events). */ | 688 | /* Get GPE bit assignment (EC events). */ |
1091 | /* TODO: Add support for _GPE returning a package */ | 689 | /* TODO: Add support for _GPE returning a package */ |
1092 | status = | 690 | status = |
1093 | acpi_evaluate_integer(ec->common.handle, "_GPE", NULL, | 691 | acpi_evaluate_integer(ec->handle, "_GPE", NULL, |
1094 | &ec->common.gpe_bit); | 692 | &ec->gpe_bit); |
1095 | if (ACPI_FAILURE(status)) { | 693 | if (ACPI_FAILURE(status)) { |
1096 | printk(KERN_ERR PREFIX "Obtaining GPE bit assignment\n"); | 694 | ACPI_EXCEPTION((AE_INFO, status, "Obtaining GPE bit assignment")); |
1097 | result = -ENODEV; | 695 | result = -ENODEV; |
1098 | goto end; | 696 | goto end; |
1099 | } | 697 | } |
@@ -1102,14 +700,14 @@ static int acpi_ec_intr_add(struct acpi_device *device) | |||
1102 | if (result) | 700 | if (result) |
1103 | goto end; | 701 | goto end; |
1104 | 702 | ||
1105 | printk(KERN_INFO PREFIX "%s [%s] (gpe %d) interrupt mode.\n", | 703 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s [%s] (gpe %d) interrupt mode.", |
1106 | acpi_device_name(device), acpi_device_bid(device), | 704 | acpi_device_name(device), acpi_device_bid(device), |
1107 | (u32) ec->common.gpe_bit); | 705 | (u32) ec->gpe_bit)); |
1108 | 706 | ||
1109 | if (!first_ec) | 707 | if (!first_ec) |
1110 | first_ec = device; | 708 | first_ec = device; |
1111 | 709 | ||
1112 | end: | 710 | end: |
1113 | if (result) | 711 | if (result) |
1114 | kfree(ec); | 712 | kfree(ec); |
1115 | 713 | ||
@@ -1118,7 +716,7 @@ static int acpi_ec_intr_add(struct acpi_device *device) | |||
1118 | 716 | ||
1119 | static int acpi_ec_remove(struct acpi_device *device, int type) | 717 | static int acpi_ec_remove(struct acpi_device *device, int type) |
1120 | { | 718 | { |
1121 | union acpi_ec *ec = NULL; | 719 | struct acpi_ec *ec = NULL; |
1122 | 720 | ||
1123 | 721 | ||
1124 | if (!device) | 722 | if (!device) |
@@ -1136,8 +734,7 @@ static int acpi_ec_remove(struct acpi_device *device, int type) | |||
1136 | static acpi_status | 734 | static acpi_status |
1137 | acpi_ec_io_ports(struct acpi_resource *resource, void *context) | 735 | acpi_ec_io_ports(struct acpi_resource *resource, void *context) |
1138 | { | 736 | { |
1139 | union acpi_ec *ec = (union acpi_ec *)context; | 737 | struct acpi_ec *ec = (struct acpi_ec *)context; |
1140 | struct acpi_generic_address *addr; | ||
1141 | 738 | ||
1142 | if (resource->type != ACPI_RESOURCE_TYPE_IO) { | 739 | if (resource->type != ACPI_RESOURCE_TYPE_IO) { |
1143 | return AE_OK; | 740 | return AE_OK; |
@@ -1148,26 +745,21 @@ acpi_ec_io_ports(struct acpi_resource *resource, void *context) | |||
1148 | * the second address region returned is the status/command | 745 | * the second address region returned is the status/command |
1149 | * port. | 746 | * port. |
1150 | */ | 747 | */ |
1151 | if (ec->common.data_addr.register_bit_width == 0) { | 748 | if (ec->data_addr == 0) { |
1152 | addr = &ec->common.data_addr; | 749 | ec->data_addr = resource->data.io.minimum; |
1153 | } else if (ec->common.command_addr.register_bit_width == 0) { | 750 | } else if (ec->command_addr == 0) { |
1154 | addr = &ec->common.command_addr; | 751 | ec->command_addr = resource->data.io.minimum; |
1155 | } else { | 752 | } else { |
1156 | return AE_CTRL_TERMINATE; | 753 | return AE_CTRL_TERMINATE; |
1157 | } | 754 | } |
1158 | 755 | ||
1159 | addr->address_space_id = ACPI_ADR_SPACE_SYSTEM_IO; | ||
1160 | addr->register_bit_width = 8; | ||
1161 | addr->register_bit_offset = 0; | ||
1162 | addr->address = resource->data.io.minimum; | ||
1163 | |||
1164 | return AE_OK; | 756 | return AE_OK; |
1165 | } | 757 | } |
1166 | 758 | ||
1167 | static int acpi_ec_start(struct acpi_device *device) | 759 | static int acpi_ec_start(struct acpi_device *device) |
1168 | { | 760 | { |
1169 | acpi_status status = AE_OK; | 761 | acpi_status status = AE_OK; |
1170 | union acpi_ec *ec = NULL; | 762 | struct acpi_ec *ec = NULL; |
1171 | 763 | ||
1172 | 764 | ||
1173 | if (!device) | 765 | if (!device) |
@@ -1181,39 +773,35 @@ static int acpi_ec_start(struct acpi_device *device) | |||
1181 | /* | 773 | /* |
1182 | * Get I/O port addresses. Convert to GAS format. | 774 | * Get I/O port addresses. Convert to GAS format. |
1183 | */ | 775 | */ |
1184 | status = acpi_walk_resources(ec->common.handle, METHOD_NAME__CRS, | 776 | status = acpi_walk_resources(ec->handle, METHOD_NAME__CRS, |
1185 | acpi_ec_io_ports, ec); | 777 | acpi_ec_io_ports, ec); |
1186 | if (ACPI_FAILURE(status) | 778 | if (ACPI_FAILURE(status) || ec->command_addr == 0) { |
1187 | || ec->common.command_addr.register_bit_width == 0) { | 779 | ACPI_EXCEPTION((AE_INFO, status, |
1188 | printk(KERN_ERR PREFIX "Error getting I/O port addresses\n"); | 780 | "Error getting I/O port addresses")); |
1189 | return -ENODEV; | 781 | return -ENODEV; |
1190 | } | 782 | } |
1191 | 783 | ||
1192 | ec->common.status_addr = ec->common.command_addr; | 784 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02lx, ports=0x%2lx,0x%2lx", |
1193 | 785 | ec->gpe_bit, ec->command_addr, ec->data_addr)); | |
1194 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02x, ports=0x%2x,0x%2x\n", | ||
1195 | (u32) ec->common.gpe_bit, | ||
1196 | (u32) ec->common.command_addr.address, | ||
1197 | (u32) ec->common.data_addr.address)); | ||
1198 | 786 | ||
1199 | /* | 787 | /* |
1200 | * Install GPE handler | 788 | * Install GPE handler |
1201 | */ | 789 | */ |
1202 | status = acpi_install_gpe_handler(NULL, ec->common.gpe_bit, | 790 | status = acpi_install_gpe_handler(NULL, ec->gpe_bit, |
1203 | ACPI_GPE_EDGE_TRIGGERED, | 791 | ACPI_GPE_EDGE_TRIGGERED, |
1204 | &acpi_ec_gpe_handler, ec); | 792 | &acpi_ec_gpe_handler, ec); |
1205 | if (ACPI_FAILURE(status)) { | 793 | if (ACPI_FAILURE(status)) { |
1206 | return -ENODEV; | 794 | return -ENODEV; |
1207 | } | 795 | } |
1208 | acpi_set_gpe_type(NULL, ec->common.gpe_bit, ACPI_GPE_TYPE_RUNTIME); | 796 | acpi_set_gpe_type(NULL, ec->gpe_bit, ACPI_GPE_TYPE_RUNTIME); |
1209 | acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); | 797 | acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); |
1210 | 798 | ||
1211 | status = acpi_install_address_space_handler(ec->common.handle, | 799 | status = acpi_install_address_space_handler(ec->handle, |
1212 | ACPI_ADR_SPACE_EC, | 800 | ACPI_ADR_SPACE_EC, |
1213 | &acpi_ec_space_handler, | 801 | &acpi_ec_space_handler, |
1214 | &acpi_ec_space_setup, ec); | 802 | &acpi_ec_space_setup, ec); |
1215 | if (ACPI_FAILURE(status)) { | 803 | if (ACPI_FAILURE(status)) { |
1216 | acpi_remove_gpe_handler(NULL, ec->common.gpe_bit, | 804 | acpi_remove_gpe_handler(NULL, ec->gpe_bit, |
1217 | &acpi_ec_gpe_handler); | 805 | &acpi_ec_gpe_handler); |
1218 | return -ENODEV; | 806 | return -ENODEV; |
1219 | } | 807 | } |
@@ -1224,7 +812,7 @@ static int acpi_ec_start(struct acpi_device *device) | |||
1224 | static int acpi_ec_stop(struct acpi_device *device, int type) | 812 | static int acpi_ec_stop(struct acpi_device *device, int type) |
1225 | { | 813 | { |
1226 | acpi_status status = AE_OK; | 814 | acpi_status status = AE_OK; |
1227 | union acpi_ec *ec = NULL; | 815 | struct acpi_ec *ec = NULL; |
1228 | 816 | ||
1229 | 817 | ||
1230 | if (!device) | 818 | if (!device) |
@@ -1232,14 +820,14 @@ static int acpi_ec_stop(struct acpi_device *device, int type) | |||
1232 | 820 | ||
1233 | ec = acpi_driver_data(device); | 821 | ec = acpi_driver_data(device); |
1234 | 822 | ||
1235 | status = acpi_remove_address_space_handler(ec->common.handle, | 823 | status = acpi_remove_address_space_handler(ec->handle, |
1236 | ACPI_ADR_SPACE_EC, | 824 | ACPI_ADR_SPACE_EC, |
1237 | &acpi_ec_space_handler); | 825 | &acpi_ec_space_handler); |
1238 | if (ACPI_FAILURE(status)) | 826 | if (ACPI_FAILURE(status)) |
1239 | return -ENODEV; | 827 | return -ENODEV; |
1240 | 828 | ||
1241 | status = | 829 | status = |
1242 | acpi_remove_gpe_handler(NULL, ec->common.gpe_bit, | 830 | acpi_remove_gpe_handler(NULL, ec->gpe_bit, |
1243 | &acpi_ec_gpe_handler); | 831 | &acpi_ec_gpe_handler); |
1244 | if (ACPI_FAILURE(status)) | 832 | if (ACPI_FAILURE(status)) |
1245 | return -ENODEV; | 833 | return -ENODEV; |
@@ -1251,76 +839,30 @@ static acpi_status __init | |||
1251 | acpi_fake_ecdt_callback(acpi_handle handle, | 839 | acpi_fake_ecdt_callback(acpi_handle handle, |
1252 | u32 Level, void *context, void **retval) | 840 | u32 Level, void *context, void **retval) |
1253 | { | 841 | { |
1254 | |||
1255 | if (acpi_ec_poll_mode) | ||
1256 | return acpi_fake_ecdt_poll_callback(handle, | ||
1257 | Level, context, retval); | ||
1258 | else | ||
1259 | return acpi_fake_ecdt_intr_callback(handle, | ||
1260 | Level, context, retval); | ||
1261 | } | ||
1262 | |||
1263 | static acpi_status __init | ||
1264 | acpi_fake_ecdt_poll_callback(acpi_handle handle, | ||
1265 | u32 Level, void *context, void **retval) | ||
1266 | { | ||
1267 | acpi_status status; | ||
1268 | |||
1269 | status = acpi_walk_resources(handle, METHOD_NAME__CRS, | ||
1270 | acpi_ec_io_ports, ec_ecdt); | ||
1271 | if (ACPI_FAILURE(status)) | ||
1272 | return status; | ||
1273 | ec_ecdt->common.status_addr = ec_ecdt->common.command_addr; | ||
1274 | |||
1275 | ec_ecdt->common.uid = -1; | ||
1276 | acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->common.uid); | ||
1277 | |||
1278 | status = | ||
1279 | acpi_evaluate_integer(handle, "_GPE", NULL, | ||
1280 | &ec_ecdt->common.gpe_bit); | ||
1281 | if (ACPI_FAILURE(status)) | ||
1282 | return status; | ||
1283 | init_MUTEX(&ec_ecdt->poll.sem); | ||
1284 | ec_ecdt->common.global_lock = TRUE; | ||
1285 | ec_ecdt->common.handle = handle; | ||
1286 | |||
1287 | printk(KERN_INFO PREFIX "GPE=0x%02x, ports=0x%2x, 0x%2x\n", | ||
1288 | (u32) ec_ecdt->common.gpe_bit, | ||
1289 | (u32) ec_ecdt->common.command_addr.address, | ||
1290 | (u32) ec_ecdt->common.data_addr.address); | ||
1291 | |||
1292 | return AE_CTRL_TERMINATE; | ||
1293 | } | ||
1294 | |||
1295 | static acpi_status __init | ||
1296 | acpi_fake_ecdt_intr_callback(acpi_handle handle, | ||
1297 | u32 Level, void *context, void **retval) | ||
1298 | { | ||
1299 | acpi_status status; | 842 | acpi_status status; |
1300 | 843 | ||
1301 | init_MUTEX(&ec_ecdt->intr.sem); | 844 | init_MUTEX(&ec_ecdt->sem); |
1302 | init_waitqueue_head(&ec_ecdt->intr.wait); | 845 | if (acpi_ec_mode == EC_INTR) { |
846 | init_waitqueue_head(&ec_ecdt->wait); | ||
847 | } | ||
1303 | status = acpi_walk_resources(handle, METHOD_NAME__CRS, | 848 | status = acpi_walk_resources(handle, METHOD_NAME__CRS, |
1304 | acpi_ec_io_ports, ec_ecdt); | 849 | acpi_ec_io_ports, ec_ecdt); |
1305 | if (ACPI_FAILURE(status)) | 850 | if (ACPI_FAILURE(status)) |
1306 | return status; | 851 | return status; |
1307 | ec_ecdt->common.status_addr = ec_ecdt->common.command_addr; | ||
1308 | 852 | ||
1309 | ec_ecdt->common.uid = -1; | 853 | ec_ecdt->uid = -1; |
1310 | acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->common.uid); | 854 | acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->uid); |
1311 | 855 | ||
1312 | status = | 856 | status = |
1313 | acpi_evaluate_integer(handle, "_GPE", NULL, | 857 | acpi_evaluate_integer(handle, "_GPE", NULL, |
1314 | &ec_ecdt->common.gpe_bit); | 858 | &ec_ecdt->gpe_bit); |
1315 | if (ACPI_FAILURE(status)) | 859 | if (ACPI_FAILURE(status)) |
1316 | return status; | 860 | return status; |
1317 | ec_ecdt->common.global_lock = TRUE; | 861 | ec_ecdt->global_lock = TRUE; |
1318 | ec_ecdt->common.handle = handle; | 862 | ec_ecdt->handle = handle; |
1319 | 863 | ||
1320 | printk(KERN_INFO PREFIX "GPE=0x%02x, ports=0x%2x, 0x%2x\n", | 864 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "GPE=0x%02lx, ports=0x%2lx, 0x%2lx", |
1321 | (u32) ec_ecdt->common.gpe_bit, | 865 | ec_ecdt->gpe_bit, ec_ecdt->command_addr, ec_ecdt->data_addr)); |
1322 | (u32) ec_ecdt->common.command_addr.address, | ||
1323 | (u32) ec_ecdt->common.data_addr.address); | ||
1324 | 866 | ||
1325 | return AE_CTRL_TERMINATE; | 867 | return AE_CTRL_TERMINATE; |
1326 | } | 868 | } |
@@ -1340,14 +882,14 @@ static int __init acpi_ec_fake_ecdt(void) | |||
1340 | acpi_status status; | 882 | acpi_status status; |
1341 | int ret = 0; | 883 | int ret = 0; |
1342 | 884 | ||
1343 | printk(KERN_INFO PREFIX "Try to make an fake ECDT\n"); | 885 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Try to make an fake ECDT")); |
1344 | 886 | ||
1345 | ec_ecdt = kmalloc(sizeof(union acpi_ec), GFP_KERNEL); | 887 | ec_ecdt = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL); |
1346 | if (!ec_ecdt) { | 888 | if (!ec_ecdt) { |
1347 | ret = -ENOMEM; | 889 | ret = -ENOMEM; |
1348 | goto error; | 890 | goto error; |
1349 | } | 891 | } |
1350 | memset(ec_ecdt, 0, sizeof(union acpi_ec)); | 892 | memset(ec_ecdt, 0, sizeof(struct acpi_ec)); |
1351 | 893 | ||
1352 | status = acpi_get_devices(ACPI_EC_HID, | 894 | status = acpi_get_devices(ACPI_EC_HID, |
1353 | acpi_fake_ecdt_callback, NULL, NULL); | 895 | acpi_fake_ecdt_callback, NULL, NULL); |
@@ -1355,24 +897,16 @@ static int __init acpi_ec_fake_ecdt(void) | |||
1355 | kfree(ec_ecdt); | 897 | kfree(ec_ecdt); |
1356 | ec_ecdt = NULL; | 898 | ec_ecdt = NULL; |
1357 | ret = -ENODEV; | 899 | ret = -ENODEV; |
900 | ACPI_EXCEPTION((AE_INFO, status, "Can't make an fake ECDT")); | ||
1358 | goto error; | 901 | goto error; |
1359 | } | 902 | } |
1360 | return 0; | 903 | return 0; |
1361 | error: | 904 | error: |
1362 | printk(KERN_ERR PREFIX "Can't make an fake ECDT\n"); | ||
1363 | return ret; | 905 | return ret; |
1364 | } | 906 | } |
1365 | 907 | ||
1366 | static int __init acpi_ec_get_real_ecdt(void) | 908 | static int __init acpi_ec_get_real_ecdt(void) |
1367 | { | 909 | { |
1368 | if (acpi_ec_poll_mode) | ||
1369 | return acpi_ec_poll_get_real_ecdt(); | ||
1370 | else | ||
1371 | return acpi_ec_intr_get_real_ecdt(); | ||
1372 | } | ||
1373 | |||
1374 | static int __init acpi_ec_poll_get_real_ecdt(void) | ||
1375 | { | ||
1376 | acpi_status status; | 910 | acpi_status status; |
1377 | struct acpi_table_ecdt *ecdt_ptr; | 911 | struct acpi_table_ecdt *ecdt_ptr; |
1378 | 912 | ||
@@ -1382,80 +916,36 @@ static int __init acpi_ec_poll_get_real_ecdt(void) | |||
1382 | if (ACPI_FAILURE(status)) | 916 | if (ACPI_FAILURE(status)) |
1383 | return -ENODEV; | 917 | return -ENODEV; |
1384 | 918 | ||
1385 | printk(KERN_INFO PREFIX "Found ECDT\n"); | 919 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found ECDT")); |
1386 | 920 | ||
1387 | /* | 921 | /* |
1388 | * Generate a temporary ec context to use until the namespace is scanned | 922 | * Generate a temporary ec context to use until the namespace is scanned |
1389 | */ | 923 | */ |
1390 | ec_ecdt = kmalloc(sizeof(union acpi_ec), GFP_KERNEL); | 924 | ec_ecdt = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL); |
1391 | if (!ec_ecdt) | 925 | if (!ec_ecdt) |
1392 | return -ENOMEM; | 926 | return -ENOMEM; |
1393 | memset(ec_ecdt, 0, sizeof(union acpi_ec)); | 927 | memset(ec_ecdt, 0, sizeof(struct acpi_ec)); |
1394 | |||
1395 | ec_ecdt->common.command_addr = ecdt_ptr->ec_control; | ||
1396 | ec_ecdt->common.status_addr = ecdt_ptr->ec_control; | ||
1397 | ec_ecdt->common.data_addr = ecdt_ptr->ec_data; | ||
1398 | ec_ecdt->common.gpe_bit = ecdt_ptr->gpe_bit; | ||
1399 | init_MUTEX(&ec_ecdt->poll.sem); | ||
1400 | /* use the GL just to be safe */ | ||
1401 | ec_ecdt->common.global_lock = TRUE; | ||
1402 | ec_ecdt->common.uid = ecdt_ptr->uid; | ||
1403 | 928 | ||
1404 | status = | 929 | init_MUTEX(&ec_ecdt->sem); |
1405 | acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->common.handle); | 930 | if (acpi_ec_mode == EC_INTR) { |
1406 | if (ACPI_FAILURE(status)) { | 931 | init_waitqueue_head(&ec_ecdt->wait); |
1407 | goto error; | ||
1408 | } | 932 | } |
1409 | 933 | ec_ecdt->command_addr = ecdt_ptr->ec_control.address; | |
1410 | return 0; | 934 | ec_ecdt->data_addr = ecdt_ptr->ec_data.address; |
1411 | error: | 935 | ec_ecdt->gpe_bit = ecdt_ptr->gpe_bit; |
1412 | printk(KERN_ERR PREFIX "Could not use ECDT\n"); | ||
1413 | kfree(ec_ecdt); | ||
1414 | ec_ecdt = NULL; | ||
1415 | |||
1416 | return -ENODEV; | ||
1417 | } | ||
1418 | |||
1419 | static int __init acpi_ec_intr_get_real_ecdt(void) | ||
1420 | { | ||
1421 | acpi_status status; | ||
1422 | struct acpi_table_ecdt *ecdt_ptr; | ||
1423 | |||
1424 | status = acpi_get_firmware_table("ECDT", 1, ACPI_LOGICAL_ADDRESSING, | ||
1425 | (struct acpi_table_header **) | ||
1426 | &ecdt_ptr); | ||
1427 | if (ACPI_FAILURE(status)) | ||
1428 | return -ENODEV; | ||
1429 | |||
1430 | printk(KERN_INFO PREFIX "Found ECDT\n"); | ||
1431 | |||
1432 | /* | ||
1433 | * Generate a temporary ec context to use until the namespace is scanned | ||
1434 | */ | ||
1435 | ec_ecdt = kmalloc(sizeof(union acpi_ec), GFP_KERNEL); | ||
1436 | if (!ec_ecdt) | ||
1437 | return -ENOMEM; | ||
1438 | memset(ec_ecdt, 0, sizeof(union acpi_ec)); | ||
1439 | |||
1440 | init_MUTEX(&ec_ecdt->intr.sem); | ||
1441 | init_waitqueue_head(&ec_ecdt->intr.wait); | ||
1442 | ec_ecdt->common.command_addr = ecdt_ptr->ec_control; | ||
1443 | ec_ecdt->common.status_addr = ecdt_ptr->ec_control; | ||
1444 | ec_ecdt->common.data_addr = ecdt_ptr->ec_data; | ||
1445 | ec_ecdt->common.gpe_bit = ecdt_ptr->gpe_bit; | ||
1446 | /* use the GL just to be safe */ | 936 | /* use the GL just to be safe */ |
1447 | ec_ecdt->common.global_lock = TRUE; | 937 | ec_ecdt->global_lock = TRUE; |
1448 | ec_ecdt->common.uid = ecdt_ptr->uid; | 938 | ec_ecdt->uid = ecdt_ptr->uid; |
1449 | 939 | ||
1450 | status = | 940 | status = |
1451 | acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->common.handle); | 941 | acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->handle); |
1452 | if (ACPI_FAILURE(status)) { | 942 | if (ACPI_FAILURE(status)) { |
1453 | goto error; | 943 | goto error; |
1454 | } | 944 | } |
1455 | 945 | ||
1456 | return 0; | 946 | return 0; |
1457 | error: | 947 | error: |
1458 | printk(KERN_ERR PREFIX "Could not use ECDT\n"); | 948 | ACPI_EXCEPTION((AE_INFO, status, "Could not use ECDT")); |
1459 | kfree(ec_ecdt); | 949 | kfree(ec_ecdt); |
1460 | ec_ecdt = NULL; | 950 | ec_ecdt = NULL; |
1461 | 951 | ||
@@ -1480,14 +970,14 @@ int __init acpi_ec_ecdt_probe(void) | |||
1480 | /* | 970 | /* |
1481 | * Install GPE handler | 971 | * Install GPE handler |
1482 | */ | 972 | */ |
1483 | status = acpi_install_gpe_handler(NULL, ec_ecdt->common.gpe_bit, | 973 | status = acpi_install_gpe_handler(NULL, ec_ecdt->gpe_bit, |
1484 | ACPI_GPE_EDGE_TRIGGERED, | 974 | ACPI_GPE_EDGE_TRIGGERED, |
1485 | &acpi_ec_gpe_handler, ec_ecdt); | 975 | &acpi_ec_gpe_handler, ec_ecdt); |
1486 | if (ACPI_FAILURE(status)) { | 976 | if (ACPI_FAILURE(status)) { |
1487 | goto error; | 977 | goto error; |
1488 | } | 978 | } |
1489 | acpi_set_gpe_type(NULL, ec_ecdt->common.gpe_bit, ACPI_GPE_TYPE_RUNTIME); | 979 | acpi_set_gpe_type(NULL, ec_ecdt->gpe_bit, ACPI_GPE_TYPE_RUNTIME); |
1490 | acpi_enable_gpe(NULL, ec_ecdt->common.gpe_bit, ACPI_NOT_ISR); | 980 | acpi_enable_gpe(NULL, ec_ecdt->gpe_bit, ACPI_NOT_ISR); |
1491 | 981 | ||
1492 | status = acpi_install_address_space_handler(ACPI_ROOT_OBJECT, | 982 | status = acpi_install_address_space_handler(ACPI_ROOT_OBJECT, |
1493 | ACPI_ADR_SPACE_EC, | 983 | ACPI_ADR_SPACE_EC, |
@@ -1495,7 +985,7 @@ int __init acpi_ec_ecdt_probe(void) | |||
1495 | &acpi_ec_space_setup, | 985 | &acpi_ec_space_setup, |
1496 | ec_ecdt); | 986 | ec_ecdt); |
1497 | if (ACPI_FAILURE(status)) { | 987 | if (ACPI_FAILURE(status)) { |
1498 | acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit, | 988 | acpi_remove_gpe_handler(NULL, ec_ecdt->gpe_bit, |
1499 | &acpi_ec_gpe_handler); | 989 | &acpi_ec_gpe_handler); |
1500 | goto error; | 990 | goto error; |
1501 | } | 991 | } |
@@ -1503,7 +993,7 @@ int __init acpi_ec_ecdt_probe(void) | |||
1503 | return 0; | 993 | return 0; |
1504 | 994 | ||
1505 | error: | 995 | error: |
1506 | printk(KERN_ERR PREFIX "Could not use ECDT\n"); | 996 | ACPI_EXCEPTION((AE_INFO, status, "Could not use ECDT")); |
1507 | kfree(ec_ecdt); | 997 | kfree(ec_ecdt); |
1508 | ec_ecdt = NULL; | 998 | ec_ecdt = NULL; |
1509 | 999 | ||
@@ -1562,13 +1052,13 @@ static int __init acpi_ec_set_intr_mode(char *str) | |||
1562 | return 0; | 1052 | return 0; |
1563 | 1053 | ||
1564 | if (intr) { | 1054 | if (intr) { |
1565 | acpi_ec_poll_mode = EC_INTR; | 1055 | acpi_ec_mode = EC_INTR; |
1566 | acpi_ec_driver.ops.add = acpi_ec_intr_add; | ||
1567 | } else { | 1056 | } else { |
1568 | acpi_ec_poll_mode = EC_POLL; | 1057 | acpi_ec_mode = EC_POLL; |
1569 | acpi_ec_driver.ops.add = acpi_ec_poll_add; | ||
1570 | } | 1058 | } |
1571 | printk(KERN_INFO PREFIX "EC %s mode.\n", intr ? "interrupt" : "polling"); | 1059 | acpi_ec_driver.ops.add = acpi_ec_add; |
1060 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "EC %s mode.\n", intr ? "interrupt" : "polling")); | ||
1061 | |||
1572 | return 1; | 1062 | return 1; |
1573 | } | 1063 | } |
1574 | 1064 | ||
diff --git a/drivers/acpi/events/evmisc.c b/drivers/acpi/events/evmisc.c index 6eef4efddcf6..ee2a10bf9077 100644 --- a/drivers/acpi/events/evmisc.c +++ b/drivers/acpi/events/evmisc.c | |||
@@ -342,20 +342,8 @@ static u32 acpi_ev_global_lock_handler(void *context) | |||
342 | if (acquired) { | 342 | if (acquired) { |
343 | 343 | ||
344 | /* Got the lock, now wake all threads waiting for it */ | 344 | /* Got the lock, now wake all threads waiting for it */ |
345 | |||
346 | acpi_gbl_global_lock_acquired = TRUE; | 345 | acpi_gbl_global_lock_acquired = TRUE; |
347 | 346 | acpi_ev_global_lock_thread(context); | |
348 | /* Run the Global Lock thread which will signal all waiting threads */ | ||
349 | |||
350 | status = | ||
351 | acpi_os_execute(OSL_GLOBAL_LOCK_HANDLER, | ||
352 | acpi_ev_global_lock_thread, context); | ||
353 | if (ACPI_FAILURE(status)) { | ||
354 | ACPI_EXCEPTION((AE_INFO, status, | ||
355 | "Could not queue Global Lock thread")); | ||
356 | |||
357 | return (ACPI_INTERRUPT_NOT_HANDLED); | ||
358 | } | ||
359 | } | 347 | } |
360 | 348 | ||
361 | return (ACPI_INTERRUPT_HANDLED); | 349 | return (ACPI_INTERRUPT_HANDLED); |
diff --git a/drivers/acpi/events/evrgnini.c b/drivers/acpi/events/evrgnini.c index 5b3c7a85eb9a..203d1359190a 100644 --- a/drivers/acpi/events/evrgnini.c +++ b/drivers/acpi/events/evrgnini.c | |||
@@ -225,13 +225,12 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, | |||
225 | if (! | 225 | if (! |
226 | (ACPI_STRNCMP | 226 | (ACPI_STRNCMP |
227 | (object_hID.value, PCI_ROOT_HID_STRING, | 227 | (object_hID.value, PCI_ROOT_HID_STRING, |
228 | sizeof(PCI_ROOT_HID_STRING)) | 228 | sizeof(PCI_ROOT_HID_STRING))) |
229 | || | 229 | || |
230 | !(ACPI_STRNCMP | 230 | !(ACPI_STRNCMP |
231 | (object_hID.value, | 231 | (object_hID.value, |
232 | PCI_EXPRESS_ROOT_HID_STRING, | 232 | PCI_EXPRESS_ROOT_HID_STRING, |
233 | sizeof(PCI_EXPRESS_ROOT_HID_STRING))))) | 233 | sizeof(PCI_EXPRESS_ROOT_HID_STRING)))) { |
234 | { | ||
235 | 234 | ||
236 | /* Install a handler for this PCI root bridge */ | 235 | /* Install a handler for this PCI root bridge */ |
237 | 236 | ||
diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c index 15fc12482ba0..003a9876c968 100644 --- a/drivers/acpi/ibm_acpi.c +++ b/drivers/acpi/ibm_acpi.c | |||
@@ -1702,13 +1702,11 @@ static struct ibm_struct ibms[] = { | |||
1702 | .name = "brightness", | 1702 | .name = "brightness", |
1703 | .read = brightness_read, | 1703 | .read = brightness_read, |
1704 | .write = brightness_write, | 1704 | .write = brightness_write, |
1705 | .experimental = 1, | ||
1706 | }, | 1705 | }, |
1707 | { | 1706 | { |
1708 | .name = "volume", | 1707 | .name = "volume", |
1709 | .read = volume_read, | 1708 | .read = volume_read, |
1710 | .write = volume_write, | 1709 | .write = volume_write, |
1711 | .experimental = 1, | ||
1712 | }, | 1710 | }, |
1713 | { | 1711 | { |
1714 | .name = "fan", | 1712 | .name = "fan", |
diff --git a/drivers/acpi/motherboard.c b/drivers/acpi/motherboard.c index ec6b7f9ede34..2e17ec75af03 100644 --- a/drivers/acpi/motherboard.c +++ b/drivers/acpi/motherboard.c | |||
@@ -48,6 +48,12 @@ ACPI_MODULE_NAME("acpi_motherboard") | |||
48 | * the io ports if they really know they can use it, while | 48 | * the io ports if they really know they can use it, while |
49 | * still preventing hotplug PCI devices from using it. | 49 | * still preventing hotplug PCI devices from using it. |
50 | */ | 50 | */ |
51 | |||
52 | /* | ||
53 | * When CONFIG_PNP is enabled, pnp/system.c binds to PNP0C01 | ||
54 | * and PNP0C02, redundant with acpi_reserve_io_ranges(). | ||
55 | * But acpi_reserve_io_ranges() is necessary for !CONFIG_PNP. | ||
56 | */ | ||
51 | static acpi_status acpi_reserve_io_ranges(struct acpi_resource *res, void *data) | 57 | static acpi_status acpi_reserve_io_ranges(struct acpi_resource *res, void *data) |
52 | { | 58 | { |
53 | struct resource *requested_res = NULL; | 59 | struct resource *requested_res = NULL; |
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c index 7f3e7e77e794..d53bd9878ca2 100644 --- a/drivers/acpi/pci_link.c +++ b/drivers/acpi/pci_link.c | |||
@@ -307,7 +307,7 @@ static int acpi_pci_link_set(struct acpi_pci_link *link, int irq) | |||
307 | if (!link || !irq) | 307 | if (!link || !irq) |
308 | return -EINVAL; | 308 | return -EINVAL; |
309 | 309 | ||
310 | resource = kmalloc(sizeof(*resource) + 1, GFP_ATOMIC); | 310 | resource = kmalloc(sizeof(*resource) + 1, irqs_disabled() ? GFP_ATOMIC: GFP_KERNEL); |
311 | if (!resource) | 311 | if (!resource) |
312 | return -ENOMEM; | 312 | return -ENOMEM; |
313 | 313 | ||
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index fec225d1b6b7..fe67a8af520e 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c | |||
@@ -216,10 +216,8 @@ static int acpi_power_off_device(acpi_handle handle) | |||
216 | { | 216 | { |
217 | int result = 0; | 217 | int result = 0; |
218 | acpi_status status = AE_OK; | 218 | acpi_status status = AE_OK; |
219 | struct acpi_device *device = NULL; | ||
220 | struct acpi_power_resource *resource = NULL; | 219 | struct acpi_power_resource *resource = NULL; |
221 | 220 | ||
222 | |||
223 | result = acpi_power_get_context(handle, &resource); | 221 | result = acpi_power_get_context(handle, &resource); |
224 | if (result) | 222 | if (result) |
225 | return result; | 223 | return result; |
@@ -230,13 +228,13 @@ static int acpi_power_off_device(acpi_handle handle) | |||
230 | if (resource->references) { | 228 | if (resource->references) { |
231 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 229 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
232 | "Resource [%s] is still in use, dereferencing\n", | 230 | "Resource [%s] is still in use, dereferencing\n", |
233 | device->pnp.bus_id)); | 231 | resource->device->pnp.bus_id)); |
234 | return 0; | 232 | return 0; |
235 | } | 233 | } |
236 | 234 | ||
237 | if (resource->state == ACPI_POWER_RESOURCE_STATE_OFF) { | 235 | if (resource->state == ACPI_POWER_RESOURCE_STATE_OFF) { |
238 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] already off\n", | 236 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] already off\n", |
239 | device->pnp.bus_id)); | 237 | resource->device->pnp.bus_id)); |
240 | return 0; | 238 | return 0; |
241 | } | 239 | } |
242 | 240 | ||
@@ -251,8 +249,7 @@ static int acpi_power_off_device(acpi_handle handle) | |||
251 | return -ENOEXEC; | 249 | return -ENOEXEC; |
252 | 250 | ||
253 | /* Update the power resource's _device_ power state */ | 251 | /* Update the power resource's _device_ power state */ |
254 | device = resource->device; | 252 | resource->device->power.state = ACPI_STATE_D3; |
255 | device->power.state = ACPI_STATE_D3; | ||
256 | 253 | ||
257 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] turned off\n", | 254 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] turned off\n", |
258 | resource->name)); | 255 | resource->name)); |
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index b13d64415b7a..1908e0d20222 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c | |||
@@ -519,7 +519,7 @@ static int acpi_processor_get_info(struct acpi_processor *pr) | |||
519 | 519 | ||
520 | static void *processor_device_array[NR_CPUS]; | 520 | static void *processor_device_array[NR_CPUS]; |
521 | 521 | ||
522 | static int acpi_processor_start(struct acpi_device *device) | 522 | static int __cpuinit acpi_processor_start(struct acpi_device *device) |
523 | { | 523 | { |
524 | int result = 0; | 524 | int result = 0; |
525 | acpi_status status = AE_OK; | 525 | acpi_status status = AE_OK; |
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 0a395fca843b..65b3f056ad89 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
@@ -219,6 +219,23 @@ static void acpi_safe_halt(void) | |||
219 | 219 | ||
220 | static atomic_t c3_cpu_count; | 220 | static atomic_t c3_cpu_count; |
221 | 221 | ||
222 | /* Common C-state entry for C2, C3, .. */ | ||
223 | static void acpi_cstate_enter(struct acpi_processor_cx *cstate) | ||
224 | { | ||
225 | if (cstate->space_id == ACPI_CSTATE_FFH) { | ||
226 | /* Call into architectural FFH based C-state */ | ||
227 | acpi_processor_ffh_cstate_enter(cstate); | ||
228 | } else { | ||
229 | int unused; | ||
230 | /* IO port based C-state */ | ||
231 | inb(cstate->address); | ||
232 | /* Dummy wait op - must do something useless after P_LVL2 read | ||
233 | because chipsets cannot guarantee that STPCLK# signal | ||
234 | gets asserted in time to freeze execution properly. */ | ||
235 | unused = inl(acpi_fadt.xpm_tmr_blk.address); | ||
236 | } | ||
237 | } | ||
238 | |||
222 | static void acpi_processor_idle(void) | 239 | static void acpi_processor_idle(void) |
223 | { | 240 | { |
224 | struct acpi_processor *pr = NULL; | 241 | struct acpi_processor *pr = NULL; |
@@ -361,11 +378,7 @@ static void acpi_processor_idle(void) | |||
361 | /* Get start time (ticks) */ | 378 | /* Get start time (ticks) */ |
362 | t1 = inl(acpi_fadt.xpm_tmr_blk.address); | 379 | t1 = inl(acpi_fadt.xpm_tmr_blk.address); |
363 | /* Invoke C2 */ | 380 | /* Invoke C2 */ |
364 | inb(cx->address); | 381 | acpi_cstate_enter(cx); |
365 | /* Dummy wait op - must do something useless after P_LVL2 read | ||
366 | because chipsets cannot guarantee that STPCLK# signal | ||
367 | gets asserted in time to freeze execution properly. */ | ||
368 | t2 = inl(acpi_fadt.xpm_tmr_blk.address); | ||
369 | /* Get end time (ticks) */ | 382 | /* Get end time (ticks) */ |
370 | t2 = inl(acpi_fadt.xpm_tmr_blk.address); | 383 | t2 = inl(acpi_fadt.xpm_tmr_blk.address); |
371 | 384 | ||
@@ -401,9 +414,7 @@ static void acpi_processor_idle(void) | |||
401 | /* Get start time (ticks) */ | 414 | /* Get start time (ticks) */ |
402 | t1 = inl(acpi_fadt.xpm_tmr_blk.address); | 415 | t1 = inl(acpi_fadt.xpm_tmr_blk.address); |
403 | /* Invoke C3 */ | 416 | /* Invoke C3 */ |
404 | inb(cx->address); | 417 | acpi_cstate_enter(cx); |
405 | /* Dummy wait op (see above) */ | ||
406 | t2 = inl(acpi_fadt.xpm_tmr_blk.address); | ||
407 | /* Get end time (ticks) */ | 418 | /* Get end time (ticks) */ |
408 | t2 = inl(acpi_fadt.xpm_tmr_blk.address); | 419 | t2 = inl(acpi_fadt.xpm_tmr_blk.address); |
409 | if (pr->flags.bm_check) { | 420 | if (pr->flags.bm_check) { |
@@ -628,20 +639,16 @@ static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr) | |||
628 | return 0; | 639 | return 0; |
629 | } | 640 | } |
630 | 641 | ||
631 | static int acpi_processor_get_power_info_default_c1(struct acpi_processor *pr) | 642 | static int acpi_processor_get_power_info_default(struct acpi_processor *pr) |
632 | { | 643 | { |
633 | 644 | if (!pr->power.states[ACPI_STATE_C1].valid) { | |
634 | /* Zero initialize all the C-states info. */ | 645 | /* set the first C-State to C1 */ |
635 | memset(pr->power.states, 0, sizeof(pr->power.states)); | 646 | /* all processors need to support C1 */ |
636 | 647 | pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1; | |
637 | /* set the first C-State to C1 */ | 648 | pr->power.states[ACPI_STATE_C1].valid = 1; |
638 | pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1; | 649 | } |
639 | 650 | /* the C0 state only exists as a filler in our array */ | |
640 | /* the C0 state only exists as a filler in our array, | ||
641 | * and all processors need to support C1 */ | ||
642 | pr->power.states[ACPI_STATE_C0].valid = 1; | 651 | pr->power.states[ACPI_STATE_C0].valid = 1; |
643 | pr->power.states[ACPI_STATE_C1].valid = 1; | ||
644 | |||
645 | return 0; | 652 | return 0; |
646 | } | 653 | } |
647 | 654 | ||
@@ -658,12 +665,7 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) | |||
658 | if (nocst) | 665 | if (nocst) |
659 | return -ENODEV; | 666 | return -ENODEV; |
660 | 667 | ||
661 | current_count = 1; | 668 | current_count = 0; |
662 | |||
663 | /* Zero initialize C2 onwards and prepare for fresh CST lookup */ | ||
664 | for (i = 2; i < ACPI_PROCESSOR_MAX_POWER; i++) | ||
665 | memset(&(pr->power.states[i]), 0, | ||
666 | sizeof(struct acpi_processor_cx)); | ||
667 | 669 | ||
668 | status = acpi_evaluate_object(pr->handle, "_CST", NULL, &buffer); | 670 | status = acpi_evaluate_object(pr->handle, "_CST", NULL, &buffer); |
669 | if (ACPI_FAILURE(status)) { | 671 | if (ACPI_FAILURE(status)) { |
@@ -718,22 +720,39 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) | |||
718 | (reg->space_id != ACPI_ADR_SPACE_FIXED_HARDWARE)) | 720 | (reg->space_id != ACPI_ADR_SPACE_FIXED_HARDWARE)) |
719 | continue; | 721 | continue; |
720 | 722 | ||
721 | cx.address = (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) ? | ||
722 | 0 : reg->address; | ||
723 | |||
724 | /* There should be an easy way to extract an integer... */ | 723 | /* There should be an easy way to extract an integer... */ |
725 | obj = (union acpi_object *)&(element->package.elements[1]); | 724 | obj = (union acpi_object *)&(element->package.elements[1]); |
726 | if (obj->type != ACPI_TYPE_INTEGER) | 725 | if (obj->type != ACPI_TYPE_INTEGER) |
727 | continue; | 726 | continue; |
728 | 727 | ||
729 | cx.type = obj->integer.value; | 728 | cx.type = obj->integer.value; |
730 | 729 | /* | |
731 | if ((cx.type != ACPI_STATE_C1) && | 730 | * Some buggy BIOSes won't list C1 in _CST - |
732 | (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO)) | 731 | * Let acpi_processor_get_power_info_default() handle them later |
733 | continue; | 732 | */ |
734 | 733 | if (i == 1 && cx.type != ACPI_STATE_C1) | |
735 | if ((cx.type < ACPI_STATE_C2) || (cx.type > ACPI_STATE_C3)) | 734 | current_count++; |
736 | continue; | 735 | |
736 | cx.address = reg->address; | ||
737 | cx.index = current_count + 1; | ||
738 | |||
739 | cx.space_id = ACPI_CSTATE_SYSTEMIO; | ||
740 | if (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) { | ||
741 | if (acpi_processor_ffh_cstate_probe | ||
742 | (pr->id, &cx, reg) == 0) { | ||
743 | cx.space_id = ACPI_CSTATE_FFH; | ||
744 | } else if (cx.type != ACPI_STATE_C1) { | ||
745 | /* | ||
746 | * C1 is a special case where FIXED_HARDWARE | ||
747 | * can be handled in non-MWAIT way as well. | ||
748 | * In that case, save this _CST entry info. | ||
749 | * That is, we retain space_id of SYSTEM_IO for | ||
750 | * halt based C1. | ||
751 | * Otherwise, ignore this info and continue. | ||
752 | */ | ||
753 | continue; | ||
754 | } | ||
755 | } | ||
737 | 756 | ||
738 | obj = (union acpi_object *)&(element->package.elements[2]); | 757 | obj = (union acpi_object *)&(element->package.elements[2]); |
739 | if (obj->type != ACPI_TYPE_INTEGER) | 758 | if (obj->type != ACPI_TYPE_INTEGER) |
@@ -938,11 +957,17 @@ static int acpi_processor_get_power_info(struct acpi_processor *pr) | |||
938 | /* NOTE: the idle thread may not be running while calling | 957 | /* NOTE: the idle thread may not be running while calling |
939 | * this function */ | 958 | * this function */ |
940 | 959 | ||
941 | /* Adding C1 state */ | 960 | /* Zero initialize all the C-states info. */ |
942 | acpi_processor_get_power_info_default_c1(pr); | 961 | memset(pr->power.states, 0, sizeof(pr->power.states)); |
962 | |||
943 | result = acpi_processor_get_power_info_cst(pr); | 963 | result = acpi_processor_get_power_info_cst(pr); |
944 | if (result == -ENODEV) | 964 | if (result == -ENODEV) |
945 | acpi_processor_get_power_info_fadt(pr); | 965 | result = acpi_processor_get_power_info_fadt(pr); |
966 | |||
967 | if (result) | ||
968 | return result; | ||
969 | |||
970 | acpi_processor_get_power_info_default(pr); | ||
946 | 971 | ||
947 | pr->power.count = acpi_processor_power_verify(pr); | 972 | pr->power.count = acpi_processor_power_verify(pr); |
948 | 973 | ||
@@ -1083,6 +1108,7 @@ static const struct file_operations acpi_processor_power_fops = { | |||
1083 | .release = single_release, | 1108 | .release = single_release, |
1084 | }; | 1109 | }; |
1085 | 1110 | ||
1111 | #ifdef CONFIG_SMP | ||
1086 | static void smp_callback(void *v) | 1112 | static void smp_callback(void *v) |
1087 | { | 1113 | { |
1088 | /* we already woke the CPU up, nothing more to do */ | 1114 | /* we already woke the CPU up, nothing more to do */ |
@@ -1104,8 +1130,9 @@ static int acpi_processor_latency_notify(struct notifier_block *b, | |||
1104 | static struct notifier_block acpi_processor_latency_notifier = { | 1130 | static struct notifier_block acpi_processor_latency_notifier = { |
1105 | .notifier_call = acpi_processor_latency_notify, | 1131 | .notifier_call = acpi_processor_latency_notify, |
1106 | }; | 1132 | }; |
1133 | #endif | ||
1107 | 1134 | ||
1108 | int acpi_processor_power_init(struct acpi_processor *pr, | 1135 | int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, |
1109 | struct acpi_device *device) | 1136 | struct acpi_device *device) |
1110 | { | 1137 | { |
1111 | acpi_status status = 0; | 1138 | acpi_status status = 0; |
@@ -1121,7 +1148,9 @@ int acpi_processor_power_init(struct acpi_processor *pr, | |||
1121 | "ACPI: processor limited to max C-state %d\n", | 1148 | "ACPI: processor limited to max C-state %d\n", |
1122 | max_cstate); | 1149 | max_cstate); |
1123 | first_run++; | 1150 | first_run++; |
1151 | #ifdef CONFIG_SMP | ||
1124 | register_latency_notifier(&acpi_processor_latency_notifier); | 1152 | register_latency_notifier(&acpi_processor_latency_notifier); |
1153 | #endif | ||
1125 | } | 1154 | } |
1126 | 1155 | ||
1127 | if (!pr) | 1156 | if (!pr) |
@@ -1193,7 +1222,9 @@ int acpi_processor_power_exit(struct acpi_processor *pr, | |||
1193 | * copies of pm_idle before proceeding. | 1222 | * copies of pm_idle before proceeding. |
1194 | */ | 1223 | */ |
1195 | cpu_idle_wait(); | 1224 | cpu_idle_wait(); |
1225 | #ifdef CONFIG_SMP | ||
1196 | unregister_latency_notifier(&acpi_processor_latency_notifier); | 1226 | unregister_latency_notifier(&acpi_processor_latency_notifier); |
1227 | #endif | ||
1197 | } | 1228 | } |
1198 | 1229 | ||
1199 | return 0; | 1230 | return 0; |
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index 62bef0b3b614..8908a975e575 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c | |||
@@ -98,11 +98,11 @@ static int update_info_mode = UPDATE_INFO_MODE; | |||
98 | static int update_time = UPDATE_TIME; | 98 | static int update_time = UPDATE_TIME; |
99 | static int update_time2 = UPDATE_TIME2; | 99 | static int update_time2 = UPDATE_TIME2; |
100 | 100 | ||
101 | module_param(capacity_mode, int, CAPACITY_UNIT); | 101 | module_param(capacity_mode, int, 0); |
102 | module_param(update_mode, int, UPDATE_MODE); | 102 | module_param(update_mode, int, 0); |
103 | module_param(update_info_mode, int, UPDATE_INFO_MODE); | 103 | module_param(update_info_mode, int, 0); |
104 | module_param(update_time, int, UPDATE_TIME); | 104 | module_param(update_time, int, 0); |
105 | module_param(update_time2, int, UPDATE_TIME2); | 105 | module_param(update_time2, int, 0); |
106 | 106 | ||
107 | static int acpi_sbs_add(struct acpi_device *device); | 107 | static int acpi_sbs_add(struct acpi_device *device); |
108 | static int acpi_sbs_remove(struct acpi_device *device, int type); | 108 | static int acpi_sbs_remove(struct acpi_device *device, int type); |
@@ -1685,10 +1685,16 @@ static int acpi_sbs_add(struct acpi_device *device) | |||
1685 | 1685 | ||
1686 | int acpi_sbs_remove(struct acpi_device *device, int type) | 1686 | int acpi_sbs_remove(struct acpi_device *device, int type) |
1687 | { | 1687 | { |
1688 | struct acpi_sbs *sbs = (struct acpi_sbs *)acpi_driver_data(device); | 1688 | struct acpi_sbs *sbs = NULL; |
1689 | int id; | 1689 | int id; |
1690 | 1690 | ||
1691 | if (!device || !sbs) { | 1691 | if (!device) { |
1692 | return -EINVAL; | ||
1693 | } | ||
1694 | |||
1695 | sbs = (struct acpi_sbs *)acpi_driver_data(device); | ||
1696 | |||
1697 | if (!sbs) { | ||
1692 | return -EINVAL; | 1698 | return -EINVAL; |
1693 | } | 1699 | } |
1694 | 1700 | ||
diff --git a/drivers/acpi/tables/tbget.c b/drivers/acpi/tables/tbget.c index 7856db759af0..11e2d4454e05 100644 --- a/drivers/acpi/tables/tbget.c +++ b/drivers/acpi/tables/tbget.c | |||
@@ -324,7 +324,7 @@ acpi_tb_get_this_table(struct acpi_pointer *address, | |||
324 | 324 | ||
325 | if (header->length < sizeof(struct acpi_table_header)) { | 325 | if (header->length < sizeof(struct acpi_table_header)) { |
326 | ACPI_ERROR((AE_INFO, | 326 | ACPI_ERROR((AE_INFO, |
327 | "Table length (%X) is smaller than minimum (%X)", | 327 | "Table length (%X) is smaller than minimum (%zX)", |
328 | header->length, sizeof(struct acpi_table_header))); | 328 | header->length, sizeof(struct acpi_table_header))); |
329 | 329 | ||
330 | return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH); | 330 | return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH); |
diff --git a/drivers/acpi/tables/tbrsdt.c b/drivers/acpi/tables/tbrsdt.c index 0ad3dbb9ebca..86a5fca9b739 100644 --- a/drivers/acpi/tables/tbrsdt.c +++ b/drivers/acpi/tables/tbrsdt.c | |||
@@ -187,7 +187,7 @@ acpi_status acpi_tb_validate_rsdt(struct acpi_table_header *table_ptr) | |||
187 | 187 | ||
188 | if (table_ptr->length < sizeof(struct acpi_table_header)) { | 188 | if (table_ptr->length < sizeof(struct acpi_table_header)) { |
189 | ACPI_ERROR((AE_INFO, | 189 | ACPI_ERROR((AE_INFO, |
190 | "RSDT/XSDT length (%X) is smaller than minimum (%X)", | 190 | "RSDT/XSDT length (%X) is smaller than minimum (%zX)", |
191 | table_ptr->length, | 191 | table_ptr->length, |
192 | sizeof(struct acpi_table_header))); | 192 | sizeof(struct acpi_table_header))); |
193 | 193 | ||
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 3f4aa0c99ee4..03f6338acc8f 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig | |||
@@ -6,6 +6,7 @@ menu "Serial ATA (prod) and Parallel ATA (experimental) drivers" | |||
6 | 6 | ||
7 | config ATA | 7 | config ATA |
8 | tristate "ATA device support" | 8 | tristate "ATA device support" |
9 | depends on BLOCK | ||
9 | depends on !(M32R || M68K) || BROKEN | 10 | depends on !(M32R || M68K) || BROKEN |
10 | depends on !SUN4 || BROKEN | 11 | depends on !SUN4 || BROKEN |
11 | select SCSI | 12 | select SCSI |
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 25929123ffff..234197e57e9e 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -334,6 +334,14 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
334 | { PCI_VDEVICE(NVIDIA, 0x044d), board_ahci }, /* MCP65 */ | 334 | { PCI_VDEVICE(NVIDIA, 0x044d), board_ahci }, /* MCP65 */ |
335 | { PCI_VDEVICE(NVIDIA, 0x044e), board_ahci }, /* MCP65 */ | 335 | { PCI_VDEVICE(NVIDIA, 0x044e), board_ahci }, /* MCP65 */ |
336 | { PCI_VDEVICE(NVIDIA, 0x044f), board_ahci }, /* MCP65 */ | 336 | { PCI_VDEVICE(NVIDIA, 0x044f), board_ahci }, /* MCP65 */ |
337 | { PCI_VDEVICE(NVIDIA, 0x0554), board_ahci }, /* MCP67 */ | ||
338 | { PCI_VDEVICE(NVIDIA, 0x0555), board_ahci }, /* MCP67 */ | ||
339 | { PCI_VDEVICE(NVIDIA, 0x0556), board_ahci }, /* MCP67 */ | ||
340 | { PCI_VDEVICE(NVIDIA, 0x0557), board_ahci }, /* MCP67 */ | ||
341 | { PCI_VDEVICE(NVIDIA, 0x0558), board_ahci }, /* MCP67 */ | ||
342 | { PCI_VDEVICE(NVIDIA, 0x0559), board_ahci }, /* MCP67 */ | ||
343 | { PCI_VDEVICE(NVIDIA, 0x055a), board_ahci }, /* MCP67 */ | ||
344 | { PCI_VDEVICE(NVIDIA, 0x055b), board_ahci }, /* MCP67 */ | ||
337 | 345 | ||
338 | /* SiS */ | 346 | /* SiS */ |
339 | { PCI_VDEVICE(SI, 0x1184), board_ahci }, /* SiS 966 */ | 347 | { PCI_VDEVICE(SI, 0x1184), board_ahci }, /* SiS 966 */ |
@@ -736,8 +744,7 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class) | |||
736 | } | 744 | } |
737 | 745 | ||
738 | /* check BUSY/DRQ, perform Command List Override if necessary */ | 746 | /* check BUSY/DRQ, perform Command List Override if necessary */ |
739 | ahci_tf_read(ap, &tf); | 747 | if (ahci_check_status(ap) & (ATA_BUSY | ATA_DRQ)) { |
740 | if (tf.command & (ATA_BUSY | ATA_DRQ)) { | ||
741 | rc = ahci_clo(ap); | 748 | rc = ahci_clo(ap); |
742 | 749 | ||
743 | if (rc == -EOPNOTSUPP) { | 750 | if (rc == -EOPNOTSUPP) { |
@@ -1041,7 +1048,7 @@ static void ahci_host_intr(struct ata_port *ap) | |||
1041 | /* hmmm... a spurious interupt */ | 1048 | /* hmmm... a spurious interupt */ |
1042 | 1049 | ||
1043 | /* some devices send D2H reg with I bit set during NCQ command phase */ | 1050 | /* some devices send D2H reg with I bit set during NCQ command phase */ |
1044 | if (ap->sactive && status & PORT_IRQ_D2H_REG_FIS) | 1051 | if (ap->sactive && (status & PORT_IRQ_D2H_REG_FIS)) |
1045 | return; | 1052 | return; |
1046 | 1053 | ||
1047 | /* ignore interim PIO setup fis interrupts */ | 1054 | /* ignore interim PIO setup fis interrupts */ |
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 5719704eb0ee..720174d628fa 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c | |||
@@ -126,8 +126,7 @@ enum { | |||
126 | ich6_sata = 7, | 126 | ich6_sata = 7, |
127 | ich6_sata_ahci = 8, | 127 | ich6_sata_ahci = 8, |
128 | ich6m_sata_ahci = 9, | 128 | ich6m_sata_ahci = 9, |
129 | ich7m_sata_ahci = 10, | 129 | ich8_sata_ahci = 10, |
130 | ich8_sata_ahci = 11, | ||
131 | 130 | ||
132 | /* constants for mapping table */ | 131 | /* constants for mapping table */ |
133 | P0 = 0, /* port 0 */ | 132 | P0 = 0, /* port 0 */ |
@@ -227,7 +226,7 @@ static const struct pci_device_id piix_pci_tbl[] = { | |||
227 | /* 82801GB/GR/GH (ICH7, identical to ICH6) */ | 226 | /* 82801GB/GR/GH (ICH7, identical to ICH6) */ |
228 | { 0x8086, 0x27c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci }, | 227 | { 0x8086, 0x27c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci }, |
229 | /* 2801GBM/GHM (ICH7M, identical to ICH6M) */ | 228 | /* 2801GBM/GHM (ICH7M, identical to ICH6M) */ |
230 | { 0x8086, 0x27c4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich7m_sata_ahci }, | 229 | { 0x8086, 0x27c4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6m_sata_ahci }, |
231 | /* Enterprise Southbridge 2 (where's the datasheet?) */ | 230 | /* Enterprise Southbridge 2 (where's the datasheet?) */ |
232 | { 0x8086, 0x2680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci }, | 231 | { 0x8086, 0x2680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci }, |
233 | /* SATA Controller 1 IDE (ICH8, no datasheet yet) */ | 232 | /* SATA Controller 1 IDE (ICH8, no datasheet yet) */ |
@@ -399,23 +398,10 @@ static const struct piix_map_db ich6m_map_db = { | |||
399 | .mask = 0x3, | 398 | .mask = 0x3, |
400 | .port_enable = 0x5, | 399 | .port_enable = 0x5, |
401 | .present_shift = 4, | 400 | .present_shift = 4, |
402 | .map = { | ||
403 | /* PM PS SM SS MAP */ | ||
404 | { P0, P2, RV, RV }, /* 00b */ | ||
405 | { RV, RV, RV, RV }, | ||
406 | { P0, P2, IDE, IDE }, /* 10b */ | ||
407 | { RV, RV, RV, RV }, | ||
408 | }, | ||
409 | }; | ||
410 | |||
411 | static const struct piix_map_db ich7m_map_db = { | ||
412 | .mask = 0x3, | ||
413 | .port_enable = 0x5, | ||
414 | .present_shift = 4, | ||
415 | 401 | ||
416 | /* Map 01b isn't specified in the doc but some notebooks use | 402 | /* Map 01b isn't specified in the doc but some notebooks use |
417 | * it anyway. ATM, the only case spotted carries subsystem ID | 403 | * it anyway. MAP 01b have been spotted on both ICH6M and |
418 | * 1025:0107. This is the only difference from ich6m. | 404 | * ICH7M. |
419 | */ | 405 | */ |
420 | .map = { | 406 | .map = { |
421 | /* PM PS SM SS MAP */ | 407 | /* PM PS SM SS MAP */ |
@@ -432,9 +418,9 @@ static const struct piix_map_db ich8_map_db = { | |||
432 | .present_shift = 8, | 418 | .present_shift = 8, |
433 | .map = { | 419 | .map = { |
434 | /* PM PS SM SS MAP */ | 420 | /* PM PS SM SS MAP */ |
435 | { P0, NA, P1, NA }, /* 00b (hardwired) */ | 421 | { P0, P2, P1, P3 }, /* 00b (hardwired when in AHCI) */ |
436 | { RV, RV, RV, RV }, | 422 | { RV, RV, RV, RV }, |
437 | { RV, RV, RV, RV }, /* 10b (never) */ | 423 | { IDE, IDE, NA, NA }, /* 10b (IDE mode) */ |
438 | { RV, RV, RV, RV }, | 424 | { RV, RV, RV, RV }, |
439 | }, | 425 | }, |
440 | }; | 426 | }; |
@@ -445,7 +431,6 @@ static const struct piix_map_db *piix_map_db_table[] = { | |||
445 | [ich6_sata] = &ich6_map_db, | 431 | [ich6_sata] = &ich6_map_db, |
446 | [ich6_sata_ahci] = &ich6_map_db, | 432 | [ich6_sata_ahci] = &ich6_map_db, |
447 | [ich6m_sata_ahci] = &ich6m_map_db, | 433 | [ich6m_sata_ahci] = &ich6m_map_db, |
448 | [ich7m_sata_ahci] = &ich7m_map_db, | ||
449 | [ich8_sata_ahci] = &ich8_map_db, | 434 | [ich8_sata_ahci] = &ich8_map_db, |
450 | }; | 435 | }; |
451 | 436 | ||
@@ -556,19 +541,7 @@ static struct ata_port_info piix_port_info[] = { | |||
556 | .port_ops = &piix_sata_ops, | 541 | .port_ops = &piix_sata_ops, |
557 | }, | 542 | }, |
558 | 543 | ||
559 | /* ich7m_sata_ahci: 10 */ | 544 | /* ich8_sata_ahci: 10 */ |
560 | { | ||
561 | .sht = &piix_sht, | ||
562 | .flags = ATA_FLAG_SATA | | ||
563 | PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR | | ||
564 | PIIX_FLAG_AHCI, | ||
565 | .pio_mask = 0x1f, /* pio0-4 */ | ||
566 | .mwdma_mask = 0x07, /* mwdma0-2 */ | ||
567 | .udma_mask = 0x7f, /* udma0-6 */ | ||
568 | .port_ops = &piix_sata_ops, | ||
569 | }, | ||
570 | |||
571 | /* ich8_sata_ahci: 11 */ | ||
572 | { | 545 | { |
573 | .sht = &piix_sht, | 546 | .sht = &piix_sht, |
574 | .flags = ATA_FLAG_SATA | | 547 | .flags = ATA_FLAG_SATA | |
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 77138a39eb04..915a55a6cc14 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -870,7 +870,11 @@ static unsigned int ata_id_xfermask(const u16 *id) | |||
870 | * the PIO timing number for the maximum. Turn it into | 870 | * the PIO timing number for the maximum. Turn it into |
871 | * a mask. | 871 | * a mask. |
872 | */ | 872 | */ |
873 | pio_mask = (2 << (id[ATA_ID_OLD_PIO_MODES] & 0xFF)) - 1 ; | 873 | u8 mode = id[ATA_ID_OLD_PIO_MODES] & 0xFF; |
874 | if (mode < 5) /* Valid PIO range */ | ||
875 | pio_mask = (2 << mode) - 1; | ||
876 | else | ||
877 | pio_mask = 1; | ||
874 | 878 | ||
875 | /* But wait.. there's more. Design your standards by | 879 | /* But wait.. there's more. Design your standards by |
876 | * committee and you too can get a free iordy field to | 880 | * committee and you too can get a free iordy field to |
@@ -5953,7 +5957,7 @@ static void __exit ata_exit(void) | |||
5953 | destroy_workqueue(ata_aux_wq); | 5957 | destroy_workqueue(ata_aux_wq); |
5954 | } | 5958 | } |
5955 | 5959 | ||
5956 | module_init(ata_init); | 5960 | subsys_initcall(ata_init); |
5957 | module_exit(ata_exit); | 5961 | module_exit(ata_exit); |
5958 | 5962 | ||
5959 | static unsigned long ratelimit_time; | 5963 | static unsigned long ratelimit_time; |
@@ -6118,7 +6122,6 @@ EXPORT_SYMBOL_GPL(ata_std_prereset); | |||
6118 | EXPORT_SYMBOL_GPL(ata_std_softreset); | 6122 | EXPORT_SYMBOL_GPL(ata_std_softreset); |
6119 | EXPORT_SYMBOL_GPL(sata_std_hardreset); | 6123 | EXPORT_SYMBOL_GPL(sata_std_hardreset); |
6120 | EXPORT_SYMBOL_GPL(ata_std_postreset); | 6124 | EXPORT_SYMBOL_GPL(ata_std_postreset); |
6121 | EXPORT_SYMBOL_GPL(ata_dev_revalidate); | ||
6122 | EXPORT_SYMBOL_GPL(ata_dev_classify); | 6125 | EXPORT_SYMBOL_GPL(ata_dev_classify); |
6123 | EXPORT_SYMBOL_GPL(ata_dev_pair); | 6126 | EXPORT_SYMBOL_GPL(ata_dev_pair); |
6124 | EXPORT_SYMBOL_GPL(ata_port_disable); | 6127 | EXPORT_SYMBOL_GPL(ata_port_disable); |
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index b0d0cc41f3e8..5c1fc467fc7f 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c | |||
@@ -164,10 +164,10 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg) | |||
164 | { | 164 | { |
165 | int rc = 0; | 165 | int rc = 0; |
166 | u8 scsi_cmd[MAX_COMMAND_SIZE]; | 166 | u8 scsi_cmd[MAX_COMMAND_SIZE]; |
167 | u8 args[4], *argbuf = NULL; | 167 | u8 args[4], *argbuf = NULL, *sensebuf = NULL; |
168 | int argsize = 0; | 168 | int argsize = 0; |
169 | struct scsi_sense_hdr sshdr; | ||
170 | enum dma_data_direction data_dir; | 169 | enum dma_data_direction data_dir; |
170 | int cmd_result; | ||
171 | 171 | ||
172 | if (arg == NULL) | 172 | if (arg == NULL) |
173 | return -EINVAL; | 173 | return -EINVAL; |
@@ -175,6 +175,10 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg) | |||
175 | if (copy_from_user(args, arg, sizeof(args))) | 175 | if (copy_from_user(args, arg, sizeof(args))) |
176 | return -EFAULT; | 176 | return -EFAULT; |
177 | 177 | ||
178 | sensebuf = kzalloc(SCSI_SENSE_BUFFERSIZE, GFP_NOIO); | ||
179 | if (!sensebuf) | ||
180 | return -ENOMEM; | ||
181 | |||
178 | memset(scsi_cmd, 0, sizeof(scsi_cmd)); | 182 | memset(scsi_cmd, 0, sizeof(scsi_cmd)); |
179 | 183 | ||
180 | if (args[3]) { | 184 | if (args[3]) { |
@@ -191,7 +195,7 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg) | |||
191 | data_dir = DMA_FROM_DEVICE; | 195 | data_dir = DMA_FROM_DEVICE; |
192 | } else { | 196 | } else { |
193 | scsi_cmd[1] = (3 << 1); /* Non-data */ | 197 | scsi_cmd[1] = (3 << 1); /* Non-data */ |
194 | /* scsi_cmd[2] is already 0 -- no off.line, cc, or data xfer */ | 198 | scsi_cmd[2] = 0x20; /* cc but no off.line or data xfer */ |
195 | data_dir = DMA_NONE; | 199 | data_dir = DMA_NONE; |
196 | } | 200 | } |
197 | 201 | ||
@@ -210,18 +214,46 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg) | |||
210 | 214 | ||
211 | /* Good values for timeout and retries? Values below | 215 | /* Good values for timeout and retries? Values below |
212 | from scsi_ioctl_send_command() for default case... */ | 216 | from scsi_ioctl_send_command() for default case... */ |
213 | if (scsi_execute_req(scsidev, scsi_cmd, data_dir, argbuf, argsize, | 217 | cmd_result = scsi_execute(scsidev, scsi_cmd, data_dir, argbuf, argsize, |
214 | &sshdr, (10*HZ), 5)) { | 218 | sensebuf, (10*HZ), 5, 0); |
219 | |||
220 | if (driver_byte(cmd_result) == DRIVER_SENSE) {/* sense data available */ | ||
221 | u8 *desc = sensebuf + 8; | ||
222 | cmd_result &= ~(0xFF<<24); /* DRIVER_SENSE is not an error */ | ||
223 | |||
224 | /* If we set cc then ATA pass-through will cause a | ||
225 | * check condition even if no error. Filter that. */ | ||
226 | if (cmd_result & SAM_STAT_CHECK_CONDITION) { | ||
227 | struct scsi_sense_hdr sshdr; | ||
228 | scsi_normalize_sense(sensebuf, SCSI_SENSE_BUFFERSIZE, | ||
229 | &sshdr); | ||
230 | if (sshdr.sense_key==0 && | ||
231 | sshdr.asc==0 && sshdr.ascq==0) | ||
232 | cmd_result &= ~SAM_STAT_CHECK_CONDITION; | ||
233 | } | ||
234 | |||
235 | /* Send userspace a few ATA registers (same as drivers/ide) */ | ||
236 | if (sensebuf[0] == 0x72 && /* format is "descriptor" */ | ||
237 | desc[0] == 0x09 ) { /* code is "ATA Descriptor" */ | ||
238 | args[0] = desc[13]; /* status */ | ||
239 | args[1] = desc[3]; /* error */ | ||
240 | args[2] = desc[5]; /* sector count (0:7) */ | ||
241 | if (copy_to_user(arg, args, sizeof(args))) | ||
242 | rc = -EFAULT; | ||
243 | } | ||
244 | } | ||
245 | |||
246 | |||
247 | if (cmd_result) { | ||
215 | rc = -EIO; | 248 | rc = -EIO; |
216 | goto error; | 249 | goto error; |
217 | } | 250 | } |
218 | 251 | ||
219 | /* Need code to retrieve data from check condition? */ | ||
220 | |||
221 | if ((argbuf) | 252 | if ((argbuf) |
222 | && copy_to_user(arg + sizeof(args), argbuf, argsize)) | 253 | && copy_to_user(arg + sizeof(args), argbuf, argsize)) |
223 | rc = -EFAULT; | 254 | rc = -EFAULT; |
224 | error: | 255 | error: |
256 | kfree(sensebuf); | ||
225 | kfree(argbuf); | 257 | kfree(argbuf); |
226 | return rc; | 258 | return rc; |
227 | } | 259 | } |
@@ -1580,9 +1612,9 @@ early_finish: | |||
1580 | 1612 | ||
1581 | err_did: | 1613 | err_did: |
1582 | ata_qc_free(qc); | 1614 | ata_qc_free(qc); |
1583 | err_mem: | ||
1584 | cmd->result = (DID_ERROR << 16); | 1615 | cmd->result = (DID_ERROR << 16); |
1585 | done(cmd); | 1616 | done(cmd); |
1617 | err_mem: | ||
1586 | DPRINTK("EXIT - internal\n"); | 1618 | DPRINTK("EXIT - internal\n"); |
1587 | return 0; | 1619 | return 0; |
1588 | 1620 | ||
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 06daaa3736a2..7645f2b30ccf 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c | |||
@@ -981,6 +981,15 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, | |||
981 | mask = (1 << 2) | (1 << 0); | 981 | mask = (1 << 2) | (1 << 0); |
982 | if ((tmp8 & mask) != mask) | 982 | if ((tmp8 & mask) != mask) |
983 | legacy_mode = (1 << 3); | 983 | legacy_mode = (1 << 3); |
984 | #if defined(CONFIG_NO_ATA_LEGACY) | ||
985 | /* Some platforms with PCI limits cannot address compat | ||
986 | port space. In that case we punt if their firmware has | ||
987 | left a device in compatibility mode */ | ||
988 | if (legacy_mode) { | ||
989 | printk(KERN_ERR "ata: Compatibility mode ATA is not supported on this platform, skipping.\n"); | ||
990 | return -EOPNOTSUPP; | ||
991 | } | ||
992 | #endif | ||
984 | } | 993 | } |
985 | 994 | ||
986 | rc = pci_request_regions(pdev, DRV_NAME); | 995 | rc = pci_request_regions(pdev, DRV_NAME); |
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index a5ecb71390a9..0ed263be652a 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h | |||
@@ -53,6 +53,7 @@ extern unsigned ata_exec_internal(struct ata_device *dev, | |||
53 | extern unsigned int ata_do_simple_cmd(struct ata_device *dev, u8 cmd); | 53 | extern unsigned int ata_do_simple_cmd(struct ata_device *dev, u8 cmd); |
54 | extern int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, | 54 | extern int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, |
55 | int post_reset, u16 *id); | 55 | int post_reset, u16 *id); |
56 | extern int ata_dev_revalidate(struct ata_device *dev, int post_reset); | ||
56 | extern int ata_dev_configure(struct ata_device *dev, int print_info); | 57 | extern int ata_dev_configure(struct ata_device *dev, int print_info); |
57 | extern int sata_down_spd_limit(struct ata_port *ap); | 58 | extern int sata_down_spd_limit(struct ata_port *ap); |
58 | extern int sata_set_spd_needed(struct ata_port *ap); | 59 | extern int sata_set_spd_needed(struct ata_port *ap); |
diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c index 29234c897118..5c47a9e0e0ca 100644 --- a/drivers/ata/pata_amd.c +++ b/drivers/ata/pata_amd.c | |||
@@ -677,6 +677,8 @@ static const struct pci_device_id amd[] = { | |||
677 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE), 8 }, | 677 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE), 8 }, |
678 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE), 8 }, | 678 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE), 8 }, |
679 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE), 8 }, | 679 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE), 8 }, |
680 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE), 8 }, | ||
681 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE), 8 }, | ||
680 | { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_CS5536_IDE), 9 }, | 682 | { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_CS5536_IDE), 9 }, |
681 | 683 | ||
682 | { }, | 684 | { }, |
diff --git a/drivers/ata/pata_artop.c b/drivers/ata/pata_artop.c index 690828eb5226..96a098020a8f 100644 --- a/drivers/ata/pata_artop.c +++ b/drivers/ata/pata_artop.c | |||
@@ -92,7 +92,7 @@ static int artop6260_pre_reset(struct ata_port *ap) | |||
92 | return -ENOENT; | 92 | return -ENOENT; |
93 | 93 | ||
94 | pci_read_config_byte(pdev, 0x49, &tmp); | 94 | pci_read_config_byte(pdev, 0x49, &tmp); |
95 | if (tmp & (1 >> ap->port_no)) | 95 | if (tmp & (1 << ap->port_no)) |
96 | ap->cbl = ATA_CBL_PATA40; | 96 | ap->cbl = ATA_CBL_PATA40; |
97 | else | 97 | else |
98 | ap->cbl = ATA_CBL_PATA80; | 98 | ap->cbl = ATA_CBL_PATA80; |
diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c index 7350443948c1..fce3fcdc7e79 100644 --- a/drivers/ata/pata_hpt37x.c +++ b/drivers/ata/pata_hpt37x.c | |||
@@ -25,7 +25,7 @@ | |||
25 | #include <linux/libata.h> | 25 | #include <linux/libata.h> |
26 | 26 | ||
27 | #define DRV_NAME "pata_hpt37x" | 27 | #define DRV_NAME "pata_hpt37x" |
28 | #define DRV_VERSION "0.5" | 28 | #define DRV_VERSION "0.5.1" |
29 | 29 | ||
30 | struct hpt_clock { | 30 | struct hpt_clock { |
31 | u8 xfer_speed; | 31 | u8 xfer_speed; |
@@ -453,7 +453,13 @@ static int hpt37x_pre_reset(struct ata_port *ap) | |||
453 | { | 453 | { |
454 | u8 scr2, ata66; | 454 | u8 scr2, ata66; |
455 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); | 455 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); |
456 | 456 | static const struct pci_bits hpt37x_enable_bits[] = { | |
457 | { 0x50, 1, 0x04, 0x04 }, | ||
458 | { 0x54, 1, 0x04, 0x04 } | ||
459 | }; | ||
460 | if (!pci_test_config_bits(pdev, &hpt37x_enable_bits[ap->port_no])) | ||
461 | return -ENOENT; | ||
462 | |||
457 | pci_read_config_byte(pdev, 0x5B, &scr2); | 463 | pci_read_config_byte(pdev, 0x5B, &scr2); |
458 | pci_write_config_byte(pdev, 0x5B, scr2 & ~0x01); | 464 | pci_write_config_byte(pdev, 0x5B, scr2 & ~0x01); |
459 | /* Cable register now active */ | 465 | /* Cable register now active */ |
@@ -488,10 +494,17 @@ static void hpt37x_error_handler(struct ata_port *ap) | |||
488 | 494 | ||
489 | static int hpt374_pre_reset(struct ata_port *ap) | 495 | static int hpt374_pre_reset(struct ata_port *ap) |
490 | { | 496 | { |
497 | static const struct pci_bits hpt37x_enable_bits[] = { | ||
498 | { 0x50, 1, 0x04, 0x04 }, | ||
499 | { 0x54, 1, 0x04, 0x04 } | ||
500 | }; | ||
491 | u16 mcr3, mcr6; | 501 | u16 mcr3, mcr6; |
492 | u8 ata66; | 502 | u8 ata66; |
493 | |||
494 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); | 503 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); |
504 | |||
505 | if (!pci_test_config_bits(pdev, &hpt37x_enable_bits[ap->port_no])) | ||
506 | return -ENOENT; | ||
507 | |||
495 | /* Do the extra channel work */ | 508 | /* Do the extra channel work */ |
496 | pci_read_config_word(pdev, 0x52, &mcr3); | 509 | pci_read_config_word(pdev, 0x52, &mcr3); |
497 | pci_read_config_word(pdev, 0x56, &mcr6); | 510 | pci_read_config_word(pdev, 0x56, &mcr6); |
diff --git a/drivers/ata/pata_qdi.c b/drivers/ata/pata_qdi.c index 7977f471d5e9..2c3cc0ccc606 100644 --- a/drivers/ata/pata_qdi.c +++ b/drivers/ata/pata_qdi.c | |||
@@ -141,7 +141,7 @@ static void qdi_data_xfer(struct ata_device *adev, unsigned char *buf, unsigned | |||
141 | memcpy(&pad, buf + buflen - slop, slop); | 141 | memcpy(&pad, buf + buflen - slop, slop); |
142 | outl(le32_to_cpu(pad), ap->ioaddr.data_addr); | 142 | outl(le32_to_cpu(pad), ap->ioaddr.data_addr); |
143 | } else { | 143 | } else { |
144 | pad = cpu_to_le16(inl(ap->ioaddr.data_addr)); | 144 | pad = cpu_to_le32(inl(ap->ioaddr.data_addr)); |
145 | memcpy(buf + buflen - slop, &pad, slop); | 145 | memcpy(buf + buflen - slop, &pad, slop); |
146 | } | 146 | } |
147 | } | 147 | } |
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index 323b60710806..d65ebfd7c7b2 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c | |||
@@ -117,10 +117,14 @@ static const struct pci_device_id nv_pci_tbl[] = { | |||
117 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA), GENERIC }, | 117 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA), GENERIC }, |
118 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA2), GENERIC }, | 118 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA2), GENERIC }, |
119 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA3), GENERIC }, | 119 | { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA3), GENERIC }, |
120 | { PCI_VDEVICE(NVIDIA, 0x045c), GENERIC }, | 120 | { PCI_VDEVICE(NVIDIA, 0x045c), GENERIC }, /* MCP65 */ |
121 | { PCI_VDEVICE(NVIDIA, 0x045d), GENERIC }, | 121 | { PCI_VDEVICE(NVIDIA, 0x045d), GENERIC }, /* MCP65 */ |
122 | { PCI_VDEVICE(NVIDIA, 0x045e), GENERIC }, | 122 | { PCI_VDEVICE(NVIDIA, 0x045e), GENERIC }, /* MCP65 */ |
123 | { PCI_VDEVICE(NVIDIA, 0x045f), GENERIC }, | 123 | { PCI_VDEVICE(NVIDIA, 0x045f), GENERIC }, /* MCP65 */ |
124 | { PCI_VDEVICE(NVIDIA, 0x0550), GENERIC }, /* MCP67 */ | ||
125 | { PCI_VDEVICE(NVIDIA, 0x0551), GENERIC }, /* MCP67 */ | ||
126 | { PCI_VDEVICE(NVIDIA, 0x0552), GENERIC }, /* MCP67 */ | ||
127 | { PCI_VDEVICE(NVIDIA, 0x0553), GENERIC }, /* MCP67 */ | ||
124 | { PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, | 128 | { PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, |
125 | PCI_ANY_ID, PCI_ANY_ID, | 129 | PCI_ANY_ID, PCI_ANY_ID, |
126 | PCI_CLASS_STORAGE_IDE<<8, 0xffff00, GENERIC }, | 130 | PCI_CLASS_STORAGE_IDE<<8, 0xffff00, GENERIC }, |
diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c index 8bcdfa64667c..72eda5160fad 100644 --- a/drivers/ata/sata_promise.c +++ b/drivers/ata/sata_promise.c | |||
@@ -260,6 +260,7 @@ static const struct pci_device_id pdc_ata_pci_tbl[] = { | |||
260 | #if 0 | 260 | #if 0 |
261 | { PCI_VDEVICE(PROMISE, 0x3570), board_20771 }, | 261 | { PCI_VDEVICE(PROMISE, 0x3570), board_20771 }, |
262 | #endif | 262 | #endif |
263 | { PCI_VDEVICE(PROMISE, 0x3577), board_20771 }, | ||
263 | 264 | ||
264 | { } /* terminate list */ | 265 | { } /* terminate list */ |
265 | }; | 266 | }; |
diff --git a/drivers/ata/sata_sis.c b/drivers/ata/sata_sis.c index 0738f52463a9..9d1235ba06b1 100644 --- a/drivers/ata/sata_sis.c +++ b/drivers/ata/sata_sis.c | |||
@@ -240,7 +240,7 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
240 | struct ata_probe_ent *probe_ent = NULL; | 240 | struct ata_probe_ent *probe_ent = NULL; |
241 | int rc; | 241 | int rc; |
242 | u32 genctl; | 242 | u32 genctl; |
243 | struct ata_port_info *ppi[2]; | 243 | struct ata_port_info pi = sis_port_info, *ppi[2] = { &pi, &pi }; |
244 | int pci_dev_busy = 0; | 244 | int pci_dev_busy = 0; |
245 | u8 pmr; | 245 | u8 pmr; |
246 | u8 port2_start; | 246 | u8 port2_start; |
@@ -265,27 +265,20 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
265 | if (rc) | 265 | if (rc) |
266 | goto err_out_regions; | 266 | goto err_out_regions; |
267 | 267 | ||
268 | ppi[0] = ppi[1] = &sis_port_info; | ||
269 | probe_ent = ata_pci_init_native_mode(pdev, ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY); | ||
270 | if (!probe_ent) { | ||
271 | rc = -ENOMEM; | ||
272 | goto err_out_regions; | ||
273 | } | ||
274 | |||
275 | /* check and see if the SCRs are in IO space or PCI cfg space */ | 268 | /* check and see if the SCRs are in IO space or PCI cfg space */ |
276 | pci_read_config_dword(pdev, SIS_GENCTL, &genctl); | 269 | pci_read_config_dword(pdev, SIS_GENCTL, &genctl); |
277 | if ((genctl & GENCTL_IOMAPPED_SCR) == 0) | 270 | if ((genctl & GENCTL_IOMAPPED_SCR) == 0) |
278 | probe_ent->port_flags |= SIS_FLAG_CFGSCR; | 271 | pi.flags |= SIS_FLAG_CFGSCR; |
279 | 272 | ||
280 | /* if hardware thinks SCRs are in IO space, but there are | 273 | /* if hardware thinks SCRs are in IO space, but there are |
281 | * no IO resources assigned, change to PCI cfg space. | 274 | * no IO resources assigned, change to PCI cfg space. |
282 | */ | 275 | */ |
283 | if ((!(probe_ent->port_flags & SIS_FLAG_CFGSCR)) && | 276 | if ((!(pi.flags & SIS_FLAG_CFGSCR)) && |
284 | ((pci_resource_start(pdev, SIS_SCR_PCI_BAR) == 0) || | 277 | ((pci_resource_start(pdev, SIS_SCR_PCI_BAR) == 0) || |
285 | (pci_resource_len(pdev, SIS_SCR_PCI_BAR) < 128))) { | 278 | (pci_resource_len(pdev, SIS_SCR_PCI_BAR) < 128))) { |
286 | genctl &= ~GENCTL_IOMAPPED_SCR; | 279 | genctl &= ~GENCTL_IOMAPPED_SCR; |
287 | pci_write_config_dword(pdev, SIS_GENCTL, genctl); | 280 | pci_write_config_dword(pdev, SIS_GENCTL, genctl); |
288 | probe_ent->port_flags |= SIS_FLAG_CFGSCR; | 281 | pi.flags |= SIS_FLAG_CFGSCR; |
289 | } | 282 | } |
290 | 283 | ||
291 | pci_read_config_byte(pdev, SIS_PMR, &pmr); | 284 | pci_read_config_byte(pdev, SIS_PMR, &pmr); |
@@ -306,6 +299,12 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
306 | port2_start = 0x20; | 299 | port2_start = 0x20; |
307 | } | 300 | } |
308 | 301 | ||
302 | probe_ent = ata_pci_init_native_mode(pdev, ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY); | ||
303 | if (!probe_ent) { | ||
304 | rc = -ENOMEM; | ||
305 | goto err_out_regions; | ||
306 | } | ||
307 | |||
309 | if (!(probe_ent->port_flags & SIS_FLAG_CFGSCR)) { | 308 | if (!(probe_ent->port_flags & SIS_FLAG_CFGSCR)) { |
310 | probe_ent->port[0].scr_addr = | 309 | probe_ent->port[0].scr_addr = |
311 | pci_resource_start(pdev, SIS_SCR_PCI_BAR); | 310 | pci_resource_start(pdev, SIS_SCR_PCI_BAR); |
diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c index f4455a1efe2d..1c7f19aecc25 100644 --- a/drivers/ata/sata_via.c +++ b/drivers/ata/sata_via.c | |||
@@ -230,7 +230,7 @@ static int vt6420_prereset(struct ata_port *ap) | |||
230 | int online; | 230 | int online; |
231 | 231 | ||
232 | /* don't do any SCR stuff if we're not loading */ | 232 | /* don't do any SCR stuff if we're not loading */ |
233 | if (!ATA_PFLAG_LOADING) | 233 | if (!(ap->pflags & ATA_PFLAG_LOADING)) |
234 | goto skip_scr; | 234 | goto skip_scr; |
235 | 235 | ||
236 | /* Resume phy. This is the old resume sequence from | 236 | /* Resume phy. This is the old resume sequence from |
diff --git a/drivers/atm/ambassador.c b/drivers/atm/ambassador.c index 323592de047b..9fffa7af6db1 100644 --- a/drivers/atm/ambassador.c +++ b/drivers/atm/ambassador.c | |||
@@ -2452,8 +2452,8 @@ static int __init amb_module_init (void) | |||
2452 | static void __exit amb_module_exit (void) | 2452 | static void __exit amb_module_exit (void) |
2453 | { | 2453 | { |
2454 | PRINTD (DBG_FLOW|DBG_INIT, "cleanup_module"); | 2454 | PRINTD (DBG_FLOW|DBG_INIT, "cleanup_module"); |
2455 | 2455 | ||
2456 | return pci_unregister_driver(&amb_driver); | 2456 | pci_unregister_driver(&amb_driver); |
2457 | } | 2457 | } |
2458 | 2458 | ||
2459 | module_init(amb_module_init); | 2459 | module_init(amb_module_init); |
diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c index 40ab9b65fae9..697ad82f6634 100644 --- a/drivers/atm/firestream.c +++ b/drivers/atm/firestream.c | |||
@@ -1002,6 +1002,10 @@ static int fs_open(struct atm_vcc *atm_vcc) | |||
1002 | r = ROUND_UP; | 1002 | r = ROUND_UP; |
1003 | } | 1003 | } |
1004 | error = make_rate (pcr, r, &tmc0, NULL); | 1004 | error = make_rate (pcr, r, &tmc0, NULL); |
1005 | if (error) { | ||
1006 | kfree(tc); | ||
1007 | return error; | ||
1008 | } | ||
1005 | } | 1009 | } |
1006 | fs_dprintk (FS_DEBUG_OPEN, "pcr = %d.\n", pcr); | 1010 | fs_dprintk (FS_DEBUG_OPEN, "pcr = %d.\n", pcr); |
1007 | } | 1011 | } |
diff --git a/drivers/atm/horizon.c b/drivers/atm/horizon.c index f59349206dd2..4dc10105d610 100644 --- a/drivers/atm/horizon.c +++ b/drivers/atm/horizon.c | |||
@@ -1789,7 +1789,7 @@ static inline void CLOCK_IT (const hrz_dev *dev, u32 ctrl) | |||
1789 | WRITE_IT_WAIT(dev, ctrl | SEEPROM_SK); | 1789 | WRITE_IT_WAIT(dev, ctrl | SEEPROM_SK); |
1790 | } | 1790 | } |
1791 | 1791 | ||
1792 | static u16 __init read_bia (const hrz_dev * dev, u16 addr) | 1792 | static u16 __devinit read_bia (const hrz_dev * dev, u16 addr) |
1793 | { | 1793 | { |
1794 | u32 ctrl = rd_regl (dev, CONTROL_0_REG); | 1794 | u32 ctrl = rd_regl (dev, CONTROL_0_REG); |
1795 | 1795 | ||
@@ -2932,8 +2932,8 @@ static int __init hrz_module_init (void) { | |||
2932 | 2932 | ||
2933 | static void __exit hrz_module_exit (void) { | 2933 | static void __exit hrz_module_exit (void) { |
2934 | PRINTD (DBG_FLOW, "cleanup_module"); | 2934 | PRINTD (DBG_FLOW, "cleanup_module"); |
2935 | 2935 | ||
2936 | return pci_unregister_driver(&hrz_driver); | 2936 | pci_unregister_driver(&hrz_driver); |
2937 | } | 2937 | } |
2938 | 2938 | ||
2939 | module_init(hrz_module_init); | 2939 | module_init(hrz_module_init); |
diff --git a/drivers/atm/nicstar.c b/drivers/atm/nicstar.c index 632ede552761..bd0904594805 100644 --- a/drivers/atm/nicstar.c +++ b/drivers/atm/nicstar.c | |||
@@ -2759,7 +2759,7 @@ static int ns_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg) | |||
2759 | { | 2759 | { |
2760 | ns_dev *card; | 2760 | ns_dev *card; |
2761 | pool_levels pl; | 2761 | pool_levels pl; |
2762 | int btype; | 2762 | long btype; |
2763 | unsigned long flags; | 2763 | unsigned long flags; |
2764 | 2764 | ||
2765 | card = dev->dev_data; | 2765 | card = dev->dev_data; |
@@ -2859,7 +2859,7 @@ static int ns_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg) | |||
2859 | case NS_ADJBUFLEV: | 2859 | case NS_ADJBUFLEV: |
2860 | if (!capable(CAP_NET_ADMIN)) | 2860 | if (!capable(CAP_NET_ADMIN)) |
2861 | return -EPERM; | 2861 | return -EPERM; |
2862 | btype = (int) arg; /* an int is the same size as a pointer */ | 2862 | btype = (long) arg; /* a long is the same size as a pointer or bigger */ |
2863 | switch (btype) | 2863 | switch (btype) |
2864 | { | 2864 | { |
2865 | case NS_BUFTYPE_SMALL: | 2865 | case NS_BUFTYPE_SMALL: |
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig index 0b4e22436935..1429f3a2629e 100644 --- a/drivers/base/Kconfig +++ b/drivers/base/Kconfig | |||
@@ -37,8 +37,8 @@ config DEBUG_DRIVER | |||
37 | 37 | ||
38 | If you are unsure about this, say N here. | 38 | If you are unsure about this, say N here. |
39 | 39 | ||
40 | endmenu | ||
41 | |||
42 | config SYS_HYPERVISOR | 40 | config SYS_HYPERVISOR |
43 | bool | 41 | bool |
44 | default n | 42 | default n |
43 | |||
44 | endmenu | ||
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 12173d16bea7..7d8a7ce73fb3 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c | |||
@@ -372,19 +372,30 @@ int bus_add_device(struct device * dev) | |||
372 | pr_debug("bus %s: add device %s\n", bus->name, dev->bus_id); | 372 | pr_debug("bus %s: add device %s\n", bus->name, dev->bus_id); |
373 | error = device_add_attrs(bus, dev); | 373 | error = device_add_attrs(bus, dev); |
374 | if (error) | 374 | if (error) |
375 | goto out; | 375 | goto out_put; |
376 | error = sysfs_create_link(&bus->devices.kobj, | 376 | error = sysfs_create_link(&bus->devices.kobj, |
377 | &dev->kobj, dev->bus_id); | 377 | &dev->kobj, dev->bus_id); |
378 | if (error) | 378 | if (error) |
379 | goto out; | 379 | goto out_id; |
380 | error = sysfs_create_link(&dev->kobj, | 380 | error = sysfs_create_link(&dev->kobj, |
381 | &dev->bus->subsys.kset.kobj, "subsystem"); | 381 | &dev->bus->subsys.kset.kobj, "subsystem"); |
382 | if (error) | 382 | if (error) |
383 | goto out; | 383 | goto out_subsys; |
384 | error = sysfs_create_link(&dev->kobj, | 384 | error = sysfs_create_link(&dev->kobj, |
385 | &dev->bus->subsys.kset.kobj, "bus"); | 385 | &dev->bus->subsys.kset.kobj, "bus"); |
386 | if (error) | ||
387 | goto out_deprecated; | ||
386 | } | 388 | } |
387 | out: | 389 | return 0; |
390 | |||
391 | out_deprecated: | ||
392 | sysfs_remove_link(&dev->kobj, "subsystem"); | ||
393 | out_subsys: | ||
394 | sysfs_remove_link(&bus->devices.kobj, dev->bus_id); | ||
395 | out_id: | ||
396 | device_remove_attrs(bus, dev); | ||
397 | out_put: | ||
398 | put_bus(dev->bus); | ||
388 | return error; | 399 | return error; |
389 | } | 400 | } |
390 | 401 | ||
@@ -428,8 +439,10 @@ void bus_remove_device(struct device * dev) | |||
428 | sysfs_remove_link(&dev->kobj, "bus"); | 439 | sysfs_remove_link(&dev->kobj, "bus"); |
429 | sysfs_remove_link(&dev->bus->devices.kobj, dev->bus_id); | 440 | sysfs_remove_link(&dev->bus->devices.kobj, dev->bus_id); |
430 | device_remove_attrs(dev->bus, dev); | 441 | device_remove_attrs(dev->bus, dev); |
431 | dev->is_registered = 0; | 442 | if (dev->is_registered) { |
432 | klist_del(&dev->knode_bus); | 443 | dev->is_registered = 0; |
444 | klist_del(&dev->knode_bus); | ||
445 | } | ||
433 | pr_debug("bus %s: remove device %s\n", dev->bus->name, dev->bus_id); | 446 | pr_debug("bus %s: remove device %s\n", dev->bus->name, dev->bus_id); |
434 | device_release_driver(dev); | 447 | device_release_driver(dev); |
435 | put_bus(dev->bus); | 448 | put_bus(dev->bus); |
@@ -505,34 +518,36 @@ int bus_add_driver(struct device_driver *drv) | |||
505 | struct bus_type * bus = get_bus(drv->bus); | 518 | struct bus_type * bus = get_bus(drv->bus); |
506 | int error = 0; | 519 | int error = 0; |
507 | 520 | ||
508 | if (bus) { | 521 | if (!bus) |
509 | pr_debug("bus %s: add driver %s\n", bus->name, drv->name); | 522 | return 0; |
510 | error = kobject_set_name(&drv->kobj, "%s", drv->name); | 523 | |
511 | if (error) | 524 | pr_debug("bus %s: add driver %s\n", bus->name, drv->name); |
512 | goto out_put_bus; | 525 | error = kobject_set_name(&drv->kobj, "%s", drv->name); |
513 | drv->kobj.kset = &bus->drivers; | 526 | if (error) |
514 | if ((error = kobject_register(&drv->kobj))) | 527 | goto out_put_bus; |
515 | goto out_put_bus; | 528 | drv->kobj.kset = &bus->drivers; |
516 | 529 | if ((error = kobject_register(&drv->kobj))) | |
517 | error = driver_attach(drv); | 530 | goto out_put_bus; |
518 | if (error) | 531 | |
519 | goto out_unregister; | 532 | error = driver_attach(drv); |
520 | klist_add_tail(&drv->knode_bus, &bus->klist_drivers); | 533 | if (error) |
521 | module_add_driver(drv->owner, drv); | 534 | goto out_unregister; |
522 | 535 | klist_add_tail(&drv->knode_bus, &bus->klist_drivers); | |
523 | error = driver_add_attrs(bus, drv); | 536 | module_add_driver(drv->owner, drv); |
524 | if (error) { | 537 | |
525 | /* How the hell do we get out of this pickle? Give up */ | 538 | error = driver_add_attrs(bus, drv); |
526 | printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n", | 539 | if (error) { |
527 | __FUNCTION__, drv->name); | 540 | /* How the hell do we get out of this pickle? Give up */ |
528 | } | 541 | printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n", |
529 | error = add_bind_files(drv); | 542 | __FUNCTION__, drv->name); |
530 | if (error) { | ||
531 | /* Ditto */ | ||
532 | printk(KERN_ERR "%s: add_bind_files(%s) failed\n", | ||
533 | __FUNCTION__, drv->name); | ||
534 | } | ||
535 | } | 543 | } |
544 | error = add_bind_files(drv); | ||
545 | if (error) { | ||
546 | /* Ditto */ | ||
547 | printk(KERN_ERR "%s: add_bind_files(%s) failed\n", | ||
548 | __FUNCTION__, drv->name); | ||
549 | } | ||
550 | |||
536 | return error; | 551 | return error; |
537 | out_unregister: | 552 | out_unregister: |
538 | kobject_unregister(&drv->kobj); | 553 | kobject_unregister(&drv->kobj); |
@@ -552,16 +567,17 @@ out_put_bus: | |||
552 | 567 | ||
553 | void bus_remove_driver(struct device_driver * drv) | 568 | void bus_remove_driver(struct device_driver * drv) |
554 | { | 569 | { |
555 | if (drv->bus) { | 570 | if (!drv->bus) |
556 | remove_bind_files(drv); | 571 | return; |
557 | driver_remove_attrs(drv->bus, drv); | 572 | |
558 | klist_remove(&drv->knode_bus); | 573 | remove_bind_files(drv); |
559 | pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name); | 574 | driver_remove_attrs(drv->bus, drv); |
560 | driver_detach(drv); | 575 | klist_remove(&drv->knode_bus); |
561 | module_remove_driver(drv); | 576 | pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name); |
562 | kobject_unregister(&drv->kobj); | 577 | driver_detach(drv); |
563 | put_bus(drv->bus); | 578 | module_remove_driver(drv); |
564 | } | 579 | kobject_unregister(&drv->kobj); |
580 | put_bus(drv->bus); | ||
565 | } | 581 | } |
566 | 582 | ||
567 | 583 | ||
@@ -732,11 +748,15 @@ int bus_register(struct bus_type * bus) | |||
732 | 748 | ||
733 | klist_init(&bus->klist_devices, klist_devices_get, klist_devices_put); | 749 | klist_init(&bus->klist_devices, klist_devices_get, klist_devices_put); |
734 | klist_init(&bus->klist_drivers, NULL, NULL); | 750 | klist_init(&bus->klist_drivers, NULL, NULL); |
735 | bus_add_attrs(bus); | 751 | retval = bus_add_attrs(bus); |
752 | if (retval) | ||
753 | goto bus_attrs_fail; | ||
736 | 754 | ||
737 | pr_debug("bus type '%s' registered\n", bus->name); | 755 | pr_debug("bus type '%s' registered\n", bus->name); |
738 | return 0; | 756 | return 0; |
739 | 757 | ||
758 | bus_attrs_fail: | ||
759 | kset_unregister(&bus->drivers); | ||
740 | bus_drivers_fail: | 760 | bus_drivers_fail: |
741 | kset_unregister(&bus->devices); | 761 | kset_unregister(&bus->devices); |
742 | bus_devices_fail: | 762 | bus_devices_fail: |
diff --git a/drivers/base/class.c b/drivers/base/class.c index b32b77ff2dcd..0ff267a248db 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c | |||
@@ -562,7 +562,10 @@ int class_device_add(struct class_device *class_dev) | |||
562 | goto out2; | 562 | goto out2; |
563 | 563 | ||
564 | /* add the needed attributes to this device */ | 564 | /* add the needed attributes to this device */ |
565 | sysfs_create_link(&class_dev->kobj, &parent_class->subsys.kset.kobj, "subsystem"); | 565 | error = sysfs_create_link(&class_dev->kobj, |
566 | &parent_class->subsys.kset.kobj, "subsystem"); | ||
567 | if (error) | ||
568 | goto out3; | ||
566 | class_dev->uevent_attr.attr.name = "uevent"; | 569 | class_dev->uevent_attr.attr.name = "uevent"; |
567 | class_dev->uevent_attr.attr.mode = S_IWUSR; | 570 | class_dev->uevent_attr.attr.mode = S_IWUSR; |
568 | class_dev->uevent_attr.attr.owner = parent_class->owner; | 571 | class_dev->uevent_attr.attr.owner = parent_class->owner; |
diff --git a/drivers/base/core.c b/drivers/base/core.c index b224bb43ff63..68ad11af22b4 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -44,7 +44,7 @@ const char *dev_driver_string(struct device *dev) | |||
44 | return dev->driver ? dev->driver->name : | 44 | return dev->driver ? dev->driver->name : |
45 | (dev->bus ? dev->bus->name : ""); | 45 | (dev->bus ? dev->bus->name : ""); |
46 | } | 46 | } |
47 | EXPORT_SYMBOL_GPL(dev_driver_string); | 47 | EXPORT_SYMBOL(dev_driver_string); |
48 | 48 | ||
49 | #define to_dev(obj) container_of(obj, struct device, kobj) | 49 | #define to_dev(obj) container_of(obj, struct device, kobj) |
50 | #define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr) | 50 | #define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr) |
@@ -433,14 +433,16 @@ int device_add(struct device *dev) | |||
433 | if (dev->driver) | 433 | if (dev->driver) |
434 | dev->uevent_attr.attr.owner = dev->driver->owner; | 434 | dev->uevent_attr.attr.owner = dev->driver->owner; |
435 | dev->uevent_attr.store = store_uevent; | 435 | dev->uevent_attr.store = store_uevent; |
436 | device_create_file(dev, &dev->uevent_attr); | 436 | error = device_create_file(dev, &dev->uevent_attr); |
437 | if (error) | ||
438 | goto attrError; | ||
437 | 439 | ||
438 | if (MAJOR(dev->devt)) { | 440 | if (MAJOR(dev->devt)) { |
439 | struct device_attribute *attr; | 441 | struct device_attribute *attr; |
440 | attr = kzalloc(sizeof(*attr), GFP_KERNEL); | 442 | attr = kzalloc(sizeof(*attr), GFP_KERNEL); |
441 | if (!attr) { | 443 | if (!attr) { |
442 | error = -ENOMEM; | 444 | error = -ENOMEM; |
443 | goto PMError; | 445 | goto ueventattrError; |
444 | } | 446 | } |
445 | attr->attr.name = "dev"; | 447 | attr->attr.name = "dev"; |
446 | attr->attr.mode = S_IRUGO; | 448 | attr->attr.mode = S_IRUGO; |
@@ -450,7 +452,7 @@ int device_add(struct device *dev) | |||
450 | error = device_create_file(dev, attr); | 452 | error = device_create_file(dev, attr); |
451 | if (error) { | 453 | if (error) { |
452 | kfree(attr); | 454 | kfree(attr); |
453 | goto attrError; | 455 | goto ueventattrError; |
454 | } | 456 | } |
455 | 457 | ||
456 | dev->devt_attr = attr; | 458 | dev->devt_attr = attr; |
@@ -477,7 +479,8 @@ int device_add(struct device *dev) | |||
477 | if ((error = bus_add_device(dev))) | 479 | if ((error = bus_add_device(dev))) |
478 | goto BusError; | 480 | goto BusError; |
479 | kobject_uevent(&dev->kobj, KOBJ_ADD); | 481 | kobject_uevent(&dev->kobj, KOBJ_ADD); |
480 | bus_attach_device(dev); | 482 | if ((error = bus_attach_device(dev))) |
483 | goto AttachError; | ||
481 | if (parent) | 484 | if (parent) |
482 | klist_add_tail(&dev->knode_parent, &parent->klist_children); | 485 | klist_add_tail(&dev->knode_parent, &parent->klist_children); |
483 | 486 | ||
@@ -496,6 +499,8 @@ int device_add(struct device *dev) | |||
496 | kfree(class_name); | 499 | kfree(class_name); |
497 | put_device(dev); | 500 | put_device(dev); |
498 | return error; | 501 | return error; |
502 | AttachError: | ||
503 | bus_remove_device(dev); | ||
499 | BusError: | 504 | BusError: |
500 | device_pm_remove(dev); | 505 | device_pm_remove(dev); |
501 | PMError: | 506 | PMError: |
@@ -507,6 +512,8 @@ int device_add(struct device *dev) | |||
507 | device_remove_file(dev, dev->devt_attr); | 512 | device_remove_file(dev, dev->devt_attr); |
508 | kfree(dev->devt_attr); | 513 | kfree(dev->devt_attr); |
509 | } | 514 | } |
515 | ueventattrError: | ||
516 | device_remove_file(dev, &dev->uevent_attr); | ||
510 | attrError: | 517 | attrError: |
511 | kobject_uevent(&dev->kobj, KOBJ_REMOVE); | 518 | kobject_uevent(&dev->kobj, KOBJ_REMOVE); |
512 | kobject_del(&dev->kobj); | 519 | kobject_del(&dev->kobj); |
@@ -805,8 +812,10 @@ int device_rename(struct device *dev, char *new_name) | |||
805 | 812 | ||
806 | if (dev->class) { | 813 | if (dev->class) { |
807 | old_symlink_name = kmalloc(BUS_ID_SIZE, GFP_KERNEL); | 814 | old_symlink_name = kmalloc(BUS_ID_SIZE, GFP_KERNEL); |
808 | if (!old_symlink_name) | 815 | if (!old_symlink_name) { |
809 | return -ENOMEM; | 816 | error = -ENOMEM; |
817 | goto out_free_old_class; | ||
818 | } | ||
810 | strlcpy(old_symlink_name, dev->bus_id, BUS_ID_SIZE); | 819 | strlcpy(old_symlink_name, dev->bus_id, BUS_ID_SIZE); |
811 | } | 820 | } |
812 | 821 | ||
@@ -830,9 +839,10 @@ int device_rename(struct device *dev, char *new_name) | |||
830 | } | 839 | } |
831 | put_device(dev); | 840 | put_device(dev); |
832 | 841 | ||
833 | kfree(old_class_name); | ||
834 | kfree(new_class_name); | 842 | kfree(new_class_name); |
835 | kfree(old_symlink_name); | 843 | kfree(old_symlink_name); |
844 | out_free_old_class: | ||
845 | kfree(old_class_name); | ||
836 | 846 | ||
837 | return error; | 847 | return error; |
838 | } | 848 | } |
diff --git a/drivers/base/dd.c b/drivers/base/dd.c index b5f43c3e44fa..c5d6bb4290ad 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/device.h> | 18 | #include <linux/device.h> |
19 | #include <linux/module.h> | 19 | #include <linux/module.h> |
20 | #include <linux/kthread.h> | 20 | #include <linux/kthread.h> |
21 | #include <linux/wait.h> | ||
21 | 22 | ||
22 | #include "base.h" | 23 | #include "base.h" |
23 | #include "power/power.h" | 24 | #include "power/power.h" |
@@ -70,6 +71,8 @@ struct stupid_thread_structure { | |||
70 | }; | 71 | }; |
71 | 72 | ||
72 | static atomic_t probe_count = ATOMIC_INIT(0); | 73 | static atomic_t probe_count = ATOMIC_INIT(0); |
74 | static DECLARE_WAIT_QUEUE_HEAD(probe_waitqueue); | ||
75 | |||
73 | static int really_probe(void *void_data) | 76 | static int really_probe(void *void_data) |
74 | { | 77 | { |
75 | struct stupid_thread_structure *data = void_data; | 78 | struct stupid_thread_structure *data = void_data; |
@@ -121,6 +124,7 @@ probe_failed: | |||
121 | done: | 124 | done: |
122 | kfree(data); | 125 | kfree(data); |
123 | atomic_dec(&probe_count); | 126 | atomic_dec(&probe_count); |
127 | wake_up(&probe_waitqueue); | ||
124 | return ret; | 128 | return ret; |
125 | } | 129 | } |
126 | 130 | ||
@@ -171,6 +175,8 @@ int driver_probe_device(struct device_driver * drv, struct device * dev) | |||
171 | drv->bus->name, dev->bus_id, drv->name); | 175 | drv->bus->name, dev->bus_id, drv->name); |
172 | 176 | ||
173 | data = kmalloc(sizeof(*data), GFP_KERNEL); | 177 | data = kmalloc(sizeof(*data), GFP_KERNEL); |
178 | if (!data) | ||
179 | return -ENOMEM; | ||
174 | data->drv = drv; | 180 | data->drv = drv; |
175 | data->dev = dev; | 181 | data->dev = dev; |
176 | 182 | ||
@@ -178,7 +184,7 @@ int driver_probe_device(struct device_driver * drv, struct device * dev) | |||
178 | probe_task = kthread_run(really_probe, data, | 184 | probe_task = kthread_run(really_probe, data, |
179 | "probe-%s", dev->bus_id); | 185 | "probe-%s", dev->bus_id); |
180 | if (IS_ERR(probe_task)) | 186 | if (IS_ERR(probe_task)) |
181 | ret = PTR_ERR(probe_task); | 187 | ret = really_probe(data); |
182 | } else | 188 | } else |
183 | ret = really_probe(data); | 189 | ret = really_probe(data); |
184 | 190 | ||
@@ -335,6 +341,32 @@ void driver_detach(struct device_driver * drv) | |||
335 | } | 341 | } |
336 | } | 342 | } |
337 | 343 | ||
344 | #ifdef CONFIG_PCI_MULTITHREAD_PROBE | ||
345 | static int __init wait_for_probes(void) | ||
346 | { | ||
347 | DEFINE_WAIT(wait); | ||
348 | |||
349 | printk(KERN_INFO "%s: waiting for %d threads\n", __FUNCTION__, | ||
350 | atomic_read(&probe_count)); | ||
351 | if (!atomic_read(&probe_count)) | ||
352 | return 0; | ||
353 | while (atomic_read(&probe_count)) { | ||
354 | prepare_to_wait(&probe_waitqueue, &wait, TASK_UNINTERRUPTIBLE); | ||
355 | if (atomic_read(&probe_count)) | ||
356 | schedule(); | ||
357 | } | ||
358 | finish_wait(&probe_waitqueue, &wait); | ||
359 | return 0; | ||
360 | } | ||
361 | |||
362 | core_initcall_sync(wait_for_probes); | ||
363 | postcore_initcall_sync(wait_for_probes); | ||
364 | arch_initcall_sync(wait_for_probes); | ||
365 | subsys_initcall_sync(wait_for_probes); | ||
366 | fs_initcall_sync(wait_for_probes); | ||
367 | device_initcall_sync(wait_for_probes); | ||
368 | late_initcall_sync(wait_for_probes); | ||
369 | #endif | ||
338 | 370 | ||
339 | EXPORT_SYMBOL_GPL(device_bind_driver); | 371 | EXPORT_SYMBOL_GPL(device_bind_driver); |
340 | EXPORT_SYMBOL_GPL(device_release_driver); | 372 | EXPORT_SYMBOL_GPL(device_release_driver); |
diff --git a/drivers/base/dmapool.c b/drivers/base/dmapool.c index 33c5cce1560b..b2efbd4cf710 100644 --- a/drivers/base/dmapool.c +++ b/drivers/base/dmapool.c | |||
@@ -141,11 +141,20 @@ dma_pool_create (const char *name, struct device *dev, | |||
141 | init_waitqueue_head (&retval->waitq); | 141 | init_waitqueue_head (&retval->waitq); |
142 | 142 | ||
143 | if (dev) { | 143 | if (dev) { |
144 | int ret; | ||
145 | |||
144 | down (&pools_lock); | 146 | down (&pools_lock); |
145 | if (list_empty (&dev->dma_pools)) | 147 | if (list_empty (&dev->dma_pools)) |
146 | device_create_file (dev, &dev_attr_pools); | 148 | ret = device_create_file (dev, &dev_attr_pools); |
149 | else | ||
150 | ret = 0; | ||
147 | /* note: not currently insisting "name" be unique */ | 151 | /* note: not currently insisting "name" be unique */ |
148 | list_add (&retval->pools, &dev->dma_pools); | 152 | if (!ret) |
153 | list_add (&retval->pools, &dev->dma_pools); | ||
154 | else { | ||
155 | kfree(retval); | ||
156 | retval = NULL; | ||
157 | } | ||
149 | up (&pools_lock); | 158 | up (&pools_lock); |
150 | } else | 159 | } else |
151 | INIT_LIST_HEAD (&retval->pools); | 160 | INIT_LIST_HEAD (&retval->pools); |
diff --git a/drivers/base/topology.c b/drivers/base/topology.c index 3ef9d514b916..28dccb730af9 100644 --- a/drivers/base/topology.c +++ b/drivers/base/topology.c | |||
@@ -97,8 +97,7 @@ static struct attribute_group topology_attr_group = { | |||
97 | /* Add/Remove cpu_topology interface for CPU device */ | 97 | /* Add/Remove cpu_topology interface for CPU device */ |
98 | static int __cpuinit topology_add_dev(struct sys_device * sys_dev) | 98 | static int __cpuinit topology_add_dev(struct sys_device * sys_dev) |
99 | { | 99 | { |
100 | sysfs_create_group(&sys_dev->kobj, &topology_attr_group); | 100 | return sysfs_create_group(&sys_dev->kobj, &topology_attr_group); |
101 | return 0; | ||
102 | } | 101 | } |
103 | 102 | ||
104 | static int __cpuinit topology_remove_dev(struct sys_device * sys_dev) | 103 | static int __cpuinit topology_remove_dev(struct sys_device * sys_dev) |
diff --git a/drivers/block/DAC960.h b/drivers/block/DAC960.h index cec539e601fe..6148073532b2 100644 --- a/drivers/block/DAC960.h +++ b/drivers/block/DAC960.h | |||
@@ -4379,8 +4379,8 @@ static inline void DAC960_P_To_PD_TranslateEnquiry(void *Enquiry) | |||
4379 | static inline void DAC960_P_To_PD_TranslateDeviceState(void *DeviceState) | 4379 | static inline void DAC960_P_To_PD_TranslateDeviceState(void *DeviceState) |
4380 | { | 4380 | { |
4381 | memcpy(DeviceState + 2, DeviceState + 3, 1); | 4381 | memcpy(DeviceState + 2, DeviceState + 3, 1); |
4382 | memcpy(DeviceState + 4, DeviceState + 5, 2); | 4382 | memmove(DeviceState + 4, DeviceState + 5, 2); |
4383 | memcpy(DeviceState + 6, DeviceState + 8, 4); | 4383 | memmove(DeviceState + 6, DeviceState + 8, 4); |
4384 | } | 4384 | } |
4385 | 4385 | ||
4386 | static inline | 4386 | static inline |
diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c index 5d254b714509..5d6562171533 100644 --- a/drivers/block/amiflop.c +++ b/drivers/block/amiflop.c | |||
@@ -1709,10 +1709,13 @@ static struct kobject *floppy_find(dev_t dev, int *part, void *data) | |||
1709 | return get_disk(unit[drive].gendisk); | 1709 | return get_disk(unit[drive].gendisk); |
1710 | } | 1710 | } |
1711 | 1711 | ||
1712 | int __init amiga_floppy_init(void) | 1712 | static int __init amiga_floppy_init(void) |
1713 | { | 1713 | { |
1714 | int i, ret; | 1714 | int i, ret; |
1715 | 1715 | ||
1716 | if (!MACH_IS_AMIGA) | ||
1717 | return -ENXIO; | ||
1718 | |||
1716 | if (!AMIGAHW_PRESENT(AMI_FLOPPY)) | 1719 | if (!AMIGAHW_PRESENT(AMI_FLOPPY)) |
1717 | return -ENXIO; | 1720 | return -ENXIO; |
1718 | 1721 | ||
@@ -1809,15 +1812,9 @@ out_blkdev: | |||
1809 | return ret; | 1812 | return ret; |
1810 | } | 1813 | } |
1811 | 1814 | ||
1815 | module_init(amiga_floppy_init); | ||
1812 | #ifdef MODULE | 1816 | #ifdef MODULE |
1813 | 1817 | ||
1814 | int init_module(void) | ||
1815 | { | ||
1816 | if (!MACH_IS_AMIGA) | ||
1817 | return -ENXIO; | ||
1818 | return amiga_floppy_init(); | ||
1819 | } | ||
1820 | |||
1821 | #if 0 /* not safe to unload */ | 1818 | #if 0 /* not safe to unload */ |
1822 | void cleanup_module(void) | 1819 | void cleanup_module(void) |
1823 | { | 1820 | { |
diff --git a/drivers/block/aoe/aoe.h b/drivers/block/aoe/aoe.h index 6eebcb7be97e..6d111228cfac 100644 --- a/drivers/block/aoe/aoe.h +++ b/drivers/block/aoe/aoe.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* Copyright (c) 2004 Coraid, Inc. See COPYING for GPL terms. */ | 1 | /* Copyright (c) 2006 Coraid, Inc. See COPYING for GPL terms. */ |
2 | #define VERSION "22" | 2 | #define VERSION "32" |
3 | #define AOE_MAJOR 152 | 3 | #define AOE_MAJOR 152 |
4 | #define DEVICE_NAME "aoe" | 4 | #define DEVICE_NAME "aoe" |
5 | 5 | ||
@@ -65,7 +65,7 @@ struct aoe_atahdr { | |||
65 | struct aoe_cfghdr { | 65 | struct aoe_cfghdr { |
66 | __be16 bufcnt; | 66 | __be16 bufcnt; |
67 | __be16 fwver; | 67 | __be16 fwver; |
68 | unsigned char res; | 68 | unsigned char scnt; |
69 | unsigned char aoeccmd; | 69 | unsigned char aoeccmd; |
70 | unsigned char cslen[2]; | 70 | unsigned char cslen[2]; |
71 | }; | 71 | }; |
@@ -78,12 +78,14 @@ enum { | |||
78 | DEVFL_GDALLOC = (1<<4), /* need to alloc gendisk */ | 78 | DEVFL_GDALLOC = (1<<4), /* need to alloc gendisk */ |
79 | DEVFL_PAUSE = (1<<5), | 79 | DEVFL_PAUSE = (1<<5), |
80 | DEVFL_NEWSIZE = (1<<6), /* need to update dev size in block layer */ | 80 | DEVFL_NEWSIZE = (1<<6), /* need to update dev size in block layer */ |
81 | DEVFL_MAXBCNT = (1<<7), /* d->maxbcnt is not changeable */ | ||
82 | DEVFL_KICKME = (1<<8), | ||
81 | 83 | ||
82 | BUFFL_FAIL = 1, | 84 | BUFFL_FAIL = 1, |
83 | }; | 85 | }; |
84 | 86 | ||
85 | enum { | 87 | enum { |
86 | MAXATADATA = 1024, | 88 | DEFAULTBCNT = 2 * 512, /* 2 sectors */ |
87 | NPERSHELF = 16, /* number of slots per shelf address */ | 89 | NPERSHELF = 16, /* number of slots per shelf address */ |
88 | FREETAG = -1, | 90 | FREETAG = -1, |
89 | MIN_BUFS = 8, | 91 | MIN_BUFS = 8, |
@@ -107,11 +109,9 @@ struct frame { | |||
107 | ulong waited; | 109 | ulong waited; |
108 | struct buf *buf; | 110 | struct buf *buf; |
109 | char *bufaddr; | 111 | char *bufaddr; |
110 | int writedatalen; | 112 | ulong bcnt; |
111 | int ndata; | 113 | sector_t lba; |
112 | 114 | struct sk_buff *skb; | |
113 | /* largest possible */ | ||
114 | unsigned char data[sizeof(struct aoe_hdr) + sizeof(struct aoe_atahdr)]; | ||
115 | }; | 115 | }; |
116 | 116 | ||
117 | struct aoedev { | 117 | struct aoedev { |
@@ -121,9 +121,12 @@ struct aoedev { | |||
121 | ulong sysminor; | 121 | ulong sysminor; |
122 | ulong aoemajor; | 122 | ulong aoemajor; |
123 | ulong aoeminor; | 123 | ulong aoeminor; |
124 | ulong nopen; /* (bd_openers isn't available without sleeping) */ | 124 | u16 nopen; /* (bd_openers isn't available without sleeping) */ |
125 | ulong rttavg; /* round trip average of requests/responses */ | 125 | u16 lasttag; /* last tag sent */ |
126 | u16 rttavg; /* round trip average of requests/responses */ | ||
127 | u16 mintimer; | ||
126 | u16 fw_ver; /* version of blade's firmware */ | 128 | u16 fw_ver; /* version of blade's firmware */ |
129 | u16 maxbcnt; | ||
127 | struct work_struct work;/* disk create work struct */ | 130 | struct work_struct work;/* disk create work struct */ |
128 | struct gendisk *gd; | 131 | struct gendisk *gd; |
129 | request_queue_t blkq; | 132 | request_queue_t blkq; |
@@ -137,8 +140,8 @@ struct aoedev { | |||
137 | mempool_t *bufpool; /* for deadlock-free Buf allocation */ | 140 | mempool_t *bufpool; /* for deadlock-free Buf allocation */ |
138 | struct list_head bufq; /* queue of bios to work on */ | 141 | struct list_head bufq; /* queue of bios to work on */ |
139 | struct buf *inprocess; /* the one we're currently working on */ | 142 | struct buf *inprocess; /* the one we're currently working on */ |
140 | ulong lasttag; /* last tag sent */ | 143 | ushort lostjumbo; |
141 | ulong nframes; /* number of frames below */ | 144 | ushort nframes; /* number of frames below */ |
142 | struct frame *frames; | 145 | struct frame *frames; |
143 | }; | 146 | }; |
144 | 147 | ||
@@ -157,6 +160,7 @@ void aoecmd_cfg(ushort aoemajor, unsigned char aoeminor); | |||
157 | void aoecmd_ata_rsp(struct sk_buff *); | 160 | void aoecmd_ata_rsp(struct sk_buff *); |
158 | void aoecmd_cfg_rsp(struct sk_buff *); | 161 | void aoecmd_cfg_rsp(struct sk_buff *); |
159 | void aoecmd_sleepwork(void *vp); | 162 | void aoecmd_sleepwork(void *vp); |
163 | struct sk_buff *new_skb(ulong); | ||
160 | 164 | ||
161 | int aoedev_init(void); | 165 | int aoedev_init(void); |
162 | void aoedev_exit(void); | 166 | void aoedev_exit(void); |
diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c index 393b86a3dbf8..aa25f8b09fe3 100644 --- a/drivers/block/aoe/aoeblk.c +++ b/drivers/block/aoe/aoeblk.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* Copyright (c) 2004 Coraid, Inc. See COPYING for GPL terms. */ | 1 | /* Copyright (c) 2006 Coraid, Inc. See COPYING for GPL terms. */ |
2 | /* | 2 | /* |
3 | * aoeblk.c | 3 | * aoeblk.c |
4 | * block device routines | 4 | * block device routines |
@@ -14,7 +14,6 @@ | |||
14 | 14 | ||
15 | static kmem_cache_t *buf_pool_cache; | 15 | static kmem_cache_t *buf_pool_cache; |
16 | 16 | ||
17 | /* add attributes for our block devices in sysfs */ | ||
18 | static ssize_t aoedisk_show_state(struct gendisk * disk, char *page) | 17 | static ssize_t aoedisk_show_state(struct gendisk * disk, char *page) |
19 | { | 18 | { |
20 | struct aoedev *d = disk->private_data; | 19 | struct aoedev *d = disk->private_data; |
@@ -64,21 +63,27 @@ static struct disk_attribute disk_attr_fwver = { | |||
64 | .show = aoedisk_show_fwver | 63 | .show = aoedisk_show_fwver |
65 | }; | 64 | }; |
66 | 65 | ||
67 | static void | 66 | static struct attribute *aoe_attrs[] = { |
67 | &disk_attr_state.attr, | ||
68 | &disk_attr_mac.attr, | ||
69 | &disk_attr_netif.attr, | ||
70 | &disk_attr_fwver.attr, | ||
71 | NULL | ||
72 | }; | ||
73 | |||
74 | static const struct attribute_group attr_group = { | ||
75 | .attrs = aoe_attrs, | ||
76 | }; | ||
77 | |||
78 | static int | ||
68 | aoedisk_add_sysfs(struct aoedev *d) | 79 | aoedisk_add_sysfs(struct aoedev *d) |
69 | { | 80 | { |
70 | sysfs_create_file(&d->gd->kobj, &disk_attr_state.attr); | 81 | return sysfs_create_group(&d->gd->kobj, &attr_group); |
71 | sysfs_create_file(&d->gd->kobj, &disk_attr_mac.attr); | ||
72 | sysfs_create_file(&d->gd->kobj, &disk_attr_netif.attr); | ||
73 | sysfs_create_file(&d->gd->kobj, &disk_attr_fwver.attr); | ||
74 | } | 82 | } |
75 | void | 83 | void |
76 | aoedisk_rm_sysfs(struct aoedev *d) | 84 | aoedisk_rm_sysfs(struct aoedev *d) |
77 | { | 85 | { |
78 | sysfs_remove_link(&d->gd->kobj, "state"); | 86 | sysfs_remove_group(&d->gd->kobj, &attr_group); |
79 | sysfs_remove_link(&d->gd->kobj, "mac"); | ||
80 | sysfs_remove_link(&d->gd->kobj, "netif"); | ||
81 | sysfs_remove_link(&d->gd->kobj, "firmware-version"); | ||
82 | } | 87 | } |
83 | 88 | ||
84 | static int | 89 | static int |
@@ -132,8 +137,7 @@ aoeblk_make_request(request_queue_t *q, struct bio *bio) | |||
132 | d = bio->bi_bdev->bd_disk->private_data; | 137 | d = bio->bi_bdev->bd_disk->private_data; |
133 | buf = mempool_alloc(d->bufpool, GFP_NOIO); | 138 | buf = mempool_alloc(d->bufpool, GFP_NOIO); |
134 | if (buf == NULL) { | 139 | if (buf == NULL) { |
135 | printk(KERN_INFO "aoe: aoeblk_make_request: buf allocation " | 140 | printk(KERN_INFO "aoe: buf allocation failure\n"); |
136 | "failure\n"); | ||
137 | bio_endio(bio, bio->bi_size, -ENOMEM); | 141 | bio_endio(bio, bio->bi_size, -ENOMEM); |
138 | return 0; | 142 | return 0; |
139 | } | 143 | } |
@@ -143,14 +147,15 @@ aoeblk_make_request(request_queue_t *q, struct bio *bio) | |||
143 | buf->bio = bio; | 147 | buf->bio = bio; |
144 | buf->resid = bio->bi_size; | 148 | buf->resid = bio->bi_size; |
145 | buf->sector = bio->bi_sector; | 149 | buf->sector = bio->bi_sector; |
146 | buf->bv = buf->bio->bi_io_vec; | 150 | buf->bv = &bio->bi_io_vec[bio->bi_idx]; |
151 | WARN_ON(buf->bv->bv_len == 0); | ||
147 | buf->bv_resid = buf->bv->bv_len; | 152 | buf->bv_resid = buf->bv->bv_len; |
148 | buf->bufaddr = page_address(buf->bv->bv_page) + buf->bv->bv_offset; | 153 | buf->bufaddr = page_address(buf->bv->bv_page) + buf->bv->bv_offset; |
149 | 154 | ||
150 | spin_lock_irqsave(&d->lock, flags); | 155 | spin_lock_irqsave(&d->lock, flags); |
151 | 156 | ||
152 | if ((d->flags & DEVFL_UP) == 0) { | 157 | if ((d->flags & DEVFL_UP) == 0) { |
153 | printk(KERN_INFO "aoe: aoeblk_make_request: device %ld.%ld is not up\n", | 158 | printk(KERN_INFO "aoe: device %ld.%ld is not up\n", |
154 | d->aoemajor, d->aoeminor); | 159 | d->aoemajor, d->aoeminor); |
155 | spin_unlock_irqrestore(&d->lock, flags); | 160 | spin_unlock_irqrestore(&d->lock, flags); |
156 | mempool_free(buf, d->bufpool); | 161 | mempool_free(buf, d->bufpool); |
@@ -176,7 +181,7 @@ aoeblk_getgeo(struct block_device *bdev, struct hd_geometry *geo) | |||
176 | struct aoedev *d = bdev->bd_disk->private_data; | 181 | struct aoedev *d = bdev->bd_disk->private_data; |
177 | 182 | ||
178 | if ((d->flags & DEVFL_UP) == 0) { | 183 | if ((d->flags & DEVFL_UP) == 0) { |
179 | printk(KERN_ERR "aoe: aoeblk_ioctl: disk not up\n"); | 184 | printk(KERN_ERR "aoe: disk not up\n"); |
180 | return -ENODEV; | 185 | return -ENODEV; |
181 | } | 186 | } |
182 | 187 | ||
@@ -203,8 +208,8 @@ aoeblk_gdalloc(void *vp) | |||
203 | 208 | ||
204 | gd = alloc_disk(AOE_PARTITIONS); | 209 | gd = alloc_disk(AOE_PARTITIONS); |
205 | if (gd == NULL) { | 210 | if (gd == NULL) { |
206 | printk(KERN_ERR "aoe: aoeblk_gdalloc: cannot allocate disk " | 211 | printk(KERN_ERR "aoe: cannot allocate disk structure for %ld.%ld\n", |
207 | "structure for %ld.%ld\n", d->aoemajor, d->aoeminor); | 212 | d->aoemajor, d->aoeminor); |
208 | spin_lock_irqsave(&d->lock, flags); | 213 | spin_lock_irqsave(&d->lock, flags); |
209 | d->flags &= ~DEVFL_GDALLOC; | 214 | d->flags &= ~DEVFL_GDALLOC; |
210 | spin_unlock_irqrestore(&d->lock, flags); | 215 | spin_unlock_irqrestore(&d->lock, flags); |
@@ -213,8 +218,8 @@ aoeblk_gdalloc(void *vp) | |||
213 | 218 | ||
214 | d->bufpool = mempool_create_slab_pool(MIN_BUFS, buf_pool_cache); | 219 | d->bufpool = mempool_create_slab_pool(MIN_BUFS, buf_pool_cache); |
215 | if (d->bufpool == NULL) { | 220 | if (d->bufpool == NULL) { |
216 | printk(KERN_ERR "aoe: aoeblk_gdalloc: cannot allocate bufpool " | 221 | printk(KERN_ERR "aoe: cannot allocate bufpool for %ld.%ld\n", |
217 | "for %ld.%ld\n", d->aoemajor, d->aoeminor); | 222 | d->aoemajor, d->aoeminor); |
218 | put_disk(gd); | 223 | put_disk(gd); |
219 | spin_lock_irqsave(&d->lock, flags); | 224 | spin_lock_irqsave(&d->lock, flags); |
220 | d->flags &= ~DEVFL_GDALLOC; | 225 | d->flags &= ~DEVFL_GDALLOC; |
diff --git a/drivers/block/aoe/aoechr.c b/drivers/block/aoe/aoechr.c index 1bc1cf9603f1..e22b4c9520a9 100644 --- a/drivers/block/aoe/aoechr.c +++ b/drivers/block/aoe/aoechr.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* Copyright (c) 2004 Coraid, Inc. See COPYING for GPL terms. */ | 1 | /* Copyright (c) 2006 Coraid, Inc. See COPYING for GPL terms. */ |
2 | /* | 2 | /* |
3 | * aoechr.c | 3 | * aoechr.c |
4 | * AoE character device driver | 4 | * AoE character device driver |
@@ -15,7 +15,6 @@ enum { | |||
15 | MINOR_INTERFACES, | 15 | MINOR_INTERFACES, |
16 | MINOR_REVALIDATE, | 16 | MINOR_REVALIDATE, |
17 | MSGSZ = 2048, | 17 | MSGSZ = 2048, |
18 | NARGS = 10, | ||
19 | NMSG = 100, /* message backlog to retain */ | 18 | NMSG = 100, /* message backlog to retain */ |
20 | }; | 19 | }; |
21 | 20 | ||
@@ -56,9 +55,8 @@ static int | |||
56 | interfaces(const char __user *str, size_t size) | 55 | interfaces(const char __user *str, size_t size) |
57 | { | 56 | { |
58 | if (set_aoe_iflist(str, size)) { | 57 | if (set_aoe_iflist(str, size)) { |
59 | printk(KERN_CRIT | 58 | printk(KERN_ERR |
60 | "%s: could not set interface list: %s\n", | 59 | "aoe: could not set interface list: too many interfaces\n"); |
61 | __FUNCTION__, "too many interfaces"); | ||
62 | return -EINVAL; | 60 | return -EINVAL; |
63 | } | 61 | } |
64 | return 0; | 62 | return 0; |
@@ -81,8 +79,7 @@ revalidate(const char __user *str, size_t size) | |||
81 | /* should be e%d.%d format */ | 79 | /* should be e%d.%d format */ |
82 | n = sscanf(buf, "e%d.%d", &major, &minor); | 80 | n = sscanf(buf, "e%d.%d", &major, &minor); |
83 | if (n != 2) { | 81 | if (n != 2) { |
84 | printk(KERN_ERR "aoe: %s: invalid device specification\n", | 82 | printk(KERN_ERR "aoe: invalid device specification\n"); |
85 | __FUNCTION__); | ||
86 | return -EINVAL; | 83 | return -EINVAL; |
87 | } | 84 | } |
88 | d = aoedev_by_aoeaddr(major, minor); | 85 | d = aoedev_by_aoeaddr(major, minor); |
@@ -90,6 +87,7 @@ revalidate(const char __user *str, size_t size) | |||
90 | return -EINVAL; | 87 | return -EINVAL; |
91 | 88 | ||
92 | spin_lock_irqsave(&d->lock, flags); | 89 | spin_lock_irqsave(&d->lock, flags); |
90 | d->flags &= ~DEVFL_MAXBCNT; | ||
93 | d->flags |= DEVFL_PAUSE; | 91 | d->flags |= DEVFL_PAUSE; |
94 | spin_unlock_irqrestore(&d->lock, flags); | 92 | spin_unlock_irqrestore(&d->lock, flags); |
95 | aoecmd_cfg(major, minor); | 93 | aoecmd_cfg(major, minor); |
@@ -116,7 +114,7 @@ bail: spin_unlock_irqrestore(&emsgs_lock, flags); | |||
116 | 114 | ||
117 | mp = kmalloc(n, GFP_ATOMIC); | 115 | mp = kmalloc(n, GFP_ATOMIC); |
118 | if (mp == NULL) { | 116 | if (mp == NULL) { |
119 | printk(KERN_CRIT "aoe: aoechr_error: allocation failure, len=%ld\n", n); | 117 | printk(KERN_ERR "aoe: allocation failure, len=%ld\n", n); |
120 | goto bail; | 118 | goto bail; |
121 | } | 119 | } |
122 | 120 | ||
@@ -141,7 +139,7 @@ aoechr_write(struct file *filp, const char __user *buf, size_t cnt, loff_t *offp | |||
141 | 139 | ||
142 | switch ((unsigned long) filp->private_data) { | 140 | switch ((unsigned long) filp->private_data) { |
143 | default: | 141 | default: |
144 | printk(KERN_INFO "aoe: aoechr_write: can't write to that file.\n"); | 142 | printk(KERN_INFO "aoe: can't write to that file.\n"); |
145 | break; | 143 | break; |
146 | case MINOR_DISCOVER: | 144 | case MINOR_DISCOVER: |
147 | ret = discover(); | 145 | ret = discover(); |
@@ -250,7 +248,7 @@ aoechr_init(void) | |||
250 | 248 | ||
251 | n = register_chrdev(AOE_MAJOR, "aoechr", &aoe_fops); | 249 | n = register_chrdev(AOE_MAJOR, "aoechr", &aoe_fops); |
252 | if (n < 0) { | 250 | if (n < 0) { |
253 | printk(KERN_ERR "aoe: aoechr_init: can't register char device\n"); | 251 | printk(KERN_ERR "aoe: can't register char device\n"); |
254 | return n; | 252 | return n; |
255 | } | 253 | } |
256 | sema_init(&emsgs_sema, 0); | 254 | sema_init(&emsgs_sema, 0); |
diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c index 39da28d344fe..8a13b1af8bab 100644 --- a/drivers/block/aoe/aoecmd.c +++ b/drivers/block/aoe/aoecmd.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* Copyright (c) 2004 Coraid, Inc. See COPYING for GPL terms. */ | 1 | /* Copyright (c) 2006 Coraid, Inc. See COPYING for GPL terms. */ |
2 | /* | 2 | /* |
3 | * aoecmd.c | 3 | * aoecmd.c |
4 | * Filesystem request handling methods | 4 | * Filesystem request handling methods |
@@ -15,17 +15,19 @@ | |||
15 | #define TIMERTICK (HZ / 10) | 15 | #define TIMERTICK (HZ / 10) |
16 | #define MINTIMER (2 * TIMERTICK) | 16 | #define MINTIMER (2 * TIMERTICK) |
17 | #define MAXTIMER (HZ << 1) | 17 | #define MAXTIMER (HZ << 1) |
18 | #define MAXWAIT (60 * 3) /* After MAXWAIT seconds, give up and fail dev */ | ||
19 | 18 | ||
20 | static struct sk_buff * | 19 | static int aoe_deadsecs = 60 * 3; |
21 | new_skb(struct net_device *if_dev, ulong len) | 20 | module_param(aoe_deadsecs, int, 0644); |
21 | MODULE_PARM_DESC(aoe_deadsecs, "After aoe_deadsecs seconds, give up and fail dev."); | ||
22 | |||
23 | struct sk_buff * | ||
24 | new_skb(ulong len) | ||
22 | { | 25 | { |
23 | struct sk_buff *skb; | 26 | struct sk_buff *skb; |
24 | 27 | ||
25 | skb = alloc_skb(len, GFP_ATOMIC); | 28 | skb = alloc_skb(len, GFP_ATOMIC); |
26 | if (skb) { | 29 | if (skb) { |
27 | skb->nh.raw = skb->mac.raw = skb->data; | 30 | skb->nh.raw = skb->mac.raw = skb->data; |
28 | skb->dev = if_dev; | ||
29 | skb->protocol = __constant_htons(ETH_P_AOE); | 31 | skb->protocol = __constant_htons(ETH_P_AOE); |
30 | skb->priority = 0; | 32 | skb->priority = 0; |
31 | skb_put(skb, len); | 33 | skb_put(skb, len); |
@@ -40,29 +42,6 @@ new_skb(struct net_device *if_dev, ulong len) | |||
40 | return skb; | 42 | return skb; |
41 | } | 43 | } |
42 | 44 | ||
43 | static struct sk_buff * | ||
44 | skb_prepare(struct aoedev *d, struct frame *f) | ||
45 | { | ||
46 | struct sk_buff *skb; | ||
47 | char *p; | ||
48 | |||
49 | skb = new_skb(d->ifp, f->ndata + f->writedatalen); | ||
50 | if (!skb) { | ||
51 | printk(KERN_INFO "aoe: skb_prepare: failure to allocate skb\n"); | ||
52 | return NULL; | ||
53 | } | ||
54 | |||
55 | p = skb->mac.raw; | ||
56 | memcpy(p, f->data, f->ndata); | ||
57 | |||
58 | if (f->writedatalen) { | ||
59 | p += sizeof(struct aoe_hdr) + sizeof(struct aoe_atahdr); | ||
60 | memcpy(p, f->bufaddr, f->writedatalen); | ||
61 | } | ||
62 | |||
63 | return skb; | ||
64 | } | ||
65 | |||
66 | static struct frame * | 45 | static struct frame * |
67 | getframe(struct aoedev *d, int tag) | 46 | getframe(struct aoedev *d, int tag) |
68 | { | 47 | { |
@@ -107,6 +86,17 @@ aoehdr_atainit(struct aoedev *d, struct aoe_hdr *h) | |||
107 | return host_tag; | 86 | return host_tag; |
108 | } | 87 | } |
109 | 88 | ||
89 | static inline void | ||
90 | put_lba(struct aoe_atahdr *ah, sector_t lba) | ||
91 | { | ||
92 | ah->lba0 = lba; | ||
93 | ah->lba1 = lba >>= 8; | ||
94 | ah->lba2 = lba >>= 8; | ||
95 | ah->lba3 = lba >>= 8; | ||
96 | ah->lba4 = lba >>= 8; | ||
97 | ah->lba5 = lba >>= 8; | ||
98 | } | ||
99 | |||
110 | static void | 100 | static void |
111 | aoecmd_ata_rw(struct aoedev *d, struct frame *f) | 101 | aoecmd_ata_rw(struct aoedev *d, struct frame *f) |
112 | { | 102 | { |
@@ -125,29 +115,27 @@ aoecmd_ata_rw(struct aoedev *d, struct frame *f) | |||
125 | 115 | ||
126 | sector = buf->sector; | 116 | sector = buf->sector; |
127 | bcnt = buf->bv_resid; | 117 | bcnt = buf->bv_resid; |
128 | if (bcnt > MAXATADATA) | 118 | if (bcnt > d->maxbcnt) |
129 | bcnt = MAXATADATA; | 119 | bcnt = d->maxbcnt; |
130 | 120 | ||
131 | /* initialize the headers & frame */ | 121 | /* initialize the headers & frame */ |
132 | h = (struct aoe_hdr *) f->data; | 122 | skb = f->skb; |
123 | h = (struct aoe_hdr *) skb->mac.raw; | ||
133 | ah = (struct aoe_atahdr *) (h+1); | 124 | ah = (struct aoe_atahdr *) (h+1); |
134 | f->ndata = sizeof *h + sizeof *ah; | 125 | skb->len = sizeof *h + sizeof *ah; |
135 | memset(h, 0, f->ndata); | 126 | memset(h, 0, ETH_ZLEN); |
136 | f->tag = aoehdr_atainit(d, h); | 127 | f->tag = aoehdr_atainit(d, h); |
137 | f->waited = 0; | 128 | f->waited = 0; |
138 | f->buf = buf; | 129 | f->buf = buf; |
139 | f->bufaddr = buf->bufaddr; | 130 | f->bufaddr = buf->bufaddr; |
131 | f->bcnt = bcnt; | ||
132 | f->lba = sector; | ||
140 | 133 | ||
141 | /* set up ata header */ | 134 | /* set up ata header */ |
142 | ah->scnt = bcnt >> 9; | 135 | ah->scnt = bcnt >> 9; |
143 | ah->lba0 = sector; | 136 | put_lba(ah, sector); |
144 | ah->lba1 = sector >>= 8; | ||
145 | ah->lba2 = sector >>= 8; | ||
146 | ah->lba3 = sector >>= 8; | ||
147 | if (d->flags & DEVFL_EXT) { | 137 | if (d->flags & DEVFL_EXT) { |
148 | ah->aflags |= AOEAFL_EXT; | 138 | ah->aflags |= AOEAFL_EXT; |
149 | ah->lba4 = sector >>= 8; | ||
150 | ah->lba5 = sector >>= 8; | ||
151 | } else { | 139 | } else { |
152 | extbit = 0; | 140 | extbit = 0; |
153 | ah->lba3 &= 0x0f; | 141 | ah->lba3 &= 0x0f; |
@@ -155,11 +143,14 @@ aoecmd_ata_rw(struct aoedev *d, struct frame *f) | |||
155 | } | 143 | } |
156 | 144 | ||
157 | if (bio_data_dir(buf->bio) == WRITE) { | 145 | if (bio_data_dir(buf->bio) == WRITE) { |
146 | skb_fill_page_desc(skb, 0, virt_to_page(f->bufaddr), | ||
147 | offset_in_page(f->bufaddr), bcnt); | ||
158 | ah->aflags |= AOEAFL_WRITE; | 148 | ah->aflags |= AOEAFL_WRITE; |
159 | f->writedatalen = bcnt; | 149 | skb->len += bcnt; |
150 | skb->data_len = bcnt; | ||
160 | } else { | 151 | } else { |
152 | skb->len = ETH_ZLEN; | ||
161 | writebit = 0; | 153 | writebit = 0; |
162 | f->writedatalen = 0; | ||
163 | } | 154 | } |
164 | 155 | ||
165 | ah->cmdstat = WIN_READ | writebit | extbit; | 156 | ah->cmdstat = WIN_READ | writebit | extbit; |
@@ -168,26 +159,27 @@ aoecmd_ata_rw(struct aoedev *d, struct frame *f) | |||
168 | buf->nframesout += 1; | 159 | buf->nframesout += 1; |
169 | buf->bufaddr += bcnt; | 160 | buf->bufaddr += bcnt; |
170 | buf->bv_resid -= bcnt; | 161 | buf->bv_resid -= bcnt; |
171 | /* printk(KERN_INFO "aoe: bv_resid=%ld\n", buf->bv_resid); */ | 162 | /* printk(KERN_DEBUG "aoe: bv_resid=%ld\n", buf->bv_resid); */ |
172 | buf->resid -= bcnt; | 163 | buf->resid -= bcnt; |
173 | buf->sector += bcnt >> 9; | 164 | buf->sector += bcnt >> 9; |
174 | if (buf->resid == 0) { | 165 | if (buf->resid == 0) { |
175 | d->inprocess = NULL; | 166 | d->inprocess = NULL; |
176 | } else if (buf->bv_resid == 0) { | 167 | } else if (buf->bv_resid == 0) { |
177 | buf->bv++; | 168 | buf->bv++; |
169 | WARN_ON(buf->bv->bv_len == 0); | ||
178 | buf->bv_resid = buf->bv->bv_len; | 170 | buf->bv_resid = buf->bv->bv_len; |
179 | buf->bufaddr = page_address(buf->bv->bv_page) + buf->bv->bv_offset; | 171 | buf->bufaddr = page_address(buf->bv->bv_page) + buf->bv->bv_offset; |
180 | } | 172 | } |
181 | 173 | ||
182 | skb = skb_prepare(d, f); | 174 | skb->dev = d->ifp; |
183 | if (skb) { | 175 | skb = skb_clone(skb, GFP_ATOMIC); |
184 | skb->next = NULL; | 176 | if (skb == NULL) |
185 | if (d->sendq_hd) | 177 | return; |
186 | d->sendq_tl->next = skb; | 178 | if (d->sendq_hd) |
187 | else | 179 | d->sendq_tl->next = skb; |
188 | d->sendq_hd = skb; | 180 | else |
189 | d->sendq_tl = skb; | 181 | d->sendq_hd = skb; |
190 | } | 182 | d->sendq_tl = skb; |
191 | } | 183 | } |
192 | 184 | ||
193 | /* some callers cannot sleep, and they can call this function, | 185 | /* some callers cannot sleep, and they can call this function, |
@@ -209,11 +201,12 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff **tail) | |||
209 | if (!is_aoe_netif(ifp)) | 201 | if (!is_aoe_netif(ifp)) |
210 | continue; | 202 | continue; |
211 | 203 | ||
212 | skb = new_skb(ifp, sizeof *h + sizeof *ch); | 204 | skb = new_skb(sizeof *h + sizeof *ch); |
213 | if (skb == NULL) { | 205 | if (skb == NULL) { |
214 | printk(KERN_INFO "aoe: aoecmd_cfg: skb alloc failure\n"); | 206 | printk(KERN_INFO "aoe: skb alloc failure\n"); |
215 | continue; | 207 | continue; |
216 | } | 208 | } |
209 | skb->dev = ifp; | ||
217 | if (sl_tail == NULL) | 210 | if (sl_tail == NULL) |
218 | sl_tail = skb; | 211 | sl_tail = skb; |
219 | h = (struct aoe_hdr *) skb->mac.raw; | 212 | h = (struct aoe_hdr *) skb->mac.raw; |
@@ -237,6 +230,29 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff **tail) | |||
237 | return sl; | 230 | return sl; |
238 | } | 231 | } |
239 | 232 | ||
233 | static struct frame * | ||
234 | freeframe(struct aoedev *d) | ||
235 | { | ||
236 | struct frame *f, *e; | ||
237 | int n = 0; | ||
238 | |||
239 | f = d->frames; | ||
240 | e = f + d->nframes; | ||
241 | for (; f<e; f++) { | ||
242 | if (f->tag != FREETAG) | ||
243 | continue; | ||
244 | if (atomic_read(&skb_shinfo(f->skb)->dataref) == 1) { | ||
245 | skb_shinfo(f->skb)->nr_frags = f->skb->data_len = 0; | ||
246 | return f; | ||
247 | } | ||
248 | n++; | ||
249 | } | ||
250 | if (n == d->nframes) /* wait for network layer */ | ||
251 | d->flags |= DEVFL_KICKME; | ||
252 | |||
253 | return NULL; | ||
254 | } | ||
255 | |||
240 | /* enters with d->lock held */ | 256 | /* enters with d->lock held */ |
241 | void | 257 | void |
242 | aoecmd_work(struct aoedev *d) | 258 | aoecmd_work(struct aoedev *d) |
@@ -252,7 +268,7 @@ aoecmd_work(struct aoedev *d) | |||
252 | } | 268 | } |
253 | 269 | ||
254 | loop: | 270 | loop: |
255 | f = getframe(d, FREETAG); | 271 | f = freeframe(d); |
256 | if (f == NULL) | 272 | if (f == NULL) |
257 | return; | 273 | return; |
258 | if (d->inprocess == NULL) { | 274 | if (d->inprocess == NULL) { |
@@ -260,7 +276,7 @@ loop: | |||
260 | return; | 276 | return; |
261 | buf = container_of(d->bufq.next, struct buf, bufs); | 277 | buf = container_of(d->bufq.next, struct buf, bufs); |
262 | list_del(d->bufq.next); | 278 | list_del(d->bufq.next); |
263 | /*printk(KERN_INFO "aoecmd_work: bi_size=%ld\n", buf->bio->bi_size); */ | 279 | /*printk(KERN_DEBUG "aoe: bi_size=%ld\n", buf->bio->bi_size); */ |
264 | d->inprocess = buf; | 280 | d->inprocess = buf; |
265 | } | 281 | } |
266 | aoecmd_ata_rw(d, f); | 282 | aoecmd_ata_rw(d, f); |
@@ -272,6 +288,7 @@ rexmit(struct aoedev *d, struct frame *f) | |||
272 | { | 288 | { |
273 | struct sk_buff *skb; | 289 | struct sk_buff *skb; |
274 | struct aoe_hdr *h; | 290 | struct aoe_hdr *h; |
291 | struct aoe_atahdr *ah; | ||
275 | char buf[128]; | 292 | char buf[128]; |
276 | u32 n; | 293 | u32 n; |
277 | 294 | ||
@@ -283,21 +300,41 @@ rexmit(struct aoedev *d, struct frame *f) | |||
283 | d->aoemajor, d->aoeminor, f->tag, jiffies, n); | 300 | d->aoemajor, d->aoeminor, f->tag, jiffies, n); |
284 | aoechr_error(buf); | 301 | aoechr_error(buf); |
285 | 302 | ||
286 | h = (struct aoe_hdr *) f->data; | 303 | skb = f->skb; |
304 | h = (struct aoe_hdr *) skb->mac.raw; | ||
305 | ah = (struct aoe_atahdr *) (h+1); | ||
287 | f->tag = n; | 306 | f->tag = n; |
288 | h->tag = cpu_to_be32(n); | 307 | h->tag = cpu_to_be32(n); |
289 | memcpy(h->dst, d->addr, sizeof h->dst); | 308 | memcpy(h->dst, d->addr, sizeof h->dst); |
290 | memcpy(h->src, d->ifp->dev_addr, sizeof h->src); | 309 | memcpy(h->src, d->ifp->dev_addr, sizeof h->src); |
291 | 310 | ||
292 | skb = skb_prepare(d, f); | 311 | n = DEFAULTBCNT / 512; |
293 | if (skb) { | 312 | if (ah->scnt > n) { |
294 | skb->next = NULL; | 313 | ah->scnt = n; |
295 | if (d->sendq_hd) | 314 | if (ah->aflags & AOEAFL_WRITE) { |
296 | d->sendq_tl->next = skb; | 315 | skb_fill_page_desc(skb, 0, virt_to_page(f->bufaddr), |
297 | else | 316 | offset_in_page(f->bufaddr), DEFAULTBCNT); |
298 | d->sendq_hd = skb; | 317 | skb->len = sizeof *h + sizeof *ah + DEFAULTBCNT; |
299 | d->sendq_tl = skb; | 318 | skb->data_len = DEFAULTBCNT; |
319 | } | ||
320 | if (++d->lostjumbo > (d->nframes << 1)) | ||
321 | if (d->maxbcnt != DEFAULTBCNT) { | ||
322 | printk(KERN_INFO "aoe: e%ld.%ld: too many lost jumbo on %s - using 1KB frames.\n", | ||
323 | d->aoemajor, d->aoeminor, d->ifp->name); | ||
324 | d->maxbcnt = DEFAULTBCNT; | ||
325 | d->flags |= DEVFL_MAXBCNT; | ||
326 | } | ||
300 | } | 327 | } |
328 | |||
329 | skb->dev = d->ifp; | ||
330 | skb = skb_clone(skb, GFP_ATOMIC); | ||
331 | if (skb == NULL) | ||
332 | return; | ||
333 | if (d->sendq_hd) | ||
334 | d->sendq_tl->next = skb; | ||
335 | else | ||
336 | d->sendq_hd = skb; | ||
337 | d->sendq_tl = skb; | ||
301 | } | 338 | } |
302 | 339 | ||
303 | static int | 340 | static int |
@@ -340,13 +377,17 @@ rexmit_timer(ulong vp) | |||
340 | if (f->tag != FREETAG && tsince(f->tag) >= timeout) { | 377 | if (f->tag != FREETAG && tsince(f->tag) >= timeout) { |
341 | n = f->waited += timeout; | 378 | n = f->waited += timeout; |
342 | n /= HZ; | 379 | n /= HZ; |
343 | if (n > MAXWAIT) { /* waited too long. device failure. */ | 380 | if (n > aoe_deadsecs) { /* waited too long for response */ |
344 | aoedev_downdev(d); | 381 | aoedev_downdev(d); |
345 | break; | 382 | break; |
346 | } | 383 | } |
347 | rexmit(d, f); | 384 | rexmit(d, f); |
348 | } | 385 | } |
349 | } | 386 | } |
387 | if (d->flags & DEVFL_KICKME) { | ||
388 | d->flags &= ~DEVFL_KICKME; | ||
389 | aoecmd_work(d); | ||
390 | } | ||
350 | 391 | ||
351 | sl = d->sendq_hd; | 392 | sl = d->sendq_hd; |
352 | d->sendq_hd = d->sendq_tl = NULL; | 393 | d->sendq_hd = d->sendq_tl = NULL; |
@@ -431,8 +472,8 @@ ataid_complete(struct aoedev *d, unsigned char *id) | |||
431 | } | 472 | } |
432 | 473 | ||
433 | if (d->ssize != ssize) | 474 | if (d->ssize != ssize) |
434 | printk(KERN_INFO "aoe: %012llx e%lu.%lu v%04x has %llu " | 475 | printk(KERN_INFO "aoe: %012llx e%lu.%lu v%04x has %llu sectors\n", |
435 | "sectors\n", (unsigned long long)mac_addr(d->addr), | 476 | (unsigned long long)mac_addr(d->addr), |
436 | d->aoemajor, d->aoeminor, | 477 | d->aoemajor, d->aoeminor, |
437 | d->fw_ver, (long long)ssize); | 478 | d->fw_ver, (long long)ssize); |
438 | d->ssize = ssize; | 479 | d->ssize = ssize; |
@@ -442,11 +483,9 @@ ataid_complete(struct aoedev *d, unsigned char *id) | |||
442 | d->flags |= DEVFL_NEWSIZE; | 483 | d->flags |= DEVFL_NEWSIZE; |
443 | } else { | 484 | } else { |
444 | if (d->flags & DEVFL_GDALLOC) { | 485 | if (d->flags & DEVFL_GDALLOC) { |
445 | printk(KERN_INFO "aoe: %s: %s e%lu.%lu, %s\n", | 486 | printk(KERN_ERR "aoe: can't schedule work for e%lu.%lu, %s\n", |
446 | __FUNCTION__, | ||
447 | "can't schedule work for", | ||
448 | d->aoemajor, d->aoeminor, | 487 | d->aoemajor, d->aoeminor, |
449 | "it's already on! (This really shouldn't happen).\n"); | 488 | "it's already on! This shouldn't happen.\n"); |
450 | return; | 489 | return; |
451 | } | 490 | } |
452 | d->flags |= DEVFL_GDALLOC; | 491 | d->flags |= DEVFL_GDALLOC; |
@@ -460,8 +499,15 @@ calc_rttavg(struct aoedev *d, int rtt) | |||
460 | register long n; | 499 | register long n; |
461 | 500 | ||
462 | n = rtt; | 501 | n = rtt; |
463 | if (n < MINTIMER) | 502 | if (n < 0) { |
464 | n = MINTIMER; | 503 | n = -rtt; |
504 | if (n < MINTIMER) | ||
505 | n = MINTIMER; | ||
506 | else if (n > MAXTIMER) | ||
507 | n = MAXTIMER; | ||
508 | d->mintimer += (n - d->mintimer) >> 1; | ||
509 | } else if (n < d->mintimer) | ||
510 | n = d->mintimer; | ||
465 | else if (n > MAXTIMER) | 511 | else if (n > MAXTIMER) |
466 | n = MAXTIMER; | 512 | n = MAXTIMER; |
467 | 513 | ||
@@ -474,7 +520,7 @@ void | |||
474 | aoecmd_ata_rsp(struct sk_buff *skb) | 520 | aoecmd_ata_rsp(struct sk_buff *skb) |
475 | { | 521 | { |
476 | struct aoedev *d; | 522 | struct aoedev *d; |
477 | struct aoe_hdr *hin; | 523 | struct aoe_hdr *hin, *hout; |
478 | struct aoe_atahdr *ahin, *ahout; | 524 | struct aoe_atahdr *ahin, *ahout; |
479 | struct frame *f; | 525 | struct frame *f; |
480 | struct buf *buf; | 526 | struct buf *buf; |
@@ -497,8 +543,10 @@ aoecmd_ata_rsp(struct sk_buff *skb) | |||
497 | 543 | ||
498 | spin_lock_irqsave(&d->lock, flags); | 544 | spin_lock_irqsave(&d->lock, flags); |
499 | 545 | ||
500 | f = getframe(d, be32_to_cpu(hin->tag)); | 546 | n = be32_to_cpu(hin->tag); |
547 | f = getframe(d, n); | ||
501 | if (f == NULL) { | 548 | if (f == NULL) { |
549 | calc_rttavg(d, -tsince(n)); | ||
502 | spin_unlock_irqrestore(&d->lock, flags); | 550 | spin_unlock_irqrestore(&d->lock, flags); |
503 | snprintf(ebuf, sizeof ebuf, | 551 | snprintf(ebuf, sizeof ebuf, |
504 | "%15s e%d.%d tag=%08x@%08lx\n", | 552 | "%15s e%d.%d tag=%08x@%08lx\n", |
@@ -514,26 +562,27 @@ aoecmd_ata_rsp(struct sk_buff *skb) | |||
514 | calc_rttavg(d, tsince(f->tag)); | 562 | calc_rttavg(d, tsince(f->tag)); |
515 | 563 | ||
516 | ahin = (struct aoe_atahdr *) (hin+1); | 564 | ahin = (struct aoe_atahdr *) (hin+1); |
517 | ahout = (struct aoe_atahdr *) (f->data + sizeof(struct aoe_hdr)); | 565 | hout = (struct aoe_hdr *) f->skb->mac.raw; |
566 | ahout = (struct aoe_atahdr *) (hout+1); | ||
518 | buf = f->buf; | 567 | buf = f->buf; |
519 | 568 | ||
520 | if (ahout->cmdstat == WIN_IDENTIFY) | 569 | if (ahout->cmdstat == WIN_IDENTIFY) |
521 | d->flags &= ~DEVFL_PAUSE; | 570 | d->flags &= ~DEVFL_PAUSE; |
522 | if (ahin->cmdstat & 0xa9) { /* these bits cleared on success */ | 571 | if (ahin->cmdstat & 0xa9) { /* these bits cleared on success */ |
523 | printk(KERN_CRIT "aoe: aoecmd_ata_rsp: ata error cmd=%2.2Xh " | 572 | printk(KERN_ERR |
524 | "stat=%2.2Xh from e%ld.%ld\n", | 573 | "aoe: ata error cmd=%2.2Xh stat=%2.2Xh from e%ld.%ld\n", |
525 | ahout->cmdstat, ahin->cmdstat, | 574 | ahout->cmdstat, ahin->cmdstat, |
526 | d->aoemajor, d->aoeminor); | 575 | d->aoemajor, d->aoeminor); |
527 | if (buf) | 576 | if (buf) |
528 | buf->flags |= BUFFL_FAIL; | 577 | buf->flags |= BUFFL_FAIL; |
529 | } else { | 578 | } else { |
579 | n = ahout->scnt << 9; | ||
530 | switch (ahout->cmdstat) { | 580 | switch (ahout->cmdstat) { |
531 | case WIN_READ: | 581 | case WIN_READ: |
532 | case WIN_READ_EXT: | 582 | case WIN_READ_EXT: |
533 | n = ahout->scnt << 9; | ||
534 | if (skb->len - sizeof *hin - sizeof *ahin < n) { | 583 | if (skb->len - sizeof *hin - sizeof *ahin < n) { |
535 | printk(KERN_CRIT "aoe: aoecmd_ata_rsp: runt " | 584 | printk(KERN_ERR |
536 | "ata data size in read. skb->len=%d\n", | 585 | "aoe: runt data size in read. skb->len=%d\n", |
537 | skb->len); | 586 | skb->len); |
538 | /* fail frame f? just returning will rexmit. */ | 587 | /* fail frame f? just returning will rexmit. */ |
539 | spin_unlock_irqrestore(&d->lock, flags); | 588 | spin_unlock_irqrestore(&d->lock, flags); |
@@ -542,22 +591,49 @@ aoecmd_ata_rsp(struct sk_buff *skb) | |||
542 | memcpy(f->bufaddr, ahin+1, n); | 591 | memcpy(f->bufaddr, ahin+1, n); |
543 | case WIN_WRITE: | 592 | case WIN_WRITE: |
544 | case WIN_WRITE_EXT: | 593 | case WIN_WRITE_EXT: |
594 | if (f->bcnt -= n) { | ||
595 | skb = f->skb; | ||
596 | f->bufaddr += n; | ||
597 | put_lba(ahout, f->lba += ahout->scnt); | ||
598 | n = f->bcnt; | ||
599 | if (n > DEFAULTBCNT) | ||
600 | n = DEFAULTBCNT; | ||
601 | ahout->scnt = n >> 9; | ||
602 | if (ahout->aflags & AOEAFL_WRITE) { | ||
603 | skb_fill_page_desc(skb, 0, | ||
604 | virt_to_page(f->bufaddr), | ||
605 | offset_in_page(f->bufaddr), n); | ||
606 | skb->len = sizeof *hout + sizeof *ahout + n; | ||
607 | skb->data_len = n; | ||
608 | } | ||
609 | f->tag = newtag(d); | ||
610 | hout->tag = cpu_to_be32(f->tag); | ||
611 | skb->dev = d->ifp; | ||
612 | skb = skb_clone(skb, GFP_ATOMIC); | ||
613 | spin_unlock_irqrestore(&d->lock, flags); | ||
614 | if (skb) | ||
615 | aoenet_xmit(skb); | ||
616 | return; | ||
617 | } | ||
618 | if (n > DEFAULTBCNT) | ||
619 | d->lostjumbo = 0; | ||
545 | break; | 620 | break; |
546 | case WIN_IDENTIFY: | 621 | case WIN_IDENTIFY: |
547 | if (skb->len - sizeof *hin - sizeof *ahin < 512) { | 622 | if (skb->len - sizeof *hin - sizeof *ahin < 512) { |
548 | printk(KERN_INFO "aoe: aoecmd_ata_rsp: runt data size " | 623 | printk(KERN_INFO |
549 | "in ataid. skb->len=%d\n", skb->len); | 624 | "aoe: runt data size in ataid. skb->len=%d\n", |
625 | skb->len); | ||
550 | spin_unlock_irqrestore(&d->lock, flags); | 626 | spin_unlock_irqrestore(&d->lock, flags); |
551 | return; | 627 | return; |
552 | } | 628 | } |
553 | ataid_complete(d, (char *) (ahin+1)); | 629 | ataid_complete(d, (char *) (ahin+1)); |
554 | break; | 630 | break; |
555 | default: | 631 | default: |
556 | printk(KERN_INFO "aoe: aoecmd_ata_rsp: unrecognized " | 632 | printk(KERN_INFO |
557 | "outbound ata command %2.2Xh for %d.%d\n", | 633 | "aoe: unrecognized ata command %2.2Xh for %d.%d\n", |
558 | ahout->cmdstat, | 634 | ahout->cmdstat, |
559 | be16_to_cpu(hin->major), | 635 | be16_to_cpu(hin->major), |
560 | hin->minor); | 636 | hin->minor); |
561 | } | 637 | } |
562 | } | 638 | } |
563 | 639 | ||
@@ -612,33 +688,32 @@ aoecmd_ata_id(struct aoedev *d) | |||
612 | struct frame *f; | 688 | struct frame *f; |
613 | struct sk_buff *skb; | 689 | struct sk_buff *skb; |
614 | 690 | ||
615 | f = getframe(d, FREETAG); | 691 | f = freeframe(d); |
616 | if (f == NULL) { | 692 | if (f == NULL) { |
617 | printk(KERN_CRIT "aoe: aoecmd_ata_id: can't get a frame. " | 693 | printk(KERN_ERR "aoe: can't get a frame. This shouldn't happen.\n"); |
618 | "This shouldn't happen.\n"); | ||
619 | return NULL; | 694 | return NULL; |
620 | } | 695 | } |
621 | 696 | ||
622 | /* initialize the headers & frame */ | 697 | /* initialize the headers & frame */ |
623 | h = (struct aoe_hdr *) f->data; | 698 | skb = f->skb; |
699 | h = (struct aoe_hdr *) skb->mac.raw; | ||
624 | ah = (struct aoe_atahdr *) (h+1); | 700 | ah = (struct aoe_atahdr *) (h+1); |
625 | f->ndata = sizeof *h + sizeof *ah; | 701 | skb->len = ETH_ZLEN; |
626 | memset(h, 0, f->ndata); | 702 | memset(h, 0, ETH_ZLEN); |
627 | f->tag = aoehdr_atainit(d, h); | 703 | f->tag = aoehdr_atainit(d, h); |
628 | f->waited = 0; | 704 | f->waited = 0; |
629 | f->writedatalen = 0; | ||
630 | 705 | ||
631 | /* set up ata header */ | 706 | /* set up ata header */ |
632 | ah->scnt = 1; | 707 | ah->scnt = 1; |
633 | ah->cmdstat = WIN_IDENTIFY; | 708 | ah->cmdstat = WIN_IDENTIFY; |
634 | ah->lba3 = 0xa0; | 709 | ah->lba3 = 0xa0; |
635 | 710 | ||
636 | skb = skb_prepare(d, f); | 711 | skb->dev = d->ifp; |
637 | 712 | ||
638 | d->rttavg = MAXTIMER; | 713 | d->rttavg = MAXTIMER; |
639 | d->timer.function = rexmit_timer; | 714 | d->timer.function = rexmit_timer; |
640 | 715 | ||
641 | return skb; | 716 | return skb_clone(skb, GFP_ATOMIC); |
642 | } | 717 | } |
643 | 718 | ||
644 | void | 719 | void |
@@ -648,9 +723,9 @@ aoecmd_cfg_rsp(struct sk_buff *skb) | |||
648 | struct aoe_hdr *h; | 723 | struct aoe_hdr *h; |
649 | struct aoe_cfghdr *ch; | 724 | struct aoe_cfghdr *ch; |
650 | ulong flags, sysminor, aoemajor; | 725 | ulong flags, sysminor, aoemajor; |
651 | u16 bufcnt; | ||
652 | struct sk_buff *sl; | 726 | struct sk_buff *sl; |
653 | enum { MAXFRAMES = 16 }; | 727 | enum { MAXFRAMES = 16 }; |
728 | u16 n; | ||
654 | 729 | ||
655 | h = (struct aoe_hdr *) skb->mac.raw; | 730 | h = (struct aoe_hdr *) skb->mac.raw; |
656 | ch = (struct aoe_cfghdr *) (h+1); | 731 | ch = (struct aoe_cfghdr *) (h+1); |
@@ -661,26 +736,25 @@ aoecmd_cfg_rsp(struct sk_buff *skb) | |||
661 | */ | 736 | */ |
662 | aoemajor = be16_to_cpu(h->major); | 737 | aoemajor = be16_to_cpu(h->major); |
663 | if (aoemajor == 0xfff) { | 738 | if (aoemajor == 0xfff) { |
664 | printk(KERN_CRIT "aoe: aoecmd_cfg_rsp: Warning: shelf " | 739 | printk(KERN_ERR "aoe: Warning: shelf address is all ones. " |
665 | "address is all ones. Check shelf dip switches\n"); | 740 | "Check shelf dip switches.\n"); |
666 | return; | 741 | return; |
667 | } | 742 | } |
668 | 743 | ||
669 | sysminor = SYSMINOR(aoemajor, h->minor); | 744 | sysminor = SYSMINOR(aoemajor, h->minor); |
670 | if (sysminor * AOE_PARTITIONS + AOE_PARTITIONS > MINORMASK) { | 745 | if (sysminor * AOE_PARTITIONS + AOE_PARTITIONS > MINORMASK) { |
671 | printk(KERN_INFO | 746 | printk(KERN_INFO "aoe: e%ld.%d: minor number too large\n", |
672 | "aoe: e%ld.%d: minor number too large\n", | ||
673 | aoemajor, (int) h->minor); | 747 | aoemajor, (int) h->minor); |
674 | return; | 748 | return; |
675 | } | 749 | } |
676 | 750 | ||
677 | bufcnt = be16_to_cpu(ch->bufcnt); | 751 | n = be16_to_cpu(ch->bufcnt); |
678 | if (bufcnt > MAXFRAMES) /* keep it reasonable */ | 752 | if (n > MAXFRAMES) /* keep it reasonable */ |
679 | bufcnt = MAXFRAMES; | 753 | n = MAXFRAMES; |
680 | 754 | ||
681 | d = aoedev_by_sysminor_m(sysminor, bufcnt); | 755 | d = aoedev_by_sysminor_m(sysminor, n); |
682 | if (d == NULL) { | 756 | if (d == NULL) { |
683 | printk(KERN_INFO "aoe: aoecmd_cfg_rsp: device sysminor_m failure\n"); | 757 | printk(KERN_INFO "aoe: device sysminor_m failure\n"); |
684 | return; | 758 | return; |
685 | } | 759 | } |
686 | 760 | ||
@@ -689,6 +763,20 @@ aoecmd_cfg_rsp(struct sk_buff *skb) | |||
689 | /* permit device to migrate mac and network interface */ | 763 | /* permit device to migrate mac and network interface */ |
690 | d->ifp = skb->dev; | 764 | d->ifp = skb->dev; |
691 | memcpy(d->addr, h->src, sizeof d->addr); | 765 | memcpy(d->addr, h->src, sizeof d->addr); |
766 | if (!(d->flags & DEVFL_MAXBCNT)) { | ||
767 | n = d->ifp->mtu; | ||
768 | n -= sizeof (struct aoe_hdr) + sizeof (struct aoe_atahdr); | ||
769 | n /= 512; | ||
770 | if (n > ch->scnt) | ||
771 | n = ch->scnt; | ||
772 | n = n ? n * 512 : DEFAULTBCNT; | ||
773 | if (n != d->maxbcnt) { | ||
774 | printk(KERN_INFO | ||
775 | "aoe: e%ld.%ld: setting %d byte data frames on %s\n", | ||
776 | d->aoemajor, d->aoeminor, n, d->ifp->name); | ||
777 | d->maxbcnt = n; | ||
778 | } | ||
779 | } | ||
692 | 780 | ||
693 | /* don't change users' perspective */ | 781 | /* don't change users' perspective */ |
694 | if (d->nopen && !(d->flags & DEVFL_PAUSE)) { | 782 | if (d->nopen && !(d->flags & DEVFL_PAUSE)) { |
@@ -696,6 +784,7 @@ aoecmd_cfg_rsp(struct sk_buff *skb) | |||
696 | return; | 784 | return; |
697 | } | 785 | } |
698 | d->flags |= DEVFL_PAUSE; /* force pause */ | 786 | d->flags |= DEVFL_PAUSE; /* force pause */ |
787 | d->mintimer = MINTIMER; | ||
699 | d->fw_ver = be16_to_cpu(ch->fwver); | 788 | d->fw_ver = be16_to_cpu(ch->fwver); |
700 | 789 | ||
701 | /* check for already outstanding ataid */ | 790 | /* check for already outstanding ataid */ |
diff --git a/drivers/block/aoe/aoedev.c b/drivers/block/aoe/aoedev.c index ed4258a62df5..6125921bbec4 100644 --- a/drivers/block/aoe/aoedev.c +++ b/drivers/block/aoe/aoedev.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* Copyright (c) 2004 Coraid, Inc. See COPYING for GPL terms. */ | 1 | /* Copyright (c) 2006 Coraid, Inc. See COPYING for GPL terms. */ |
2 | /* | 2 | /* |
3 | * aoedev.c | 3 | * aoedev.c |
4 | * AoE device utility functions; maintains device list. | 4 | * AoE device utility functions; maintains device list. |
@@ -20,11 +20,8 @@ aoedev_isbusy(struct aoedev *d) | |||
20 | f = d->frames; | 20 | f = d->frames; |
21 | e = f + d->nframes; | 21 | e = f + d->nframes; |
22 | do { | 22 | do { |
23 | if (f->tag != FREETAG) { | 23 | if (f->tag != FREETAG) |
24 | printk(KERN_DEBUG "aoe: %ld.%ld isbusy\n", | ||
25 | d->aoemajor, d->aoeminor); | ||
26 | return 1; | 24 | return 1; |
27 | } | ||
28 | } while (++f < e); | 25 | } while (++f < e); |
29 | 26 | ||
30 | return 0; | 27 | return 0; |
@@ -66,22 +63,32 @@ aoedev_newdev(ulong nframes) | |||
66 | struct frame *f, *e; | 63 | struct frame *f, *e; |
67 | 64 | ||
68 | d = kzalloc(sizeof *d, GFP_ATOMIC); | 65 | d = kzalloc(sizeof *d, GFP_ATOMIC); |
69 | if (d == NULL) | ||
70 | return NULL; | ||
71 | f = kcalloc(nframes, sizeof *f, GFP_ATOMIC); | 66 | f = kcalloc(nframes, sizeof *f, GFP_ATOMIC); |
72 | if (f == NULL) { | 67 | switch (!d || !f) { |
73 | kfree(d); | 68 | case 0: |
69 | d->nframes = nframes; | ||
70 | d->frames = f; | ||
71 | e = f + nframes; | ||
72 | for (; f<e; f++) { | ||
73 | f->tag = FREETAG; | ||
74 | f->skb = new_skb(ETH_ZLEN); | ||
75 | if (!f->skb) | ||
76 | break; | ||
77 | } | ||
78 | if (f == e) | ||
79 | break; | ||
80 | while (f > d->frames) { | ||
81 | f--; | ||
82 | dev_kfree_skb(f->skb); | ||
83 | } | ||
84 | default: | ||
85 | if (f) | ||
86 | kfree(f); | ||
87 | if (d) | ||
88 | kfree(d); | ||
74 | return NULL; | 89 | return NULL; |
75 | } | 90 | } |
76 | |||
77 | INIT_WORK(&d->work, aoecmd_sleepwork, d); | 91 | INIT_WORK(&d->work, aoecmd_sleepwork, d); |
78 | |||
79 | d->nframes = nframes; | ||
80 | d->frames = f; | ||
81 | e = f + nframes; | ||
82 | for (; f<e; f++) | ||
83 | f->tag = FREETAG; | ||
84 | |||
85 | spin_lock_init(&d->lock); | 92 | spin_lock_init(&d->lock); |
86 | init_timer(&d->timer); | 93 | init_timer(&d->timer); |
87 | d->timer.data = (ulong) d; | 94 | d->timer.data = (ulong) d; |
@@ -114,6 +121,7 @@ aoedev_downdev(struct aoedev *d) | |||
114 | mempool_free(buf, d->bufpool); | 121 | mempool_free(buf, d->bufpool); |
115 | bio_endio(bio, bio->bi_size, -EIO); | 122 | bio_endio(bio, bio->bi_size, -EIO); |
116 | } | 123 | } |
124 | skb_shinfo(f->skb)->nr_frags = f->skb->data_len = 0; | ||
117 | } | 125 | } |
118 | d->inprocess = NULL; | 126 | d->inprocess = NULL; |
119 | 127 | ||
@@ -148,7 +156,7 @@ aoedev_by_sysminor_m(ulong sysminor, ulong bufcnt) | |||
148 | d = aoedev_newdev(bufcnt); | 156 | d = aoedev_newdev(bufcnt); |
149 | if (d == NULL) { | 157 | if (d == NULL) { |
150 | spin_unlock_irqrestore(&devlist_lock, flags); | 158 | spin_unlock_irqrestore(&devlist_lock, flags); |
151 | printk(KERN_INFO "aoe: aoedev_set: aoedev_newdev failure.\n"); | 159 | printk(KERN_INFO "aoe: aoedev_newdev failure.\n"); |
152 | return NULL; | 160 | return NULL; |
153 | } | 161 | } |
154 | d->sysminor = sysminor; | 162 | d->sysminor = sysminor; |
@@ -163,11 +171,19 @@ aoedev_by_sysminor_m(ulong sysminor, ulong bufcnt) | |||
163 | static void | 171 | static void |
164 | aoedev_freedev(struct aoedev *d) | 172 | aoedev_freedev(struct aoedev *d) |
165 | { | 173 | { |
174 | struct frame *f, *e; | ||
175 | |||
166 | if (d->gd) { | 176 | if (d->gd) { |
167 | aoedisk_rm_sysfs(d); | 177 | aoedisk_rm_sysfs(d); |
168 | del_gendisk(d->gd); | 178 | del_gendisk(d->gd); |
169 | put_disk(d->gd); | 179 | put_disk(d->gd); |
170 | } | 180 | } |
181 | f = d->frames; | ||
182 | e = f + d->nframes; | ||
183 | for (; f<e; f++) { | ||
184 | skb_shinfo(f->skb)->nr_frags = 0; | ||
185 | dev_kfree_skb(f->skb); | ||
186 | } | ||
171 | kfree(d->frames); | 187 | kfree(d->frames); |
172 | if (d->bufpool) | 188 | if (d->bufpool) |
173 | mempool_destroy(d->bufpool); | 189 | mempool_destroy(d->bufpool); |
diff --git a/drivers/block/aoe/aoemain.c b/drivers/block/aoe/aoemain.c index de08491ebe66..a04b7d613299 100644 --- a/drivers/block/aoe/aoemain.c +++ b/drivers/block/aoe/aoemain.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* Copyright (c) 2004 Coraid, Inc. See COPYING for GPL terms. */ | 1 | /* Copyright (c) 2006 Coraid, Inc. See COPYING for GPL terms. */ |
2 | /* | 2 | /* |
3 | * aoemain.c | 3 | * aoemain.c |
4 | * Module initialization routines, discover timer | 4 | * Module initialization routines, discover timer |
@@ -84,13 +84,11 @@ aoe_init(void) | |||
84 | goto net_fail; | 84 | goto net_fail; |
85 | ret = register_blkdev(AOE_MAJOR, DEVICE_NAME); | 85 | ret = register_blkdev(AOE_MAJOR, DEVICE_NAME); |
86 | if (ret < 0) { | 86 | if (ret < 0) { |
87 | printk(KERN_ERR "aoe: aoeblk_init: can't register major\n"); | 87 | printk(KERN_ERR "aoe: can't register major\n"); |
88 | goto blkreg_fail; | 88 | goto blkreg_fail; |
89 | } | 89 | } |
90 | 90 | ||
91 | printk(KERN_INFO | 91 | printk(KERN_INFO "aoe: AoE v%s initialised.\n", VERSION); |
92 | "aoe: aoe_init: AoE v%s initialised.\n", | ||
93 | VERSION); | ||
94 | discover_timer(TINIT); | 92 | discover_timer(TINIT); |
95 | return 0; | 93 | return 0; |
96 | 94 | ||
@@ -103,7 +101,7 @@ aoe_init(void) | |||
103 | chr_fail: | 101 | chr_fail: |
104 | aoedev_exit(); | 102 | aoedev_exit(); |
105 | 103 | ||
106 | printk(KERN_INFO "aoe: aoe_init: initialisation failure.\n"); | 104 | printk(KERN_INFO "aoe: initialisation failure.\n"); |
107 | return ret; | 105 | return ret; |
108 | } | 106 | } |
109 | 107 | ||
diff --git a/drivers/block/aoe/aoenet.c b/drivers/block/aoe/aoenet.c index c1434ed11880..9626e0f5da9d 100644 --- a/drivers/block/aoe/aoenet.c +++ b/drivers/block/aoe/aoenet.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* Copyright (c) 2004 Coraid, Inc. See COPYING for GPL terms. */ | 1 | /* Copyright (c) 2006 Coraid, Inc. See COPYING for GPL terms. */ |
2 | /* | 2 | /* |
3 | * aoenet.c | 3 | * aoenet.c |
4 | * Ethernet portion of AoE driver | 4 | * Ethernet portion of AoE driver |
@@ -74,7 +74,7 @@ set_aoe_iflist(const char __user *user_str, size_t size) | |||
74 | return -EINVAL; | 74 | return -EINVAL; |
75 | 75 | ||
76 | if (copy_from_user(aoe_iflist, user_str, size)) { | 76 | if (copy_from_user(aoe_iflist, user_str, size)) { |
77 | printk(KERN_INFO "aoe: %s: copy from user failed\n", __FUNCTION__); | 77 | printk(KERN_INFO "aoe: copy from user failed\n"); |
78 | return -EFAULT; | 78 | return -EFAULT; |
79 | } | 79 | } |
80 | aoe_iflist[size] = 0x00; | 80 | aoe_iflist[size] = 0x00; |
@@ -132,8 +132,7 @@ aoenet_rcv(struct sk_buff *skb, struct net_device *ifp, struct packet_type *pt, | |||
132 | if (n > NECODES) | 132 | if (n > NECODES) |
133 | n = 0; | 133 | n = 0; |
134 | if (net_ratelimit()) | 134 | if (net_ratelimit()) |
135 | printk(KERN_ERR "aoe: aoenet_rcv: error packet from %d.%d; " | 135 | printk(KERN_ERR "aoe: error packet from %d.%d; ecode=%d '%s'\n", |
136 | "ecode=%d '%s'\n", | ||
137 | be16_to_cpu(h->major), h->minor, | 136 | be16_to_cpu(h->major), h->minor, |
138 | h->err, aoe_errlist[n]); | 137 | h->err, aoe_errlist[n]); |
139 | goto exit; | 138 | goto exit; |
@@ -147,7 +146,7 @@ aoenet_rcv(struct sk_buff *skb, struct net_device *ifp, struct packet_type *pt, | |||
147 | aoecmd_cfg_rsp(skb); | 146 | aoecmd_cfg_rsp(skb); |
148 | break; | 147 | break; |
149 | default: | 148 | default: |
150 | printk(KERN_INFO "aoe: aoenet_rcv: unknown cmd %d\n", h->cmd); | 149 | printk(KERN_INFO "aoe: unknown cmd %d\n", h->cmd); |
151 | } | 150 | } |
152 | exit: | 151 | exit: |
153 | dev_kfree_skb(skb); | 152 | dev_kfree_skb(skb); |
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index dcccaf2782f3..4105c3bf3476 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
@@ -1300,6 +1300,12 @@ static void cciss_softirq_done(struct request *rq) | |||
1300 | 1300 | ||
1301 | complete_buffers(rq->bio, rq->errors); | 1301 | complete_buffers(rq->bio, rq->errors); |
1302 | 1302 | ||
1303 | if (blk_fs_request(rq)) { | ||
1304 | const int rw = rq_data_dir(rq); | ||
1305 | |||
1306 | disk_stat_add(rq->rq_disk, sectors[rw], rq->nr_sectors); | ||
1307 | } | ||
1308 | |||
1303 | #ifdef CCISS_DEBUG | 1309 | #ifdef CCISS_DEBUG |
1304 | printk("Done with %p\n", rq); | 1310 | printk("Done with %p\n", rq); |
1305 | #endif /* CCISS_DEBUG */ | 1311 | #endif /* CCISS_DEBUG */ |
@@ -1923,7 +1929,6 @@ static void cciss_geometry_inquiry(int ctlr, int logvol, | |||
1923 | { | 1929 | { |
1924 | int return_code; | 1930 | int return_code; |
1925 | unsigned long t; | 1931 | unsigned long t; |
1926 | unsigned long rem; | ||
1927 | 1932 | ||
1928 | memset(inq_buff, 0, sizeof(InquiryData_struct)); | 1933 | memset(inq_buff, 0, sizeof(InquiryData_struct)); |
1929 | if (withirq) | 1934 | if (withirq) |
@@ -1939,26 +1944,23 @@ static void cciss_geometry_inquiry(int ctlr, int logvol, | |||
1939 | printk(KERN_WARNING | 1944 | printk(KERN_WARNING |
1940 | "cciss: reading geometry failed, volume " | 1945 | "cciss: reading geometry failed, volume " |
1941 | "does not support reading geometry\n"); | 1946 | "does not support reading geometry\n"); |
1942 | drv->block_size = block_size; | ||
1943 | drv->nr_blocks = total_size; | ||
1944 | drv->heads = 255; | 1947 | drv->heads = 255; |
1945 | drv->sectors = 32; // Sectors per track | 1948 | drv->sectors = 32; // Sectors per track |
1946 | t = drv->heads * drv->sectors; | ||
1947 | drv->cylinders = total_size; | ||
1948 | rem = do_div(drv->cylinders, t); | ||
1949 | } else { | 1949 | } else { |
1950 | drv->block_size = block_size; | ||
1951 | drv->nr_blocks = total_size; | ||
1952 | drv->heads = inq_buff->data_byte[6]; | 1950 | drv->heads = inq_buff->data_byte[6]; |
1953 | drv->sectors = inq_buff->data_byte[7]; | 1951 | drv->sectors = inq_buff->data_byte[7]; |
1954 | drv->cylinders = (inq_buff->data_byte[4] & 0xff) << 8; | 1952 | drv->cylinders = (inq_buff->data_byte[4] & 0xff) << 8; |
1955 | drv->cylinders += inq_buff->data_byte[5]; | 1953 | drv->cylinders += inq_buff->data_byte[5]; |
1956 | drv->raid_level = inq_buff->data_byte[8]; | 1954 | drv->raid_level = inq_buff->data_byte[8]; |
1957 | t = drv->heads * drv->sectors; | 1955 | } |
1958 | if (t > 1) { | 1956 | drv->block_size = block_size; |
1959 | drv->cylinders = total_size; | 1957 | drv->nr_blocks = total_size; |
1960 | rem = do_div(drv->cylinders, t); | 1958 | t = drv->heads * drv->sectors; |
1961 | } | 1959 | if (t > 1) { |
1960 | unsigned rem = sector_div(total_size, t); | ||
1961 | if (rem) | ||
1962 | total_size++; | ||
1963 | drv->cylinders = total_size; | ||
1962 | } | 1964 | } |
1963 | } else { /* Get geometry failed */ | 1965 | } else { /* Get geometry failed */ |
1964 | printk(KERN_WARNING "cciss: reading geometry failed\n"); | 1966 | printk(KERN_WARNING "cciss: reading geometry failed\n"); |
@@ -1996,8 +1998,8 @@ cciss_read_capacity(int ctlr, int logvol, int withirq, sector_t *total_size, | |||
1996 | *block_size = BLOCK_SIZE; | 1998 | *block_size = BLOCK_SIZE; |
1997 | } | 1999 | } |
1998 | if (*total_size != (__u32) 0) | 2000 | if (*total_size != (__u32) 0) |
1999 | printk(KERN_INFO " blocks= %lld block_size= %d\n", | 2001 | printk(KERN_INFO " blocks= %llu block_size= %d\n", |
2000 | *total_size, *block_size); | 2002 | (unsigned long long)*total_size, *block_size); |
2001 | kfree(buf); | 2003 | kfree(buf); |
2002 | return; | 2004 | return; |
2003 | } | 2005 | } |
@@ -2031,8 +2033,8 @@ cciss_read_capacity_16(int ctlr, int logvol, int withirq, sector_t *total_size, | |||
2031 | *total_size = 0; | 2033 | *total_size = 0; |
2032 | *block_size = BLOCK_SIZE; | 2034 | *block_size = BLOCK_SIZE; |
2033 | } | 2035 | } |
2034 | printk(KERN_INFO " blocks= %lld block_size= %d\n", | 2036 | printk(KERN_INFO " blocks= %llu block_size= %d\n", |
2035 | *total_size, *block_size); | 2037 | (unsigned long long)*total_size, *block_size); |
2036 | kfree(buf); | 2038 | kfree(buf); |
2037 | return; | 2039 | return; |
2038 | } | 2040 | } |
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c index 570d2f049323..d5f519ebbc08 100644 --- a/drivers/block/cpqarray.c +++ b/drivers/block/cpqarray.c | |||
@@ -998,6 +998,7 @@ static inline void complete_buffers(struct bio *bio, int ok) | |||
998 | */ | 998 | */ |
999 | static inline void complete_command(cmdlist_t *cmd, int timeout) | 999 | static inline void complete_command(cmdlist_t *cmd, int timeout) |
1000 | { | 1000 | { |
1001 | struct request *rq = cmd->rq; | ||
1001 | int ok=1; | 1002 | int ok=1; |
1002 | int i, ddir; | 1003 | int i, ddir; |
1003 | 1004 | ||
@@ -1029,12 +1030,18 @@ static inline void complete_command(cmdlist_t *cmd, int timeout) | |||
1029 | pci_unmap_page(hba[cmd->ctlr]->pci_dev, cmd->req.sg[i].addr, | 1030 | pci_unmap_page(hba[cmd->ctlr]->pci_dev, cmd->req.sg[i].addr, |
1030 | cmd->req.sg[i].size, ddir); | 1031 | cmd->req.sg[i].size, ddir); |
1031 | 1032 | ||
1032 | complete_buffers(cmd->rq->bio, ok); | 1033 | complete_buffers(rq->bio, ok); |
1033 | 1034 | ||
1034 | add_disk_randomness(cmd->rq->rq_disk); | 1035 | if (blk_fs_request(rq)) { |
1036 | const int rw = rq_data_dir(rq); | ||
1035 | 1037 | ||
1036 | DBGPX(printk("Done with %p\n", cmd->rq);); | 1038 | disk_stat_add(rq->rq_disk, sectors[rw], rq->nr_sectors); |
1037 | end_that_request_last(cmd->rq, ok ? 1 : -EIO); | 1039 | } |
1040 | |||
1041 | add_disk_randomness(rq->rq_disk); | ||
1042 | |||
1043 | DBGPX(printk("Done with %p\n", rq);); | ||
1044 | end_that_request_last(rq, ok ? 1 : -EIO); | ||
1038 | } | 1045 | } |
1039 | 1046 | ||
1040 | /* | 1047 | /* |
diff --git a/drivers/block/rd.c b/drivers/block/rd.c index a3f64bfe6b58..485aa87e9bcd 100644 --- a/drivers/block/rd.c +++ b/drivers/block/rd.c | |||
@@ -432,6 +432,12 @@ static int __init rd_init(void) | |||
432 | rd_disks[i] = alloc_disk(1); | 432 | rd_disks[i] = alloc_disk(1); |
433 | if (!rd_disks[i]) | 433 | if (!rd_disks[i]) |
434 | goto out; | 434 | goto out; |
435 | |||
436 | rd_queue[i] = blk_alloc_queue(GFP_KERNEL); | ||
437 | if (!rd_queue[i]) { | ||
438 | put_disk(rd_disks[i]); | ||
439 | goto out; | ||
440 | } | ||
435 | } | 441 | } |
436 | 442 | ||
437 | if (register_blkdev(RAMDISK_MAJOR, "ramdisk")) { | 443 | if (register_blkdev(RAMDISK_MAJOR, "ramdisk")) { |
@@ -442,10 +448,6 @@ static int __init rd_init(void) | |||
442 | for (i = 0; i < CONFIG_BLK_DEV_RAM_COUNT; i++) { | 448 | for (i = 0; i < CONFIG_BLK_DEV_RAM_COUNT; i++) { |
443 | struct gendisk *disk = rd_disks[i]; | 449 | struct gendisk *disk = rd_disks[i]; |
444 | 450 | ||
445 | rd_queue[i] = blk_alloc_queue(GFP_KERNEL); | ||
446 | if (!rd_queue[i]) | ||
447 | goto out_queue; | ||
448 | |||
449 | blk_queue_make_request(rd_queue[i], &rd_make_request); | 451 | blk_queue_make_request(rd_queue[i], &rd_make_request); |
450 | blk_queue_hardsect_size(rd_queue[i], rd_blocksize); | 452 | blk_queue_hardsect_size(rd_queue[i], rd_blocksize); |
451 | 453 | ||
@@ -466,8 +468,6 @@ static int __init rd_init(void) | |||
466 | CONFIG_BLK_DEV_RAM_COUNT, rd_size, rd_blocksize); | 468 | CONFIG_BLK_DEV_RAM_COUNT, rd_size, rd_blocksize); |
467 | 469 | ||
468 | return 0; | 470 | return 0; |
469 | out_queue: | ||
470 | unregister_blkdev(RAMDISK_MAJOR, "ramdisk"); | ||
471 | out: | 471 | out: |
472 | while (i--) { | 472 | while (i--) { |
473 | put_disk(rd_disks[i]); | 473 | put_disk(rd_disks[i]); |
diff --git a/drivers/block/xd.c b/drivers/block/xd.c index 10cc38783bdf..0d97b7eb818a 100644 --- a/drivers/block/xd.c +++ b/drivers/block/xd.c | |||
@@ -48,9 +48,9 @@ | |||
48 | #include <linux/blkdev.h> | 48 | #include <linux/blkdev.h> |
49 | #include <linux/blkpg.h> | 49 | #include <linux/blkpg.h> |
50 | #include <linux/delay.h> | 50 | #include <linux/delay.h> |
51 | #include <linux/io.h> | ||
51 | 52 | ||
52 | #include <asm/system.h> | 53 | #include <asm/system.h> |
53 | #include <asm/io.h> | ||
54 | #include <asm/uaccess.h> | 54 | #include <asm/uaccess.h> |
55 | #include <asm/dma.h> | 55 | #include <asm/dma.h> |
56 | 56 | ||
diff --git a/drivers/block/z2ram.c b/drivers/block/z2ram.c index 82ddbdd7bd4b..7cc2685ca84a 100644 --- a/drivers/block/z2ram.c +++ b/drivers/block/z2ram.c | |||
@@ -329,7 +329,7 @@ static struct kobject *z2_find(dev_t dev, int *part, void *data) | |||
329 | 329 | ||
330 | static struct request_queue *z2_queue; | 330 | static struct request_queue *z2_queue; |
331 | 331 | ||
332 | int __init | 332 | static int __init |
333 | z2_init(void) | 333 | z2_init(void) |
334 | { | 334 | { |
335 | int ret; | 335 | int ret; |
@@ -370,26 +370,7 @@ err: | |||
370 | return ret; | 370 | return ret; |
371 | } | 371 | } |
372 | 372 | ||
373 | #if defined(MODULE) | 373 | static void __exit z2_exit(void) |
374 | |||
375 | MODULE_LICENSE("GPL"); | ||
376 | |||
377 | int | ||
378 | init_module( void ) | ||
379 | { | ||
380 | int error; | ||
381 | |||
382 | error = z2_init(); | ||
383 | if ( error == 0 ) | ||
384 | { | ||
385 | printk( KERN_INFO DEVICE_NAME ": loaded as module\n" ); | ||
386 | } | ||
387 | |||
388 | return error; | ||
389 | } | ||
390 | |||
391 | void | ||
392 | cleanup_module( void ) | ||
393 | { | 374 | { |
394 | int i, j; | 375 | int i, j; |
395 | blk_unregister_region(MKDEV(Z2RAM_MAJOR, 0), 256); | 376 | blk_unregister_region(MKDEV(Z2RAM_MAJOR, 0), 256); |
@@ -425,4 +406,7 @@ cleanup_module( void ) | |||
425 | 406 | ||
426 | return; | 407 | return; |
427 | } | 408 | } |
428 | #endif | 409 | |
410 | module_init(z2_init); | ||
411 | module_exit(z2_exit); | ||
412 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/bluetooth/bcm203x.c b/drivers/bluetooth/bcm203x.c index 67cdda43f229..516751754aa9 100644 --- a/drivers/bluetooth/bcm203x.c +++ b/drivers/bluetooth/bcm203x.c | |||
@@ -29,7 +29,6 @@ | |||
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/types.h> | 30 | #include <linux/types.h> |
31 | #include <linux/errno.h> | 31 | #include <linux/errno.h> |
32 | #include <linux/timer.h> | ||
33 | 32 | ||
34 | #include <linux/device.h> | 33 | #include <linux/device.h> |
35 | #include <linux/firmware.h> | 34 | #include <linux/firmware.h> |
@@ -43,7 +42,7 @@ | |||
43 | #define BT_DBG(D...) | 42 | #define BT_DBG(D...) |
44 | #endif | 43 | #endif |
45 | 44 | ||
46 | #define VERSION "1.0" | 45 | #define VERSION "1.1" |
47 | 46 | ||
48 | static int ignore = 0; | 47 | static int ignore = 0; |
49 | 48 | ||
@@ -72,7 +71,7 @@ struct bcm203x_data { | |||
72 | 71 | ||
73 | unsigned long state; | 72 | unsigned long state; |
74 | 73 | ||
75 | struct timer_list timer; | 74 | struct work_struct work; |
76 | 75 | ||
77 | struct urb *urb; | 76 | struct urb *urb; |
78 | unsigned char *buffer; | 77 | unsigned char *buffer; |
@@ -105,7 +104,7 @@ static void bcm203x_complete(struct urb *urb) | |||
105 | 104 | ||
106 | data->state = BCM203X_SELECT_MEMORY; | 105 | data->state = BCM203X_SELECT_MEMORY; |
107 | 106 | ||
108 | mod_timer(&data->timer, jiffies + (HZ / 10)); | 107 | schedule_work(&data->work); |
109 | break; | 108 | break; |
110 | 109 | ||
111 | case BCM203X_SELECT_MEMORY: | 110 | case BCM203X_SELECT_MEMORY: |
@@ -158,9 +157,9 @@ static void bcm203x_complete(struct urb *urb) | |||
158 | } | 157 | } |
159 | } | 158 | } |
160 | 159 | ||
161 | static void bcm203x_timer(unsigned long user_data) | 160 | static void bcm203x_work(void *user_data) |
162 | { | 161 | { |
163 | struct bcm203x_data *data = (struct bcm203x_data *) user_data; | 162 | struct bcm203x_data *data = user_data; |
164 | 163 | ||
165 | if (usb_submit_urb(data->urb, GFP_ATOMIC) < 0) | 164 | if (usb_submit_urb(data->urb, GFP_ATOMIC) < 0) |
166 | BT_ERR("Can't submit URB"); | 165 | BT_ERR("Can't submit URB"); |
@@ -247,13 +246,11 @@ static int bcm203x_probe(struct usb_interface *intf, const struct usb_device_id | |||
247 | 246 | ||
248 | release_firmware(firmware); | 247 | release_firmware(firmware); |
249 | 248 | ||
250 | init_timer(&data->timer); | 249 | INIT_WORK(&data->work, bcm203x_work, (void *) data); |
251 | data->timer.function = bcm203x_timer; | ||
252 | data->timer.data = (unsigned long) data; | ||
253 | 250 | ||
254 | usb_set_intfdata(intf, data); | 251 | usb_set_intfdata(intf, data); |
255 | 252 | ||
256 | mod_timer(&data->timer, jiffies + HZ); | 253 | schedule_work(&data->work); |
257 | 254 | ||
258 | return 0; | 255 | return 0; |
259 | } | 256 | } |
diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c index 845b8680032a..cbc07250b898 100644 --- a/drivers/bluetooth/bluecard_cs.c +++ b/drivers/bluetooth/bluecard_cs.c | |||
@@ -282,7 +282,7 @@ static void bluecard_write_wakeup(bluecard_info_t *info) | |||
282 | clear_bit(ready_bit, &(info->tx_state)); | 282 | clear_bit(ready_bit, &(info->tx_state)); |
283 | 283 | ||
284 | if (bt_cb(skb)->pkt_type & 0x80) { | 284 | if (bt_cb(skb)->pkt_type & 0x80) { |
285 | DECLARE_WAIT_QUEUE_HEAD(wq); | 285 | DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq); |
286 | DEFINE_WAIT(wait); | 286 | DEFINE_WAIT(wait); |
287 | 287 | ||
288 | unsigned char baud_reg; | 288 | unsigned char baud_reg; |
diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c index e7c800f4c3ad..07eafbc5dc3a 100644 --- a/drivers/bluetooth/dtl1_cs.c +++ b/drivers/bluetooth/dtl1_cs.c | |||
@@ -711,6 +711,7 @@ static void dtl1_release(struct pcmcia_device *link) | |||
711 | 711 | ||
712 | static struct pcmcia_device_id dtl1_ids[] = { | 712 | static struct pcmcia_device_id dtl1_ids[] = { |
713 | PCMCIA_DEVICE_PROD_ID12("Nokia Mobile Phones", "DTL-1", 0xe1bfdd64, 0xe168480d), | 713 | PCMCIA_DEVICE_PROD_ID12("Nokia Mobile Phones", "DTL-1", 0xe1bfdd64, 0xe168480d), |
714 | PCMCIA_DEVICE_PROD_ID12("Nokia Mobile Phones", "DTL-4", 0xe1bfdd64, 0x9102bc82), | ||
714 | PCMCIA_DEVICE_PROD_ID12("Socket", "CF", 0xb38bcc2e, 0x44ebf863), | 715 | PCMCIA_DEVICE_PROD_ID12("Socket", "CF", 0xb38bcc2e, 0x44ebf863), |
715 | PCMCIA_DEVICE_PROD_ID12("Socket", "CF+ Personal Network Card", 0xb38bcc2e, 0xe732bae3), | 716 | PCMCIA_DEVICE_PROD_ID12("Socket", "CF+ Personal Network Card", 0xb38bcc2e, 0xe732bae3), |
716 | PCMCIA_DEVICE_NULL | 717 | PCMCIA_DEVICE_NULL |
diff --git a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c index 7565642a007a..fdea58ae16b2 100644 --- a/drivers/bluetooth/hci_usb.c +++ b/drivers/bluetooth/hci_usb.c | |||
@@ -118,6 +118,9 @@ static struct usb_device_id blacklist_ids[] = { | |||
118 | /* IBM/Lenovo ThinkPad with Broadcom chip */ | 118 | /* IBM/Lenovo ThinkPad with Broadcom chip */ |
119 | { USB_DEVICE(0x0a5c, 0x201e), .driver_info = HCI_WRONG_SCO_MTU }, | 119 | { USB_DEVICE(0x0a5c, 0x201e), .driver_info = HCI_WRONG_SCO_MTU }, |
120 | 120 | ||
121 | /* ANYCOM Bluetooth USB-200 and USB-250 */ | ||
122 | { USB_DEVICE(0x0a5c, 0x2111), .driver_info = HCI_RESET }, | ||
123 | |||
121 | /* Microsoft Wireless Transceiver for Bluetooth 2.0 */ | 124 | /* Microsoft Wireless Transceiver for Bluetooth 2.0 */ |
122 | { USB_DEVICE(0x045e, 0x009c), .driver_info = HCI_RESET }, | 125 | { USB_DEVICE(0x045e, 0x009c), .driver_info = HCI_RESET }, |
123 | 126 | ||
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 0e6f35fcc2eb..2af12fc45115 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -409,14 +409,6 @@ config SGI_MBCS | |||
409 | If you have an SGI Altix with an attached SABrick | 409 | If you have an SGI Altix with an attached SABrick |
410 | say Y or M here, otherwise say N. | 410 | say Y or M here, otherwise say N. |
411 | 411 | ||
412 | config MSPEC | ||
413 | tristate "Memory special operations driver" | ||
414 | depends on IA64 | ||
415 | help | ||
416 | If you have an ia64 and you want to enable memory special | ||
417 | operations support (formerly known as fetchop), say Y here, | ||
418 | otherwise say N. | ||
419 | |||
420 | source "drivers/serial/Kconfig" | 412 | source "drivers/serial/Kconfig" |
421 | 413 | ||
422 | config UNIX98_PTYS | 414 | config UNIX98_PTYS |
@@ -1046,7 +1038,7 @@ source "drivers/char/tpm/Kconfig" | |||
1046 | 1038 | ||
1047 | config TELCLOCK | 1039 | config TELCLOCK |
1048 | tristate "Telecom clock driver for MPBL0010 ATCA SBC" | 1040 | tristate "Telecom clock driver for MPBL0010 ATCA SBC" |
1049 | depends on EXPERIMENTAL | 1041 | depends on EXPERIMENTAL && X86 |
1050 | default n | 1042 | default n |
1051 | help | 1043 | help |
1052 | The telecom clock device is specific to the MPBL0010 ATCA computer and | 1044 | The telecom clock device is specific to the MPBL0010 ATCA computer and |
diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c index 91b71e750ee1..dffc19382f7e 100644 --- a/drivers/char/agp/uninorth-agp.c +++ b/drivers/char/agp/uninorth-agp.c | |||
@@ -27,32 +27,42 @@ | |||
27 | static int uninorth_rev; | 27 | static int uninorth_rev; |
28 | static int is_u3; | 28 | static int is_u3; |
29 | 29 | ||
30 | static char __devinitdata *aperture = NULL; | ||
30 | 31 | ||
31 | static int uninorth_fetch_size(void) | 32 | static int uninorth_fetch_size(void) |
32 | { | 33 | { |
33 | int i; | 34 | int i, size = 0; |
34 | u32 temp; | 35 | struct aper_size_info_32 *values = |
35 | struct aper_size_info_32 *values; | 36 | A_SIZE_32(agp_bridge->driver->aperture_sizes); |
36 | 37 | ||
37 | pci_read_config_dword(agp_bridge->dev, UNI_N_CFG_GART_BASE, &temp); | 38 | if (aperture) { |
38 | temp &= ~(0xfffff000); | 39 | char *save = aperture; |
39 | values = A_SIZE_32(agp_bridge->driver->aperture_sizes); | 40 | |
40 | 41 | size = memparse(aperture, &aperture) >> 20; | |
41 | for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) { | 42 | aperture = save; |
42 | if (temp == values[i].size_value) { | 43 | |
43 | agp_bridge->previous_size = | 44 | for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) |
44 | agp_bridge->current_size = (void *) (values + i); | 45 | if (size == values[i].size) |
45 | agp_bridge->aperture_size_idx = i; | 46 | break; |
46 | return values[i].size; | 47 | |
48 | if (i == agp_bridge->driver->num_aperture_sizes) { | ||
49 | printk(KERN_ERR PFX "Invalid aperture size, using" | ||
50 | " default\n"); | ||
51 | size = 0; | ||
52 | aperture = NULL; | ||
47 | } | 53 | } |
48 | } | 54 | } |
49 | 55 | ||
50 | agp_bridge->previous_size = | 56 | if (!size) { |
51 | agp_bridge->current_size = (void *) (values + 1); | 57 | for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) |
52 | agp_bridge->aperture_size_idx = 1; | 58 | if (values[i].size == 32) |
53 | return values[1].size; | 59 | break; |
60 | } | ||
54 | 61 | ||
55 | return 0; | 62 | agp_bridge->previous_size = |
63 | agp_bridge->current_size = (void *)(values + i); | ||
64 | agp_bridge->aperture_size_idx = i; | ||
65 | return values[i].size; | ||
56 | } | 66 | } |
57 | 67 | ||
58 | static void uninorth_tlbflush(struct agp_memory *mem) | 68 | static void uninorth_tlbflush(struct agp_memory *mem) |
@@ -683,5 +693,11 @@ static void __exit agp_uninorth_cleanup(void) | |||
683 | module_init(agp_uninorth_init); | 693 | module_init(agp_uninorth_init); |
684 | module_exit(agp_uninorth_cleanup); | 694 | module_exit(agp_uninorth_cleanup); |
685 | 695 | ||
696 | module_param(aperture, charp, 0); | ||
697 | MODULE_PARM_DESC(aperture, | ||
698 | "Aperture size, must be power of two between 4MB and an\n" | ||
699 | "\t\tupper limit specific to the UniNorth revision.\n" | ||
700 | "\t\tDefault: 32M"); | ||
701 | |||
686 | MODULE_AUTHOR("Ben Herrenschmidt & Paul Mackerras"); | 702 | MODULE_AUTHOR("Ben Herrenschmidt & Paul Mackerras"); |
687 | MODULE_LICENSE("GPL"); | 703 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c index 029baea33b62..6eafff13dab6 100644 --- a/drivers/char/drm/drm_bufs.c +++ b/drivers/char/drm/drm_bufs.c | |||
@@ -237,6 +237,8 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset, | |||
237 | 237 | ||
238 | list = drm_alloc(sizeof(*list), DRM_MEM_MAPS); | 238 | list = drm_alloc(sizeof(*list), DRM_MEM_MAPS); |
239 | if (!list) { | 239 | if (!list) { |
240 | if (map->type == _DRM_REGISTERS) | ||
241 | drm_ioremapfree(map->handle, map->size, dev); | ||
240 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); | 242 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); |
241 | return -EINVAL; | 243 | return -EINVAL; |
242 | } | 244 | } |
@@ -252,6 +254,8 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset, | |||
252 | map->offset; | 254 | map->offset; |
253 | ret = drm_map_handle(dev, &list->hash, user_token, 0); | 255 | ret = drm_map_handle(dev, &list->hash, user_token, 0); |
254 | if (ret) { | 256 | if (ret) { |
257 | if (map->type == _DRM_REGISTERS) | ||
258 | drm_ioremapfree(map->handle, map->size, dev); | ||
255 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); | 259 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); |
256 | drm_free(list, sizeof(*list), DRM_MEM_MAPS); | 260 | drm_free(list, sizeof(*list), DRM_MEM_MAPS); |
257 | mutex_unlock(&dev->struct_mutex); | 261 | mutex_unlock(&dev->struct_mutex); |
diff --git a/drivers/char/drm/drm_sysfs.c b/drivers/char/drm/drm_sysfs.c index 51ad98c685c3..ba4b8de83cf0 100644 --- a/drivers/char/drm/drm_sysfs.c +++ b/drivers/char/drm/drm_sysfs.c | |||
@@ -42,13 +42,24 @@ static CLASS_ATTR(version, S_IRUGO, version_show, NULL); | |||
42 | struct class *drm_sysfs_create(struct module *owner, char *name) | 42 | struct class *drm_sysfs_create(struct module *owner, char *name) |
43 | { | 43 | { |
44 | struct class *class; | 44 | struct class *class; |
45 | int err; | ||
45 | 46 | ||
46 | class = class_create(owner, name); | 47 | class = class_create(owner, name); |
47 | if (!class) | 48 | if (!class) { |
48 | return class; | 49 | err = -ENOMEM; |
50 | goto err_out; | ||
51 | } | ||
52 | |||
53 | err = class_create_file(class, &class_attr_version); | ||
54 | if (err) | ||
55 | goto err_out_class; | ||
49 | 56 | ||
50 | class_create_file(class, &class_attr_version); | ||
51 | return class; | 57 | return class; |
58 | |||
59 | err_out_class: | ||
60 | class_destroy(class); | ||
61 | err_out: | ||
62 | return ERR_PTR(err); | ||
52 | } | 63 | } |
53 | 64 | ||
54 | /** | 65 | /** |
@@ -96,20 +107,36 @@ static struct class_device_attribute class_device_attrs[] = { | |||
96 | struct class_device *drm_sysfs_device_add(struct class *cs, drm_head_t *head) | 107 | struct class_device *drm_sysfs_device_add(struct class *cs, drm_head_t *head) |
97 | { | 108 | { |
98 | struct class_device *class_dev; | 109 | struct class_device *class_dev; |
99 | int i; | 110 | int i, j, err; |
100 | 111 | ||
101 | class_dev = class_device_create(cs, NULL, | 112 | class_dev = class_device_create(cs, NULL, |
102 | MKDEV(DRM_MAJOR, head->minor), | 113 | MKDEV(DRM_MAJOR, head->minor), |
103 | &(head->dev->pdev)->dev, | 114 | &(head->dev->pdev)->dev, |
104 | "card%d", head->minor); | 115 | "card%d", head->minor); |
105 | if (!class_dev) | 116 | if (!class_dev) { |
106 | return NULL; | 117 | err = -ENOMEM; |
118 | goto err_out; | ||
119 | } | ||
107 | 120 | ||
108 | class_set_devdata(class_dev, head); | 121 | class_set_devdata(class_dev, head); |
109 | 122 | ||
110 | for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) | 123 | for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) { |
111 | class_device_create_file(class_dev, &class_device_attrs[i]); | 124 | err = class_device_create_file(class_dev, |
125 | &class_device_attrs[i]); | ||
126 | if (err) | ||
127 | goto err_out_files; | ||
128 | } | ||
129 | |||
112 | return class_dev; | 130 | return class_dev; |
131 | |||
132 | err_out_files: | ||
133 | if (i > 0) | ||
134 | for (j = 0; j < i; j++) | ||
135 | class_device_remove_file(class_dev, | ||
136 | &class_device_attrs[i]); | ||
137 | class_device_unregister(class_dev); | ||
138 | err_out: | ||
139 | return ERR_PTR(err); | ||
113 | } | 140 | } |
114 | 141 | ||
115 | /** | 142 | /** |
diff --git a/drivers/char/drm/mga_drv.c b/drivers/char/drm/mga_drv.c index e30f556b79f1..be49dbb9ec3f 100644 --- a/drivers/char/drm/mga_drv.c +++ b/drivers/char/drm/mga_drv.c | |||
@@ -47,6 +47,7 @@ static struct drm_driver driver = { | |||
47 | DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | | 47 | DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | |
48 | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | | 48 | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | |
49 | DRIVER_IRQ_VBL, | 49 | DRIVER_IRQ_VBL, |
50 | .dev_priv_size = sizeof(drm_mga_buf_priv_t), | ||
50 | .load = mga_driver_load, | 51 | .load = mga_driver_load, |
51 | .unload = mga_driver_unload, | 52 | .unload = mga_driver_unload, |
52 | .lastclose = mga_driver_lastclose, | 53 | .lastclose = mga_driver_lastclose, |
diff --git a/drivers/char/drm/r300_cmdbuf.c b/drivers/char/drm/r300_cmdbuf.c index 26bdf2ca59d7..d14477ba3679 100644 --- a/drivers/char/drm/r300_cmdbuf.c +++ b/drivers/char/drm/r300_cmdbuf.c | |||
@@ -538,6 +538,36 @@ static __inline__ int r300_emit_bitblt_multi(drm_radeon_private_t *dev_priv, | |||
538 | return 0; | 538 | return 0; |
539 | } | 539 | } |
540 | 540 | ||
541 | static __inline__ int r300_emit_indx_buffer(drm_radeon_private_t *dev_priv, | ||
542 | drm_radeon_kcmd_buffer_t *cmdbuf) | ||
543 | { | ||
544 | u32 *cmd = (u32 *) cmdbuf->buf; | ||
545 | int count, ret; | ||
546 | RING_LOCALS; | ||
547 | |||
548 | count=(cmd[0]>>16) & 0x3fff; | ||
549 | |||
550 | if ((cmd[1] & 0x8000ffff) != 0x80000810) { | ||
551 | DRM_ERROR("Invalid indx_buffer reg address %08X\n", cmd[1]); | ||
552 | return DRM_ERR(EINVAL); | ||
553 | } | ||
554 | ret = r300_check_offset(dev_priv, cmd[2]); | ||
555 | if (ret) { | ||
556 | DRM_ERROR("Invalid indx_buffer offset is %08X\n", cmd[2]); | ||
557 | return DRM_ERR(EINVAL); | ||
558 | } | ||
559 | |||
560 | BEGIN_RING(count+2); | ||
561 | OUT_RING(cmd[0]); | ||
562 | OUT_RING_TABLE((int *)(cmdbuf->buf + 4), count + 1); | ||
563 | ADVANCE_RING(); | ||
564 | |||
565 | cmdbuf->buf += (count+2)*4; | ||
566 | cmdbuf->bufsz -= (count+2)*4; | ||
567 | |||
568 | return 0; | ||
569 | } | ||
570 | |||
541 | static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t *dev_priv, | 571 | static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t *dev_priv, |
542 | drm_radeon_kcmd_buffer_t *cmdbuf) | 572 | drm_radeon_kcmd_buffer_t *cmdbuf) |
543 | { | 573 | { |
@@ -578,10 +608,11 @@ static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t *dev_priv, | |||
578 | case RADEON_CNTL_BITBLT_MULTI: | 608 | case RADEON_CNTL_BITBLT_MULTI: |
579 | return r300_emit_bitblt_multi(dev_priv, cmdbuf); | 609 | return r300_emit_bitblt_multi(dev_priv, cmdbuf); |
580 | 610 | ||
611 | case RADEON_CP_INDX_BUFFER: /* DRAW_INDX_2 without INDX_BUFFER seems to lock up the gpu */ | ||
612 | return r300_emit_indx_buffer(dev_priv, cmdbuf); | ||
581 | case RADEON_CP_3D_DRAW_IMMD_2: /* triggers drawing using in-packet vertex data */ | 613 | case RADEON_CP_3D_DRAW_IMMD_2: /* triggers drawing using in-packet vertex data */ |
582 | case RADEON_CP_3D_DRAW_VBUF_2: /* triggers drawing of vertex buffers setup elsewhere */ | 614 | case RADEON_CP_3D_DRAW_VBUF_2: /* triggers drawing of vertex buffers setup elsewhere */ |
583 | case RADEON_CP_3D_DRAW_INDX_2: /* triggers drawing using indices to vertex buffer */ | 615 | case RADEON_CP_3D_DRAW_INDX_2: /* triggers drawing using indices to vertex buffer */ |
584 | case RADEON_CP_INDX_BUFFER: /* DRAW_INDX_2 without INDX_BUFFER seems to lock up the gpu */ | ||
585 | case RADEON_WAIT_FOR_IDLE: | 616 | case RADEON_WAIT_FOR_IDLE: |
586 | case RADEON_CP_NOP: | 617 | case RADEON_CP_NOP: |
587 | /* these packets are safe */ | 618 | /* these packets are safe */ |
diff --git a/drivers/char/drm/radeon_state.c b/drivers/char/drm/radeon_state.c index feac5f005d47..6e04fdd732ac 100644 --- a/drivers/char/drm/radeon_state.c +++ b/drivers/char/drm/radeon_state.c | |||
@@ -275,6 +275,8 @@ static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t * | |||
275 | unsigned int *cmdsz) | 275 | unsigned int *cmdsz) |
276 | { | 276 | { |
277 | u32 *cmd = (u32 *) cmdbuf->buf; | 277 | u32 *cmd = (u32 *) cmdbuf->buf; |
278 | u32 offset, narrays; | ||
279 | int count, i, k; | ||
278 | 280 | ||
279 | *cmdsz = 2 + ((cmd[0] & RADEON_CP_PACKET_COUNT_MASK) >> 16); | 281 | *cmdsz = 2 + ((cmd[0] & RADEON_CP_PACKET_COUNT_MASK) >> 16); |
280 | 282 | ||
@@ -288,10 +290,106 @@ static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t * | |||
288 | return DRM_ERR(EINVAL); | 290 | return DRM_ERR(EINVAL); |
289 | } | 291 | } |
290 | 292 | ||
291 | /* Check client state and fix it up if necessary */ | 293 | switch(cmd[0] & 0xff00) { |
292 | if (cmd[0] & 0x8000) { /* MSB of opcode: next DWORD GUI_CNTL */ | 294 | /* XXX Are there old drivers needing other packets? */ |
293 | u32 offset; | ||
294 | 295 | ||
296 | case RADEON_3D_DRAW_IMMD: | ||
297 | case RADEON_3D_DRAW_VBUF: | ||
298 | case RADEON_3D_DRAW_INDX: | ||
299 | case RADEON_WAIT_FOR_IDLE: | ||
300 | case RADEON_CP_NOP: | ||
301 | case RADEON_3D_CLEAR_ZMASK: | ||
302 | /* case RADEON_CP_NEXT_CHAR: | ||
303 | case RADEON_CP_PLY_NEXTSCAN: | ||
304 | case RADEON_CP_SET_SCISSORS: */ /* probably safe but will never need them? */ | ||
305 | /* these packets are safe */ | ||
306 | break; | ||
307 | |||
308 | case RADEON_CP_3D_DRAW_IMMD_2: | ||
309 | case RADEON_CP_3D_DRAW_VBUF_2: | ||
310 | case RADEON_CP_3D_DRAW_INDX_2: | ||
311 | case RADEON_3D_CLEAR_HIZ: | ||
312 | /* safe but r200 only */ | ||
313 | if (dev_priv->microcode_version != UCODE_R200) { | ||
314 | DRM_ERROR("Invalid 3d packet for r100-class chip\n"); | ||
315 | return DRM_ERR(EINVAL); | ||
316 | } | ||
317 | break; | ||
318 | |||
319 | case RADEON_3D_LOAD_VBPNTR: | ||
320 | count = (cmd[0] >> 16) & 0x3fff; | ||
321 | |||
322 | if (count > 18) { /* 12 arrays max */ | ||
323 | DRM_ERROR("Too large payload in 3D_LOAD_VBPNTR (count=%d)\n", | ||
324 | count); | ||
325 | return DRM_ERR(EINVAL); | ||
326 | } | ||
327 | |||
328 | /* carefully check packet contents */ | ||
329 | narrays = cmd[1] & ~0xc000; | ||
330 | k = 0; | ||
331 | i = 2; | ||
332 | while ((k < narrays) && (i < (count + 2))) { | ||
333 | i++; /* skip attribute field */ | ||
334 | if (radeon_check_and_fixup_offset(dev_priv, filp_priv, &cmd[i])) { | ||
335 | DRM_ERROR | ||
336 | ("Invalid offset (k=%d i=%d) in 3D_LOAD_VBPNTR packet.\n", | ||
337 | k, i); | ||
338 | return DRM_ERR(EINVAL); | ||
339 | } | ||
340 | k++; | ||
341 | i++; | ||
342 | if (k == narrays) | ||
343 | break; | ||
344 | /* have one more to process, they come in pairs */ | ||
345 | if (radeon_check_and_fixup_offset(dev_priv, filp_priv, &cmd[i])) { | ||
346 | DRM_ERROR | ||
347 | ("Invalid offset (k=%d i=%d) in 3D_LOAD_VBPNTR packet.\n", | ||
348 | k, i); | ||
349 | return DRM_ERR(EINVAL); | ||
350 | } | ||
351 | k++; | ||
352 | i++; | ||
353 | } | ||
354 | /* do the counts match what we expect ? */ | ||
355 | if ((k != narrays) || (i != (count + 2))) { | ||
356 | DRM_ERROR | ||
357 | ("Malformed 3D_LOAD_VBPNTR packet (k=%d i=%d narrays=%d count+1=%d).\n", | ||
358 | k, i, narrays, count + 1); | ||
359 | return DRM_ERR(EINVAL); | ||
360 | } | ||
361 | break; | ||
362 | |||
363 | case RADEON_3D_RNDR_GEN_INDX_PRIM: | ||
364 | if (dev_priv->microcode_version != UCODE_R100) { | ||
365 | DRM_ERROR("Invalid 3d packet for r200-class chip\n"); | ||
366 | return DRM_ERR(EINVAL); | ||
367 | } | ||
368 | if (radeon_check_and_fixup_offset(dev_priv, filp_priv, &cmd[1])) { | ||
369 | DRM_ERROR("Invalid rndr_gen_indx offset\n"); | ||
370 | return DRM_ERR(EINVAL); | ||
371 | } | ||
372 | break; | ||
373 | |||
374 | case RADEON_CP_INDX_BUFFER: | ||
375 | if (dev_priv->microcode_version != UCODE_R200) { | ||
376 | DRM_ERROR("Invalid 3d packet for r100-class chip\n"); | ||
377 | return DRM_ERR(EINVAL); | ||
378 | } | ||
379 | if ((cmd[1] & 0x8000ffff) != 0x80000810) { | ||
380 | DRM_ERROR("Invalid indx_buffer reg address %08X\n", cmd[1]); | ||
381 | return DRM_ERR(EINVAL); | ||
382 | } | ||
383 | if (radeon_check_and_fixup_offset(dev_priv, filp_priv, &cmd[2])) { | ||
384 | DRM_ERROR("Invalid indx_buffer offset is %08X\n", cmd[2]); | ||
385 | return DRM_ERR(EINVAL); | ||
386 | } | ||
387 | break; | ||
388 | |||
389 | case RADEON_CNTL_HOSTDATA_BLT: | ||
390 | case RADEON_CNTL_PAINT_MULTI: | ||
391 | case RADEON_CNTL_BITBLT_MULTI: | ||
392 | /* MSB of opcode: next DWORD GUI_CNTL */ | ||
295 | if (cmd[1] & (RADEON_GMC_SRC_PITCH_OFFSET_CNTL | 393 | if (cmd[1] & (RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
296 | | RADEON_GMC_DST_PITCH_OFFSET_CNTL)) { | 394 | | RADEON_GMC_DST_PITCH_OFFSET_CNTL)) { |
297 | offset = cmd[2] << 10; | 395 | offset = cmd[2] << 10; |
@@ -313,6 +411,11 @@ static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t * | |||
313 | } | 411 | } |
314 | cmd[3] = (cmd[3] & 0xffc00000) | offset >> 10; | 412 | cmd[3] = (cmd[3] & 0xffc00000) | offset >> 10; |
315 | } | 413 | } |
414 | break; | ||
415 | |||
416 | default: | ||
417 | DRM_ERROR("Invalid packet type %x\n", cmd[0] & 0xff00); | ||
418 | return DRM_ERR(EINVAL); | ||
316 | } | 419 | } |
317 | 420 | ||
318 | return 0; | 421 | return 0; |
diff --git a/drivers/char/drm/savage_bci.c b/drivers/char/drm/savage_bci.c index 59c7520bf9a2..a9a84f88df5e 100644 --- a/drivers/char/drm/savage_bci.c +++ b/drivers/char/drm/savage_bci.c | |||
@@ -728,6 +728,7 @@ static int savage_do_init_bci(drm_device_t * dev, drm_savage_init_t * init) | |||
728 | dev_priv->status = NULL; | 728 | dev_priv->status = NULL; |
729 | } | 729 | } |
730 | if (dev_priv->dma_type == SAVAGE_DMA_AGP && init->buffers_offset) { | 730 | if (dev_priv->dma_type == SAVAGE_DMA_AGP && init->buffers_offset) { |
731 | dev->agp_buffer_token = init->buffers_offset; | ||
731 | dev->agp_buffer_map = drm_core_findmap(dev, | 732 | dev->agp_buffer_map = drm_core_findmap(dev, |
732 | init->buffers_offset); | 733 | init->buffers_offset); |
733 | if (!dev->agp_buffer_map) { | 734 | if (!dev->agp_buffer_map) { |
diff --git a/drivers/char/drm/savage_state.c b/drivers/char/drm/savage_state.c index ef2581d16146..1ca1e9cb5a33 100644 --- a/drivers/char/drm/savage_state.c +++ b/drivers/char/drm/savage_state.c | |||
@@ -994,7 +994,7 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS) | |||
994 | if (cmdbuf.size) { | 994 | if (cmdbuf.size) { |
995 | kcmd_addr = drm_alloc(cmdbuf.size * 8, DRM_MEM_DRIVER); | 995 | kcmd_addr = drm_alloc(cmdbuf.size * 8, DRM_MEM_DRIVER); |
996 | if (kcmd_addr == NULL) | 996 | if (kcmd_addr == NULL) |
997 | return ENOMEM; | 997 | return DRM_ERR(ENOMEM); |
998 | 998 | ||
999 | if (DRM_COPY_FROM_USER(kcmd_addr, cmdbuf.cmd_addr, | 999 | if (DRM_COPY_FROM_USER(kcmd_addr, cmdbuf.cmd_addr, |
1000 | cmdbuf.size * 8)) | 1000 | cmdbuf.size * 8)) |
diff --git a/drivers/char/epca.c b/drivers/char/epca.c index c3f95583a120..706733c0b36a 100644 --- a/drivers/char/epca.c +++ b/drivers/char/epca.c | |||
@@ -1157,6 +1157,7 @@ static int __init pc_init(void) | |||
1157 | int crd; | 1157 | int crd; |
1158 | struct board_info *bd; | 1158 | struct board_info *bd; |
1159 | unsigned char board_id = 0; | 1159 | unsigned char board_id = 0; |
1160 | int err = -ENOMEM; | ||
1160 | 1161 | ||
1161 | int pci_boards_found, pci_count; | 1162 | int pci_boards_found, pci_count; |
1162 | 1163 | ||
@@ -1164,13 +1165,11 @@ static int __init pc_init(void) | |||
1164 | 1165 | ||
1165 | pc_driver = alloc_tty_driver(MAX_ALLOC); | 1166 | pc_driver = alloc_tty_driver(MAX_ALLOC); |
1166 | if (!pc_driver) | 1167 | if (!pc_driver) |
1167 | return -ENOMEM; | 1168 | goto out1; |
1168 | 1169 | ||
1169 | pc_info = alloc_tty_driver(MAX_ALLOC); | 1170 | pc_info = alloc_tty_driver(MAX_ALLOC); |
1170 | if (!pc_info) { | 1171 | if (!pc_info) |
1171 | put_tty_driver(pc_driver); | 1172 | goto out2; |
1172 | return -ENOMEM; | ||
1173 | } | ||
1174 | 1173 | ||
1175 | /* ----------------------------------------------------------------------- | 1174 | /* ----------------------------------------------------------------------- |
1176 | If epca_setup has not been ran by LILO set num_cards to defaults; copy | 1175 | If epca_setup has not been ran by LILO set num_cards to defaults; copy |
@@ -1370,11 +1369,17 @@ static int __init pc_init(void) | |||
1370 | 1369 | ||
1371 | } /* End for each card */ | 1370 | } /* End for each card */ |
1372 | 1371 | ||
1373 | if (tty_register_driver(pc_driver)) | 1372 | err = tty_register_driver(pc_driver); |
1374 | panic("Couldn't register Digi PC/ driver"); | 1373 | if (err) { |
1374 | printk(KERN_ERR "Couldn't register Digi PC/ driver"); | ||
1375 | goto out3; | ||
1376 | } | ||
1375 | 1377 | ||
1376 | if (tty_register_driver(pc_info)) | 1378 | err = tty_register_driver(pc_info); |
1377 | panic("Couldn't register Digi PC/ info "); | 1379 | if (err) { |
1380 | printk(KERN_ERR "Couldn't register Digi PC/ info "); | ||
1381 | goto out4; | ||
1382 | } | ||
1378 | 1383 | ||
1379 | /* ------------------------------------------------------------------- | 1384 | /* ------------------------------------------------------------------- |
1380 | Start up the poller to check for events on all enabled boards | 1385 | Start up the poller to check for events on all enabled boards |
@@ -1385,6 +1390,15 @@ static int __init pc_init(void) | |||
1385 | mod_timer(&epca_timer, jiffies + HZ/25); | 1390 | mod_timer(&epca_timer, jiffies + HZ/25); |
1386 | return 0; | 1391 | return 0; |
1387 | 1392 | ||
1393 | out4: | ||
1394 | tty_unregister_driver(pc_driver); | ||
1395 | out3: | ||
1396 | put_tty_driver(pc_info); | ||
1397 | out2: | ||
1398 | put_tty_driver(pc_driver); | ||
1399 | out1: | ||
1400 | return err; | ||
1401 | |||
1388 | } /* End pc_init */ | 1402 | } /* End pc_init */ |
1389 | 1403 | ||
1390 | /* ------------------ Begin post_fep_init ---------------------- */ | 1404 | /* ------------------ Begin post_fep_init ---------------------- */ |
diff --git a/drivers/char/ftape/zftape/zftape-buffers.c b/drivers/char/ftape/zftape/zftape-buffers.c index da06f138334e..7ebce2ec7897 100644 --- a/drivers/char/ftape/zftape/zftape-buffers.c +++ b/drivers/char/ftape/zftape/zftape-buffers.c | |||
@@ -85,7 +85,7 @@ int zft_vmalloc_once(void *new, size_t size) | |||
85 | peak_memory = used_memory; | 85 | peak_memory = used_memory; |
86 | } | 86 | } |
87 | TRACE_ABORT(0, ft_t_noise, | 87 | TRACE_ABORT(0, ft_t_noise, |
88 | "allocated buffer @ %p, %d bytes", *(void **)new, size); | 88 | "allocated buffer @ %p, %zd bytes", *(void **)new, size); |
89 | } | 89 | } |
90 | int zft_vmalloc_always(void *new, size_t size) | 90 | int zft_vmalloc_always(void *new, size_t size) |
91 | { | 91 | { |
@@ -101,7 +101,7 @@ void zft_vfree(void *old, size_t size) | |||
101 | if (*(void **)old) { | 101 | if (*(void **)old) { |
102 | vfree(*(void **)old); | 102 | vfree(*(void **)old); |
103 | used_memory -= size; | 103 | used_memory -= size; |
104 | TRACE(ft_t_noise, "released buffer @ %p, %d bytes", | 104 | TRACE(ft_t_noise, "released buffer @ %p, %zd bytes", |
105 | *(void **)old, size); | 105 | *(void **)old, size); |
106 | *(void **)old = NULL; | 106 | *(void **)old = NULL; |
107 | } | 107 | } |
diff --git a/drivers/char/ip2/i2lib.c b/drivers/char/ip2/i2lib.c index fc944d375be7..54d93f0345e8 100644 --- a/drivers/char/ip2/i2lib.c +++ b/drivers/char/ip2/i2lib.c | |||
@@ -1007,7 +1007,7 @@ i2InputAvailable(i2ChanStrPtr pCh) | |||
1007 | // applications that one cannot break out of. | 1007 | // applications that one cannot break out of. |
1008 | //****************************************************************************** | 1008 | //****************************************************************************** |
1009 | static int | 1009 | static int |
1010 | i2Output(i2ChanStrPtr pCh, const char *pSource, int count, int user ) | 1010 | i2Output(i2ChanStrPtr pCh, const char *pSource, int count) |
1011 | { | 1011 | { |
1012 | i2eBordStrPtr pB; | 1012 | i2eBordStrPtr pB; |
1013 | unsigned char *pInsert; | 1013 | unsigned char *pInsert; |
@@ -1020,7 +1020,7 @@ i2Output(i2ChanStrPtr pCh, const char *pSource, int count, int user ) | |||
1020 | 1020 | ||
1021 | int bailout = 10; | 1021 | int bailout = 10; |
1022 | 1022 | ||
1023 | ip2trace (CHANN, ITRC_OUTPUT, ITRC_ENTER, 2, count, user ); | 1023 | ip2trace (CHANN, ITRC_OUTPUT, ITRC_ENTER, 2, count, 0 ); |
1024 | 1024 | ||
1025 | // Ensure channel structure seems real | 1025 | // Ensure channel structure seems real |
1026 | if ( !i2Validate ( pCh ) ) | 1026 | if ( !i2Validate ( pCh ) ) |
@@ -1087,12 +1087,7 @@ i2Output(i2ChanStrPtr pCh, const char *pSource, int count, int user ) | |||
1087 | DATA_COUNT_OF(pInsert) = amountToMove; | 1087 | DATA_COUNT_OF(pInsert) = amountToMove; |
1088 | 1088 | ||
1089 | // Move the data | 1089 | // Move the data |
1090 | if ( user ) { | 1090 | memcpy( (char*)(DATA_OF(pInsert)), pSource, amountToMove ); |
1091 | rc = copy_from_user((char*)(DATA_OF(pInsert)), pSource, | ||
1092 | amountToMove ); | ||
1093 | } else { | ||
1094 | memcpy( (char*)(DATA_OF(pInsert)), pSource, amountToMove ); | ||
1095 | } | ||
1096 | // Adjust pointers and indices | 1091 | // Adjust pointers and indices |
1097 | pSource += amountToMove; | 1092 | pSource += amountToMove; |
1098 | pCh->Obuf_char_count += amountToMove; | 1093 | pCh->Obuf_char_count += amountToMove; |
diff --git a/drivers/char/ip2/i2lib.h b/drivers/char/ip2/i2lib.h index 952e113ccd8a..e559e9bac06d 100644 --- a/drivers/char/ip2/i2lib.h +++ b/drivers/char/ip2/i2lib.h | |||
@@ -332,7 +332,7 @@ static int i2QueueCommands(int, i2ChanStrPtr, int, int, cmdSyntaxPtr,...); | |||
332 | static int i2GetStatus(i2ChanStrPtr, int); | 332 | static int i2GetStatus(i2ChanStrPtr, int); |
333 | static int i2Input(i2ChanStrPtr); | 333 | static int i2Input(i2ChanStrPtr); |
334 | static int i2InputFlush(i2ChanStrPtr); | 334 | static int i2InputFlush(i2ChanStrPtr); |
335 | static int i2Output(i2ChanStrPtr, const char *, int, int); | 335 | static int i2Output(i2ChanStrPtr, const char *, int); |
336 | static int i2OutputFree(i2ChanStrPtr); | 336 | static int i2OutputFree(i2ChanStrPtr); |
337 | static int i2ServiceBoard(i2eBordStrPtr); | 337 | static int i2ServiceBoard(i2eBordStrPtr); |
338 | static void i2DrainOutput(i2ChanStrPtr, int); | 338 | static void i2DrainOutput(i2ChanStrPtr, int); |
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c index 858ba5432c99..a3f32d46d2f8 100644 --- a/drivers/char/ip2/ip2main.c +++ b/drivers/char/ip2/ip2main.c | |||
@@ -1704,7 +1704,7 @@ ip2_write( PTTY tty, const unsigned char *pData, int count) | |||
1704 | 1704 | ||
1705 | /* This is the actual move bit. Make sure it does what we need!!!!! */ | 1705 | /* This is the actual move bit. Make sure it does what we need!!!!! */ |
1706 | WRITE_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags); | 1706 | WRITE_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags); |
1707 | bytesSent = i2Output( pCh, pData, count, 0 ); | 1707 | bytesSent = i2Output( pCh, pData, count); |
1708 | WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags); | 1708 | WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags); |
1709 | 1709 | ||
1710 | ip2trace (CHANN, ITRC_WRITE, ITRC_RETURN, 1, bytesSent ); | 1710 | ip2trace (CHANN, ITRC_WRITE, ITRC_RETURN, 1, bytesSent ); |
@@ -1764,7 +1764,7 @@ ip2_flush_chars( PTTY tty ) | |||
1764 | // | 1764 | // |
1765 | // We may need to restart i2Output if it does not fullfill this request | 1765 | // We may need to restart i2Output if it does not fullfill this request |
1766 | // | 1766 | // |
1767 | strip = i2Output( pCh, pCh->Pbuf, pCh->Pbuf_stuff, 0 ); | 1767 | strip = i2Output( pCh, pCh->Pbuf, pCh->Pbuf_stuff); |
1768 | if ( strip != pCh->Pbuf_stuff ) { | 1768 | if ( strip != pCh->Pbuf_stuff ) { |
1769 | memmove( pCh->Pbuf, &pCh->Pbuf[strip], pCh->Pbuf_stuff - strip ); | 1769 | memmove( pCh->Pbuf, &pCh->Pbuf[strip], pCh->Pbuf_stuff - strip ); |
1770 | } | 1770 | } |
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 2455e8d478ac..c47add8e47df 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c | |||
@@ -376,13 +376,23 @@ static void free_recv_msg_list(struct list_head *q) | |||
376 | } | 376 | } |
377 | } | 377 | } |
378 | 378 | ||
379 | static void free_smi_msg_list(struct list_head *q) | ||
380 | { | ||
381 | struct ipmi_smi_msg *msg, *msg2; | ||
382 | |||
383 | list_for_each_entry_safe(msg, msg2, q, link) { | ||
384 | list_del(&msg->link); | ||
385 | ipmi_free_smi_msg(msg); | ||
386 | } | ||
387 | } | ||
388 | |||
379 | static void clean_up_interface_data(ipmi_smi_t intf) | 389 | static void clean_up_interface_data(ipmi_smi_t intf) |
380 | { | 390 | { |
381 | int i; | 391 | int i; |
382 | struct cmd_rcvr *rcvr, *rcvr2; | 392 | struct cmd_rcvr *rcvr, *rcvr2; |
383 | struct list_head list; | 393 | struct list_head list; |
384 | 394 | ||
385 | free_recv_msg_list(&intf->waiting_msgs); | 395 | free_smi_msg_list(&intf->waiting_msgs); |
386 | free_recv_msg_list(&intf->waiting_events); | 396 | free_recv_msg_list(&intf->waiting_events); |
387 | 397 | ||
388 | /* Wholesale remove all the entries from the list in the | 398 | /* Wholesale remove all the entries from the list in the |
@@ -1844,7 +1854,7 @@ static ssize_t provides_dev_sdrs_show(struct device *dev, | |||
1844 | struct bmc_device *bmc = dev_get_drvdata(dev); | 1854 | struct bmc_device *bmc = dev_get_drvdata(dev); |
1845 | 1855 | ||
1846 | return snprintf(buf, 10, "%u\n", | 1856 | return snprintf(buf, 10, "%u\n", |
1847 | bmc->id.device_revision && 0x80 >> 7); | 1857 | (bmc->id.device_revision & 0x80) >> 7); |
1848 | } | 1858 | } |
1849 | 1859 | ||
1850 | static ssize_t revision_show(struct device *dev, struct device_attribute *attr, | 1860 | static ssize_t revision_show(struct device *dev, struct device_attribute *attr, |
@@ -1853,7 +1863,7 @@ static ssize_t revision_show(struct device *dev, struct device_attribute *attr, | |||
1853 | struct bmc_device *bmc = dev_get_drvdata(dev); | 1863 | struct bmc_device *bmc = dev_get_drvdata(dev); |
1854 | 1864 | ||
1855 | return snprintf(buf, 20, "%u\n", | 1865 | return snprintf(buf, 20, "%u\n", |
1856 | bmc->id.device_revision && 0x0F); | 1866 | bmc->id.device_revision & 0x0F); |
1857 | } | 1867 | } |
1858 | 1868 | ||
1859 | static ssize_t firmware_rev_show(struct device *dev, | 1869 | static ssize_t firmware_rev_show(struct device *dev, |
@@ -1928,13 +1938,8 @@ static ssize_t guid_show(struct device *dev, struct device_attribute *attr, | |||
1928 | (long long) bmc->guid[8]); | 1938 | (long long) bmc->guid[8]); |
1929 | } | 1939 | } |
1930 | 1940 | ||
1931 | static void | 1941 | static void remove_files(struct bmc_device *bmc) |
1932 | cleanup_bmc_device(struct kref *ref) | ||
1933 | { | 1942 | { |
1934 | struct bmc_device *bmc; | ||
1935 | |||
1936 | bmc = container_of(ref, struct bmc_device, refcount); | ||
1937 | |||
1938 | device_remove_file(&bmc->dev->dev, | 1943 | device_remove_file(&bmc->dev->dev, |
1939 | &bmc->device_id_attr); | 1944 | &bmc->device_id_attr); |
1940 | device_remove_file(&bmc->dev->dev, | 1945 | device_remove_file(&bmc->dev->dev, |
@@ -1951,12 +1956,23 @@ cleanup_bmc_device(struct kref *ref) | |||
1951 | &bmc->manufacturer_id_attr); | 1956 | &bmc->manufacturer_id_attr); |
1952 | device_remove_file(&bmc->dev->dev, | 1957 | device_remove_file(&bmc->dev->dev, |
1953 | &bmc->product_id_attr); | 1958 | &bmc->product_id_attr); |
1959 | |||
1954 | if (bmc->id.aux_firmware_revision_set) | 1960 | if (bmc->id.aux_firmware_revision_set) |
1955 | device_remove_file(&bmc->dev->dev, | 1961 | device_remove_file(&bmc->dev->dev, |
1956 | &bmc->aux_firmware_rev_attr); | 1962 | &bmc->aux_firmware_rev_attr); |
1957 | if (bmc->guid_set) | 1963 | if (bmc->guid_set) |
1958 | device_remove_file(&bmc->dev->dev, | 1964 | device_remove_file(&bmc->dev->dev, |
1959 | &bmc->guid_attr); | 1965 | &bmc->guid_attr); |
1966 | } | ||
1967 | |||
1968 | static void | ||
1969 | cleanup_bmc_device(struct kref *ref) | ||
1970 | { | ||
1971 | struct bmc_device *bmc; | ||
1972 | |||
1973 | bmc = container_of(ref, struct bmc_device, refcount); | ||
1974 | |||
1975 | remove_files(bmc); | ||
1960 | platform_device_unregister(bmc->dev); | 1976 | platform_device_unregister(bmc->dev); |
1961 | kfree(bmc); | 1977 | kfree(bmc); |
1962 | } | 1978 | } |
@@ -1977,6 +1993,79 @@ static void ipmi_bmc_unregister(ipmi_smi_t intf) | |||
1977 | mutex_unlock(&ipmidriver_mutex); | 1993 | mutex_unlock(&ipmidriver_mutex); |
1978 | } | 1994 | } |
1979 | 1995 | ||
1996 | static int create_files(struct bmc_device *bmc) | ||
1997 | { | ||
1998 | int err; | ||
1999 | |||
2000 | err = device_create_file(&bmc->dev->dev, | ||
2001 | &bmc->device_id_attr); | ||
2002 | if (err) goto out; | ||
2003 | err = device_create_file(&bmc->dev->dev, | ||
2004 | &bmc->provides_dev_sdrs_attr); | ||
2005 | if (err) goto out_devid; | ||
2006 | err = device_create_file(&bmc->dev->dev, | ||
2007 | &bmc->revision_attr); | ||
2008 | if (err) goto out_sdrs; | ||
2009 | err = device_create_file(&bmc->dev->dev, | ||
2010 | &bmc->firmware_rev_attr); | ||
2011 | if (err) goto out_rev; | ||
2012 | err = device_create_file(&bmc->dev->dev, | ||
2013 | &bmc->version_attr); | ||
2014 | if (err) goto out_firm; | ||
2015 | err = device_create_file(&bmc->dev->dev, | ||
2016 | &bmc->add_dev_support_attr); | ||
2017 | if (err) goto out_version; | ||
2018 | err = device_create_file(&bmc->dev->dev, | ||
2019 | &bmc->manufacturer_id_attr); | ||
2020 | if (err) goto out_add_dev; | ||
2021 | err = device_create_file(&bmc->dev->dev, | ||
2022 | &bmc->product_id_attr); | ||
2023 | if (err) goto out_manu; | ||
2024 | if (bmc->id.aux_firmware_revision_set) { | ||
2025 | err = device_create_file(&bmc->dev->dev, | ||
2026 | &bmc->aux_firmware_rev_attr); | ||
2027 | if (err) goto out_prod_id; | ||
2028 | } | ||
2029 | if (bmc->guid_set) { | ||
2030 | err = device_create_file(&bmc->dev->dev, | ||
2031 | &bmc->guid_attr); | ||
2032 | if (err) goto out_aux_firm; | ||
2033 | } | ||
2034 | |||
2035 | return 0; | ||
2036 | |||
2037 | out_aux_firm: | ||
2038 | if (bmc->id.aux_firmware_revision_set) | ||
2039 | device_remove_file(&bmc->dev->dev, | ||
2040 | &bmc->aux_firmware_rev_attr); | ||
2041 | out_prod_id: | ||
2042 | device_remove_file(&bmc->dev->dev, | ||
2043 | &bmc->product_id_attr); | ||
2044 | out_manu: | ||
2045 | device_remove_file(&bmc->dev->dev, | ||
2046 | &bmc->manufacturer_id_attr); | ||
2047 | out_add_dev: | ||
2048 | device_remove_file(&bmc->dev->dev, | ||
2049 | &bmc->add_dev_support_attr); | ||
2050 | out_version: | ||
2051 | device_remove_file(&bmc->dev->dev, | ||
2052 | &bmc->version_attr); | ||
2053 | out_firm: | ||
2054 | device_remove_file(&bmc->dev->dev, | ||
2055 | &bmc->firmware_rev_attr); | ||
2056 | out_rev: | ||
2057 | device_remove_file(&bmc->dev->dev, | ||
2058 | &bmc->revision_attr); | ||
2059 | out_sdrs: | ||
2060 | device_remove_file(&bmc->dev->dev, | ||
2061 | &bmc->provides_dev_sdrs_attr); | ||
2062 | out_devid: | ||
2063 | device_remove_file(&bmc->dev->dev, | ||
2064 | &bmc->device_id_attr); | ||
2065 | out: | ||
2066 | return err; | ||
2067 | } | ||
2068 | |||
1980 | static int ipmi_bmc_register(ipmi_smi_t intf) | 2069 | static int ipmi_bmc_register(ipmi_smi_t intf) |
1981 | { | 2070 | { |
1982 | int rv; | 2071 | int rv; |
@@ -2029,7 +2118,7 @@ static int ipmi_bmc_register(ipmi_smi_t intf) | |||
2029 | dev_set_drvdata(&bmc->dev->dev, bmc); | 2118 | dev_set_drvdata(&bmc->dev->dev, bmc); |
2030 | kref_init(&bmc->refcount); | 2119 | kref_init(&bmc->refcount); |
2031 | 2120 | ||
2032 | rv = platform_device_register(bmc->dev); | 2121 | rv = platform_device_add(bmc->dev); |
2033 | mutex_unlock(&ipmidriver_mutex); | 2122 | mutex_unlock(&ipmidriver_mutex); |
2034 | if (rv) { | 2123 | if (rv) { |
2035 | printk(KERN_ERR | 2124 | printk(KERN_ERR |
@@ -2051,7 +2140,6 @@ static int ipmi_bmc_register(ipmi_smi_t intf) | |||
2051 | bmc->provides_dev_sdrs_attr.attr.mode = S_IRUGO; | 2140 | bmc->provides_dev_sdrs_attr.attr.mode = S_IRUGO; |
2052 | bmc->provides_dev_sdrs_attr.show = provides_dev_sdrs_show; | 2141 | bmc->provides_dev_sdrs_attr.show = provides_dev_sdrs_show; |
2053 | 2142 | ||
2054 | |||
2055 | bmc->revision_attr.attr.name = "revision"; | 2143 | bmc->revision_attr.attr.name = "revision"; |
2056 | bmc->revision_attr.attr.owner = THIS_MODULE; | 2144 | bmc->revision_attr.attr.owner = THIS_MODULE; |
2057 | bmc->revision_attr.attr.mode = S_IRUGO; | 2145 | bmc->revision_attr.attr.mode = S_IRUGO; |
@@ -2093,28 +2181,14 @@ static int ipmi_bmc_register(ipmi_smi_t intf) | |||
2093 | bmc->aux_firmware_rev_attr.attr.mode = S_IRUGO; | 2181 | bmc->aux_firmware_rev_attr.attr.mode = S_IRUGO; |
2094 | bmc->aux_firmware_rev_attr.show = aux_firmware_rev_show; | 2182 | bmc->aux_firmware_rev_attr.show = aux_firmware_rev_show; |
2095 | 2183 | ||
2096 | device_create_file(&bmc->dev->dev, | 2184 | rv = create_files(bmc); |
2097 | &bmc->device_id_attr); | 2185 | if (rv) { |
2098 | device_create_file(&bmc->dev->dev, | 2186 | mutex_lock(&ipmidriver_mutex); |
2099 | &bmc->provides_dev_sdrs_attr); | 2187 | platform_device_unregister(bmc->dev); |
2100 | device_create_file(&bmc->dev->dev, | 2188 | mutex_unlock(&ipmidriver_mutex); |
2101 | &bmc->revision_attr); | 2189 | |
2102 | device_create_file(&bmc->dev->dev, | 2190 | return rv; |
2103 | &bmc->firmware_rev_attr); | 2191 | } |
2104 | device_create_file(&bmc->dev->dev, | ||
2105 | &bmc->version_attr); | ||
2106 | device_create_file(&bmc->dev->dev, | ||
2107 | &bmc->add_dev_support_attr); | ||
2108 | device_create_file(&bmc->dev->dev, | ||
2109 | &bmc->manufacturer_id_attr); | ||
2110 | device_create_file(&bmc->dev->dev, | ||
2111 | &bmc->product_id_attr); | ||
2112 | if (bmc->id.aux_firmware_revision_set) | ||
2113 | device_create_file(&bmc->dev->dev, | ||
2114 | &bmc->aux_firmware_rev_attr); | ||
2115 | if (bmc->guid_set) | ||
2116 | device_create_file(&bmc->dev->dev, | ||
2117 | &bmc->guid_attr); | ||
2118 | 2192 | ||
2119 | printk(KERN_INFO | 2193 | printk(KERN_INFO |
2120 | "ipmi: Found new BMC (man_id: 0x%6.6x, " | 2194 | "ipmi: Found new BMC (man_id: 0x%6.6x, " |
@@ -3168,7 +3242,9 @@ void ipmi_smi_msg_received(ipmi_smi_t intf, | |||
3168 | report the error immediately. */ | 3242 | report the error immediately. */ |
3169 | if ((msg->rsp_size >= 3) && (msg->rsp[2] != 0) | 3243 | if ((msg->rsp_size >= 3) && (msg->rsp[2] != 0) |
3170 | && (msg->rsp[2] != IPMI_NODE_BUSY_ERR) | 3244 | && (msg->rsp[2] != IPMI_NODE_BUSY_ERR) |
3171 | && (msg->rsp[2] != IPMI_LOST_ARBITRATION_ERR)) | 3245 | && (msg->rsp[2] != IPMI_LOST_ARBITRATION_ERR) |
3246 | && (msg->rsp[2] != IPMI_BUS_ERR) | ||
3247 | && (msg->rsp[2] != IPMI_NAK_ON_WRITE_ERR)) | ||
3172 | { | 3248 | { |
3173 | int chan = msg->rsp[3] & 0xf; | 3249 | int chan = msg->rsp[3] & 0xf; |
3174 | 3250 | ||
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 24825bdca8f4..bb1fac104fda 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
@@ -1211,7 +1211,7 @@ static void intf_mem_outb(struct si_sm_io *io, unsigned int offset, | |||
1211 | static unsigned char intf_mem_inw(struct si_sm_io *io, unsigned int offset) | 1211 | static unsigned char intf_mem_inw(struct si_sm_io *io, unsigned int offset) |
1212 | { | 1212 | { |
1213 | return (readw((io->addr)+(offset * io->regspacing)) >> io->regshift) | 1213 | return (readw((io->addr)+(offset * io->regspacing)) >> io->regshift) |
1214 | && 0xff; | 1214 | & 0xff; |
1215 | } | 1215 | } |
1216 | 1216 | ||
1217 | static void intf_mem_outw(struct si_sm_io *io, unsigned int offset, | 1217 | static void intf_mem_outw(struct si_sm_io *io, unsigned int offset, |
@@ -1223,7 +1223,7 @@ static void intf_mem_outw(struct si_sm_io *io, unsigned int offset, | |||
1223 | static unsigned char intf_mem_inl(struct si_sm_io *io, unsigned int offset) | 1223 | static unsigned char intf_mem_inl(struct si_sm_io *io, unsigned int offset) |
1224 | { | 1224 | { |
1225 | return (readl((io->addr)+(offset * io->regspacing)) >> io->regshift) | 1225 | return (readl((io->addr)+(offset * io->regspacing)) >> io->regshift) |
1226 | && 0xff; | 1226 | & 0xff; |
1227 | } | 1227 | } |
1228 | 1228 | ||
1229 | static void intf_mem_outl(struct si_sm_io *io, unsigned int offset, | 1229 | static void intf_mem_outl(struct si_sm_io *io, unsigned int offset, |
@@ -1236,7 +1236,7 @@ static void intf_mem_outl(struct si_sm_io *io, unsigned int offset, | |||
1236 | static unsigned char mem_inq(struct si_sm_io *io, unsigned int offset) | 1236 | static unsigned char mem_inq(struct si_sm_io *io, unsigned int offset) |
1237 | { | 1237 | { |
1238 | return (readq((io->addr)+(offset * io->regspacing)) >> io->regshift) | 1238 | return (readq((io->addr)+(offset * io->regspacing)) >> io->regshift) |
1239 | && 0xff; | 1239 | & 0xff; |
1240 | } | 1240 | } |
1241 | 1241 | ||
1242 | static void mem_outq(struct si_sm_io *io, unsigned int offset, | 1242 | static void mem_outq(struct si_sm_io *io, unsigned int offset, |
@@ -1789,7 +1789,7 @@ static int __devinit ipmi_pci_probe(struct pci_dev *pdev, | |||
1789 | 1789 | ||
1790 | info = kzalloc(sizeof(*info), GFP_KERNEL); | 1790 | info = kzalloc(sizeof(*info), GFP_KERNEL); |
1791 | if (!info) | 1791 | if (!info) |
1792 | return ENOMEM; | 1792 | return -ENOMEM; |
1793 | 1793 | ||
1794 | info->addr_source = "PCI"; | 1794 | info->addr_source = "PCI"; |
1795 | 1795 | ||
@@ -1810,7 +1810,7 @@ static int __devinit ipmi_pci_probe(struct pci_dev *pdev, | |||
1810 | kfree(info); | 1810 | kfree(info); |
1811 | printk(KERN_INFO "ipmi_si: %s: Unknown IPMI type: %d\n", | 1811 | printk(KERN_INFO "ipmi_si: %s: Unknown IPMI type: %d\n", |
1812 | pci_name(pdev), class_type); | 1812 | pci_name(pdev), class_type); |
1813 | return ENOMEM; | 1813 | return -ENOMEM; |
1814 | } | 1814 | } |
1815 | 1815 | ||
1816 | rv = pci_enable_device(pdev); | 1816 | rv = pci_enable_device(pdev); |
@@ -1867,7 +1867,7 @@ static int ipmi_pci_resume(struct pci_dev *pdev) | |||
1867 | 1867 | ||
1868 | static struct pci_device_id ipmi_pci_devices[] = { | 1868 | static struct pci_device_id ipmi_pci_devices[] = { |
1869 | { PCI_DEVICE(PCI_HP_VENDOR_ID, PCI_MMC_DEVICE_ID) }, | 1869 | { PCI_DEVICE(PCI_HP_VENDOR_ID, PCI_MMC_DEVICE_ID) }, |
1870 | { PCI_DEVICE_CLASS(PCI_ERMC_CLASSCODE, PCI_ERMC_CLASSCODE) } | 1870 | { PCI_DEVICE_CLASS(PCI_ERMC_CLASSCODE, PCI_ERMC_CLASSCODE_MASK) } |
1871 | }; | 1871 | }; |
1872 | MODULE_DEVICE_TABLE(pci, ipmi_pci_devices); | 1872 | MODULE_DEVICE_TABLE(pci, ipmi_pci_devices); |
1873 | 1873 | ||
@@ -2346,7 +2346,7 @@ static int try_smi_init(struct smi_info *new_smi) | |||
2346 | new_smi->dev = &new_smi->pdev->dev; | 2346 | new_smi->dev = &new_smi->pdev->dev; |
2347 | new_smi->dev->driver = &ipmi_driver; | 2347 | new_smi->dev->driver = &ipmi_driver; |
2348 | 2348 | ||
2349 | rv = platform_device_register(new_smi->pdev); | 2349 | rv = platform_device_add(new_smi->pdev); |
2350 | if (rv) { | 2350 | if (rv) { |
2351 | printk(KERN_ERR | 2351 | printk(KERN_ERR |
2352 | "ipmi_si_intf:" | 2352 | "ipmi_si_intf:" |
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c index e9e9bf31c369..58c955e390b3 100644 --- a/drivers/char/isicom.c +++ b/drivers/char/isicom.c | |||
@@ -1062,11 +1062,12 @@ static void isicom_shutdown_port(struct isi_port *port) | |||
1062 | static void isicom_close(struct tty_struct *tty, struct file *filp) | 1062 | static void isicom_close(struct tty_struct *tty, struct file *filp) |
1063 | { | 1063 | { |
1064 | struct isi_port *port = tty->driver_data; | 1064 | struct isi_port *port = tty->driver_data; |
1065 | struct isi_board *card = port->card; | 1065 | struct isi_board *card; |
1066 | unsigned long flags; | 1066 | unsigned long flags; |
1067 | 1067 | ||
1068 | if (!port) | 1068 | if (!port) |
1069 | return; | 1069 | return; |
1070 | card = port->card; | ||
1070 | if (isicom_paranoia_check(port, tty->name, "isicom_close")) | 1071 | if (isicom_paranoia_check(port, tty->name, "isicom_close")) |
1071 | return; | 1072 | return; |
1072 | 1073 | ||
diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 6511012cbdcd..55473371b7c6 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/backing-dev.h> | 26 | #include <linux/backing-dev.h> |
27 | #include <linux/bootmem.h> | 27 | #include <linux/bootmem.h> |
28 | #include <linux/pipe_fs_i.h> | 28 | #include <linux/pipe_fs_i.h> |
29 | #include <linux/pfn.h> | ||
29 | 30 | ||
30 | #include <asm/uaccess.h> | 31 | #include <asm/uaccess.h> |
31 | #include <asm/io.h> | 32 | #include <asm/io.h> |
@@ -292,8 +293,8 @@ static int mmap_kmem(struct file * file, struct vm_area_struct * vma) | |||
292 | { | 293 | { |
293 | unsigned long pfn; | 294 | unsigned long pfn; |
294 | 295 | ||
295 | /* Turn a kernel-virtual address into a physical page frame */ | 296 | /* Turn a pfn offset into an absolute pfn */ |
296 | pfn = __pa((u64)vma->vm_pgoff << PAGE_SHIFT) >> PAGE_SHIFT; | 297 | pfn = PFN_DOWN(virt_to_phys((void *)PAGE_OFFSET)) + vma->vm_pgoff; |
297 | 298 | ||
298 | /* | 299 | /* |
299 | * RED-PEN: on some architectures there is more mapped memory | 300 | * RED-PEN: on some architectures there is more mapped memory |
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c index b401383808c2..96cb1f07332b 100644 --- a/drivers/char/moxa.c +++ b/drivers/char/moxa.c | |||
@@ -130,6 +130,7 @@ static moxa_isa_board_conf moxa_isa_boards[] = | |||
130 | typedef struct _moxa_pci_devinfo { | 130 | typedef struct _moxa_pci_devinfo { |
131 | ushort busNum; | 131 | ushort busNum; |
132 | ushort devNum; | 132 | ushort devNum; |
133 | struct pci_dev *pdev; | ||
133 | } moxa_pci_devinfo; | 134 | } moxa_pci_devinfo; |
134 | 135 | ||
135 | typedef struct _moxa_board_conf { | 136 | typedef struct _moxa_board_conf { |
@@ -324,6 +325,9 @@ static int moxa_get_PCI_conf(struct pci_dev *p, int board_type, moxa_board_conf | |||
324 | board->busType = MOXA_BUS_TYPE_PCI; | 325 | board->busType = MOXA_BUS_TYPE_PCI; |
325 | board->pciInfo.busNum = p->bus->number; | 326 | board->pciInfo.busNum = p->bus->number; |
326 | board->pciInfo.devNum = p->devfn >> 3; | 327 | board->pciInfo.devNum = p->devfn >> 3; |
328 | board->pciInfo.pdev = p; | ||
329 | /* don't lose the reference in the next pci_get_device iteration */ | ||
330 | pci_dev_get(p); | ||
327 | 331 | ||
328 | return (0); | 332 | return (0); |
329 | } | 333 | } |
@@ -493,6 +497,11 @@ static void __exit moxa_exit(void) | |||
493 | if (tty_unregister_driver(moxaDriver)) | 497 | if (tty_unregister_driver(moxaDriver)) |
494 | printk("Couldn't unregister MOXA Intellio family serial driver\n"); | 498 | printk("Couldn't unregister MOXA Intellio family serial driver\n"); |
495 | put_tty_driver(moxaDriver); | 499 | put_tty_driver(moxaDriver); |
500 | |||
501 | for (i = 0; i < MAX_BOARDS; i++) | ||
502 | if (moxa_boards[i].busType == MOXA_BUS_TYPE_PCI) | ||
503 | pci_dev_put(moxa_boards[i].pciInfo.pdev); | ||
504 | |||
496 | if (verbose) | 505 | if (verbose) |
497 | printk("Done\n"); | 506 | printk("Done\n"); |
498 | } | 507 | } |
diff --git a/drivers/char/mspec.c b/drivers/char/mspec.c index 5c0dec39cf6c..235e89226112 100644 --- a/drivers/char/mspec.c +++ b/drivers/char/mspec.c | |||
@@ -72,7 +72,11 @@ enum { | |||
72 | MSPEC_UNCACHED | 72 | MSPEC_UNCACHED |
73 | }; | 73 | }; |
74 | 74 | ||
75 | #ifdef CONFIG_SGI_SN | ||
75 | static int is_sn2; | 76 | static int is_sn2; |
77 | #else | ||
78 | #define is_sn2 0 | ||
79 | #endif | ||
76 | 80 | ||
77 | /* | 81 | /* |
78 | * One of these structures is allocated when an mspec region is mmaped. The | 82 | * One of these structures is allocated when an mspec region is mmaped. The |
@@ -211,7 +215,7 @@ mspec_nopfn(struct vm_area_struct *vma, unsigned long address) | |||
211 | if (vdata->type == MSPEC_FETCHOP) | 215 | if (vdata->type == MSPEC_FETCHOP) |
212 | paddr = TO_AMO(maddr); | 216 | paddr = TO_AMO(maddr); |
213 | else | 217 | else |
214 | paddr = __pa(TO_CAC(maddr)); | 218 | paddr = maddr & ~__IA64_UNCACHED_OFFSET; |
215 | 219 | ||
216 | pfn = paddr >> PAGE_SHIFT; | 220 | pfn = paddr >> PAGE_SHIFT; |
217 | 221 | ||
@@ -335,6 +339,7 @@ mspec_init(void) | |||
335 | * The fetchop device only works on SN2 hardware, uncached and cached | 339 | * The fetchop device only works on SN2 hardware, uncached and cached |
336 | * memory drivers should both be valid on all ia64 hardware | 340 | * memory drivers should both be valid on all ia64 hardware |
337 | */ | 341 | */ |
342 | #ifdef CONFIG_SGI_SN | ||
338 | if (ia64_platform_is("sn2")) { | 343 | if (ia64_platform_is("sn2")) { |
339 | is_sn2 = 1; | 344 | is_sn2 = 1; |
340 | if (is_shub2()) { | 345 | if (is_shub2()) { |
@@ -363,6 +368,7 @@ mspec_init(void) | |||
363 | goto free_scratch_pages; | 368 | goto free_scratch_pages; |
364 | } | 369 | } |
365 | } | 370 | } |
371 | #endif | ||
366 | ret = misc_register(&cached_miscdev); | 372 | ret = misc_register(&cached_miscdev); |
367 | if (ret) { | 373 | if (ret) { |
368 | printk(KERN_ERR "%s: failed to register device %i\n", | 374 | printk(KERN_ERR "%s: failed to register device %i\n", |
diff --git a/drivers/char/random.c b/drivers/char/random.c index 07f47a0208a7..eb6b13f4211a 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c | |||
@@ -645,6 +645,7 @@ void add_input_randomness(unsigned int type, unsigned int code, | |||
645 | add_timer_randomness(&input_timer_state, | 645 | add_timer_randomness(&input_timer_state, |
646 | (type << 4) ^ code ^ (code >> 4) ^ value); | 646 | (type << 4) ^ code ^ (code >> 4) ^ value); |
647 | } | 647 | } |
648 | EXPORT_SYMBOL_GPL(add_input_randomness); | ||
648 | 649 | ||
649 | void add_interrupt_randomness(int irq) | 650 | void add_interrupt_randomness(int irq) |
650 | { | 651 | { |
diff --git a/drivers/char/rio/host.h b/drivers/char/rio/host.h index ee2ddea7a63a..23d0681fe491 100644 --- a/drivers/char/rio/host.h +++ b/drivers/char/rio/host.h | |||
@@ -44,6 +44,7 @@ | |||
44 | ** the host. | 44 | ** the host. |
45 | */ | 45 | */ |
46 | struct Host { | 46 | struct Host { |
47 | struct pci_dev *pdev; | ||
47 | unsigned char Type; /* RIO_EISA, RIO_MCA, ... */ | 48 | unsigned char Type; /* RIO_EISA, RIO_MCA, ... */ |
48 | unsigned char Ivec; /* POLLED or ivec number */ | 49 | unsigned char Ivec; /* POLLED or ivec number */ |
49 | unsigned char Mode; /* Control stuff */ | 50 | unsigned char Mode; /* Control stuff */ |
diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c index c382df0f82f6..7ac68cb3bedd 100644 --- a/drivers/char/rio/rio_linux.c +++ b/drivers/char/rio/rio_linux.c | |||
@@ -1017,6 +1017,10 @@ static int __init rio_init(void) | |||
1017 | rio_dprintk(RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n", p->RIOHosts[p->RIONumHosts].UniqueNum); | 1017 | rio_dprintk(RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n", p->RIOHosts[p->RIONumHosts].UniqueNum); |
1018 | 1018 | ||
1019 | fix_rio_pci(pdev); | 1019 | fix_rio_pci(pdev); |
1020 | |||
1021 | p->RIOHosts[p->RIONumHosts].pdev = pdev; | ||
1022 | pci_dev_get(pdev); | ||
1023 | |||
1020 | p->RIOLastPCISearch = 0; | 1024 | p->RIOLastPCISearch = 0; |
1021 | p->RIONumHosts++; | 1025 | p->RIONumHosts++; |
1022 | found++; | 1026 | found++; |
@@ -1066,6 +1070,9 @@ static int __init rio_init(void) | |||
1066 | ((readb(&p->RIOHosts[p->RIONumHosts].Unique[1]) & 0xFF) << 8) | ((readb(&p->RIOHosts[p->RIONumHosts].Unique[2]) & 0xFF) << 16) | ((readb(&p->RIOHosts[p->RIONumHosts].Unique[3]) & 0xFF) << 24); | 1070 | ((readb(&p->RIOHosts[p->RIONumHosts].Unique[1]) & 0xFF) << 8) | ((readb(&p->RIOHosts[p->RIONumHosts].Unique[2]) & 0xFF) << 16) | ((readb(&p->RIOHosts[p->RIONumHosts].Unique[3]) & 0xFF) << 24); |
1067 | rio_dprintk(RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n", p->RIOHosts[p->RIONumHosts].UniqueNum); | 1071 | rio_dprintk(RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n", p->RIOHosts[p->RIONumHosts].UniqueNum); |
1068 | 1072 | ||
1073 | p->RIOHosts[p->RIONumHosts].pdev = pdev; | ||
1074 | pci_dev_get(pdev); | ||
1075 | |||
1069 | p->RIOLastPCISearch = 0; | 1076 | p->RIOLastPCISearch = 0; |
1070 | p->RIONumHosts++; | 1077 | p->RIONumHosts++; |
1071 | found++; | 1078 | found++; |
@@ -1181,6 +1188,8 @@ static void __exit rio_exit(void) | |||
1181 | } | 1188 | } |
1182 | /* It is safe/allowed to del_timer a non-active timer */ | 1189 | /* It is safe/allowed to del_timer a non-active timer */ |
1183 | del_timer(&hp->timer); | 1190 | del_timer(&hp->timer); |
1191 | if (hp->Type == RIO_PCI) | ||
1192 | pci_dev_put(hp->pdev); | ||
1184 | } | 1193 | } |
1185 | 1194 | ||
1186 | if (misc_deregister(&rio_fw_device) < 0) { | 1195 | if (misc_deregister(&rio_fw_device) < 0) { |
diff --git a/drivers/char/rio/rioctrl.c b/drivers/char/rio/rioctrl.c index 052e8120a471..7ce77619707c 100644 --- a/drivers/char/rio/rioctrl.c +++ b/drivers/char/rio/rioctrl.c | |||
@@ -662,7 +662,7 @@ int riocontrol(struct rio_info *p, dev_t dev, int cmd, unsigned long arg, int su | |||
662 | p->RIOError.Error = COPYIN_FAILED; | 662 | p->RIOError.Error = COPYIN_FAILED; |
663 | return -EFAULT; | 663 | return -EFAULT; |
664 | } | 664 | } |
665 | if (portStats.port >= RIO_PORTS) { | 665 | if (portStats.port < 0 || portStats.port >= RIO_PORTS) { |
666 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; | 666 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; |
667 | return -ENXIO; | 667 | return -ENXIO; |
668 | } | 668 | } |
@@ -702,7 +702,7 @@ int riocontrol(struct rio_info *p, dev_t dev, int cmd, unsigned long arg, int su | |||
702 | p->RIOError.Error = COPYIN_FAILED; | 702 | p->RIOError.Error = COPYIN_FAILED; |
703 | return -EFAULT; | 703 | return -EFAULT; |
704 | } | 704 | } |
705 | if (portStats.port >= RIO_PORTS) { | 705 | if (portStats.port < 0 || portStats.port >= RIO_PORTS) { |
706 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; | 706 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; |
707 | return -ENXIO; | 707 | return -ENXIO; |
708 | } | 708 | } |
diff --git a/drivers/char/serial167.c b/drivers/char/serial167.c index 461bfe0234c9..3af7f0958c5d 100644 --- a/drivers/char/serial167.c +++ b/drivers/char/serial167.c | |||
@@ -839,7 +839,7 @@ shutdown(struct cyclades_port * info) | |||
839 | local_irq_save(flags); | 839 | local_irq_save(flags); |
840 | if (info->xmit_buf){ | 840 | if (info->xmit_buf){ |
841 | free_page((unsigned long) info->xmit_buf); | 841 | free_page((unsigned long) info->xmit_buf); |
842 | info->xmit_buf = 0; | 842 | info->xmit_buf = NULL; |
843 | } | 843 | } |
844 | 844 | ||
845 | base_addr[CyCAR] = (u_char)channel; | 845 | base_addr[CyCAR] = (u_char)channel; |
@@ -1354,7 +1354,7 @@ cy_unthrottle(struct tty_struct * tty) | |||
1354 | 1354 | ||
1355 | static int | 1355 | static int |
1356 | get_serial_info(struct cyclades_port * info, | 1356 | get_serial_info(struct cyclades_port * info, |
1357 | struct serial_struct * retinfo) | 1357 | struct serial_struct __user * retinfo) |
1358 | { | 1358 | { |
1359 | struct serial_struct tmp; | 1359 | struct serial_struct tmp; |
1360 | 1360 | ||
@@ -1376,7 +1376,7 @@ get_serial_info(struct cyclades_port * info, | |||
1376 | 1376 | ||
1377 | static int | 1377 | static int |
1378 | set_serial_info(struct cyclades_port * info, | 1378 | set_serial_info(struct cyclades_port * info, |
1379 | struct serial_struct * new_info) | 1379 | struct serial_struct __user * new_info) |
1380 | { | 1380 | { |
1381 | struct serial_struct new_serial; | 1381 | struct serial_struct new_serial; |
1382 | struct cyclades_port old_info; | 1382 | struct cyclades_port old_info; |
@@ -1503,7 +1503,7 @@ send_break( struct cyclades_port * info, int duration) | |||
1503 | } /* send_break */ | 1503 | } /* send_break */ |
1504 | 1504 | ||
1505 | static int | 1505 | static int |
1506 | get_mon_info(struct cyclades_port * info, struct cyclades_monitor * mon) | 1506 | get_mon_info(struct cyclades_port * info, struct cyclades_monitor __user * mon) |
1507 | { | 1507 | { |
1508 | 1508 | ||
1509 | if (copy_to_user(mon, &info->mon, sizeof(struct cyclades_monitor))) | 1509 | if (copy_to_user(mon, &info->mon, sizeof(struct cyclades_monitor))) |
@@ -1516,7 +1516,7 @@ get_mon_info(struct cyclades_port * info, struct cyclades_monitor * mon) | |||
1516 | } | 1516 | } |
1517 | 1517 | ||
1518 | static int | 1518 | static int |
1519 | set_threshold(struct cyclades_port * info, unsigned long *arg) | 1519 | set_threshold(struct cyclades_port * info, unsigned long __user *arg) |
1520 | { | 1520 | { |
1521 | volatile unsigned char *base_addr = (u_char *)BASE_ADDR; | 1521 | volatile unsigned char *base_addr = (u_char *)BASE_ADDR; |
1522 | unsigned long value; | 1522 | unsigned long value; |
@@ -1533,7 +1533,7 @@ set_threshold(struct cyclades_port * info, unsigned long *arg) | |||
1533 | } | 1533 | } |
1534 | 1534 | ||
1535 | static int | 1535 | static int |
1536 | get_threshold(struct cyclades_port * info, unsigned long *value) | 1536 | get_threshold(struct cyclades_port * info, unsigned long __user *value) |
1537 | { | 1537 | { |
1538 | volatile unsigned char *base_addr = (u_char *)BASE_ADDR; | 1538 | volatile unsigned char *base_addr = (u_char *)BASE_ADDR; |
1539 | int channel; | 1539 | int channel; |
@@ -1546,7 +1546,7 @@ get_threshold(struct cyclades_port * info, unsigned long *value) | |||
1546 | } | 1546 | } |
1547 | 1547 | ||
1548 | static int | 1548 | static int |
1549 | set_default_threshold(struct cyclades_port * info, unsigned long *arg) | 1549 | set_default_threshold(struct cyclades_port * info, unsigned long __user *arg) |
1550 | { | 1550 | { |
1551 | unsigned long value; | 1551 | unsigned long value; |
1552 | 1552 | ||
@@ -1558,13 +1558,13 @@ set_default_threshold(struct cyclades_port * info, unsigned long *arg) | |||
1558 | } | 1558 | } |
1559 | 1559 | ||
1560 | static int | 1560 | static int |
1561 | get_default_threshold(struct cyclades_port * info, unsigned long *value) | 1561 | get_default_threshold(struct cyclades_port * info, unsigned long __user *value) |
1562 | { | 1562 | { |
1563 | return put_user(info->default_threshold,value); | 1563 | return put_user(info->default_threshold,value); |
1564 | } | 1564 | } |
1565 | 1565 | ||
1566 | static int | 1566 | static int |
1567 | set_timeout(struct cyclades_port * info, unsigned long *arg) | 1567 | set_timeout(struct cyclades_port * info, unsigned long __user *arg) |
1568 | { | 1568 | { |
1569 | volatile unsigned char *base_addr = (u_char *)BASE_ADDR; | 1569 | volatile unsigned char *base_addr = (u_char *)BASE_ADDR; |
1570 | int channel; | 1570 | int channel; |
@@ -1581,7 +1581,7 @@ set_timeout(struct cyclades_port * info, unsigned long *arg) | |||
1581 | } | 1581 | } |
1582 | 1582 | ||
1583 | static int | 1583 | static int |
1584 | get_timeout(struct cyclades_port * info, unsigned long *value) | 1584 | get_timeout(struct cyclades_port * info, unsigned long __user *value) |
1585 | { | 1585 | { |
1586 | volatile unsigned char *base_addr = (u_char *)BASE_ADDR; | 1586 | volatile unsigned char *base_addr = (u_char *)BASE_ADDR; |
1587 | int channel; | 1587 | int channel; |
@@ -1601,7 +1601,7 @@ set_default_timeout(struct cyclades_port * info, unsigned long value) | |||
1601 | } | 1601 | } |
1602 | 1602 | ||
1603 | static int | 1603 | static int |
1604 | get_default_timeout(struct cyclades_port * info, unsigned long *value) | 1604 | get_default_timeout(struct cyclades_port * info, unsigned long __user *value) |
1605 | { | 1605 | { |
1606 | return put_user(info->default_timeout,value); | 1606 | return put_user(info->default_timeout,value); |
1607 | } | 1607 | } |
@@ -1613,6 +1613,7 @@ cy_ioctl(struct tty_struct *tty, struct file * file, | |||
1613 | unsigned long val; | 1613 | unsigned long val; |
1614 | struct cyclades_port * info = (struct cyclades_port *)tty->driver_data; | 1614 | struct cyclades_port * info = (struct cyclades_port *)tty->driver_data; |
1615 | int ret_val = 0; | 1615 | int ret_val = 0; |
1616 | void __user *argp = (void __user *)arg; | ||
1616 | 1617 | ||
1617 | #ifdef SERIAL_DEBUG_OTHER | 1618 | #ifdef SERIAL_DEBUG_OTHER |
1618 | printk("cy_ioctl %s, cmd = %x arg = %lx\n", tty->name, cmd, arg); /* */ | 1619 | printk("cy_ioctl %s, cmd = %x arg = %lx\n", tty->name, cmd, arg); /* */ |
@@ -1620,28 +1621,28 @@ cy_ioctl(struct tty_struct *tty, struct file * file, | |||
1620 | 1621 | ||
1621 | switch (cmd) { | 1622 | switch (cmd) { |
1622 | case CYGETMON: | 1623 | case CYGETMON: |
1623 | ret_val = get_mon_info(info, (struct cyclades_monitor *)arg); | 1624 | ret_val = get_mon_info(info, argp); |
1624 | break; | 1625 | break; |
1625 | case CYGETTHRESH: | 1626 | case CYGETTHRESH: |
1626 | ret_val = get_threshold(info, (unsigned long *)arg); | 1627 | ret_val = get_threshold(info, argp); |
1627 | break; | 1628 | break; |
1628 | case CYSETTHRESH: | 1629 | case CYSETTHRESH: |
1629 | ret_val = set_threshold(info, (unsigned long *)arg); | 1630 | ret_val = set_threshold(info, argp); |
1630 | break; | 1631 | break; |
1631 | case CYGETDEFTHRESH: | 1632 | case CYGETDEFTHRESH: |
1632 | ret_val = get_default_threshold(info, (unsigned long *)arg); | 1633 | ret_val = get_default_threshold(info, argp); |
1633 | break; | 1634 | break; |
1634 | case CYSETDEFTHRESH: | 1635 | case CYSETDEFTHRESH: |
1635 | ret_val = set_default_threshold(info, (unsigned long *)arg); | 1636 | ret_val = set_default_threshold(info, argp); |
1636 | break; | 1637 | break; |
1637 | case CYGETTIMEOUT: | 1638 | case CYGETTIMEOUT: |
1638 | ret_val = get_timeout(info, (unsigned long *)arg); | 1639 | ret_val = get_timeout(info, argp); |
1639 | break; | 1640 | break; |
1640 | case CYSETTIMEOUT: | 1641 | case CYSETTIMEOUT: |
1641 | ret_val = set_timeout(info, (unsigned long *)arg); | 1642 | ret_val = set_timeout(info, argp); |
1642 | break; | 1643 | break; |
1643 | case CYGETDEFTIMEOUT: | 1644 | case CYGETDEFTIMEOUT: |
1644 | ret_val = get_default_timeout(info, (unsigned long *)arg); | 1645 | ret_val = get_default_timeout(info, argp); |
1645 | break; | 1646 | break; |
1646 | case CYSETDEFTIMEOUT: | 1647 | case CYSETDEFTIMEOUT: |
1647 | ret_val = set_default_timeout(info, (unsigned long)arg); | 1648 | ret_val = set_default_timeout(info, (unsigned long)arg); |
@@ -1664,21 +1665,20 @@ cy_ioctl(struct tty_struct *tty, struct file * file, | |||
1664 | 1665 | ||
1665 | /* The following commands are incompletely implemented!!! */ | 1666 | /* The following commands are incompletely implemented!!! */ |
1666 | case TIOCGSOFTCAR: | 1667 | case TIOCGSOFTCAR: |
1667 | ret_val = put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long *) arg); | 1668 | ret_val = put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long __user *) argp); |
1668 | break; | 1669 | break; |
1669 | case TIOCSSOFTCAR: | 1670 | case TIOCSSOFTCAR: |
1670 | ret_val = get_user(val, (unsigned long *) arg); | 1671 | ret_val = get_user(val, (unsigned long __user *) argp); |
1671 | if (ret_val) | 1672 | if (ret_val) |
1672 | break; | 1673 | break; |
1673 | tty->termios->c_cflag = | 1674 | tty->termios->c_cflag = |
1674 | ((tty->termios->c_cflag & ~CLOCAL) | (val ? CLOCAL : 0)); | 1675 | ((tty->termios->c_cflag & ~CLOCAL) | (val ? CLOCAL : 0)); |
1675 | break; | 1676 | break; |
1676 | case TIOCGSERIAL: | 1677 | case TIOCGSERIAL: |
1677 | ret_val = get_serial_info(info, (struct serial_struct *) arg); | 1678 | ret_val = get_serial_info(info, argp); |
1678 | break; | 1679 | break; |
1679 | case TIOCSSERIAL: | 1680 | case TIOCSSERIAL: |
1680 | ret_val = set_serial_info(info, | 1681 | ret_val = set_serial_info(info, argp); |
1681 | (struct serial_struct *) arg); | ||
1682 | break; | 1682 | break; |
1683 | default: | 1683 | default: |
1684 | ret_val = -ENOIOCTLCMD; | 1684 | ret_val = -ENOIOCTLCMD; |
@@ -1773,7 +1773,7 @@ cy_close(struct tty_struct * tty, struct file * filp) | |||
1773 | tty->driver->flush_buffer(tty); | 1773 | tty->driver->flush_buffer(tty); |
1774 | tty_ldisc_flush(tty); | 1774 | tty_ldisc_flush(tty); |
1775 | info->event = 0; | 1775 | info->event = 0; |
1776 | info->tty = 0; | 1776 | info->tty = NULL; |
1777 | if (info->blocked_open) { | 1777 | if (info->blocked_open) { |
1778 | if (info->close_delay) { | 1778 | if (info->close_delay) { |
1779 | msleep_interruptible(jiffies_to_msecs(info->close_delay)); | 1779 | msleep_interruptible(jiffies_to_msecs(info->close_delay)); |
@@ -2250,7 +2250,7 @@ scrn[1] = '\0'; | |||
2250 | info->card = index; | 2250 | info->card = index; |
2251 | info->line = port_num; | 2251 | info->line = port_num; |
2252 | info->flags = STD_COM_FLAGS; | 2252 | info->flags = STD_COM_FLAGS; |
2253 | info->tty = 0; | 2253 | info->tty = NULL; |
2254 | info->xmit_fifo_size = 12; | 2254 | info->xmit_fifo_size = 12; |
2255 | info->cor1 = CyPARITY_NONE|Cy_8_BITS; | 2255 | info->cor1 = CyPARITY_NONE|Cy_8_BITS; |
2256 | info->cor2 = CyETC; | 2256 | info->cor2 = CyETC; |
diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c index d0b88d0e87fd..7e1bd9562c2a 100644 --- a/drivers/char/specialix.c +++ b/drivers/char/specialix.c | |||
@@ -183,11 +183,6 @@ static int sx_poll = HZ; | |||
183 | 183 | ||
184 | static struct tty_driver *specialix_driver; | 184 | static struct tty_driver *specialix_driver; |
185 | 185 | ||
186 | static unsigned long baud_table[] = { | ||
187 | 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, | ||
188 | 9600, 19200, 38400, 57600, 115200, 0, | ||
189 | }; | ||
190 | |||
191 | static struct specialix_board sx_board[SX_NBOARD] = { | 186 | static struct specialix_board sx_board[SX_NBOARD] = { |
192 | { 0, SX_IOBASE1, 9, }, | 187 | { 0, SX_IOBASE1, 9, }, |
193 | { 0, SX_IOBASE2, 11, }, | 188 | { 0, SX_IOBASE2, 11, }, |
@@ -1090,9 +1085,9 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p | |||
1090 | 1085 | ||
1091 | if (baud == 38400) { | 1086 | if (baud == 38400) { |
1092 | if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) | 1087 | if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) |
1093 | baud ++; | 1088 | baud = 57600; |
1094 | if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) | 1089 | if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) |
1095 | baud += 2; | 1090 | baud = 115200; |
1096 | } | 1091 | } |
1097 | 1092 | ||
1098 | if (!baud) { | 1093 | if (!baud) { |
@@ -1150,11 +1145,9 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p | |||
1150 | sx_out(bp, CD186x_RBPRL, tmp & 0xff); | 1145 | sx_out(bp, CD186x_RBPRL, tmp & 0xff); |
1151 | sx_out(bp, CD186x_TBPRL, tmp & 0xff); | 1146 | sx_out(bp, CD186x_TBPRL, tmp & 0xff); |
1152 | spin_unlock_irqrestore(&bp->lock, flags); | 1147 | spin_unlock_irqrestore(&bp->lock, flags); |
1153 | if (port->custom_divisor) { | 1148 | if (port->custom_divisor) |
1154 | baud = (SX_OSCFREQ + port->custom_divisor/2) / port->custom_divisor; | 1149 | baud = (SX_OSCFREQ + port->custom_divisor/2) / port->custom_divisor; |
1155 | baud = ( baud + 5 ) / 10; | 1150 | baud = (baud + 5) / 10; /* Estimated CPS */ |
1156 | } else | ||
1157 | baud = (baud_table[baud] + 5) / 10; /* Estimated CPS */ | ||
1158 | 1151 | ||
1159 | /* Two timer ticks seems enough to wakeup something like SLIP driver */ | 1152 | /* Two timer ticks seems enough to wakeup something like SLIP driver */ |
1160 | tmp = ((baud + HZ/2) / HZ) * 2 - CD186x_NFIFO; | 1153 | tmp = ((baud + HZ/2) / HZ) * 2 - CD186x_NFIFO; |
diff --git a/drivers/char/sx.c b/drivers/char/sx.c index 5fec626598cd..cc10af08cb05 100644 --- a/drivers/char/sx.c +++ b/drivers/char/sx.c | |||
@@ -2602,7 +2602,7 @@ static void __exit sx_exit (void) | |||
2602 | } | 2602 | } |
2603 | } | 2603 | } |
2604 | if (misc_deregister(&sx_fw_device) < 0) { | 2604 | if (misc_deregister(&sx_fw_device) < 0) { |
2605 | printk (KERN_INFO "sx: couldn't deregister firmware loader devic\n"); | 2605 | printk (KERN_INFO "sx: couldn't deregister firmware loader device\n"); |
2606 | } | 2606 | } |
2607 | sx_dprintk (SX_DEBUG_CLEANUP, "Cleaning up drivers (%d)\n", sx_initialized); | 2607 | sx_dprintk (SX_DEBUG_CLEANUP, "Cleaning up drivers (%d)\n", sx_initialized); |
2608 | if (sx_initialized) | 2608 | if (sx_initialized) |
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c index f2864cc64240..06784adcc35c 100644 --- a/drivers/char/synclink.c +++ b/drivers/char/synclink.c | |||
@@ -133,8 +133,8 @@ static MGSL_PARAMS default_params = { | |||
133 | }; | 133 | }; |
134 | 134 | ||
135 | #define SHARED_MEM_ADDRESS_SIZE 0x40000 | 135 | #define SHARED_MEM_ADDRESS_SIZE 0x40000 |
136 | #define BUFFERLISTSIZE (PAGE_SIZE) | 136 | #define BUFFERLISTSIZE 4096 |
137 | #define DMABUFFERSIZE (PAGE_SIZE) | 137 | #define DMABUFFERSIZE 4096 |
138 | #define MAXRXFRAMES 7 | 138 | #define MAXRXFRAMES 7 |
139 | 139 | ||
140 | typedef struct _DMABUFFERENTRY | 140 | typedef struct _DMABUFFERENTRY |
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index a082a2e34252..6ad2d3bb945c 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c | |||
@@ -1153,7 +1153,14 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vend | |||
1153 | 1153 | ||
1154 | spin_unlock(&driver_lock); | 1154 | spin_unlock(&driver_lock); |
1155 | 1155 | ||
1156 | sysfs_create_group(&dev->kobj, chip->vendor.attr_group); | 1156 | if (sysfs_create_group(&dev->kobj, chip->vendor.attr_group)) { |
1157 | list_del(&chip->list); | ||
1158 | put_device(dev); | ||
1159 | clear_bit(chip->dev_num, dev_mask); | ||
1160 | kfree(chip); | ||
1161 | kfree(devname); | ||
1162 | return NULL; | ||
1163 | } | ||
1157 | 1164 | ||
1158 | chip->bios_dir = tpm_bios_log_setup(devname); | 1165 | chip->bios_dir = tpm_bios_log_setup(devname); |
1159 | 1166 | ||
diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c index ad8ffe49256f..1ab0896070be 100644 --- a/drivers/char/tpm/tpm_atmel.c +++ b/drivers/char/tpm/tpm_atmel.c | |||
@@ -184,7 +184,9 @@ static int __init init_atmel(void) | |||
184 | unsigned long base; | 184 | unsigned long base; |
185 | struct tpm_chip *chip; | 185 | struct tpm_chip *chip; |
186 | 186 | ||
187 | driver_register(&atml_drv); | 187 | rc = driver_register(&atml_drv); |
188 | if (rc) | ||
189 | return rc; | ||
188 | 190 | ||
189 | if ((iobase = atmel_get_base_addr(&base, ®ion_size)) == NULL) { | 191 | if ((iobase = atmel_get_base_addr(&base, ®ion_size)) == NULL) { |
190 | rc = -ENODEV; | 192 | rc = -ENODEV; |
@@ -195,10 +197,8 @@ static int __init init_atmel(void) | |||
195 | (atmel_request_region | 197 | (atmel_request_region |
196 | (tpm_atmel.base, region_size, "tpm_atmel0") == NULL) ? 0 : 1; | 198 | (tpm_atmel.base, region_size, "tpm_atmel0") == NULL) ? 0 : 1; |
197 | 199 | ||
198 | 200 | pdev = platform_device_register_simple("tpm_atmel", -1, NULL, 0); | |
199 | if (IS_ERR | 201 | if (IS_ERR(pdev)) { |
200 | (pdev = | ||
201 | platform_device_register_simple("tpm_atmel", -1, NULL, 0))) { | ||
202 | rc = PTR_ERR(pdev); | 202 | rc = PTR_ERR(pdev); |
203 | goto err_rel_reg; | 203 | goto err_rel_reg; |
204 | } | 204 | } |
diff --git a/drivers/char/tpm/tpm_nsc.c b/drivers/char/tpm/tpm_nsc.c index 26287aace87d..608f73071bef 100644 --- a/drivers/char/tpm/tpm_nsc.c +++ b/drivers/char/tpm/tpm_nsc.c | |||
@@ -284,7 +284,7 @@ static struct device_driver nsc_drv = { | |||
284 | static int __init init_nsc(void) | 284 | static int __init init_nsc(void) |
285 | { | 285 | { |
286 | int rc = 0; | 286 | int rc = 0; |
287 | int lo, hi; | 287 | int lo, hi, err; |
288 | int nscAddrBase = TPM_ADDR; | 288 | int nscAddrBase = TPM_ADDR; |
289 | struct tpm_chip *chip; | 289 | struct tpm_chip *chip; |
290 | unsigned long base; | 290 | unsigned long base; |
@@ -297,7 +297,9 @@ static int __init init_nsc(void) | |||
297 | return -ENODEV; | 297 | return -ENODEV; |
298 | } | 298 | } |
299 | 299 | ||
300 | driver_register(&nsc_drv); | 300 | err = driver_register(&nsc_drv); |
301 | if (err) | ||
302 | return err; | ||
301 | 303 | ||
302 | hi = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_HI); | 304 | hi = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_HI); |
303 | lo = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_LO); | 305 | lo = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_LO); |
diff --git a/drivers/char/watchdog/Kconfig b/drivers/char/watchdog/Kconfig index 89e46d6dfc4e..0187b1185323 100644 --- a/drivers/char/watchdog/Kconfig +++ b/drivers/char/watchdog/Kconfig | |||
@@ -13,7 +13,7 @@ config WATCHDOG | |||
13 | subsequently opening the file and then failing to write to it for | 13 | subsequently opening the file and then failing to write to it for |
14 | longer than 1 minute will result in rebooting the machine. This | 14 | longer than 1 minute will result in rebooting the machine. This |
15 | could be useful for a networked machine that needs to come back | 15 | could be useful for a networked machine that needs to come back |
16 | online as fast as possible after a lock-up. There's both a watchdog | 16 | on-line as fast as possible after a lock-up. There's both a watchdog |
17 | implementation entirely in software (which can sometimes fail to | 17 | implementation entirely in software (which can sometimes fail to |
18 | reboot the machine) and a driver for hardware watchdog boards, which | 18 | reboot the machine) and a driver for hardware watchdog boards, which |
19 | are more robust and can also keep track of the temperature inside | 19 | are more robust and can also keep track of the temperature inside |
@@ -60,7 +60,7 @@ config SOFT_WATCHDOG | |||
60 | 60 | ||
61 | # ARM Architecture | 61 | # ARM Architecture |
62 | 62 | ||
63 | config AT91_WATCHDOG | 63 | config AT91RM9200_WATCHDOG |
64 | tristate "AT91RM9200 watchdog" | 64 | tristate "AT91RM9200 watchdog" |
65 | depends on WATCHDOG && ARCH_AT91RM9200 | 65 | depends on WATCHDOG && ARCH_AT91RM9200 |
66 | help | 66 | help |
@@ -71,7 +71,7 @@ config 21285_WATCHDOG | |||
71 | tristate "DC21285 watchdog" | 71 | tristate "DC21285 watchdog" |
72 | depends on WATCHDOG && FOOTBRIDGE | 72 | depends on WATCHDOG && FOOTBRIDGE |
73 | help | 73 | help |
74 | The Intel Footbridge chip contains a builtin watchdog circuit. Say Y | 74 | The Intel Footbridge chip contains a built-in watchdog circuit. Say Y |
75 | here if you wish to use this. Alternatively say M to compile the | 75 | here if you wish to use this. Alternatively say M to compile the |
76 | driver as a module, which will be called wdt285. | 76 | driver as a module, which will be called wdt285. |
77 | 77 | ||
@@ -269,11 +269,11 @@ config IB700_WDT | |||
269 | Most people will say N. | 269 | Most people will say N. |
270 | 270 | ||
271 | config IBMASR | 271 | config IBMASR |
272 | tristate "IBM Automatic Server Restart" | 272 | tristate "IBM Automatic Server Restart" |
273 | depends on WATCHDOG && X86 | 273 | depends on WATCHDOG && X86 |
274 | help | 274 | help |
275 | This is the driver for the IBM Automatic Server Restart watchdog | 275 | This is the driver for the IBM Automatic Server Restart watchdog |
276 | timer builtin into some eServer xSeries machines. | 276 | timer built-in into some eServer xSeries machines. |
277 | 277 | ||
278 | To compile this driver as a module, choose M here: the | 278 | To compile this driver as a module, choose M here: the |
279 | module will be called ibmasr. | 279 | module will be called ibmasr. |
@@ -316,13 +316,16 @@ config I8XX_TCO | |||
316 | To compile this driver as a module, choose M here: the | 316 | To compile this driver as a module, choose M here: the |
317 | module will be called i8xx_tco. | 317 | module will be called i8xx_tco. |
318 | 318 | ||
319 | Note: This driver will be removed in the near future. Please | ||
320 | use the Intel TCO Timer/Watchdog driver. | ||
321 | |||
319 | config ITCO_WDT | 322 | config ITCO_WDT |
320 | tristate "Intel TCO Timer/Watchdog (EXPERIMENTAL)" | 323 | tristate "Intel TCO Timer/Watchdog" |
321 | depends on WATCHDOG && (X86 || IA64) && PCI && EXPERIMENTAL | 324 | depends on WATCHDOG && (X86 || IA64) && PCI |
322 | ---help--- | 325 | ---help--- |
323 | Hardware driver for the intel TCO timer based watchdog devices. | 326 | Hardware driver for the intel TCO timer based watchdog devices. |
324 | These drivers are included in the Intel 82801 I/O Controller | 327 | These drivers are included in the Intel 82801 I/O Controller |
325 | Hub family 'from ICH0 up to ICH7) and in the Intel 6300ESB | 328 | Hub family (from ICH0 up to ICH8) and in the Intel 6300ESB |
326 | controller hub. | 329 | controller hub. |
327 | 330 | ||
328 | The TCO (Total Cost of Ownership) timer is a watchdog timer | 331 | The TCO (Total Cost of Ownership) timer is a watchdog timer |
@@ -395,6 +398,26 @@ config CPU5_WDT | |||
395 | To compile this driver as a module, choose M here: the | 398 | To compile this driver as a module, choose M here: the |
396 | module will be called cpu5wdt. | 399 | module will be called cpu5wdt. |
397 | 400 | ||
401 | config SMSC37B787_WDT | ||
402 | tristate "Winbond SMsC37B787 Watchdog Timer" | ||
403 | depends on WATCHDOG && X86 | ||
404 | ---help--- | ||
405 | This is the driver for the hardware watchdog component on the | ||
406 | Winbond SMsC37B787 chipset as used on the NetRunner Mainboard | ||
407 | from Vision Systems and maybe others. | ||
408 | |||
409 | This watchdog simply watches your kernel to make sure it doesn't | ||
410 | freeze, and if it does, it reboots your computer after a certain | ||
411 | amount of time. | ||
412 | |||
413 | Usually a userspace daemon will notify the kernel WDT driver that | ||
414 | userspace is still alive, at regular intervals. | ||
415 | |||
416 | To compile this driver as a module, choose M here: the | ||
417 | module will be called smsc37b787_wdt. | ||
418 | |||
419 | Most people will say N. | ||
420 | |||
398 | config W83627HF_WDT | 421 | config W83627HF_WDT |
399 | tristate "W83627HF Watchdog Timer" | 422 | tristate "W83627HF Watchdog Timer" |
400 | depends on WATCHDOG && X86 | 423 | depends on WATCHDOG && X86 |
@@ -410,6 +433,21 @@ config W83627HF_WDT | |||
410 | 433 | ||
411 | Most people will say N. | 434 | Most people will say N. |
412 | 435 | ||
436 | config W83697HF_WDT | ||
437 | tristate "W83697HF/W83697HG Watchdog Timer" | ||
438 | depends on WATCHDOG && X86 | ||
439 | ---help--- | ||
440 | This is the driver for the hardware watchdog on the W83697HF/HG | ||
441 | chipset as used in Dedibox/VIA motherboards (and likely others). | ||
442 | This watchdog simply watches your kernel to make sure it doesn't | ||
443 | freeze, and if it does, it reboots your computer after a certain | ||
444 | amount of time. | ||
445 | |||
446 | To compile this driver as a module, choose M here: the | ||
447 | module will be called w83697hf_wdt. | ||
448 | |||
449 | Most people will say N. | ||
450 | |||
413 | config W83877F_WDT | 451 | config W83877F_WDT |
414 | tristate "W83877F (EMACS) Watchdog Timer" | 452 | tristate "W83877F (EMACS) Watchdog Timer" |
415 | depends on WATCHDOG && X86 | 453 | depends on WATCHDOG && X86 |
@@ -443,7 +481,7 @@ config MACHZ_WDT | |||
443 | depends on WATCHDOG && X86 | 481 | depends on WATCHDOG && X86 |
444 | ---help--- | 482 | ---help--- |
445 | If you are using a ZF Micro MachZ processor, say Y here, otherwise | 483 | If you are using a ZF Micro MachZ processor, say Y here, otherwise |
446 | N. This is the driver for the watchdog timer builtin on that | 484 | N. This is the driver for the watchdog timer built-in on that |
447 | processor using ZF-Logic interface. This watchdog simply watches | 485 | processor using ZF-Logic interface. This watchdog simply watches |
448 | your kernel to make sure it doesn't freeze, and if it does, it | 486 | your kernel to make sure it doesn't freeze, and if it does, it |
449 | reboots your computer after a certain amount of time. | 487 | reboots your computer after a certain amount of time. |
@@ -472,7 +510,6 @@ config SBC_EPX_C3_WATCHDOG | |||
472 | To compile this driver as a module, choose M here: the | 510 | To compile this driver as a module, choose M here: the |
473 | module will be called sbc_epx_c3. | 511 | module will be called sbc_epx_c3. |
474 | 512 | ||
475 | |||
476 | # PowerPC Architecture | 513 | # PowerPC Architecture |
477 | 514 | ||
478 | config 8xx_WDT | 515 | config 8xx_WDT |
@@ -502,7 +539,7 @@ config WATCHDOG_RTAS | |||
502 | help | 539 | help |
503 | This driver adds watchdog support for the RTAS watchdog. | 540 | This driver adds watchdog support for the RTAS watchdog. |
504 | 541 | ||
505 | To compile this driver as a module, choose M here. The module | 542 | To compile this driver as a module, choose M here. The module |
506 | will be called wdrtas. | 543 | will be called wdrtas. |
507 | 544 | ||
508 | # MIPS Architecture | 545 | # MIPS Architecture |
@@ -556,7 +593,7 @@ config SH_WDT_MMAP | |||
556 | help | 593 | help |
557 | If you say Y here, user applications will be able to mmap the | 594 | If you say Y here, user applications will be able to mmap the |
558 | WDT/CPG registers. | 595 | WDT/CPG registers. |
559 | # | 596 | |
560 | # SPARC64 Architecture | 597 | # SPARC64 Architecture |
561 | 598 | ||
562 | config WATCHDOG_CP1XXX | 599 | config WATCHDOG_CP1XXX |
diff --git a/drivers/char/watchdog/Makefile b/drivers/char/watchdog/Makefile index 7f70abad465a..36440497047c 100644 --- a/drivers/char/watchdog/Makefile +++ b/drivers/char/watchdog/Makefile | |||
@@ -23,7 +23,7 @@ obj-$(CONFIG_WDTPCI) += wdt_pci.o | |||
23 | obj-$(CONFIG_USBPCWATCHDOG) += pcwd_usb.o | 23 | obj-$(CONFIG_USBPCWATCHDOG) += pcwd_usb.o |
24 | 24 | ||
25 | # ARM Architecture | 25 | # ARM Architecture |
26 | obj-$(CONFIG_AT91_WATCHDOG) += at91_wdt.o | 26 | obj-$(CONFIG_AT91RM9200_WATCHDOG) += at91rm9200_wdt.o |
27 | obj-$(CONFIG_OMAP_WATCHDOG) += omap_wdt.o | 27 | obj-$(CONFIG_OMAP_WATCHDOG) += omap_wdt.o |
28 | obj-$(CONFIG_21285_WATCHDOG) += wdt285.o | 28 | obj-$(CONFIG_21285_WATCHDOG) += wdt285.o |
29 | obj-$(CONFIG_977_WATCHDOG) += wdt977.o | 29 | obj-$(CONFIG_977_WATCHDOG) += wdt977.o |
@@ -53,7 +53,9 @@ obj-$(CONFIG_SCx200_WDT) += scx200_wdt.o | |||
53 | obj-$(CONFIG_60XX_WDT) += sbc60xxwdt.o | 53 | obj-$(CONFIG_60XX_WDT) += sbc60xxwdt.o |
54 | obj-$(CONFIG_SBC8360_WDT) += sbc8360.o | 54 | obj-$(CONFIG_SBC8360_WDT) += sbc8360.o |
55 | obj-$(CONFIG_CPU5_WDT) += cpu5wdt.o | 55 | obj-$(CONFIG_CPU5_WDT) += cpu5wdt.o |
56 | obj-$(CONFIG_SMSC37B787_WDT) += smsc37b787_wdt.o | ||
56 | obj-$(CONFIG_W83627HF_WDT) += w83627hf_wdt.o | 57 | obj-$(CONFIG_W83627HF_WDT) += w83627hf_wdt.o |
58 | obj-$(CONFIG_W83697HF_WDT) += w83697hf_wdt.o | ||
57 | obj-$(CONFIG_W83877F_WDT) += w83877f_wdt.o | 59 | obj-$(CONFIG_W83877F_WDT) += w83877f_wdt.o |
58 | obj-$(CONFIG_W83977F_WDT) += w83977f_wdt.o | 60 | obj-$(CONFIG_W83977F_WDT) += w83977f_wdt.o |
59 | obj-$(CONFIG_MACHZ_WDT) += machzwd.o | 61 | obj-$(CONFIG_MACHZ_WDT) += machzwd.o |
diff --git a/drivers/char/watchdog/alim7101_wdt.c b/drivers/char/watchdog/alim7101_wdt.c index 5948863b592b..bf25d0a55a99 100644 --- a/drivers/char/watchdog/alim7101_wdt.c +++ b/drivers/char/watchdog/alim7101_wdt.c | |||
@@ -77,7 +77,8 @@ static struct pci_dev *alim7101_pmu; | |||
77 | 77 | ||
78 | static int nowayout = WATCHDOG_NOWAYOUT; | 78 | static int nowayout = WATCHDOG_NOWAYOUT; |
79 | module_param(nowayout, int, 0); | 79 | module_param(nowayout, int, 0); |
80 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); | 80 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" |
81 | __stringify(CONFIG_WATCHDOG_NOWAYOUT) ")"); | ||
81 | 82 | ||
82 | /* | 83 | /* |
83 | * Whack the dog | 84 | * Whack the dog |
@@ -415,6 +416,16 @@ err_out: | |||
415 | module_init(alim7101_wdt_init); | 416 | module_init(alim7101_wdt_init); |
416 | module_exit(alim7101_wdt_unload); | 417 | module_exit(alim7101_wdt_unload); |
417 | 418 | ||
419 | static struct pci_device_id alim7101_pci_tbl[] __devinitdata = { | ||
420 | { PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, | ||
421 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | ||
422 | { PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101, | ||
423 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | ||
424 | { } | ||
425 | }; | ||
426 | |||
427 | MODULE_DEVICE_TABLE(pci, alim7101_pci_tbl); | ||
428 | |||
418 | MODULE_AUTHOR("Steve Hill"); | 429 | MODULE_AUTHOR("Steve Hill"); |
419 | MODULE_DESCRIPTION("ALi M7101 PMU Computer Watchdog Timer driver"); | 430 | MODULE_DESCRIPTION("ALi M7101 PMU Computer Watchdog Timer driver"); |
420 | MODULE_LICENSE("GPL"); | 431 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/char/watchdog/at91_wdt.c b/drivers/char/watchdog/at91rm9200_wdt.c index 4e7a1145e78f..4e7a1145e78f 100644 --- a/drivers/char/watchdog/at91_wdt.c +++ b/drivers/char/watchdog/at91rm9200_wdt.c | |||
diff --git a/drivers/char/watchdog/iTCO_wdt.c b/drivers/char/watchdog/iTCO_wdt.c index aaac94db0d8b..b6f29cb8bd39 100644 --- a/drivers/char/watchdog/iTCO_wdt.c +++ b/drivers/char/watchdog/iTCO_wdt.c | |||
@@ -35,6 +35,10 @@ | |||
35 | * 82801GDH (ICH7DH) : document number 307013-002, 307014-009, | 35 | * 82801GDH (ICH7DH) : document number 307013-002, 307014-009, |
36 | * 82801GBM (ICH7-M) : document number 307013-002, 307014-009, | 36 | * 82801GBM (ICH7-M) : document number 307013-002, 307014-009, |
37 | * 82801GHM (ICH7-M DH) : document number 307013-002, 307014-009, | 37 | * 82801GHM (ICH7-M DH) : document number 307013-002, 307014-009, |
38 | * 82801HB (ICH8) : document number 313056-002, 313057-004, | ||
39 | * 82801HR (ICH8R) : document number 313056-002, 313057-004, | ||
40 | * 82801HH (ICH8DH) : document number 313056-002, 313057-004, | ||
41 | * 82801HO (ICH8DO) : document number 313056-002, 313057-004, | ||
38 | * 6300ESB (6300ESB) : document number 300641-003 | 42 | * 6300ESB (6300ESB) : document number 300641-003 |
39 | */ | 43 | */ |
40 | 44 | ||
@@ -45,7 +49,7 @@ | |||
45 | /* Module and version information */ | 49 | /* Module and version information */ |
46 | #define DRV_NAME "iTCO_wdt" | 50 | #define DRV_NAME "iTCO_wdt" |
47 | #define DRV_VERSION "1.00" | 51 | #define DRV_VERSION "1.00" |
48 | #define DRV_RELDATE "30-Jul-2006" | 52 | #define DRV_RELDATE "08-Oct-2006" |
49 | #define PFX DRV_NAME ": " | 53 | #define PFX DRV_NAME ": " |
50 | 54 | ||
51 | /* Includes */ | 55 | /* Includes */ |
@@ -85,6 +89,9 @@ enum iTCO_chipsets { | |||
85 | TCO_ICH7, /* ICH7 & ICH7R */ | 89 | TCO_ICH7, /* ICH7 & ICH7R */ |
86 | TCO_ICH7M, /* ICH7-M */ | 90 | TCO_ICH7M, /* ICH7-M */ |
87 | TCO_ICH7MDH, /* ICH7-M DH */ | 91 | TCO_ICH7MDH, /* ICH7-M DH */ |
92 | TCO_ICH8, /* ICH8 & ICH8R */ | ||
93 | TCO_ICH8DH, /* ICH8DH */ | ||
94 | TCO_ICH8DO, /* ICH8DO */ | ||
88 | }; | 95 | }; |
89 | 96 | ||
90 | static struct { | 97 | static struct { |
@@ -108,6 +115,9 @@ static struct { | |||
108 | {"ICH7 or ICH7R", 2}, | 115 | {"ICH7 or ICH7R", 2}, |
109 | {"ICH7-M", 2}, | 116 | {"ICH7-M", 2}, |
110 | {"ICH7-M DH", 2}, | 117 | {"ICH7-M DH", 2}, |
118 | {"ICH8 or ICH8R", 2}, | ||
119 | {"ICH8DH", 2}, | ||
120 | {"ICH8DO", 2}, | ||
111 | {NULL,0} | 121 | {NULL,0} |
112 | }; | 122 | }; |
113 | 123 | ||
@@ -135,6 +145,9 @@ static struct pci_device_id iTCO_wdt_pci_tbl[] = { | |||
135 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH7 }, | 145 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH7 }, |
136 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH7M }, | 146 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH7M }, |
137 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_31, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH7MDH }, | 147 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_31, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH7MDH }, |
148 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH8 }, | ||
149 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH8DH }, | ||
150 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH8DO }, | ||
138 | { 0, }, /* End of list */ | 151 | { 0, }, /* End of list */ |
139 | }; | 152 | }; |
140 | MODULE_DEVICE_TABLE (pci, iTCO_wdt_pci_tbl); | 153 | MODULE_DEVICE_TABLE (pci, iTCO_wdt_pci_tbl); |
@@ -355,7 +368,8 @@ static int iTCO_wdt_get_timeleft (int *time_left) | |||
355 | spin_unlock(&iTCO_wdt_private.io_lock); | 368 | spin_unlock(&iTCO_wdt_private.io_lock); |
356 | 369 | ||
357 | *time_left = (val8 * 6) / 10; | 370 | *time_left = (val8 * 6) / 10; |
358 | } | 371 | } else |
372 | return -EINVAL; | ||
359 | return 0; | 373 | return 0; |
360 | } | 374 | } |
361 | 375 | ||
@@ -426,7 +440,6 @@ static int iTCO_wdt_ioctl (struct inode *inode, struct file *file, | |||
426 | { | 440 | { |
427 | int new_options, retval = -EINVAL; | 441 | int new_options, retval = -EINVAL; |
428 | int new_heartbeat; | 442 | int new_heartbeat; |
429 | int time_left; | ||
430 | void __user *argp = (void __user *)arg; | 443 | void __user *argp = (void __user *)arg; |
431 | int __user *p = argp; | 444 | int __user *p = argp; |
432 | static struct watchdog_info ident = { | 445 | static struct watchdog_info ident = { |
@@ -486,6 +499,8 @@ static int iTCO_wdt_ioctl (struct inode *inode, struct file *file, | |||
486 | 499 | ||
487 | case WDIOC_GETTIMELEFT: | 500 | case WDIOC_GETTIMELEFT: |
488 | { | 501 | { |
502 | int time_left; | ||
503 | |||
489 | if (iTCO_wdt_get_timeleft(&time_left)) | 504 | if (iTCO_wdt_get_timeleft(&time_left)) |
490 | return -EINVAL; | 505 | return -EINVAL; |
491 | 506 | ||
diff --git a/drivers/char/watchdog/s3c2410_wdt.c b/drivers/char/watchdog/s3c2410_wdt.c index 68b1ca976d53..18cb050c3862 100644 --- a/drivers/char/watchdog/s3c2410_wdt.c +++ b/drivers/char/watchdog/s3c2410_wdt.c | |||
@@ -380,18 +380,21 @@ static int s3c2410wdt_probe(struct platform_device *pdev) | |||
380 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | 380 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); |
381 | if (res == NULL) { | 381 | if (res == NULL) { |
382 | printk(KERN_INFO PFX "failed to get irq resource\n"); | 382 | printk(KERN_INFO PFX "failed to get irq resource\n"); |
383 | iounmap(wdt_base); | ||
383 | return -ENOENT; | 384 | return -ENOENT; |
384 | } | 385 | } |
385 | 386 | ||
386 | ret = request_irq(res->start, s3c2410wdt_irq, 0, pdev->name, pdev); | 387 | ret = request_irq(res->start, s3c2410wdt_irq, 0, pdev->name, pdev); |
387 | if (ret != 0) { | 388 | if (ret != 0) { |
388 | printk(KERN_INFO PFX "failed to install irq (%d)\n", ret); | 389 | printk(KERN_INFO PFX "failed to install irq (%d)\n", ret); |
390 | iounmap(wdt_base); | ||
389 | return ret; | 391 | return ret; |
390 | } | 392 | } |
391 | 393 | ||
392 | wdt_clock = clk_get(&pdev->dev, "watchdog"); | 394 | wdt_clock = clk_get(&pdev->dev, "watchdog"); |
393 | if (wdt_clock == NULL) { | 395 | if (wdt_clock == NULL) { |
394 | printk(KERN_INFO PFX "failed to find watchdog clock source\n"); | 396 | printk(KERN_INFO PFX "failed to find watchdog clock source\n"); |
397 | iounmap(wdt_base); | ||
395 | return -ENOENT; | 398 | return -ENOENT; |
396 | } | 399 | } |
397 | 400 | ||
@@ -415,6 +418,7 @@ static int s3c2410wdt_probe(struct platform_device *pdev) | |||
415 | if (ret) { | 418 | if (ret) { |
416 | printk (KERN_ERR PFX "cannot register miscdev on minor=%d (%d)\n", | 419 | printk (KERN_ERR PFX "cannot register miscdev on minor=%d (%d)\n", |
417 | WATCHDOG_MINOR, ret); | 420 | WATCHDOG_MINOR, ret); |
421 | iounmap(wdt_base); | ||
418 | return ret; | 422 | return ret; |
419 | } | 423 | } |
420 | 424 | ||
@@ -451,6 +455,7 @@ static int s3c2410wdt_remove(struct platform_device *dev) | |||
451 | wdt_clock = NULL; | 455 | wdt_clock = NULL; |
452 | } | 456 | } |
453 | 457 | ||
458 | iounmap(wdt_base); | ||
454 | misc_deregister(&s3c2410wdt_miscdev); | 459 | misc_deregister(&s3c2410wdt_miscdev); |
455 | return 0; | 460 | return 0; |
456 | } | 461 | } |
diff --git a/drivers/char/watchdog/sc1200wdt.c b/drivers/char/watchdog/sc1200wdt.c index d8d0f28e0acf..e3239833e4b0 100644 --- a/drivers/char/watchdog/sc1200wdt.c +++ b/drivers/char/watchdog/sc1200wdt.c | |||
@@ -392,7 +392,7 @@ static int __init sc1200wdt_init(void) | |||
392 | if (io == -1) { | 392 | if (io == -1) { |
393 | printk(KERN_ERR PFX "io parameter must be specified\n"); | 393 | printk(KERN_ERR PFX "io parameter must be specified\n"); |
394 | ret = -EINVAL; | 394 | ret = -EINVAL; |
395 | goto out_clean; | 395 | goto out_pnp; |
396 | } | 396 | } |
397 | 397 | ||
398 | #if defined CONFIG_PNP | 398 | #if defined CONFIG_PNP |
@@ -405,7 +405,7 @@ static int __init sc1200wdt_init(void) | |||
405 | if (!request_region(io, io_len, SC1200_MODULE_NAME)) { | 405 | if (!request_region(io, io_len, SC1200_MODULE_NAME)) { |
406 | printk(KERN_ERR PFX "Unable to register IO port %#x\n", io); | 406 | printk(KERN_ERR PFX "Unable to register IO port %#x\n", io); |
407 | ret = -EBUSY; | 407 | ret = -EBUSY; |
408 | goto out_clean; | 408 | goto out_pnp; |
409 | } | 409 | } |
410 | 410 | ||
411 | ret = sc1200wdt_probe(); | 411 | ret = sc1200wdt_probe(); |
@@ -435,6 +435,11 @@ out_rbt: | |||
435 | out_io: | 435 | out_io: |
436 | release_region(io, io_len); | 436 | release_region(io, io_len); |
437 | 437 | ||
438 | out_pnp: | ||
439 | #if defined CONFIG_PNP | ||
440 | if (isapnp) | ||
441 | pnp_unregister_driver(&scl200wdt_pnp_driver); | ||
442 | #endif | ||
438 | goto out_clean; | 443 | goto out_clean; |
439 | } | 444 | } |
440 | 445 | ||
diff --git a/drivers/char/watchdog/smsc37b787_wdt.c b/drivers/char/watchdog/smsc37b787_wdt.c new file mode 100644 index 000000000000..9f56913b484f --- /dev/null +++ b/drivers/char/watchdog/smsc37b787_wdt.c | |||
@@ -0,0 +1,627 @@ | |||
1 | /* | ||
2 | * SMsC 37B787 Watchdog Timer driver for Linux 2.6.x.x | ||
3 | * | ||
4 | * Based on acquirewdt.c by Alan Cox <alan@redhat.com> | ||
5 | * and some other existing drivers | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License | ||
9 | * as published by the Free Software Foundation; either version | ||
10 | * 2 of the License, or (at your option) any later version. | ||
11 | * | ||
12 | * The authors do NOT admit liability nor provide warranty for | ||
13 | * any of this software. This material is provided "AS-IS" in | ||
14 | * the hope that it may be useful for others. | ||
15 | * | ||
16 | * (C) Copyright 2003-2006 Sven Anders <anders@anduras.de> | ||
17 | * | ||
18 | * History: | ||
19 | * 2003 - Created version 1.0 for Linux 2.4.x. | ||
20 | * 2006 - Ported to Linux 2.6, added nowayout and MAGICCLOSE | ||
21 | * features. Released version 1.1 | ||
22 | * | ||
23 | * Theory of operation: | ||
24 | * | ||
25 | * A Watchdog Timer (WDT) is a hardware circuit that can | ||
26 | * reset the computer system in case of a software fault. | ||
27 | * You probably knew that already. | ||
28 | * | ||
29 | * Usually a userspace daemon will notify the kernel WDT driver | ||
30 | * via the /dev/watchdog special device file that userspace is | ||
31 | * still alive, at regular intervals. When such a notification | ||
32 | * occurs, the driver will usually tell the hardware watchdog | ||
33 | * that everything is in order, and that the watchdog should wait | ||
34 | * for yet another little while to reset the system. | ||
35 | * If userspace fails (RAM error, kernel bug, whatever), the | ||
36 | * notifications cease to occur, and the hardware watchdog will | ||
37 | * reset the system (causing a reboot) after the timeout occurs. | ||
38 | * | ||
39 | * Create device with: | ||
40 | * mknod /dev/watchdog c 10 130 | ||
41 | * | ||
42 | * For an example userspace keep-alive daemon, see: | ||
43 | * Documentation/watchdog/watchdog.txt | ||
44 | */ | ||
45 | |||
46 | #include <linux/module.h> | ||
47 | #include <linux/moduleparam.h> | ||
48 | #include <linux/types.h> | ||
49 | #include <linux/miscdevice.h> | ||
50 | #include <linux/watchdog.h> | ||
51 | #include <linux/delay.h> | ||
52 | #include <linux/fs.h> | ||
53 | #include <linux/ioport.h> | ||
54 | #include <linux/notifier.h> | ||
55 | #include <linux/reboot.h> | ||
56 | #include <linux/init.h> | ||
57 | #include <linux/spinlock.h> | ||
58 | |||
59 | #include <asm/io.h> | ||
60 | #include <asm/uaccess.h> | ||
61 | #include <asm/system.h> | ||
62 | |||
63 | /* enable support for minutes as units? */ | ||
64 | /* (does not always work correctly, so disabled by default!) */ | ||
65 | #define SMSC_SUPPORT_MINUTES | ||
66 | #undef SMSC_SUPPORT_MINUTES | ||
67 | |||
68 | #define MAX_TIMEOUT 255 | ||
69 | |||
70 | #define UNIT_SECOND 0 | ||
71 | #define UNIT_MINUTE 1 | ||
72 | |||
73 | #define MODNAME "smsc37b787_wdt: " | ||
74 | #define VERSION "1.1" | ||
75 | |||
76 | #define IOPORT 0x3F0 | ||
77 | #define IOPORT_SIZE 2 | ||
78 | #define IODEV_NO 8 | ||
79 | |||
80 | static int unit = UNIT_SECOND; /* timer's unit */ | ||
81 | static int timeout = 60; /* timeout value: default is 60 "units" */ | ||
82 | static unsigned long timer_enabled = 0; /* is the timer enabled? */ | ||
83 | |||
84 | static char expect_close; /* is the close expected? */ | ||
85 | |||
86 | static spinlock_t io_lock; /* to guard the watchdog from io races */ | ||
87 | |||
88 | static int nowayout = WATCHDOG_NOWAYOUT; | ||
89 | |||
90 | /* -- Low level function ----------------------------------------*/ | ||
91 | |||
92 | /* unlock the IO chip */ | ||
93 | |||
94 | static inline void open_io_config(void) | ||
95 | { | ||
96 | outb(0x55, IOPORT); | ||
97 | mdelay(1); | ||
98 | outb(0x55, IOPORT); | ||
99 | } | ||
100 | |||
101 | /* lock the IO chip */ | ||
102 | static inline void close_io_config(void) | ||
103 | { | ||
104 | outb(0xAA, IOPORT); | ||
105 | } | ||
106 | |||
107 | /* select the IO device */ | ||
108 | static inline void select_io_device(unsigned char devno) | ||
109 | { | ||
110 | outb(0x07, IOPORT); | ||
111 | outb(devno, IOPORT+1); | ||
112 | } | ||
113 | |||
114 | /* write to the control register */ | ||
115 | static inline void write_io_cr(unsigned char reg, unsigned char data) | ||
116 | { | ||
117 | outb(reg, IOPORT); | ||
118 | outb(data, IOPORT+1); | ||
119 | } | ||
120 | |||
121 | /* read from the control register */ | ||
122 | static inline char read_io_cr(unsigned char reg) | ||
123 | { | ||
124 | outb(reg, IOPORT); | ||
125 | return inb(IOPORT+1); | ||
126 | } | ||
127 | |||
128 | /* -- Medium level functions ------------------------------------*/ | ||
129 | |||
130 | static inline void gpio_bit12(unsigned char reg) | ||
131 | { | ||
132 | // -- General Purpose I/O Bit 1.2 -- | ||
133 | // Bit 0, In/Out: 0 = Output, 1 = Input | ||
134 | // Bit 1, Polarity: 0 = No Invert, 1 = Invert | ||
135 | // Bit 2, Group Enable Intr.: 0 = Disable, 1 = Enable | ||
136 | // Bit 3/4, Function select: 00 = GPI/O, 01 = WDT, 10 = P17, | ||
137 | // 11 = Either Edge Triggered Intr. 2 | ||
138 | // Bit 5/6 (Reserved) | ||
139 | // Bit 7, Output Type: 0 = Push Pull Bit, 1 = Open Drain | ||
140 | write_io_cr(0xE2, reg); | ||
141 | } | ||
142 | |||
143 | static inline void gpio_bit13(unsigned char reg) | ||
144 | { | ||
145 | // -- General Purpose I/O Bit 1.3 -- | ||
146 | // Bit 0, In/Out: 0 = Output, 1 = Input | ||
147 | // Bit 1, Polarity: 0 = No Invert, 1 = Invert | ||
148 | // Bit 2, Group Enable Intr.: 0 = Disable, 1 = Enable | ||
149 | // Bit 3, Function select: 0 = GPI/O, 1 = LED | ||
150 | // Bit 4-6 (Reserved) | ||
151 | // Bit 7, Output Type: 0 = Push Pull Bit, 1 = Open Drain | ||
152 | write_io_cr(0xE3, reg); | ||
153 | } | ||
154 | |||
155 | static inline void wdt_timer_units(unsigned char new_units) | ||
156 | { | ||
157 | // -- Watchdog timer units -- | ||
158 | // Bit 0-6 (Reserved) | ||
159 | // Bit 7, WDT Time-out Value Units Select | ||
160 | // (0 = Minutes, 1 = Seconds) | ||
161 | write_io_cr(0xF1, new_units); | ||
162 | } | ||
163 | |||
164 | static inline void wdt_timeout_value(unsigned char new_timeout) | ||
165 | { | ||
166 | // -- Watchdog Timer Time-out Value -- | ||
167 | // Bit 0-7 Binary coded units (0=Disabled, 1..255) | ||
168 | write_io_cr(0xF2, new_timeout); | ||
169 | } | ||
170 | |||
171 | static inline void wdt_timer_conf(unsigned char conf) | ||
172 | { | ||
173 | // -- Watchdog timer configuration -- | ||
174 | // Bit 0 Joystick enable: 0* = No Reset, 1 = Reset WDT upon Gameport I/O | ||
175 | // Bit 1 Keyboard enable: 0* = No Reset, 1 = Reset WDT upon KBD Intr. | ||
176 | // Bit 2 Mouse enable: 0* = No Reset, 1 = Reset WDT upon Mouse Intr. | ||
177 | // Bit 3 Reset the timer | ||
178 | // (Wrong in SMsC documentation? Given as: PowerLED Timout Enabled) | ||
179 | // Bit 4-7 WDT Interrupt Mapping: (0000* = Disabled, | ||
180 | // 0001=IRQ1, 0010=(Invalid), 0011=IRQ3 to 1111=IRQ15) | ||
181 | write_io_cr(0xF3, conf); | ||
182 | } | ||
183 | |||
184 | static inline void wdt_timer_ctrl(unsigned char reg) | ||
185 | { | ||
186 | // -- Watchdog timer control -- | ||
187 | // Bit 0 Status Bit: 0 = Timer counting, 1 = Timeout occured | ||
188 | // Bit 1 Power LED Toggle: 0 = Disable Toggle, 1 = Toggle at 1 Hz | ||
189 | // Bit 2 Force Timeout: 1 = Forces WD timeout event (self-cleaning) | ||
190 | // Bit 3 P20 Force Timeout enabled: | ||
191 | // 0 = P20 activity does not generate the WD timeout event | ||
192 | // 1 = P20 Allows rising edge of P20, from the keyboard | ||
193 | // controller, to force the WD timeout event. | ||
194 | // Bit 4 (Reserved) | ||
195 | // -- Soft power management -- | ||
196 | // Bit 5 Stop Counter: 1 = Stop software power down counter | ||
197 | // set via register 0xB8, (self-cleaning) | ||
198 | // (Upon read: 0 = Counter running, 1 = Counter stopped) | ||
199 | // Bit 6 Restart Counter: 1 = Restart software power down counter | ||
200 | // set via register 0xB8, (self-cleaning) | ||
201 | // Bit 7 SPOFF: 1 = Force software power down (self-cleaning) | ||
202 | |||
203 | write_io_cr(0xF4, reg); | ||
204 | } | ||
205 | |||
206 | /* -- Higher level functions ------------------------------------*/ | ||
207 | |||
208 | /* initialize watchdog */ | ||
209 | |||
210 | static void wb_smsc_wdt_initialize(void) | ||
211 | { | ||
212 | unsigned char old; | ||
213 | |||
214 | spin_lock(&io_lock); | ||
215 | open_io_config(); | ||
216 | select_io_device(IODEV_NO); | ||
217 | |||
218 | // enable the watchdog | ||
219 | gpio_bit13(0x08); // Select pin 80 = LED not GPIO | ||
220 | gpio_bit12(0x0A); // Set pin 79 = WDT not GPIO/Output/Polarity=Invert | ||
221 | |||
222 | // disable the timeout | ||
223 | wdt_timeout_value(0); | ||
224 | |||
225 | // reset control register | ||
226 | wdt_timer_ctrl(0x00); | ||
227 | |||
228 | // reset configuration register | ||
229 | wdt_timer_conf(0x00); | ||
230 | |||
231 | // read old (timer units) register | ||
232 | old = read_io_cr(0xF1) & 0x7F; | ||
233 | if (unit == UNIT_SECOND) old |= 0x80; // set to seconds | ||
234 | |||
235 | // set the watchdog timer units | ||
236 | wdt_timer_units(old); | ||
237 | |||
238 | close_io_config(); | ||
239 | spin_unlock(&io_lock); | ||
240 | } | ||
241 | |||
242 | /* shutdown the watchdog */ | ||
243 | |||
244 | static void wb_smsc_wdt_shutdown(void) | ||
245 | { | ||
246 | spin_lock(&io_lock); | ||
247 | open_io_config(); | ||
248 | select_io_device(IODEV_NO); | ||
249 | |||
250 | // disable the watchdog | ||
251 | gpio_bit13(0x09); | ||
252 | gpio_bit12(0x09); | ||
253 | |||
254 | // reset watchdog config register | ||
255 | wdt_timer_conf(0x00); | ||
256 | |||
257 | // reset watchdog control register | ||
258 | wdt_timer_ctrl(0x00); | ||
259 | |||
260 | // disable timeout | ||
261 | wdt_timeout_value(0x00); | ||
262 | |||
263 | close_io_config(); | ||
264 | spin_unlock(&io_lock); | ||
265 | } | ||
266 | |||
267 | /* set timeout => enable watchdog */ | ||
268 | |||
269 | static void wb_smsc_wdt_set_timeout(unsigned char new_timeout) | ||
270 | { | ||
271 | spin_lock(&io_lock); | ||
272 | open_io_config(); | ||
273 | select_io_device(IODEV_NO); | ||
274 | |||
275 | // set Power LED to blink, if we enable the timeout | ||
276 | wdt_timer_ctrl((new_timeout == 0) ? 0x00 : 0x02); | ||
277 | |||
278 | // set timeout value | ||
279 | wdt_timeout_value(new_timeout); | ||
280 | |||
281 | close_io_config(); | ||
282 | spin_unlock(&io_lock); | ||
283 | } | ||
284 | |||
285 | /* get timeout */ | ||
286 | |||
287 | static unsigned char wb_smsc_wdt_get_timeout(void) | ||
288 | { | ||
289 | unsigned char set_timeout; | ||
290 | |||
291 | spin_lock(&io_lock); | ||
292 | open_io_config(); | ||
293 | select_io_device(IODEV_NO); | ||
294 | set_timeout = read_io_cr(0xF2); | ||
295 | close_io_config(); | ||
296 | spin_unlock(&io_lock); | ||
297 | |||
298 | return set_timeout; | ||
299 | } | ||
300 | |||
301 | /* disable watchdog */ | ||
302 | |||
303 | static void wb_smsc_wdt_disable(void) | ||
304 | { | ||
305 | // set the timeout to 0 to disable the watchdog | ||
306 | wb_smsc_wdt_set_timeout(0); | ||
307 | } | ||
308 | |||
309 | /* enable watchdog by setting the current timeout */ | ||
310 | |||
311 | static void wb_smsc_wdt_enable(void) | ||
312 | { | ||
313 | // set the current timeout... | ||
314 | wb_smsc_wdt_set_timeout(timeout); | ||
315 | } | ||
316 | |||
317 | /* reset the timer */ | ||
318 | |||
319 | static void wb_smsc_wdt_reset_timer(void) | ||
320 | { | ||
321 | spin_lock(&io_lock); | ||
322 | open_io_config(); | ||
323 | select_io_device(IODEV_NO); | ||
324 | |||
325 | // reset the timer | ||
326 | wdt_timeout_value(timeout); | ||
327 | wdt_timer_conf(0x08); | ||
328 | |||
329 | close_io_config(); | ||
330 | spin_unlock(&io_lock); | ||
331 | } | ||
332 | |||
333 | /* return, if the watchdog is enabled (timeout is set...) */ | ||
334 | |||
335 | static int wb_smsc_wdt_status(void) | ||
336 | { | ||
337 | return (wb_smsc_wdt_get_timeout() == 0) ? 0 : WDIOF_KEEPALIVEPING; | ||
338 | } | ||
339 | |||
340 | |||
341 | /* -- File operations -------------------------------------------*/ | ||
342 | |||
343 | /* open => enable watchdog and set initial timeout */ | ||
344 | |||
345 | static int wb_smsc_wdt_open(struct inode *inode, struct file *file) | ||
346 | { | ||
347 | /* /dev/watchdog can only be opened once */ | ||
348 | |||
349 | if (test_and_set_bit(0, &timer_enabled)) | ||
350 | return -EBUSY; | ||
351 | |||
352 | if (nowayout) | ||
353 | __module_get(THIS_MODULE); | ||
354 | |||
355 | /* Reload and activate timer */ | ||
356 | wb_smsc_wdt_enable(); | ||
357 | |||
358 | printk(KERN_INFO MODNAME "Watchdog enabled. Timeout set to %d %s.\n", timeout, (unit == UNIT_SECOND) ? "second(s)" : "minute(s)"); | ||
359 | |||
360 | return nonseekable_open(inode, file); | ||
361 | } | ||
362 | |||
363 | /* close => shut off the timer */ | ||
364 | |||
365 | static int wb_smsc_wdt_release(struct inode *inode, struct file *file) | ||
366 | { | ||
367 | /* Shut off the timer. */ | ||
368 | |||
369 | if (expect_close == 42) { | ||
370 | wb_smsc_wdt_disable(); | ||
371 | printk(KERN_INFO MODNAME "Watchdog disabled, sleeping again...\n"); | ||
372 | } else { | ||
373 | printk(KERN_CRIT MODNAME "Unexpected close, not stopping watchdog!\n"); | ||
374 | wb_smsc_wdt_reset_timer(); | ||
375 | } | ||
376 | |||
377 | clear_bit(0, &timer_enabled); | ||
378 | expect_close = 0; | ||
379 | return 0; | ||
380 | } | ||
381 | |||
382 | /* write => update the timer to keep the machine alive */ | ||
383 | |||
384 | static ssize_t wb_smsc_wdt_write(struct file *file, const char __user *data, | ||
385 | size_t len, loff_t *ppos) | ||
386 | { | ||
387 | /* See if we got the magic character 'V' and reload the timer */ | ||
388 | if (len) { | ||
389 | if (!nowayout) { | ||
390 | size_t i; | ||
391 | |||
392 | /* reset expect flag */ | ||
393 | expect_close = 0; | ||
394 | |||
395 | /* scan to see whether or not we got the magic character */ | ||
396 | for (i = 0; i != len; i++) { | ||
397 | char c; | ||
398 | if (get_user(c, data+i)) | ||
399 | return -EFAULT; | ||
400 | if (c == 'V') | ||
401 | expect_close = 42; | ||
402 | } | ||
403 | } | ||
404 | |||
405 | /* someone wrote to us, we should reload the timer */ | ||
406 | wb_smsc_wdt_reset_timer(); | ||
407 | } | ||
408 | return len; | ||
409 | } | ||
410 | |||
411 | /* ioctl => control interface */ | ||
412 | |||
413 | static int wb_smsc_wdt_ioctl(struct inode *inode, struct file *file, | ||
414 | unsigned int cmd, unsigned long arg) | ||
415 | { | ||
416 | int new_timeout; | ||
417 | |||
418 | union { | ||
419 | struct watchdog_info __user *ident; | ||
420 | int __user *i; | ||
421 | } uarg; | ||
422 | |||
423 | static struct watchdog_info ident = { | ||
424 | .options = WDIOF_KEEPALIVEPING | | ||
425 | WDIOF_SETTIMEOUT | | ||
426 | WDIOF_MAGICCLOSE, | ||
427 | .firmware_version = 0, | ||
428 | .identity = "SMsC 37B787 Watchdog" | ||
429 | }; | ||
430 | |||
431 | uarg.i = (int __user *)arg; | ||
432 | |||
433 | switch (cmd) { | ||
434 | default: | ||
435 | return -ENOTTY; | ||
436 | |||
437 | case WDIOC_GETSUPPORT: | ||
438 | return copy_to_user(uarg.ident, &ident, | ||
439 | sizeof(ident)) ? -EFAULT : 0; | ||
440 | |||
441 | case WDIOC_GETSTATUS: | ||
442 | return put_user(wb_smsc_wdt_status(), uarg.i); | ||
443 | |||
444 | case WDIOC_GETBOOTSTATUS: | ||
445 | return put_user(0, uarg.i); | ||
446 | |||
447 | case WDIOC_KEEPALIVE: | ||
448 | wb_smsc_wdt_reset_timer(); | ||
449 | return 0; | ||
450 | |||
451 | case WDIOC_SETTIMEOUT: | ||
452 | if (get_user(new_timeout, uarg.i)) | ||
453 | return -EFAULT; | ||
454 | |||
455 | // the API states this is given in secs | ||
456 | if (unit == UNIT_MINUTE) | ||
457 | new_timeout /= 60; | ||
458 | |||
459 | if (new_timeout < 0 || new_timeout > MAX_TIMEOUT) | ||
460 | return -EINVAL; | ||
461 | |||
462 | timeout = new_timeout; | ||
463 | wb_smsc_wdt_set_timeout(timeout); | ||
464 | |||
465 | // fall through and return the new timeout... | ||
466 | |||
467 | case WDIOC_GETTIMEOUT: | ||
468 | |||
469 | new_timeout = timeout; | ||
470 | |||
471 | if (unit == UNIT_MINUTE) | ||
472 | new_timeout *= 60; | ||
473 | |||
474 | return put_user(new_timeout, uarg.i); | ||
475 | |||
476 | case WDIOC_SETOPTIONS: | ||
477 | { | ||
478 | int options, retval = -EINVAL; | ||
479 | |||
480 | if (get_user(options, uarg.i)) | ||
481 | return -EFAULT; | ||
482 | |||
483 | if (options & WDIOS_DISABLECARD) { | ||
484 | wb_smsc_wdt_disable(); | ||
485 | retval = 0; | ||
486 | } | ||
487 | |||
488 | if (options & WDIOS_ENABLECARD) { | ||
489 | wb_smsc_wdt_enable(); | ||
490 | retval = 0; | ||
491 | } | ||
492 | |||
493 | return retval; | ||
494 | } | ||
495 | } | ||
496 | } | ||
497 | |||
498 | /* -- Notifier funtions -----------------------------------------*/ | ||
499 | |||
500 | static int wb_smsc_wdt_notify_sys(struct notifier_block *this, unsigned long code, void *unused) | ||
501 | { | ||
502 | if (code == SYS_DOWN || code == SYS_HALT) | ||
503 | { | ||
504 | // set timeout to 0, to avoid possible race-condition | ||
505 | timeout = 0; | ||
506 | wb_smsc_wdt_disable(); | ||
507 | } | ||
508 | return NOTIFY_DONE; | ||
509 | } | ||
510 | |||
511 | /* -- Module's structures ---------------------------------------*/ | ||
512 | |||
513 | static struct file_operations wb_smsc_wdt_fops = | ||
514 | { | ||
515 | .owner = THIS_MODULE, | ||
516 | .llseek = no_llseek, | ||
517 | .write = wb_smsc_wdt_write, | ||
518 | .ioctl = wb_smsc_wdt_ioctl, | ||
519 | .open = wb_smsc_wdt_open, | ||
520 | .release = wb_smsc_wdt_release, | ||
521 | }; | ||
522 | |||
523 | static struct notifier_block wb_smsc_wdt_notifier = | ||
524 | { | ||
525 | .notifier_call = wb_smsc_wdt_notify_sys, | ||
526 | }; | ||
527 | |||
528 | static struct miscdevice wb_smsc_wdt_miscdev = | ||
529 | { | ||
530 | .minor = WATCHDOG_MINOR, | ||
531 | .name = "watchdog", | ||
532 | .fops = &wb_smsc_wdt_fops, | ||
533 | }; | ||
534 | |||
535 | /* -- Module init functions -------------------------------------*/ | ||
536 | |||
537 | /* module's "constructor" */ | ||
538 | |||
539 | static int __init wb_smsc_wdt_init(void) | ||
540 | { | ||
541 | int ret; | ||
542 | |||
543 | spin_lock_init(&io_lock); | ||
544 | |||
545 | printk("SMsC 37B787 watchdog component driver " VERSION " initialising...\n"); | ||
546 | |||
547 | if (!request_region(IOPORT, IOPORT_SIZE, "SMsC 37B787 watchdog")) { | ||
548 | printk(KERN_ERR MODNAME "Unable to register IO port %#x\n", IOPORT); | ||
549 | ret = -EBUSY; | ||
550 | goto out_pnp; | ||
551 | } | ||
552 | |||
553 | // set new maximum, if it's too big | ||
554 | if (timeout > MAX_TIMEOUT) | ||
555 | timeout = MAX_TIMEOUT; | ||
556 | |||
557 | // init the watchdog timer | ||
558 | wb_smsc_wdt_initialize(); | ||
559 | |||
560 | ret = register_reboot_notifier(&wb_smsc_wdt_notifier); | ||
561 | if (ret) { | ||
562 | printk(KERN_ERR MODNAME "Unable to register reboot notifier err = %d\n", ret); | ||
563 | goto out_io; | ||
564 | } | ||
565 | |||
566 | ret = misc_register(&wb_smsc_wdt_miscdev); | ||
567 | if (ret) { | ||
568 | printk(KERN_ERR MODNAME "Unable to register miscdev on minor %d\n", WATCHDOG_MINOR); | ||
569 | goto out_rbt; | ||
570 | } | ||
571 | |||
572 | // output info | ||
573 | printk(KERN_INFO MODNAME "Timeout set to %d %s.\n", timeout, (unit == UNIT_SECOND) ? "second(s)" : "minute(s)"); | ||
574 | printk(KERN_INFO MODNAME "Watchdog initialized and sleeping (nowayout=%d)...\n", nowayout); | ||
575 | |||
576 | // ret = 0 | ||
577 | |||
578 | out_clean: | ||
579 | return ret; | ||
580 | |||
581 | out_rbt: | ||
582 | unregister_reboot_notifier(&wb_smsc_wdt_notifier); | ||
583 | |||
584 | out_io: | ||
585 | release_region(IOPORT, IOPORT_SIZE); | ||
586 | |||
587 | out_pnp: | ||
588 | goto out_clean; | ||
589 | } | ||
590 | |||
591 | /* module's "destructor" */ | ||
592 | |||
593 | static void __exit wb_smsc_wdt_exit(void) | ||
594 | { | ||
595 | /* Stop the timer before we leave */ | ||
596 | if (!nowayout) | ||
597 | { | ||
598 | wb_smsc_wdt_shutdown(); | ||
599 | printk(KERN_INFO MODNAME "Watchdog disabled.\n"); | ||
600 | } | ||
601 | |||
602 | misc_deregister(&wb_smsc_wdt_miscdev); | ||
603 | unregister_reboot_notifier(&wb_smsc_wdt_notifier); | ||
604 | release_region(IOPORT, IOPORT_SIZE); | ||
605 | |||
606 | printk("SMsC 37B787 watchdog component driver removed.\n"); | ||
607 | } | ||
608 | |||
609 | module_init(wb_smsc_wdt_init); | ||
610 | module_exit(wb_smsc_wdt_exit); | ||
611 | |||
612 | MODULE_AUTHOR("Sven Anders <anders@anduras.de>"); | ||
613 | MODULE_DESCRIPTION("Driver for SMsC 37B787 watchdog component (Version " VERSION ")"); | ||
614 | MODULE_LICENSE("GPL"); | ||
615 | |||
616 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); | ||
617 | |||
618 | #ifdef SMSC_SUPPORT_MINUTES | ||
619 | module_param(unit, int, 0); | ||
620 | MODULE_PARM_DESC(unit, "set unit to use, 0=seconds or 1=minutes, default is 0"); | ||
621 | #endif | ||
622 | |||
623 | module_param(timeout, int, 0); | ||
624 | MODULE_PARM_DESC(timeout, "range is 1-255 units, default is 60"); | ||
625 | |||
626 | module_param(nowayout, int, 0); | ||
627 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); | ||
diff --git a/drivers/char/watchdog/w83627hf_wdt.c b/drivers/char/watchdog/w83627hf_wdt.c index b4adc527e687..07d4bff27226 100644 --- a/drivers/char/watchdog/w83627hf_wdt.c +++ b/drivers/char/watchdog/w83627hf_wdt.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/notifier.h> | 33 | #include <linux/notifier.h> |
34 | #include <linux/reboot.h> | 34 | #include <linux/reboot.h> |
35 | #include <linux/init.h> | 35 | #include <linux/init.h> |
36 | #include <linux/spinlock.h> | ||
36 | 37 | ||
37 | #include <asm/io.h> | 38 | #include <asm/io.h> |
38 | #include <asm/uaccess.h> | 39 | #include <asm/uaccess.h> |
@@ -44,6 +45,7 @@ | |||
44 | 45 | ||
45 | static unsigned long wdt_is_open; | 46 | static unsigned long wdt_is_open; |
46 | static char expect_close; | 47 | static char expect_close; |
48 | static spinlock_t io_lock; | ||
47 | 49 | ||
48 | /* You must set this - there is no sane way to probe for this board. */ | 50 | /* You must set this - there is no sane way to probe for this board. */ |
49 | static int wdt_io = 0x2E; | 51 | static int wdt_io = 0x2E; |
@@ -110,12 +112,16 @@ w83627hf_init(void) | |||
110 | static void | 112 | static void |
111 | wdt_ctrl(int timeout) | 113 | wdt_ctrl(int timeout) |
112 | { | 114 | { |
115 | spin_lock(&io_lock); | ||
116 | |||
113 | w83627hf_select_wd_register(); | 117 | w83627hf_select_wd_register(); |
114 | 118 | ||
115 | outb_p(0xF6, WDT_EFER); /* Select CRF6 */ | 119 | outb_p(0xF6, WDT_EFER); /* Select CRF6 */ |
116 | outb_p(timeout, WDT_EFDR); /* Write Timeout counter to CRF6 */ | 120 | outb_p(timeout, WDT_EFDR); /* Write Timeout counter to CRF6 */ |
117 | 121 | ||
118 | w83627hf_unselect_wd_register(); | 122 | w83627hf_unselect_wd_register(); |
123 | |||
124 | spin_unlock(&io_lock); | ||
119 | } | 125 | } |
120 | 126 | ||
121 | static int | 127 | static int |
@@ -303,6 +309,8 @@ wdt_init(void) | |||
303 | { | 309 | { |
304 | int ret; | 310 | int ret; |
305 | 311 | ||
312 | spin_lock_init(&io_lock); | ||
313 | |||
306 | printk(KERN_INFO "WDT driver for the Winbond(TM) W83627HF Super I/O chip initialising.\n"); | 314 | printk(KERN_INFO "WDT driver for the Winbond(TM) W83627HF Super I/O chip initialising.\n"); |
307 | 315 | ||
308 | if (wdt_set_heartbeat(timeout)) { | 316 | if (wdt_set_heartbeat(timeout)) { |
diff --git a/drivers/char/watchdog/w83697hf_wdt.c b/drivers/char/watchdog/w83697hf_wdt.c new file mode 100644 index 000000000000..7768b55487c8 --- /dev/null +++ b/drivers/char/watchdog/w83697hf_wdt.c | |||
@@ -0,0 +1,450 @@ | |||
1 | /* | ||
2 | * w83697hf/hg WDT driver | ||
3 | * | ||
4 | * (c) Copyright 2006 Samuel Tardieu <sam@rfc1149.net> | ||
5 | * (c) Copyright 2006 Marcus Junker <junker@anduras.de> | ||
6 | * | ||
7 | * Based on w83627hf_wdt.c which is based on advantechwdt.c | ||
8 | * which is based on wdt.c. | ||
9 | * Original copyright messages: | ||
10 | * | ||
11 | * (c) Copyright 2003 Pádraig Brady <P@draigBrady.com> | ||
12 | * | ||
13 | * (c) Copyright 2000-2001 Marek Michalkiewicz <marekm@linux.org.pl> | ||
14 | * | ||
15 | * (c) Copyright 1996 Alan Cox <alan@redhat.com>, All Rights Reserved. | ||
16 | * http://www.redhat.com | ||
17 | * | ||
18 | * This program is free software; you can redistribute it and/or | ||
19 | * modify it under the terms of the GNU General Public License | ||
20 | * as published by the Free Software Foundation; either version | ||
21 | * 2 of the License, or (at your option) any later version. | ||
22 | * | ||
23 | * Neither Marcus Junker nor ANDURAS AG admit liability nor provide | ||
24 | * warranty for any of this software. This material is provided | ||
25 | * "AS-IS" and at no charge. | ||
26 | */ | ||
27 | |||
28 | #include <linux/module.h> | ||
29 | #include <linux/moduleparam.h> | ||
30 | #include <linux/types.h> | ||
31 | #include <linux/miscdevice.h> | ||
32 | #include <linux/watchdog.h> | ||
33 | #include <linux/fs.h> | ||
34 | #include <linux/ioport.h> | ||
35 | #include <linux/notifier.h> | ||
36 | #include <linux/reboot.h> | ||
37 | #include <linux/init.h> | ||
38 | #include <linux/spinlock.h> | ||
39 | |||
40 | #include <asm/io.h> | ||
41 | #include <asm/uaccess.h> | ||
42 | #include <asm/system.h> | ||
43 | |||
44 | #define WATCHDOG_NAME "w83697hf/hg WDT" | ||
45 | #define PFX WATCHDOG_NAME ": " | ||
46 | #define WATCHDOG_TIMEOUT 60 /* 60 sec default timeout */ | ||
47 | |||
48 | static unsigned long wdt_is_open; | ||
49 | static char expect_close; | ||
50 | static spinlock_t io_lock; | ||
51 | |||
52 | /* You must set this - there is no sane way to probe for this board. */ | ||
53 | static int wdt_io = 0x2e; | ||
54 | module_param(wdt_io, int, 0); | ||
55 | MODULE_PARM_DESC(wdt_io, "w83697hf/hg WDT io port (default 0x2e, 0 = autodetect)"); | ||
56 | |||
57 | static int timeout = WATCHDOG_TIMEOUT; /* in seconds */ | ||
58 | module_param(timeout, int, 0); | ||
59 | MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=255, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) "."); | ||
60 | |||
61 | static int nowayout = WATCHDOG_NOWAYOUT; | ||
62 | module_param(nowayout, int, 0); | ||
63 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); | ||
64 | |||
65 | /* | ||
66 | * Kernel methods. | ||
67 | */ | ||
68 | |||
69 | #define W83697HF_EFER (wdt_io+0) /* Extended Function Enable Register */ | ||
70 | #define W83697HF_EFIR (wdt_io+0) /* Extended Function Index Register (same as EFER) */ | ||
71 | #define W83697HF_EFDR (wdt_io+1) /* Extended Function Data Register */ | ||
72 | |||
73 | static inline void | ||
74 | w83697hf_unlock(void) | ||
75 | { | ||
76 | outb_p(0x87, W83697HF_EFER); /* Enter extended function mode */ | ||
77 | outb_p(0x87, W83697HF_EFER); /* Again according to manual */ | ||
78 | } | ||
79 | |||
80 | static inline void | ||
81 | w83697hf_lock(void) | ||
82 | { | ||
83 | outb_p(0xAA, W83697HF_EFER); /* Leave extended function mode */ | ||
84 | } | ||
85 | |||
86 | /* | ||
87 | * The three functions w83697hf_get_reg(), w83697hf_set_reg() and | ||
88 | * w83697hf_write_timeout() must be called with the device unlocked. | ||
89 | */ | ||
90 | |||
91 | static unsigned char | ||
92 | w83697hf_get_reg(unsigned char reg) | ||
93 | { | ||
94 | outb_p(reg, W83697HF_EFIR); | ||
95 | return inb_p(W83697HF_EFDR); | ||
96 | } | ||
97 | |||
98 | static void | ||
99 | w83697hf_set_reg(unsigned char reg, unsigned char data) | ||
100 | { | ||
101 | outb_p(reg, W83697HF_EFIR); | ||
102 | outb_p(data, W83697HF_EFDR); | ||
103 | } | ||
104 | |||
105 | static void | ||
106 | w83697hf_write_timeout(int timeout) | ||
107 | { | ||
108 | w83697hf_set_reg(0xF4, timeout); /* Write Timeout counter to CRF4 */ | ||
109 | } | ||
110 | |||
111 | static void | ||
112 | w83697hf_select_wdt(void) | ||
113 | { | ||
114 | w83697hf_unlock(); | ||
115 | w83697hf_set_reg(0x07, 0x08); /* Switch to logic device 8 (GPIO2) */ | ||
116 | } | ||
117 | |||
118 | static inline void | ||
119 | w83697hf_deselect_wdt(void) | ||
120 | { | ||
121 | w83697hf_lock(); | ||
122 | } | ||
123 | |||
124 | static void | ||
125 | w83697hf_init(void) | ||
126 | { | ||
127 | unsigned char bbuf; | ||
128 | |||
129 | w83697hf_select_wdt(); | ||
130 | |||
131 | bbuf = w83697hf_get_reg(0x29); | ||
132 | bbuf &= ~0x60; | ||
133 | bbuf |= 0x20; | ||
134 | w83697hf_set_reg(0x29, bbuf); /* Set pin 119 to WDTO# mode (= CR29, WDT0) */ | ||
135 | |||
136 | bbuf = w83697hf_get_reg(0xF3); | ||
137 | bbuf &= ~0x04; | ||
138 | w83697hf_set_reg(0xF3, bbuf); /* Count mode is seconds */ | ||
139 | |||
140 | w83697hf_deselect_wdt(); | ||
141 | } | ||
142 | |||
143 | static int | ||
144 | wdt_ping(void) | ||
145 | { | ||
146 | spin_lock(&io_lock); | ||
147 | w83697hf_select_wdt(); | ||
148 | |||
149 | w83697hf_write_timeout(timeout); | ||
150 | |||
151 | w83697hf_deselect_wdt(); | ||
152 | spin_unlock(&io_lock); | ||
153 | return 0; | ||
154 | } | ||
155 | |||
156 | static int | ||
157 | wdt_enable(void) | ||
158 | { | ||
159 | spin_lock(&io_lock); | ||
160 | w83697hf_select_wdt(); | ||
161 | |||
162 | w83697hf_write_timeout(timeout); | ||
163 | w83697hf_set_reg(0x30, 1); /* Enable timer */ | ||
164 | |||
165 | w83697hf_deselect_wdt(); | ||
166 | spin_unlock(&io_lock); | ||
167 | return 0; | ||
168 | } | ||
169 | |||
170 | static int | ||
171 | wdt_disable(void) | ||
172 | { | ||
173 | spin_lock(&io_lock); | ||
174 | w83697hf_select_wdt(); | ||
175 | |||
176 | w83697hf_set_reg(0x30, 0); /* Disable timer */ | ||
177 | w83697hf_write_timeout(0); | ||
178 | |||
179 | w83697hf_deselect_wdt(); | ||
180 | spin_unlock(&io_lock); | ||
181 | return 0; | ||
182 | } | ||
183 | |||
184 | static int | ||
185 | wdt_set_heartbeat(int t) | ||
186 | { | ||
187 | if ((t < 1) || (t > 255)) | ||
188 | return -EINVAL; | ||
189 | |||
190 | timeout = t; | ||
191 | return 0; | ||
192 | } | ||
193 | |||
194 | static ssize_t | ||
195 | wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) | ||
196 | { | ||
197 | if (count) { | ||
198 | if (!nowayout) { | ||
199 | size_t i; | ||
200 | |||
201 | expect_close = 0; | ||
202 | |||
203 | for (i = 0; i != count; i++) { | ||
204 | char c; | ||
205 | if (get_user(c, buf+i)) | ||
206 | return -EFAULT; | ||
207 | if (c == 'V') | ||
208 | expect_close = 42; | ||
209 | } | ||
210 | } | ||
211 | wdt_ping(); | ||
212 | } | ||
213 | return count; | ||
214 | } | ||
215 | |||
216 | static int | ||
217 | wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | ||
218 | unsigned long arg) | ||
219 | { | ||
220 | void __user *argp = (void __user *)arg; | ||
221 | int __user *p = argp; | ||
222 | int new_timeout; | ||
223 | static struct watchdog_info ident = { | ||
224 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, | ||
225 | .firmware_version = 1, | ||
226 | .identity = "W83697HF WDT", | ||
227 | }; | ||
228 | |||
229 | switch (cmd) { | ||
230 | case WDIOC_GETSUPPORT: | ||
231 | if (copy_to_user(argp, &ident, sizeof(ident))) | ||
232 | return -EFAULT; | ||
233 | break; | ||
234 | |||
235 | case WDIOC_GETSTATUS: | ||
236 | case WDIOC_GETBOOTSTATUS: | ||
237 | return put_user(0, p); | ||
238 | |||
239 | case WDIOC_KEEPALIVE: | ||
240 | wdt_ping(); | ||
241 | break; | ||
242 | |||
243 | case WDIOC_SETTIMEOUT: | ||
244 | if (get_user(new_timeout, p)) | ||
245 | return -EFAULT; | ||
246 | if (wdt_set_heartbeat(new_timeout)) | ||
247 | return -EINVAL; | ||
248 | wdt_ping(); | ||
249 | /* Fall */ | ||
250 | |||
251 | case WDIOC_GETTIMEOUT: | ||
252 | return put_user(timeout, p); | ||
253 | |||
254 | case WDIOC_SETOPTIONS: | ||
255 | { | ||
256 | int options, retval = -EINVAL; | ||
257 | |||
258 | if (get_user(options, p)) | ||
259 | return -EFAULT; | ||
260 | |||
261 | if (options & WDIOS_DISABLECARD) { | ||
262 | wdt_disable(); | ||
263 | retval = 0; | ||
264 | } | ||
265 | |||
266 | if (options & WDIOS_ENABLECARD) { | ||
267 | wdt_enable(); | ||
268 | retval = 0; | ||
269 | } | ||
270 | |||
271 | return retval; | ||
272 | } | ||
273 | |||
274 | default: | ||
275 | return -ENOTTY; | ||
276 | } | ||
277 | return 0; | ||
278 | } | ||
279 | |||
280 | static int | ||
281 | wdt_open(struct inode *inode, struct file *file) | ||
282 | { | ||
283 | if (test_and_set_bit(0, &wdt_is_open)) | ||
284 | return -EBUSY; | ||
285 | /* | ||
286 | * Activate | ||
287 | */ | ||
288 | |||
289 | wdt_enable(); | ||
290 | return nonseekable_open(inode, file); | ||
291 | } | ||
292 | |||
293 | static int | ||
294 | wdt_close(struct inode *inode, struct file *file) | ||
295 | { | ||
296 | if (expect_close == 42) { | ||
297 | wdt_disable(); | ||
298 | } else { | ||
299 | printk (KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); | ||
300 | wdt_ping(); | ||
301 | } | ||
302 | expect_close = 0; | ||
303 | clear_bit(0, &wdt_is_open); | ||
304 | return 0; | ||
305 | } | ||
306 | |||
307 | /* | ||
308 | * Notifier for system down | ||
309 | */ | ||
310 | |||
311 | static int | ||
312 | wdt_notify_sys(struct notifier_block *this, unsigned long code, | ||
313 | void *unused) | ||
314 | { | ||
315 | if (code == SYS_DOWN || code == SYS_HALT) { | ||
316 | /* Turn the WDT off */ | ||
317 | wdt_disable(); | ||
318 | } | ||
319 | return NOTIFY_DONE; | ||
320 | } | ||
321 | |||
322 | /* | ||
323 | * Kernel Interfaces | ||
324 | */ | ||
325 | |||
326 | static struct file_operations wdt_fops = { | ||
327 | .owner = THIS_MODULE, | ||
328 | .llseek = no_llseek, | ||
329 | .write = wdt_write, | ||
330 | .ioctl = wdt_ioctl, | ||
331 | .open = wdt_open, | ||
332 | .release = wdt_close, | ||
333 | }; | ||
334 | |||
335 | static struct miscdevice wdt_miscdev = { | ||
336 | .minor = WATCHDOG_MINOR, | ||
337 | .name = "watchdog", | ||
338 | .fops = &wdt_fops, | ||
339 | }; | ||
340 | |||
341 | /* | ||
342 | * The WDT needs to learn about soft shutdowns in order to | ||
343 | * turn the timebomb registers off. | ||
344 | */ | ||
345 | |||
346 | static struct notifier_block wdt_notifier = { | ||
347 | .notifier_call = wdt_notify_sys, | ||
348 | }; | ||
349 | |||
350 | static int | ||
351 | w83697hf_check_wdt(void) | ||
352 | { | ||
353 | if (!request_region(wdt_io, 2, WATCHDOG_NAME)) { | ||
354 | printk (KERN_ERR PFX "I/O address 0x%x already in use\n", wdt_io); | ||
355 | return -EIO; | ||
356 | } | ||
357 | |||
358 | printk (KERN_DEBUG PFX "Looking for watchdog at address 0x%x\n", wdt_io); | ||
359 | w83697hf_unlock(); | ||
360 | if (w83697hf_get_reg(0x20) == 0x60) { | ||
361 | printk (KERN_INFO PFX "watchdog found at address 0x%x\n", wdt_io); | ||
362 | w83697hf_lock(); | ||
363 | return 0; | ||
364 | } | ||
365 | w83697hf_lock(); /* Reprotect in case it was a compatible device */ | ||
366 | |||
367 | printk (KERN_INFO PFX "watchdog not found at address 0x%x\n", wdt_io); | ||
368 | release_region(wdt_io, 2); | ||
369 | return -EIO; | ||
370 | } | ||
371 | |||
372 | static int w83697hf_ioports[] = { 0x2e, 0x4e, 0x00 }; | ||
373 | |||
374 | static int __init | ||
375 | wdt_init(void) | ||
376 | { | ||
377 | int ret, i, found = 0; | ||
378 | |||
379 | spin_lock_init(&io_lock); | ||
380 | |||
381 | printk (KERN_INFO PFX "WDT driver for W83697HF/HG initializing\n"); | ||
382 | |||
383 | if (wdt_io == 0) { | ||
384 | /* we will autodetect the W83697HF/HG watchdog */ | ||
385 | for (i = 0; ((!found) && (w83697hf_ioports[i] != 0)); i++) { | ||
386 | wdt_io = w83697hf_ioports[i]; | ||
387 | if (!w83697hf_check_wdt()) | ||
388 | found++; | ||
389 | } | ||
390 | } else { | ||
391 | if (!w83697hf_check_wdt()) | ||
392 | found++; | ||
393 | } | ||
394 | |||
395 | if (!found) { | ||
396 | printk (KERN_ERR PFX "No W83697HF/HG could be found\n"); | ||
397 | ret = -EIO; | ||
398 | goto out; | ||
399 | } | ||
400 | |||
401 | w83697hf_init(); | ||
402 | wdt_disable(); /* Disable watchdog until first use */ | ||
403 | |||
404 | if (wdt_set_heartbeat(timeout)) { | ||
405 | wdt_set_heartbeat(WATCHDOG_TIMEOUT); | ||
406 | printk (KERN_INFO PFX "timeout value must be 1<=timeout<=255, using %d\n", | ||
407 | WATCHDOG_TIMEOUT); | ||
408 | } | ||
409 | |||
410 | ret = register_reboot_notifier(&wdt_notifier); | ||
411 | if (ret != 0) { | ||
412 | printk (KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", | ||
413 | ret); | ||
414 | goto unreg_regions; | ||
415 | } | ||
416 | |||
417 | ret = misc_register(&wdt_miscdev); | ||
418 | if (ret != 0) { | ||
419 | printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", | ||
420 | WATCHDOG_MINOR, ret); | ||
421 | goto unreg_reboot; | ||
422 | } | ||
423 | |||
424 | printk (KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d)\n", | ||
425 | timeout, nowayout); | ||
426 | |||
427 | out: | ||
428 | return ret; | ||
429 | unreg_reboot: | ||
430 | unregister_reboot_notifier(&wdt_notifier); | ||
431 | unreg_regions: | ||
432 | release_region(wdt_io, 2); | ||
433 | goto out; | ||
434 | } | ||
435 | |||
436 | static void __exit | ||
437 | wdt_exit(void) | ||
438 | { | ||
439 | misc_deregister(&wdt_miscdev); | ||
440 | unregister_reboot_notifier(&wdt_notifier); | ||
441 | release_region(wdt_io, 2); | ||
442 | } | ||
443 | |||
444 | module_init(wdt_init); | ||
445 | module_exit(wdt_exit); | ||
446 | |||
447 | MODULE_LICENSE("GPL"); | ||
448 | MODULE_AUTHOR("Marcus Junker <junker@anduras.de>, Samuel Tardieu <sam@rfc1149.net>"); | ||
449 | MODULE_DESCRIPTION("w83697hf/hg WDT driver"); | ||
450 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); | ||
diff --git a/drivers/clocksource/acpi_pm.c b/drivers/clocksource/acpi_pm.c index 7ad3be8c0f49..7fcb77a9d011 100644 --- a/drivers/clocksource/acpi_pm.c +++ b/drivers/clocksource/acpi_pm.c | |||
@@ -54,8 +54,8 @@ static cycle_t acpi_pm_read_verified(void) | |||
54 | v1 = read_pmtmr(); | 54 | v1 = read_pmtmr(); |
55 | v2 = read_pmtmr(); | 55 | v2 = read_pmtmr(); |
56 | v3 = read_pmtmr(); | 56 | v3 = read_pmtmr(); |
57 | } while ((v1 > v2 && v1 < v3) || (v2 > v3 && v2 < v1) | 57 | } while (unlikely((v1 > v2 && v1 < v3) || (v2 > v3 && v2 < v1) |
58 | || (v3 > v1 && v3 < v2)); | 58 | || (v3 > v1 && v3 < v2))); |
59 | 59 | ||
60 | return (cycle_t)v2; | 60 | return (cycle_t)v2; |
61 | } | 61 | } |
@@ -138,6 +138,8 @@ static void __devinit acpi_pm_check_graylist(struct pci_dev *dev) | |||
138 | } | 138 | } |
139 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, | 139 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, |
140 | acpi_pm_check_graylist); | 140 | acpi_pm_check_graylist); |
141 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_LE, | ||
142 | acpi_pm_check_graylist); | ||
141 | #endif | 143 | #endif |
142 | 144 | ||
143 | 145 | ||
diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig index 2cc71b66231e..491779af8d55 100644 --- a/drivers/cpufreq/Kconfig +++ b/drivers/cpufreq/Kconfig | |||
@@ -107,6 +107,7 @@ config CPU_FREQ_GOV_USERSPACE | |||
107 | 107 | ||
108 | config CPU_FREQ_GOV_ONDEMAND | 108 | config CPU_FREQ_GOV_ONDEMAND |
109 | tristate "'ondemand' cpufreq policy governor" | 109 | tristate "'ondemand' cpufreq policy governor" |
110 | select CPU_FREQ_TABLE | ||
110 | help | 111 | help |
111 | 'ondemand' - This driver adds a dynamic cpufreq policy governor. | 112 | 'ondemand' - This driver adds a dynamic cpufreq policy governor. |
112 | The governor does a periodic polling and | 113 | The governor does a periodic polling and |
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 86e69b7f9122..dd0c2623e27b 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -59,7 +59,7 @@ static int __init init_cpufreq_transition_notifier_list(void) | |||
59 | srcu_init_notifier_head(&cpufreq_transition_notifier_list); | 59 | srcu_init_notifier_head(&cpufreq_transition_notifier_list); |
60 | return 0; | 60 | return 0; |
61 | } | 61 | } |
62 | core_initcall(init_cpufreq_transition_notifier_list); | 62 | pure_initcall(init_cpufreq_transition_notifier_list); |
63 | 63 | ||
64 | static LIST_HEAD(cpufreq_governor_list); | 64 | static LIST_HEAD(cpufreq_governor_list); |
65 | static DEFINE_MUTEX (cpufreq_governor_mutex); | 65 | static DEFINE_MUTEX (cpufreq_governor_mutex); |
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index 4bde30bb3be7..75e9e38330ff 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c | |||
@@ -230,34 +230,43 @@ static struct kobj_type ktype_memctrl = { | |||
230 | */ | 230 | */ |
231 | static int edac_sysfs_memctrl_setup(void) | 231 | static int edac_sysfs_memctrl_setup(void) |
232 | { | 232 | { |
233 | int err=0; | 233 | int err = 0; |
234 | 234 | ||
235 | debugf1("%s()\n", __func__); | 235 | debugf1("%s()\n", __func__); |
236 | 236 | ||
237 | /* create the /sys/devices/system/edac directory */ | 237 | /* create the /sys/devices/system/edac directory */ |
238 | err = sysdev_class_register(&edac_class); | 238 | err = sysdev_class_register(&edac_class); |
239 | 239 | ||
240 | if (!err) { | 240 | if (err) { |
241 | /* Init the MC's kobject */ | 241 | debugf1("%s() error=%d\n", __func__, err); |
242 | memset(&edac_memctrl_kobj, 0, sizeof (edac_memctrl_kobj)); | 242 | return err; |
243 | edac_memctrl_kobj.parent = &edac_class.kset.kobj; | 243 | } |
244 | edac_memctrl_kobj.ktype = &ktype_memctrl; | ||
245 | 244 | ||
246 | /* generate sysfs "..../edac/mc" */ | 245 | /* Init the MC's kobject */ |
247 | err = kobject_set_name(&edac_memctrl_kobj,"mc"); | 246 | memset(&edac_memctrl_kobj, 0, sizeof (edac_memctrl_kobj)); |
247 | edac_memctrl_kobj.parent = &edac_class.kset.kobj; | ||
248 | edac_memctrl_kobj.ktype = &ktype_memctrl; | ||
248 | 249 | ||
249 | if (!err) { | 250 | /* generate sysfs "..../edac/mc" */ |
250 | /* FIXME: maybe new sysdev_create_subdir() */ | 251 | err = kobject_set_name(&edac_memctrl_kobj,"mc"); |
251 | err = kobject_register(&edac_memctrl_kobj); | ||
252 | 252 | ||
253 | if (err) | 253 | if (err) |
254 | debugf1("Failed to register '.../edac/mc'\n"); | 254 | goto fail; |
255 | else | 255 | |
256 | debugf1("Registered '.../edac/mc' kobject\n"); | 256 | /* FIXME: maybe new sysdev_create_subdir() */ |
257 | } | 257 | err = kobject_register(&edac_memctrl_kobj); |
258 | } else | 258 | |
259 | debugf1("%s() error=%d\n", __func__, err); | 259 | if (err) { |
260 | debugf1("Failed to register '.../edac/mc'\n"); | ||
261 | goto fail; | ||
262 | } | ||
260 | 263 | ||
264 | debugf1("Registered '.../edac/mc' kobject\n"); | ||
265 | |||
266 | return 0; | ||
267 | |||
268 | fail: | ||
269 | sysdev_class_unregister(&edac_class); | ||
261 | return err; | 270 | return err; |
262 | } | 271 | } |
263 | 272 | ||
diff --git a/drivers/eisa/eisa-bus.c b/drivers/eisa/eisa-bus.c index 3a365e159d89..d944647c82c2 100644 --- a/drivers/eisa/eisa-bus.c +++ b/drivers/eisa/eisa-bus.c | |||
@@ -226,14 +226,26 @@ static int __init eisa_init_device (struct eisa_root_device *root, | |||
226 | 226 | ||
227 | static int __init eisa_register_device (struct eisa_device *edev) | 227 | static int __init eisa_register_device (struct eisa_device *edev) |
228 | { | 228 | { |
229 | if (device_register (&edev->dev)) | 229 | int rc = device_register (&edev->dev); |
230 | return -1; | 230 | if (rc) |
231 | return rc; | ||
231 | 232 | ||
232 | device_create_file (&edev->dev, &dev_attr_signature); | 233 | rc = device_create_file (&edev->dev, &dev_attr_signature); |
233 | device_create_file (&edev->dev, &dev_attr_enabled); | 234 | if (rc) goto err_devreg; |
234 | device_create_file (&edev->dev, &dev_attr_modalias); | 235 | rc = device_create_file (&edev->dev, &dev_attr_enabled); |
236 | if (rc) goto err_sig; | ||
237 | rc = device_create_file (&edev->dev, &dev_attr_modalias); | ||
238 | if (rc) goto err_enab; | ||
235 | 239 | ||
236 | return 0; | 240 | return 0; |
241 | |||
242 | err_enab: | ||
243 | device_remove_file (&edev->dev, &dev_attr_enabled); | ||
244 | err_sig: | ||
245 | device_remove_file (&edev->dev, &dev_attr_signature); | ||
246 | err_devreg: | ||
247 | device_unregister(&edev->dev); | ||
248 | return rc; | ||
237 | } | 249 | } |
238 | 250 | ||
239 | static int __init eisa_request_resources (struct eisa_root_device *root, | 251 | static int __init eisa_request_resources (struct eisa_root_device *root, |
diff --git a/drivers/fc4/fc.c b/drivers/fc4/fc.c index 22d17474755f..ca4e67a022d0 100644 --- a/drivers/fc4/fc.c +++ b/drivers/fc4/fc.c | |||
@@ -70,9 +70,9 @@ | |||
70 | 70 | ||
71 | #define FCP_CMND(SCpnt) ((fcp_cmnd *)&(SCpnt->SCp)) | 71 | #define FCP_CMND(SCpnt) ((fcp_cmnd *)&(SCpnt->SCp)) |
72 | #define FC_SCMND(SCpnt) ((fc_channel *)(SCpnt->device->host->hostdata[0])) | 72 | #define FC_SCMND(SCpnt) ((fc_channel *)(SCpnt->device->host->hostdata[0])) |
73 | #define SC_FCMND(fcmnd) ((Scsi_Cmnd *)((long)fcmnd - (long)&(((Scsi_Cmnd *)0)->SCp))) | 73 | #define SC_FCMND(fcmnd) ((struct scsi_cmnd *)((long)fcmnd - (long)&(((struct scsi_cmnd *)0)->SCp))) |
74 | 74 | ||
75 | static int fcp_scsi_queue_it(fc_channel *, Scsi_Cmnd *, fcp_cmnd *, int); | 75 | static int fcp_scsi_queue_it(fc_channel *, struct scsi_cmnd *, fcp_cmnd *, int); |
76 | void fcp_queue_empty(fc_channel *); | 76 | void fcp_queue_empty(fc_channel *); |
77 | 77 | ||
78 | static void fcp_scsi_insert_queue (fc_channel *fc, fcp_cmnd *fcmd) | 78 | static void fcp_scsi_insert_queue (fc_channel *fc, fcp_cmnd *fcmd) |
@@ -378,14 +378,14 @@ void fcp_register(fc_channel *fc, u8 type, int unregister) | |||
378 | printk ("FC: %segistering unknown type %02x\n", unregister ? "Unr" : "R", type); | 378 | printk ("FC: %segistering unknown type %02x\n", unregister ? "Unr" : "R", type); |
379 | } | 379 | } |
380 | 380 | ||
381 | static void fcp_scsi_done(Scsi_Cmnd *SCpnt); | 381 | static void fcp_scsi_done(struct scsi_cmnd *SCpnt); |
382 | 382 | ||
383 | static inline void fcp_scsi_receive(fc_channel *fc, int token, int status, fc_hdr *fch) | 383 | static inline void fcp_scsi_receive(fc_channel *fc, int token, int status, fc_hdr *fch) |
384 | { | 384 | { |
385 | fcp_cmnd *fcmd; | 385 | fcp_cmnd *fcmd; |
386 | fcp_rsp *rsp; | 386 | fcp_rsp *rsp; |
387 | int host_status; | 387 | int host_status; |
388 | Scsi_Cmnd *SCpnt; | 388 | struct scsi_cmnd *SCpnt; |
389 | int sense_len; | 389 | int sense_len; |
390 | int rsp_status; | 390 | int rsp_status; |
391 | 391 | ||
@@ -757,13 +757,14 @@ void fcp_release(fc_channel *fcchain, int count) /* count must > 0 */ | |||
757 | } | 757 | } |
758 | 758 | ||
759 | 759 | ||
760 | static void fcp_scsi_done (Scsi_Cmnd *SCpnt) | 760 | static void fcp_scsi_done(struct scsi_cmnd *SCpnt) |
761 | { | 761 | { |
762 | if (FCP_CMND(SCpnt)->done) | 762 | if (FCP_CMND(SCpnt)->done) |
763 | FCP_CMND(SCpnt)->done(SCpnt); | 763 | FCP_CMND(SCpnt)->done(SCpnt); |
764 | } | 764 | } |
765 | 765 | ||
766 | static int fcp_scsi_queue_it(fc_channel *fc, Scsi_Cmnd *SCpnt, fcp_cmnd *fcmd, int prepare) | 766 | static int fcp_scsi_queue_it(fc_channel *fc, struct scsi_cmnd *SCpnt, |
767 | fcp_cmnd *fcmd, int prepare) | ||
767 | { | 768 | { |
768 | long i; | 769 | long i; |
769 | fcp_cmd *cmd; | 770 | fcp_cmd *cmd; |
@@ -837,7 +838,8 @@ static int fcp_scsi_queue_it(fc_channel *fc, Scsi_Cmnd *SCpnt, fcp_cmnd *fcmd, i | |||
837 | return 0; | 838 | return 0; |
838 | } | 839 | } |
839 | 840 | ||
840 | int fcp_scsi_queuecommand(Scsi_Cmnd *SCpnt, void (* done)(Scsi_Cmnd *)) | 841 | int fcp_scsi_queuecommand(struct scsi_cmnd *SCpnt, |
842 | void (* done)(struct scsi_cmnd *)) | ||
841 | { | 843 | { |
842 | fcp_cmnd *fcmd = FCP_CMND(SCpnt); | 844 | fcp_cmnd *fcmd = FCP_CMND(SCpnt); |
843 | fc_channel *fc = FC_SCMND(SCpnt); | 845 | fc_channel *fc = FC_SCMND(SCpnt); |
@@ -873,7 +875,7 @@ void fcp_queue_empty(fc_channel *fc) | |||
873 | } | 875 | } |
874 | } | 876 | } |
875 | 877 | ||
876 | int fcp_scsi_abort(Scsi_Cmnd *SCpnt) | 878 | int fcp_scsi_abort(struct scsi_cmnd *SCpnt) |
877 | { | 879 | { |
878 | /* Internal bookkeeping only. Lose 1 cmd_slots slot. */ | 880 | /* Internal bookkeeping only. Lose 1 cmd_slots slot. */ |
879 | fcp_cmnd *fcmd = FCP_CMND(SCpnt); | 881 | fcp_cmnd *fcmd = FCP_CMND(SCpnt); |
@@ -910,7 +912,7 @@ int fcp_scsi_abort(Scsi_Cmnd *SCpnt) | |||
910 | } | 912 | } |
911 | 913 | ||
912 | #if 0 | 914 | #if 0 |
913 | void fcp_scsi_reset_done(Scsi_Cmnd *SCpnt) | 915 | void fcp_scsi_reset_done(struct scsi_cmnd *SCpnt) |
914 | { | 916 | { |
915 | fc_channel *fc = FC_SCMND(SCpnt); | 917 | fc_channel *fc = FC_SCMND(SCpnt); |
916 | 918 | ||
@@ -921,7 +923,7 @@ void fcp_scsi_reset_done(Scsi_Cmnd *SCpnt) | |||
921 | 923 | ||
922 | #define FCP_RESET_TIMEOUT (2*HZ) | 924 | #define FCP_RESET_TIMEOUT (2*HZ) |
923 | 925 | ||
924 | int fcp_scsi_dev_reset(Scsi_Cmnd *SCpnt) | 926 | int fcp_scsi_dev_reset(struct scsi_cmnd *SCpnt) |
925 | { | 927 | { |
926 | #if 0 /* broken junk, but if davem wants to compile this driver, let him.. */ | 928 | #if 0 /* broken junk, but if davem wants to compile this driver, let him.. */ |
927 | unsigned long flags; | 929 | unsigned long flags; |
@@ -931,7 +933,7 @@ int fcp_scsi_dev_reset(Scsi_Cmnd *SCpnt) | |||
931 | DECLARE_MUTEX_LOCKED(sem); | 933 | DECLARE_MUTEX_LOCKED(sem); |
932 | 934 | ||
933 | if (!fc->rst_pkt) { | 935 | if (!fc->rst_pkt) { |
934 | fc->rst_pkt = (Scsi_Cmnd *) kmalloc(sizeof(SCpnt), GFP_KERNEL); | 936 | fc->rst_pkt = (struct scsi_cmnd *) kmalloc(sizeof(SCpnt), GFP_KERNEL); |
935 | if (!fc->rst_pkt) return FAILED; | 937 | if (!fc->rst_pkt) return FAILED; |
936 | 938 | ||
937 | fcmd = FCP_CMND(fc->rst_pkt); | 939 | fcmd = FCP_CMND(fc->rst_pkt); |
@@ -999,7 +1001,7 @@ int fcp_scsi_dev_reset(Scsi_Cmnd *SCpnt) | |||
999 | return SUCCESS; | 1001 | return SUCCESS; |
1000 | } | 1002 | } |
1001 | 1003 | ||
1002 | static int __fcp_scsi_host_reset(Scsi_Cmnd *SCpnt) | 1004 | static int __fcp_scsi_host_reset(struct scsi_cmnd *SCpnt) |
1003 | { | 1005 | { |
1004 | fc_channel *fc = FC_SCMND(SCpnt); | 1006 | fc_channel *fc = FC_SCMND(SCpnt); |
1005 | fcp_cmnd *fcmd = FCP_CMND(SCpnt); | 1007 | fcp_cmnd *fcmd = FCP_CMND(SCpnt); |
@@ -1020,7 +1022,7 @@ static int __fcp_scsi_host_reset(Scsi_Cmnd *SCpnt) | |||
1020 | else return FAILED; | 1022 | else return FAILED; |
1021 | } | 1023 | } |
1022 | 1024 | ||
1023 | int fcp_scsi_host_reset(Scsi_Cmnd *SCpnt) | 1025 | int fcp_scsi_host_reset(struct scsi_cmnd *SCpnt) |
1024 | { | 1026 | { |
1025 | unsigned long flags; | 1027 | unsigned long flags; |
1026 | int rc; | 1028 | int rc; |
diff --git a/drivers/fc4/fcp_impl.h b/drivers/fc4/fcp_impl.h index c397c84bef63..1ac61330592e 100644 --- a/drivers/fc4/fcp_impl.h +++ b/drivers/fc4/fcp_impl.h | |||
@@ -39,7 +39,7 @@ struct _fc_channel; | |||
39 | typedef struct fcp_cmnd { | 39 | typedef struct fcp_cmnd { |
40 | struct fcp_cmnd *next; | 40 | struct fcp_cmnd *next; |
41 | struct fcp_cmnd *prev; | 41 | struct fcp_cmnd *prev; |
42 | void (*done)(Scsi_Cmnd *); | 42 | void (*done)(struct scsi_cmnd *); |
43 | unsigned short proto; | 43 | unsigned short proto; |
44 | unsigned short token; | 44 | unsigned short token; |
45 | unsigned int did; | 45 | unsigned int did; |
@@ -94,14 +94,14 @@ typedef struct _fc_channel { | |||
94 | long *scsi_bitmap; | 94 | long *scsi_bitmap; |
95 | long scsi_bitmap_end; | 95 | long scsi_bitmap_end; |
96 | int scsi_free; | 96 | int scsi_free; |
97 | int (*encode_addr)(Scsi_Cmnd *, u16 *, struct _fc_channel *, fcp_cmnd *); | 97 | int (*encode_addr)(struct scsi_cmnd *, u16 *, struct _fc_channel *, fcp_cmnd *); |
98 | fcp_cmnd *scsi_que; | 98 | fcp_cmnd *scsi_que; |
99 | char scsi_name[4]; | 99 | char scsi_name[4]; |
100 | fcp_cmnd **cmd_slots; | 100 | fcp_cmnd **cmd_slots; |
101 | int channels; | 101 | int channels; |
102 | int targets; | 102 | int targets; |
103 | long *ages; | 103 | long *ages; |
104 | Scsi_Cmnd *rst_pkt; | 104 | struct scsi_cmnd *rst_pkt; |
105 | fcp_posmap *posmap; | 105 | fcp_posmap *posmap; |
106 | /* LOGIN stuff */ | 106 | /* LOGIN stuff */ |
107 | fcp_cmnd *login; | 107 | fcp_cmnd *login; |
@@ -155,9 +155,10 @@ int fc_do_prli(fc_channel *, unsigned char); | |||
155 | for_each_fc_channel(fc) \ | 155 | for_each_fc_channel(fc) \ |
156 | if (fc->state == FC_STATE_ONLINE) | 156 | if (fc->state == FC_STATE_ONLINE) |
157 | 157 | ||
158 | int fcp_scsi_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *)); | 158 | int fcp_scsi_queuecommand(struct scsi_cmnd *, |
159 | int fcp_scsi_abort(Scsi_Cmnd *); | 159 | void (* done) (struct scsi_cmnd *)); |
160 | int fcp_scsi_dev_reset(Scsi_Cmnd *); | 160 | int fcp_scsi_abort(struct scsi_cmnd *); |
161 | int fcp_scsi_host_reset(Scsi_Cmnd *); | 161 | int fcp_scsi_dev_reset(struct scsi_cmnd *); |
162 | int fcp_scsi_host_reset(struct scsi_cmnd *); | ||
162 | 163 | ||
163 | #endif /* !(_FCP_SCSI_H) */ | 164 | #endif /* !(_FCP_SCSI_H) */ |
diff --git a/drivers/firmware/dcdbas.c b/drivers/firmware/dcdbas.c index 8bcb58cd4ac0..1865b56fb141 100644 --- a/drivers/firmware/dcdbas.c +++ b/drivers/firmware/dcdbas.c | |||
@@ -8,7 +8,7 @@ | |||
8 | * | 8 | * |
9 | * See Documentation/dcdbas.txt for more information. | 9 | * See Documentation/dcdbas.txt for more information. |
10 | * | 10 | * |
11 | * Copyright (C) 1995-2005 Dell Inc. | 11 | * Copyright (C) 1995-2006 Dell Inc. |
12 | * | 12 | * |
13 | * This program is free software; you can redistribute it and/or modify | 13 | * This program is free software; you can redistribute it and/or modify |
14 | * it under the terms of the GNU General Public License v2.0 as published by | 14 | * it under the terms of the GNU General Public License v2.0 as published by |
@@ -40,7 +40,7 @@ | |||
40 | #include "dcdbas.h" | 40 | #include "dcdbas.h" |
41 | 41 | ||
42 | #define DRIVER_NAME "dcdbas" | 42 | #define DRIVER_NAME "dcdbas" |
43 | #define DRIVER_VERSION "5.6.0-2" | 43 | #define DRIVER_VERSION "5.6.0-3.2" |
44 | #define DRIVER_DESCRIPTION "Dell Systems Management Base Driver" | 44 | #define DRIVER_DESCRIPTION "Dell Systems Management Base Driver" |
45 | 45 | ||
46 | static struct platform_device *dcdbas_pdev; | 46 | static struct platform_device *dcdbas_pdev; |
@@ -175,6 +175,9 @@ static ssize_t smi_data_write(struct kobject *kobj, char *buf, loff_t pos, | |||
175 | { | 175 | { |
176 | ssize_t ret; | 176 | ssize_t ret; |
177 | 177 | ||
178 | if ((pos + count) > MAX_SMI_DATA_BUF_SIZE) | ||
179 | return -EINVAL; | ||
180 | |||
178 | mutex_lock(&smi_data_lock); | 181 | mutex_lock(&smi_data_lock); |
179 | 182 | ||
180 | ret = smi_data_buf_realloc(pos + count); | 183 | ret = smi_data_buf_realloc(pos + count); |
diff --git a/drivers/firmware/dell_rbu.c b/drivers/firmware/dell_rbu.c index fc17599c905e..fc702e40bd43 100644 --- a/drivers/firmware/dell_rbu.c +++ b/drivers/firmware/dell_rbu.c | |||
@@ -249,7 +249,7 @@ static int packetize_data(void *data, size_t length) | |||
249 | if ((rc = create_packet(temp, packet_length))) | 249 | if ((rc = create_packet(temp, packet_length))) |
250 | return rc; | 250 | return rc; |
251 | 251 | ||
252 | pr_debug("%p:%lu\n", temp, (end - temp)); | 252 | pr_debug("%p:%td\n", temp, (end - temp)); |
253 | temp += packet_length; | 253 | temp += packet_length; |
254 | } | 254 | } |
255 | 255 | ||
@@ -705,27 +705,39 @@ static struct bin_attribute rbu_packet_size_attr = { | |||
705 | 705 | ||
706 | static int __init dcdrbu_init(void) | 706 | static int __init dcdrbu_init(void) |
707 | { | 707 | { |
708 | int rc = 0; | 708 | int rc; |
709 | spin_lock_init(&rbu_data.lock); | 709 | spin_lock_init(&rbu_data.lock); |
710 | 710 | ||
711 | init_packet_head(); | 711 | init_packet_head(); |
712 | rbu_device = | 712 | rbu_device = platform_device_register_simple("dell_rbu", -1, NULL, 0); |
713 | platform_device_register_simple("dell_rbu", -1, NULL, 0); | 713 | if (IS_ERR(rbu_device)) { |
714 | if (!rbu_device) { | ||
715 | printk(KERN_ERR | 714 | printk(KERN_ERR |
716 | "dell_rbu:%s:platform_device_register_simple " | 715 | "dell_rbu:%s:platform_device_register_simple " |
717 | "failed\n", __FUNCTION__); | 716 | "failed\n", __FUNCTION__); |
718 | return -EIO; | 717 | return PTR_ERR(rbu_device); |
719 | } | 718 | } |
720 | 719 | ||
721 | sysfs_create_bin_file(&rbu_device->dev.kobj, &rbu_data_attr); | 720 | rc = sysfs_create_bin_file(&rbu_device->dev.kobj, &rbu_data_attr); |
722 | sysfs_create_bin_file(&rbu_device->dev.kobj, &rbu_image_type_attr); | 721 | if (rc) |
723 | sysfs_create_bin_file(&rbu_device->dev.kobj, | 722 | goto out_devreg; |
723 | rc = sysfs_create_bin_file(&rbu_device->dev.kobj, &rbu_image_type_attr); | ||
724 | if (rc) | ||
725 | goto out_data; | ||
726 | rc = sysfs_create_bin_file(&rbu_device->dev.kobj, | ||
724 | &rbu_packet_size_attr); | 727 | &rbu_packet_size_attr); |
728 | if (rc) | ||
729 | goto out_imtype; | ||
725 | 730 | ||
726 | rbu_data.entry_created = 0; | 731 | rbu_data.entry_created = 0; |
727 | return rc; | 732 | return 0; |
728 | 733 | ||
734 | out_imtype: | ||
735 | sysfs_remove_bin_file(&rbu_device->dev.kobj, &rbu_image_type_attr); | ||
736 | out_data: | ||
737 | sysfs_remove_bin_file(&rbu_device->dev.kobj, &rbu_data_attr); | ||
738 | out_devreg: | ||
739 | platform_device_unregister(rbu_device); | ||
740 | return rc; | ||
729 | } | 741 | } |
730 | 742 | ||
731 | static __exit void dcdrbu_exit(void) | 743 | static __exit void dcdrbu_exit(void) |
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index b8b596d5778d..37deee6c0c1c 100644 --- a/drivers/firmware/dmi_scan.c +++ b/drivers/firmware/dmi_scan.c | |||
@@ -326,6 +326,26 @@ char *dmi_get_system_info(int field) | |||
326 | } | 326 | } |
327 | EXPORT_SYMBOL(dmi_get_system_info); | 327 | EXPORT_SYMBOL(dmi_get_system_info); |
328 | 328 | ||
329 | |||
330 | /** | ||
331 | * dmi_name_in_vendors - Check if string is anywhere in the DMI vendor information. | ||
332 | * @str: Case sensitive Name | ||
333 | */ | ||
334 | int dmi_name_in_vendors(char *str) | ||
335 | { | ||
336 | static int fields[] = { DMI_BIOS_VENDOR, DMI_BIOS_VERSION, DMI_SYS_VENDOR, | ||
337 | DMI_PRODUCT_NAME, DMI_PRODUCT_VERSION, DMI_BOARD_VENDOR, | ||
338 | DMI_BOARD_NAME, DMI_BOARD_VERSION, DMI_NONE }; | ||
339 | int i; | ||
340 | for (i = 0; fields[i] != DMI_NONE; i++) { | ||
341 | int f = fields[i]; | ||
342 | if (dmi_ident[f] && strstr(dmi_ident[f], str)) | ||
343 | return 1; | ||
344 | } | ||
345 | return 0; | ||
346 | } | ||
347 | EXPORT_SYMBOL(dmi_name_in_vendors); | ||
348 | |||
329 | /** | 349 | /** |
330 | * dmi_find_device - find onboard device by type/name | 350 | * dmi_find_device - find onboard device by type/name |
331 | * @type: device type or %DMI_DEV_TYPE_ANY to match all device types | 351 | * @type: device type or %DMI_DEV_TYPE_ANY to match all device types |
diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c index 8ebce1c03ad7..5ab5e393b882 100644 --- a/drivers/firmware/efivars.c +++ b/drivers/firmware/efivars.c | |||
@@ -639,7 +639,12 @@ efivar_create_sysfs_entry(unsigned long variable_name_size, | |||
639 | 639 | ||
640 | kobject_set_name(&new_efivar->kobj, "%s", short_name); | 640 | kobject_set_name(&new_efivar->kobj, "%s", short_name); |
641 | kobj_set_kset_s(new_efivar, vars_subsys); | 641 | kobj_set_kset_s(new_efivar, vars_subsys); |
642 | kobject_register(&new_efivar->kobj); | 642 | i = kobject_register(&new_efivar->kobj); |
643 | if (i) { | ||
644 | kfree(short_name); | ||
645 | kfree(new_efivar); | ||
646 | return 1; | ||
647 | } | ||
643 | 648 | ||
644 | kfree(short_name); | 649 | kfree(short_name); |
645 | short_name = NULL; | 650 | short_name = NULL; |
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 9b88b25b6edb..e76d91906c99 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -95,11 +95,13 @@ config SENSORS_ADM9240 | |||
95 | will be called adm9240. | 95 | will be called adm9240. |
96 | 96 | ||
97 | config SENSORS_K8TEMP | 97 | config SENSORS_K8TEMP |
98 | tristate "AMD K8 processor sensor" | 98 | tristate "AMD Athlon64/FX or Opteron temperature sensor" |
99 | depends on HWMON && X86 && PCI && EXPERIMENTAL | 99 | depends on HWMON && X86 && PCI && EXPERIMENTAL |
100 | help | 100 | help |
101 | If you say yes here you get support for the temperature | 101 | If you say yes here you get support for the temperature |
102 | sensor(s) inside your AMD K8 CPU. | 102 | sensor(s) inside your CPU. Supported is whole AMD K8 |
103 | microarchitecture. Please note that you will need at least | ||
104 | lm-sensors 2.10.1 for proper userspace support. | ||
103 | 105 | ||
104 | This driver can also be built as a module. If so, the module | 106 | This driver can also be built as a module. If so, the module |
105 | will be called k8temp. | 107 | will be called k8temp. |
@@ -369,8 +371,8 @@ config SENSORS_SMSC47M1 | |||
369 | help | 371 | help |
370 | If you say yes here you get support for the integrated fan | 372 | If you say yes here you get support for the integrated fan |
371 | monitoring and control capabilities of the SMSC LPC47B27x, | 373 | monitoring and control capabilities of the SMSC LPC47B27x, |
372 | LPC47M10x, LPC47M13x, LPC47M14x, LPC47M15x, LPC47M192 and | 374 | LPC47M10x, LPC47M112, LPC47M13x, LPC47M14x, LPC47M15x, |
373 | LPC47M997 chips. | 375 | LPC47M192 and LPC47M997 chips. |
374 | 376 | ||
375 | The temperature and voltage sensor features of the LPC47M192 | 377 | The temperature and voltage sensor features of the LPC47M192 |
376 | and LPC47M997 are supported by another driver, select also | 378 | and LPC47M997 are supported by another driver, select also |
diff --git a/drivers/hwmon/adm9240.c b/drivers/hwmon/adm9240.c index 377961c4a41e..aad594adf0c7 100644 --- a/drivers/hwmon/adm9240.c +++ b/drivers/hwmon/adm9240.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * Copyright (C) 1999 Frodo Looijaard <frodol@dds.nl> | 5 | * Copyright (C) 1999 Frodo Looijaard <frodol@dds.nl> |
6 | * Philip Edelbrock <phil@netroedge.com> | 6 | * Philip Edelbrock <phil@netroedge.com> |
7 | * Copyright (C) 2003 Michiel Rook <michiel@grendelproject.nl> | 7 | * Copyright (C) 2003 Michiel Rook <michiel@grendelproject.nl> |
8 | * Copyright (C) 2005 Grant Coady <gcoady@gmail.com> with valuable | 8 | * Copyright (C) 2005 Grant Coady <gcoady.lk@gmail.com> with valuable |
9 | * guidance from Jean Delvare | 9 | * guidance from Jean Delvare |
10 | * | 10 | * |
11 | * Driver supports Analog Devices ADM9240 | 11 | * Driver supports Analog Devices ADM9240 |
@@ -774,7 +774,7 @@ static void __exit sensors_adm9240_exit(void) | |||
774 | } | 774 | } |
775 | 775 | ||
776 | MODULE_AUTHOR("Michiel Rook <michiel@grendelproject.nl>, " | 776 | MODULE_AUTHOR("Michiel Rook <michiel@grendelproject.nl>, " |
777 | "Grant Coady <gcoady@gmail.com> and others"); | 777 | "Grant Coady <gcoady.lk@gmail.com> and others"); |
778 | MODULE_DESCRIPTION("ADM9240/DS1780/LM81 driver"); | 778 | MODULE_DESCRIPTION("ADM9240/DS1780/LM81 driver"); |
779 | MODULE_LICENSE("GPL"); | 779 | MODULE_LICENSE("GPL"); |
780 | 780 | ||
diff --git a/drivers/hwmon/lm78.c b/drivers/hwmon/lm78.c index ac1b746df6d0..73bc2ffc598d 100644 --- a/drivers/hwmon/lm78.c +++ b/drivers/hwmon/lm78.c | |||
@@ -815,18 +815,18 @@ static int __init sm_lm78_init(void) | |||
815 | if (res) | 815 | if (res) |
816 | return res; | 816 | return res; |
817 | 817 | ||
818 | res = i2c_isa_add_driver(&lm78_isa_driver); | 818 | /* Don't exit if this one fails, we still want the I2C variants |
819 | if (res) { | 819 | to work! */ |
820 | i2c_del_driver(&lm78_driver); | 820 | if (i2c_isa_add_driver(&lm78_isa_driver)) |
821 | return res; | 821 | isa_address = 0; |
822 | } | ||
823 | 822 | ||
824 | return 0; | 823 | return 0; |
825 | } | 824 | } |
826 | 825 | ||
827 | static void __exit sm_lm78_exit(void) | 826 | static void __exit sm_lm78_exit(void) |
828 | { | 827 | { |
829 | i2c_isa_del_driver(&lm78_isa_driver); | 828 | if (isa_address) |
829 | i2c_isa_del_driver(&lm78_isa_driver); | ||
830 | i2c_del_driver(&lm78_driver); | 830 | i2c_del_driver(&lm78_driver); |
831 | } | 831 | } |
832 | 832 | ||
diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c index 47132fd26b1b..beb881c4b2e8 100644 --- a/drivers/hwmon/smsc47m1.c +++ b/drivers/hwmon/smsc47m1.c | |||
@@ -2,8 +2,8 @@ | |||
2 | smsc47m1.c - Part of lm_sensors, Linux kernel modules | 2 | smsc47m1.c - Part of lm_sensors, Linux kernel modules |
3 | for hardware monitoring | 3 | for hardware monitoring |
4 | 4 | ||
5 | Supports the SMSC LPC47B27x, LPC47M10x, LPC47M13x, LPC47M14x, | 5 | Supports the SMSC LPC47B27x, LPC47M10x, LPC47M112, LPC47M13x, |
6 | LPC47M15x, LPC47M192 and LPC47M997 Super-I/O chips. | 6 | LPC47M14x, LPC47M15x, LPC47M192 and LPC47M997 Super-I/O chips. |
7 | 7 | ||
8 | Copyright (C) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com> | 8 | Copyright (C) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com> |
9 | Copyright (C) 2004 Jean Delvare <khali@linux-fr.org> | 9 | Copyright (C) 2004 Jean Delvare <khali@linux-fr.org> |
@@ -380,8 +380,8 @@ static int __init smsc47m1_find(unsigned short *addr) | |||
380 | val = superio_inb(SUPERIO_REG_DEVID); | 380 | val = superio_inb(SUPERIO_REG_DEVID); |
381 | 381 | ||
382 | /* | 382 | /* |
383 | * SMSC LPC47M10x/LPC47M13x (device id 0x59), LPC47M14x (device id | 383 | * SMSC LPC47M10x/LPC47M112/LPC47M13x (device id 0x59), LPC47M14x |
384 | * 0x5F) and LPC47B27x (device id 0x51) have fan control. | 384 | * (device id 0x5F) and LPC47B27x (device id 0x51) have fan control. |
385 | * The LPC47M15x and LPC47M192 chips "with hardware monitoring block" | 385 | * The LPC47M15x and LPC47M192 chips "with hardware monitoring block" |
386 | * can do much more besides (device id 0x60). | 386 | * can do much more besides (device id 0x60). |
387 | * The LPC47M997 is undocumented, but seems to be compatible with | 387 | * The LPC47M997 is undocumented, but seems to be compatible with |
@@ -390,7 +390,8 @@ static int __init smsc47m1_find(unsigned short *addr) | |||
390 | if (val == 0x51) | 390 | if (val == 0x51) |
391 | printk(KERN_INFO "smsc47m1: Found SMSC LPC47B27x\n"); | 391 | printk(KERN_INFO "smsc47m1: Found SMSC LPC47B27x\n"); |
392 | else if (val == 0x59) | 392 | else if (val == 0x59) |
393 | printk(KERN_INFO "smsc47m1: Found SMSC LPC47M10x/LPC47M13x\n"); | 393 | printk(KERN_INFO "smsc47m1: Found SMSC " |
394 | "LPC47M10x/LPC47M112/LPC47M13x\n"); | ||
394 | else if (val == 0x5F) | 395 | else if (val == 0x5F) |
395 | printk(KERN_INFO "smsc47m1: Found SMSC LPC47M14x\n"); | 396 | printk(KERN_INFO "smsc47m1: Found SMSC LPC47M14x\n"); |
396 | else if (val == 0x60) | 397 | else if (val == 0x60) |
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index 833faa275ffa..2257806d0102 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c | |||
@@ -354,6 +354,8 @@ static void w83627ehf_write_fan_div(struct i2c_client *client, int nr) | |||
354 | case 0: | 354 | case 0: |
355 | reg = (w83627ehf_read_value(client, W83627EHF_REG_FANDIV1) & 0xcf) | 355 | reg = (w83627ehf_read_value(client, W83627EHF_REG_FANDIV1) & 0xcf) |
356 | | ((data->fan_div[0] & 0x03) << 4); | 356 | | ((data->fan_div[0] & 0x03) << 4); |
357 | /* fan5 input control bit is write only, compute the value */ | ||
358 | reg |= (data->has_fan & (1 << 4)) ? 1 : 0; | ||
357 | w83627ehf_write_value(client, W83627EHF_REG_FANDIV1, reg); | 359 | w83627ehf_write_value(client, W83627EHF_REG_FANDIV1, reg); |
358 | reg = (w83627ehf_read_value(client, W83627EHF_REG_VBAT) & 0xdf) | 360 | reg = (w83627ehf_read_value(client, W83627EHF_REG_VBAT) & 0xdf) |
359 | | ((data->fan_div[0] & 0x04) << 3); | 361 | | ((data->fan_div[0] & 0x04) << 3); |
@@ -362,6 +364,8 @@ static void w83627ehf_write_fan_div(struct i2c_client *client, int nr) | |||
362 | case 1: | 364 | case 1: |
363 | reg = (w83627ehf_read_value(client, W83627EHF_REG_FANDIV1) & 0x3f) | 365 | reg = (w83627ehf_read_value(client, W83627EHF_REG_FANDIV1) & 0x3f) |
364 | | ((data->fan_div[1] & 0x03) << 6); | 366 | | ((data->fan_div[1] & 0x03) << 6); |
367 | /* fan5 input control bit is write only, compute the value */ | ||
368 | reg |= (data->has_fan & (1 << 4)) ? 1 : 0; | ||
365 | w83627ehf_write_value(client, W83627EHF_REG_FANDIV1, reg); | 369 | w83627ehf_write_value(client, W83627EHF_REG_FANDIV1, reg); |
366 | reg = (w83627ehf_read_value(client, W83627EHF_REG_VBAT) & 0xbf) | 370 | reg = (w83627ehf_read_value(client, W83627EHF_REG_VBAT) & 0xbf) |
367 | | ((data->fan_div[1] & 0x04) << 4); | 371 | | ((data->fan_div[1] & 0x04) << 4); |
@@ -1216,13 +1220,16 @@ static int w83627ehf_detect(struct i2c_adapter *adapter) | |||
1216 | superio_exit(); | 1220 | superio_exit(); |
1217 | 1221 | ||
1218 | /* It looks like fan4 and fan5 pins can be alternatively used | 1222 | /* It looks like fan4 and fan5 pins can be alternatively used |
1219 | as fan on/off switches */ | 1223 | as fan on/off switches, but fan5 control is write only :/ |
1224 | We assume that if the serial interface is disabled, designers | ||
1225 | connected fan5 as input unless they are emitting log 1, which | ||
1226 | is not the default. */ | ||
1220 | 1227 | ||
1221 | data->has_fan = 0x07; /* fan1, fan2 and fan3 */ | 1228 | data->has_fan = 0x07; /* fan1, fan2 and fan3 */ |
1222 | i = w83627ehf_read_value(client, W83627EHF_REG_FANDIV1); | 1229 | i = w83627ehf_read_value(client, W83627EHF_REG_FANDIV1); |
1223 | if ((i & (1 << 2)) && (!fan4pin)) | 1230 | if ((i & (1 << 2)) && (!fan4pin)) |
1224 | data->has_fan |= (1 << 3); | 1231 | data->has_fan |= (1 << 3); |
1225 | if ((i & (1 << 0)) && (!fan5pin)) | 1232 | if (!(i & (1 << 1)) && (!fan5pin)) |
1226 | data->has_fan |= (1 << 4); | 1233 | data->has_fan |= (1 << 4); |
1227 | 1234 | ||
1228 | /* Register sysfs hooks */ | 1235 | /* Register sysfs hooks */ |
diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c index a4584ec69842..1232171c3aad 100644 --- a/drivers/hwmon/w83781d.c +++ b/drivers/hwmon/w83781d.c | |||
@@ -1099,7 +1099,8 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1099 | bank. */ | 1099 | bank. */ |
1100 | if (kind < 0) { | 1100 | if (kind < 0) { |
1101 | if (w83781d_read_value(client, W83781D_REG_CONFIG) & 0x80) { | 1101 | if (w83781d_read_value(client, W83781D_REG_CONFIG) & 0x80) { |
1102 | dev_dbg(dev, "Detection failed at step 3\n"); | 1102 | dev_dbg(&adapter->dev, "Detection of w83781d chip " |
1103 | "failed at step 3\n"); | ||
1103 | err = -ENODEV; | 1104 | err = -ENODEV; |
1104 | goto ERROR2; | 1105 | goto ERROR2; |
1105 | } | 1106 | } |
@@ -1109,7 +1110,8 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1109 | if ((!(val1 & 0x07)) && | 1110 | if ((!(val1 & 0x07)) && |
1110 | (((!(val1 & 0x80)) && (val2 != 0xa3) && (val2 != 0xc3)) | 1111 | (((!(val1 & 0x80)) && (val2 != 0xa3) && (val2 != 0xc3)) |
1111 | || ((val1 & 0x80) && (val2 != 0x5c) && (val2 != 0x12)))) { | 1112 | || ((val1 & 0x80) && (val2 != 0x5c) && (val2 != 0x12)))) { |
1112 | dev_dbg(dev, "Detection failed at step 4\n"); | 1113 | dev_dbg(&adapter->dev, "Detection of w83781d chip " |
1114 | "failed at step 4\n"); | ||
1113 | err = -ENODEV; | 1115 | err = -ENODEV; |
1114 | goto ERROR2; | 1116 | goto ERROR2; |
1115 | } | 1117 | } |
@@ -1119,7 +1121,8 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1119 | ((val1 & 0x80) && (val2 == 0x5c)))) { | 1121 | ((val1 & 0x80) && (val2 == 0x5c)))) { |
1120 | if (w83781d_read_value | 1122 | if (w83781d_read_value |
1121 | (client, W83781D_REG_I2C_ADDR) != address) { | 1123 | (client, W83781D_REG_I2C_ADDR) != address) { |
1122 | dev_dbg(dev, "Detection failed at step 5\n"); | 1124 | dev_dbg(&adapter->dev, "Detection of w83781d " |
1125 | "chip failed at step 5\n"); | ||
1123 | err = -ENODEV; | 1126 | err = -ENODEV; |
1124 | goto ERROR2; | 1127 | goto ERROR2; |
1125 | } | 1128 | } |
@@ -1141,8 +1144,8 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1141 | else if (val2 == 0x12) | 1144 | else if (val2 == 0x12) |
1142 | vendid = asus; | 1145 | vendid = asus; |
1143 | else { | 1146 | else { |
1144 | dev_dbg(dev, "Chip was made by neither " | 1147 | dev_dbg(&adapter->dev, "w83781d chip vendor is " |
1145 | "Winbond nor Asus?\n"); | 1148 | "neither Winbond nor Asus\n"); |
1146 | err = -ENODEV; | 1149 | err = -ENODEV; |
1147 | goto ERROR2; | 1150 | goto ERROR2; |
1148 | } | 1151 | } |
@@ -1161,10 +1164,9 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1161 | kind = as99127f; | 1164 | kind = as99127f; |
1162 | else { | 1165 | else { |
1163 | if (kind == 0) | 1166 | if (kind == 0) |
1164 | dev_warn(dev, "Ignoring 'force' " | 1167 | dev_warn(&adapter->dev, "Ignoring 'force' " |
1165 | "parameter for unknown chip at " | 1168 | "parameter for unknown chip at " |
1166 | "adapter %d, address 0x%02x\n", | 1169 | "address 0x%02x\n", address); |
1167 | i2c_adapter_id(adapter), address); | ||
1168 | err = -EINVAL; | 1170 | err = -EINVAL; |
1169 | goto ERROR2; | 1171 | goto ERROR2; |
1170 | } | 1172 | } |
@@ -1685,11 +1687,10 @@ sensors_w83781d_init(void) | |||
1685 | if (res) | 1687 | if (res) |
1686 | return res; | 1688 | return res; |
1687 | 1689 | ||
1688 | res = i2c_isa_add_driver(&w83781d_isa_driver); | 1690 | /* Don't exit if this one fails, we still want the I2C variants |
1689 | if (res) { | 1691 | to work! */ |
1690 | i2c_del_driver(&w83781d_driver); | 1692 | if (i2c_isa_add_driver(&w83781d_isa_driver)) |
1691 | return res; | 1693 | isa_address = 0; |
1692 | } | ||
1693 | 1694 | ||
1694 | return 0; | 1695 | return 0; |
1695 | } | 1696 | } |
@@ -1697,7 +1698,8 @@ sensors_w83781d_init(void) | |||
1697 | static void __exit | 1698 | static void __exit |
1698 | sensors_w83781d_exit(void) | 1699 | sensors_w83781d_exit(void) |
1699 | { | 1700 | { |
1700 | i2c_isa_del_driver(&w83781d_isa_driver); | 1701 | if (isa_address) |
1702 | i2c_isa_del_driver(&w83781d_isa_driver); | ||
1701 | i2c_del_driver(&w83781d_driver); | 1703 | i2c_del_driver(&w83781d_driver); |
1702 | } | 1704 | } |
1703 | 1705 | ||
diff --git a/drivers/hwmon/w83791d.c b/drivers/hwmon/w83791d.c index 371ed4f69a97..9e5f885368b4 100644 --- a/drivers/hwmon/w83791d.c +++ b/drivers/hwmon/w83791d.c | |||
@@ -746,6 +746,52 @@ static ssize_t store_vrm_reg(struct device *dev, | |||
746 | 746 | ||
747 | static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg); | 747 | static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg); |
748 | 748 | ||
749 | #define IN_UNIT_ATTRS(X) \ | ||
750 | &sda_in_input[X].dev_attr.attr, \ | ||
751 | &sda_in_min[X].dev_attr.attr, \ | ||
752 | &sda_in_max[X].dev_attr.attr | ||
753 | |||
754 | #define FAN_UNIT_ATTRS(X) \ | ||
755 | &sda_fan_input[X].dev_attr.attr, \ | ||
756 | &sda_fan_min[X].dev_attr.attr, \ | ||
757 | &sda_fan_div[X].dev_attr.attr | ||
758 | |||
759 | #define TEMP_UNIT_ATTRS(X) \ | ||
760 | &sda_temp_input[X].dev_attr.attr, \ | ||
761 | &sda_temp_max[X].dev_attr.attr, \ | ||
762 | &sda_temp_max_hyst[X].dev_attr.attr | ||
763 | |||
764 | static struct attribute *w83791d_attributes[] = { | ||
765 | IN_UNIT_ATTRS(0), | ||
766 | IN_UNIT_ATTRS(1), | ||
767 | IN_UNIT_ATTRS(2), | ||
768 | IN_UNIT_ATTRS(3), | ||
769 | IN_UNIT_ATTRS(4), | ||
770 | IN_UNIT_ATTRS(5), | ||
771 | IN_UNIT_ATTRS(6), | ||
772 | IN_UNIT_ATTRS(7), | ||
773 | IN_UNIT_ATTRS(8), | ||
774 | IN_UNIT_ATTRS(9), | ||
775 | FAN_UNIT_ATTRS(0), | ||
776 | FAN_UNIT_ATTRS(1), | ||
777 | FAN_UNIT_ATTRS(2), | ||
778 | FAN_UNIT_ATTRS(3), | ||
779 | FAN_UNIT_ATTRS(4), | ||
780 | TEMP_UNIT_ATTRS(0), | ||
781 | TEMP_UNIT_ATTRS(1), | ||
782 | TEMP_UNIT_ATTRS(2), | ||
783 | &dev_attr_alarms.attr, | ||
784 | &sda_beep_ctrl[0].dev_attr.attr, | ||
785 | &sda_beep_ctrl[1].dev_attr.attr, | ||
786 | &dev_attr_cpu0_vid.attr, | ||
787 | &dev_attr_vrm.attr, | ||
788 | NULL | ||
789 | }; | ||
790 | |||
791 | static const struct attribute_group w83791d_group = { | ||
792 | .attrs = w83791d_attributes, | ||
793 | }; | ||
794 | |||
749 | /* This function is called when: | 795 | /* This function is called when: |
750 | * w83791d_driver is inserted (when this module is loaded), for each | 796 | * w83791d_driver is inserted (when this module is loaded), for each |
751 | available adapter | 797 | available adapter |
@@ -967,41 +1013,20 @@ static int w83791d_detect(struct i2c_adapter *adapter, int address, int kind) | |||
967 | } | 1013 | } |
968 | 1014 | ||
969 | /* Register sysfs hooks */ | 1015 | /* Register sysfs hooks */ |
1016 | if ((err = sysfs_create_group(&client->dev.kobj, &w83791d_group))) | ||
1017 | goto error3; | ||
1018 | |||
1019 | /* Everything is ready, now register the working device */ | ||
970 | data->class_dev = hwmon_device_register(dev); | 1020 | data->class_dev = hwmon_device_register(dev); |
971 | if (IS_ERR(data->class_dev)) { | 1021 | if (IS_ERR(data->class_dev)) { |
972 | err = PTR_ERR(data->class_dev); | 1022 | err = PTR_ERR(data->class_dev); |
973 | goto error3; | 1023 | goto error4; |
974 | } | 1024 | } |
975 | 1025 | ||
976 | for (i = 0; i < NUMBER_OF_VIN; i++) { | ||
977 | device_create_file(dev, &sda_in_input[i].dev_attr); | ||
978 | device_create_file(dev, &sda_in_min[i].dev_attr); | ||
979 | device_create_file(dev, &sda_in_max[i].dev_attr); | ||
980 | } | ||
981 | |||
982 | for (i = 0; i < NUMBER_OF_FANIN; i++) { | ||
983 | device_create_file(dev, &sda_fan_input[i].dev_attr); | ||
984 | device_create_file(dev, &sda_fan_div[i].dev_attr); | ||
985 | device_create_file(dev, &sda_fan_min[i].dev_attr); | ||
986 | } | ||
987 | |||
988 | for (i = 0; i < NUMBER_OF_TEMPIN; i++) { | ||
989 | device_create_file(dev, &sda_temp_input[i].dev_attr); | ||
990 | device_create_file(dev, &sda_temp_max[i].dev_attr); | ||
991 | device_create_file(dev, &sda_temp_max_hyst[i].dev_attr); | ||
992 | } | ||
993 | |||
994 | device_create_file(dev, &dev_attr_alarms); | ||
995 | |||
996 | for (i = 0; i < ARRAY_SIZE(sda_beep_ctrl); i++) { | ||
997 | device_create_file(dev, &sda_beep_ctrl[i].dev_attr); | ||
998 | } | ||
999 | |||
1000 | device_create_file(dev, &dev_attr_cpu0_vid); | ||
1001 | device_create_file(dev, &dev_attr_vrm); | ||
1002 | |||
1003 | return 0; | 1026 | return 0; |
1004 | 1027 | ||
1028 | error4: | ||
1029 | sysfs_remove_group(&client->dev.kobj, &w83791d_group); | ||
1005 | error3: | 1030 | error3: |
1006 | if (data->lm75[0] != NULL) { | 1031 | if (data->lm75[0] != NULL) { |
1007 | i2c_detach_client(data->lm75[0]); | 1032 | i2c_detach_client(data->lm75[0]); |
@@ -1025,8 +1050,10 @@ static int w83791d_detach_client(struct i2c_client *client) | |||
1025 | int err; | 1050 | int err; |
1026 | 1051 | ||
1027 | /* main client */ | 1052 | /* main client */ |
1028 | if (data) | 1053 | if (data) { |
1029 | hwmon_device_unregister(data->class_dev); | 1054 | hwmon_device_unregister(data->class_dev); |
1055 | sysfs_remove_group(&client->dev.kobj, &w83791d_group); | ||
1056 | } | ||
1030 | 1057 | ||
1031 | if ((err = i2c_detach_client(client))) | 1058 | if ((err = i2c_detach_client(client))) |
1032 | return err; | 1059 | return err; |
diff --git a/drivers/i2c/busses/i2c-isa.c b/drivers/i2c/busses/i2c-isa.c index 4380653748a4..8ed59a2dff53 100644 --- a/drivers/i2c/busses/i2c-isa.c +++ b/drivers/i2c/busses/i2c-isa.c | |||
@@ -91,7 +91,7 @@ int i2c_isa_add_driver(struct i2c_driver *driver) | |||
91 | /* Now look for clients */ | 91 | /* Now look for clients */ |
92 | res = driver->attach_adapter(&isa_adapter); | 92 | res = driver->attach_adapter(&isa_adapter); |
93 | if (res) { | 93 | if (res) { |
94 | dev_err(&isa_adapter.dev, | 94 | dev_dbg(&isa_adapter.dev, |
95 | "Driver %s failed to attach adapter, unregistering\n", | 95 | "Driver %s failed to attach adapter, unregistering\n", |
96 | driver->driver.name); | 96 | driver->driver.name); |
97 | driver_unregister(&driver->driver); | 97 | driver_unregister(&driver->driver); |
diff --git a/drivers/i2c/busses/i2c-ixp4xx.c b/drivers/i2c/busses/i2c-ixp4xx.c index 1ce01fb0ac09..05fffb9415a2 100644 --- a/drivers/i2c/busses/i2c-ixp4xx.c +++ b/drivers/i2c/busses/i2c-ixp4xx.c | |||
@@ -137,7 +137,8 @@ static int ixp4xx_i2c_probe(struct platform_device *plat_dev) | |||
137 | gpio_line_set(gpio->scl_pin, 0); | 137 | gpio_line_set(gpio->scl_pin, 0); |
138 | gpio_line_set(gpio->sda_pin, 0); | 138 | gpio_line_set(gpio->sda_pin, 0); |
139 | 139 | ||
140 | if ((err = i2c_bit_add_bus(&drv_data->adapter) != 0)) { | 140 | err = i2c_bit_add_bus(&drv_data->adapter); |
141 | if (err != 0) | ||
141 | printk(KERN_ERR "ERROR: Could not install %s\n", plat_dev->dev.bus_id); | 142 | printk(KERN_ERR "ERROR: Could not install %s\n", plat_dev->dev.bus_id); |
142 | 143 | ||
143 | kfree(drv_data); | 144 | kfree(drv_data); |
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index 81050d3c9b21..c95a6c154165 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c | |||
@@ -272,7 +272,8 @@ static int i2c_pxa_wait_slave(struct pxa_i2c *i2c) | |||
272 | dev_dbg(&i2c->adap.dev, "%s: %ld: ISR=%08x, ICR=%08x, IBMR=%02x\n", | 272 | dev_dbg(&i2c->adap.dev, "%s: %ld: ISR=%08x, ICR=%08x, IBMR=%02x\n", |
273 | __func__, (long)jiffies, ISR, ICR, IBMR); | 273 | __func__, (long)jiffies, ISR, ICR, IBMR); |
274 | 274 | ||
275 | if ((ISR & (ISR_UB|ISR_IBB|ISR_SAD)) == ISR_SAD || | 275 | if ((ISR & (ISR_UB|ISR_IBB)) == 0 || |
276 | (ISR & ISR_SAD) != 0 || | ||
276 | (ICR & ICR_SCLE) == 0) { | 277 | (ICR & ICR_SCLE) == 0) { |
277 | if (i2c_debug > 1) | 278 | if (i2c_debug > 1) |
278 | dev_dbg(&i2c->adap.dev, "%s: done\n", __func__); | 279 | dev_dbg(&i2c->adap.dev, "%s: done\n", __func__); |
@@ -492,7 +493,10 @@ static void i2c_pxa_slave_txempty(struct pxa_i2c *i2c, u32 isr) | |||
492 | if (isr & ISR_BED) { | 493 | if (isr & ISR_BED) { |
493 | /* what should we do here? */ | 494 | /* what should we do here? */ |
494 | } else { | 495 | } else { |
495 | int ret = i2c->slave->read(i2c->slave->data); | 496 | int ret = 0; |
497 | |||
498 | if (i2c->slave != NULL) | ||
499 | ret = i2c->slave->read(i2c->slave->data); | ||
496 | 500 | ||
497 | IDBR = ret; | 501 | IDBR = ret; |
498 | ICR |= ICR_TB; /* allow next byte */ | 502 | ICR |= ICR_TB; /* allow next byte */ |
diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c index 32aab0d34ee9..714bae780953 100644 --- a/drivers/i2c/busses/scx200_acb.c +++ b/drivers/i2c/busses/scx200_acb.c | |||
@@ -494,11 +494,12 @@ static __init int scx200_create_pci(const char *text, struct pci_dev *pdev, | |||
494 | iface->pdev = pdev; | 494 | iface->pdev = pdev; |
495 | iface->bar = bar; | 495 | iface->bar = bar; |
496 | 496 | ||
497 | pci_enable_device_bars(iface->pdev, 1 << iface->bar); | 497 | rc = pci_enable_device_bars(iface->pdev, 1 << iface->bar); |
498 | if (rc) | ||
499 | goto errout_free; | ||
498 | 500 | ||
499 | rc = pci_request_region(iface->pdev, iface->bar, iface->adapter.name); | 501 | rc = pci_request_region(iface->pdev, iface->bar, iface->adapter.name); |
500 | 502 | if (rc) { | |
501 | if (rc != 0) { | ||
502 | printk(KERN_ERR NAME ": can't allocate PCI BAR %d\n", | 503 | printk(KERN_ERR NAME ": can't allocate PCI BAR %d\n", |
503 | iface->bar); | 504 | iface->bar); |
504 | goto errout_free; | 505 | goto errout_free; |
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 69bbb6206a00..88214943d00a 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c | |||
@@ -597,7 +597,7 @@ static void cdrom_prepare_request(ide_drive_t *drive, struct request *rq) | |||
597 | struct cdrom_info *cd = drive->driver_data; | 597 | struct cdrom_info *cd = drive->driver_data; |
598 | 598 | ||
599 | ide_init_drive_cmd(rq); | 599 | ide_init_drive_cmd(rq); |
600 | rq->cmd_type = REQ_TYPE_BLOCK_PC; | 600 | rq->cmd_type = REQ_TYPE_ATA_PC; |
601 | rq->rq_disk = cd->disk; | 601 | rq->rq_disk = cd->disk; |
602 | } | 602 | } |
603 | 603 | ||
@@ -716,7 +716,7 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) | |||
716 | ide_error(drive, "request sense failure", stat); | 716 | ide_error(drive, "request sense failure", stat); |
717 | return 1; | 717 | return 1; |
718 | 718 | ||
719 | } else if (blk_pc_request(rq)) { | 719 | } else if (blk_pc_request(rq) || rq->cmd_type == REQ_TYPE_ATA_PC) { |
720 | /* All other functions, except for READ. */ | 720 | /* All other functions, except for READ. */ |
721 | unsigned long flags; | 721 | unsigned long flags; |
722 | 722 | ||
@@ -724,7 +724,7 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) | |||
724 | * if we have an error, pass back CHECK_CONDITION as the | 724 | * if we have an error, pass back CHECK_CONDITION as the |
725 | * scsi status byte | 725 | * scsi status byte |
726 | */ | 726 | */ |
727 | if (!rq->errors) | 727 | if (blk_pc_request(rq) && !rq->errors) |
728 | rq->errors = SAM_STAT_CHECK_CONDITION; | 728 | rq->errors = SAM_STAT_CHECK_CONDITION; |
729 | 729 | ||
730 | /* Check for tray open. */ | 730 | /* Check for tray open. */ |
@@ -2023,7 +2023,8 @@ ide_do_rw_cdrom (ide_drive_t *drive, struct request *rq, sector_t block) | |||
2023 | } | 2023 | } |
2024 | info->last_block = block; | 2024 | info->last_block = block; |
2025 | return action; | 2025 | return action; |
2026 | } else if (rq->cmd_type == REQ_TYPE_SENSE) { | 2026 | } else if (rq->cmd_type == REQ_TYPE_SENSE || |
2027 | rq->cmd_type == REQ_TYPE_ATA_PC) { | ||
2027 | return cdrom_do_packet_command(drive); | 2028 | return cdrom_do_packet_command(drive); |
2028 | } else if (blk_pc_request(rq)) { | 2029 | } else if (blk_pc_request(rq)) { |
2029 | return cdrom_do_block_pc(drive, rq); | 2030 | return cdrom_do_block_pc(drive, rq); |
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index 1d0470c1f957..30175c7688e8 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c | |||
@@ -524,8 +524,8 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) | |||
524 | task_ioreg_t *hobsptr = args.hobRegister; | 524 | task_ioreg_t *hobsptr = args.hobRegister; |
525 | int err = 0; | 525 | int err = 0; |
526 | int tasksize = sizeof(struct ide_task_request_s); | 526 | int tasksize = sizeof(struct ide_task_request_s); |
527 | int taskin = 0; | 527 | unsigned int taskin = 0; |
528 | int taskout = 0; | 528 | unsigned int taskout = 0; |
529 | u8 io_32bit = drive->io_32bit; | 529 | u8 io_32bit = drive->io_32bit; |
530 | char __user *buf = (char __user *)arg; | 530 | char __user *buf = (char __user *)arg; |
531 | 531 | ||
@@ -538,8 +538,13 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) | |||
538 | return -EFAULT; | 538 | return -EFAULT; |
539 | } | 539 | } |
540 | 540 | ||
541 | taskout = (int) req_task->out_size; | 541 | taskout = req_task->out_size; |
542 | taskin = (int) req_task->in_size; | 542 | taskin = req_task->in_size; |
543 | |||
544 | if (taskin > 65536 || taskout > 65536) { | ||
545 | err = -EINVAL; | ||
546 | goto abort; | ||
547 | } | ||
543 | 548 | ||
544 | if (taskout) { | 549 | if (taskout) { |
545 | int outtotal = tasksize; | 550 | int outtotal = tasksize; |
diff --git a/drivers/ide/legacy/hd.c b/drivers/ide/legacy/hd.c index b1d5291531b7..45ed03591cd8 100644 --- a/drivers/ide/legacy/hd.c +++ b/drivers/ide/legacy/hd.c | |||
@@ -459,7 +459,7 @@ ok_to_read: | |||
459 | #ifdef DEBUG | 459 | #ifdef DEBUG |
460 | printk("%s: read: sector %ld, remaining = %ld, buffer=%p\n", | 460 | printk("%s: read: sector %ld, remaining = %ld, buffer=%p\n", |
461 | req->rq_disk->disk_name, req->sector, req->nr_sectors, | 461 | req->rq_disk->disk_name, req->sector, req->nr_sectors, |
462 | req->buffer+512)); | 462 | req->buffer+512); |
463 | #endif | 463 | #endif |
464 | if (req->current_nr_sectors <= 0) | 464 | if (req->current_nr_sectors <= 0) |
465 | end_request(req, 1); | 465 | end_request(req, 1); |
diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c index 2b0ea8b6608d..753fe0e21456 100644 --- a/drivers/ide/pci/amd74xx.c +++ b/drivers/ide/pci/amd74xx.c | |||
@@ -75,6 +75,7 @@ static struct amd_ide_chip { | |||
75 | { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, 0x50, AMD_UDMA_133 }, | 75 | { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, 0x50, AMD_UDMA_133 }, |
76 | { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE, 0x50, AMD_UDMA_133 }, | 76 | { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE, 0x50, AMD_UDMA_133 }, |
77 | { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE, 0x50, AMD_UDMA_133 }, | 77 | { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE, 0x50, AMD_UDMA_133 }, |
78 | { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE, 0x50, AMD_UDMA_133 }, | ||
78 | { PCI_DEVICE_ID_AMD_CS5536_IDE, 0x40, AMD_UDMA_100 }, | 79 | { PCI_DEVICE_ID_AMD_CS5536_IDE, 0x40, AMD_UDMA_100 }, |
79 | { 0 } | 80 | { 0 } |
80 | }; | 81 | }; |
@@ -491,7 +492,8 @@ static ide_pci_device_t amd74xx_chipsets[] __devinitdata = { | |||
491 | /* 16 */ DECLARE_NV_DEV("NFORCE-MCP55"), | 492 | /* 16 */ DECLARE_NV_DEV("NFORCE-MCP55"), |
492 | /* 17 */ DECLARE_NV_DEV("NFORCE-MCP61"), | 493 | /* 17 */ DECLARE_NV_DEV("NFORCE-MCP61"), |
493 | /* 18 */ DECLARE_NV_DEV("NFORCE-MCP65"), | 494 | /* 18 */ DECLARE_NV_DEV("NFORCE-MCP65"), |
494 | /* 19 */ DECLARE_AMD_DEV("AMD5536"), | 495 | /* 19 */ DECLARE_NV_DEV("NFORCE-MCP67"), |
496 | /* 20 */ DECLARE_AMD_DEV("AMD5536"), | ||
495 | }; | 497 | }; |
496 | 498 | ||
497 | static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id) | 499 | static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id) |
@@ -530,7 +532,8 @@ static struct pci_device_id amd74xx_pci_tbl[] = { | |||
530 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 16 }, | 532 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 16 }, |
531 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 17 }, | 533 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 17 }, |
532 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 18 }, | 534 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 18 }, |
533 | { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 19 }, | 535 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 19 }, |
536 | { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 20 }, | ||
534 | { 0, }, | 537 | { 0, }, |
535 | }; | 538 | }; |
536 | MODULE_DEVICE_TABLE(pci, amd74xx_pci_tbl); | 539 | MODULE_DEVICE_TABLE(pci, amd74xx_pci_tbl); |
diff --git a/drivers/ide/pci/generic.c b/drivers/ide/pci/generic.c index 965c43659e35..9f306880491a 100644 --- a/drivers/ide/pci/generic.c +++ b/drivers/ide/pci/generic.c | |||
@@ -40,6 +40,19 @@ | |||
40 | 40 | ||
41 | static int ide_generic_all; /* Set to claim all devices */ | 41 | static int ide_generic_all; /* Set to claim all devices */ |
42 | 42 | ||
43 | /* | ||
44 | * the module_param_named() was added for the modular case | ||
45 | * the __setup() is left as compatibility for existing setups | ||
46 | */ | ||
47 | #ifndef MODULE | ||
48 | static int __init ide_generic_all_on(char *unused) | ||
49 | { | ||
50 | ide_generic_all = 1; | ||
51 | printk(KERN_INFO "IDE generic will claim all unknown PCI IDE storage controllers.\n"); | ||
52 | return 1; | ||
53 | } | ||
54 | __setup("all-generic-ide", ide_generic_all_on); | ||
55 | #endif | ||
43 | module_param_named(all_generic_ide, ide_generic_all, bool, 0444); | 56 | module_param_named(all_generic_ide, ide_generic_all, bool, 0444); |
44 | MODULE_PARM_DESC(all_generic_ide, "IDE generic will claim all unknown PCI IDE storage controllers."); | 57 | MODULE_PARM_DESC(all_generic_ide, "IDE generic will claim all unknown PCI IDE storage controllers."); |
45 | 58 | ||
@@ -234,13 +247,17 @@ static int __devinit generic_init_one(struct pci_dev *dev, const struct pci_devi | |||
234 | (!(PCI_FUNC(dev->devfn) & 1))) | 247 | (!(PCI_FUNC(dev->devfn) & 1))) |
235 | goto out; | 248 | goto out; |
236 | 249 | ||
237 | if (dev->vendor == PCI_VENDOR_ID_JMICRON && PCI_FUNC(dev->devfn) != 1) | 250 | if (dev->vendor == PCI_VENDOR_ID_JMICRON) { |
238 | goto out; | 251 | if (dev->device != PCI_DEVICE_ID_JMICRON_JMB368 && PCI_FUNC(dev->devfn) != 1) |
252 | goto out; | ||
253 | } | ||
239 | 254 | ||
240 | pci_read_config_word(dev, PCI_COMMAND, &command); | 255 | if (dev->vendor != PCI_VENDOR_ID_JMICRON) { |
241 | if (!(command & PCI_COMMAND_IO)) { | 256 | pci_read_config_word(dev, PCI_COMMAND, &command); |
242 | printk(KERN_INFO "Skipping disabled %s IDE controller.\n", d->name); | 257 | if (!(command & PCI_COMMAND_IO)) { |
243 | goto out; | 258 | printk(KERN_INFO "Skipping disabled %s IDE controller.\n", d->name); |
259 | goto out; | ||
260 | } | ||
244 | } | 261 | } |
245 | ret = ide_setup_pci_device(dev, d); | 262 | ret = ide_setup_pci_device(dev, d); |
246 | out: | 263 | out: |
diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c index f3fe287fbd89..244f7eb7006d 100644 --- a/drivers/ide/pci/sgiioc4.c +++ b/drivers/ide/pci/sgiioc4.c | |||
@@ -774,7 +774,7 @@ ioc4_ide_exit(void) | |||
774 | ioc4_unregister_submodule(&ioc4_ide_submodule); | 774 | ioc4_unregister_submodule(&ioc4_ide_submodule); |
775 | } | 775 | } |
776 | 776 | ||
777 | module_init(ioc4_ide_init); | 777 | late_initcall(ioc4_ide_init); /* Call only after IDE init is done */ |
778 | module_exit(ioc4_ide_exit); | 778 | module_exit(ioc4_ide_exit); |
779 | 779 | ||
780 | MODULE_AUTHOR("Aniket Malatpure/Jeremy Higdon"); | 780 | MODULE_AUTHOR("Aniket Malatpure/Jeremy Higdon"); |
diff --git a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c index 8a7b8fab6238..31e5cc49d61a 100644 --- a/drivers/ieee1394/eth1394.c +++ b/drivers/ieee1394/eth1394.c | |||
@@ -64,6 +64,7 @@ | |||
64 | #include <linux/ethtool.h> | 64 | #include <linux/ethtool.h> |
65 | #include <asm/uaccess.h> | 65 | #include <asm/uaccess.h> |
66 | #include <asm/delay.h> | 66 | #include <asm/delay.h> |
67 | #include <asm/unaligned.h> | ||
67 | #include <net/arp.h> | 68 | #include <net/arp.h> |
68 | 69 | ||
69 | #include "config_roms.h" | 70 | #include "config_roms.h" |
@@ -491,7 +492,7 @@ static void ether1394_reset_priv (struct net_device *dev, int set_mtu) | |||
491 | int i; | 492 | int i; |
492 | struct eth1394_priv *priv = netdev_priv(dev); | 493 | struct eth1394_priv *priv = netdev_priv(dev); |
493 | struct hpsb_host *host = priv->host; | 494 | struct hpsb_host *host = priv->host; |
494 | u64 guid = *((u64*)&(host->csr.rom->bus_info_data[3])); | 495 | u64 guid = get_unaligned((u64*)&(host->csr.rom->bus_info_data[3])); |
495 | u16 maxpayload = 1 << (host->csr.max_rec + 1); | 496 | u16 maxpayload = 1 << (host->csr.max_rec + 1); |
496 | int max_speed = IEEE1394_SPEED_MAX; | 497 | int max_speed = IEEE1394_SPEED_MAX; |
497 | 498 | ||
@@ -514,8 +515,8 @@ static void ether1394_reset_priv (struct net_device *dev, int set_mtu) | |||
514 | ETHER1394_GASP_OVERHEAD))); | 515 | ETHER1394_GASP_OVERHEAD))); |
515 | 516 | ||
516 | /* Set our hardware address while we're at it */ | 517 | /* Set our hardware address while we're at it */ |
517 | *(u64*)dev->dev_addr = guid; | 518 | memcpy(dev->dev_addr, &guid, sizeof(u64)); |
518 | *(u64*)dev->broadcast = ~0x0ULL; | 519 | memset(dev->broadcast, 0xff, sizeof(u64)); |
519 | } | 520 | } |
520 | 521 | ||
521 | spin_unlock_irqrestore (&priv->lock, flags); | 522 | spin_unlock_irqrestore (&priv->lock, flags); |
@@ -894,6 +895,7 @@ static inline u16 ether1394_parse_encap(struct sk_buff *skb, | |||
894 | u16 maxpayload; | 895 | u16 maxpayload; |
895 | struct eth1394_node_ref *node; | 896 | struct eth1394_node_ref *node; |
896 | struct eth1394_node_info *node_info; | 897 | struct eth1394_node_info *node_info; |
898 | __be64 guid; | ||
897 | 899 | ||
898 | /* Sanity check. MacOSX seems to be sending us 131 in this | 900 | /* Sanity check. MacOSX seems to be sending us 131 in this |
899 | * field (atleast on my Panther G5). Not sure why. */ | 901 | * field (atleast on my Panther G5). Not sure why. */ |
@@ -902,8 +904,9 @@ static inline u16 ether1394_parse_encap(struct sk_buff *skb, | |||
902 | 904 | ||
903 | maxpayload = min(eth1394_speedto_maxpayload[sspd], (u16)(1 << (max_rec + 1))); | 905 | maxpayload = min(eth1394_speedto_maxpayload[sspd], (u16)(1 << (max_rec + 1))); |
904 | 906 | ||
907 | guid = get_unaligned(&arp1394->s_uniq_id); | ||
905 | node = eth1394_find_node_guid(&priv->ip_node_list, | 908 | node = eth1394_find_node_guid(&priv->ip_node_list, |
906 | be64_to_cpu(arp1394->s_uniq_id)); | 909 | be64_to_cpu(guid)); |
907 | if (!node) { | 910 | if (!node) { |
908 | return 0; | 911 | return 0; |
909 | } | 912 | } |
@@ -931,10 +934,9 @@ static inline u16 ether1394_parse_encap(struct sk_buff *skb, | |||
931 | arp_ptr += arp->ar_pln; /* skip over sender IP addr */ | 934 | arp_ptr += arp->ar_pln; /* skip over sender IP addr */ |
932 | 935 | ||
933 | if (arp->ar_op == htons(ARPOP_REQUEST)) | 936 | if (arp->ar_op == htons(ARPOP_REQUEST)) |
934 | /* just set ARP req target unique ID to 0 */ | 937 | memset(arp_ptr, 0, sizeof(u64)); |
935 | *((u64*)arp_ptr) = 0; | ||
936 | else | 938 | else |
937 | *((u64*)arp_ptr) = *((u64*)dev->dev_addr); | 939 | memcpy(arp_ptr, dev->dev_addr, sizeof(u64)); |
938 | } | 940 | } |
939 | 941 | ||
940 | /* Now add the ethernet header. */ | 942 | /* Now add the ethernet header. */ |
@@ -1675,8 +1677,10 @@ static int ether1394_tx (struct sk_buff *skb, struct net_device *dev) | |||
1675 | if (max_payload < dg_size + hdr_type_len[ETH1394_HDR_LF_UF]) | 1677 | if (max_payload < dg_size + hdr_type_len[ETH1394_HDR_LF_UF]) |
1676 | priv->bc_dgl++; | 1678 | priv->bc_dgl++; |
1677 | } else { | 1679 | } else { |
1680 | __be64 guid = get_unaligned((u64 *)eth->h_dest); | ||
1681 | |||
1678 | node = eth1394_find_node_guid(&priv->ip_node_list, | 1682 | node = eth1394_find_node_guid(&priv->ip_node_list, |
1679 | be64_to_cpu(*(u64*)eth->h_dest)); | 1683 | be64_to_cpu(guid)); |
1680 | if (!node) { | 1684 | if (!node) { |
1681 | ret = -EAGAIN; | 1685 | ret = -EAGAIN; |
1682 | goto fail; | 1686 | goto fail; |
diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c index dea13525df88..6e8ea9110c46 100644 --- a/drivers/ieee1394/ohci1394.c +++ b/drivers/ieee1394/ohci1394.c | |||
@@ -3552,12 +3552,21 @@ static int ohci1394_pci_suspend (struct pci_dev *pdev, pm_message_t state) | |||
3552 | { | 3552 | { |
3553 | int err; | 3553 | int err; |
3554 | 3554 | ||
3555 | printk(KERN_INFO "%s does not fully support suspend and resume yet\n", | ||
3556 | OHCI1394_DRIVER_NAME); | ||
3557 | |||
3555 | err = pci_save_state(pdev); | 3558 | err = pci_save_state(pdev); |
3556 | if (err) | 3559 | if (err) { |
3557 | goto out; | 3560 | printk(KERN_ERR "%s: pci_save_state failed with %d\n", |
3561 | OHCI1394_DRIVER_NAME, err); | ||
3562 | return err; | ||
3563 | } | ||
3558 | err = pci_set_power_state(pdev, pci_choose_state(pdev, state)); | 3564 | err = pci_set_power_state(pdev, pci_choose_state(pdev, state)); |
3565 | #ifdef OHCI1394_DEBUG | ||
3559 | if (err) | 3566 | if (err) |
3560 | goto out; | 3567 | printk(KERN_DEBUG "%s: pci_set_power_state failed with %d\n", |
3568 | OHCI1394_DRIVER_NAME, err); | ||
3569 | #endif /* OHCI1394_DEBUG */ | ||
3561 | 3570 | ||
3562 | /* PowerMac suspend code comes last */ | 3571 | /* PowerMac suspend code comes last */ |
3563 | #ifdef CONFIG_PPC_PMAC | 3572 | #ifdef CONFIG_PPC_PMAC |
@@ -3570,8 +3579,8 @@ static int ohci1394_pci_suspend (struct pci_dev *pdev, pm_message_t state) | |||
3570 | pmac_call_feature(PMAC_FTR_1394_ENABLE, of_node, 0, 0); | 3579 | pmac_call_feature(PMAC_FTR_1394_ENABLE, of_node, 0, 0); |
3571 | } | 3580 | } |
3572 | #endif /* CONFIG_PPC_PMAC */ | 3581 | #endif /* CONFIG_PPC_PMAC */ |
3573 | out: | 3582 | |
3574 | return err; | 3583 | return 0; |
3575 | } | 3584 | } |
3576 | #endif /* CONFIG_PM */ | 3585 | #endif /* CONFIG_PM */ |
3577 | 3586 | ||
diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c index 60d3fbdd216c..e11187ecc931 100644 --- a/drivers/infiniband/core/addr.c +++ b/drivers/infiniband/core/addr.c | |||
@@ -47,6 +47,7 @@ struct addr_req { | |||
47 | struct sockaddr src_addr; | 47 | struct sockaddr src_addr; |
48 | struct sockaddr dst_addr; | 48 | struct sockaddr dst_addr; |
49 | struct rdma_dev_addr *addr; | 49 | struct rdma_dev_addr *addr; |
50 | struct rdma_addr_client *client; | ||
50 | void *context; | 51 | void *context; |
51 | void (*callback)(int status, struct sockaddr *src_addr, | 52 | void (*callback)(int status, struct sockaddr *src_addr, |
52 | struct rdma_dev_addr *addr, void *context); | 53 | struct rdma_dev_addr *addr, void *context); |
@@ -61,6 +62,26 @@ static LIST_HEAD(req_list); | |||
61 | static DECLARE_WORK(work, process_req, NULL); | 62 | static DECLARE_WORK(work, process_req, NULL); |
62 | static struct workqueue_struct *addr_wq; | 63 | static struct workqueue_struct *addr_wq; |
63 | 64 | ||
65 | void rdma_addr_register_client(struct rdma_addr_client *client) | ||
66 | { | ||
67 | atomic_set(&client->refcount, 1); | ||
68 | init_completion(&client->comp); | ||
69 | } | ||
70 | EXPORT_SYMBOL(rdma_addr_register_client); | ||
71 | |||
72 | static inline void put_client(struct rdma_addr_client *client) | ||
73 | { | ||
74 | if (atomic_dec_and_test(&client->refcount)) | ||
75 | complete(&client->comp); | ||
76 | } | ||
77 | |||
78 | void rdma_addr_unregister_client(struct rdma_addr_client *client) | ||
79 | { | ||
80 | put_client(client); | ||
81 | wait_for_completion(&client->comp); | ||
82 | } | ||
83 | EXPORT_SYMBOL(rdma_addr_unregister_client); | ||
84 | |||
64 | int rdma_copy_addr(struct rdma_dev_addr *dev_addr, struct net_device *dev, | 85 | int rdma_copy_addr(struct rdma_dev_addr *dev_addr, struct net_device *dev, |
65 | const unsigned char *dst_dev_addr) | 86 | const unsigned char *dst_dev_addr) |
66 | { | 87 | { |
@@ -229,6 +250,7 @@ static void process_req(void *data) | |||
229 | list_del(&req->list); | 250 | list_del(&req->list); |
230 | req->callback(req->status, &req->src_addr, req->addr, | 251 | req->callback(req->status, &req->src_addr, req->addr, |
231 | req->context); | 252 | req->context); |
253 | put_client(req->client); | ||
232 | kfree(req); | 254 | kfree(req); |
233 | } | 255 | } |
234 | } | 256 | } |
@@ -264,7 +286,8 @@ static int addr_resolve_local(struct sockaddr_in *src_in, | |||
264 | return ret; | 286 | return ret; |
265 | } | 287 | } |
266 | 288 | ||
267 | int rdma_resolve_ip(struct sockaddr *src_addr, struct sockaddr *dst_addr, | 289 | int rdma_resolve_ip(struct rdma_addr_client *client, |
290 | struct sockaddr *src_addr, struct sockaddr *dst_addr, | ||
268 | struct rdma_dev_addr *addr, int timeout_ms, | 291 | struct rdma_dev_addr *addr, int timeout_ms, |
269 | void (*callback)(int status, struct sockaddr *src_addr, | 292 | void (*callback)(int status, struct sockaddr *src_addr, |
270 | struct rdma_dev_addr *addr, void *context), | 293 | struct rdma_dev_addr *addr, void *context), |
@@ -285,6 +308,8 @@ int rdma_resolve_ip(struct sockaddr *src_addr, struct sockaddr *dst_addr, | |||
285 | req->addr = addr; | 308 | req->addr = addr; |
286 | req->callback = callback; | 309 | req->callback = callback; |
287 | req->context = context; | 310 | req->context = context; |
311 | req->client = client; | ||
312 | atomic_inc(&client->refcount); | ||
288 | 313 | ||
289 | src_in = (struct sockaddr_in *) &req->src_addr; | 314 | src_in = (struct sockaddr_in *) &req->src_addr; |
290 | dst_in = (struct sockaddr_in *) &req->dst_addr; | 315 | dst_in = (struct sockaddr_in *) &req->dst_addr; |
@@ -305,6 +330,7 @@ int rdma_resolve_ip(struct sockaddr *src_addr, struct sockaddr *dst_addr, | |||
305 | break; | 330 | break; |
306 | default: | 331 | default: |
307 | ret = req->status; | 332 | ret = req->status; |
333 | atomic_dec(&client->refcount); | ||
308 | kfree(req); | 334 | kfree(req); |
309 | break; | 335 | break; |
310 | } | 336 | } |
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index 9ae4f3a67c70..845090b0859c 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c | |||
@@ -63,6 +63,7 @@ static struct ib_client cma_client = { | |||
63 | }; | 63 | }; |
64 | 64 | ||
65 | static struct ib_sa_client sa_client; | 65 | static struct ib_sa_client sa_client; |
66 | static struct rdma_addr_client addr_client; | ||
66 | static LIST_HEAD(dev_list); | 67 | static LIST_HEAD(dev_list); |
67 | static LIST_HEAD(listen_any_list); | 68 | static LIST_HEAD(listen_any_list); |
68 | static DEFINE_MUTEX(lock); | 69 | static DEFINE_MUTEX(lock); |
@@ -1625,8 +1626,8 @@ int rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr, | |||
1625 | if (cma_any_addr(dst_addr)) | 1626 | if (cma_any_addr(dst_addr)) |
1626 | ret = cma_resolve_loopback(id_priv); | 1627 | ret = cma_resolve_loopback(id_priv); |
1627 | else | 1628 | else |
1628 | ret = rdma_resolve_ip(&id->route.addr.src_addr, dst_addr, | 1629 | ret = rdma_resolve_ip(&addr_client, &id->route.addr.src_addr, |
1629 | &id->route.addr.dev_addr, | 1630 | dst_addr, &id->route.addr.dev_addr, |
1630 | timeout_ms, addr_handler, id_priv); | 1631 | timeout_ms, addr_handler, id_priv); |
1631 | if (ret) | 1632 | if (ret) |
1632 | goto err; | 1633 | goto err; |
@@ -1762,22 +1763,29 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr) | |||
1762 | 1763 | ||
1763 | if (!cma_any_addr(addr)) { | 1764 | if (!cma_any_addr(addr)) { |
1764 | ret = rdma_translate_ip(addr, &id->route.addr.dev_addr); | 1765 | ret = rdma_translate_ip(addr, &id->route.addr.dev_addr); |
1765 | if (!ret) { | ||
1766 | mutex_lock(&lock); | ||
1767 | ret = cma_acquire_dev(id_priv); | ||
1768 | mutex_unlock(&lock); | ||
1769 | } | ||
1770 | if (ret) | 1766 | if (ret) |
1771 | goto err; | 1767 | goto err1; |
1768 | |||
1769 | mutex_lock(&lock); | ||
1770 | ret = cma_acquire_dev(id_priv); | ||
1771 | mutex_unlock(&lock); | ||
1772 | if (ret) | ||
1773 | goto err1; | ||
1772 | } | 1774 | } |
1773 | 1775 | ||
1774 | memcpy(&id->route.addr.src_addr, addr, ip_addr_size(addr)); | 1776 | memcpy(&id->route.addr.src_addr, addr, ip_addr_size(addr)); |
1775 | ret = cma_get_port(id_priv); | 1777 | ret = cma_get_port(id_priv); |
1776 | if (ret) | 1778 | if (ret) |
1777 | goto err; | 1779 | goto err2; |
1778 | 1780 | ||
1779 | return 0; | 1781 | return 0; |
1780 | err: | 1782 | err2: |
1783 | if (!cma_any_addr(addr)) { | ||
1784 | mutex_lock(&lock); | ||
1785 | cma_detach_from_dev(id_priv); | ||
1786 | mutex_unlock(&lock); | ||
1787 | } | ||
1788 | err1: | ||
1781 | cma_comp_exch(id_priv, CMA_ADDR_BOUND, CMA_IDLE); | 1789 | cma_comp_exch(id_priv, CMA_ADDR_BOUND, CMA_IDLE); |
1782 | return ret; | 1790 | return ret; |
1783 | } | 1791 | } |
@@ -2210,6 +2218,7 @@ static int cma_init(void) | |||
2210 | return -ENOMEM; | 2218 | return -ENOMEM; |
2211 | 2219 | ||
2212 | ib_sa_register_client(&sa_client); | 2220 | ib_sa_register_client(&sa_client); |
2221 | rdma_addr_register_client(&addr_client); | ||
2213 | 2222 | ||
2214 | ret = ib_register_client(&cma_client); | 2223 | ret = ib_register_client(&cma_client); |
2215 | if (ret) | 2224 | if (ret) |
@@ -2217,6 +2226,7 @@ static int cma_init(void) | |||
2217 | return 0; | 2226 | return 0; |
2218 | 2227 | ||
2219 | err: | 2228 | err: |
2229 | rdma_addr_unregister_client(&addr_client); | ||
2220 | ib_sa_unregister_client(&sa_client); | 2230 | ib_sa_unregister_client(&sa_client); |
2221 | destroy_workqueue(cma_wq); | 2231 | destroy_workqueue(cma_wq); |
2222 | return ret; | 2232 | return ret; |
@@ -2225,6 +2235,7 @@ err: | |||
2225 | static void cma_cleanup(void) | 2235 | static void cma_cleanup(void) |
2226 | { | 2236 | { |
2227 | ib_unregister_client(&cma_client); | 2237 | ib_unregister_client(&cma_client); |
2238 | rdma_addr_unregister_client(&addr_client); | ||
2228 | ib_sa_unregister_client(&sa_client); | 2239 | ib_sa_unregister_client(&sa_client); |
2229 | destroy_workqueue(cma_wq); | 2240 | destroy_workqueue(cma_wq); |
2230 | idr_destroy(&sdp_ps); | 2241 | idr_destroy(&sdp_ps); |
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c index 493f4c65c7a2..a72bcea46ff6 100644 --- a/drivers/infiniband/core/mad.c +++ b/drivers/infiniband/core/mad.c | |||
@@ -1750,7 +1750,7 @@ ib_find_send_mad(struct ib_mad_agent_private *mad_agent_priv, | |||
1750 | */ | 1750 | */ |
1751 | (is_direct(wc->recv_buf.mad->mad_hdr.mgmt_class) || | 1751 | (is_direct(wc->recv_buf.mad->mad_hdr.mgmt_class) || |
1752 | rcv_has_same_gid(mad_agent_priv, wr, wc))) | 1752 | rcv_has_same_gid(mad_agent_priv, wr, wc))) |
1753 | return wr; | 1753 | return (wr->status == IB_WC_SUCCESS) ? wr : NULL; |
1754 | } | 1754 | } |
1755 | 1755 | ||
1756 | /* | 1756 | /* |
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index b72c7f69ca90..743247ec065e 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c | |||
@@ -1214,7 +1214,7 @@ ssize_t ib_uverbs_query_qp(struct ib_uverbs_file *file, | |||
1214 | resp.qp_access_flags = attr->qp_access_flags; | 1214 | resp.qp_access_flags = attr->qp_access_flags; |
1215 | resp.pkey_index = attr->pkey_index; | 1215 | resp.pkey_index = attr->pkey_index; |
1216 | resp.alt_pkey_index = attr->alt_pkey_index; | 1216 | resp.alt_pkey_index = attr->alt_pkey_index; |
1217 | resp.en_sqd_async_notify = attr->en_sqd_async_notify; | 1217 | resp.sq_draining = attr->sq_draining; |
1218 | resp.max_rd_atomic = attr->max_rd_atomic; | 1218 | resp.max_rd_atomic = attr->max_rd_atomic; |
1219 | resp.max_dest_rd_atomic = attr->max_dest_rd_atomic; | 1219 | resp.max_dest_rd_atomic = attr->max_dest_rd_atomic; |
1220 | resp.min_rnr_timer = attr->min_rnr_timer; | 1220 | resp.min_rnr_timer = attr->min_rnr_timer; |
diff --git a/drivers/infiniband/hw/amso1100/c2.c b/drivers/infiniband/hw/amso1100/c2.c index dc1ebeac35c7..27fe242ed435 100644 --- a/drivers/infiniband/hw/amso1100/c2.c +++ b/drivers/infiniband/hw/amso1100/c2.c | |||
@@ -1155,7 +1155,8 @@ static int __devinit c2_probe(struct pci_dev *pcidev, | |||
1155 | goto bail10; | 1155 | goto bail10; |
1156 | } | 1156 | } |
1157 | 1157 | ||
1158 | c2_register_device(c2dev); | 1158 | if (c2_register_device(c2dev)) |
1159 | goto bail10; | ||
1159 | 1160 | ||
1160 | return 0; | 1161 | return 0; |
1161 | 1162 | ||
@@ -1243,7 +1244,7 @@ static struct pci_driver c2_pci_driver = { | |||
1243 | 1244 | ||
1244 | static int __init c2_init_module(void) | 1245 | static int __init c2_init_module(void) |
1245 | { | 1246 | { |
1246 | return pci_module_init(&c2_pci_driver); | 1247 | return pci_register_driver(&c2_pci_driver); |
1247 | } | 1248 | } |
1248 | 1249 | ||
1249 | static void __exit c2_exit_module(void) | 1250 | static void __exit c2_exit_module(void) |
diff --git a/drivers/infiniband/hw/amso1100/c2_alloc.c b/drivers/infiniband/hw/amso1100/c2_alloc.c index 028a60bbfca9..0315f99e4191 100644 --- a/drivers/infiniband/hw/amso1100/c2_alloc.c +++ b/drivers/infiniband/hw/amso1100/c2_alloc.c | |||
@@ -42,13 +42,14 @@ static int c2_alloc_mqsp_chunk(struct c2_dev *c2dev, gfp_t gfp_mask, | |||
42 | { | 42 | { |
43 | int i; | 43 | int i; |
44 | struct sp_chunk *new_head; | 44 | struct sp_chunk *new_head; |
45 | dma_addr_t dma_addr; | ||
45 | 46 | ||
46 | new_head = (struct sp_chunk *) __get_free_page(gfp_mask); | 47 | new_head = dma_alloc_coherent(&c2dev->pcidev->dev, PAGE_SIZE, |
48 | &dma_addr, gfp_mask); | ||
47 | if (new_head == NULL) | 49 | if (new_head == NULL) |
48 | return -ENOMEM; | 50 | return -ENOMEM; |
49 | 51 | ||
50 | new_head->dma_addr = dma_map_single(c2dev->ibdev.dma_device, new_head, | 52 | new_head->dma_addr = dma_addr; |
51 | PAGE_SIZE, DMA_FROM_DEVICE); | ||
52 | pci_unmap_addr_set(new_head, mapping, new_head->dma_addr); | 53 | pci_unmap_addr_set(new_head, mapping, new_head->dma_addr); |
53 | 54 | ||
54 | new_head->next = NULL; | 55 | new_head->next = NULL; |
@@ -80,10 +81,8 @@ void c2_free_mqsp_pool(struct c2_dev *c2dev, struct sp_chunk *root) | |||
80 | 81 | ||
81 | while (root) { | 82 | while (root) { |
82 | next = root->next; | 83 | next = root->next; |
83 | dma_unmap_single(c2dev->ibdev.dma_device, | 84 | dma_free_coherent(&c2dev->pcidev->dev, PAGE_SIZE, root, |
84 | pci_unmap_addr(root, mapping), PAGE_SIZE, | 85 | pci_unmap_addr(root, mapping)); |
85 | DMA_FROM_DEVICE); | ||
86 | __free_page((struct page *) root); | ||
87 | root = next; | 86 | root = next; |
88 | } | 87 | } |
89 | } | 88 | } |
diff --git a/drivers/infiniband/hw/amso1100/c2_cq.c b/drivers/infiniband/hw/amso1100/c2_cq.c index 9d7bcc5ade93..05c9154d46f4 100644 --- a/drivers/infiniband/hw/amso1100/c2_cq.c +++ b/drivers/infiniband/hw/amso1100/c2_cq.c | |||
@@ -246,20 +246,17 @@ int c2_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify notify) | |||
246 | 246 | ||
247 | static void c2_free_cq_buf(struct c2_dev *c2dev, struct c2_mq *mq) | 247 | static void c2_free_cq_buf(struct c2_dev *c2dev, struct c2_mq *mq) |
248 | { | 248 | { |
249 | 249 | dma_free_coherent(&c2dev->pcidev->dev, mq->q_size * mq->msg_size, | |
250 | dma_unmap_single(c2dev->ibdev.dma_device, pci_unmap_addr(mq, mapping), | 250 | mq->msg_pool.host, pci_unmap_addr(mq, mapping)); |
251 | mq->q_size * mq->msg_size, DMA_FROM_DEVICE); | ||
252 | free_pages((unsigned long) mq->msg_pool.host, | ||
253 | get_order(mq->q_size * mq->msg_size)); | ||
254 | } | 251 | } |
255 | 252 | ||
256 | static int c2_alloc_cq_buf(struct c2_dev *c2dev, struct c2_mq *mq, int q_size, | 253 | static int c2_alloc_cq_buf(struct c2_dev *c2dev, struct c2_mq *mq, int q_size, |
257 | int msg_size) | 254 | int msg_size) |
258 | { | 255 | { |
259 | unsigned long pool_start; | 256 | u8 *pool_start; |
260 | 257 | ||
261 | pool_start = __get_free_pages(GFP_KERNEL, | 258 | pool_start = dma_alloc_coherent(&c2dev->pcidev->dev, q_size * msg_size, |
262 | get_order(q_size * msg_size)); | 259 | &mq->host_dma, GFP_KERNEL); |
263 | if (!pool_start) | 260 | if (!pool_start) |
264 | return -ENOMEM; | 261 | return -ENOMEM; |
265 | 262 | ||
@@ -267,13 +264,10 @@ static int c2_alloc_cq_buf(struct c2_dev *c2dev, struct c2_mq *mq, int q_size, | |||
267 | 0, /* index (currently unknown) */ | 264 | 0, /* index (currently unknown) */ |
268 | q_size, | 265 | q_size, |
269 | msg_size, | 266 | msg_size, |
270 | (u8 *) pool_start, | 267 | pool_start, |
271 | NULL, /* peer (currently unknown) */ | 268 | NULL, /* peer (currently unknown) */ |
272 | C2_MQ_HOST_TARGET); | 269 | C2_MQ_HOST_TARGET); |
273 | 270 | ||
274 | mq->host_dma = dma_map_single(c2dev->ibdev.dma_device, | ||
275 | (void *)pool_start, | ||
276 | q_size * msg_size, DMA_FROM_DEVICE); | ||
277 | pci_unmap_addr_set(mq, mapping, mq->host_dma); | 271 | pci_unmap_addr_set(mq, mapping, mq->host_dma); |
278 | 272 | ||
279 | return 0; | 273 | return 0; |
diff --git a/drivers/infiniband/hw/amso1100/c2_provider.c b/drivers/infiniband/hw/amso1100/c2_provider.c index da98d9f71429..fef972752912 100644 --- a/drivers/infiniband/hw/amso1100/c2_provider.c +++ b/drivers/infiniband/hw/amso1100/c2_provider.c | |||
@@ -757,20 +757,17 @@ static struct net_device *c2_pseudo_netdev_init(struct c2_dev *c2dev) | |||
757 | 757 | ||
758 | int c2_register_device(struct c2_dev *dev) | 758 | int c2_register_device(struct c2_dev *dev) |
759 | { | 759 | { |
760 | int ret; | 760 | int ret = -ENOMEM; |
761 | int i; | 761 | int i; |
762 | 762 | ||
763 | /* Register pseudo network device */ | 763 | /* Register pseudo network device */ |
764 | dev->pseudo_netdev = c2_pseudo_netdev_init(dev); | 764 | dev->pseudo_netdev = c2_pseudo_netdev_init(dev); |
765 | if (dev->pseudo_netdev) { | 765 | if (!dev->pseudo_netdev) |
766 | ret = register_netdev(dev->pseudo_netdev); | 766 | goto out3; |
767 | if (ret) { | 767 | |
768 | printk(KERN_ERR PFX | 768 | ret = register_netdev(dev->pseudo_netdev); |
769 | "Unable to register netdev, ret = %d\n", ret); | 769 | if (ret) |
770 | free_netdev(dev->pseudo_netdev); | 770 | goto out2; |
771 | return ret; | ||
772 | } | ||
773 | } | ||
774 | 771 | ||
775 | pr_debug("%s:%u\n", __FUNCTION__, __LINE__); | 772 | pr_debug("%s:%u\n", __FUNCTION__, __LINE__); |
776 | strlcpy(dev->ibdev.name, "amso%d", IB_DEVICE_NAME_MAX); | 773 | strlcpy(dev->ibdev.name, "amso%d", IB_DEVICE_NAME_MAX); |
@@ -848,21 +845,25 @@ int c2_register_device(struct c2_dev *dev) | |||
848 | 845 | ||
849 | ret = ib_register_device(&dev->ibdev); | 846 | ret = ib_register_device(&dev->ibdev); |
850 | if (ret) | 847 | if (ret) |
851 | return ret; | 848 | goto out1; |
852 | 849 | ||
853 | for (i = 0; i < ARRAY_SIZE(c2_class_attributes); ++i) { | 850 | for (i = 0; i < ARRAY_SIZE(c2_class_attributes); ++i) { |
854 | ret = class_device_create_file(&dev->ibdev.class_dev, | 851 | ret = class_device_create_file(&dev->ibdev.class_dev, |
855 | c2_class_attributes[i]); | 852 | c2_class_attributes[i]); |
856 | if (ret) { | 853 | if (ret) |
857 | unregister_netdev(dev->pseudo_netdev); | 854 | goto out0; |
858 | free_netdev(dev->pseudo_netdev); | ||
859 | ib_unregister_device(&dev->ibdev); | ||
860 | return ret; | ||
861 | } | ||
862 | } | 855 | } |
856 | goto out3; | ||
863 | 857 | ||
864 | pr_debug("%s:%u\n", __FUNCTION__, __LINE__); | 858 | out0: |
865 | return 0; | 859 | ib_unregister_device(&dev->ibdev); |
860 | out1: | ||
861 | unregister_netdev(dev->pseudo_netdev); | ||
862 | out2: | ||
863 | free_netdev(dev->pseudo_netdev); | ||
864 | out3: | ||
865 | pr_debug("%s:%u ret=%d\n", __FUNCTION__, __LINE__, ret); | ||
866 | return ret; | ||
866 | } | 867 | } |
867 | 868 | ||
868 | void c2_unregister_device(struct c2_dev *dev) | 869 | void c2_unregister_device(struct c2_dev *dev) |
diff --git a/drivers/infiniband/hw/amso1100/c2_rnic.c b/drivers/infiniband/hw/amso1100/c2_rnic.c index e37c5688c214..623dc95f91df 100644 --- a/drivers/infiniband/hw/amso1100/c2_rnic.c +++ b/drivers/infiniband/hw/amso1100/c2_rnic.c | |||
@@ -150,15 +150,15 @@ static int c2_rnic_query(struct c2_dev *c2dev, struct ib_device_attr *props) | |||
150 | (struct c2wr_rnic_query_rep *) (unsigned long) (vq_req->reply_msg); | 150 | (struct c2wr_rnic_query_rep *) (unsigned long) (vq_req->reply_msg); |
151 | if (!reply) | 151 | if (!reply) |
152 | err = -ENOMEM; | 152 | err = -ENOMEM; |
153 | 153 | else | |
154 | err = c2_errno(reply); | 154 | err = c2_errno(reply); |
155 | if (err) | 155 | if (err) |
156 | goto bail2; | 156 | goto bail2; |
157 | 157 | ||
158 | props->fw_ver = | 158 | props->fw_ver = |
159 | ((u64)be32_to_cpu(reply->fw_ver_major) << 32) | | 159 | ((u64)be32_to_cpu(reply->fw_ver_major) << 32) | |
160 | ((be32_to_cpu(reply->fw_ver_minor) && 0xFFFF) << 16) | | 160 | ((be32_to_cpu(reply->fw_ver_minor) & 0xFFFF) << 16) | |
161 | (be32_to_cpu(reply->fw_ver_patch) && 0xFFFF); | 161 | (be32_to_cpu(reply->fw_ver_patch) & 0xFFFF); |
162 | memcpy(&props->sys_image_guid, c2dev->netdev->dev_addr, 6); | 162 | memcpy(&props->sys_image_guid, c2dev->netdev->dev_addr, 6); |
163 | props->max_mr_size = 0xFFFFFFFF; | 163 | props->max_mr_size = 0xFFFFFFFF; |
164 | props->page_size_cap = ~(C2_MIN_PAGESIZE-1); | 164 | props->page_size_cap = ~(C2_MIN_PAGESIZE-1); |
@@ -517,14 +517,12 @@ int c2_rnic_init(struct c2_dev *c2dev) | |||
517 | /* Initialize the Verbs Reply Queue */ | 517 | /* Initialize the Verbs Reply Queue */ |
518 | qsize = be32_to_cpu(readl(mmio_regs + C2_REGS_Q1_QSIZE)); | 518 | qsize = be32_to_cpu(readl(mmio_regs + C2_REGS_Q1_QSIZE)); |
519 | msgsize = be32_to_cpu(readl(mmio_regs + C2_REGS_Q1_MSGSIZE)); | 519 | msgsize = be32_to_cpu(readl(mmio_regs + C2_REGS_Q1_MSGSIZE)); |
520 | q1_pages = kmalloc(qsize * msgsize, GFP_KERNEL); | 520 | q1_pages = dma_alloc_coherent(&c2dev->pcidev->dev, qsize * msgsize, |
521 | &c2dev->rep_vq.host_dma, GFP_KERNEL); | ||
521 | if (!q1_pages) { | 522 | if (!q1_pages) { |
522 | err = -ENOMEM; | 523 | err = -ENOMEM; |
523 | goto bail1; | 524 | goto bail1; |
524 | } | 525 | } |
525 | c2dev->rep_vq.host_dma = dma_map_single(c2dev->ibdev.dma_device, | ||
526 | (void *)q1_pages, qsize * msgsize, | ||
527 | DMA_FROM_DEVICE); | ||
528 | pci_unmap_addr_set(&c2dev->rep_vq, mapping, c2dev->rep_vq.host_dma); | 526 | pci_unmap_addr_set(&c2dev->rep_vq, mapping, c2dev->rep_vq.host_dma); |
529 | pr_debug("%s rep_vq va %p dma %llx\n", __FUNCTION__, q1_pages, | 527 | pr_debug("%s rep_vq va %p dma %llx\n", __FUNCTION__, q1_pages, |
530 | (unsigned long long) c2dev->rep_vq.host_dma); | 528 | (unsigned long long) c2dev->rep_vq.host_dma); |
@@ -540,17 +538,15 @@ int c2_rnic_init(struct c2_dev *c2dev) | |||
540 | /* Initialize the Asynchronus Event Queue */ | 538 | /* Initialize the Asynchronus Event Queue */ |
541 | qsize = be32_to_cpu(readl(mmio_regs + C2_REGS_Q2_QSIZE)); | 539 | qsize = be32_to_cpu(readl(mmio_regs + C2_REGS_Q2_QSIZE)); |
542 | msgsize = be32_to_cpu(readl(mmio_regs + C2_REGS_Q2_MSGSIZE)); | 540 | msgsize = be32_to_cpu(readl(mmio_regs + C2_REGS_Q2_MSGSIZE)); |
543 | q2_pages = kmalloc(qsize * msgsize, GFP_KERNEL); | 541 | q2_pages = dma_alloc_coherent(&c2dev->pcidev->dev, qsize * msgsize, |
542 | &c2dev->aeq.host_dma, GFP_KERNEL); | ||
544 | if (!q2_pages) { | 543 | if (!q2_pages) { |
545 | err = -ENOMEM; | 544 | err = -ENOMEM; |
546 | goto bail2; | 545 | goto bail2; |
547 | } | 546 | } |
548 | c2dev->aeq.host_dma = dma_map_single(c2dev->ibdev.dma_device, | ||
549 | (void *)q2_pages, qsize * msgsize, | ||
550 | DMA_FROM_DEVICE); | ||
551 | pci_unmap_addr_set(&c2dev->aeq, mapping, c2dev->aeq.host_dma); | 547 | pci_unmap_addr_set(&c2dev->aeq, mapping, c2dev->aeq.host_dma); |
552 | pr_debug("%s aeq va %p dma %llx\n", __FUNCTION__, q1_pages, | 548 | pr_debug("%s aeq va %p dma %llx\n", __FUNCTION__, q2_pages, |
553 | (unsigned long long) c2dev->rep_vq.host_dma); | 549 | (unsigned long long) c2dev->aeq.host_dma); |
554 | c2_mq_rep_init(&c2dev->aeq, | 550 | c2_mq_rep_init(&c2dev->aeq, |
555 | 2, | 551 | 2, |
556 | qsize, | 552 | qsize, |
@@ -597,17 +593,13 @@ int c2_rnic_init(struct c2_dev *c2dev) | |||
597 | bail4: | 593 | bail4: |
598 | vq_term(c2dev); | 594 | vq_term(c2dev); |
599 | bail3: | 595 | bail3: |
600 | dma_unmap_single(c2dev->ibdev.dma_device, | 596 | dma_free_coherent(&c2dev->pcidev->dev, |
601 | pci_unmap_addr(&c2dev->aeq, mapping), | 597 | c2dev->aeq.q_size * c2dev->aeq.msg_size, |
602 | c2dev->aeq.q_size * c2dev->aeq.msg_size, | 598 | q2_pages, pci_unmap_addr(&c2dev->aeq, mapping)); |
603 | DMA_FROM_DEVICE); | ||
604 | kfree(q2_pages); | ||
605 | bail2: | 599 | bail2: |
606 | dma_unmap_single(c2dev->ibdev.dma_device, | 600 | dma_free_coherent(&c2dev->pcidev->dev, |
607 | pci_unmap_addr(&c2dev->rep_vq, mapping), | 601 | c2dev->rep_vq.q_size * c2dev->rep_vq.msg_size, |
608 | c2dev->rep_vq.q_size * c2dev->rep_vq.msg_size, | 602 | q1_pages, pci_unmap_addr(&c2dev->rep_vq, mapping)); |
609 | DMA_FROM_DEVICE); | ||
610 | kfree(q1_pages); | ||
611 | bail1: | 603 | bail1: |
612 | c2_free_mqsp_pool(c2dev, c2dev->kern_mqsp_pool); | 604 | c2_free_mqsp_pool(c2dev, c2dev->kern_mqsp_pool); |
613 | bail0: | 605 | bail0: |
@@ -640,19 +632,17 @@ void c2_rnic_term(struct c2_dev *c2dev) | |||
640 | /* Free the verbs request allocator */ | 632 | /* Free the verbs request allocator */ |
641 | vq_term(c2dev); | 633 | vq_term(c2dev); |
642 | 634 | ||
643 | /* Unmap and free the asynchronus event queue */ | 635 | /* Free the asynchronus event queue */ |
644 | dma_unmap_single(c2dev->ibdev.dma_device, | 636 | dma_free_coherent(&c2dev->pcidev->dev, |
645 | pci_unmap_addr(&c2dev->aeq, mapping), | 637 | c2dev->aeq.q_size * c2dev->aeq.msg_size, |
646 | c2dev->aeq.q_size * c2dev->aeq.msg_size, | 638 | c2dev->aeq.msg_pool.host, |
647 | DMA_FROM_DEVICE); | 639 | pci_unmap_addr(&c2dev->aeq, mapping)); |
648 | kfree(c2dev->aeq.msg_pool.host); | 640 | |
649 | 641 | /* Free the verbs reply queue */ | |
650 | /* Unmap and free the verbs reply queue */ | 642 | dma_free_coherent(&c2dev->pcidev->dev, |
651 | dma_unmap_single(c2dev->ibdev.dma_device, | 643 | c2dev->rep_vq.q_size * c2dev->rep_vq.msg_size, |
652 | pci_unmap_addr(&c2dev->rep_vq, mapping), | 644 | c2dev->rep_vq.msg_pool.host, |
653 | c2dev->rep_vq.q_size * c2dev->rep_vq.msg_size, | 645 | pci_unmap_addr(&c2dev->rep_vq, mapping)); |
654 | DMA_FROM_DEVICE); | ||
655 | kfree(c2dev->rep_vq.msg_pool.host); | ||
656 | 646 | ||
657 | /* Free the MQ shared pointer pool */ | 647 | /* Free the MQ shared pointer pool */ |
658 | c2_free_mqsp_pool(c2dev, c2dev->kern_mqsp_pool); | 648 | c2_free_mqsp_pool(c2dev, c2dev->kern_mqsp_pool); |
diff --git a/drivers/infiniband/hw/ehca/Kconfig b/drivers/infiniband/hw/ehca/Kconfig index 922389b64394..727b10d89686 100644 --- a/drivers/infiniband/hw/ehca/Kconfig +++ b/drivers/infiniband/hw/ehca/Kconfig | |||
@@ -10,6 +10,7 @@ config INFINIBAND_EHCA | |||
10 | config INFINIBAND_EHCA_SCALING | 10 | config INFINIBAND_EHCA_SCALING |
11 | bool "Scaling support (EXPERIMENTAL)" | 11 | bool "Scaling support (EXPERIMENTAL)" |
12 | depends on IBMEBUS && INFINIBAND_EHCA && HOTPLUG_CPU && EXPERIMENTAL | 12 | depends on IBMEBUS && INFINIBAND_EHCA && HOTPLUG_CPU && EXPERIMENTAL |
13 | default y | ||
13 | ---help--- | 14 | ---help--- |
14 | eHCA scaling support schedules the CQ callbacks to different CPUs. | 15 | eHCA scaling support schedules the CQ callbacks to different CPUs. |
15 | 16 | ||
diff --git a/drivers/infiniband/hw/ehca/ehca_av.c b/drivers/infiniband/hw/ehca/ehca_av.c index 3bac197f9014..214e2fdddeef 100644 --- a/drivers/infiniband/hw/ehca/ehca_av.c +++ b/drivers/infiniband/hw/ehca/ehca_av.c | |||
@@ -118,8 +118,7 @@ struct ib_ah *ehca_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr) | |||
118 | } | 118 | } |
119 | memcpy(&av->av.grh.word_1, &gid, sizeof(gid)); | 119 | memcpy(&av->av.grh.word_1, &gid, sizeof(gid)); |
120 | } | 120 | } |
121 | /* for the time being we use a hard coded PMTU of 2048 Bytes */ | 121 | av->av.pmtu = EHCA_MAX_MTU; |
122 | av->av.pmtu = 4; | ||
123 | 122 | ||
124 | /* dgid comes in grh.word_3 */ | 123 | /* dgid comes in grh.word_3 */ |
125 | memcpy(&av->av.grh.word_3, &ah_attr->grh.dgid, | 124 | memcpy(&av->av.grh.word_3, &ah_attr->grh.dgid, |
@@ -193,7 +192,7 @@ int ehca_modify_ah(struct ib_ah *ah, struct ib_ah_attr *ah_attr) | |||
193 | memcpy(&new_ehca_av.grh.word_1, &gid, sizeof(gid)); | 192 | memcpy(&new_ehca_av.grh.word_1, &gid, sizeof(gid)); |
194 | } | 193 | } |
195 | 194 | ||
196 | new_ehca_av.pmtu = 4; /* see also comment in create_ah() */ | 195 | new_ehca_av.pmtu = EHCA_MAX_MTU; |
197 | 196 | ||
198 | memcpy(&new_ehca_av.grh.word_3, &ah_attr->grh.dgid, | 197 | memcpy(&new_ehca_av.grh.word_3, &ah_attr->grh.dgid, |
199 | sizeof(ah_attr->grh.dgid)); | 198 | sizeof(ah_attr->grh.dgid)); |
diff --git a/drivers/infiniband/hw/ehca/ehca_hca.c b/drivers/infiniband/hw/ehca/ehca_hca.c index 5eae6ac48425..e1b618c5f685 100644 --- a/drivers/infiniband/hw/ehca/ehca_hca.c +++ b/drivers/infiniband/hw/ehca/ehca_hca.c | |||
@@ -40,6 +40,7 @@ | |||
40 | */ | 40 | */ |
41 | 41 | ||
42 | #include "ehca_tools.h" | 42 | #include "ehca_tools.h" |
43 | #include "ehca_iverbs.h" | ||
43 | #include "hcp_if.h" | 44 | #include "hcp_if.h" |
44 | 45 | ||
45 | int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props) | 46 | int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props) |
@@ -49,7 +50,7 @@ int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props) | |||
49 | ib_device); | 50 | ib_device); |
50 | struct hipz_query_hca *rblock; | 51 | struct hipz_query_hca *rblock; |
51 | 52 | ||
52 | rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); | 53 | rblock = ehca_alloc_fw_ctrlblock(); |
53 | if (!rblock) { | 54 | if (!rblock) { |
54 | ehca_err(&shca->ib_device, "Can't allocate rblock memory."); | 55 | ehca_err(&shca->ib_device, "Can't allocate rblock memory."); |
55 | return -ENOMEM; | 56 | return -ENOMEM; |
@@ -96,7 +97,7 @@ int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props) | |||
96 | = min_t(int, rblock->max_total_mcast_qp_attach, INT_MAX); | 97 | = min_t(int, rblock->max_total_mcast_qp_attach, INT_MAX); |
97 | 98 | ||
98 | query_device1: | 99 | query_device1: |
99 | kfree(rblock); | 100 | ehca_free_fw_ctrlblock(rblock); |
100 | 101 | ||
101 | return ret; | 102 | return ret; |
102 | } | 103 | } |
@@ -109,7 +110,7 @@ int ehca_query_port(struct ib_device *ibdev, | |||
109 | ib_device); | 110 | ib_device); |
110 | struct hipz_query_port *rblock; | 111 | struct hipz_query_port *rblock; |
111 | 112 | ||
112 | rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); | 113 | rblock = ehca_alloc_fw_ctrlblock(); |
113 | if (!rblock) { | 114 | if (!rblock) { |
114 | ehca_err(&shca->ib_device, "Can't allocate rblock memory."); | 115 | ehca_err(&shca->ib_device, "Can't allocate rblock memory."); |
115 | return -ENOMEM; | 116 | return -ENOMEM; |
@@ -162,7 +163,7 @@ int ehca_query_port(struct ib_device *ibdev, | |||
162 | props->active_speed = 0x1; | 163 | props->active_speed = 0x1; |
163 | 164 | ||
164 | query_port1: | 165 | query_port1: |
165 | kfree(rblock); | 166 | ehca_free_fw_ctrlblock(rblock); |
166 | 167 | ||
167 | return ret; | 168 | return ret; |
168 | } | 169 | } |
@@ -178,7 +179,7 @@ int ehca_query_pkey(struct ib_device *ibdev, u8 port, u16 index, u16 *pkey) | |||
178 | return -EINVAL; | 179 | return -EINVAL; |
179 | } | 180 | } |
180 | 181 | ||
181 | rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); | 182 | rblock = ehca_alloc_fw_ctrlblock(); |
182 | if (!rblock) { | 183 | if (!rblock) { |
183 | ehca_err(&shca->ib_device, "Can't allocate rblock memory."); | 184 | ehca_err(&shca->ib_device, "Can't allocate rblock memory."); |
184 | return -ENOMEM; | 185 | return -ENOMEM; |
@@ -193,7 +194,7 @@ int ehca_query_pkey(struct ib_device *ibdev, u8 port, u16 index, u16 *pkey) | |||
193 | memcpy(pkey, &rblock->pkey_entries + index, sizeof(u16)); | 194 | memcpy(pkey, &rblock->pkey_entries + index, sizeof(u16)); |
194 | 195 | ||
195 | query_pkey1: | 196 | query_pkey1: |
196 | kfree(rblock); | 197 | ehca_free_fw_ctrlblock(rblock); |
197 | 198 | ||
198 | return ret; | 199 | return ret; |
199 | } | 200 | } |
@@ -211,7 +212,7 @@ int ehca_query_gid(struct ib_device *ibdev, u8 port, | |||
211 | return -EINVAL; | 212 | return -EINVAL; |
212 | } | 213 | } |
213 | 214 | ||
214 | rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); | 215 | rblock = ehca_alloc_fw_ctrlblock(); |
215 | if (!rblock) { | 216 | if (!rblock) { |
216 | ehca_err(&shca->ib_device, "Can't allocate rblock memory."); | 217 | ehca_err(&shca->ib_device, "Can't allocate rblock memory."); |
217 | return -ENOMEM; | 218 | return -ENOMEM; |
@@ -227,7 +228,7 @@ int ehca_query_gid(struct ib_device *ibdev, u8 port, | |||
227 | memcpy(&gid->raw[8], &rblock->guid_entries[index], sizeof(u64)); | 228 | memcpy(&gid->raw[8], &rblock->guid_entries[index], sizeof(u64)); |
228 | 229 | ||
229 | query_gid1: | 230 | query_gid1: |
230 | kfree(rblock); | 231 | ehca_free_fw_ctrlblock(rblock); |
231 | 232 | ||
232 | return ret; | 233 | return ret; |
233 | } | 234 | } |
diff --git a/drivers/infiniband/hw/ehca/ehca_irq.c b/drivers/infiniband/hw/ehca/ehca_irq.c index 048cc443d1e7..c3ea746e9045 100644 --- a/drivers/infiniband/hw/ehca/ehca_irq.c +++ b/drivers/infiniband/hw/ehca/ehca_irq.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include "ehca_tools.h" | 45 | #include "ehca_tools.h" |
46 | #include "hcp_if.h" | 46 | #include "hcp_if.h" |
47 | #include "hipz_fns.h" | 47 | #include "hipz_fns.h" |
48 | #include "ipz_pt_fn.h" | ||
48 | 49 | ||
49 | #define EQE_COMPLETION_EVENT EHCA_BMASK_IBM(1,1) | 50 | #define EQE_COMPLETION_EVENT EHCA_BMASK_IBM(1,1) |
50 | #define EQE_CQ_QP_NUMBER EHCA_BMASK_IBM(8,31) | 51 | #define EQE_CQ_QP_NUMBER EHCA_BMASK_IBM(8,31) |
@@ -137,38 +138,36 @@ int ehca_error_data(struct ehca_shca *shca, void *data, | |||
137 | u64 *rblock; | 138 | u64 *rblock; |
138 | unsigned long block_count; | 139 | unsigned long block_count; |
139 | 140 | ||
140 | rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); | 141 | rblock = ehca_alloc_fw_ctrlblock(); |
141 | if (!rblock) { | 142 | if (!rblock) { |
142 | ehca_err(&shca->ib_device, "Cannot allocate rblock memory."); | 143 | ehca_err(&shca->ib_device, "Cannot allocate rblock memory."); |
143 | ret = -ENOMEM; | 144 | ret = -ENOMEM; |
144 | goto error_data1; | 145 | goto error_data1; |
145 | } | 146 | } |
146 | 147 | ||
148 | /* rblock must be 4K aligned and should be 4K large */ | ||
147 | ret = hipz_h_error_data(shca->ipz_hca_handle, | 149 | ret = hipz_h_error_data(shca->ipz_hca_handle, |
148 | resource, | 150 | resource, |
149 | rblock, | 151 | rblock, |
150 | &block_count); | 152 | &block_count); |
151 | 153 | ||
152 | if (ret == H_R_STATE) { | 154 | if (ret == H_R_STATE) |
153 | ehca_err(&shca->ib_device, | 155 | ehca_err(&shca->ib_device, |
154 | "No error data is available: %lx.", resource); | 156 | "No error data is available: %lx.", resource); |
155 | } | ||
156 | else if (ret == H_SUCCESS) { | 157 | else if (ret == H_SUCCESS) { |
157 | int length; | 158 | int length; |
158 | 159 | ||
159 | length = EHCA_BMASK_GET(ERROR_DATA_LENGTH, rblock[0]); | 160 | length = EHCA_BMASK_GET(ERROR_DATA_LENGTH, rblock[0]); |
160 | 161 | ||
161 | if (length > PAGE_SIZE) | 162 | if (length > EHCA_PAGESIZE) |
162 | length = PAGE_SIZE; | 163 | length = EHCA_PAGESIZE; |
163 | 164 | ||
164 | print_error_data(shca, data, rblock, length); | 165 | print_error_data(shca, data, rblock, length); |
165 | } | 166 | } else |
166 | else { | ||
167 | ehca_err(&shca->ib_device, | 167 | ehca_err(&shca->ib_device, |
168 | "Error data could not be fetched: %lx", resource); | 168 | "Error data could not be fetched: %lx", resource); |
169 | } | ||
170 | 169 | ||
171 | kfree(rblock); | 170 | ehca_free_fw_ctrlblock(rblock); |
172 | 171 | ||
173 | error_data1: | 172 | error_data1: |
174 | return ret; | 173 | return ret; |
diff --git a/drivers/infiniband/hw/ehca/ehca_iverbs.h b/drivers/infiniband/hw/ehca/ehca_iverbs.h index 319c39d47f3a..3720e3032cce 100644 --- a/drivers/infiniband/hw/ehca/ehca_iverbs.h +++ b/drivers/infiniband/hw/ehca/ehca_iverbs.h | |||
@@ -179,4 +179,12 @@ int ehca_mmap_register(u64 physical,void **mapped, | |||
179 | 179 | ||
180 | int ehca_munmap(unsigned long addr, size_t len); | 180 | int ehca_munmap(unsigned long addr, size_t len); |
181 | 181 | ||
182 | #ifdef CONFIG_PPC_64K_PAGES | ||
183 | void *ehca_alloc_fw_ctrlblock(void); | ||
184 | void ehca_free_fw_ctrlblock(void *ptr); | ||
185 | #else | ||
186 | #define ehca_alloc_fw_ctrlblock() ((void *) get_zeroed_page(GFP_KERNEL)) | ||
187 | #define ehca_free_fw_ctrlblock(ptr) free_page((unsigned long)(ptr)) | ||
188 | #endif | ||
189 | |||
182 | #endif | 190 | #endif |
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c index 024d511c4b58..01f5aa9cb56d 100644 --- a/drivers/infiniband/hw/ehca/ehca_main.c +++ b/drivers/infiniband/hw/ehca/ehca_main.c | |||
@@ -40,6 +40,9 @@ | |||
40 | * POSSIBILITY OF SUCH DAMAGE. | 40 | * POSSIBILITY OF SUCH DAMAGE. |
41 | */ | 41 | */ |
42 | 42 | ||
43 | #ifdef CONFIG_PPC_64K_PAGES | ||
44 | #include <linux/slab.h> | ||
45 | #endif | ||
43 | #include "ehca_classes.h" | 46 | #include "ehca_classes.h" |
44 | #include "ehca_iverbs.h" | 47 | #include "ehca_iverbs.h" |
45 | #include "ehca_mrmw.h" | 48 | #include "ehca_mrmw.h" |
@@ -49,7 +52,7 @@ | |||
49 | MODULE_LICENSE("Dual BSD/GPL"); | 52 | MODULE_LICENSE("Dual BSD/GPL"); |
50 | MODULE_AUTHOR("Christoph Raisch <raisch@de.ibm.com>"); | 53 | MODULE_AUTHOR("Christoph Raisch <raisch@de.ibm.com>"); |
51 | MODULE_DESCRIPTION("IBM eServer HCA InfiniBand Device Driver"); | 54 | MODULE_DESCRIPTION("IBM eServer HCA InfiniBand Device Driver"); |
52 | MODULE_VERSION("SVNEHCA_0017"); | 55 | MODULE_VERSION("SVNEHCA_0018"); |
53 | 56 | ||
54 | int ehca_open_aqp1 = 0; | 57 | int ehca_open_aqp1 = 0; |
55 | int ehca_debug_level = 0; | 58 | int ehca_debug_level = 0; |
@@ -94,11 +97,31 @@ spinlock_t ehca_cq_idr_lock; | |||
94 | DEFINE_IDR(ehca_qp_idr); | 97 | DEFINE_IDR(ehca_qp_idr); |
95 | DEFINE_IDR(ehca_cq_idr); | 98 | DEFINE_IDR(ehca_cq_idr); |
96 | 99 | ||
100 | |||
97 | static struct list_head shca_list; /* list of all registered ehcas */ | 101 | static struct list_head shca_list; /* list of all registered ehcas */ |
98 | static spinlock_t shca_list_lock; | 102 | static spinlock_t shca_list_lock; |
99 | 103 | ||
100 | static struct timer_list poll_eqs_timer; | 104 | static struct timer_list poll_eqs_timer; |
101 | 105 | ||
106 | #ifdef CONFIG_PPC_64K_PAGES | ||
107 | static struct kmem_cache *ctblk_cache = NULL; | ||
108 | |||
109 | void *ehca_alloc_fw_ctrlblock(void) | ||
110 | { | ||
111 | void *ret = kmem_cache_zalloc(ctblk_cache, SLAB_KERNEL); | ||
112 | if (!ret) | ||
113 | ehca_gen_err("Out of memory for ctblk"); | ||
114 | return ret; | ||
115 | } | ||
116 | |||
117 | void ehca_free_fw_ctrlblock(void *ptr) | ||
118 | { | ||
119 | if (ptr) | ||
120 | kmem_cache_free(ctblk_cache, ptr); | ||
121 | |||
122 | } | ||
123 | #endif | ||
124 | |||
102 | static int ehca_create_slab_caches(void) | 125 | static int ehca_create_slab_caches(void) |
103 | { | 126 | { |
104 | int ret; | 127 | int ret; |
@@ -133,6 +156,17 @@ static int ehca_create_slab_caches(void) | |||
133 | goto create_slab_caches5; | 156 | goto create_slab_caches5; |
134 | } | 157 | } |
135 | 158 | ||
159 | #ifdef CONFIG_PPC_64K_PAGES | ||
160 | ctblk_cache = kmem_cache_create("ehca_cache_ctblk", | ||
161 | EHCA_PAGESIZE, H_CB_ALIGNMENT, | ||
162 | SLAB_HWCACHE_ALIGN, | ||
163 | NULL, NULL); | ||
164 | if (!ctblk_cache) { | ||
165 | ehca_gen_err("Cannot create ctblk SLAB cache."); | ||
166 | ehca_cleanup_mrmw_cache(); | ||
167 | goto create_slab_caches5; | ||
168 | } | ||
169 | #endif | ||
136 | return 0; | 170 | return 0; |
137 | 171 | ||
138 | create_slab_caches5: | 172 | create_slab_caches5: |
@@ -157,6 +191,10 @@ static void ehca_destroy_slab_caches(void) | |||
157 | ehca_cleanup_qp_cache(); | 191 | ehca_cleanup_qp_cache(); |
158 | ehca_cleanup_cq_cache(); | 192 | ehca_cleanup_cq_cache(); |
159 | ehca_cleanup_pd_cache(); | 193 | ehca_cleanup_pd_cache(); |
194 | #ifdef CONFIG_PPC_64K_PAGES | ||
195 | if (ctblk_cache) | ||
196 | kmem_cache_destroy(ctblk_cache); | ||
197 | #endif | ||
160 | } | 198 | } |
161 | 199 | ||
162 | #define EHCA_HCAAVER EHCA_BMASK_IBM(32,39) | 200 | #define EHCA_HCAAVER EHCA_BMASK_IBM(32,39) |
@@ -168,7 +206,7 @@ int ehca_sense_attributes(struct ehca_shca *shca) | |||
168 | u64 h_ret; | 206 | u64 h_ret; |
169 | struct hipz_query_hca *rblock; | 207 | struct hipz_query_hca *rblock; |
170 | 208 | ||
171 | rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); | 209 | rblock = ehca_alloc_fw_ctrlblock(); |
172 | if (!rblock) { | 210 | if (!rblock) { |
173 | ehca_gen_err("Cannot allocate rblock memory."); | 211 | ehca_gen_err("Cannot allocate rblock memory."); |
174 | return -ENOMEM; | 212 | return -ENOMEM; |
@@ -211,7 +249,7 @@ int ehca_sense_attributes(struct ehca_shca *shca) | |||
211 | shca->sport[1].rate = IB_RATE_30_GBPS; | 249 | shca->sport[1].rate = IB_RATE_30_GBPS; |
212 | 250 | ||
213 | num_ports1: | 251 | num_ports1: |
214 | kfree(rblock); | 252 | ehca_free_fw_ctrlblock(rblock); |
215 | return ret; | 253 | return ret; |
216 | } | 254 | } |
217 | 255 | ||
@@ -220,7 +258,7 @@ static int init_node_guid(struct ehca_shca *shca) | |||
220 | int ret = 0; | 258 | int ret = 0; |
221 | struct hipz_query_hca *rblock; | 259 | struct hipz_query_hca *rblock; |
222 | 260 | ||
223 | rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); | 261 | rblock = ehca_alloc_fw_ctrlblock(); |
224 | if (!rblock) { | 262 | if (!rblock) { |
225 | ehca_err(&shca->ib_device, "Can't allocate rblock memory."); | 263 | ehca_err(&shca->ib_device, "Can't allocate rblock memory."); |
226 | return -ENOMEM; | 264 | return -ENOMEM; |
@@ -235,7 +273,7 @@ static int init_node_guid(struct ehca_shca *shca) | |||
235 | memcpy(&shca->ib_device.node_guid, &rblock->node_guid, sizeof(u64)); | 273 | memcpy(&shca->ib_device.node_guid, &rblock->node_guid, sizeof(u64)); |
236 | 274 | ||
237 | init_node_guid1: | 275 | init_node_guid1: |
238 | kfree(rblock); | 276 | ehca_free_fw_ctrlblock(rblock); |
239 | return ret; | 277 | return ret; |
240 | } | 278 | } |
241 | 279 | ||
@@ -431,7 +469,7 @@ static ssize_t ehca_show_##name(struct device *dev, \ | |||
431 | \ | 469 | \ |
432 | shca = dev->driver_data; \ | 470 | shca = dev->driver_data; \ |
433 | \ | 471 | \ |
434 | rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); \ | 472 | rblock = ehca_alloc_fw_ctrlblock(); \ |
435 | if (!rblock) { \ | 473 | if (!rblock) { \ |
436 | dev_err(dev, "Can't allocate rblock memory."); \ | 474 | dev_err(dev, "Can't allocate rblock memory."); \ |
437 | return 0; \ | 475 | return 0; \ |
@@ -439,12 +477,12 @@ static ssize_t ehca_show_##name(struct device *dev, \ | |||
439 | \ | 477 | \ |
440 | if (hipz_h_query_hca(shca->ipz_hca_handle, rblock) != H_SUCCESS) { \ | 478 | if (hipz_h_query_hca(shca->ipz_hca_handle, rblock) != H_SUCCESS) { \ |
441 | dev_err(dev, "Can't query device properties"); \ | 479 | dev_err(dev, "Can't query device properties"); \ |
442 | kfree(rblock); \ | 480 | ehca_free_fw_ctrlblock(rblock); \ |
443 | return 0; \ | 481 | return 0; \ |
444 | } \ | 482 | } \ |
445 | \ | 483 | \ |
446 | data = rblock->name; \ | 484 | data = rblock->name; \ |
447 | kfree(rblock); \ | 485 | ehca_free_fw_ctrlblock(rblock); \ |
448 | \ | 486 | \ |
449 | if ((strcmp(#name, "num_ports") == 0) && (ehca_nr_ports == 1)) \ | 487 | if ((strcmp(#name, "num_ports") == 0) && (ehca_nr_ports == 1)) \ |
450 | return snprintf(buf, 256, "1\n"); \ | 488 | return snprintf(buf, 256, "1\n"); \ |
@@ -752,7 +790,7 @@ int __init ehca_module_init(void) | |||
752 | int ret; | 790 | int ret; |
753 | 791 | ||
754 | printk(KERN_INFO "eHCA Infiniband Device Driver " | 792 | printk(KERN_INFO "eHCA Infiniband Device Driver " |
755 | "(Rel.: SVNEHCA_0017)\n"); | 793 | "(Rel.: SVNEHCA_0018)\n"); |
756 | idr_init(&ehca_qp_idr); | 794 | idr_init(&ehca_qp_idr); |
757 | idr_init(&ehca_cq_idr); | 795 | idr_init(&ehca_cq_idr); |
758 | spin_lock_init(&ehca_qp_idr_lock); | 796 | spin_lock_init(&ehca_qp_idr_lock); |
diff --git a/drivers/infiniband/hw/ehca/ehca_mrmw.c b/drivers/infiniband/hw/ehca/ehca_mrmw.c index 5ca65441e1da..abce676c0ae0 100644 --- a/drivers/infiniband/hw/ehca/ehca_mrmw.c +++ b/drivers/infiniband/hw/ehca/ehca_mrmw.c | |||
@@ -1013,7 +1013,7 @@ int ehca_reg_mr_rpages(struct ehca_shca *shca, | |||
1013 | u32 i; | 1013 | u32 i; |
1014 | u64 *kpage; | 1014 | u64 *kpage; |
1015 | 1015 | ||
1016 | kpage = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); | 1016 | kpage = ehca_alloc_fw_ctrlblock(); |
1017 | if (!kpage) { | 1017 | if (!kpage) { |
1018 | ehca_err(&shca->ib_device, "kpage alloc failed"); | 1018 | ehca_err(&shca->ib_device, "kpage alloc failed"); |
1019 | ret = -ENOMEM; | 1019 | ret = -ENOMEM; |
@@ -1092,7 +1092,7 @@ int ehca_reg_mr_rpages(struct ehca_shca *shca, | |||
1092 | 1092 | ||
1093 | 1093 | ||
1094 | ehca_reg_mr_rpages_exit1: | 1094 | ehca_reg_mr_rpages_exit1: |
1095 | kfree(kpage); | 1095 | ehca_free_fw_ctrlblock(kpage); |
1096 | ehca_reg_mr_rpages_exit0: | 1096 | ehca_reg_mr_rpages_exit0: |
1097 | if (ret) | 1097 | if (ret) |
1098 | ehca_err(&shca->ib_device, "ret=%x shca=%p e_mr=%p pginfo=%p " | 1098 | ehca_err(&shca->ib_device, "ret=%x shca=%p e_mr=%p pginfo=%p " |
@@ -1124,7 +1124,7 @@ inline int ehca_rereg_mr_rereg1(struct ehca_shca *shca, | |||
1124 | ehca_mrmw_map_acl(acl, &hipz_acl); | 1124 | ehca_mrmw_map_acl(acl, &hipz_acl); |
1125 | ehca_mrmw_set_pgsize_hipz_acl(&hipz_acl); | 1125 | ehca_mrmw_set_pgsize_hipz_acl(&hipz_acl); |
1126 | 1126 | ||
1127 | kpage = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); | 1127 | kpage = ehca_alloc_fw_ctrlblock(); |
1128 | if (!kpage) { | 1128 | if (!kpage) { |
1129 | ehca_err(&shca->ib_device, "kpage alloc failed"); | 1129 | ehca_err(&shca->ib_device, "kpage alloc failed"); |
1130 | ret = -ENOMEM; | 1130 | ret = -ENOMEM; |
@@ -1181,7 +1181,7 @@ inline int ehca_rereg_mr_rereg1(struct ehca_shca *shca, | |||
1181 | } | 1181 | } |
1182 | 1182 | ||
1183 | ehca_rereg_mr_rereg1_exit1: | 1183 | ehca_rereg_mr_rereg1_exit1: |
1184 | kfree(kpage); | 1184 | ehca_free_fw_ctrlblock(kpage); |
1185 | ehca_rereg_mr_rereg1_exit0: | 1185 | ehca_rereg_mr_rereg1_exit0: |
1186 | if ( ret && (ret != -EAGAIN) ) | 1186 | if ( ret && (ret != -EAGAIN) ) |
1187 | ehca_err(&shca->ib_device, "ret=%x lkey=%x rkey=%x " | 1187 | ehca_err(&shca->ib_device, "ret=%x lkey=%x rkey=%x " |
diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c index 4394123cdbd7..cf3e50ee2d06 100644 --- a/drivers/infiniband/hw/ehca/ehca_qp.c +++ b/drivers/infiniband/hw/ehca/ehca_qp.c | |||
@@ -811,8 +811,8 @@ static int internal_modify_qp(struct ib_qp *ibqp, | |||
811 | unsigned long spl_flags = 0; | 811 | unsigned long spl_flags = 0; |
812 | 812 | ||
813 | /* do query_qp to obtain current attr values */ | 813 | /* do query_qp to obtain current attr values */ |
814 | mqpcb = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); | 814 | mqpcb = ehca_alloc_fw_ctrlblock(); |
815 | if (mqpcb == NULL) { | 815 | if (!mqpcb) { |
816 | ehca_err(ibqp->device, "Could not get zeroed page for mqpcb " | 816 | ehca_err(ibqp->device, "Could not get zeroed page for mqpcb " |
817 | "ehca_qp=%p qp_num=%x ", my_qp, ibqp->qp_num); | 817 | "ehca_qp=%p qp_num=%x ", my_qp, ibqp->qp_num); |
818 | return -ENOMEM; | 818 | return -ENOMEM; |
@@ -1225,7 +1225,7 @@ modify_qp_exit2: | |||
1225 | } | 1225 | } |
1226 | 1226 | ||
1227 | modify_qp_exit1: | 1227 | modify_qp_exit1: |
1228 | kfree(mqpcb); | 1228 | ehca_free_fw_ctrlblock(mqpcb); |
1229 | 1229 | ||
1230 | return ret; | 1230 | return ret; |
1231 | } | 1231 | } |
@@ -1277,7 +1277,7 @@ int ehca_query_qp(struct ib_qp *qp, | |||
1277 | return -EINVAL; | 1277 | return -EINVAL; |
1278 | } | 1278 | } |
1279 | 1279 | ||
1280 | qpcb = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL ); | 1280 | qpcb = ehca_alloc_fw_ctrlblock(); |
1281 | if (!qpcb) { | 1281 | if (!qpcb) { |
1282 | ehca_err(qp->device,"Out of memory for qpcb " | 1282 | ehca_err(qp->device,"Out of memory for qpcb " |
1283 | "ehca_qp=%p qp_num=%x", my_qp, qp->qp_num); | 1283 | "ehca_qp=%p qp_num=%x", my_qp, qp->qp_num); |
@@ -1401,7 +1401,7 @@ int ehca_query_qp(struct ib_qp *qp, | |||
1401 | ehca_dmp(qpcb, 4*70, "qp_num=%x", qp->qp_num); | 1401 | ehca_dmp(qpcb, 4*70, "qp_num=%x", qp->qp_num); |
1402 | 1402 | ||
1403 | query_qp_exit1: | 1403 | query_qp_exit1: |
1404 | kfree(qpcb); | 1404 | ehca_free_fw_ctrlblock(qpcb); |
1405 | 1405 | ||
1406 | return ret; | 1406 | return ret; |
1407 | } | 1407 | } |
diff --git a/drivers/infiniband/hw/ehca/ehca_tools.h b/drivers/infiniband/hw/ehca/ehca_tools.h index 809da3ef706b..973c4b591545 100644 --- a/drivers/infiniband/hw/ehca/ehca_tools.h +++ b/drivers/infiniband/hw/ehca/ehca_tools.h | |||
@@ -63,6 +63,7 @@ | |||
63 | #include <asm/ibmebus.h> | 63 | #include <asm/ibmebus.h> |
64 | #include <asm/io.h> | 64 | #include <asm/io.h> |
65 | #include <asm/pgtable.h> | 65 | #include <asm/pgtable.h> |
66 | #include <asm/hvcall.h> | ||
66 | 67 | ||
67 | extern int ehca_debug_level; | 68 | extern int ehca_debug_level; |
68 | 69 | ||
diff --git a/drivers/infiniband/hw/ehca/hipz_hw.h b/drivers/infiniband/hw/ehca/hipz_hw.h index 3fc92b031c50..fad91368dc5a 100644 --- a/drivers/infiniband/hw/ehca/hipz_hw.h +++ b/drivers/infiniband/hw/ehca/hipz_hw.h | |||
@@ -45,6 +45,8 @@ | |||
45 | 45 | ||
46 | #include "ehca_tools.h" | 46 | #include "ehca_tools.h" |
47 | 47 | ||
48 | #define EHCA_MAX_MTU 4 | ||
49 | |||
48 | /* QP Table Entry Memory Map */ | 50 | /* QP Table Entry Memory Map */ |
49 | struct hipz_qptemm { | 51 | struct hipz_qptemm { |
50 | u64 qpx_hcr; | 52 | u64 qpx_hcr; |
diff --git a/drivers/infiniband/hw/ipath/Kconfig b/drivers/infiniband/hw/ipath/Kconfig index 574a678e7fdd..90c14543677d 100644 --- a/drivers/infiniband/hw/ipath/Kconfig +++ b/drivers/infiniband/hw/ipath/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config INFINIBAND_IPATH | 1 | config INFINIBAND_IPATH |
2 | tristate "QLogic InfiniPath Driver" | 2 | tristate "QLogic InfiniPath Driver" |
3 | depends on PCI_MSI && 64BIT && INFINIBAND | 3 | depends on (PCI_MSI || HT_IRQ) && 64BIT && INFINIBAND && NET |
4 | ---help--- | 4 | ---help--- |
5 | This is a driver for QLogic InfiniPath host channel adapters, | 5 | This is a driver for QLogic InfiniPath host channel adapters, |
6 | including InfiniBand verbs support. This driver allows these | 6 | including InfiniBand verbs support. This driver allows these |
diff --git a/drivers/infiniband/hw/ipath/Makefile b/drivers/infiniband/hw/ipath/Makefile index 5e29cb0095e5..7dc10551cf18 100644 --- a/drivers/infiniband/hw/ipath/Makefile +++ b/drivers/infiniband/hw/ipath/Makefile | |||
@@ -10,8 +10,6 @@ ib_ipath-y := \ | |||
10 | ipath_eeprom.o \ | 10 | ipath_eeprom.o \ |
11 | ipath_file_ops.o \ | 11 | ipath_file_ops.o \ |
12 | ipath_fs.o \ | 12 | ipath_fs.o \ |
13 | ipath_iba6110.o \ | ||
14 | ipath_iba6120.o \ | ||
15 | ipath_init_chip.o \ | 13 | ipath_init_chip.o \ |
16 | ipath_intr.o \ | 14 | ipath_intr.o \ |
17 | ipath_keys.o \ | 15 | ipath_keys.o \ |
@@ -31,5 +29,8 @@ ib_ipath-y := \ | |||
31 | ipath_verbs_mcast.o \ | 29 | ipath_verbs_mcast.o \ |
32 | ipath_verbs.o | 30 | ipath_verbs.o |
33 | 31 | ||
32 | ib_ipath-$(CONFIG_HT_IRQ) += ipath_iba6110.o | ||
33 | ib_ipath-$(CONFIG_PCI_MSI) += ipath_iba6120.o | ||
34 | |||
34 | ib_ipath-$(CONFIG_X86_64) += ipath_wc_x86_64.o | 35 | ib_ipath-$(CONFIG_X86_64) += ipath_wc_x86_64.o |
35 | ib_ipath-$(CONFIG_PPC64) += ipath_wc_ppc64.o | 36 | ib_ipath-$(CONFIG_PPC64) += ipath_wc_ppc64.o |
diff --git a/drivers/infiniband/hw/ipath/ipath_diag.c b/drivers/infiniband/hw/ipath/ipath_diag.c index 29958b6e0214..28c087b824c2 100644 --- a/drivers/infiniband/hw/ipath/ipath_diag.c +++ b/drivers/infiniband/hw/ipath/ipath_diag.c | |||
@@ -67,19 +67,54 @@ static struct file_operations diag_file_ops = { | |||
67 | .release = ipath_diag_release | 67 | .release = ipath_diag_release |
68 | }; | 68 | }; |
69 | 69 | ||
70 | static ssize_t ipath_diagpkt_write(struct file *fp, | ||
71 | const char __user *data, | ||
72 | size_t count, loff_t *off); | ||
73 | |||
74 | static struct file_operations diagpkt_file_ops = { | ||
75 | .owner = THIS_MODULE, | ||
76 | .write = ipath_diagpkt_write, | ||
77 | }; | ||
78 | |||
79 | static atomic_t diagpkt_count = ATOMIC_INIT(0); | ||
80 | static struct cdev *diagpkt_cdev; | ||
81 | static struct class_device *diagpkt_class_dev; | ||
82 | |||
70 | int ipath_diag_add(struct ipath_devdata *dd) | 83 | int ipath_diag_add(struct ipath_devdata *dd) |
71 | { | 84 | { |
72 | char name[16]; | 85 | char name[16]; |
86 | int ret = 0; | ||
87 | |||
88 | if (atomic_inc_return(&diagpkt_count) == 1) { | ||
89 | ret = ipath_cdev_init(IPATH_DIAGPKT_MINOR, | ||
90 | "ipath_diagpkt", &diagpkt_file_ops, | ||
91 | &diagpkt_cdev, &diagpkt_class_dev); | ||
92 | |||
93 | if (ret) { | ||
94 | ipath_dev_err(dd, "Couldn't create ipath_diagpkt " | ||
95 | "device: %d", ret); | ||
96 | goto done; | ||
97 | } | ||
98 | } | ||
73 | 99 | ||
74 | snprintf(name, sizeof(name), "ipath_diag%d", dd->ipath_unit); | 100 | snprintf(name, sizeof(name), "ipath_diag%d", dd->ipath_unit); |
75 | 101 | ||
76 | return ipath_cdev_init(IPATH_DIAG_MINOR_BASE + dd->ipath_unit, name, | 102 | ret = ipath_cdev_init(IPATH_DIAG_MINOR_BASE + dd->ipath_unit, name, |
77 | &diag_file_ops, &dd->diag_cdev, | 103 | &diag_file_ops, &dd->diag_cdev, |
78 | &dd->diag_class_dev); | 104 | &dd->diag_class_dev); |
105 | if (ret) | ||
106 | ipath_dev_err(dd, "Couldn't create %s device: %d", | ||
107 | name, ret); | ||
108 | |||
109 | done: | ||
110 | return ret; | ||
79 | } | 111 | } |
80 | 112 | ||
81 | void ipath_diag_remove(struct ipath_devdata *dd) | 113 | void ipath_diag_remove(struct ipath_devdata *dd) |
82 | { | 114 | { |
115 | if (atomic_dec_and_test(&diagpkt_count)) | ||
116 | ipath_cdev_cleanup(&diagpkt_cdev, &diagpkt_class_dev); | ||
117 | |||
83 | ipath_cdev_cleanup(&dd->diag_cdev, &dd->diag_class_dev); | 118 | ipath_cdev_cleanup(&dd->diag_cdev, &dd->diag_class_dev); |
84 | } | 119 | } |
85 | 120 | ||
@@ -275,30 +310,6 @@ bail: | |||
275 | return ret; | 310 | return ret; |
276 | } | 311 | } |
277 | 312 | ||
278 | static ssize_t ipath_diagpkt_write(struct file *fp, | ||
279 | const char __user *data, | ||
280 | size_t count, loff_t *off); | ||
281 | |||
282 | static struct file_operations diagpkt_file_ops = { | ||
283 | .owner = THIS_MODULE, | ||
284 | .write = ipath_diagpkt_write, | ||
285 | }; | ||
286 | |||
287 | static struct cdev *diagpkt_cdev; | ||
288 | static struct class_device *diagpkt_class_dev; | ||
289 | |||
290 | int __init ipath_diagpkt_add(void) | ||
291 | { | ||
292 | return ipath_cdev_init(IPATH_DIAGPKT_MINOR, | ||
293 | "ipath_diagpkt", &diagpkt_file_ops, | ||
294 | &diagpkt_cdev, &diagpkt_class_dev); | ||
295 | } | ||
296 | |||
297 | void __exit ipath_diagpkt_remove(void) | ||
298 | { | ||
299 | ipath_cdev_cleanup(&diagpkt_cdev, &diagpkt_class_dev); | ||
300 | } | ||
301 | |||
302 | /** | 313 | /** |
303 | * ipath_diagpkt_write - write an IB packet | 314 | * ipath_diagpkt_write - write an IB packet |
304 | * @fp: the diag data device file pointer | 315 | * @fp: the diag data device file pointer |
diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c index 12cefa658f3b..1aeddb48e355 100644 --- a/drivers/infiniband/hw/ipath/ipath_driver.c +++ b/drivers/infiniband/hw/ipath/ipath_driver.c | |||
@@ -304,7 +304,7 @@ static int __devinit ipath_init_one(struct pci_dev *pdev, | |||
304 | } | 304 | } |
305 | addr = pci_resource_start(pdev, 0); | 305 | addr = pci_resource_start(pdev, 0); |
306 | len = pci_resource_len(pdev, 0); | 306 | len = pci_resource_len(pdev, 0); |
307 | ipath_cdbg(VERBOSE, "regbase (0) %llx len %d irq %x, vend %x/%x " | 307 | ipath_cdbg(VERBOSE, "regbase (0) %llx len %d pdev->irq %d, vend %x/%x " |
308 | "driver_data %lx\n", addr, len, pdev->irq, ent->vendor, | 308 | "driver_data %lx\n", addr, len, pdev->irq, ent->vendor, |
309 | ent->device, ent->driver_data); | 309 | ent->device, ent->driver_data); |
310 | 310 | ||
@@ -390,12 +390,16 @@ static int __devinit ipath_init_one(struct pci_dev *pdev, | |||
390 | 390 | ||
391 | /* setup the chip-specific functions, as early as possible. */ | 391 | /* setup the chip-specific functions, as early as possible. */ |
392 | switch (ent->device) { | 392 | switch (ent->device) { |
393 | #ifdef CONFIG_HT_IRQ | ||
393 | case PCI_DEVICE_ID_INFINIPATH_HT: | 394 | case PCI_DEVICE_ID_INFINIPATH_HT: |
394 | ipath_init_iba6110_funcs(dd); | 395 | ipath_init_iba6110_funcs(dd); |
395 | break; | 396 | break; |
397 | #endif | ||
398 | #ifdef CONFIG_PCI_MSI | ||
396 | case PCI_DEVICE_ID_INFINIPATH_PE800: | 399 | case PCI_DEVICE_ID_INFINIPATH_PE800: |
397 | ipath_init_iba6120_funcs(dd); | 400 | ipath_init_iba6120_funcs(dd); |
398 | break; | 401 | break; |
402 | #endif | ||
399 | default: | 403 | default: |
400 | ipath_dev_err(dd, "Found unknown QLogic deviceid 0x%x, " | 404 | ipath_dev_err(dd, "Found unknown QLogic deviceid 0x%x, " |
401 | "failing\n", ent->device); | 405 | "failing\n", ent->device); |
@@ -467,15 +471,15 @@ static int __devinit ipath_init_one(struct pci_dev *pdev, | |||
467 | * check 0 irq after we return from chip-specific bus setup, since | 471 | * check 0 irq after we return from chip-specific bus setup, since |
468 | * that can affect this due to setup | 472 | * that can affect this due to setup |
469 | */ | 473 | */ |
470 | if (!pdev->irq) | 474 | if (!dd->ipath_irq) |
471 | ipath_dev_err(dd, "irq is 0, BIOS error? Interrupts won't " | 475 | ipath_dev_err(dd, "irq is 0, BIOS error? Interrupts won't " |
472 | "work\n"); | 476 | "work\n"); |
473 | else { | 477 | else { |
474 | ret = request_irq(pdev->irq, ipath_intr, IRQF_SHARED, | 478 | ret = request_irq(dd->ipath_irq, ipath_intr, IRQF_SHARED, |
475 | IPATH_DRV_NAME, dd); | 479 | IPATH_DRV_NAME, dd); |
476 | if (ret) { | 480 | if (ret) { |
477 | ipath_dev_err(dd, "Couldn't setup irq handler, " | 481 | ipath_dev_err(dd, "Couldn't setup irq handler, " |
478 | "irq=%u: %d\n", pdev->irq, ret); | 482 | "irq=%d: %d\n", dd->ipath_irq, ret); |
479 | goto bail_iounmap; | 483 | goto bail_iounmap; |
480 | } | 484 | } |
481 | } | 485 | } |
@@ -637,11 +641,10 @@ static void __devexit ipath_remove_one(struct pci_dev *pdev) | |||
637 | * free up port 0 (kernel) rcvhdr, egr bufs, and eventually tid bufs | 641 | * free up port 0 (kernel) rcvhdr, egr bufs, and eventually tid bufs |
638 | * for all versions of the driver, if they were allocated | 642 | * for all versions of the driver, if they were allocated |
639 | */ | 643 | */ |
640 | if (pdev->irq) { | 644 | if (dd->ipath_irq) { |
641 | ipath_cdbg(VERBOSE, | 645 | ipath_cdbg(VERBOSE, "unit %u free irq %d\n", |
642 | "unit %u free_irq of irq %x\n", | 646 | dd->ipath_unit, dd->ipath_irq); |
643 | dd->ipath_unit, pdev->irq); | 647 | dd->ipath_f_free_irq(dd); |
644 | free_irq(pdev->irq, dd); | ||
645 | } else | 648 | } else |
646 | ipath_dbg("irq is 0, not doing free_irq " | 649 | ipath_dbg("irq is 0, not doing free_irq " |
647 | "for unit %u\n", dd->ipath_unit); | 650 | "for unit %u\n", dd->ipath_unit); |
@@ -2005,18 +2008,8 @@ static int __init infinipath_init(void) | |||
2005 | goto bail_group; | 2008 | goto bail_group; |
2006 | } | 2009 | } |
2007 | 2010 | ||
2008 | ret = ipath_diagpkt_add(); | ||
2009 | if (ret < 0) { | ||
2010 | printk(KERN_ERR IPATH_DRV_NAME ": Unable to create " | ||
2011 | "diag data device: error %d\n", -ret); | ||
2012 | goto bail_ipathfs; | ||
2013 | } | ||
2014 | |||
2015 | goto bail; | 2011 | goto bail; |
2016 | 2012 | ||
2017 | bail_ipathfs: | ||
2018 | ipath_exit_ipathfs(); | ||
2019 | |||
2020 | bail_group: | 2013 | bail_group: |
2021 | ipath_driver_remove_group(&ipath_driver.driver); | 2014 | ipath_driver_remove_group(&ipath_driver.driver); |
2022 | 2015 | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_iba6110.c b/drivers/infiniband/hw/ipath/ipath_iba6110.c index 9e4e8d4c6e20..e57c7a351cb5 100644 --- a/drivers/infiniband/hw/ipath/ipath_iba6110.c +++ b/drivers/infiniband/hw/ipath/ipath_iba6110.c | |||
@@ -38,6 +38,7 @@ | |||
38 | 38 | ||
39 | #include <linux/pci.h> | 39 | #include <linux/pci.h> |
40 | #include <linux/delay.h> | 40 | #include <linux/delay.h> |
41 | #include <linux/htirq.h> | ||
41 | 42 | ||
42 | #include "ipath_kernel.h" | 43 | #include "ipath_kernel.h" |
43 | #include "ipath_registers.h" | 44 | #include "ipath_registers.h" |
@@ -913,49 +914,40 @@ static void slave_or_pri_blk(struct ipath_devdata *dd, struct pci_dev *pdev, | |||
913 | } | 914 | } |
914 | } | 915 | } |
915 | 916 | ||
916 | static int set_int_handler(struct ipath_devdata *dd, struct pci_dev *pdev, | 917 | static int ipath_ht_intconfig(struct ipath_devdata *dd) |
917 | int pos) | ||
918 | { | 918 | { |
919 | u32 int_handler_addr_lower; | 919 | int ret; |
920 | u32 int_handler_addr_upper; | ||
921 | u64 ihandler; | ||
922 | u32 intvec; | ||
923 | 920 | ||
924 | /* use indirection register to get the intr handler */ | 921 | if (dd->ipath_intconfig) { |
925 | pci_write_config_byte(pdev, pos + HT_INTR_REG_INDEX, 0x10); | 922 | ipath_write_kreg(dd, dd->ipath_kregs->kr_interruptconfig, |
926 | pci_read_config_dword(pdev, pos + 4, &int_handler_addr_lower); | 923 | dd->ipath_intconfig); /* interrupt address */ |
927 | pci_write_config_byte(pdev, pos + HT_INTR_REG_INDEX, 0x11); | 924 | ret = 0; |
928 | pci_read_config_dword(pdev, pos + 4, &int_handler_addr_upper); | 925 | } else { |
926 | ipath_dev_err(dd, "No interrupts enabled, couldn't setup " | ||
927 | "interrupt address\n"); | ||
928 | ret = -EINVAL; | ||
929 | } | ||
929 | 930 | ||
930 | ihandler = (u64) int_handler_addr_lower | | 931 | return ret; |
931 | ((u64) int_handler_addr_upper << 32); | 932 | } |
933 | |||
934 | static void ipath_ht_irq_update(struct pci_dev *dev, int irq, | ||
935 | struct ht_irq_msg *msg) | ||
936 | { | ||
937 | struct ipath_devdata *dd = pci_get_drvdata(dev); | ||
938 | u64 prev_intconfig = dd->ipath_intconfig; | ||
939 | |||
940 | dd->ipath_intconfig = msg->address_lo; | ||
941 | dd->ipath_intconfig |= ((u64) msg->address_hi) << 32; | ||
932 | 942 | ||
933 | /* | 943 | /* |
934 | * kernels with CONFIG_PCI_MSI set the vector in the irq field of | 944 | * If the previous value of dd->ipath_intconfig is zero, we're |
935 | * struct pci_device, so we use that to program the internal | 945 | * getting configured for the first time, and must not program the |
936 | * interrupt register (not config space) with that value. The BIOS | 946 | * intconfig register here (it will be programmed later, when the |
937 | * must still have done the basic MSI setup. | 947 | * hardware is ready). Otherwise, we should. |
938 | */ | ||
939 | intvec = pdev->irq; | ||
940 | /* | ||
941 | * clear any vector bits there; normally not set but we'll overload | ||
942 | * this for some debug purposes (setting the HTC debug register | ||
943 | * value from software, rather than GPIOs), so it might be set on a | ||
944 | * driver reload. | ||
945 | */ | 948 | */ |
946 | ihandler &= ~0xff0000; | 949 | if (prev_intconfig) |
947 | /* x86 vector goes in intrinfo[23:16] */ | 950 | ipath_ht_intconfig(dd); |
948 | ihandler |= intvec << 16; | ||
949 | ipath_cdbg(VERBOSE, "ihandler lower %x, upper %x, intvec %x, " | ||
950 | "interruptconfig %llx\n", int_handler_addr_lower, | ||
951 | int_handler_addr_upper, intvec, | ||
952 | (unsigned long long) ihandler); | ||
953 | |||
954 | /* can't program yet, so save for interrupt setup */ | ||
955 | dd->ipath_intconfig = ihandler; | ||
956 | /* keep going, so we find link control stuff also */ | ||
957 | |||
958 | return ihandler != 0; | ||
959 | } | 951 | } |
960 | 952 | ||
961 | /** | 953 | /** |
@@ -971,12 +963,19 @@ static int set_int_handler(struct ipath_devdata *dd, struct pci_dev *pdev, | |||
971 | static int ipath_setup_ht_config(struct ipath_devdata *dd, | 963 | static int ipath_setup_ht_config(struct ipath_devdata *dd, |
972 | struct pci_dev *pdev) | 964 | struct pci_dev *pdev) |
973 | { | 965 | { |
974 | int pos, ret = 0; | 966 | int pos, ret; |
975 | int ihandler = 0; | 967 | |
968 | ret = __ht_create_irq(pdev, 0, ipath_ht_irq_update); | ||
969 | if (ret < 0) { | ||
970 | ipath_dev_err(dd, "Couldn't create interrupt handler: " | ||
971 | "err %d\n", ret); | ||
972 | goto bail; | ||
973 | } | ||
974 | dd->ipath_irq = ret; | ||
975 | ret = 0; | ||
976 | 976 | ||
977 | /* | 977 | /* |
978 | * Read the capability info to find the interrupt info, and also | 978 | * Handle clearing CRC errors in linkctrl register if necessary. We |
979 | * handle clearing CRC errors in linkctrl register if necessary. We | ||
980 | * do this early, before we ever enable errors or hardware errors, | 979 | * do this early, before we ever enable errors or hardware errors, |
981 | * mostly to avoid causing the chip to enter freeze mode. | 980 | * mostly to avoid causing the chip to enter freeze mode. |
982 | */ | 981 | */ |
@@ -1000,17 +999,9 @@ static int ipath_setup_ht_config(struct ipath_devdata *dd, | |||
1000 | } | 999 | } |
1001 | if (!(cap_type & 0xE0)) | 1000 | if (!(cap_type & 0xE0)) |
1002 | slave_or_pri_blk(dd, pdev, pos, cap_type); | 1001 | slave_or_pri_blk(dd, pdev, pos, cap_type); |
1003 | else if (cap_type == HT_INTR_DISC_CONFIG) | ||
1004 | ihandler = set_int_handler(dd, pdev, pos); | ||
1005 | } while ((pos = pci_find_next_capability(pdev, pos, | 1002 | } while ((pos = pci_find_next_capability(pdev, pos, |
1006 | PCI_CAP_ID_HT))); | 1003 | PCI_CAP_ID_HT))); |
1007 | 1004 | ||
1008 | if (!ihandler) { | ||
1009 | ipath_dev_err(dd, "Couldn't find interrupt handler in " | ||
1010 | "config space\n"); | ||
1011 | ret = -ENODEV; | ||
1012 | } | ||
1013 | |||
1014 | bail: | 1005 | bail: |
1015 | return ret; | 1006 | return ret; |
1016 | } | 1007 | } |
@@ -1360,25 +1351,6 @@ static void ipath_ht_quiet_serdes(struct ipath_devdata *dd) | |||
1360 | ipath_write_kreg(dd, dd->ipath_kregs->kr_serdesconfig0, val); | 1351 | ipath_write_kreg(dd, dd->ipath_kregs->kr_serdesconfig0, val); |
1361 | } | 1352 | } |
1362 | 1353 | ||
1363 | static int ipath_ht_intconfig(struct ipath_devdata *dd) | ||
1364 | { | ||
1365 | int ret; | ||
1366 | |||
1367 | if (!dd->ipath_intconfig) { | ||
1368 | ipath_dev_err(dd, "No interrupts enabled, couldn't setup " | ||
1369 | "interrupt address\n"); | ||
1370 | ret = 1; | ||
1371 | goto bail; | ||
1372 | } | ||
1373 | |||
1374 | ipath_write_kreg(dd, dd->ipath_kregs->kr_interruptconfig, | ||
1375 | dd->ipath_intconfig); /* interrupt address */ | ||
1376 | ret = 0; | ||
1377 | |||
1378 | bail: | ||
1379 | return ret; | ||
1380 | } | ||
1381 | |||
1382 | /** | 1354 | /** |
1383 | * ipath_pe_put_tid - write a TID in chip | 1355 | * ipath_pe_put_tid - write a TID in chip |
1384 | * @dd: the infinipath device | 1356 | * @dd: the infinipath device |
@@ -1575,6 +1547,14 @@ static int ipath_ht_get_base_info(struct ipath_portdata *pd, void *kbase) | |||
1575 | return 0; | 1547 | return 0; |
1576 | } | 1548 | } |
1577 | 1549 | ||
1550 | static void ipath_ht_free_irq(struct ipath_devdata *dd) | ||
1551 | { | ||
1552 | free_irq(dd->ipath_irq, dd); | ||
1553 | ht_destroy_irq(dd->ipath_irq); | ||
1554 | dd->ipath_irq = 0; | ||
1555 | dd->ipath_intconfig = 0; | ||
1556 | } | ||
1557 | |||
1578 | /** | 1558 | /** |
1579 | * ipath_init_iba6110_funcs - set up the chip-specific function pointers | 1559 | * ipath_init_iba6110_funcs - set up the chip-specific function pointers |
1580 | * @dd: the infinipath device | 1560 | * @dd: the infinipath device |
@@ -1598,6 +1578,7 @@ void ipath_init_iba6110_funcs(struct ipath_devdata *dd) | |||
1598 | dd->ipath_f_cleanup = ipath_setup_ht_cleanup; | 1578 | dd->ipath_f_cleanup = ipath_setup_ht_cleanup; |
1599 | dd->ipath_f_setextled = ipath_setup_ht_setextled; | 1579 | dd->ipath_f_setextled = ipath_setup_ht_setextled; |
1600 | dd->ipath_f_get_base_info = ipath_ht_get_base_info; | 1580 | dd->ipath_f_get_base_info = ipath_ht_get_base_info; |
1581 | dd->ipath_f_free_irq = ipath_ht_free_irq; | ||
1601 | 1582 | ||
1602 | /* | 1583 | /* |
1603 | * initialize chip-specific variables | 1584 | * initialize chip-specific variables |
diff --git a/drivers/infiniband/hw/ipath/ipath_iba6120.c b/drivers/infiniband/hw/ipath/ipath_iba6120.c index a72ab9de386a..6af89683f710 100644 --- a/drivers/infiniband/hw/ipath/ipath_iba6120.c +++ b/drivers/infiniband/hw/ipath/ipath_iba6120.c | |||
@@ -851,6 +851,7 @@ static int ipath_setup_pe_config(struct ipath_devdata *dd, | |||
851 | int pos, ret; | 851 | int pos, ret; |
852 | 852 | ||
853 | dd->ipath_msi_lo = 0; /* used as a flag during reset processing */ | 853 | dd->ipath_msi_lo = 0; /* used as a flag during reset processing */ |
854 | dd->ipath_irq = pdev->irq; | ||
854 | ret = pci_enable_msi(dd->pcidev); | 855 | ret = pci_enable_msi(dd->pcidev); |
855 | if (ret) | 856 | if (ret) |
856 | ipath_dev_err(dd, "pci_enable_msi failed: %d, " | 857 | ipath_dev_err(dd, "pci_enable_msi failed: %d, " |
@@ -1323,6 +1324,12 @@ done: | |||
1323 | return 0; | 1324 | return 0; |
1324 | } | 1325 | } |
1325 | 1326 | ||
1327 | static void ipath_pe_free_irq(struct ipath_devdata *dd) | ||
1328 | { | ||
1329 | free_irq(dd->ipath_irq, dd); | ||
1330 | dd->ipath_irq = 0; | ||
1331 | } | ||
1332 | |||
1326 | /** | 1333 | /** |
1327 | * ipath_init_iba6120_funcs - set up the chip-specific function pointers | 1334 | * ipath_init_iba6120_funcs - set up the chip-specific function pointers |
1328 | * @dd: the infinipath device | 1335 | * @dd: the infinipath device |
@@ -1349,6 +1356,7 @@ void ipath_init_iba6120_funcs(struct ipath_devdata *dd) | |||
1349 | dd->ipath_f_cleanup = ipath_setup_pe_cleanup; | 1356 | dd->ipath_f_cleanup = ipath_setup_pe_cleanup; |
1350 | dd->ipath_f_setextled = ipath_setup_pe_setextled; | 1357 | dd->ipath_f_setextled = ipath_setup_pe_setextled; |
1351 | dd->ipath_f_get_base_info = ipath_pe_get_base_info; | 1358 | dd->ipath_f_get_base_info = ipath_pe_get_base_info; |
1359 | dd->ipath_f_free_irq = ipath_pe_free_irq; | ||
1352 | 1360 | ||
1353 | /* initialize chip-specific variables */ | 1361 | /* initialize chip-specific variables */ |
1354 | dd->ipath_f_tidtemplate = ipath_pe_tidtemplate; | 1362 | dd->ipath_f_tidtemplate = ipath_pe_tidtemplate; |
diff --git a/drivers/infiniband/hw/ipath/ipath_intr.c b/drivers/infiniband/hw/ipath/ipath_intr.c index d9079ee12030..5652a550d442 100644 --- a/drivers/infiniband/hw/ipath/ipath_intr.c +++ b/drivers/infiniband/hw/ipath/ipath_intr.c | |||
@@ -710,14 +710,14 @@ static void ipath_bad_intr(struct ipath_devdata *dd, u32 * unexpectp) | |||
710 | * linuxbios development work, and it may happen in | 710 | * linuxbios development work, and it may happen in |
711 | * the future again. | 711 | * the future again. |
712 | */ | 712 | */ |
713 | if (dd->pcidev && dd->pcidev->irq) { | 713 | if (dd->pcidev && dd->ipath_irq) { |
714 | ipath_dev_err(dd, "Now %u unexpected " | 714 | ipath_dev_err(dd, "Now %u unexpected " |
715 | "interrupts, unregistering " | 715 | "interrupts, unregistering " |
716 | "interrupt handler\n", | 716 | "interrupt handler\n", |
717 | *unexpectp); | 717 | *unexpectp); |
718 | ipath_dbg("free_irq of irq %x\n", | 718 | ipath_dbg("free_irq of irq %d\n", |
719 | dd->pcidev->irq); | 719 | dd->ipath_irq); |
720 | free_irq(dd->pcidev->irq, dd); | 720 | dd->ipath_f_free_irq(dd); |
721 | } | 721 | } |
722 | } | 722 | } |
723 | if (ipath_read_kreg32(dd, dd->ipath_kregs->kr_intmask)) { | 723 | if (ipath_read_kreg32(dd, dd->ipath_kregs->kr_intmask)) { |
@@ -753,7 +753,7 @@ static void ipath_bad_regread(struct ipath_devdata *dd) | |||
753 | if (allbits == 2) { | 753 | if (allbits == 2) { |
754 | ipath_dev_err(dd, "Still bad interrupt status, " | 754 | ipath_dev_err(dd, "Still bad interrupt status, " |
755 | "unregistering interrupt\n"); | 755 | "unregistering interrupt\n"); |
756 | free_irq(dd->pcidev->irq, dd); | 756 | dd->ipath_f_free_irq(dd); |
757 | } else if (allbits > 2) { | 757 | } else if (allbits > 2) { |
758 | if ((allbits % 10000) == 0) | 758 | if ((allbits % 10000) == 0) |
759 | printk("."); | 759 | printk("."); |
diff --git a/drivers/infiniband/hw/ipath/ipath_kernel.h b/drivers/infiniband/hw/ipath/ipath_kernel.h index 7c436697d0e4..986b2125b8f5 100644 --- a/drivers/infiniband/hw/ipath/ipath_kernel.h +++ b/drivers/infiniband/hw/ipath/ipath_kernel.h | |||
@@ -213,6 +213,8 @@ struct ipath_devdata { | |||
213 | void (*ipath_f_setextled)(struct ipath_devdata *, u64, u64); | 213 | void (*ipath_f_setextled)(struct ipath_devdata *, u64, u64); |
214 | /* fill out chip-specific fields */ | 214 | /* fill out chip-specific fields */ |
215 | int (*ipath_f_get_base_info)(struct ipath_portdata *, void *); | 215 | int (*ipath_f_get_base_info)(struct ipath_portdata *, void *); |
216 | /* free irq */ | ||
217 | void (*ipath_f_free_irq)(struct ipath_devdata *); | ||
216 | struct ipath_ibdev *verbs_dev; | 218 | struct ipath_ibdev *verbs_dev; |
217 | struct timer_list verbs_timer; | 219 | struct timer_list verbs_timer; |
218 | /* total dwords sent (summed from counter) */ | 220 | /* total dwords sent (summed from counter) */ |
@@ -328,6 +330,8 @@ struct ipath_devdata { | |||
328 | /* so we can rewrite it after a chip reset */ | 330 | /* so we can rewrite it after a chip reset */ |
329 | u32 ipath_pcibar1; | 331 | u32 ipath_pcibar1; |
330 | 332 | ||
333 | /* interrupt number */ | ||
334 | int ipath_irq; | ||
331 | /* HT/PCI Vendor ID (here for NodeInfo) */ | 335 | /* HT/PCI Vendor ID (here for NodeInfo) */ |
332 | u16 ipath_vendorid; | 336 | u16 ipath_vendorid; |
333 | /* HT/PCI Device ID (here for NodeInfo) */ | 337 | /* HT/PCI Device ID (here for NodeInfo) */ |
@@ -869,9 +873,6 @@ int ipath_device_create_group(struct device *, struct ipath_devdata *); | |||
869 | void ipath_device_remove_group(struct device *, struct ipath_devdata *); | 873 | void ipath_device_remove_group(struct device *, struct ipath_devdata *); |
870 | int ipath_expose_reset(struct device *); | 874 | int ipath_expose_reset(struct device *); |
871 | 875 | ||
872 | int ipath_diagpkt_add(void); | ||
873 | void ipath_diagpkt_remove(void); | ||
874 | |||
875 | int ipath_init_ipathfs(void); | 876 | int ipath_init_ipathfs(void); |
876 | void ipath_exit_ipathfs(void); | 877 | void ipath_exit_ipathfs(void); |
877 | int ipathfs_add_device(struct ipath_devdata *); | 878 | int ipathfs_add_device(struct ipath_devdata *); |
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c index 99a94d710935..768df7265b81 100644 --- a/drivers/infiniband/hw/mthca/mthca_cmd.c +++ b/drivers/infiniband/hw/mthca/mthca_cmd.c | |||
@@ -1820,11 +1820,11 @@ int mthca_MAD_IFC(struct mthca_dev *dev, int ignore_mkey, int ignore_bkey, | |||
1820 | 1820 | ||
1821 | #define MAD_IFC_BOX_SIZE 0x400 | 1821 | #define MAD_IFC_BOX_SIZE 0x400 |
1822 | #define MAD_IFC_MY_QPN_OFFSET 0x100 | 1822 | #define MAD_IFC_MY_QPN_OFFSET 0x100 |
1823 | #define MAD_IFC_RQPN_OFFSET 0x104 | 1823 | #define MAD_IFC_RQPN_OFFSET 0x108 |
1824 | #define MAD_IFC_SL_OFFSET 0x108 | 1824 | #define MAD_IFC_SL_OFFSET 0x10c |
1825 | #define MAD_IFC_G_PATH_OFFSET 0x109 | 1825 | #define MAD_IFC_G_PATH_OFFSET 0x10d |
1826 | #define MAD_IFC_RLID_OFFSET 0x10a | 1826 | #define MAD_IFC_RLID_OFFSET 0x10e |
1827 | #define MAD_IFC_PKEY_OFFSET 0x10e | 1827 | #define MAD_IFC_PKEY_OFFSET 0x112 |
1828 | #define MAD_IFC_GRH_OFFSET 0x140 | 1828 | #define MAD_IFC_GRH_OFFSET 0x140 |
1829 | 1829 | ||
1830 | inmailbox = mthca_alloc_mailbox(dev, GFP_KERNEL); | 1830 | inmailbox = mthca_alloc_mailbox(dev, GFP_KERNEL); |
@@ -1862,7 +1862,7 @@ int mthca_MAD_IFC(struct mthca_dev *dev, int ignore_mkey, int ignore_bkey, | |||
1862 | 1862 | ||
1863 | val = in_wc->dlid_path_bits | | 1863 | val = in_wc->dlid_path_bits | |
1864 | (in_wc->wc_flags & IB_WC_GRH ? 0x80 : 0); | 1864 | (in_wc->wc_flags & IB_WC_GRH ? 0x80 : 0); |
1865 | MTHCA_PUT(inbox, val, MAD_IFC_GRH_OFFSET); | 1865 | MTHCA_PUT(inbox, val, MAD_IFC_G_PATH_OFFSET); |
1866 | 1866 | ||
1867 | MTHCA_PUT(inbox, in_wc->slid, MAD_IFC_RLID_OFFSET); | 1867 | MTHCA_PUT(inbox, in_wc->slid, MAD_IFC_RLID_OFFSET); |
1868 | MTHCA_PUT(inbox, in_wc->pkey_index, MAD_IFC_PKEY_OFFSET); | 1868 | MTHCA_PUT(inbox, in_wc->pkey_index, MAD_IFC_PKEY_OFFSET); |
@@ -1870,7 +1870,7 @@ int mthca_MAD_IFC(struct mthca_dev *dev, int ignore_mkey, int ignore_bkey, | |||
1870 | if (in_grh) | 1870 | if (in_grh) |
1871 | memcpy(inbox + MAD_IFC_GRH_OFFSET, in_grh, 40); | 1871 | memcpy(inbox + MAD_IFC_GRH_OFFSET, in_grh, 40); |
1872 | 1872 | ||
1873 | op_modifier |= 0x10; | 1873 | op_modifier |= 0x4; |
1874 | 1874 | ||
1875 | in_modifier |= in_wc->slid << 16; | 1875 | in_modifier |= in_wc->slid << 16; |
1876 | } | 1876 | } |
diff --git a/drivers/infiniband/hw/mthca/mthca_cq.c b/drivers/infiniband/hw/mthca/mthca_cq.c index e393681ba7d4..149b36901239 100644 --- a/drivers/infiniband/hw/mthca/mthca_cq.c +++ b/drivers/infiniband/hw/mthca/mthca_cq.c | |||
@@ -39,6 +39,8 @@ | |||
39 | #include <linux/init.h> | 39 | #include <linux/init.h> |
40 | #include <linux/hardirq.h> | 40 | #include <linux/hardirq.h> |
41 | 41 | ||
42 | #include <asm/io.h> | ||
43 | |||
42 | #include <rdma/ib_pack.h> | 44 | #include <rdma/ib_pack.h> |
43 | 45 | ||
44 | #include "mthca_dev.h" | 46 | #include "mthca_dev.h" |
@@ -210,6 +212,11 @@ static inline void update_cons_index(struct mthca_dev *dev, struct mthca_cq *cq, | |||
210 | mthca_write64(doorbell, | 212 | mthca_write64(doorbell, |
211 | dev->kar + MTHCA_CQ_DOORBELL, | 213 | dev->kar + MTHCA_CQ_DOORBELL, |
212 | MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock)); | 214 | MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock)); |
215 | /* | ||
216 | * Make sure doorbells don't leak out of CQ spinlock | ||
217 | * and reach the HCA out of order: | ||
218 | */ | ||
219 | mmiowb(); | ||
213 | } | 220 | } |
214 | } | 221 | } |
215 | 222 | ||
diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c index 5e5c58b9920b..6a7822e0fc19 100644 --- a/drivers/infiniband/hw/mthca/mthca_qp.c +++ b/drivers/infiniband/hw/mthca/mthca_qp.c | |||
@@ -39,6 +39,8 @@ | |||
39 | #include <linux/string.h> | 39 | #include <linux/string.h> |
40 | #include <linux/slab.h> | 40 | #include <linux/slab.h> |
41 | 41 | ||
42 | #include <asm/io.h> | ||
43 | |||
42 | #include <rdma/ib_verbs.h> | 44 | #include <rdma/ib_verbs.h> |
43 | #include <rdma/ib_cache.h> | 45 | #include <rdma/ib_cache.h> |
44 | #include <rdma/ib_pack.h> | 46 | #include <rdma/ib_pack.h> |
@@ -1732,6 +1734,11 @@ out: | |||
1732 | mthca_write64(doorbell, | 1734 | mthca_write64(doorbell, |
1733 | dev->kar + MTHCA_SEND_DOORBELL, | 1735 | dev->kar + MTHCA_SEND_DOORBELL, |
1734 | MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock)); | 1736 | MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock)); |
1737 | /* | ||
1738 | * Make sure doorbells don't leak out of SQ spinlock | ||
1739 | * and reach the HCA out of order: | ||
1740 | */ | ||
1741 | mmiowb(); | ||
1735 | } | 1742 | } |
1736 | 1743 | ||
1737 | qp->sq.next_ind = ind; | 1744 | qp->sq.next_ind = ind; |
@@ -1851,6 +1858,12 @@ out: | |||
1851 | qp->rq.next_ind = ind; | 1858 | qp->rq.next_ind = ind; |
1852 | qp->rq.head += nreq; | 1859 | qp->rq.head += nreq; |
1853 | 1860 | ||
1861 | /* | ||
1862 | * Make sure doorbells don't leak out of RQ spinlock and reach | ||
1863 | * the HCA out of order: | ||
1864 | */ | ||
1865 | mmiowb(); | ||
1866 | |||
1854 | spin_unlock_irqrestore(&qp->rq.lock, flags); | 1867 | spin_unlock_irqrestore(&qp->rq.lock, flags); |
1855 | return err; | 1868 | return err; |
1856 | } | 1869 | } |
@@ -2112,6 +2125,12 @@ out: | |||
2112 | MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock)); | 2125 | MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock)); |
2113 | } | 2126 | } |
2114 | 2127 | ||
2128 | /* | ||
2129 | * Make sure doorbells don't leak out of SQ spinlock and reach | ||
2130 | * the HCA out of order: | ||
2131 | */ | ||
2132 | mmiowb(); | ||
2133 | |||
2115 | spin_unlock_irqrestore(&qp->sq.lock, flags); | 2134 | spin_unlock_irqrestore(&qp->sq.lock, flags); |
2116 | return err; | 2135 | return err; |
2117 | } | 2136 | } |
diff --git a/drivers/infiniband/hw/mthca/mthca_srq.c b/drivers/infiniband/hw/mthca/mthca_srq.c index 92a72f521528..f5d7677d1079 100644 --- a/drivers/infiniband/hw/mthca/mthca_srq.c +++ b/drivers/infiniband/hw/mthca/mthca_srq.c | |||
@@ -35,6 +35,8 @@ | |||
35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
36 | #include <linux/string.h> | 36 | #include <linux/string.h> |
37 | 37 | ||
38 | #include <asm/io.h> | ||
39 | |||
38 | #include "mthca_dev.h" | 40 | #include "mthca_dev.h" |
39 | #include "mthca_cmd.h" | 41 | #include "mthca_cmd.h" |
40 | #include "mthca_memfree.h" | 42 | #include "mthca_memfree.h" |
@@ -595,6 +597,12 @@ int mthca_tavor_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr, | |||
595 | MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock)); | 597 | MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock)); |
596 | } | 598 | } |
597 | 599 | ||
600 | /* | ||
601 | * Make sure doorbells don't leak out of SRQ spinlock and | ||
602 | * reach the HCA out of order: | ||
603 | */ | ||
604 | mmiowb(); | ||
605 | |||
598 | spin_unlock_irqrestore(&srq->lock, flags); | 606 | spin_unlock_irqrestore(&srq->lock, flags); |
599 | return err; | 607 | return err; |
600 | } | 608 | } |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 1eaf00e9862c..85522daeb946 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c | |||
@@ -49,6 +49,8 @@ | |||
49 | 49 | ||
50 | #include <net/dst.h> | 50 | #include <net/dst.h> |
51 | 51 | ||
52 | #define IPOIB_QPN(ha) (be32_to_cpup((__be32 *) ha) & 0xffffff) | ||
53 | |||
52 | MODULE_AUTHOR("Roland Dreier"); | 54 | MODULE_AUTHOR("Roland Dreier"); |
53 | MODULE_DESCRIPTION("IP-over-InfiniBand net driver"); | 55 | MODULE_DESCRIPTION("IP-over-InfiniBand net driver"); |
54 | MODULE_LICENSE("Dual BSD/GPL"); | 56 | MODULE_LICENSE("Dual BSD/GPL"); |
@@ -520,8 +522,7 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev) | |||
520 | memcpy(&neigh->dgid.raw, &path->pathrec.dgid.raw, | 522 | memcpy(&neigh->dgid.raw, &path->pathrec.dgid.raw, |
521 | sizeof(union ib_gid)); | 523 | sizeof(union ib_gid)); |
522 | 524 | ||
523 | ipoib_send(dev, skb, path->ah, | 525 | ipoib_send(dev, skb, path->ah, IPOIB_QPN(skb->dst->neighbour->ha)); |
524 | be32_to_cpup((__be32 *) skb->dst->neighbour->ha)); | ||
525 | } else { | 526 | } else { |
526 | neigh->ah = NULL; | 527 | neigh->ah = NULL; |
527 | __skb_queue_tail(&neigh->queue, skb); | 528 | __skb_queue_tail(&neigh->queue, skb); |
@@ -599,8 +600,7 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev, | |||
599 | ipoib_dbg(priv, "Send unicast ARP to %04x\n", | 600 | ipoib_dbg(priv, "Send unicast ARP to %04x\n", |
600 | be16_to_cpu(path->pathrec.dlid)); | 601 | be16_to_cpu(path->pathrec.dlid)); |
601 | 602 | ||
602 | ipoib_send(dev, skb, path->ah, | 603 | ipoib_send(dev, skb, path->ah, IPOIB_QPN(phdr->hwaddr)); |
603 | be32_to_cpup((__be32 *) phdr->hwaddr)); | ||
604 | } else if ((path->query || !path_rec_start(dev, path)) && | 604 | } else if ((path->query || !path_rec_start(dev, path)) && |
605 | skb_queue_len(&path->queue) < IPOIB_MAX_PATH_REC_QUEUE) { | 605 | skb_queue_len(&path->queue) < IPOIB_MAX_PATH_REC_QUEUE) { |
606 | /* put pseudoheader back on for next time */ | 606 | /* put pseudoheader back on for next time */ |
@@ -661,8 +661,7 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
661 | goto out; | 661 | goto out; |
662 | } | 662 | } |
663 | 663 | ||
664 | ipoib_send(dev, skb, neigh->ah, | 664 | ipoib_send(dev, skb, neigh->ah, IPOIB_QPN(skb->dst->neighbour->ha)); |
665 | be32_to_cpup((__be32 *) skb->dst->neighbour->ha)); | ||
666 | goto out; | 665 | goto out; |
667 | } | 666 | } |
668 | 667 | ||
@@ -694,7 +693,7 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
694 | IPOIB_GID_FMT "\n", | 693 | IPOIB_GID_FMT "\n", |
695 | skb->dst ? "neigh" : "dst", | 694 | skb->dst ? "neigh" : "dst", |
696 | be16_to_cpup((__be16 *) skb->data), | 695 | be16_to_cpup((__be16 *) skb->data), |
697 | be32_to_cpup((__be32 *) phdr->hwaddr), | 696 | IPOIB_QPN(phdr->hwaddr), |
698 | IPOIB_GID_RAW_ARG(phdr->hwaddr + 4)); | 697 | IPOIB_GID_RAW_ARG(phdr->hwaddr + 4)); |
699 | dev_kfree_skb_any(skb); | 698 | dev_kfree_skb_any(skb); |
700 | ++priv->stats.tx_dropped; | 699 | ++priv->stats.tx_dropped; |
@@ -777,7 +776,7 @@ static void ipoib_neigh_destructor(struct neighbour *n) | |||
777 | 776 | ||
778 | ipoib_dbg(priv, | 777 | ipoib_dbg(priv, |
779 | "neigh_destructor for %06x " IPOIB_GID_FMT "\n", | 778 | "neigh_destructor for %06x " IPOIB_GID_FMT "\n", |
780 | be32_to_cpup((__be32 *) n->ha), | 779 | IPOIB_QPN(n->ha), |
781 | IPOIB_GID_RAW_ARG(n->ha + 4)); | 780 | IPOIB_GID_RAW_ARG(n->ha + 4)); |
782 | 781 | ||
783 | spin_lock_irqsave(&priv->lock, flags); | 782 | spin_lock_irqsave(&priv->lock, flags); |
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index eb6f98d82289..9b2041e25d59 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.c +++ b/drivers/infiniband/ulp/iser/iscsi_iser.c | |||
@@ -363,11 +363,11 @@ iscsi_iser_conn_start(struct iscsi_cls_conn *cls_conn) | |||
363 | struct iscsi_conn *conn = cls_conn->dd_data; | 363 | struct iscsi_conn *conn = cls_conn->dd_data; |
364 | int err; | 364 | int err; |
365 | 365 | ||
366 | err = iscsi_conn_start(cls_conn); | 366 | err = iser_conn_set_full_featured_mode(conn); |
367 | if (err) | 367 | if (err) |
368 | return err; | 368 | return err; |
369 | 369 | ||
370 | return iser_conn_set_full_featured_mode(conn); | 370 | return iscsi_conn_start(cls_conn); |
371 | } | 371 | } |
372 | 372 | ||
373 | static struct iscsi_transport iscsi_iser_transport; | 373 | static struct iscsi_transport iscsi_iser_transport; |
diff --git a/drivers/input/gameport/fm801-gp.c b/drivers/input/gameport/fm801-gp.c index 90de5afe03c2..1dec00e20dbc 100644 --- a/drivers/input/gameport/fm801-gp.c +++ b/drivers/input/gameport/fm801-gp.c | |||
@@ -82,17 +82,19 @@ static int __devinit fm801_gp_probe(struct pci_dev *pci, const struct pci_device | |||
82 | { | 82 | { |
83 | struct fm801_gp *gp; | 83 | struct fm801_gp *gp; |
84 | struct gameport *port; | 84 | struct gameport *port; |
85 | int error; | ||
85 | 86 | ||
86 | gp = kzalloc(sizeof(struct fm801_gp), GFP_KERNEL); | 87 | gp = kzalloc(sizeof(struct fm801_gp), GFP_KERNEL); |
87 | port = gameport_allocate_port(); | 88 | port = gameport_allocate_port(); |
88 | if (!gp || !port) { | 89 | if (!gp || !port) { |
89 | printk(KERN_ERR "fm801-gp: Memory allocation failed\n"); | 90 | printk(KERN_ERR "fm801-gp: Memory allocation failed\n"); |
90 | kfree(gp); | 91 | error = -ENOMEM; |
91 | gameport_free_port(port); | 92 | goto err_out_free; |
92 | return -ENOMEM; | ||
93 | } | 93 | } |
94 | 94 | ||
95 | pci_enable_device(pci); | 95 | error = pci_enable_device(pci); |
96 | if (error) | ||
97 | goto err_out_free; | ||
96 | 98 | ||
97 | port->open = fm801_gp_open; | 99 | port->open = fm801_gp_open; |
98 | #ifdef HAVE_COOKED | 100 | #ifdef HAVE_COOKED |
@@ -108,9 +110,8 @@ static int __devinit fm801_gp_probe(struct pci_dev *pci, const struct pci_device | |||
108 | if (!gp->res_port) { | 110 | if (!gp->res_port) { |
109 | printk(KERN_DEBUG "fm801-gp: unable to grab region 0x%x-0x%x\n", | 111 | printk(KERN_DEBUG "fm801-gp: unable to grab region 0x%x-0x%x\n", |
110 | port->io, port->io + 0x0f); | 112 | port->io, port->io + 0x0f); |
111 | gameport_free_port(port); | 113 | error = -EBUSY; |
112 | kfree(gp); | 114 | goto err_out_disable_dev; |
113 | return -EBUSY; | ||
114 | } | 115 | } |
115 | 116 | ||
116 | pci_set_drvdata(pci, gp); | 117 | pci_set_drvdata(pci, gp); |
@@ -119,6 +120,13 @@ static int __devinit fm801_gp_probe(struct pci_dev *pci, const struct pci_device | |||
119 | gameport_register_port(port); | 120 | gameport_register_port(port); |
120 | 121 | ||
121 | return 0; | 122 | return 0; |
123 | |||
124 | err_out_disable_dev: | ||
125 | pci_disable_device(pci); | ||
126 | err_out_free: | ||
127 | gameport_free_port(port); | ||
128 | kfree(gp); | ||
129 | return error; | ||
122 | } | 130 | } |
123 | 131 | ||
124 | static void __devexit fm801_gp_remove(struct pci_dev *pci) | 132 | static void __devexit fm801_gp_remove(struct pci_dev *pci) |
diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c index 3f47ae55c6f3..a0af97efe6ac 100644 --- a/drivers/input/gameport/gameport.c +++ b/drivers/input/gameport/gameport.c | |||
@@ -191,6 +191,8 @@ static void gameport_run_poll_handler(unsigned long d) | |||
191 | 191 | ||
192 | static void gameport_bind_driver(struct gameport *gameport, struct gameport_driver *drv) | 192 | static void gameport_bind_driver(struct gameport *gameport, struct gameport_driver *drv) |
193 | { | 193 | { |
194 | int error; | ||
195 | |||
194 | down_write(&gameport_bus.subsys.rwsem); | 196 | down_write(&gameport_bus.subsys.rwsem); |
195 | 197 | ||
196 | gameport->dev.driver = &drv->driver; | 198 | gameport->dev.driver = &drv->driver; |
@@ -198,8 +200,20 @@ static void gameport_bind_driver(struct gameport *gameport, struct gameport_driv | |||
198 | gameport->dev.driver = NULL; | 200 | gameport->dev.driver = NULL; |
199 | goto out; | 201 | goto out; |
200 | } | 202 | } |
201 | device_bind_driver(&gameport->dev); | 203 | |
202 | out: | 204 | error = device_bind_driver(&gameport->dev); |
205 | if (error) { | ||
206 | printk(KERN_WARNING | ||
207 | "gameport: device_bind_driver() failed " | ||
208 | "for %s (%s) and %s, error: %d\n", | ||
209 | gameport->phys, gameport->name, | ||
210 | drv->description, error); | ||
211 | drv->disconnect(gameport); | ||
212 | gameport->dev.driver = NULL; | ||
213 | goto out; | ||
214 | } | ||
215 | |||
216 | out: | ||
203 | up_write(&gameport_bus.subsys.rwsem); | 217 | up_write(&gameport_bus.subsys.rwsem); |
204 | } | 218 | } |
205 | 219 | ||
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index b6ef9eaad1dc..cbb93669d1ce 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c | |||
@@ -221,6 +221,7 @@ struct atkbd { | |||
221 | unsigned long xl_bit; | 221 | unsigned long xl_bit; |
222 | unsigned int last; | 222 | unsigned int last; |
223 | unsigned long time; | 223 | unsigned long time; |
224 | unsigned long err_count; | ||
224 | 225 | ||
225 | struct work_struct event_work; | 226 | struct work_struct event_work; |
226 | struct mutex event_mutex; | 227 | struct mutex event_mutex; |
@@ -234,11 +235,13 @@ static ssize_t atkbd_attr_set_helper(struct device *dev, const char *buf, size_t | |||
234 | #define ATKBD_DEFINE_ATTR(_name) \ | 235 | #define ATKBD_DEFINE_ATTR(_name) \ |
235 | static ssize_t atkbd_show_##_name(struct atkbd *, char *); \ | 236 | static ssize_t atkbd_show_##_name(struct atkbd *, char *); \ |
236 | static ssize_t atkbd_set_##_name(struct atkbd *, const char *, size_t); \ | 237 | static ssize_t atkbd_set_##_name(struct atkbd *, const char *, size_t); \ |
237 | static ssize_t atkbd_do_show_##_name(struct device *d, struct device_attribute *attr, char *b) \ | 238 | static ssize_t atkbd_do_show_##_name(struct device *d, \ |
239 | struct device_attribute *attr, char *b) \ | ||
238 | { \ | 240 | { \ |
239 | return atkbd_attr_show_helper(d, b, atkbd_show_##_name); \ | 241 | return atkbd_attr_show_helper(d, b, atkbd_show_##_name); \ |
240 | } \ | 242 | } \ |
241 | static ssize_t atkbd_do_set_##_name(struct device *d, struct device_attribute *attr, const char *b, size_t s) \ | 243 | static ssize_t atkbd_do_set_##_name(struct device *d, \ |
244 | struct device_attribute *attr, const char *b, size_t s) \ | ||
242 | { \ | 245 | { \ |
243 | return atkbd_attr_set_helper(d, b, s, atkbd_set_##_name); \ | 246 | return atkbd_attr_set_helper(d, b, s, atkbd_set_##_name); \ |
244 | } \ | 247 | } \ |
@@ -251,6 +254,32 @@ ATKBD_DEFINE_ATTR(set); | |||
251 | ATKBD_DEFINE_ATTR(softrepeat); | 254 | ATKBD_DEFINE_ATTR(softrepeat); |
252 | ATKBD_DEFINE_ATTR(softraw); | 255 | ATKBD_DEFINE_ATTR(softraw); |
253 | 256 | ||
257 | #define ATKBD_DEFINE_RO_ATTR(_name) \ | ||
258 | static ssize_t atkbd_show_##_name(struct atkbd *, char *); \ | ||
259 | static ssize_t atkbd_do_show_##_name(struct device *d, \ | ||
260 | struct device_attribute *attr, char *b) \ | ||
261 | { \ | ||
262 | return atkbd_attr_show_helper(d, b, atkbd_show_##_name); \ | ||
263 | } \ | ||
264 | static struct device_attribute atkbd_attr_##_name = \ | ||
265 | __ATTR(_name, S_IRUGO, atkbd_do_show_##_name, NULL); | ||
266 | |||
267 | ATKBD_DEFINE_RO_ATTR(err_count); | ||
268 | |||
269 | static struct attribute *atkbd_attributes[] = { | ||
270 | &atkbd_attr_extra.attr, | ||
271 | &atkbd_attr_scroll.attr, | ||
272 | &atkbd_attr_set.attr, | ||
273 | &atkbd_attr_softrepeat.attr, | ||
274 | &atkbd_attr_softraw.attr, | ||
275 | &atkbd_attr_err_count.attr, | ||
276 | NULL | ||
277 | }; | ||
278 | |||
279 | static struct attribute_group atkbd_attribute_group = { | ||
280 | .attrs = atkbd_attributes, | ||
281 | }; | ||
282 | |||
254 | static const unsigned int xl_table[] = { | 283 | static const unsigned int xl_table[] = { |
255 | ATKBD_RET_BAT, ATKBD_RET_ERR, ATKBD_RET_ACK, | 284 | ATKBD_RET_BAT, ATKBD_RET_ERR, ATKBD_RET_ACK, |
256 | ATKBD_RET_NAK, ATKBD_RET_HANJA, ATKBD_RET_HANGEUL, | 285 | ATKBD_RET_NAK, ATKBD_RET_HANJA, ATKBD_RET_HANGEUL, |
@@ -396,7 +425,10 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, | |||
396 | add_release_event = 1; | 425 | add_release_event = 1; |
397 | break; | 426 | break; |
398 | case ATKBD_RET_ERR: | 427 | case ATKBD_RET_ERR: |
428 | atkbd->err_count++; | ||
429 | #ifdef ATKBD_DEBUG | ||
399 | printk(KERN_DEBUG "atkbd.c: Keyboard on %s reports too many keys pressed.\n", serio->phys); | 430 | printk(KERN_DEBUG "atkbd.c: Keyboard on %s reports too many keys pressed.\n", serio->phys); |
431 | #endif | ||
400 | goto out; | 432 | goto out; |
401 | } | 433 | } |
402 | 434 | ||
@@ -786,12 +818,7 @@ static void atkbd_disconnect(struct serio *serio) | |||
786 | synchronize_sched(); /* Allow atkbd_interrupt()s to complete. */ | 818 | synchronize_sched(); /* Allow atkbd_interrupt()s to complete. */ |
787 | flush_scheduled_work(); | 819 | flush_scheduled_work(); |
788 | 820 | ||
789 | device_remove_file(&serio->dev, &atkbd_attr_extra); | 821 | sysfs_remove_group(&serio->dev.kobj, &atkbd_attribute_group); |
790 | device_remove_file(&serio->dev, &atkbd_attr_scroll); | ||
791 | device_remove_file(&serio->dev, &atkbd_attr_set); | ||
792 | device_remove_file(&serio->dev, &atkbd_attr_softrepeat); | ||
793 | device_remove_file(&serio->dev, &atkbd_attr_softraw); | ||
794 | |||
795 | input_unregister_device(atkbd->dev); | 822 | input_unregister_device(atkbd->dev); |
796 | serio_close(serio); | 823 | serio_close(serio); |
797 | serio_set_drvdata(serio, NULL); | 824 | serio_set_drvdata(serio, NULL); |
@@ -961,11 +988,7 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv) | |||
961 | atkbd_set_keycode_table(atkbd); | 988 | atkbd_set_keycode_table(atkbd); |
962 | atkbd_set_device_attrs(atkbd); | 989 | atkbd_set_device_attrs(atkbd); |
963 | 990 | ||
964 | device_create_file(&serio->dev, &atkbd_attr_extra); | 991 | sysfs_create_group(&serio->dev.kobj, &atkbd_attribute_group); |
965 | device_create_file(&serio->dev, &atkbd_attr_scroll); | ||
966 | device_create_file(&serio->dev, &atkbd_attr_set); | ||
967 | device_create_file(&serio->dev, &atkbd_attr_softrepeat); | ||
968 | device_create_file(&serio->dev, &atkbd_attr_softraw); | ||
969 | 992 | ||
970 | atkbd_enable(atkbd); | 993 | atkbd_enable(atkbd); |
971 | 994 | ||
@@ -1259,6 +1282,11 @@ static ssize_t atkbd_set_softraw(struct atkbd *atkbd, const char *buf, size_t co | |||
1259 | return count; | 1282 | return count; |
1260 | } | 1283 | } |
1261 | 1284 | ||
1285 | static ssize_t atkbd_show_err_count(struct atkbd *atkbd, char *buf) | ||
1286 | { | ||
1287 | return sprintf(buf, "%lu\n", atkbd->err_count); | ||
1288 | } | ||
1289 | |||
1262 | 1290 | ||
1263 | static int __init atkbd_init(void) | 1291 | static int __init atkbd_init(void) |
1264 | { | 1292 | { |
diff --git a/drivers/input/keyboard/corgikbd.c b/drivers/input/keyboard/corgikbd.c index cb70970625b5..befdd6006b50 100644 --- a/drivers/input/keyboard/corgikbd.c +++ b/drivers/input/keyboard/corgikbd.c | |||
@@ -207,7 +207,7 @@ static irqreturn_t corgikbd_interrupt(int irq, void *dev_id) | |||
207 | static void corgikbd_timer_callback(unsigned long data) | 207 | static void corgikbd_timer_callback(unsigned long data) |
208 | { | 208 | { |
209 | struct corgikbd *corgikbd_data = (struct corgikbd *) data; | 209 | struct corgikbd *corgikbd_data = (struct corgikbd *) data; |
210 | corgikbd_scankeyboard(corgikbd_data, NULL); | 210 | corgikbd_scankeyboard(corgikbd_data); |
211 | } | 211 | } |
212 | 212 | ||
213 | /* | 213 | /* |
diff --git a/drivers/input/keyboard/lkkbd.c b/drivers/input/keyboard/lkkbd.c index 708d5a1bc3d2..979b93e33da7 100644 --- a/drivers/input/keyboard/lkkbd.c +++ b/drivers/input/keyboard/lkkbd.c | |||
@@ -59,11 +59,6 @@ | |||
59 | * You should have received a copy of the GNU General Public License | 59 | * You should have received a copy of the GNU General Public License |
60 | * along with this program; if not, write to the Free Software | 60 | * along with this program; if not, write to the Free Software |
61 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 61 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
62 | * | ||
63 | * Should you need to contact me, the author, you can do so either by | ||
64 | * email or by paper mail: | ||
65 | * Jan-Benedict Glaw, Lilienstraße 16, 33790 Hörste (near Halle/Westf.), | ||
66 | * Germany. | ||
67 | */ | 62 | */ |
68 | 63 | ||
69 | #include <linux/delay.h> | 64 | #include <linux/delay.h> |
diff --git a/drivers/input/keyboard/locomokbd.c b/drivers/input/keyboard/locomokbd.c index fd33c9cc3272..5788dbc317bb 100644 --- a/drivers/input/keyboard/locomokbd.c +++ b/drivers/input/keyboard/locomokbd.c | |||
@@ -186,7 +186,7 @@ static irqreturn_t locomokbd_interrupt(int irq, void *dev_id) | |||
186 | static void locomokbd_timer_callback(unsigned long data) | 186 | static void locomokbd_timer_callback(unsigned long data) |
187 | { | 187 | { |
188 | struct locomokbd *locomokbd = (struct locomokbd *) data; | 188 | struct locomokbd *locomokbd = (struct locomokbd *) data; |
189 | locomokbd_scankeyboard(locomokbd, NULL); | 189 | locomokbd_scankeyboard(locomokbd); |
190 | } | 190 | } |
191 | 191 | ||
192 | static int locomokbd_probe(struct locomo_dev *dev) | 192 | static int locomokbd_probe(struct locomo_dev *dev) |
diff --git a/drivers/input/keyboard/spitzkbd.c b/drivers/input/keyboard/spitzkbd.c index 8b18c009e3e0..28b2748e82d0 100644 --- a/drivers/input/keyboard/spitzkbd.c +++ b/drivers/input/keyboard/spitzkbd.c | |||
@@ -257,7 +257,7 @@ static void spitzkbd_timer_callback(unsigned long data) | |||
257 | { | 257 | { |
258 | struct spitzkbd *spitzkbd_data = (struct spitzkbd *) data; | 258 | struct spitzkbd *spitzkbd_data = (struct spitzkbd *) data; |
259 | 259 | ||
260 | spitzkbd_scankeyboard(spitzkbd_data, NULL); | 260 | spitzkbd_scankeyboard(spitzkbd_data); |
261 | } | 261 | } |
262 | 262 | ||
263 | /* | 263 | /* |
diff --git a/drivers/input/misc/hp_sdc_rtc.c b/drivers/input/misc/hp_sdc_rtc.c index 1be963961c15..ab4da79ee560 100644 --- a/drivers/input/misc/hp_sdc_rtc.c +++ b/drivers/input/misc/hp_sdc_rtc.c | |||
@@ -60,7 +60,7 @@ static struct fasync_struct *hp_sdc_rtc_async_queue; | |||
60 | 60 | ||
61 | static DECLARE_WAIT_QUEUE_HEAD(hp_sdc_rtc_wait); | 61 | static DECLARE_WAIT_QUEUE_HEAD(hp_sdc_rtc_wait); |
62 | 62 | ||
63 | static ssize_t hp_sdc_rtc_read(struct file *file, char *buf, | 63 | static ssize_t hp_sdc_rtc_read(struct file *file, char __user *buf, |
64 | size_t count, loff_t *ppos); | 64 | size_t count, loff_t *ppos); |
65 | 65 | ||
66 | static int hp_sdc_rtc_ioctl(struct inode *inode, struct file *file, | 66 | static int hp_sdc_rtc_ioctl(struct inode *inode, struct file *file, |
@@ -385,14 +385,14 @@ static int hp_sdc_rtc_set_i8042timer (struct timeval *setto, uint8_t setcmd) | |||
385 | return 0; | 385 | return 0; |
386 | } | 386 | } |
387 | 387 | ||
388 | static ssize_t hp_sdc_rtc_read(struct file *file, char *buf, | 388 | static ssize_t hp_sdc_rtc_read(struct file *file, char __user *buf, |
389 | size_t count, loff_t *ppos) { | 389 | size_t count, loff_t *ppos) { |
390 | ssize_t retval; | 390 | ssize_t retval; |
391 | 391 | ||
392 | if (count < sizeof(unsigned long)) | 392 | if (count < sizeof(unsigned long)) |
393 | return -EINVAL; | 393 | return -EINVAL; |
394 | 394 | ||
395 | retval = put_user(68, (unsigned long *)buf); | 395 | retval = put_user(68, (unsigned long __user *)buf); |
396 | return retval; | 396 | return retval; |
397 | } | 397 | } |
398 | 398 | ||
@@ -696,7 +696,7 @@ static int __init hp_sdc_rtc_init(void) | |||
696 | if ((ret = hp_sdc_request_timer_irq(&hp_sdc_rtc_isr))) | 696 | if ((ret = hp_sdc_request_timer_irq(&hp_sdc_rtc_isr))) |
697 | return ret; | 697 | return ret; |
698 | misc_register(&hp_sdc_rtc_dev); | 698 | misc_register(&hp_sdc_rtc_dev); |
699 | create_proc_read_entry ("driver/rtc", 0, 0, | 699 | create_proc_read_entry ("driver/rtc", 0, NULL, |
700 | hp_sdc_rtc_read_proc, NULL); | 700 | hp_sdc_rtc_read_proc, NULL); |
701 | 701 | ||
702 | printk(KERN_INFO "HP i8042 SDC + MSM-58321 RTC support loaded " | 702 | printk(KERN_INFO "HP i8042 SDC + MSM-58321 RTC support loaded " |
diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c index 4639537336fc..7b9d1c1da41a 100644 --- a/drivers/input/misc/wistron_btns.c +++ b/drivers/input/misc/wistron_btns.c | |||
@@ -17,7 +17,7 @@ | |||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | 17 | * with this program; if not, write to the Free Software Foundation, Inc., |
18 | * 59 Temple Place Suite 330, Boston, MA 02111-1307, USA. | 18 | * 59 Temple Place Suite 330, Boston, MA 02111-1307, USA. |
19 | */ | 19 | */ |
20 | #include <asm/io.h> | 20 | #include <linux/io.h> |
21 | #include <linux/dmi.h> | 21 | #include <linux/dmi.h> |
22 | #include <linux/init.h> | 22 | #include <linux/init.h> |
23 | #include <linux/input.h> | 23 | #include <linux/input.h> |
diff --git a/drivers/input/serio/hil_mlc.c b/drivers/input/serio/hil_mlc.c index bdfde046b741..49e11e2c1d5d 100644 --- a/drivers/input/serio/hil_mlc.c +++ b/drivers/input/serio/hil_mlc.c | |||
@@ -391,23 +391,23 @@ static int hilse_operate(hil_mlc *mlc, int repoll) { | |||
391 | } | 391 | } |
392 | 392 | ||
393 | #define FUNC(funct, funct_arg, zero_rc, neg_rc, pos_rc) \ | 393 | #define FUNC(funct, funct_arg, zero_rc, neg_rc, pos_rc) \ |
394 | { HILSE_FUNC, { func: &funct }, funct_arg, zero_rc, neg_rc, pos_rc }, | 394 | { HILSE_FUNC, { .func = funct }, funct_arg, zero_rc, neg_rc, pos_rc }, |
395 | #define OUT(pack) \ | 395 | #define OUT(pack) \ |
396 | { HILSE_OUT, { packet: pack }, 0, HILSEN_NEXT, HILSEN_DOZE, 0 }, | 396 | { HILSE_OUT, { .packet = pack }, 0, HILSEN_NEXT, HILSEN_DOZE, 0 }, |
397 | #define CTS \ | 397 | #define CTS \ |
398 | { HILSE_CTS, { packet: 0 }, 0, HILSEN_NEXT | HILSEN_SCHED | HILSEN_BREAK, HILSEN_DOZE, 0 }, | 398 | { HILSE_CTS, { .packet = 0 }, 0, HILSEN_NEXT | HILSEN_SCHED | HILSEN_BREAK, HILSEN_DOZE, 0 }, |
399 | #define EXPECT(comp, to, got, got_wrong, timed_out) \ | 399 | #define EXPECT(comp, to, got, got_wrong, timed_out) \ |
400 | { HILSE_EXPECT, { packet: comp }, to, got, got_wrong, timed_out }, | 400 | { HILSE_EXPECT, { .packet = comp }, to, got, got_wrong, timed_out }, |
401 | #define EXPECT_LAST(comp, to, got, got_wrong, timed_out) \ | 401 | #define EXPECT_LAST(comp, to, got, got_wrong, timed_out) \ |
402 | { HILSE_EXPECT_LAST, { packet: comp }, to, got, got_wrong, timed_out }, | 402 | { HILSE_EXPECT_LAST, { .packet = comp }, to, got, got_wrong, timed_out }, |
403 | #define EXPECT_DISC(comp, to, got, got_wrong, timed_out) \ | 403 | #define EXPECT_DISC(comp, to, got, got_wrong, timed_out) \ |
404 | { HILSE_EXPECT_DISC, { packet: comp }, to, got, got_wrong, timed_out }, | 404 | { HILSE_EXPECT_DISC, { .packet = comp }, to, got, got_wrong, timed_out }, |
405 | #define IN(to, got, got_error, timed_out) \ | 405 | #define IN(to, got, got_error, timed_out) \ |
406 | { HILSE_IN, { packet: 0 }, to, got, got_error, timed_out }, | 406 | { HILSE_IN, { .packet = 0 }, to, got, got_error, timed_out }, |
407 | #define OUT_DISC(pack) \ | 407 | #define OUT_DISC(pack) \ |
408 | { HILSE_OUT_DISC, { packet: pack }, 0, 0, 0, 0 }, | 408 | { HILSE_OUT_DISC, { .packet = pack }, 0, 0, 0, 0 }, |
409 | #define OUT_LAST(pack) \ | 409 | #define OUT_LAST(pack) \ |
410 | { HILSE_OUT_LAST, { packet: pack }, 0, 0, 0, 0 }, | 410 | { HILSE_OUT_LAST, { .packet = pack }, 0, 0, 0, 0 }, |
411 | 411 | ||
412 | struct hilse_node hil_mlc_se[HILSEN_END] = { | 412 | struct hilse_node hil_mlc_se[HILSEN_END] = { |
413 | 413 | ||
diff --git a/drivers/input/serio/hp_sdc.c b/drivers/input/serio/hp_sdc.c index ba7b920347e3..9907ad3bea23 100644 --- a/drivers/input/serio/hp_sdc.c +++ b/drivers/input/serio/hp_sdc.c | |||
@@ -310,7 +310,7 @@ static void hp_sdc_tasklet(unsigned long foo) { | |||
310 | * in tasklet/bh context. | 310 | * in tasklet/bh context. |
311 | */ | 311 | */ |
312 | if (curr->act.irqhook) | 312 | if (curr->act.irqhook) |
313 | curr->act.irqhook(0, 0, 0, 0); | 313 | curr->act.irqhook(0, NULL, 0, 0); |
314 | } | 314 | } |
315 | curr->actidx = curr->idx; | 315 | curr->actidx = curr->idx; |
316 | curr->idx++; | 316 | curr->idx++; |
@@ -525,7 +525,7 @@ actdone: | |||
525 | up(curr->act.semaphore); | 525 | up(curr->act.semaphore); |
526 | } | 526 | } |
527 | else if (act & HP_SDC_ACT_CALLBACK) { | 527 | else if (act & HP_SDC_ACT_CALLBACK) { |
528 | curr->act.irqhook(0,0,0,0); | 528 | curr->act.irqhook(0,NULL,0,0); |
529 | } | 529 | } |
530 | if (curr->idx >= curr->endidx) { /* This transaction is over. */ | 530 | if (curr->idx >= curr->endidx) { /* This transaction is over. */ |
531 | if (act & HP_SDC_ACT_DEALLOC) kfree(curr); | 531 | if (act & HP_SDC_ACT_DEALLOC) kfree(curr); |
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index 09b06e605b50..7e3141f37e32 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c | |||
@@ -106,6 +106,7 @@ static unsigned char i8042_ctr; | |||
106 | static unsigned char i8042_mux_present; | 106 | static unsigned char i8042_mux_present; |
107 | static unsigned char i8042_kbd_irq_registered; | 107 | static unsigned char i8042_kbd_irq_registered; |
108 | static unsigned char i8042_aux_irq_registered; | 108 | static unsigned char i8042_aux_irq_registered; |
109 | static unsigned char i8042_suppress_kbd_ack; | ||
109 | static struct platform_device *i8042_platform_device; | 110 | static struct platform_device *i8042_platform_device; |
110 | 111 | ||
111 | static irqreturn_t i8042_interrupt(int irq, void *dev_id); | 112 | static irqreturn_t i8042_interrupt(int irq, void *dev_id); |
@@ -316,7 +317,7 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id) | |||
316 | unsigned char str, data; | 317 | unsigned char str, data; |
317 | unsigned int dfl; | 318 | unsigned int dfl; |
318 | unsigned int port_no; | 319 | unsigned int port_no; |
319 | int ret; | 320 | int ret = 1; |
320 | 321 | ||
321 | spin_lock_irqsave(&i8042_lock, flags); | 322 | spin_lock_irqsave(&i8042_lock, flags); |
322 | str = i8042_read_status(); | 323 | str = i8042_read_status(); |
@@ -378,10 +379,16 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id) | |||
378 | dfl & SERIO_PARITY ? ", bad parity" : "", | 379 | dfl & SERIO_PARITY ? ", bad parity" : "", |
379 | dfl & SERIO_TIMEOUT ? ", timeout" : ""); | 380 | dfl & SERIO_TIMEOUT ? ", timeout" : ""); |
380 | 381 | ||
382 | if (unlikely(i8042_suppress_kbd_ack)) | ||
383 | if (port_no == I8042_KBD_PORT_NO && | ||
384 | (data == 0xfa || data == 0xfe)) { | ||
385 | i8042_suppress_kbd_ack = 0; | ||
386 | goto out; | ||
387 | } | ||
388 | |||
381 | if (likely(port->exists)) | 389 | if (likely(port->exists)) |
382 | serio_interrupt(port->serio, data, dfl); | 390 | serio_interrupt(port->serio, data, dfl); |
383 | 391 | ||
384 | ret = 1; | ||
385 | out: | 392 | out: |
386 | return IRQ_RETVAL(ret); | 393 | return IRQ_RETVAL(ret); |
387 | } | 394 | } |
@@ -842,11 +849,13 @@ static long i8042_panic_blink(long count) | |||
842 | led ^= 0x01 | 0x04; | 849 | led ^= 0x01 | 0x04; |
843 | while (i8042_read_status() & I8042_STR_IBF) | 850 | while (i8042_read_status() & I8042_STR_IBF) |
844 | DELAY; | 851 | DELAY; |
852 | i8042_suppress_kbd_ack = 1; | ||
845 | i8042_write_data(0xed); /* set leds */ | 853 | i8042_write_data(0xed); /* set leds */ |
846 | DELAY; | 854 | DELAY; |
847 | while (i8042_read_status() & I8042_STR_IBF) | 855 | while (i8042_read_status() & I8042_STR_IBF) |
848 | DELAY; | 856 | DELAY; |
849 | DELAY; | 857 | DELAY; |
858 | i8042_suppress_kbd_ack = 1; | ||
850 | i8042_write_data(led); | 859 | i8042_write_data(led); |
851 | DELAY; | 860 | DELAY; |
852 | last_blink = count; | 861 | last_blink = count; |
diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c index dcb16b5cbec0..e5b1b60757bb 100644 --- a/drivers/input/serio/libps2.c +++ b/drivers/input/serio/libps2.c | |||
@@ -189,7 +189,7 @@ int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command) | |||
189 | return -1; | 189 | return -1; |
190 | } | 190 | } |
191 | 191 | ||
192 | mutex_lock_nested(&ps2dev->cmd_mutex, SINGLE_DEPTH_NESTING); | 192 | mutex_lock(&ps2dev->cmd_mutex); |
193 | 193 | ||
194 | serio_pause_rx(ps2dev->serio); | 194 | serio_pause_rx(ps2dev->serio); |
195 | ps2dev->flags = command == PS2_CMD_GETID ? PS2_FLAG_WAITID : 0; | 195 | ps2dev->flags = command == PS2_CMD_GETID ? PS2_FLAG_WAITID : 0; |
@@ -296,6 +296,7 @@ EXPORT_SYMBOL(ps2_schedule_command); | |||
296 | void ps2_init(struct ps2dev *ps2dev, struct serio *serio) | 296 | void ps2_init(struct ps2dev *ps2dev, struct serio *serio) |
297 | { | 297 | { |
298 | mutex_init(&ps2dev->cmd_mutex); | 298 | mutex_init(&ps2dev->cmd_mutex); |
299 | lockdep_set_subclass(&ps2dev->cmd_mutex, serio->depth); | ||
299 | init_waitqueue_head(&ps2dev->wait); | 300 | init_waitqueue_head(&ps2dev->wait); |
300 | ps2dev->serio = serio; | 301 | ps2dev->serio = serio; |
301 | } | 302 | } |
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index 960fae3c3cea..211943f85cb6 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c | |||
@@ -118,6 +118,8 @@ static int serio_match_port(const struct serio_device_id *ids, struct serio *ser | |||
118 | 118 | ||
119 | static void serio_bind_driver(struct serio *serio, struct serio_driver *drv) | 119 | static void serio_bind_driver(struct serio *serio, struct serio_driver *drv) |
120 | { | 120 | { |
121 | int error; | ||
122 | |||
121 | down_write(&serio_bus.subsys.rwsem); | 123 | down_write(&serio_bus.subsys.rwsem); |
122 | 124 | ||
123 | if (serio_match_port(drv->id_table, serio)) { | 125 | if (serio_match_port(drv->id_table, serio)) { |
@@ -126,9 +128,19 @@ static void serio_bind_driver(struct serio *serio, struct serio_driver *drv) | |||
126 | serio->dev.driver = NULL; | 128 | serio->dev.driver = NULL; |
127 | goto out; | 129 | goto out; |
128 | } | 130 | } |
129 | device_bind_driver(&serio->dev); | 131 | error = device_bind_driver(&serio->dev); |
132 | if (error) { | ||
133 | printk(KERN_WARNING | ||
134 | "serio: device_bind_driver() failed " | ||
135 | "for %s (%s) and %s, error: %d\n", | ||
136 | serio->phys, serio->name, | ||
137 | drv->description, error); | ||
138 | serio_disconnect_driver(serio); | ||
139 | serio->dev.driver = NULL; | ||
140 | goto out; | ||
141 | } | ||
130 | } | 142 | } |
131 | out: | 143 | out: |
132 | up_write(&serio_bus.subsys.rwsem); | 144 | up_write(&serio_bus.subsys.rwsem); |
133 | } | 145 | } |
134 | 146 | ||
@@ -538,8 +550,12 @@ static void serio_init_port(struct serio *serio) | |||
538 | "serio%ld", (long)atomic_inc_return(&serio_no) - 1); | 550 | "serio%ld", (long)atomic_inc_return(&serio_no) - 1); |
539 | serio->dev.bus = &serio_bus; | 551 | serio->dev.bus = &serio_bus; |
540 | serio->dev.release = serio_release_port; | 552 | serio->dev.release = serio_release_port; |
541 | if (serio->parent) | 553 | if (serio->parent) { |
542 | serio->dev.parent = &serio->parent->dev; | 554 | serio->dev.parent = &serio->parent->dev; |
555 | serio->depth = serio->parent->depth + 1; | ||
556 | } else | ||
557 | serio->depth = 0; | ||
558 | lockdep_set_subclass(&serio->lock, serio->depth); | ||
543 | } | 559 | } |
544 | 560 | ||
545 | /* | 561 | /* |
diff --git a/drivers/input/touchscreen/corgi_ts.c b/drivers/input/touchscreen/corgi_ts.c index ca79b2246195..66121f6a89ad 100644 --- a/drivers/input/touchscreen/corgi_ts.c +++ b/drivers/input/touchscreen/corgi_ts.c | |||
@@ -219,7 +219,7 @@ static void ts_interrupt_main(struct corgi_ts *corgi_ts, int isTimer) | |||
219 | static void corgi_ts_timer(unsigned long data) | 219 | static void corgi_ts_timer(unsigned long data) |
220 | { | 220 | { |
221 | struct corgi_ts *corgits_data = (struct corgi_ts *) data; | 221 | struct corgi_ts *corgits_data = (struct corgi_ts *) data; |
222 | ts_interrupt_main(corgits_data, 1, NULL); | 222 | ts_interrupt_main(corgits_data, 1); |
223 | } | 223 | } |
224 | 224 | ||
225 | static irqreturn_t ts_interrupt(int irq, void *dev_id) | 225 | static irqreturn_t ts_interrupt(int irq, void *dev_id) |
@@ -237,7 +237,7 @@ static int corgits_suspend(struct platform_device *dev, pm_message_t state) | |||
237 | if (corgi_ts->pendown) { | 237 | if (corgi_ts->pendown) { |
238 | del_timer_sync(&corgi_ts->timer); | 238 | del_timer_sync(&corgi_ts->timer); |
239 | corgi_ts->tc.pressure = 0; | 239 | corgi_ts->tc.pressure = 0; |
240 | new_data(corgi_ts, NULL); | 240 | new_data(corgi_ts); |
241 | corgi_ts->pendown = 0; | 241 | corgi_ts->pendown = 0; |
242 | } | 242 | } |
243 | corgi_ts->power_mode = PWR_MODE_SUSPEND; | 243 | corgi_ts->power_mode = PWR_MODE_SUSPEND; |
diff --git a/drivers/input/touchscreen/hp680_ts_input.c b/drivers/input/touchscreen/hp680_ts_input.c index e31c6c55b2e2..58fca316786c 100644 --- a/drivers/input/touchscreen/hp680_ts_input.c +++ b/drivers/input/touchscreen/hp680_ts_input.c | |||
@@ -6,7 +6,7 @@ | |||
6 | #include <asm/io.h> | 6 | #include <asm/io.h> |
7 | #include <asm/delay.h> | 7 | #include <asm/delay.h> |
8 | #include <asm/adc.h> | 8 | #include <asm/adc.h> |
9 | #include <asm/hp6xx/hp6xx.h> | 9 | #include <asm/hp6xx.h> |
10 | 10 | ||
11 | #define MODNAME "hp680_ts_input" | 11 | #define MODNAME "hp680_ts_input" |
12 | 12 | ||
diff --git a/drivers/isdn/capi/capidrv.c b/drivers/isdn/capi/capidrv.c index d10c8b82e6aa..b6f9476c0501 100644 --- a/drivers/isdn/capi/capidrv.c +++ b/drivers/isdn/capi/capidrv.c | |||
@@ -1907,7 +1907,8 @@ static int if_readstat(u8 __user *buf, int len, int id, int channel) | |||
1907 | } | 1907 | } |
1908 | 1908 | ||
1909 | for (p=buf, count=0; count < len; p++, count++) { | 1909 | for (p=buf, count=0; count < len; p++, count++) { |
1910 | put_user(*card->q931_read++, p); | 1910 | if (put_user(*card->q931_read++, p)) |
1911 | return -EFAULT; | ||
1911 | if (card->q931_read > card->q931_end) | 1912 | if (card->q931_read > card->q931_end) |
1912 | card->q931_read = card->q931_buf; | 1913 | card->q931_read = card->q931_buf; |
1913 | } | 1914 | } |
diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c index aca165d43aa0..5800beeebb85 100644 --- a/drivers/isdn/gigaset/common.c +++ b/drivers/isdn/gigaset/common.c | |||
@@ -616,7 +616,7 @@ static struct bc_state *gigaset_initbcs(struct bc_state *bcs, | |||
616 | } else if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL) | 616 | } else if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL) |
617 | skb_reserve(bcs->skb, HW_HDR_LEN); | 617 | skb_reserve(bcs->skb, HW_HDR_LEN); |
618 | else { | 618 | else { |
619 | dev_warn(cs->dev, "could not allocate skb\n"); | 619 | warn("could not allocate skb\n"); |
620 | bcs->inputstate |= INS_skip_frame; | 620 | bcs->inputstate |= INS_skip_frame; |
621 | } | 621 | } |
622 | 622 | ||
diff --git a/drivers/isdn/hisax/Kconfig b/drivers/isdn/hisax/Kconfig index eb57a988e048..cfd2718a490d 100644 --- a/drivers/isdn/hisax/Kconfig +++ b/drivers/isdn/hisax/Kconfig | |||
@@ -344,7 +344,7 @@ config HISAX_HFC_SX | |||
344 | 344 | ||
345 | config HISAX_ENTERNOW_PCI | 345 | config HISAX_ENTERNOW_PCI |
346 | bool "Formula-n enter:now PCI card" | 346 | bool "Formula-n enter:now PCI card" |
347 | depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || FRV)) | 347 | depends on HISAX_NETJET && PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || FRV)) |
348 | help | 348 | help |
349 | This enables HiSax support for the Formula-n enter:now PCI | 349 | This enables HiSax support for the Formula-n enter:now PCI |
350 | ISDN card. | 350 | ISDN card. |
diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c index e4823ab2b127..785b08554fca 100644 --- a/drivers/isdn/hisax/config.c +++ b/drivers/isdn/hisax/config.c | |||
@@ -631,7 +631,8 @@ static int HiSax_readstatus(u_char __user *buf, int len, int id, int channel) | |||
631 | count = cs->status_end - cs->status_read + 1; | 631 | count = cs->status_end - cs->status_read + 1; |
632 | if (count >= len) | 632 | if (count >= len) |
633 | count = len; | 633 | count = len; |
634 | copy_to_user(p, cs->status_read, count); | 634 | if (copy_to_user(p, cs->status_read, count)) |
635 | return -EFAULT; | ||
635 | cs->status_read += count; | 636 | cs->status_read += count; |
636 | if (cs->status_read > cs->status_end) | 637 | if (cs->status_read > cs->status_end) |
637 | cs->status_read = cs->status_buf; | 638 | cs->status_read = cs->status_buf; |
@@ -642,7 +643,8 @@ static int HiSax_readstatus(u_char __user *buf, int len, int id, int channel) | |||
642 | cnt = HISAX_STATUS_BUFSIZE; | 643 | cnt = HISAX_STATUS_BUFSIZE; |
643 | else | 644 | else |
644 | cnt = count; | 645 | cnt = count; |
645 | copy_to_user(p, cs->status_read, cnt); | 646 | if (copy_to_user(p, cs->status_read, cnt)) |
647 | return -EFAULT; | ||
646 | p += cnt; | 648 | p += cnt; |
647 | cs->status_read += cnt % HISAX_STATUS_BUFSIZE; | 649 | cs->status_read += cnt % HISAX_STATUS_BUFSIZE; |
648 | count -= cnt; | 650 | count -= cnt; |
diff --git a/drivers/isdn/hisax/diva.c b/drivers/isdn/hisax/diva.c index 7e95f04f13da..3dacfff93f5f 100644 --- a/drivers/isdn/hisax/diva.c +++ b/drivers/isdn/hisax/diva.c | |||
@@ -716,8 +716,10 @@ release_io_diva(struct IsdnCardState *cs) | |||
716 | 716 | ||
717 | *cfg = 0; /* disable INT0/1 */ | 717 | *cfg = 0; /* disable INT0/1 */ |
718 | *cfg = 2; /* reset pending INT0 */ | 718 | *cfg = 2; /* reset pending INT0 */ |
719 | iounmap((void *)cs->hw.diva.cfg_reg); | 719 | if (cs->hw.diva.cfg_reg) |
720 | iounmap((void *)cs->hw.diva.pci_cfg); | 720 | iounmap((void *)cs->hw.diva.cfg_reg); |
721 | if (cs->hw.diva.pci_cfg) | ||
722 | iounmap((void *)cs->hw.diva.pci_cfg); | ||
721 | return; | 723 | return; |
722 | } else if (cs->subtyp != DIVA_IPAC_ISA) { | 724 | } else if (cs->subtyp != DIVA_IPAC_ISA) { |
723 | del_timer(&cs->hw.diva.tl); | 725 | del_timer(&cs->hw.diva.tl); |
@@ -734,6 +736,23 @@ release_io_diva(struct IsdnCardState *cs) | |||
734 | } | 736 | } |
735 | 737 | ||
736 | static void | 738 | static void |
739 | iounmap_diva(struct IsdnCardState *cs) | ||
740 | { | ||
741 | if ((cs->subtyp == DIVA_IPAC_PCI) || (cs->subtyp == DIVA_IPACX_PCI)) { | ||
742 | if (cs->hw.diva.cfg_reg) { | ||
743 | iounmap((void *)cs->hw.diva.cfg_reg); | ||
744 | cs->hw.diva.cfg_reg = 0; | ||
745 | } | ||
746 | if (cs->hw.diva.pci_cfg) { | ||
747 | iounmap((void *)cs->hw.diva.pci_cfg); | ||
748 | cs->hw.diva.pci_cfg = 0; | ||
749 | } | ||
750 | } | ||
751 | |||
752 | return; | ||
753 | } | ||
754 | |||
755 | static void | ||
737 | reset_diva(struct IsdnCardState *cs) | 756 | reset_diva(struct IsdnCardState *cs) |
738 | { | 757 | { |
739 | if (cs->subtyp == DIVA_IPAC_ISA) { | 758 | if (cs->subtyp == DIVA_IPAC_ISA) { |
@@ -1069,11 +1088,13 @@ setup_diva(struct IsdnCard *card) | |||
1069 | 1088 | ||
1070 | if (!cs->irq) { | 1089 | if (!cs->irq) { |
1071 | printk(KERN_WARNING "Diva: No IRQ for PCI card found\n"); | 1090 | printk(KERN_WARNING "Diva: No IRQ for PCI card found\n"); |
1091 | iounmap_diva(cs); | ||
1072 | return(0); | 1092 | return(0); |
1073 | } | 1093 | } |
1074 | 1094 | ||
1075 | if (!cs->hw.diva.cfg_reg) { | 1095 | if (!cs->hw.diva.cfg_reg) { |
1076 | printk(KERN_WARNING "Diva: No IO-Adr for PCI card found\n"); | 1096 | printk(KERN_WARNING "Diva: No IO-Adr for PCI card found\n"); |
1097 | iounmap_diva(cs); | ||
1077 | return(0); | 1098 | return(0); |
1078 | } | 1099 | } |
1079 | cs->irq_flags |= IRQF_SHARED; | 1100 | cs->irq_flags |= IRQF_SHARED; |
@@ -1123,6 +1144,7 @@ ready: | |||
1123 | CardType[card->typ], | 1144 | CardType[card->typ], |
1124 | cs->hw.diva.cfg_reg, | 1145 | cs->hw.diva.cfg_reg, |
1125 | cs->hw.diva.cfg_reg + bytecnt); | 1146 | cs->hw.diva.cfg_reg + bytecnt); |
1147 | iounmap_diva(cs); | ||
1126 | return (0); | 1148 | return (0); |
1127 | } | 1149 | } |
1128 | } | 1150 | } |
diff --git a/drivers/isdn/hysdn/boardergo.c b/drivers/isdn/hysdn/boardergo.c index 160f22fa5941..82e42a80dc4b 100644 --- a/drivers/isdn/hysdn/boardergo.c +++ b/drivers/isdn/hysdn/boardergo.c | |||
@@ -45,11 +45,10 @@ ergo_interrupt(int intno, void *dev_id) | |||
45 | if (!card->irq_enabled) | 45 | if (!card->irq_enabled) |
46 | return IRQ_NONE; /* other device interrupting or irq switched off */ | 46 | return IRQ_NONE; /* other device interrupting or irq switched off */ |
47 | 47 | ||
48 | save_flags(flags); | 48 | spin_lock_irqsave(&card->hysdn_lock, flags); /* no further irqs allowed */ |
49 | cli(); /* no further irqs allowed */ | ||
50 | 49 | ||
51 | if (!(bytein(card->iobase + PCI9050_INTR_REG) & PCI9050_INTR_REG_STAT1)) { | 50 | if (!(bytein(card->iobase + PCI9050_INTR_REG) & PCI9050_INTR_REG_STAT1)) { |
52 | restore_flags(flags); /* restore old state */ | 51 | spin_unlock_irqrestore(&card->hysdn_lock, flags); /* restore old state */ |
53 | return IRQ_NONE; /* no interrupt requested by E1 */ | 52 | return IRQ_NONE; /* no interrupt requested by E1 */ |
54 | } | 53 | } |
55 | /* clear any pending ints on the board */ | 54 | /* clear any pending ints on the board */ |
@@ -61,7 +60,7 @@ ergo_interrupt(int intno, void *dev_id) | |||
61 | /* start kernel task immediately after leaving all interrupts */ | 60 | /* start kernel task immediately after leaving all interrupts */ |
62 | if (!card->hw_lock) | 61 | if (!card->hw_lock) |
63 | schedule_work(&card->irq_queue); | 62 | schedule_work(&card->irq_queue); |
64 | restore_flags(flags); | 63 | spin_unlock_irqrestore(&card->hysdn_lock, flags); |
65 | return IRQ_HANDLED; | 64 | return IRQ_HANDLED; |
66 | } /* ergo_interrupt */ | 65 | } /* ergo_interrupt */ |
67 | 66 | ||
@@ -83,10 +82,9 @@ ergo_irq_bh(hysdn_card * card) | |||
83 | 82 | ||
84 | dpr = card->dpram; /* point to DPRAM */ | 83 | dpr = card->dpram; /* point to DPRAM */ |
85 | 84 | ||
86 | save_flags(flags); | 85 | spin_lock_irqsave(&card->hysdn_lock, flags); |
87 | cli(); | ||
88 | if (card->hw_lock) { | 86 | if (card->hw_lock) { |
89 | restore_flags(flags); /* hardware currently unavailable */ | 87 | spin_unlock_irqrestore(&card->hysdn_lock, flags); /* hardware currently unavailable */ |
90 | return; | 88 | return; |
91 | } | 89 | } |
92 | card->hw_lock = 1; /* we now lock the hardware */ | 90 | card->hw_lock = 1; /* we now lock the hardware */ |
@@ -120,7 +118,7 @@ ergo_irq_bh(hysdn_card * card) | |||
120 | card->hw_lock = 0; /* free hardware again */ | 118 | card->hw_lock = 0; /* free hardware again */ |
121 | } while (again); /* until nothing more to do */ | 119 | } while (again); /* until nothing more to do */ |
122 | 120 | ||
123 | restore_flags(flags); | 121 | spin_unlock_irqrestore(&card->hysdn_lock, flags); |
124 | } /* ergo_irq_bh */ | 122 | } /* ergo_irq_bh */ |
125 | 123 | ||
126 | 124 | ||
@@ -137,8 +135,7 @@ ergo_stopcard(hysdn_card * card) | |||
137 | #ifdef CONFIG_HYSDN_CAPI | 135 | #ifdef CONFIG_HYSDN_CAPI |
138 | hycapi_capi_stop(card); | 136 | hycapi_capi_stop(card); |
139 | #endif /* CONFIG_HYSDN_CAPI */ | 137 | #endif /* CONFIG_HYSDN_CAPI */ |
140 | save_flags(flags); | 138 | spin_lock_irqsave(&card->hysdn_lock, flags); |
141 | cli(); | ||
142 | val = bytein(card->iobase + PCI9050_INTR_REG); /* get actual value */ | 139 | val = bytein(card->iobase + PCI9050_INTR_REG); /* get actual value */ |
143 | val &= ~(PCI9050_INTR_REG_ENPCI | PCI9050_INTR_REG_EN1); /* mask irq */ | 140 | val &= ~(PCI9050_INTR_REG_ENPCI | PCI9050_INTR_REG_EN1); /* mask irq */ |
144 | byteout(card->iobase + PCI9050_INTR_REG, val); | 141 | byteout(card->iobase + PCI9050_INTR_REG, val); |
@@ -147,7 +144,7 @@ ergo_stopcard(hysdn_card * card) | |||
147 | card->state = CARD_STATE_UNUSED; | 144 | card->state = CARD_STATE_UNUSED; |
148 | card->err_log_state = ERRLOG_STATE_OFF; /* currently no log active */ | 145 | card->err_log_state = ERRLOG_STATE_OFF; /* currently no log active */ |
149 | 146 | ||
150 | restore_flags(flags); | 147 | spin_unlock_irqrestore(&card->hysdn_lock, flags); |
151 | } /* ergo_stopcard */ | 148 | } /* ergo_stopcard */ |
152 | 149 | ||
153 | /**************************************************************************/ | 150 | /**************************************************************************/ |
@@ -162,12 +159,11 @@ ergo_set_errlog_state(hysdn_card * card, int on) | |||
162 | card->err_log_state = ERRLOG_STATE_OFF; /* must be off */ | 159 | card->err_log_state = ERRLOG_STATE_OFF; /* must be off */ |
163 | return; | 160 | return; |
164 | } | 161 | } |
165 | save_flags(flags); | 162 | spin_lock_irqsave(&card->hysdn_lock, flags); |
166 | cli(); | ||
167 | 163 | ||
168 | if (((card->err_log_state == ERRLOG_STATE_OFF) && !on) || | 164 | if (((card->err_log_state == ERRLOG_STATE_OFF) && !on) || |
169 | ((card->err_log_state == ERRLOG_STATE_ON) && on)) { | 165 | ((card->err_log_state == ERRLOG_STATE_ON) && on)) { |
170 | restore_flags(flags); | 166 | spin_unlock_irqrestore(&card->hysdn_lock, flags); |
171 | return; /* nothing to do */ | 167 | return; /* nothing to do */ |
172 | } | 168 | } |
173 | if (on) | 169 | if (on) |
@@ -175,7 +171,7 @@ ergo_set_errlog_state(hysdn_card * card, int on) | |||
175 | else | 171 | else |
176 | card->err_log_state = ERRLOG_STATE_STOP; /* request stop */ | 172 | card->err_log_state = ERRLOG_STATE_STOP; /* request stop */ |
177 | 173 | ||
178 | restore_flags(flags); | 174 | spin_unlock_irqrestore(&card->hysdn_lock, flags); |
179 | schedule_work(&card->irq_queue); | 175 | schedule_work(&card->irq_queue); |
180 | } /* ergo_set_errlog_state */ | 176 | } /* ergo_set_errlog_state */ |
181 | 177 | ||
@@ -356,8 +352,7 @@ ergo_waitpofready(struct HYSDN_CARD *card) | |||
356 | 352 | ||
357 | if (card->debug_flags & LOG_POF_RECORD) | 353 | if (card->debug_flags & LOG_POF_RECORD) |
358 | hysdn_addlog(card, "ERGO: pof boot success"); | 354 | hysdn_addlog(card, "ERGO: pof boot success"); |
359 | save_flags(flags); | 355 | spin_lock_irqsave(&card->hysdn_lock, flags); |
360 | cli(); | ||
361 | 356 | ||
362 | card->state = CARD_STATE_RUN; /* now card is running */ | 357 | card->state = CARD_STATE_RUN; /* now card is running */ |
363 | /* enable the cards interrupt */ | 358 | /* enable the cards interrupt */ |
@@ -370,7 +365,7 @@ ergo_waitpofready(struct HYSDN_CARD *card) | |||
370 | dpr->ToHyInt = 1; | 365 | dpr->ToHyInt = 1; |
371 | dpr->ToPcInt = 1; /* interrupt to E1 for all cards */ | 366 | dpr->ToPcInt = 1; /* interrupt to E1 for all cards */ |
372 | 367 | ||
373 | restore_flags(flags); | 368 | spin_unlock_irqrestore(&card->hysdn_lock, flags); |
374 | if ((hynet_enable & (1 << card->myid)) | 369 | if ((hynet_enable & (1 << card->myid)) |
375 | && (i = hysdn_net_create(card))) | 370 | && (i = hysdn_net_create(card))) |
376 | { | 371 | { |
@@ -408,7 +403,7 @@ ergo_releasehardware(hysdn_card * card) | |||
408 | free_irq(card->irq, card); /* release interrupt */ | 403 | free_irq(card->irq, card); /* release interrupt */ |
409 | release_region(card->iobase + PCI9050_INTR_REG, 1); /* release all io ports */ | 404 | release_region(card->iobase + PCI9050_INTR_REG, 1); /* release all io ports */ |
410 | release_region(card->iobase + PCI9050_USER_IO, 1); | 405 | release_region(card->iobase + PCI9050_USER_IO, 1); |
411 | vfree(card->dpram); | 406 | iounmap(card->dpram); |
412 | card->dpram = NULL; /* release shared mem */ | 407 | card->dpram = NULL; /* release shared mem */ |
413 | } /* ergo_releasehardware */ | 408 | } /* ergo_releasehardware */ |
414 | 409 | ||
@@ -448,6 +443,7 @@ ergo_inithardware(hysdn_card * card) | |||
448 | card->waitpofready = ergo_waitpofready; | 443 | card->waitpofready = ergo_waitpofready; |
449 | card->set_errlog_state = ergo_set_errlog_state; | 444 | card->set_errlog_state = ergo_set_errlog_state; |
450 | INIT_WORK(&card->irq_queue, (void *) (void *) ergo_irq_bh, card); | 445 | INIT_WORK(&card->irq_queue, (void *) (void *) ergo_irq_bh, card); |
446 | card->hysdn_lock = SPIN_LOCK_UNLOCKED; | ||
451 | 447 | ||
452 | return (0); | 448 | return (0); |
453 | } /* ergo_inithardware */ | 449 | } /* ergo_inithardware */ |
diff --git a/drivers/isdn/hysdn/hysdn_defs.h b/drivers/isdn/hysdn/hysdn_defs.h index 461e831592dd..729df4089385 100644 --- a/drivers/isdn/hysdn/hysdn_defs.h +++ b/drivers/isdn/hysdn/hysdn_defs.h | |||
@@ -188,6 +188,8 @@ typedef struct HYSDN_CARD { | |||
188 | /* init and deinit stopcard for booting, too */ | 188 | /* init and deinit stopcard for booting, too */ |
189 | void (*stopcard) (struct HYSDN_CARD *); | 189 | void (*stopcard) (struct HYSDN_CARD *); |
190 | void (*releasehardware) (struct HYSDN_CARD *); | 190 | void (*releasehardware) (struct HYSDN_CARD *); |
191 | |||
192 | spinlock_t hysdn_lock; | ||
191 | #ifdef CONFIG_HYSDN_CAPI | 193 | #ifdef CONFIG_HYSDN_CAPI |
192 | struct hycapictrl_info { | 194 | struct hycapictrl_info { |
193 | char cardname[32]; | 195 | char cardname[32]; |
diff --git a/drivers/isdn/hysdn/hysdn_proclog.c b/drivers/isdn/hysdn/hysdn_proclog.c index c4301e8338ef..fcd49920b220 100644 --- a/drivers/isdn/hysdn/hysdn_proclog.c +++ b/drivers/isdn/hysdn/hysdn_proclog.c | |||
@@ -116,8 +116,7 @@ put_log_buffer(hysdn_card * card, char *cp) | |||
116 | strcpy(ib->log_start, cp); /* set output string */ | 116 | strcpy(ib->log_start, cp); /* set output string */ |
117 | ib->next = NULL; | 117 | ib->next = NULL; |
118 | ib->proc_ctrl = pd; /* point to own control structure */ | 118 | ib->proc_ctrl = pd; /* point to own control structure */ |
119 | save_flags(flags); | 119 | spin_lock_irqsave(&card->hysdn_lock, flags); |
120 | cli(); | ||
121 | ib->usage_cnt = pd->if_used; | 120 | ib->usage_cnt = pd->if_used; |
122 | if (!pd->log_head) | 121 | if (!pd->log_head) |
123 | pd->log_head = ib; /* new head */ | 122 | pd->log_head = ib; /* new head */ |
@@ -125,7 +124,7 @@ put_log_buffer(hysdn_card * card, char *cp) | |||
125 | pd->log_tail->next = ib; /* follows existing messages */ | 124 | pd->log_tail->next = ib; /* follows existing messages */ |
126 | pd->log_tail = ib; /* new tail */ | 125 | pd->log_tail = ib; /* new tail */ |
127 | i = pd->del_lock++; /* get lock state */ | 126 | i = pd->del_lock++; /* get lock state */ |
128 | restore_flags(flags); | 127 | spin_unlock_irqrestore(&card->hysdn_lock, flags); |
129 | 128 | ||
130 | /* delete old entrys */ | 129 | /* delete old entrys */ |
131 | if (!i) | 130 | if (!i) |
@@ -270,14 +269,13 @@ hysdn_log_open(struct inode *ino, struct file *filep) | |||
270 | } else if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) { | 269 | } else if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) { |
271 | 270 | ||
272 | /* read access -> log/debug read */ | 271 | /* read access -> log/debug read */ |
273 | save_flags(flags); | 272 | spin_lock_irqsave(&card->hysdn_lock, flags); |
274 | cli(); | ||
275 | pd->if_used++; | 273 | pd->if_used++; |
276 | if (pd->log_head) | 274 | if (pd->log_head) |
277 | filep->private_data = &pd->log_tail->next; | 275 | filep->private_data = &pd->log_tail->next; |
278 | else | 276 | else |
279 | filep->private_data = &pd->log_head; | 277 | filep->private_data = &pd->log_head; |
280 | restore_flags(flags); | 278 | spin_unlock_irqrestore(&card->hysdn_lock, flags); |
281 | } else { /* simultaneous read/write access forbidden ! */ | 279 | } else { /* simultaneous read/write access forbidden ! */ |
282 | unlock_kernel(); | 280 | unlock_kernel(); |
283 | return (-EPERM); /* no permission this time */ | 281 | return (-EPERM); /* no permission this time */ |
@@ -301,7 +299,7 @@ hysdn_log_close(struct inode *ino, struct file *filep) | |||
301 | hysdn_card *card; | 299 | hysdn_card *card; |
302 | int retval = 0; | 300 | int retval = 0; |
303 | unsigned long flags; | 301 | unsigned long flags; |
304 | 302 | spinlock_t hysdn_lock = SPIN_LOCK_UNLOCKED; | |
305 | 303 | ||
306 | lock_kernel(); | 304 | lock_kernel(); |
307 | if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_WRITE) { | 305 | if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_WRITE) { |
@@ -311,8 +309,7 @@ hysdn_log_close(struct inode *ino, struct file *filep) | |||
311 | /* read access -> log/debug read, mark one further file as closed */ | 309 | /* read access -> log/debug read, mark one further file as closed */ |
312 | 310 | ||
313 | pd = NULL; | 311 | pd = NULL; |
314 | save_flags(flags); | 312 | spin_lock_irqsave(&hysdn_lock, flags); |
315 | cli(); | ||
316 | inf = *((struct log_data **) filep->private_data); /* get first log entry */ | 313 | inf = *((struct log_data **) filep->private_data); /* get first log entry */ |
317 | if (inf) | 314 | if (inf) |
318 | pd = (struct procdata *) inf->proc_ctrl; /* still entries there */ | 315 | pd = (struct procdata *) inf->proc_ctrl; /* still entries there */ |
@@ -335,7 +332,7 @@ hysdn_log_close(struct inode *ino, struct file *filep) | |||
335 | inf->usage_cnt--; /* decrement usage count for buffers */ | 332 | inf->usage_cnt--; /* decrement usage count for buffers */ |
336 | inf = inf->next; | 333 | inf = inf->next; |
337 | } | 334 | } |
338 | restore_flags(flags); | 335 | spin_unlock_irqrestore(&hysdn_lock, flags); |
339 | 336 | ||
340 | if (pd) | 337 | if (pd) |
341 | if (pd->if_used <= 0) /* delete buffers if last file closed */ | 338 | if (pd->if_used <= 0) /* delete buffers if last file closed */ |
diff --git a/drivers/isdn/hysdn/hysdn_sched.c b/drivers/isdn/hysdn/hysdn_sched.c index 1c0d54ac12ab..18758772b744 100644 --- a/drivers/isdn/hysdn/hysdn_sched.c +++ b/drivers/isdn/hysdn/hysdn_sched.c | |||
@@ -155,22 +155,17 @@ hysdn_tx_cfgline(hysdn_card *card, unsigned char *line, unsigned short chan) | |||
155 | if (card->debug_flags & LOG_SCHED_ASYN) | 155 | if (card->debug_flags & LOG_SCHED_ASYN) |
156 | hysdn_addlog(card, "async tx-cfg chan=%d len=%d", chan, strlen(line) + 1); | 156 | hysdn_addlog(card, "async tx-cfg chan=%d len=%d", chan, strlen(line) + 1); |
157 | 157 | ||
158 | save_flags(flags); | ||
159 | cli(); | ||
160 | while (card->async_busy) { | 158 | while (card->async_busy) { |
161 | sti(); | ||
162 | 159 | ||
163 | if (card->debug_flags & LOG_SCHED_ASYN) | 160 | if (card->debug_flags & LOG_SCHED_ASYN) |
164 | hysdn_addlog(card, "async tx-cfg delayed"); | 161 | hysdn_addlog(card, "async tx-cfg delayed"); |
165 | 162 | ||
166 | msleep_interruptible(20); /* Timeout 20ms */ | 163 | msleep_interruptible(20); /* Timeout 20ms */ |
167 | if (!--cnt) { | 164 | if (!--cnt) |
168 | restore_flags(flags); | ||
169 | return (-ERR_ASYNC_TIME); /* timed out */ | 165 | return (-ERR_ASYNC_TIME); /* timed out */ |
170 | } | ||
171 | cli(); | ||
172 | } /* wait for buffer to become free */ | 166 | } /* wait for buffer to become free */ |
173 | 167 | ||
168 | spin_lock_irqsave(&card->hysdn_lock, flags); | ||
174 | strcpy(card->async_data, line); | 169 | strcpy(card->async_data, line); |
175 | card->async_len = strlen(line) + 1; | 170 | card->async_len = strlen(line) + 1; |
176 | card->async_channel = chan; | 171 | card->async_channel = chan; |
@@ -178,30 +173,23 @@ hysdn_tx_cfgline(hysdn_card *card, unsigned char *line, unsigned short chan) | |||
178 | 173 | ||
179 | /* now queue the task */ | 174 | /* now queue the task */ |
180 | schedule_work(&card->irq_queue); | 175 | schedule_work(&card->irq_queue); |
181 | sti(); | 176 | spin_unlock_irqrestore(&card->hysdn_lock, flags); |
182 | 177 | ||
183 | if (card->debug_flags & LOG_SCHED_ASYN) | 178 | if (card->debug_flags & LOG_SCHED_ASYN) |
184 | hysdn_addlog(card, "async tx-cfg data queued"); | 179 | hysdn_addlog(card, "async tx-cfg data queued"); |
185 | 180 | ||
186 | cnt++; /* short delay */ | 181 | cnt++; /* short delay */ |
187 | cli(); | ||
188 | 182 | ||
189 | while (card->async_busy) { | 183 | while (card->async_busy) { |
190 | sti(); | ||
191 | 184 | ||
192 | if (card->debug_flags & LOG_SCHED_ASYN) | 185 | if (card->debug_flags & LOG_SCHED_ASYN) |
193 | hysdn_addlog(card, "async tx-cfg waiting for tx-ready"); | 186 | hysdn_addlog(card, "async tx-cfg waiting for tx-ready"); |
194 | 187 | ||
195 | msleep_interruptible(20); /* Timeout 20ms */ | 188 | msleep_interruptible(20); /* Timeout 20ms */ |
196 | if (!--cnt) { | 189 | if (!--cnt) |
197 | restore_flags(flags); | ||
198 | return (-ERR_ASYNC_TIME); /* timed out */ | 190 | return (-ERR_ASYNC_TIME); /* timed out */ |
199 | } | ||
200 | cli(); | ||
201 | } /* wait for buffer to become free again */ | 191 | } /* wait for buffer to become free again */ |
202 | 192 | ||
203 | restore_flags(flags); | ||
204 | |||
205 | if (card->debug_flags & LOG_SCHED_ASYN) | 193 | if (card->debug_flags & LOG_SCHED_ASYN) |
206 | hysdn_addlog(card, "async tx-cfg data send"); | 194 | hysdn_addlog(card, "async tx-cfg data send"); |
207 | 195 | ||
diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c index c3d79eef9e32..69aee2602aa6 100644 --- a/drivers/isdn/i4l/isdn_common.c +++ b/drivers/isdn/i4l/isdn_common.c | |||
@@ -1134,9 +1134,12 @@ isdn_read(struct file *file, char __user *buf, size_t count, loff_t * off) | |||
1134 | if (dev->drv[drvidx]->interface->readstat) { | 1134 | if (dev->drv[drvidx]->interface->readstat) { |
1135 | if (count > dev->drv[drvidx]->stavail) | 1135 | if (count > dev->drv[drvidx]->stavail) |
1136 | count = dev->drv[drvidx]->stavail; | 1136 | count = dev->drv[drvidx]->stavail; |
1137 | len = dev->drv[drvidx]->interface-> | 1137 | len = dev->drv[drvidx]->interface->readstat(buf, count, |
1138 | readstat(buf, count, drvidx, | 1138 | drvidx, isdn_minor2chan(minor)); |
1139 | isdn_minor2chan(minor)); | 1139 | if (len < 0) { |
1140 | retval = len; | ||
1141 | goto out; | ||
1142 | } | ||
1140 | } else { | 1143 | } else { |
1141 | len = 0; | 1144 | len = 0; |
1142 | } | 1145 | } |
diff --git a/drivers/isdn/icn/icn.c b/drivers/isdn/icn/icn.c index 6649f8bc9951..730bbd07ebc7 100644 --- a/drivers/isdn/icn/icn.c +++ b/drivers/isdn/icn/icn.c | |||
@@ -1010,7 +1010,8 @@ icn_readstatus(u_char __user *buf, int len, icn_card * card) | |||
1010 | for (p = buf, count = 0; count < len; p++, count++) { | 1010 | for (p = buf, count = 0; count < len; p++, count++) { |
1011 | if (card->msg_buf_read == card->msg_buf_write) | 1011 | if (card->msg_buf_read == card->msg_buf_write) |
1012 | return count; | 1012 | return count; |
1013 | put_user(*card->msg_buf_read++, p); | 1013 | if (put_user(*card->msg_buf_read++, p)) |
1014 | return -EFAULT; | ||
1014 | if (card->msg_buf_read > card->msg_buf_end) | 1015 | if (card->msg_buf_read > card->msg_buf_end) |
1015 | card->msg_buf_read = card->msg_buf; | 1016 | card->msg_buf_read = card->msg_buf; |
1016 | } | 1017 | } |
diff --git a/drivers/isdn/isdnloop/isdnloop.c b/drivers/isdn/isdnloop/isdnloop.c index fabbd461603e..c3ae2edaf6fa 100644 --- a/drivers/isdn/isdnloop/isdnloop.c +++ b/drivers/isdn/isdnloop/isdnloop.c | |||
@@ -100,12 +100,11 @@ isdnloop_pollbchan(unsigned long data) | |||
100 | isdnloop_bchan_send(card, 1); | 100 | isdnloop_bchan_send(card, 1); |
101 | if (card->flags & (ISDNLOOP_FLAGS_B1ACTIVE | ISDNLOOP_FLAGS_B2ACTIVE)) { | 101 | if (card->flags & (ISDNLOOP_FLAGS_B1ACTIVE | ISDNLOOP_FLAGS_B2ACTIVE)) { |
102 | /* schedule b-channel polling again */ | 102 | /* schedule b-channel polling again */ |
103 | save_flags(flags); | 103 | spin_lock_irqsave(&card->isdnloop_lock, flags); |
104 | cli(); | ||
105 | card->rb_timer.expires = jiffies + ISDNLOOP_TIMER_BCREAD; | 104 | card->rb_timer.expires = jiffies + ISDNLOOP_TIMER_BCREAD; |
106 | add_timer(&card->rb_timer); | 105 | add_timer(&card->rb_timer); |
107 | card->flags |= ISDNLOOP_FLAGS_RBTIMER; | 106 | card->flags |= ISDNLOOP_FLAGS_RBTIMER; |
108 | restore_flags(flags); | 107 | spin_unlock_irqrestore(&card->isdnloop_lock, flags); |
109 | } else | 108 | } else |
110 | card->flags &= ~ISDNLOOP_FLAGS_RBTIMER; | 109 | card->flags &= ~ISDNLOOP_FLAGS_RBTIMER; |
111 | } | 110 | } |
@@ -281,8 +280,7 @@ isdnloop_putmsg(isdnloop_card * card, unsigned char c) | |||
281 | { | 280 | { |
282 | ulong flags; | 281 | ulong flags; |
283 | 282 | ||
284 | save_flags(flags); | 283 | spin_lock_irqsave(&card->isdnloop_lock, flags); |
285 | cli(); | ||
286 | *card->msg_buf_write++ = (c == 0xff) ? '\n' : c; | 284 | *card->msg_buf_write++ = (c == 0xff) ? '\n' : c; |
287 | if (card->msg_buf_write == card->msg_buf_read) { | 285 | if (card->msg_buf_write == card->msg_buf_read) { |
288 | if (++card->msg_buf_read > card->msg_buf_end) | 286 | if (++card->msg_buf_read > card->msg_buf_end) |
@@ -290,7 +288,7 @@ isdnloop_putmsg(isdnloop_card * card, unsigned char c) | |||
290 | } | 288 | } |
291 | if (card->msg_buf_write > card->msg_buf_end) | 289 | if (card->msg_buf_write > card->msg_buf_end) |
292 | card->msg_buf_write = card->msg_buf; | 290 | card->msg_buf_write = card->msg_buf; |
293 | restore_flags(flags); | 291 | spin_unlock_irqrestore(&card->isdnloop_lock, flags); |
294 | } | 292 | } |
295 | 293 | ||
296 | /* | 294 | /* |
@@ -372,21 +370,19 @@ isdnloop_polldchan(unsigned long data) | |||
372 | if (!(card->flags & ISDNLOOP_FLAGS_RBTIMER)) { | 370 | if (!(card->flags & ISDNLOOP_FLAGS_RBTIMER)) { |
373 | /* schedule b-channel polling */ | 371 | /* schedule b-channel polling */ |
374 | card->flags |= ISDNLOOP_FLAGS_RBTIMER; | 372 | card->flags |= ISDNLOOP_FLAGS_RBTIMER; |
375 | save_flags(flags); | 373 | spin_lock_irqsave(&card->isdnloop_lock, flags); |
376 | cli(); | ||
377 | del_timer(&card->rb_timer); | 374 | del_timer(&card->rb_timer); |
378 | card->rb_timer.function = isdnloop_pollbchan; | 375 | card->rb_timer.function = isdnloop_pollbchan; |
379 | card->rb_timer.data = (unsigned long) card; | 376 | card->rb_timer.data = (unsigned long) card; |
380 | card->rb_timer.expires = jiffies + ISDNLOOP_TIMER_BCREAD; | 377 | card->rb_timer.expires = jiffies + ISDNLOOP_TIMER_BCREAD; |
381 | add_timer(&card->rb_timer); | 378 | add_timer(&card->rb_timer); |
382 | restore_flags(flags); | 379 | spin_unlock_irqrestore(&card->isdnloop_lock, flags); |
383 | } | 380 | } |
384 | /* schedule again */ | 381 | /* schedule again */ |
385 | save_flags(flags); | 382 | spin_lock_irqsave(&card->isdnloop_lock, flags); |
386 | cli(); | ||
387 | card->st_timer.expires = jiffies + ISDNLOOP_TIMER_DCREAD; | 383 | card->st_timer.expires = jiffies + ISDNLOOP_TIMER_DCREAD; |
388 | add_timer(&card->st_timer); | 384 | add_timer(&card->st_timer); |
389 | restore_flags(flags); | 385 | spin_unlock_irqrestore(&card->isdnloop_lock, flags); |
390 | } | 386 | } |
391 | 387 | ||
392 | /* | 388 | /* |
@@ -416,8 +412,7 @@ isdnloop_sendbuf(int channel, struct sk_buff *skb, isdnloop_card * card) | |||
416 | return 0; | 412 | return 0; |
417 | if (card->sndcount[channel] > ISDNLOOP_MAX_SQUEUE) | 413 | if (card->sndcount[channel] > ISDNLOOP_MAX_SQUEUE) |
418 | return 0; | 414 | return 0; |
419 | save_flags(flags); | 415 | spin_lock_irqsave(&card->isdnloop_lock, flags); |
420 | cli(); | ||
421 | nskb = dev_alloc_skb(skb->len); | 416 | nskb = dev_alloc_skb(skb->len); |
422 | if (nskb) { | 417 | if (nskb) { |
423 | memcpy(skb_put(nskb, len), skb->data, len); | 418 | memcpy(skb_put(nskb, len), skb->data, len); |
@@ -426,7 +421,7 @@ isdnloop_sendbuf(int channel, struct sk_buff *skb, isdnloop_card * card) | |||
426 | } else | 421 | } else |
427 | len = 0; | 422 | len = 0; |
428 | card->sndcount[channel] += len; | 423 | card->sndcount[channel] += len; |
429 | restore_flags(flags); | 424 | spin_unlock_irqrestore(&card->isdnloop_lock, flags); |
430 | } | 425 | } |
431 | return len; | 426 | return len; |
432 | } | 427 | } |
@@ -451,7 +446,8 @@ isdnloop_readstatus(u_char __user *buf, int len, isdnloop_card * card) | |||
451 | for (p = buf, count = 0; count < len; p++, count++) { | 446 | for (p = buf, count = 0; count < len; p++, count++) { |
452 | if (card->msg_buf_read == card->msg_buf_write) | 447 | if (card->msg_buf_read == card->msg_buf_write) |
453 | return count; | 448 | return count; |
454 | put_user(*card->msg_buf_read++, p); | 449 | if (put_user(*card->msg_buf_read++, p)) |
450 | return -EFAULT; | ||
455 | if (card->msg_buf_read > card->msg_buf_end) | 451 | if (card->msg_buf_read > card->msg_buf_end) |
456 | card->msg_buf_read = card->msg_buf; | 452 | card->msg_buf_read = card->msg_buf; |
457 | } | 453 | } |
@@ -576,8 +572,7 @@ isdnloop_atimeout(isdnloop_card * card, int ch) | |||
576 | unsigned long flags; | 572 | unsigned long flags; |
577 | char buf[60]; | 573 | char buf[60]; |
578 | 574 | ||
579 | save_flags(flags); | 575 | spin_lock_irqsave(&card->isdnloop_lock, flags); |
580 | cli(); | ||
581 | if (card->rcard) { | 576 | if (card->rcard) { |
582 | isdnloop_fake(card->rcard[ch], "DDIS_I", card->rch[ch] + 1); | 577 | isdnloop_fake(card->rcard[ch], "DDIS_I", card->rch[ch] + 1); |
583 | card->rcard[ch]->rcard[card->rch[ch]] = NULL; | 578 | card->rcard[ch]->rcard[card->rch[ch]] = NULL; |
@@ -587,7 +582,7 @@ isdnloop_atimeout(isdnloop_card * card, int ch) | |||
587 | /* No user responding */ | 582 | /* No user responding */ |
588 | sprintf(buf, "CAU%s", isdnloop_unicause(card, 1, 3)); | 583 | sprintf(buf, "CAU%s", isdnloop_unicause(card, 1, 3)); |
589 | isdnloop_fake(card, buf, ch + 1); | 584 | isdnloop_fake(card, buf, ch + 1); |
590 | restore_flags(flags); | 585 | spin_unlock_irqrestore(&card->isdnloop_lock, flags); |
591 | } | 586 | } |
592 | 587 | ||
593 | /* | 588 | /* |
@@ -622,8 +617,7 @@ isdnloop_start_ctimer(isdnloop_card * card, int ch) | |||
622 | { | 617 | { |
623 | unsigned long flags; | 618 | unsigned long flags; |
624 | 619 | ||
625 | save_flags(flags); | 620 | spin_lock_irqsave(&card->isdnloop_lock, flags); |
626 | cli(); | ||
627 | init_timer(&card->c_timer[ch]); | 621 | init_timer(&card->c_timer[ch]); |
628 | card->c_timer[ch].expires = jiffies + ISDNLOOP_TIMER_ALERTWAIT; | 622 | card->c_timer[ch].expires = jiffies + ISDNLOOP_TIMER_ALERTWAIT; |
629 | if (ch) | 623 | if (ch) |
@@ -632,7 +626,7 @@ isdnloop_start_ctimer(isdnloop_card * card, int ch) | |||
632 | card->c_timer[ch].function = isdnloop_atimeout0; | 626 | card->c_timer[ch].function = isdnloop_atimeout0; |
633 | card->c_timer[ch].data = (unsigned long) card; | 627 | card->c_timer[ch].data = (unsigned long) card; |
634 | add_timer(&card->c_timer[ch]); | 628 | add_timer(&card->c_timer[ch]); |
635 | restore_flags(flags); | 629 | spin_unlock_irqrestore(&card->isdnloop_lock, flags); |
636 | } | 630 | } |
637 | 631 | ||
638 | /* | 632 | /* |
@@ -647,10 +641,9 @@ isdnloop_kill_ctimer(isdnloop_card * card, int ch) | |||
647 | { | 641 | { |
648 | unsigned long flags; | 642 | unsigned long flags; |
649 | 643 | ||
650 | save_flags(flags); | 644 | spin_lock_irqsave(&card->isdnloop_lock, flags); |
651 | cli(); | ||
652 | del_timer(&card->c_timer[ch]); | 645 | del_timer(&card->c_timer[ch]); |
653 | restore_flags(flags); | 646 | spin_unlock_irqrestore(&card->isdnloop_lock, flags); |
654 | } | 647 | } |
655 | 648 | ||
656 | static u_char si2bit[] = | 649 | static u_char si2bit[] = |
@@ -706,13 +699,12 @@ isdnloop_try_call(isdnloop_card * card, char *p, int lch, isdn_ctrl * cmd) | |||
706 | } | 699 | } |
707 | } | 700 | } |
708 | if (num_match) { | 701 | if (num_match) { |
709 | save_flags(flags); | 702 | spin_lock_irqsave(&card->isdnloop_lock, flags); |
710 | cli(); | ||
711 | /* channel idle? */ | 703 | /* channel idle? */ |
712 | if (!(cc->rcard[ch])) { | 704 | if (!(cc->rcard[ch])) { |
713 | /* Check SI */ | 705 | /* Check SI */ |
714 | if (!(si2bit[cmd->parm.setup.si1] & cc->sil[ch])) { | 706 | if (!(si2bit[cmd->parm.setup.si1] & cc->sil[ch])) { |
715 | restore_flags(flags); | 707 | spin_unlock_irqrestore(&card->isdnloop_lock, flags); |
716 | return 3; | 708 | return 3; |
717 | } | 709 | } |
718 | /* ch is idle, si and number matches */ | 710 | /* ch is idle, si and number matches */ |
@@ -720,10 +712,10 @@ isdnloop_try_call(isdnloop_card * card, char *p, int lch, isdn_ctrl * cmd) | |||
720 | cc->rch[ch] = lch; | 712 | cc->rch[ch] = lch; |
721 | card->rcard[lch] = cc; | 713 | card->rcard[lch] = cc; |
722 | card->rch[lch] = ch; | 714 | card->rch[lch] = ch; |
723 | restore_flags(flags); | 715 | spin_unlock_irqrestore(&card->isdnloop_lock, flags); |
724 | return 0; | 716 | return 0; |
725 | } else { | 717 | } else { |
726 | restore_flags(flags); | 718 | spin_unlock_irqrestore(&card->isdnloop_lock, flags); |
727 | /* num matches, but busy */ | 719 | /* num matches, but busy */ |
728 | if (ch == 1) | 720 | if (ch == 1) |
729 | return 1; | 721 | return 1; |
@@ -1027,8 +1019,7 @@ isdnloop_stopcard(isdnloop_card * card) | |||
1027 | unsigned long flags; | 1019 | unsigned long flags; |
1028 | isdn_ctrl cmd; | 1020 | isdn_ctrl cmd; |
1029 | 1021 | ||
1030 | save_flags(flags); | 1022 | spin_lock_irqsave(&card->isdnloop_lock, flags); |
1031 | cli(); | ||
1032 | if (card->flags & ISDNLOOP_FLAGS_RUNNING) { | 1023 | if (card->flags & ISDNLOOP_FLAGS_RUNNING) { |
1033 | card->flags &= ~ISDNLOOP_FLAGS_RUNNING; | 1024 | card->flags &= ~ISDNLOOP_FLAGS_RUNNING; |
1034 | del_timer(&card->st_timer); | 1025 | del_timer(&card->st_timer); |
@@ -1039,7 +1030,7 @@ isdnloop_stopcard(isdnloop_card * card) | |||
1039 | cmd.driver = card->myid; | 1030 | cmd.driver = card->myid; |
1040 | card->interface.statcallb(&cmd); | 1031 | card->interface.statcallb(&cmd); |
1041 | } | 1032 | } |
1042 | restore_flags(flags); | 1033 | spin_unlock_irqrestore(&card->isdnloop_lock, flags); |
1043 | } | 1034 | } |
1044 | 1035 | ||
1045 | /* | 1036 | /* |
@@ -1078,18 +1069,17 @@ isdnloop_start(isdnloop_card * card, isdnloop_sdef * sdefp) | |||
1078 | return -EBUSY; | 1069 | return -EBUSY; |
1079 | if (copy_from_user((char *) &sdef, (char *) sdefp, sizeof(sdef))) | 1070 | if (copy_from_user((char *) &sdef, (char *) sdefp, sizeof(sdef))) |
1080 | return -EFAULT; | 1071 | return -EFAULT; |
1081 | save_flags(flags); | 1072 | spin_lock_irqsave(&card->isdnloop_lock, flags); |
1082 | cli(); | ||
1083 | switch (sdef.ptype) { | 1073 | switch (sdef.ptype) { |
1084 | case ISDN_PTYPE_EURO: | 1074 | case ISDN_PTYPE_EURO: |
1085 | if (isdnloop_fake(card, "DRV1.23EC-Q.931-CAPI-CNS-BASIS-20.02.96", | 1075 | if (isdnloop_fake(card, "DRV1.23EC-Q.931-CAPI-CNS-BASIS-20.02.96", |
1086 | -1)) { | 1076 | -1)) { |
1087 | restore_flags(flags); | 1077 | spin_unlock_irqrestore(&card->isdnloop_lock, flags); |
1088 | return -ENOMEM; | 1078 | return -ENOMEM; |
1089 | } | 1079 | } |
1090 | card->sil[0] = card->sil[1] = 4; | 1080 | card->sil[0] = card->sil[1] = 4; |
1091 | if (isdnloop_fake(card, "TEI OK", 0)) { | 1081 | if (isdnloop_fake(card, "TEI OK", 0)) { |
1092 | restore_flags(flags); | 1082 | spin_unlock_irqrestore(&card->isdnloop_lock, flags); |
1093 | return -ENOMEM; | 1083 | return -ENOMEM; |
1094 | } | 1084 | } |
1095 | for (i = 0; i < 3; i++) | 1085 | for (i = 0; i < 3; i++) |
@@ -1098,12 +1088,12 @@ isdnloop_start(isdnloop_card * card, isdnloop_sdef * sdefp) | |||
1098 | case ISDN_PTYPE_1TR6: | 1088 | case ISDN_PTYPE_1TR6: |
1099 | if (isdnloop_fake(card, "DRV1.04TC-1TR6-CAPI-CNS-BASIS-29.11.95", | 1089 | if (isdnloop_fake(card, "DRV1.04TC-1TR6-CAPI-CNS-BASIS-29.11.95", |
1100 | -1)) { | 1090 | -1)) { |
1101 | restore_flags(flags); | 1091 | spin_unlock_irqrestore(&card->isdnloop_lock, flags); |
1102 | return -ENOMEM; | 1092 | return -ENOMEM; |
1103 | } | 1093 | } |
1104 | card->sil[0] = card->sil[1] = 4; | 1094 | card->sil[0] = card->sil[1] = 4; |
1105 | if (isdnloop_fake(card, "TEI OK", 0)) { | 1095 | if (isdnloop_fake(card, "TEI OK", 0)) { |
1106 | restore_flags(flags); | 1096 | spin_unlock_irqrestore(&card->isdnloop_lock, flags); |
1107 | return -ENOMEM; | 1097 | return -ENOMEM; |
1108 | } | 1098 | } |
1109 | strcpy(card->s0num[0], sdef.num[0]); | 1099 | strcpy(card->s0num[0], sdef.num[0]); |
@@ -1111,7 +1101,7 @@ isdnloop_start(isdnloop_card * card, isdnloop_sdef * sdefp) | |||
1111 | card->s0num[2][0] = '\0'; | 1101 | card->s0num[2][0] = '\0'; |
1112 | break; | 1102 | break; |
1113 | default: | 1103 | default: |
1114 | restore_flags(flags); | 1104 | spin_unlock_irqrestore(&card->isdnloop_lock, flags); |
1115 | printk(KERN_WARNING "isdnloop: Illegal D-channel protocol %d\n", | 1105 | printk(KERN_WARNING "isdnloop: Illegal D-channel protocol %d\n", |
1116 | sdef.ptype); | 1106 | sdef.ptype); |
1117 | return -EINVAL; | 1107 | return -EINVAL; |
@@ -1122,7 +1112,7 @@ isdnloop_start(isdnloop_card * card, isdnloop_sdef * sdefp) | |||
1122 | card->st_timer.data = (unsigned long) card; | 1112 | card->st_timer.data = (unsigned long) card; |
1123 | add_timer(&card->st_timer); | 1113 | add_timer(&card->st_timer); |
1124 | card->flags |= ISDNLOOP_FLAGS_RUNNING; | 1114 | card->flags |= ISDNLOOP_FLAGS_RUNNING; |
1125 | restore_flags(flags); | 1115 | spin_unlock_irqrestore(&card->isdnloop_lock, flags); |
1126 | return 0; | 1116 | return 0; |
1127 | } | 1117 | } |
1128 | 1118 | ||
@@ -1472,6 +1462,7 @@ isdnloop_initcard(char *id) | |||
1472 | skb_queue_head_init(&card->bqueue[i]); | 1462 | skb_queue_head_init(&card->bqueue[i]); |
1473 | } | 1463 | } |
1474 | skb_queue_head_init(&card->dqueue); | 1464 | skb_queue_head_init(&card->dqueue); |
1465 | card->isdnloop_lock = SPIN_LOCK_UNLOCKED; | ||
1475 | card->next = cards; | 1466 | card->next = cards; |
1476 | cards = card; | 1467 | cards = card; |
1477 | if (!register_isdn(&card->interface)) { | 1468 | if (!register_isdn(&card->interface)) { |
diff --git a/drivers/isdn/isdnloop/isdnloop.h b/drivers/isdn/isdnloop/isdnloop.h index d699fe53e1c3..0d458a86f529 100644 --- a/drivers/isdn/isdnloop/isdnloop.h +++ b/drivers/isdn/isdnloop/isdnloop.h | |||
@@ -94,6 +94,7 @@ typedef struct isdnloop_card { | |||
94 | struct sk_buff_head | 94 | struct sk_buff_head |
95 | bqueue[ISDNLOOP_BCH]; /* B-Channel queues */ | 95 | bqueue[ISDNLOOP_BCH]; /* B-Channel queues */ |
96 | struct sk_buff_head dqueue; /* D-Channel queue */ | 96 | struct sk_buff_head dqueue; /* D-Channel queue */ |
97 | spinlock_t isdnloop_lock; | ||
97 | } isdnloop_card; | 98 | } isdnloop_card; |
98 | 99 | ||
99 | /* | 100 | /* |
diff --git a/drivers/isdn/pcbit/drv.c b/drivers/isdn/pcbit/drv.c index 94f21486bb24..6ead5e1508b7 100644 --- a/drivers/isdn/pcbit/drv.c +++ b/drivers/isdn/pcbit/drv.c | |||
@@ -725,23 +725,27 @@ static int pcbit_stat(u_char __user *buf, int len, int driver, int channel) | |||
725 | 725 | ||
726 | if (stat_st < stat_end) | 726 | if (stat_st < stat_end) |
727 | { | 727 | { |
728 | copy_to_user(buf, statbuf + stat_st, len); | 728 | if (copy_to_user(buf, statbuf + stat_st, len)) |
729 | return -EFAULT; | ||
729 | stat_st += len; | 730 | stat_st += len; |
730 | } | 731 | } |
731 | else | 732 | else |
732 | { | 733 | { |
733 | if (len > STATBUF_LEN - stat_st) | 734 | if (len > STATBUF_LEN - stat_st) |
734 | { | 735 | { |
735 | copy_to_user(buf, statbuf + stat_st, | 736 | if (copy_to_user(buf, statbuf + stat_st, |
736 | STATBUF_LEN - stat_st); | 737 | STATBUF_LEN - stat_st)) |
737 | copy_to_user(buf, statbuf, | 738 | return -EFAULT; |
738 | len - (STATBUF_LEN - stat_st)); | 739 | if (copy_to_user(buf, statbuf, |
740 | len - (STATBUF_LEN - stat_st))) | ||
741 | return -EFAULT; | ||
739 | 742 | ||
740 | stat_st = len - (STATBUF_LEN - stat_st); | 743 | stat_st = len - (STATBUF_LEN - stat_st); |
741 | } | 744 | } |
742 | else | 745 | else |
743 | { | 746 | { |
744 | copy_to_user(buf, statbuf + stat_st, len); | 747 | if (copy_to_user(buf, statbuf + stat_st, len)) |
748 | return -EFAULT; | ||
745 | 749 | ||
746 | stat_st += len; | 750 | stat_st += len; |
747 | 751 | ||
diff --git a/drivers/isdn/pcbit/layer2.c b/drivers/isdn/pcbit/layer2.c index 13e7d219d1c7..937fd2120381 100644 --- a/drivers/isdn/pcbit/layer2.c +++ b/drivers/isdn/pcbit/layer2.c | |||
@@ -311,6 +311,7 @@ pcbit_deliver(void *data) | |||
311 | dev->read_queue = frame->next; | 311 | dev->read_queue = frame->next; |
312 | spin_unlock_irqrestore(&dev->lock, flags); | 312 | spin_unlock_irqrestore(&dev->lock, flags); |
313 | 313 | ||
314 | msg = 0; | ||
314 | SET_MSG_CPU(msg, 0); | 315 | SET_MSG_CPU(msg, 0); |
315 | SET_MSG_PROC(msg, 0); | 316 | SET_MSG_PROC(msg, 0); |
316 | SET_MSG_CMD(msg, frame->skb->data[2]); | 317 | SET_MSG_CMD(msg, frame->skb->data[2]); |
diff --git a/drivers/isdn/sc/init.c b/drivers/isdn/sc/init.c index 222ca7c08baa..06c9872e8c6a 100644 --- a/drivers/isdn/sc/init.c +++ b/drivers/isdn/sc/init.c | |||
@@ -98,13 +98,14 @@ static int __init sc_init(void) | |||
98 | * Confirm the I/O Address with a test | 98 | * Confirm the I/O Address with a test |
99 | */ | 99 | */ |
100 | if(io[b] == 0) { | 100 | if(io[b] == 0) { |
101 | pr_debug("I/O Address 0x%x is in use.\n"); | 101 | pr_debug("I/O Address invalid.\n"); |
102 | continue; | 102 | continue; |
103 | } | 103 | } |
104 | 104 | ||
105 | outb(0x18, io[b] + 0x400 * EXP_PAGE0); | 105 | outb(0x18, io[b] + 0x400 * EXP_PAGE0); |
106 | if(inb(io[b] + 0x400 * EXP_PAGE0) != 0x18) { | 106 | if(inb(io[b] + 0x400 * EXP_PAGE0) != 0x18) { |
107 | pr_debug("I/O Base 0x%x fails test\n"); | 107 | pr_debug("I/O Base 0x%x fails test\n", |
108 | io[b] + 0x400 * EXP_PAGE0); | ||
108 | continue; | 109 | continue; |
109 | } | 110 | } |
110 | } | 111 | } |
@@ -158,8 +159,8 @@ static int __init sc_init(void) | |||
158 | outb(0xFF, io[b] + RESET_OFFSET); | 159 | outb(0xFF, io[b] + RESET_OFFSET); |
159 | msleep_interruptible(10000); | 160 | msleep_interruptible(10000); |
160 | } | 161 | } |
161 | pr_debug("RAM Base for board %d is 0x%x, %s probe\n", b, ram[b], | 162 | pr_debug("RAM Base for board %d is 0x%lx, %s probe\n", b, |
162 | ram[b] == 0 ? "will" : "won't"); | 163 | ram[b], ram[b] == 0 ? "will" : "won't"); |
163 | 164 | ||
164 | if(ram[b]) { | 165 | if(ram[b]) { |
165 | /* | 166 | /* |
@@ -168,7 +169,7 @@ static int __init sc_init(void) | |||
168 | * board model | 169 | * board model |
169 | */ | 170 | */ |
170 | if(request_region(ram[b], SRAM_PAGESIZE, "sc test")) { | 171 | if(request_region(ram[b], SRAM_PAGESIZE, "sc test")) { |
171 | pr_debug("request_region for RAM base 0x%x succeeded\n", ram[b]); | 172 | pr_debug("request_region for RAM base 0x%lx succeeded\n", ram[b]); |
172 | model = identify_board(ram[b], io[b]); | 173 | model = identify_board(ram[b], io[b]); |
173 | release_region(ram[b], SRAM_PAGESIZE); | 174 | release_region(ram[b], SRAM_PAGESIZE); |
174 | } | 175 | } |
@@ -204,7 +205,7 @@ static int __init sc_init(void) | |||
204 | * Nope, there was no place in RAM for the | 205 | * Nope, there was no place in RAM for the |
205 | * board, or it couldn't be identified | 206 | * board, or it couldn't be identified |
206 | */ | 207 | */ |
207 | pr_debug("Failed to find an adapter at 0x%x\n", ram[b]); | 208 | pr_debug("Failed to find an adapter at 0x%lx\n", ram[b]); |
208 | continue; | 209 | continue; |
209 | } | 210 | } |
210 | 211 | ||
@@ -451,7 +452,7 @@ static int identify_board(unsigned long rambase, unsigned int iobase) | |||
451 | HWConfig_pl hwci; | 452 | HWConfig_pl hwci; |
452 | int x; | 453 | int x; |
453 | 454 | ||
454 | pr_debug("Attempting to identify adapter @ 0x%x io 0x%x\n", | 455 | pr_debug("Attempting to identify adapter @ 0x%lx io 0x%x\n", |
455 | rambase, iobase); | 456 | rambase, iobase); |
456 | 457 | ||
457 | /* | 458 | /* |
@@ -490,7 +491,7 @@ static int identify_board(unsigned long rambase, unsigned int iobase) | |||
490 | outb(PRI_BASEPG_VAL, pgport); | 491 | outb(PRI_BASEPG_VAL, pgport); |
491 | msleep_interruptible(1000); | 492 | msleep_interruptible(1000); |
492 | sig = readl(rambase + SIG_OFFSET); | 493 | sig = readl(rambase + SIG_OFFSET); |
493 | pr_debug("Looking for a signature, got 0x%x\n", sig); | 494 | pr_debug("Looking for a signature, got 0x%lx\n", sig); |
494 | if(sig == SIGNATURE) | 495 | if(sig == SIGNATURE) |
495 | return PRI_BOARD; | 496 | return PRI_BOARD; |
496 | 497 | ||
@@ -500,7 +501,7 @@ static int identify_board(unsigned long rambase, unsigned int iobase) | |||
500 | outb(BRI_BASEPG_VAL, pgport); | 501 | outb(BRI_BASEPG_VAL, pgport); |
501 | msleep_interruptible(1000); | 502 | msleep_interruptible(1000); |
502 | sig = readl(rambase + SIG_OFFSET); | 503 | sig = readl(rambase + SIG_OFFSET); |
503 | pr_debug("Looking for a signature, got 0x%x\n", sig); | 504 | pr_debug("Looking for a signature, got 0x%lx\n", sig); |
504 | if(sig == SIGNATURE) | 505 | if(sig == SIGNATURE) |
505 | return BRI_BOARD; | 506 | return BRI_BOARD; |
506 | 507 | ||
@@ -510,7 +511,7 @@ static int identify_board(unsigned long rambase, unsigned int iobase) | |||
510 | * Try to spot a card | 511 | * Try to spot a card |
511 | */ | 512 | */ |
512 | sig = readl(rambase + SIG_OFFSET); | 513 | sig = readl(rambase + SIG_OFFSET); |
513 | pr_debug("Looking for a signature, got 0x%x\n", sig); | 514 | pr_debug("Looking for a signature, got 0x%lx\n", sig); |
514 | if(sig != SIGNATURE) | 515 | if(sig != SIGNATURE) |
515 | return -1; | 516 | return -1; |
516 | 517 | ||
@@ -540,7 +541,7 @@ static int identify_board(unsigned long rambase, unsigned int iobase) | |||
540 | memcpy_fromio(&rcvmsg, &(dpm->rsp_queue[dpm->rsp_tail]), MSG_LEN); | 541 | memcpy_fromio(&rcvmsg, &(dpm->rsp_queue[dpm->rsp_tail]), MSG_LEN); |
541 | pr_debug("Got HWConfig response, status = 0x%x\n", rcvmsg.rsp_status); | 542 | pr_debug("Got HWConfig response, status = 0x%x\n", rcvmsg.rsp_status); |
542 | memcpy(&hwci, &(rcvmsg.msg_data.HWCresponse), sizeof(HWConfig_pl)); | 543 | memcpy(&hwci, &(rcvmsg.msg_data.HWCresponse), sizeof(HWConfig_pl)); |
543 | pr_debug("Hardware Config: Interface: %s, RAM Size: %d, Serial: %s\n" | 544 | pr_debug("Hardware Config: Interface: %s, RAM Size: %ld, Serial: %s\n" |
544 | " Part: %s, Rev: %s\n", | 545 | " Part: %s, Rev: %s\n", |
545 | hwci.st_u_sense ? "S/T" : "U", hwci.ram_size, | 546 | hwci.st_u_sense ? "S/T" : "U", hwci.ram_size, |
546 | hwci.serial_no, hwci.part_no, hwci.rev_no); | 547 | hwci.serial_no, hwci.part_no, hwci.rev_no); |
diff --git a/drivers/isdn/sc/packet.c b/drivers/isdn/sc/packet.c index f50defc38ae5..1e04676b016b 100644 --- a/drivers/isdn/sc/packet.c +++ b/drivers/isdn/sc/packet.c | |||
@@ -44,7 +44,7 @@ int sndpkt(int devId, int channel, struct sk_buff *data) | |||
44 | return -ENODEV; | 44 | return -ENODEV; |
45 | } | 45 | } |
46 | 46 | ||
47 | pr_debug("%s: sndpkt: frst = 0x%x nxt = %d f = %d n = %d\n", | 47 | pr_debug("%s: sndpkt: frst = 0x%lx nxt = %d f = %d n = %d\n", |
48 | sc_adapter[card]->devicename, | 48 | sc_adapter[card]->devicename, |
49 | sc_adapter[card]->channel[channel].first_sendbuf, | 49 | sc_adapter[card]->channel[channel].first_sendbuf, |
50 | sc_adapter[card]->channel[channel].next_sendbuf, | 50 | sc_adapter[card]->channel[channel].next_sendbuf, |
@@ -66,7 +66,7 @@ int sndpkt(int devId, int channel, struct sk_buff *data) | |||
66 | ReqLnkWrite.buff_offset = sc_adapter[card]->channel[channel].next_sendbuf * | 66 | ReqLnkWrite.buff_offset = sc_adapter[card]->channel[channel].next_sendbuf * |
67 | BUFFER_SIZE + sc_adapter[card]->channel[channel].first_sendbuf; | 67 | BUFFER_SIZE + sc_adapter[card]->channel[channel].first_sendbuf; |
68 | ReqLnkWrite.msg_len = data->len; /* sk_buff size */ | 68 | ReqLnkWrite.msg_len = data->len; /* sk_buff size */ |
69 | pr_debug("%s: writing %d bytes to buffer offset 0x%x\n", | 69 | pr_debug("%s: writing %d bytes to buffer offset 0x%lx\n", |
70 | sc_adapter[card]->devicename, | 70 | sc_adapter[card]->devicename, |
71 | ReqLnkWrite.msg_len, ReqLnkWrite.buff_offset); | 71 | ReqLnkWrite.msg_len, ReqLnkWrite.buff_offset); |
72 | memcpy_toshmem(card, (char *)ReqLnkWrite.buff_offset, data->data, ReqLnkWrite.msg_len); | 72 | memcpy_toshmem(card, (char *)ReqLnkWrite.buff_offset, data->data, ReqLnkWrite.msg_len); |
@@ -74,7 +74,7 @@ int sndpkt(int devId, int channel, struct sk_buff *data) | |||
74 | /* | 74 | /* |
75 | * sendmessage | 75 | * sendmessage |
76 | */ | 76 | */ |
77 | pr_debug("%s: sndpkt size=%d, buf_offset=0x%x buf_indx=%d\n", | 77 | pr_debug("%s: sndpkt size=%d, buf_offset=0x%lx buf_indx=%d\n", |
78 | sc_adapter[card]->devicename, | 78 | sc_adapter[card]->devicename, |
79 | ReqLnkWrite.msg_len, ReqLnkWrite.buff_offset, | 79 | ReqLnkWrite.msg_len, ReqLnkWrite.buff_offset, |
80 | sc_adapter[card]->channel[channel].next_sendbuf); | 80 | sc_adapter[card]->channel[channel].next_sendbuf); |
@@ -124,7 +124,7 @@ void rcvpkt(int card, RspMessage *rcvmsg) | |||
124 | return; | 124 | return; |
125 | } | 125 | } |
126 | skb_put(skb, rcvmsg->msg_data.response.msg_len); | 126 | skb_put(skb, rcvmsg->msg_data.response.msg_len); |
127 | pr_debug("%s: getting data from offset: 0x%x\n", | 127 | pr_debug("%s: getting data from offset: 0x%lx\n", |
128 | sc_adapter[card]->devicename, | 128 | sc_adapter[card]->devicename, |
129 | rcvmsg->msg_data.response.buff_offset); | 129 | rcvmsg->msg_data.response.buff_offset); |
130 | memcpy_fromshmem(card, | 130 | memcpy_fromshmem(card, |
@@ -143,7 +143,7 @@ void rcvpkt(int card, RspMessage *rcvmsg) | |||
143 | /* memset_shmem(card, rcvmsg->msg_data.response.buff_offset, 0, BUFFER_SIZE); */ | 143 | /* memset_shmem(card, rcvmsg->msg_data.response.buff_offset, 0, BUFFER_SIZE); */ |
144 | newll.buff_offset = rcvmsg->msg_data.response.buff_offset; | 144 | newll.buff_offset = rcvmsg->msg_data.response.buff_offset; |
145 | newll.msg_len = BUFFER_SIZE; | 145 | newll.msg_len = BUFFER_SIZE; |
146 | pr_debug("%s: recycled buffer at offset 0x%x size %d\n", | 146 | pr_debug("%s: recycled buffer at offset 0x%lx size %d\n", |
147 | sc_adapter[card]->devicename, | 147 | sc_adapter[card]->devicename, |
148 | newll.buff_offset, newll.msg_len); | 148 | newll.buff_offset, newll.msg_len); |
149 | sendmessage(card, CEPID, ceReqTypeLnk, ceReqClass1, ceReqLnkRead, | 149 | sendmessage(card, CEPID, ceReqTypeLnk, ceReqClass1, ceReqLnkRead, |
@@ -186,7 +186,7 @@ int setup_buffers(int card, int c) | |||
186 | sc_adapter[card]->channel[c-1].num_sendbufs = nBuffers / 2; | 186 | sc_adapter[card]->channel[c-1].num_sendbufs = nBuffers / 2; |
187 | sc_adapter[card]->channel[c-1].free_sendbufs = nBuffers / 2; | 187 | sc_adapter[card]->channel[c-1].free_sendbufs = nBuffers / 2; |
188 | sc_adapter[card]->channel[c-1].next_sendbuf = 0; | 188 | sc_adapter[card]->channel[c-1].next_sendbuf = 0; |
189 | pr_debug("%s: send buffer setup complete: first=0x%x n=%d f=%d, nxt=%d\n", | 189 | pr_debug("%s: send buffer setup complete: first=0x%lx n=%d f=%d, nxt=%d\n", |
190 | sc_adapter[card]->devicename, | 190 | sc_adapter[card]->devicename, |
191 | sc_adapter[card]->channel[c-1].first_sendbuf, | 191 | sc_adapter[card]->channel[c-1].first_sendbuf, |
192 | sc_adapter[card]->channel[c-1].num_sendbufs, | 192 | sc_adapter[card]->channel[c-1].num_sendbufs, |
@@ -203,7 +203,7 @@ int setup_buffers(int card, int c) | |||
203 | ((sc_adapter[card]->channel[c-1].first_sendbuf + | 203 | ((sc_adapter[card]->channel[c-1].first_sendbuf + |
204 | (nBuffers / 2) * buffer_size) + (buffer_size * i)); | 204 | (nBuffers / 2) * buffer_size) + (buffer_size * i)); |
205 | RcvBuffOffset.msg_len = buffer_size; | 205 | RcvBuffOffset.msg_len = buffer_size; |
206 | pr_debug("%s: adding RcvBuffer #%d offset=0x%x sz=%d bufsz:%d\n", | 206 | pr_debug("%s: adding RcvBuffer #%d offset=0x%lx sz=%d bufsz:%d\n", |
207 | sc_adapter[card]->devicename, | 207 | sc_adapter[card]->devicename, |
208 | i + 1, RcvBuffOffset.buff_offset, | 208 | i + 1, RcvBuffOffset.buff_offset, |
209 | RcvBuffOffset.msg_len,buffer_size); | 209 | RcvBuffOffset.msg_len,buffer_size); |
diff --git a/drivers/isdn/sc/shmem.c b/drivers/isdn/sc/shmem.c index 24854826ca45..6f58862992db 100644 --- a/drivers/isdn/sc/shmem.c +++ b/drivers/isdn/sc/shmem.c | |||
@@ -61,7 +61,7 @@ void memcpy_toshmem(int card, void *dest, const void *src, size_t n) | |||
61 | spin_unlock_irqrestore(&sc_adapter[card]->lock, flags); | 61 | spin_unlock_irqrestore(&sc_adapter[card]->lock, flags); |
62 | pr_debug("%s: set page to %#x\n",sc_adapter[card]->devicename, | 62 | pr_debug("%s: set page to %#x\n",sc_adapter[card]->devicename, |
63 | ((sc_adapter[card]->shmem_magic + ch * SRAM_PAGESIZE)>>14)|0x80); | 63 | ((sc_adapter[card]->shmem_magic + ch * SRAM_PAGESIZE)>>14)|0x80); |
64 | pr_debug("%s: copying %d bytes from %#x to %#x\n", | 64 | pr_debug("%s: copying %d bytes from %#lx to %#lx\n", |
65 | sc_adapter[card]->devicename, n, | 65 | sc_adapter[card]->devicename, n, |
66 | (unsigned long) src, | 66 | (unsigned long) src, |
67 | sc_adapter[card]->rambase + ((unsigned long) dest %0x4000)); | 67 | sc_adapter[card]->rambase + ((unsigned long) dest %0x4000)); |
diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index aecbbe2e89a9..3c1711210e38 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c | |||
@@ -91,6 +91,8 @@ EXPORT_SYMBOL_GPL(led_classdev_resume); | |||
91 | */ | 91 | */ |
92 | int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) | 92 | int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) |
93 | { | 93 | { |
94 | int rc; | ||
95 | |||
94 | led_cdev->class_dev = class_device_create(leds_class, NULL, 0, | 96 | led_cdev->class_dev = class_device_create(leds_class, NULL, 0, |
95 | parent, "%s", led_cdev->name); | 97 | parent, "%s", led_cdev->name); |
96 | if (unlikely(IS_ERR(led_cdev->class_dev))) | 98 | if (unlikely(IS_ERR(led_cdev->class_dev))) |
@@ -99,8 +101,10 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) | |||
99 | class_set_devdata(led_cdev->class_dev, led_cdev); | 101 | class_set_devdata(led_cdev->class_dev, led_cdev); |
100 | 102 | ||
101 | /* register the attributes */ | 103 | /* register the attributes */ |
102 | class_device_create_file(led_cdev->class_dev, | 104 | rc = class_device_create_file(led_cdev->class_dev, |
103 | &class_device_attr_brightness); | 105 | &class_device_attr_brightness); |
106 | if (rc) | ||
107 | goto err_out; | ||
104 | 108 | ||
105 | /* add to the list of leds */ | 109 | /* add to the list of leds */ |
106 | write_lock(&leds_list_lock); | 110 | write_lock(&leds_list_lock); |
@@ -110,16 +114,28 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) | |||
110 | #ifdef CONFIG_LEDS_TRIGGERS | 114 | #ifdef CONFIG_LEDS_TRIGGERS |
111 | rwlock_init(&led_cdev->trigger_lock); | 115 | rwlock_init(&led_cdev->trigger_lock); |
112 | 116 | ||
113 | led_trigger_set_default(led_cdev); | 117 | rc = class_device_create_file(led_cdev->class_dev, |
118 | &class_device_attr_trigger); | ||
119 | if (rc) | ||
120 | goto err_out_led_list; | ||
114 | 121 | ||
115 | class_device_create_file(led_cdev->class_dev, | 122 | led_trigger_set_default(led_cdev); |
116 | &class_device_attr_trigger); | ||
117 | #endif | 123 | #endif |
118 | 124 | ||
119 | printk(KERN_INFO "Registered led device: %s\n", | 125 | printk(KERN_INFO "Registered led device: %s\n", |
120 | led_cdev->class_dev->class_id); | 126 | led_cdev->class_dev->class_id); |
121 | 127 | ||
122 | return 0; | 128 | return 0; |
129 | |||
130 | #ifdef CONFIG_LEDS_TRIGGERS | ||
131 | err_out_led_list: | ||
132 | class_device_remove_file(led_cdev->class_dev, | ||
133 | &class_device_attr_brightness); | ||
134 | list_del(&led_cdev->node); | ||
135 | #endif | ||
136 | err_out: | ||
137 | class_device_unregister(led_cdev->class_dev); | ||
138 | return rc; | ||
123 | } | 139 | } |
124 | EXPORT_SYMBOL_GPL(led_classdev_register); | 140 | EXPORT_SYMBOL_GPL(led_classdev_register); |
125 | 141 | ||
diff --git a/drivers/leds/ledtrig-timer.c b/drivers/leds/ledtrig-timer.c index 179c2876b541..29a8818a32ec 100644 --- a/drivers/leds/ledtrig-timer.c +++ b/drivers/leds/ledtrig-timer.c | |||
@@ -123,6 +123,7 @@ static CLASS_DEVICE_ATTR(delay_off, 0644, led_delay_off_show, | |||
123 | static void timer_trig_activate(struct led_classdev *led_cdev) | 123 | static void timer_trig_activate(struct led_classdev *led_cdev) |
124 | { | 124 | { |
125 | struct timer_trig_data *timer_data; | 125 | struct timer_trig_data *timer_data; |
126 | int rc; | ||
126 | 127 | ||
127 | timer_data = kzalloc(sizeof(struct timer_trig_data), GFP_KERNEL); | 128 | timer_data = kzalloc(sizeof(struct timer_trig_data), GFP_KERNEL); |
128 | if (!timer_data) | 129 | if (!timer_data) |
@@ -134,10 +135,21 @@ static void timer_trig_activate(struct led_classdev *led_cdev) | |||
134 | timer_data->timer.function = led_timer_function; | 135 | timer_data->timer.function = led_timer_function; |
135 | timer_data->timer.data = (unsigned long) led_cdev; | 136 | timer_data->timer.data = (unsigned long) led_cdev; |
136 | 137 | ||
137 | class_device_create_file(led_cdev->class_dev, | 138 | rc = class_device_create_file(led_cdev->class_dev, |
138 | &class_device_attr_delay_on); | 139 | &class_device_attr_delay_on); |
139 | class_device_create_file(led_cdev->class_dev, | 140 | if (rc) goto err_out; |
141 | rc = class_device_create_file(led_cdev->class_dev, | ||
140 | &class_device_attr_delay_off); | 142 | &class_device_attr_delay_off); |
143 | if (rc) goto err_out_delayon; | ||
144 | |||
145 | return; | ||
146 | |||
147 | err_out_delayon: | ||
148 | class_device_remove_file(led_cdev->class_dev, | ||
149 | &class_device_attr_delay_on); | ||
150 | err_out: | ||
151 | led_cdev->trigger_data = NULL; | ||
152 | kfree(timer_data); | ||
141 | } | 153 | } |
142 | 154 | ||
143 | static void timer_trig_deactivate(struct led_classdev *led_cdev) | 155 | static void timer_trig_deactivate(struct led_classdev *led_cdev) |
diff --git a/drivers/macintosh/windfarm_pm112.c b/drivers/macintosh/windfarm_pm112.c index fa4b13f89369..b3fbb45bc90a 100644 --- a/drivers/macintosh/windfarm_pm112.c +++ b/drivers/macintosh/windfarm_pm112.c | |||
@@ -685,6 +685,17 @@ static int __init wf_pm112_init(void) | |||
685 | ++nr_cores; | 685 | ++nr_cores; |
686 | 686 | ||
687 | printk(KERN_INFO "windfarm: initializing for dual-core desktop G5\n"); | 687 | printk(KERN_INFO "windfarm: initializing for dual-core desktop G5\n"); |
688 | |||
689 | #ifdef MODULE | ||
690 | request_module("windfarm_smu_controls"); | ||
691 | request_module("windfarm_smu_sensors"); | ||
692 | request_module("windfarm_smu_sat"); | ||
693 | request_module("windfarm_lm75_sensor"); | ||
694 | request_module("windfarm_max6690_sensor"); | ||
695 | request_module("windfarm_cpufreq_clamp"); | ||
696 | |||
697 | #endif /* MODULE */ | ||
698 | |||
688 | platform_driver_register(&wf_pm112_driver); | 699 | platform_driver_register(&wf_pm112_driver); |
689 | return 0; | 700 | return 0; |
690 | } | 701 | } |
diff --git a/drivers/macintosh/windfarm_pm81.c b/drivers/macintosh/windfarm_pm81.c index 2a944851b8e1..f24fa734046a 100644 --- a/drivers/macintosh/windfarm_pm81.c +++ b/drivers/macintosh/windfarm_pm81.c | |||
@@ -788,6 +788,7 @@ static int __init wf_smu_init(void) | |||
788 | request_module("windfarm_smu_controls"); | 788 | request_module("windfarm_smu_controls"); |
789 | request_module("windfarm_smu_sensors"); | 789 | request_module("windfarm_smu_sensors"); |
790 | request_module("windfarm_lm75_sensor"); | 790 | request_module("windfarm_lm75_sensor"); |
791 | request_module("windfarm_cpufreq_clamp"); | ||
791 | 792 | ||
792 | #endif /* MODULE */ | 793 | #endif /* MODULE */ |
793 | platform_driver_register(&wf_smu_driver); | 794 | platform_driver_register(&wf_smu_driver); |
diff --git a/drivers/macintosh/windfarm_pm91.c b/drivers/macintosh/windfarm_pm91.c index 9961a67b4f85..26eee69ebe6d 100644 --- a/drivers/macintosh/windfarm_pm91.c +++ b/drivers/macintosh/windfarm_pm91.c | |||
@@ -719,6 +719,7 @@ static int __init wf_smu_init(void) | |||
719 | request_module("windfarm_smu_controls"); | 719 | request_module("windfarm_smu_controls"); |
720 | request_module("windfarm_smu_sensors"); | 720 | request_module("windfarm_smu_sensors"); |
721 | request_module("windfarm_lm75_sensor"); | 721 | request_module("windfarm_lm75_sensor"); |
722 | request_module("windfarm_cpufreq_clamp"); | ||
722 | 723 | ||
723 | #endif /* MODULE */ | 724 | #endif /* MODULE */ |
724 | platform_driver_register(&wf_smu_driver); | 725 | platform_driver_register(&wf_smu_driver); |
diff --git a/drivers/mca/mca-bus.c b/drivers/mca/mca-bus.c index 09baa43b2599..da862e4632dd 100644 --- a/drivers/mca/mca-bus.c +++ b/drivers/mca/mca-bus.c | |||
@@ -100,6 +100,7 @@ static DEVICE_ATTR(pos, S_IRUGO, mca_show_pos, NULL); | |||
100 | int __init mca_register_device(int bus, struct mca_device *mca_dev) | 100 | int __init mca_register_device(int bus, struct mca_device *mca_dev) |
101 | { | 101 | { |
102 | struct mca_bus *mca_bus = mca_root_busses[bus]; | 102 | struct mca_bus *mca_bus = mca_root_busses[bus]; |
103 | int rc; | ||
103 | 104 | ||
104 | mca_dev->dev.parent = &mca_bus->dev; | 105 | mca_dev->dev.parent = &mca_bus->dev; |
105 | mca_dev->dev.bus = &mca_bus_type; | 106 | mca_dev->dev.bus = &mca_bus_type; |
@@ -108,13 +109,23 @@ int __init mca_register_device(int bus, struct mca_device *mca_dev) | |||
108 | mca_dev->dev.dma_mask = &mca_dev->dma_mask; | 109 | mca_dev->dev.dma_mask = &mca_dev->dma_mask; |
109 | mca_dev->dev.coherent_dma_mask = mca_dev->dma_mask; | 110 | mca_dev->dev.coherent_dma_mask = mca_dev->dma_mask; |
110 | 111 | ||
111 | if (device_register(&mca_dev->dev)) | 112 | rc = device_register(&mca_dev->dev); |
112 | return 0; | 113 | if (rc) |
114 | goto err_out; | ||
113 | 115 | ||
114 | device_create_file(&mca_dev->dev, &dev_attr_id); | 116 | rc = device_create_file(&mca_dev->dev, &dev_attr_id); |
115 | device_create_file(&mca_dev->dev, &dev_attr_pos); | 117 | if (rc) goto err_out_devreg; |
118 | rc = device_create_file(&mca_dev->dev, &dev_attr_pos); | ||
119 | if (rc) goto err_out_id; | ||
116 | 120 | ||
117 | return 1; | 121 | return 1; |
122 | |||
123 | err_out_id: | ||
124 | device_remove_file(&mca_dev->dev, &dev_attr_id); | ||
125 | err_out_devreg: | ||
126 | device_unregister(&mca_dev->dev); | ||
127 | err_out: | ||
128 | return 0; | ||
118 | } | 129 | } |
119 | 130 | ||
120 | /* */ | 131 | /* */ |
@@ -130,13 +141,16 @@ struct mca_bus * __devinit mca_attach_bus(int bus) | |||
130 | return NULL; | 141 | return NULL; |
131 | } | 142 | } |
132 | 143 | ||
133 | mca_bus = kmalloc(sizeof(struct mca_bus), GFP_KERNEL); | 144 | mca_bus = kzalloc(sizeof(struct mca_bus), GFP_KERNEL); |
134 | if (!mca_bus) | 145 | if (!mca_bus) |
135 | return NULL; | 146 | return NULL; |
136 | memset(mca_bus, 0, sizeof(struct mca_bus)); | 147 | |
137 | sprintf(mca_bus->dev.bus_id,"mca%d",bus); | 148 | sprintf(mca_bus->dev.bus_id,"mca%d",bus); |
138 | sprintf(mca_bus->name,"Host %s MCA Bridge", bus ? "Secondary" : "Primary"); | 149 | sprintf(mca_bus->name,"Host %s MCA Bridge", bus ? "Secondary" : "Primary"); |
139 | device_register(&mca_bus->dev); | 150 | if (device_register(&mca_bus->dev)) { |
151 | kfree(mca_bus); | ||
152 | return NULL; | ||
153 | } | ||
140 | 154 | ||
141 | mca_root_busses[bus] = mca_bus; | 155 | mca_root_busses[bus] = mca_bus; |
142 | 156 | ||
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 8e67634e79a0..d6f614738bbd 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c | |||
@@ -536,7 +536,7 @@ static int bitmap_read_sb(struct bitmap *bitmap) | |||
536 | printk(KERN_INFO "%s: bitmap file is out of date (%llu < %llu) " | 536 | printk(KERN_INFO "%s: bitmap file is out of date (%llu < %llu) " |
537 | "-- forcing full recovery\n", bmname(bitmap), events, | 537 | "-- forcing full recovery\n", bmname(bitmap), events, |
538 | (unsigned long long) bitmap->mddev->events); | 538 | (unsigned long long) bitmap->mddev->events); |
539 | sb->state |= BITMAP_STALE; | 539 | sb->state |= cpu_to_le32(BITMAP_STALE); |
540 | } | 540 | } |
541 | success: | 541 | success: |
542 | /* assign fields using values from superblock */ | 542 | /* assign fields using values from superblock */ |
@@ -544,11 +544,11 @@ success: | |||
544 | bitmap->daemon_sleep = daemon_sleep; | 544 | bitmap->daemon_sleep = daemon_sleep; |
545 | bitmap->daemon_lastrun = jiffies; | 545 | bitmap->daemon_lastrun = jiffies; |
546 | bitmap->max_write_behind = write_behind; | 546 | bitmap->max_write_behind = write_behind; |
547 | bitmap->flags |= sb->state; | 547 | bitmap->flags |= le32_to_cpu(sb->state); |
548 | if (le32_to_cpu(sb->version) == BITMAP_MAJOR_HOSTENDIAN) | 548 | if (le32_to_cpu(sb->version) == BITMAP_MAJOR_HOSTENDIAN) |
549 | bitmap->flags |= BITMAP_HOSTENDIAN; | 549 | bitmap->flags |= BITMAP_HOSTENDIAN; |
550 | bitmap->events_cleared = le64_to_cpu(sb->events_cleared); | 550 | bitmap->events_cleared = le64_to_cpu(sb->events_cleared); |
551 | if (sb->state & BITMAP_STALE) | 551 | if (sb->state & cpu_to_le32(BITMAP_STALE)) |
552 | bitmap->events_cleared = bitmap->mddev->events; | 552 | bitmap->events_cleared = bitmap->mddev->events; |
553 | err = 0; | 553 | err = 0; |
554 | out: | 554 | out: |
@@ -578,9 +578,9 @@ static void bitmap_mask_state(struct bitmap *bitmap, enum bitmap_state bits, | |||
578 | spin_unlock_irqrestore(&bitmap->lock, flags); | 578 | spin_unlock_irqrestore(&bitmap->lock, flags); |
579 | sb = (bitmap_super_t *)kmap_atomic(bitmap->sb_page, KM_USER0); | 579 | sb = (bitmap_super_t *)kmap_atomic(bitmap->sb_page, KM_USER0); |
580 | switch (op) { | 580 | switch (op) { |
581 | case MASK_SET: sb->state |= bits; | 581 | case MASK_SET: sb->state |= cpu_to_le32(bits); |
582 | break; | 582 | break; |
583 | case MASK_UNSET: sb->state &= ~bits; | 583 | case MASK_UNSET: sb->state &= cpu_to_le32(~bits); |
584 | break; | 584 | break; |
585 | default: BUG(); | 585 | default: BUG(); |
586 | } | 586 | } |
@@ -1413,7 +1413,7 @@ int bitmap_create(mddev_t *mddev) | |||
1413 | int err; | 1413 | int err; |
1414 | sector_t start; | 1414 | sector_t start; |
1415 | 1415 | ||
1416 | BUG_ON(sizeof(bitmap_super_t) != 256); | 1416 | BUILD_BUG_ON(sizeof(bitmap_super_t) != 256); |
1417 | 1417 | ||
1418 | if (!file && !mddev->bitmap_offset) /* bitmap disabled, nothing to do */ | 1418 | if (!file && !mddev->bitmap_offset) /* bitmap disabled, nothing to do */ |
1419 | return 0; | 1419 | return 0; |
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 655d816760e5..08a40f4e4f60 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
17 | #include <linux/crypto.h> | 17 | #include <linux/crypto.h> |
18 | #include <linux/workqueue.h> | 18 | #include <linux/workqueue.h> |
19 | #include <linux/backing-dev.h> | ||
19 | #include <asm/atomic.h> | 20 | #include <asm/atomic.h> |
20 | #include <linux/scatterlist.h> | 21 | #include <linux/scatterlist.h> |
21 | #include <asm/page.h> | 22 | #include <asm/page.h> |
@@ -602,7 +603,7 @@ static void process_write(struct crypt_io *io) | |||
602 | 603 | ||
603 | /* out of memory -> run queues */ | 604 | /* out of memory -> run queues */ |
604 | if (remaining) | 605 | if (remaining) |
605 | blk_congestion_wait(bio_data_dir(clone), HZ/100); | 606 | congestion_wait(bio_data_dir(clone), HZ/100); |
606 | } | 607 | } |
607 | } | 608 | } |
608 | 609 | ||
@@ -914,8 +915,6 @@ static int crypt_status(struct dm_target *ti, status_type_t type, | |||
914 | char *result, unsigned int maxlen) | 915 | char *result, unsigned int maxlen) |
915 | { | 916 | { |
916 | struct crypt_config *cc = (struct crypt_config *) ti->private; | 917 | struct crypt_config *cc = (struct crypt_config *) ti->private; |
917 | const char *cipher; | ||
918 | const char *chainmode = NULL; | ||
919 | unsigned int sz = 0; | 918 | unsigned int sz = 0; |
920 | 919 | ||
921 | switch (type) { | 920 | switch (type) { |
@@ -924,14 +923,11 @@ static int crypt_status(struct dm_target *ti, status_type_t type, | |||
924 | break; | 923 | break; |
925 | 924 | ||
926 | case STATUSTYPE_TABLE: | 925 | case STATUSTYPE_TABLE: |
927 | cipher = crypto_blkcipher_name(cc->tfm); | ||
928 | |||
929 | chainmode = cc->chainmode; | ||
930 | |||
931 | if (cc->iv_mode) | 926 | if (cc->iv_mode) |
932 | DMEMIT("%s-%s-%s ", cipher, chainmode, cc->iv_mode); | 927 | DMEMIT("%s-%s-%s ", cc->cipher, cc->chainmode, |
928 | cc->iv_mode); | ||
933 | else | 929 | else |
934 | DMEMIT("%s-%s ", cipher, chainmode); | 930 | DMEMIT("%s-%s ", cc->cipher, cc->chainmode); |
935 | 931 | ||
936 | if (cc->key_size > 0) { | 932 | if (cc->key_size > 0) { |
937 | if ((maxlen - sz) < ((cc->key_size << 1) + 1)) | 933 | if ((maxlen - sz) < ((cc->key_size << 1) + 1)) |
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index d13bb15a8a02..4510ad8f971c 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c | |||
@@ -606,9 +606,14 @@ static struct hash_cell *__find_device_hash_cell(struct dm_ioctl *param) | |||
606 | return __get_name_cell(param->name); | 606 | return __get_name_cell(param->name); |
607 | 607 | ||
608 | md = dm_get_md(huge_decode_dev(param->dev)); | 608 | md = dm_get_md(huge_decode_dev(param->dev)); |
609 | if (md) | 609 | if (!md) |
610 | mdptr = dm_get_mdptr(md); | 610 | goto out; |
611 | 611 | ||
612 | mdptr = dm_get_mdptr(md); | ||
613 | if (!mdptr) | ||
614 | dm_put(md); | ||
615 | |||
616 | out: | ||
612 | return mdptr; | 617 | return mdptr; |
613 | } | 618 | } |
614 | 619 | ||
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 659224cb7c53..48a653b3f518 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c | |||
@@ -24,6 +24,7 @@ | |||
24 | 24 | ||
25 | static struct workqueue_struct *_kmirrord_wq; | 25 | static struct workqueue_struct *_kmirrord_wq; |
26 | static struct work_struct _kmirrord_work; | 26 | static struct work_struct _kmirrord_work; |
27 | static DECLARE_WAIT_QUEUE_HEAD(_kmirrord_recovery_stopped); | ||
27 | 28 | ||
28 | static inline void wake(void) | 29 | static inline void wake(void) |
29 | { | 30 | { |
@@ -83,6 +84,7 @@ struct region_hash { | |||
83 | struct list_head *buckets; | 84 | struct list_head *buckets; |
84 | 85 | ||
85 | spinlock_t region_lock; | 86 | spinlock_t region_lock; |
87 | atomic_t recovery_in_flight; | ||
86 | struct semaphore recovery_count; | 88 | struct semaphore recovery_count; |
87 | struct list_head clean_regions; | 89 | struct list_head clean_regions; |
88 | struct list_head quiesced_regions; | 90 | struct list_head quiesced_regions; |
@@ -191,6 +193,7 @@ static int rh_init(struct region_hash *rh, struct mirror_set *ms, | |||
191 | 193 | ||
192 | spin_lock_init(&rh->region_lock); | 194 | spin_lock_init(&rh->region_lock); |
193 | sema_init(&rh->recovery_count, 0); | 195 | sema_init(&rh->recovery_count, 0); |
196 | atomic_set(&rh->recovery_in_flight, 0); | ||
194 | INIT_LIST_HEAD(&rh->clean_regions); | 197 | INIT_LIST_HEAD(&rh->clean_regions); |
195 | INIT_LIST_HEAD(&rh->quiesced_regions); | 198 | INIT_LIST_HEAD(&rh->quiesced_regions); |
196 | INIT_LIST_HEAD(&rh->recovered_regions); | 199 | INIT_LIST_HEAD(&rh->recovered_regions); |
@@ -382,6 +385,8 @@ static void rh_update_states(struct region_hash *rh) | |||
382 | rh->log->type->clear_region(rh->log, reg->key); | 385 | rh->log->type->clear_region(rh->log, reg->key); |
383 | rh->log->type->complete_resync_work(rh->log, reg->key, 1); | 386 | rh->log->type->complete_resync_work(rh->log, reg->key, 1); |
384 | dispatch_bios(rh->ms, ®->delayed_bios); | 387 | dispatch_bios(rh->ms, ®->delayed_bios); |
388 | if (atomic_dec_and_test(&rh->recovery_in_flight)) | ||
389 | wake_up_all(&_kmirrord_recovery_stopped); | ||
385 | up(&rh->recovery_count); | 390 | up(&rh->recovery_count); |
386 | mempool_free(reg, rh->region_pool); | 391 | mempool_free(reg, rh->region_pool); |
387 | } | 392 | } |
@@ -502,11 +507,21 @@ static int __rh_recovery_prepare(struct region_hash *rh) | |||
502 | 507 | ||
503 | static void rh_recovery_prepare(struct region_hash *rh) | 508 | static void rh_recovery_prepare(struct region_hash *rh) |
504 | { | 509 | { |
505 | while (!down_trylock(&rh->recovery_count)) | 510 | /* Extra reference to avoid race with rh_stop_recovery */ |
511 | atomic_inc(&rh->recovery_in_flight); | ||
512 | |||
513 | while (!down_trylock(&rh->recovery_count)) { | ||
514 | atomic_inc(&rh->recovery_in_flight); | ||
506 | if (__rh_recovery_prepare(rh) <= 0) { | 515 | if (__rh_recovery_prepare(rh) <= 0) { |
516 | atomic_dec(&rh->recovery_in_flight); | ||
507 | up(&rh->recovery_count); | 517 | up(&rh->recovery_count); |
508 | break; | 518 | break; |
509 | } | 519 | } |
520 | } | ||
521 | |||
522 | /* Drop the extra reference */ | ||
523 | if (atomic_dec_and_test(&rh->recovery_in_flight)) | ||
524 | wake_up_all(&_kmirrord_recovery_stopped); | ||
510 | } | 525 | } |
511 | 526 | ||
512 | /* | 527 | /* |
@@ -1177,6 +1192,11 @@ static void mirror_postsuspend(struct dm_target *ti) | |||
1177 | struct dirty_log *log = ms->rh.log; | 1192 | struct dirty_log *log = ms->rh.log; |
1178 | 1193 | ||
1179 | rh_stop_recovery(&ms->rh); | 1194 | rh_stop_recovery(&ms->rh); |
1195 | |||
1196 | /* Wait for all I/O we generated to complete */ | ||
1197 | wait_event(_kmirrord_recovery_stopped, | ||
1198 | !atomic_read(&ms->rh.recovery_in_flight)); | ||
1199 | |||
1180 | if (log->type->suspend && log->type->suspend(log)) | 1200 | if (log->type->suspend && log->type->suspend(log)) |
1181 | /* FIXME: need better error handling */ | 1201 | /* FIXME: need better error handling */ |
1182 | DMWARN("log suspend failed"); | 1202 | DMWARN("log suspend failed"); |
diff --git a/drivers/md/dm-round-robin.c b/drivers/md/dm-round-robin.c index c5a16c550122..6f9fcd4db9b5 100644 --- a/drivers/md/dm-round-robin.c +++ b/drivers/md/dm-round-robin.c | |||
@@ -136,7 +136,7 @@ static int rr_add_path(struct path_selector *ps, struct path *path, | |||
136 | 136 | ||
137 | path->pscontext = pi; | 137 | path->pscontext = pi; |
138 | 138 | ||
139 | list_add(&pi->list, &s->valid_paths); | 139 | list_add_tail(&pi->list, &s->valid_paths); |
140 | 140 | ||
141 | return 0; | 141 | return 0; |
142 | } | 142 | } |
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index b5764a86c8b5..fc4f743f3b53 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
@@ -1285,7 +1285,7 @@ int dm_suspend(struct mapped_device *md, int do_lockfs) | |||
1285 | down(&md->suspend_lock); | 1285 | down(&md->suspend_lock); |
1286 | 1286 | ||
1287 | if (dm_suspended(md)) | 1287 | if (dm_suspended(md)) |
1288 | goto out; | 1288 | goto out_unlock; |
1289 | 1289 | ||
1290 | map = dm_get_table(md); | 1290 | map = dm_get_table(md); |
1291 | 1291 | ||
@@ -1361,6 +1361,8 @@ out: | |||
1361 | } | 1361 | } |
1362 | 1362 | ||
1363 | dm_table_put(map); | 1363 | dm_table_put(map); |
1364 | |||
1365 | out_unlock: | ||
1364 | up(&md->suspend_lock); | 1366 | up(&md->suspend_lock); |
1365 | return r; | 1367 | return r; |
1366 | } | 1368 | } |
diff --git a/drivers/md/md.c b/drivers/md/md.c index 57fa64f93e5f..8cbf9c9df1c3 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -974,12 +974,13 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev) | |||
974 | * version 1 superblock | 974 | * version 1 superblock |
975 | */ | 975 | */ |
976 | 976 | ||
977 | static unsigned int calc_sb_1_csum(struct mdp_superblock_1 * sb) | 977 | static __le32 calc_sb_1_csum(struct mdp_superblock_1 * sb) |
978 | { | 978 | { |
979 | unsigned int disk_csum, csum; | 979 | __le32 disk_csum; |
980 | u32 csum; | ||
980 | unsigned long long newcsum; | 981 | unsigned long long newcsum; |
981 | int size = 256 + le32_to_cpu(sb->max_dev)*2; | 982 | int size = 256 + le32_to_cpu(sb->max_dev)*2; |
982 | unsigned int *isuper = (unsigned int*)sb; | 983 | __le32 *isuper = (__le32*)sb; |
983 | int i; | 984 | int i; |
984 | 985 | ||
985 | disk_csum = sb->sb_csum; | 986 | disk_csum = sb->sb_csum; |
@@ -989,7 +990,7 @@ static unsigned int calc_sb_1_csum(struct mdp_superblock_1 * sb) | |||
989 | newcsum += le32_to_cpu(*isuper++); | 990 | newcsum += le32_to_cpu(*isuper++); |
990 | 991 | ||
991 | if (size == 2) | 992 | if (size == 2) |
992 | newcsum += le16_to_cpu(*(unsigned short*) isuper); | 993 | newcsum += le16_to_cpu(*(__le16*) isuper); |
993 | 994 | ||
994 | csum = (newcsum & 0xffffffff) + (newcsum >> 32); | 995 | csum = (newcsum & 0xffffffff) + (newcsum >> 32); |
995 | sb->sb_csum = disk_csum; | 996 | sb->sb_csum = disk_csum; |
@@ -1106,7 +1107,7 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version) | |||
1106 | if (le32_to_cpu(sb->chunksize)) | 1107 | if (le32_to_cpu(sb->chunksize)) |
1107 | rdev->size &= ~((sector_t)le32_to_cpu(sb->chunksize)/2 - 1); | 1108 | rdev->size &= ~((sector_t)le32_to_cpu(sb->chunksize)/2 - 1); |
1108 | 1109 | ||
1109 | if (le32_to_cpu(sb->size) > rdev->size*2) | 1110 | if (le64_to_cpu(sb->size) > rdev->size*2) |
1110 | return -EINVAL; | 1111 | return -EINVAL; |
1111 | return ret; | 1112 | return ret; |
1112 | } | 1113 | } |
@@ -1228,7 +1229,7 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev) | |||
1228 | else | 1229 | else |
1229 | sb->resync_offset = cpu_to_le64(0); | 1230 | sb->resync_offset = cpu_to_le64(0); |
1230 | 1231 | ||
1231 | sb->cnt_corrected_read = atomic_read(&rdev->corrected_errors); | 1232 | sb->cnt_corrected_read = cpu_to_le32(atomic_read(&rdev->corrected_errors)); |
1232 | 1233 | ||
1233 | sb->raid_disks = cpu_to_le32(mddev->raid_disks); | 1234 | sb->raid_disks = cpu_to_le32(mddev->raid_disks); |
1234 | sb->size = cpu_to_le64(mddev->size<<1); | 1235 | sb->size = cpu_to_le64(mddev->size<<1); |
@@ -2002,6 +2003,7 @@ static mdk_rdev_t *md_import_device(dev_t newdev, int super_format, int super_mi | |||
2002 | kobject_init(&rdev->kobj); | 2003 | kobject_init(&rdev->kobj); |
2003 | 2004 | ||
2004 | rdev->desc_nr = -1; | 2005 | rdev->desc_nr = -1; |
2006 | rdev->saved_raid_disk = -1; | ||
2005 | rdev->flags = 0; | 2007 | rdev->flags = 0; |
2006 | rdev->data_offset = 0; | 2008 | rdev->data_offset = 0; |
2007 | rdev->sb_events = 0; | 2009 | rdev->sb_events = 0; |
@@ -3198,6 +3200,7 @@ static int do_md_run(mddev_t * mddev) | |||
3198 | 3200 | ||
3199 | mddev->changed = 1; | 3201 | mddev->changed = 1; |
3200 | md_new_event(mddev); | 3202 | md_new_event(mddev); |
3203 | kobject_uevent(&mddev->gendisk->kobj, KOBJ_CHANGE); | ||
3201 | return 0; | 3204 | return 0; |
3202 | } | 3205 | } |
3203 | 3206 | ||
@@ -4043,11 +4046,8 @@ static int update_size(mddev_t *mddev, unsigned long size) | |||
4043 | return -EBUSY; | 4046 | return -EBUSY; |
4044 | ITERATE_RDEV(mddev,rdev,tmp) { | 4047 | ITERATE_RDEV(mddev,rdev,tmp) { |
4045 | sector_t avail; | 4048 | sector_t avail; |
4046 | if (rdev->sb_offset > rdev->data_offset) | 4049 | avail = rdev->size * 2; |
4047 | avail = (rdev->sb_offset*2) - rdev->data_offset; | 4050 | |
4048 | else | ||
4049 | avail = get_capacity(rdev->bdev->bd_disk) | ||
4050 | - rdev->data_offset; | ||
4051 | if (fit && (size == 0 || size > avail/2)) | 4051 | if (fit && (size == 0 || size > avail/2)) |
4052 | size = avail/2; | 4052 | size = avail/2; |
4053 | if (avail < ((sector_t)size << 1)) | 4053 | if (avail < ((sector_t)size << 1)) |
@@ -4486,6 +4486,7 @@ static int md_thread(void * arg) | |||
4486 | * many dirty RAID5 blocks. | 4486 | * many dirty RAID5 blocks. |
4487 | */ | 4487 | */ |
4488 | 4488 | ||
4489 | current->flags |= PF_NOFREEZE; | ||
4489 | allow_signal(SIGKILL); | 4490 | allow_signal(SIGKILL); |
4490 | while (!kthread_should_stop()) { | 4491 | while (!kthread_should_stop()) { |
4491 | 4492 | ||
@@ -4502,7 +4503,6 @@ static int md_thread(void * arg) | |||
4502 | test_bit(THREAD_WAKEUP, &thread->flags) | 4503 | test_bit(THREAD_WAKEUP, &thread->flags) |
4503 | || kthread_should_stop(), | 4504 | || kthread_should_stop(), |
4504 | thread->timeout); | 4505 | thread->timeout); |
4505 | try_to_freeze(); | ||
4506 | 4506 | ||
4507 | clear_bit(THREAD_WAKEUP, &thread->flags); | 4507 | clear_bit(THREAD_WAKEUP, &thread->flags); |
4508 | 4508 | ||
@@ -4912,6 +4912,7 @@ static unsigned int mdstat_poll(struct file *filp, poll_table *wait) | |||
4912 | } | 4912 | } |
4913 | 4913 | ||
4914 | static struct file_operations md_seq_fops = { | 4914 | static struct file_operations md_seq_fops = { |
4915 | .owner = THIS_MODULE, | ||
4915 | .open = md_seq_open, | 4916 | .open = md_seq_open, |
4916 | .read = seq_read, | 4917 | .read = seq_read, |
4917 | .llseek = seq_lseek, | 4918 | .llseek = seq_lseek, |
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c index 171ff41b52b0..14da37fee37b 100644 --- a/drivers/md/multipath.c +++ b/drivers/md/multipath.c | |||
@@ -277,6 +277,7 @@ static void multipath_error (mddev_t *mddev, mdk_rdev_t *rdev) | |||
277 | set_bit(Faulty, &rdev->flags); | 277 | set_bit(Faulty, &rdev->flags); |
278 | set_bit(MD_CHANGE_DEVS, &mddev->flags); | 278 | set_bit(MD_CHANGE_DEVS, &mddev->flags); |
279 | conf->working_disks--; | 279 | conf->working_disks--; |
280 | mddev->degraded++; | ||
280 | printk(KERN_ALERT "multipath: IO failure on %s," | 281 | printk(KERN_ALERT "multipath: IO failure on %s," |
281 | " disabling IO path. \n Operation continuing" | 282 | " disabling IO path. \n Operation continuing" |
282 | " on %d IO paths.\n", | 283 | " on %d IO paths.\n", |
@@ -336,6 +337,7 @@ static int multipath_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) | |||
336 | blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9); | 337 | blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9); |
337 | 338 | ||
338 | conf->working_disks++; | 339 | conf->working_disks++; |
340 | mddev->degraded--; | ||
339 | rdev->raid_disk = path; | 341 | rdev->raid_disk = path; |
340 | set_bit(In_sync, &rdev->flags); | 342 | set_bit(In_sync, &rdev->flags); |
341 | rcu_assign_pointer(p->rdev, rdev); | 343 | rcu_assign_pointer(p->rdev, rdev); |
@@ -501,7 +503,7 @@ static int multipath_run (mddev_t *mddev) | |||
501 | mdname(mddev)); | 503 | mdname(mddev)); |
502 | goto out_free_conf; | 504 | goto out_free_conf; |
503 | } | 505 | } |
504 | mddev->degraded = conf->raid_disks = conf->working_disks; | 506 | mddev->degraded = conf->raid_disks - conf->working_disks; |
505 | 507 | ||
506 | conf->pool = mempool_create_kzalloc_pool(NR_RESERVED_BUFS, | 508 | conf->pool = mempool_create_kzalloc_pool(NR_RESERVED_BUFS, |
507 | sizeof(struct multipath_bh)); | 509 | sizeof(struct multipath_bh)); |
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index dc9d2def0270..656fae912fe3 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
@@ -1474,8 +1474,8 @@ static void fix_read_error(conf_t *conf, int read_disk, | |||
1474 | "raid1:%s: read error corrected " | 1474 | "raid1:%s: read error corrected " |
1475 | "(%d sectors at %llu on %s)\n", | 1475 | "(%d sectors at %llu on %s)\n", |
1476 | mdname(mddev), s, | 1476 | mdname(mddev), s, |
1477 | (unsigned long long)sect + | 1477 | (unsigned long long)(sect + |
1478 | rdev->data_offset, | 1478 | rdev->data_offset), |
1479 | bdevname(rdev->bdev, b)); | 1479 | bdevname(rdev->bdev, b)); |
1480 | } | 1480 | } |
1481 | } | 1481 | } |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 1250f0eab4af..7492d6033ac6 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -1470,8 +1470,8 @@ static void fix_read_error(conf_t *conf, mddev_t *mddev, r10bio_t *r10_bio) | |||
1470 | "raid10:%s: read error corrected" | 1470 | "raid10:%s: read error corrected" |
1471 | " (%d sectors at %llu on %s)\n", | 1471 | " (%d sectors at %llu on %s)\n", |
1472 | mdname(mddev), s, | 1472 | mdname(mddev), s, |
1473 | (unsigned long long)sect+ | 1473 | (unsigned long long)(sect+ |
1474 | rdev->data_offset, | 1474 | rdev->data_offset), |
1475 | bdevname(rdev->bdev, b)); | 1475 | bdevname(rdev->bdev, b)); |
1476 | 1476 | ||
1477 | rdev_dec_pending(rdev, mddev); | 1477 | rdev_dec_pending(rdev, mddev); |
@@ -2079,7 +2079,7 @@ static int run(mddev_t *mddev) | |||
2079 | disk = conf->mirrors + i; | 2079 | disk = conf->mirrors + i; |
2080 | 2080 | ||
2081 | if (!disk->rdev || | 2081 | if (!disk->rdev || |
2082 | !test_bit(In_sync, &rdev->flags)) { | 2082 | !test_bit(In_sync, &disk->rdev->flags)) { |
2083 | disk->head_position = 0; | 2083 | disk->head_position = 0; |
2084 | mddev->degraded++; | 2084 | mddev->degraded++; |
2085 | } | 2085 | } |
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index e14f45780720..69c3e201fa3b 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -3659,7 +3659,7 @@ static void end_reshape(raid5_conf_t *conf) | |||
3659 | bdev = bdget_disk(conf->mddev->gendisk, 0); | 3659 | bdev = bdget_disk(conf->mddev->gendisk, 0); |
3660 | if (bdev) { | 3660 | if (bdev) { |
3661 | mutex_lock(&bdev->bd_inode->i_mutex); | 3661 | mutex_lock(&bdev->bd_inode->i_mutex); |
3662 | i_size_write(bdev->bd_inode, conf->mddev->array_size << 10); | 3662 | i_size_write(bdev->bd_inode, (loff_t)conf->mddev->array_size << 10); |
3663 | mutex_unlock(&bdev->bd_inode->i_mutex); | 3663 | mutex_unlock(&bdev->bd_inode->i_mutex); |
3664 | bdput(bdev); | 3664 | bdput(bdev); |
3665 | } | 3665 | } |
diff --git a/drivers/media/common/saa7146_i2c.c b/drivers/media/common/saa7146_i2c.c index d9953f7a8b6b..5297a365c928 100644 --- a/drivers/media/common/saa7146_i2c.c +++ b/drivers/media/common/saa7146_i2c.c | |||
@@ -217,11 +217,9 @@ static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword, int short_d | |||
217 | } | 217 | } |
218 | /* wait until we get a transfer done or error */ | 218 | /* wait until we get a transfer done or error */ |
219 | timeout = jiffies + HZ/100 + 1; /* 10ms */ | 219 | timeout = jiffies + HZ/100 + 1; /* 10ms */ |
220 | /* first read usually delivers bogus results... */ | ||
221 | saa7146_i2c_status(dev); | ||
220 | while(1) { | 222 | while(1) { |
221 | /** | ||
222 | * first read usually delivers bogus results... | ||
223 | */ | ||
224 | saa7146_i2c_status(dev); | ||
225 | status = saa7146_i2c_status(dev); | 223 | status = saa7146_i2c_status(dev); |
226 | if ((status & 0x3) != 1) | 224 | if ((status & 0x3) != 1) |
227 | break; | 225 | break; |
@@ -232,10 +230,10 @@ static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword, int short_d | |||
232 | DEB_I2C(("saa7146_i2c_writeout: timed out waiting for end of xfer\n")); | 230 | DEB_I2C(("saa7146_i2c_writeout: timed out waiting for end of xfer\n")); |
233 | return -EIO; | 231 | return -EIO; |
234 | } | 232 | } |
235 | if ((++trial < 20) && short_delay) | 233 | if (++trial < 50 && short_delay) |
236 | udelay(10); | 234 | udelay(10); |
237 | else | 235 | else |
238 | msleep(1); | 236 | msleep(1); |
239 | } | 237 | } |
240 | } | 238 | } |
241 | 239 | ||
diff --git a/drivers/media/dvb/b2c2/flexcop-usb.c b/drivers/media/dvb/b2c2/flexcop-usb.c index 2853ea1bdaf1..87fb75f0d1cf 100644 --- a/drivers/media/dvb/b2c2/flexcop-usb.c +++ b/drivers/media/dvb/b2c2/flexcop-usb.c | |||
@@ -246,7 +246,7 @@ static int flexcop_usb_i2c_req(struct flexcop_usb *fc_usb, | |||
246 | wIndex = (chipaddr << 8 ) | addr; | 246 | wIndex = (chipaddr << 8 ) | addr; |
247 | 247 | ||
248 | deb_i2c("i2c %2d: %02x %02x %02x %02x %02x %02x\n",func,request_type,req, | 248 | deb_i2c("i2c %2d: %02x %02x %02x %02x %02x %02x\n",func,request_type,req, |
249 | ((wValue && 0xff) << 8),wValue >> 8,((wIndex && 0xff) << 8),wIndex >> 8); | 249 | wValue & 0xff, wValue >> 8, wIndex & 0xff, wIndex >> 8); |
250 | 250 | ||
251 | len = usb_control_msg(fc_usb->udev,pipe, | 251 | len = usb_control_msg(fc_usb->udev,pipe, |
252 | req, | 252 | req, |
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c index fb6c4cc8477d..14e69a736eda 100644 --- a/drivers/media/dvb/bt8xx/dvb-bt8xx.c +++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.c | |||
@@ -665,6 +665,10 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) | |||
665 | case BTTV_BOARD_TWINHAN_DST: | 665 | case BTTV_BOARD_TWINHAN_DST: |
666 | /* DST is not a frontend driver !!! */ | 666 | /* DST is not a frontend driver !!! */ |
667 | state = (struct dst_state *) kmalloc(sizeof (struct dst_state), GFP_KERNEL); | 667 | state = (struct dst_state *) kmalloc(sizeof (struct dst_state), GFP_KERNEL); |
668 | if (!state) { | ||
669 | printk("dvb_bt8xx: No memory\n"); | ||
670 | break; | ||
671 | } | ||
668 | /* Setup the Card */ | 672 | /* Setup the Card */ |
669 | state->config = &dst_config; | 673 | state->config = &dst_config; |
670 | state->i2c = card->i2c_adapter; | 674 | state->i2c = card->i2c_adapter; |
diff --git a/drivers/media/dvb/dvb-core/Kconfig b/drivers/media/dvb/dvb-core/Kconfig index e46eae3b9be2..1990eda10c46 100644 --- a/drivers/media/dvb/dvb-core/Kconfig +++ b/drivers/media/dvb/dvb-core/Kconfig | |||
@@ -19,6 +19,6 @@ config DVB_CORE_ATTACH | |||
19 | allow the card drivers to only load the frontend modules | 19 | allow the card drivers to only load the frontend modules |
20 | they require. This saves several KBytes of memory. | 20 | they require. This saves several KBytes of memory. |
21 | 21 | ||
22 | Note: You will need moudule-init-tools v3.2 or later for this feature. | 22 | Note: You will need module-init-tools v3.2 or later for this feature. |
23 | 23 | ||
24 | If unsure say Y. | 24 | If unsure say Y. |
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index 2cc5caa26a0a..a263b3f3c21d 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig | |||
@@ -26,7 +26,7 @@ config DVB_USB_A800 | |||
26 | tristate "AVerMedia AverTV DVB-T USB 2.0 (A800)" | 26 | tristate "AVerMedia AverTV DVB-T USB 2.0 (A800)" |
27 | depends on DVB_USB | 27 | depends on DVB_USB |
28 | select DVB_DIB3000MC | 28 | select DVB_DIB3000MC |
29 | select DVB_TUNER_MT2060 | 29 | select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE |
30 | help | 30 | help |
31 | Say Y here to support the AVerMedia AverTV DVB-T USB 2.0 (A800) receiver. | 31 | Say Y here to support the AVerMedia AverTV DVB-T USB 2.0 (A800) receiver. |
32 | 32 | ||
@@ -34,7 +34,7 @@ config DVB_USB_DIBUSB_MB | |||
34 | tristate "DiBcom USB DVB-T devices (based on the DiB3000M-B) (see help for device list)" | 34 | tristate "DiBcom USB DVB-T devices (based on the DiB3000M-B) (see help for device list)" |
35 | depends on DVB_USB | 35 | depends on DVB_USB |
36 | select DVB_DIB3000MB | 36 | select DVB_DIB3000MB |
37 | select DVB_TUNER_MT2060 | 37 | select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE |
38 | help | 38 | help |
39 | Support for USB 1.1 and 2.0 DVB-T receivers based on reference designs made by | 39 | Support for USB 1.1 and 2.0 DVB-T receivers based on reference designs made by |
40 | DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-B demodulator. | 40 | DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-B demodulator. |
@@ -55,7 +55,7 @@ config DVB_USB_DIBUSB_MC | |||
55 | tristate "DiBcom USB DVB-T devices (based on the DiB3000M-C/P) (see help for device list)" | 55 | tristate "DiBcom USB DVB-T devices (based on the DiB3000M-C/P) (see help for device list)" |
56 | depends on DVB_USB | 56 | depends on DVB_USB |
57 | select DVB_DIB3000MC | 57 | select DVB_DIB3000MC |
58 | select DVB_TUNER_MT2060 | 58 | select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE |
59 | help | 59 | help |
60 | Support for USB2.0 DVB-T receivers based on reference designs made by | 60 | Support for USB2.0 DVB-T receivers based on reference designs made by |
61 | DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-C/P demodulator. | 61 | DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-C/P demodulator. |
@@ -70,7 +70,7 @@ config DVB_USB_DIB0700 | |||
70 | tristate "DiBcom DiB0700 USB DVB devices (see help for supported devices)" | 70 | tristate "DiBcom DiB0700 USB DVB devices (see help for supported devices)" |
71 | depends on DVB_USB | 71 | depends on DVB_USB |
72 | select DVB_DIB3000MC | 72 | select DVB_DIB3000MC |
73 | select DVB_TUNER_MT2060 | 73 | select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE |
74 | help | 74 | help |
75 | Support for USB2.0/1.1 DVB receivers based on the DiB0700 USB bridge. The | 75 | Support for USB2.0/1.1 DVB receivers based on the DiB0700 USB bridge. The |
76 | USB bridge is also present in devices having the DiB7700 DVB-T-USB | 76 | USB bridge is also present in devices having the DiB7700 DVB-T-USB |
@@ -87,7 +87,7 @@ config DVB_USB_UMT_010 | |||
87 | tristate "HanfTek UMT-010 DVB-T USB2.0 support" | 87 | tristate "HanfTek UMT-010 DVB-T USB2.0 support" |
88 | depends on DVB_USB | 88 | depends on DVB_USB |
89 | select DVB_DIB3000MC | 89 | select DVB_DIB3000MC |
90 | select DVB_TUNER_MT2060 | 90 | select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE |
91 | help | 91 | help |
92 | Say Y here to support the HanfTek UMT-010 USB2.0 stick-sized DVB-T receiver. | 92 | Say Y here to support the HanfTek UMT-010 USB2.0 stick-sized DVB-T receiver. |
93 | 93 | ||
@@ -153,7 +153,7 @@ config DVB_USB_NOVA_T_USB2 | |||
153 | tristate "Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 support" | 153 | tristate "Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 support" |
154 | depends on DVB_USB | 154 | depends on DVB_USB |
155 | select DVB_DIB3000MC | 155 | select DVB_DIB3000MC |
156 | select DVB_TUNER_MT2060 | 156 | select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE |
157 | help | 157 | help |
158 | Say Y here to support the Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 receiver. | 158 | Say Y here to support the Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 receiver. |
159 | 159 | ||
diff --git a/drivers/media/dvb/dvb-usb/dibusb-common.c b/drivers/media/dvb/dvb-usb/dibusb-common.c index fd3a9902f98d..5143e426d283 100644 --- a/drivers/media/dvb/dvb-usb/dibusb-common.c +++ b/drivers/media/dvb/dvb-usb/dibusb-common.c | |||
@@ -169,7 +169,7 @@ EXPORT_SYMBOL(dibusb_read_eeprom_byte); | |||
169 | // Config Adjacent channels Perf -cal22 | 169 | // Config Adjacent channels Perf -cal22 |
170 | static struct dibx000_agc_config dib3000p_mt2060_agc_config = { | 170 | static struct dibx000_agc_config dib3000p_mt2060_agc_config = { |
171 | .band_caps = BAND_VHF | BAND_UHF, | 171 | .band_caps = BAND_VHF | BAND_UHF, |
172 | .setup = (0 << 15) | (0 << 14) | (1 << 13) | (1 << 12) | (29 << 0), | 172 | .setup = (1 << 8) | (5 << 5) | (1 << 4) | (1 << 3) | (0 << 2) | (2 << 0), |
173 | 173 | ||
174 | .agc1_max = 48497, | 174 | .agc1_max = 48497, |
175 | .agc1_min = 23593, | 175 | .agc1_min = 23593, |
@@ -196,10 +196,14 @@ static struct dib3000mc_config stk3000p_dib3000p_config = { | |||
196 | .ln_adc_level = 0x1cc7, | 196 | .ln_adc_level = 0x1cc7, |
197 | 197 | ||
198 | .output_mpeg2_in_188_bytes = 1, | 198 | .output_mpeg2_in_188_bytes = 1, |
199 | |||
200 | .agc_command1 = 1, | ||
201 | .agc_command2 = 1, | ||
199 | }; | 202 | }; |
200 | 203 | ||
201 | static struct dibx000_agc_config dib3000p_panasonic_agc_config = { | 204 | static struct dibx000_agc_config dib3000p_panasonic_agc_config = { |
202 | .setup = (0 << 15) | (0 << 14) | (1 << 13) | (1 << 12) | (29 << 0), | 205 | .band_caps = BAND_VHF | BAND_UHF, |
206 | .setup = (1 << 8) | (5 << 5) | (1 << 4) | (1 << 3) | (0 << 2) | (2 << 0), | ||
203 | 207 | ||
204 | .agc1_max = 56361, | 208 | .agc1_max = 56361, |
205 | .agc1_min = 22282, | 209 | .agc1_min = 22282, |
@@ -226,6 +230,9 @@ static struct dib3000mc_config mod3000p_dib3000p_config = { | |||
226 | .ln_adc_level = 0x1cc7, | 230 | .ln_adc_level = 0x1cc7, |
227 | 231 | ||
228 | .output_mpeg2_in_188_bytes = 1, | 232 | .output_mpeg2_in_188_bytes = 1, |
233 | |||
234 | .agc_command1 = 1, | ||
235 | .agc_command2 = 1, | ||
229 | }; | 236 | }; |
230 | 237 | ||
231 | int dibusb_dib3000mc_frontend_attach(struct dvb_usb_adapter *adap) | 238 | int dibusb_dib3000mc_frontend_attach(struct dvb_usb_adapter *adap) |
diff --git a/drivers/media/dvb/dvb-usb/dibusb.h b/drivers/media/dvb/dvb-usb/dibusb.h index 5153fb943da1..b60781032742 100644 --- a/drivers/media/dvb/dvb-usb/dibusb.h +++ b/drivers/media/dvb/dvb-usb/dibusb.h | |||
@@ -99,7 +99,9 @@ | |||
99 | struct dibusb_state { | 99 | struct dibusb_state { |
100 | struct dib_fe_xfer_ops ops; | 100 | struct dib_fe_xfer_ops ops; |
101 | int mt2060_present; | 101 | int mt2060_present; |
102 | }; | ||
102 | 103 | ||
104 | struct dibusb_device_state { | ||
103 | /* for RC5 remote control */ | 105 | /* for RC5 remote control */ |
104 | int old_toggle; | 106 | int old_toggle; |
105 | int last_repeat_count; | 107 | int last_repeat_count; |
diff --git a/drivers/media/dvb/dvb-usb/nova-t-usb2.c b/drivers/media/dvb/dvb-usb/nova-t-usb2.c index a9219bf69b89..a58874c790b2 100644 --- a/drivers/media/dvb/dvb-usb/nova-t-usb2.c +++ b/drivers/media/dvb/dvb-usb/nova-t-usb2.c | |||
@@ -75,7 +75,7 @@ static int nova_t_rc_query(struct dvb_usb_device *d, u32 *event, int *state) | |||
75 | u8 key[5],cmd[2] = { DIBUSB_REQ_POLL_REMOTE, 0x35 }, data,toggle,custom; | 75 | u8 key[5],cmd[2] = { DIBUSB_REQ_POLL_REMOTE, 0x35 }, data,toggle,custom; |
76 | u16 raw; | 76 | u16 raw; |
77 | int i; | 77 | int i; |
78 | struct dibusb_state *st = d->priv; | 78 | struct dibusb_device_state *st = d->priv; |
79 | 79 | ||
80 | dvb_usb_generic_rw(d,cmd,2,key,5,0); | 80 | dvb_usb_generic_rw(d,cmd,2,key,5,0); |
81 | 81 | ||
@@ -184,6 +184,7 @@ static struct dvb_usb_device_properties nova_t_properties = { | |||
184 | .size_of_priv = sizeof(struct dibusb_state), | 184 | .size_of_priv = sizeof(struct dibusb_state), |
185 | } | 185 | } |
186 | }, | 186 | }, |
187 | .size_of_priv = sizeof(struct dibusb_device_state), | ||
187 | 188 | ||
188 | .power_ctrl = dibusb2_0_power_ctrl, | 189 | .power_ctrl = dibusb2_0_power_ctrl, |
189 | .read_mac_address = nova_t_read_mac_address, | 190 | .read_mac_address = nova_t_read_mac_address, |
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index 080fa257a0bc..aebb8d6f26f8 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig | |||
@@ -276,6 +276,8 @@ config DVB_TDA826X | |||
276 | 276 | ||
277 | config DVB_TUNER_MT2060 | 277 | config DVB_TUNER_MT2060 |
278 | tristate "Microtune MT2060 silicon IF tuner" | 278 | tristate "Microtune MT2060 silicon IF tuner" |
279 | depends on I2C | ||
280 | default m if DVB_FE_CUSTOMISE | ||
279 | help | 281 | help |
280 | A driver for the silicon IF tuner MT2060 from Microtune. | 282 | A driver for the silicon IF tuner MT2060 from Microtune. |
281 | 283 | ||
diff --git a/drivers/media/dvb/frontends/bcm3510.h b/drivers/media/dvb/frontends/bcm3510.h index 6dfa839a7022..7e4f95e1734b 100644 --- a/drivers/media/dvb/frontends/bcm3510.h +++ b/drivers/media/dvb/frontends/bcm3510.h | |||
@@ -34,7 +34,7 @@ struct bcm3510_config | |||
34 | int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); | 34 | int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); |
35 | }; | 35 | }; |
36 | 36 | ||
37 | #if defined(CONFIG_DVB_BCM3510) || defined(CONFIG_DVB_BCM3510_MODULE) | 37 | #if defined(CONFIG_DVB_BCM3510) || (defined(CONFIG_DVB_BCM3510_MODULE) && defined(MODULE)) |
38 | extern struct dvb_frontend* bcm3510_attach(const struct bcm3510_config* config, | 38 | extern struct dvb_frontend* bcm3510_attach(const struct bcm3510_config* config, |
39 | struct i2c_adapter* i2c); | 39 | struct i2c_adapter* i2c); |
40 | #else | 40 | #else |
diff --git a/drivers/media/dvb/frontends/cx22700.h b/drivers/media/dvb/frontends/cx22700.h index 10286cc29fb4..7ac33690cdcc 100644 --- a/drivers/media/dvb/frontends/cx22700.h +++ b/drivers/media/dvb/frontends/cx22700.h | |||
@@ -31,7 +31,7 @@ struct cx22700_config | |||
31 | u8 demod_address; | 31 | u8 demod_address; |
32 | }; | 32 | }; |
33 | 33 | ||
34 | #if defined(CONFIG_DVB_CX22700) || defined(CONFIG_DVB_CX22700_MODULE) | 34 | #if defined(CONFIG_DVB_CX22700) || (defined(CONFIG_DVB_CX22700_MODULE) && defined(MODULE)) |
35 | extern struct dvb_frontend* cx22700_attach(const struct cx22700_config* config, | 35 | extern struct dvb_frontend* cx22700_attach(const struct cx22700_config* config, |
36 | struct i2c_adapter* i2c); | 36 | struct i2c_adapter* i2c); |
37 | #else | 37 | #else |
diff --git a/drivers/media/dvb/frontends/cx22702.h b/drivers/media/dvb/frontends/cx22702.h index bc217ddf02c0..9cd64da6ee40 100644 --- a/drivers/media/dvb/frontends/cx22702.h +++ b/drivers/media/dvb/frontends/cx22702.h | |||
@@ -41,7 +41,7 @@ struct cx22702_config | |||
41 | u8 output_mode; | 41 | u8 output_mode; |
42 | }; | 42 | }; |
43 | 43 | ||
44 | #if defined(CONFIG_DVB_CX22702) || defined(CONFIG_DVB_CX22702_MODULE) | 44 | #if defined(CONFIG_DVB_CX22702) || (defined(CONFIG_DVB_CX22702_MODULE) && defined(MODULE)) |
45 | extern struct dvb_frontend* cx22702_attach(const struct cx22702_config* config, | 45 | extern struct dvb_frontend* cx22702_attach(const struct cx22702_config* config, |
46 | struct i2c_adapter* i2c); | 46 | struct i2c_adapter* i2c); |
47 | #else | 47 | #else |
diff --git a/drivers/media/dvb/frontends/cx24110.h b/drivers/media/dvb/frontends/cx24110.h index c9d5ae250ebb..0ca3af4db513 100644 --- a/drivers/media/dvb/frontends/cx24110.h +++ b/drivers/media/dvb/frontends/cx24110.h | |||
@@ -41,7 +41,7 @@ static inline int cx24110_pll_write(struct dvb_frontend *fe, u32 val) { | |||
41 | return r; | 41 | return r; |
42 | } | 42 | } |
43 | 43 | ||
44 | #if defined(CONFIG_DVB_CX24110) || defined(CONFIG_DVB_CX24110_MODULE) | 44 | #if defined(CONFIG_DVB_CX24110) || (defined(CONFIG_DVB_CX24110_MODULE) && defined(MODULE)) |
45 | extern struct dvb_frontend* cx24110_attach(const struct cx24110_config* config, | 45 | extern struct dvb_frontend* cx24110_attach(const struct cx24110_config* config, |
46 | struct i2c_adapter* i2c); | 46 | struct i2c_adapter* i2c); |
47 | #else | 47 | #else |
diff --git a/drivers/media/dvb/frontends/cx24123.h b/drivers/media/dvb/frontends/cx24123.h index 57a1dae1dc40..84f9e4f5c15e 100644 --- a/drivers/media/dvb/frontends/cx24123.h +++ b/drivers/media/dvb/frontends/cx24123.h | |||
@@ -35,7 +35,7 @@ struct cx24123_config | |||
35 | int lnb_polarity; | 35 | int lnb_polarity; |
36 | }; | 36 | }; |
37 | 37 | ||
38 | #if defined(CONFIG_DVB_CX24123) || defined(CONFIG_DVB_CX24123_MODULE) | 38 | #if defined(CONFIG_DVB_CX24123) || (defined(CONFIG_DVB_CX24123_MODULE) && defined(MODULE)) |
39 | extern struct dvb_frontend* cx24123_attach(const struct cx24123_config* config, | 39 | extern struct dvb_frontend* cx24123_attach(const struct cx24123_config* config, |
40 | struct i2c_adapter* i2c); | 40 | struct i2c_adapter* i2c); |
41 | #else | 41 | #else |
diff --git a/drivers/media/dvb/frontends/dib3000.h b/drivers/media/dvb/frontends/dib3000.h index 0caac3f0f279..a6d3854a67bc 100644 --- a/drivers/media/dvb/frontends/dib3000.h +++ b/drivers/media/dvb/frontends/dib3000.h | |||
@@ -41,7 +41,7 @@ struct dib_fe_xfer_ops | |||
41 | int (*tuner_pass_ctrl)(struct dvb_frontend *fe, int onoff, u8 pll_ctrl); | 41 | int (*tuner_pass_ctrl)(struct dvb_frontend *fe, int onoff, u8 pll_ctrl); |
42 | }; | 42 | }; |
43 | 43 | ||
44 | #if defined(CONFIG_DVB_DIB3000MB) || defined(CONFIG_DVB_DIB3000MB_MODULE) | 44 | #if defined(CONFIG_DVB_DIB3000MB) || (defined(CONFIG_DVB_DIB3000MB_MODULE) && defined(MODULE)) |
45 | extern struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config, | 45 | extern struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config, |
46 | struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops); | 46 | struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops); |
47 | #else | 47 | #else |
diff --git a/drivers/media/dvb/frontends/dib3000mc.c b/drivers/media/dvb/frontends/dib3000mc.c index ccc813b525d6..3561a777568c 100644 --- a/drivers/media/dvb/frontends/dib3000mc.c +++ b/drivers/media/dvb/frontends/dib3000mc.c | |||
@@ -345,7 +345,7 @@ static int dib3000mc_init(struct dvb_frontend *demod) | |||
345 | 345 | ||
346 | /* agc */ | 346 | /* agc */ |
347 | dib3000mc_write_word(state, 36, state->cfg->max_time); | 347 | dib3000mc_write_word(state, 36, state->cfg->max_time); |
348 | dib3000mc_write_word(state, 37, agc->setup); | 348 | dib3000mc_write_word(state, 37, (state->cfg->agc_command1 << 13) | (state->cfg->agc_command2 << 12) | (0x1d << 0)); |
349 | dib3000mc_write_word(state, 38, state->cfg->pwm3_value); | 349 | dib3000mc_write_word(state, 38, state->cfg->pwm3_value); |
350 | dib3000mc_write_word(state, 39, state->cfg->ln_adc_level); | 350 | dib3000mc_write_word(state, 39, state->cfg->ln_adc_level); |
351 | 351 | ||
diff --git a/drivers/media/dvb/frontends/dib3000mc.h b/drivers/media/dvb/frontends/dib3000mc.h index b198cd5b1843..72d4757601d8 100644 --- a/drivers/media/dvb/frontends/dib3000mc.h +++ b/drivers/media/dvb/frontends/dib3000mc.h | |||
@@ -28,6 +28,9 @@ struct dib3000mc_config { | |||
28 | u16 max_time; | 28 | u16 max_time; |
29 | u16 ln_adc_level; | 29 | u16 ln_adc_level; |
30 | 30 | ||
31 | u8 agc_command1 :1; | ||
32 | u8 agc_command2 :1; | ||
33 | |||
31 | u8 mobile_mode; | 34 | u8 mobile_mode; |
32 | 35 | ||
33 | u8 output_mpeg2_in_188_bytes; | 36 | u8 output_mpeg2_in_188_bytes; |
@@ -36,7 +39,7 @@ struct dib3000mc_config { | |||
36 | #define DEFAULT_DIB3000MC_I2C_ADDRESS 16 | 39 | #define DEFAULT_DIB3000MC_I2C_ADDRESS 16 |
37 | #define DEFAULT_DIB3000P_I2C_ADDRESS 24 | 40 | #define DEFAULT_DIB3000P_I2C_ADDRESS 24 |
38 | 41 | ||
39 | #if defined(CONFIG_DVB_DIB3000MC) || defined(CONFIG_DVB_DIB3000MC_MODULE) | 42 | #if defined(CONFIG_DVB_DIB3000MC) || (defined(CONFIG_DVB_DIB3000MC_MODULE) && defined(MODULE)) |
40 | extern struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg); | 43 | extern struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg); |
41 | #else | 44 | #else |
42 | static inline struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg) | 45 | static inline struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg) |
diff --git a/drivers/media/dvb/frontends/isl6421.h b/drivers/media/dvb/frontends/isl6421.h index 1916e3eb2df3..ea7f78a7d3cd 100644 --- a/drivers/media/dvb/frontends/isl6421.h +++ b/drivers/media/dvb/frontends/isl6421.h | |||
@@ -39,7 +39,7 @@ | |||
39 | #define ISL6421_ISEL1 0x20 | 39 | #define ISL6421_ISEL1 0x20 |
40 | #define ISL6421_DCL 0x40 | 40 | #define ISL6421_DCL 0x40 |
41 | 41 | ||
42 | #if defined(CONFIG_DVB_ISL6421) || defined(CONFIG_DVB_ISL6421_MODULE) | 42 | #if defined(CONFIG_DVB_ISL6421) || (defined(CONFIG_DVB_ISL6421_MODULE) && defined(MODULE)) |
43 | /* override_set and override_clear control which system register bits (above) to always set & clear */ | 43 | /* override_set and override_clear control which system register bits (above) to always set & clear */ |
44 | extern struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr, | 44 | extern struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr, |
45 | u8 override_set, u8 override_clear); | 45 | u8 override_set, u8 override_clear); |
diff --git a/drivers/media/dvb/frontends/l64781.h b/drivers/media/dvb/frontends/l64781.h index 21ba4a230760..cd15f76ff28d 100644 --- a/drivers/media/dvb/frontends/l64781.h +++ b/drivers/media/dvb/frontends/l64781.h | |||
@@ -31,7 +31,7 @@ struct l64781_config | |||
31 | u8 demod_address; | 31 | u8 demod_address; |
32 | }; | 32 | }; |
33 | 33 | ||
34 | #if defined(CONFIG_DVB_L64781) || defined(CONFIG_DVB_L64781_MODULE) | 34 | #if defined(CONFIG_DVB_L64781) || (defined(CONFIG_DVB_L64781_MODULE) && defined(MODULE)) |
35 | extern struct dvb_frontend* l64781_attach(const struct l64781_config* config, | 35 | extern struct dvb_frontend* l64781_attach(const struct l64781_config* config, |
36 | struct i2c_adapter* i2c); | 36 | struct i2c_adapter* i2c); |
37 | #else | 37 | #else |
diff --git a/drivers/media/dvb/frontends/lgdt330x.h b/drivers/media/dvb/frontends/lgdt330x.h index 3f96b485584c..995059004b10 100644 --- a/drivers/media/dvb/frontends/lgdt330x.h +++ b/drivers/media/dvb/frontends/lgdt330x.h | |||
@@ -52,7 +52,7 @@ struct lgdt330x_config | |||
52 | int clock_polarity_flip; | 52 | int clock_polarity_flip; |
53 | }; | 53 | }; |
54 | 54 | ||
55 | #if defined(CONFIG_DVB_LGDT330X) || defined(CONFIG_DVB_LGDT330X_MODULE) | 55 | #if defined(CONFIG_DVB_LGDT330X) || (defined(CONFIG_DVB_LGDT330X_MODULE) && defined(MODULE)) |
56 | extern struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config, | 56 | extern struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config, |
57 | struct i2c_adapter* i2c); | 57 | struct i2c_adapter* i2c); |
58 | #else | 58 | #else |
diff --git a/drivers/media/dvb/frontends/lnbp21.h b/drivers/media/dvb/frontends/lnbp21.h index 1fe1dd179312..68906acf7d63 100644 --- a/drivers/media/dvb/frontends/lnbp21.h +++ b/drivers/media/dvb/frontends/lnbp21.h | |||
@@ -39,7 +39,7 @@ | |||
39 | 39 | ||
40 | #include <linux/dvb/frontend.h> | 40 | #include <linux/dvb/frontend.h> |
41 | 41 | ||
42 | #if defined(CONFIG_DVB_LNBP21) || defined(CONFIG_DVB_LNBP21_MODULE) | 42 | #if defined(CONFIG_DVB_LNBP21) || (defined(CONFIG_DVB_LNBP21_MODULE) && defined(MODULE)) |
43 | /* override_set and override_clear control which system register bits (above) to always set & clear */ | 43 | /* override_set and override_clear control which system register bits (above) to always set & clear */ |
44 | extern struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear); | 44 | extern struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear); |
45 | #else | 45 | #else |
diff --git a/drivers/media/dvb/frontends/mt2060.h b/drivers/media/dvb/frontends/mt2060.h index 34a37c2b556f..0a86eab3a954 100644 --- a/drivers/media/dvb/frontends/mt2060.h +++ b/drivers/media/dvb/frontends/mt2060.h | |||
@@ -30,6 +30,14 @@ struct mt2060_config { | |||
30 | u8 clock_out; /* 0 = off, 1 = CLK/4, 2 = CLK/2, 3 = CLK/1 */ | 30 | u8 clock_out; /* 0 = off, 1 = CLK/4, 2 = CLK/2, 3 = CLK/1 */ |
31 | }; | 31 | }; |
32 | 32 | ||
33 | #if defined(CONFIG_DVB_TUNER_MT2060) || (defined(CONFIG_DVB_TUNER_MT2060_MODULE) && defined(MODULE)) | ||
33 | extern struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1); | 34 | extern struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1); |
35 | #else | ||
36 | static inline struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1) | ||
37 | { | ||
38 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); | ||
39 | return NULL; | ||
40 | } | ||
41 | #endif // CONFIG_DVB_TUNER_MT2060 | ||
34 | 42 | ||
35 | #endif | 43 | #endif |
diff --git a/drivers/media/dvb/frontends/mt312.h b/drivers/media/dvb/frontends/mt312.h index 7112fb4d58ac..cf9a1505ad4b 100644 --- a/drivers/media/dvb/frontends/mt312.h +++ b/drivers/media/dvb/frontends/mt312.h | |||
@@ -34,7 +34,7 @@ struct mt312_config | |||
34 | u8 demod_address; | 34 | u8 demod_address; |
35 | }; | 35 | }; |
36 | 36 | ||
37 | #if defined(CONFIG_DVB_MT312) || defined(CONFIG_DVB_MT312_MODULE) | 37 | #if defined(CONFIG_DVB_MT312) || (defined(CONFIG_DVB_MT312_MODULE) && defined(MODULE)) |
38 | struct dvb_frontend* vp310_mt312_attach(const struct mt312_config* config, | 38 | struct dvb_frontend* vp310_mt312_attach(const struct mt312_config* config, |
39 | struct i2c_adapter* i2c); | 39 | struct i2c_adapter* i2c); |
40 | #else | 40 | #else |
diff --git a/drivers/media/dvb/frontends/mt352.h b/drivers/media/dvb/frontends/mt352.h index 0035c2e2d7c2..e9964081fd84 100644 --- a/drivers/media/dvb/frontends/mt352.h +++ b/drivers/media/dvb/frontends/mt352.h | |||
@@ -51,7 +51,7 @@ struct mt352_config | |||
51 | int (*demod_init)(struct dvb_frontend* fe); | 51 | int (*demod_init)(struct dvb_frontend* fe); |
52 | }; | 52 | }; |
53 | 53 | ||
54 | #if defined(CONFIG_DVB_MT352) || defined(CONFIG_DVB_MT352_MODULE) | 54 | #if defined(CONFIG_DVB_MT352) || (defined(CONFIG_DVB_MT352_MODULE) && defined(MODULE)) |
55 | extern struct dvb_frontend* mt352_attach(const struct mt352_config* config, | 55 | extern struct dvb_frontend* mt352_attach(const struct mt352_config* config, |
56 | struct i2c_adapter* i2c); | 56 | struct i2c_adapter* i2c); |
57 | #else | 57 | #else |
diff --git a/drivers/media/dvb/frontends/nxt200x.h b/drivers/media/dvb/frontends/nxt200x.h index 2eb220e98062..28bc5591b319 100644 --- a/drivers/media/dvb/frontends/nxt200x.h +++ b/drivers/media/dvb/frontends/nxt200x.h | |||
@@ -45,7 +45,7 @@ struct nxt200x_config | |||
45 | int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); | 45 | int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); |
46 | }; | 46 | }; |
47 | 47 | ||
48 | #if defined(CONFIG_DVB_NXT200X) || defined(CONFIG_DVB_NXT200X_MODULE) | 48 | #if defined(CONFIG_DVB_NXT200X) || (defined(CONFIG_DVB_NXT200X_MODULE) && defined(MODULE)) |
49 | extern struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config, | 49 | extern struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config, |
50 | struct i2c_adapter* i2c); | 50 | struct i2c_adapter* i2c); |
51 | #else | 51 | #else |
diff --git a/drivers/media/dvb/frontends/nxt6000.h b/drivers/media/dvb/frontends/nxt6000.h index 9397393a6bd1..13d22518356e 100644 --- a/drivers/media/dvb/frontends/nxt6000.h +++ b/drivers/media/dvb/frontends/nxt6000.h | |||
@@ -33,7 +33,7 @@ struct nxt6000_config | |||
33 | u8 clock_inversion:1; | 33 | u8 clock_inversion:1; |
34 | }; | 34 | }; |
35 | 35 | ||
36 | #if defined(CONFIG_DVB_NXT6000) || defined(CONFIG_DVB_NXT6000_MODULE) | 36 | #if defined(CONFIG_DVB_NXT6000) || (defined(CONFIG_DVB_NXT6000_MODULE) && defined(MODULE)) |
37 | extern struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config, | 37 | extern struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config, |
38 | struct i2c_adapter* i2c); | 38 | struct i2c_adapter* i2c); |
39 | #else | 39 | #else |
diff --git a/drivers/media/dvb/frontends/or51132.h b/drivers/media/dvb/frontends/or51132.h index 9718be4fb835..add24f0a743b 100644 --- a/drivers/media/dvb/frontends/or51132.h +++ b/drivers/media/dvb/frontends/or51132.h | |||
@@ -34,7 +34,7 @@ struct or51132_config | |||
34 | int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); | 34 | int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); |
35 | }; | 35 | }; |
36 | 36 | ||
37 | #if defined(CONFIG_DVB_OR51132) || defined(CONFIG_DVB_OR51132_MODULE) | 37 | #if defined(CONFIG_DVB_OR51132) || (defined(CONFIG_DVB_OR51132_MODULE) && defined(MODULE)) |
38 | extern struct dvb_frontend* or51132_attach(const struct or51132_config* config, | 38 | extern struct dvb_frontend* or51132_attach(const struct or51132_config* config, |
39 | struct i2c_adapter* i2c); | 39 | struct i2c_adapter* i2c); |
40 | #else | 40 | #else |
diff --git a/drivers/media/dvb/frontends/or51211.h b/drivers/media/dvb/frontends/or51211.h index 10a5419f9e00..8aad8402d615 100644 --- a/drivers/media/dvb/frontends/or51211.h +++ b/drivers/media/dvb/frontends/or51211.h | |||
@@ -37,7 +37,7 @@ struct or51211_config | |||
37 | void (*sleep)(struct dvb_frontend * fe); | 37 | void (*sleep)(struct dvb_frontend * fe); |
38 | }; | 38 | }; |
39 | 39 | ||
40 | #if defined(CONFIG_DVB_OR51211) || defined(CONFIG_DVB_OR51211_MODULE) | 40 | #if defined(CONFIG_DVB_OR51211) || (defined(CONFIG_DVB_OR51211_MODULE) && defined(MODULE)) |
41 | extern struct dvb_frontend* or51211_attach(const struct or51211_config* config, | 41 | extern struct dvb_frontend* or51211_attach(const struct or51211_config* config, |
42 | struct i2c_adapter* i2c); | 42 | struct i2c_adapter* i2c); |
43 | #else | 43 | #else |
diff --git a/drivers/media/dvb/frontends/s5h1420.h b/drivers/media/dvb/frontends/s5h1420.h index efc54d7f3c55..1555870f7226 100644 --- a/drivers/media/dvb/frontends/s5h1420.h +++ b/drivers/media/dvb/frontends/s5h1420.h | |||
@@ -34,7 +34,7 @@ struct s5h1420_config | |||
34 | u8 invert:1; | 34 | u8 invert:1; |
35 | }; | 35 | }; |
36 | 36 | ||
37 | #if defined(CONFIG_DVB_S5H1420) || defined(CONFIG_DVB_S5H1420_MODULE) | 37 | #if defined(CONFIG_DVB_S5H1420) || (defined(CONFIG_DVB_S5H1420_MODULE) && defined(MODULE)) |
38 | extern struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config, | 38 | extern struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config, |
39 | struct i2c_adapter* i2c); | 39 | struct i2c_adapter* i2c); |
40 | #else | 40 | #else |
diff --git a/drivers/media/dvb/frontends/sp8870.h b/drivers/media/dvb/frontends/sp8870.h index 4cf27d3b10f2..909cefe7139e 100644 --- a/drivers/media/dvb/frontends/sp8870.h +++ b/drivers/media/dvb/frontends/sp8870.h | |||
@@ -35,7 +35,7 @@ struct sp8870_config | |||
35 | int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); | 35 | int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); |
36 | }; | 36 | }; |
37 | 37 | ||
38 | #if defined(CONFIG_DVB_SP8870) || defined(CONFIG_DVB_SP8870_MODULE) | 38 | #if defined(CONFIG_DVB_SP8870) || (defined(CONFIG_DVB_SP8870_MODULE) && defined(MODULE)) |
39 | extern struct dvb_frontend* sp8870_attach(const struct sp8870_config* config, | 39 | extern struct dvb_frontend* sp8870_attach(const struct sp8870_config* config, |
40 | struct i2c_adapter* i2c); | 40 | struct i2c_adapter* i2c); |
41 | #else | 41 | #else |
diff --git a/drivers/media/dvb/frontends/sp887x.h b/drivers/media/dvb/frontends/sp887x.h index cab7ea644dfa..7ee78d7d916d 100644 --- a/drivers/media/dvb/frontends/sp887x.h +++ b/drivers/media/dvb/frontends/sp887x.h | |||
@@ -17,7 +17,7 @@ struct sp887x_config | |||
17 | int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); | 17 | int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); |
18 | }; | 18 | }; |
19 | 19 | ||
20 | #if defined(CONFIG_DVB_SP887X) || defined(CONFIG_DVB_SP887X_MODULE) | 20 | #if defined(CONFIG_DVB_SP887X) || (defined(CONFIG_DVB_SP887X_MODULE) && defined(MODULE)) |
21 | extern struct dvb_frontend* sp887x_attach(const struct sp887x_config* config, | 21 | extern struct dvb_frontend* sp887x_attach(const struct sp887x_config* config, |
22 | struct i2c_adapter* i2c); | 22 | struct i2c_adapter* i2c); |
23 | #else | 23 | #else |
diff --git a/drivers/media/dvb/frontends/stv0297.h b/drivers/media/dvb/frontends/stv0297.h index 760b80db43a5..69f4515df2b9 100644 --- a/drivers/media/dvb/frontends/stv0297.h +++ b/drivers/media/dvb/frontends/stv0297.h | |||
@@ -42,7 +42,7 @@ struct stv0297_config | |||
42 | u8 stop_during_read:1; | 42 | u8 stop_during_read:1; |
43 | }; | 43 | }; |
44 | 44 | ||
45 | #if defined(CONFIG_DVB_STV0297) || defined(CONFIG_DVB_STV0297_MODULE) | 45 | #if defined(CONFIG_DVB_STV0297) || (defined(CONFIG_DVB_STV0297_MODULE) && defined(MODULE)) |
46 | extern struct dvb_frontend* stv0297_attach(const struct stv0297_config* config, | 46 | extern struct dvb_frontend* stv0297_attach(const struct stv0297_config* config, |
47 | struct i2c_adapter* i2c); | 47 | struct i2c_adapter* i2c); |
48 | #else | 48 | #else |
diff --git a/drivers/media/dvb/frontends/stv0299.h b/drivers/media/dvb/frontends/stv0299.h index 7ef25207081d..33df9495908f 100644 --- a/drivers/media/dvb/frontends/stv0299.h +++ b/drivers/media/dvb/frontends/stv0299.h | |||
@@ -89,7 +89,7 @@ struct stv0299_config | |||
89 | int (*set_symbol_rate)(struct dvb_frontend* fe, u32 srate, u32 ratio); | 89 | int (*set_symbol_rate)(struct dvb_frontend* fe, u32 srate, u32 ratio); |
90 | }; | 90 | }; |
91 | 91 | ||
92 | #if defined(CONFIG_DVB_STV0299) || defined(CONFIG_DVB_STV0299_MODULE) | 92 | #if defined(CONFIG_DVB_STV0299) || (defined(CONFIG_DVB_STV0299_MODULE) && defined(MODULE)) |
93 | extern struct dvb_frontend* stv0299_attach(const struct stv0299_config* config, | 93 | extern struct dvb_frontend* stv0299_attach(const struct stv0299_config* config, |
94 | struct i2c_adapter* i2c); | 94 | struct i2c_adapter* i2c); |
95 | #else | 95 | #else |
diff --git a/drivers/media/dvb/frontends/tda10021.h b/drivers/media/dvb/frontends/tda10021.h index d68ae20c8412..e3da780108f6 100644 --- a/drivers/media/dvb/frontends/tda10021.h +++ b/drivers/media/dvb/frontends/tda10021.h | |||
@@ -32,7 +32,7 @@ struct tda10021_config | |||
32 | u8 demod_address; | 32 | u8 demod_address; |
33 | }; | 33 | }; |
34 | 34 | ||
35 | #if defined(CONFIG_DVB_TDA10021) || defined(CONFIG_DVB_TDA10021_MODULE) | 35 | #if defined(CONFIG_DVB_TDA10021) || (defined(CONFIG_DVB_TDA10021_MODULE) && defined(MODULE)) |
36 | extern struct dvb_frontend* tda10021_attach(const struct tda10021_config* config, | 36 | extern struct dvb_frontend* tda10021_attach(const struct tda10021_config* config, |
37 | struct i2c_adapter* i2c, u8 pwm); | 37 | struct i2c_adapter* i2c, u8 pwm); |
38 | #else | 38 | #else |
diff --git a/drivers/media/dvb/frontends/tda1004x.h b/drivers/media/dvb/frontends/tda1004x.h index e28fca05734c..605ad2dfc09d 100644 --- a/drivers/media/dvb/frontends/tda1004x.h +++ b/drivers/media/dvb/frontends/tda1004x.h | |||
@@ -71,7 +71,7 @@ struct tda1004x_config | |||
71 | int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); | 71 | int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); |
72 | }; | 72 | }; |
73 | 73 | ||
74 | #if defined(CONFIG_DVB_TDA1004X) || defined(CONFIG_DVB_TDA1004X_MODULE) | 74 | #if defined(CONFIG_DVB_TDA1004X) || (defined(CONFIG_DVB_TDA1004X_MODULE) && defined(MODULE)) |
75 | extern struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, | 75 | extern struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, |
76 | struct i2c_adapter* i2c); | 76 | struct i2c_adapter* i2c); |
77 | 77 | ||
diff --git a/drivers/media/dvb/frontends/tda10086.h b/drivers/media/dvb/frontends/tda10086.h index e8061db11123..ed584a8f4a89 100644 --- a/drivers/media/dvb/frontends/tda10086.h +++ b/drivers/media/dvb/frontends/tda10086.h | |||
@@ -35,7 +35,16 @@ struct tda10086_config | |||
35 | u8 invert; | 35 | u8 invert; |
36 | }; | 36 | }; |
37 | 37 | ||
38 | #if defined(CONFIG_DVB_TDA10086) || (defined(CONFIG_DVB_TDA10086_MODULE) && defined(MODULE)) | ||
38 | extern struct dvb_frontend* tda10086_attach(const struct tda10086_config* config, | 39 | extern struct dvb_frontend* tda10086_attach(const struct tda10086_config* config, |
39 | struct i2c_adapter* i2c); | 40 | struct i2c_adapter* i2c); |
41 | #else | ||
42 | static inline struct dvb_frontend* tda10086_attach(const struct tda10086_config* config, | ||
43 | struct i2c_adapter* i2c) | ||
44 | { | ||
45 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); | ||
46 | return NULL; | ||
47 | } | ||
48 | #endif // CONFIG_DVB_TDA10086 | ||
40 | 49 | ||
41 | #endif // TDA10086_H | 50 | #endif // TDA10086_H |
diff --git a/drivers/media/dvb/frontends/tda8083.h b/drivers/media/dvb/frontends/tda8083.h index aae15bdce6eb..2d3307999f21 100644 --- a/drivers/media/dvb/frontends/tda8083.h +++ b/drivers/media/dvb/frontends/tda8083.h | |||
@@ -35,7 +35,7 @@ struct tda8083_config | |||
35 | u8 demod_address; | 35 | u8 demod_address; |
36 | }; | 36 | }; |
37 | 37 | ||
38 | #if defined(CONFIG_DVB_TDA8083) || defined(CONFIG_DVB_TDA8083_MODULE) | 38 | #if defined(CONFIG_DVB_TDA8083) || (defined(CONFIG_DVB_TDA8083_MODULE) && defined(MODULE)) |
39 | extern struct dvb_frontend* tda8083_attach(const struct tda8083_config* config, | 39 | extern struct dvb_frontend* tda8083_attach(const struct tda8083_config* config, |
40 | struct i2c_adapter* i2c); | 40 | struct i2c_adapter* i2c); |
41 | #else | 41 | #else |
diff --git a/drivers/media/dvb/frontends/tda826x.c b/drivers/media/dvb/frontends/tda826x.c index eeab26bd36ed..34815b0b97e4 100644 --- a/drivers/media/dvb/frontends/tda826x.c +++ b/drivers/media/dvb/frontends/tda826x.c | |||
@@ -121,7 +121,7 @@ static struct dvb_tuner_ops tda826x_tuner_ops = { | |||
121 | .info = { | 121 | .info = { |
122 | .name = "Philips TDA826X", | 122 | .name = "Philips TDA826X", |
123 | .frequency_min = 950000, | 123 | .frequency_min = 950000, |
124 | .frequency_min = 2175000 | 124 | .frequency_max = 2175000 |
125 | }, | 125 | }, |
126 | .release = tda826x_release, | 126 | .release = tda826x_release, |
127 | .sleep = tda826x_sleep, | 127 | .sleep = tda826x_sleep, |
diff --git a/drivers/media/dvb/frontends/tda826x.h b/drivers/media/dvb/frontends/tda826x.h index 3307607632b0..ad9981195961 100644 --- a/drivers/media/dvb/frontends/tda826x.h +++ b/drivers/media/dvb/frontends/tda826x.h | |||
@@ -35,6 +35,19 @@ | |||
35 | * @param has_loopthrough Set to 1 if the card has a loopthrough RF connector. | 35 | * @param has_loopthrough Set to 1 if the card has a loopthrough RF connector. |
36 | * @return FE pointer on success, NULL on failure. | 36 | * @return FE pointer on success, NULL on failure. |
37 | */ | 37 | */ |
38 | extern struct dvb_frontend *tda826x_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c, int has_loopthrough); | 38 | #if defined(CONFIG_DVB_TDA826X) || (defined(CONFIG_DVB_TDA826X_MODULE) && defined(MODULE)) |
39 | 39 | extern struct dvb_frontend* tda826x_attach(struct dvb_frontend *fe, int addr, | |
40 | #endif | 40 | struct i2c_adapter *i2c, |
41 | int has_loopthrough); | ||
42 | #else | ||
43 | static inline struct dvb_frontend* tda826x_attach(struct dvb_frontend *fe, | ||
44 | int addr, | ||
45 | struct i2c_adapter *i2c, | ||
46 | int has_loopthrough) | ||
47 | { | ||
48 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); | ||
49 | return NULL; | ||
50 | } | ||
51 | #endif // CONFIG_DVB_TDA826X | ||
52 | |||
53 | #endif // __DVB_TDA826X_H__ | ||
diff --git a/drivers/media/dvb/frontends/tua6100.h b/drivers/media/dvb/frontends/tua6100.h index 8f98033ffa7b..03a665e7df6d 100644 --- a/drivers/media/dvb/frontends/tua6100.h +++ b/drivers/media/dvb/frontends/tua6100.h | |||
@@ -34,7 +34,7 @@ | |||
34 | #include <linux/i2c.h> | 34 | #include <linux/i2c.h> |
35 | #include "dvb_frontend.h" | 35 | #include "dvb_frontend.h" |
36 | 36 | ||
37 | #if defined(CONFIG_DVB_TUA6100) || defined(CONFIG_DVB_TUA6100_MODULE) | 37 | #if defined(CONFIG_DVB_TUA6100) || (defined(CONFIG_DVB_TUA6100_MODULE) && defined(MODULE)) |
38 | extern struct dvb_frontend *tua6100_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c); | 38 | extern struct dvb_frontend *tua6100_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c); |
39 | #else | 39 | #else |
40 | static inline struct dvb_frontend* tua6100_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c) | 40 | static inline struct dvb_frontend* tua6100_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c) |
diff --git a/drivers/media/dvb/frontends/ves1820.h b/drivers/media/dvb/frontends/ves1820.h index f0c9dded39d7..e4a2a324046a 100644 --- a/drivers/media/dvb/frontends/ves1820.h +++ b/drivers/media/dvb/frontends/ves1820.h | |||
@@ -41,7 +41,7 @@ struct ves1820_config | |||
41 | u8 selagc:1; | 41 | u8 selagc:1; |
42 | }; | 42 | }; |
43 | 43 | ||
44 | #if defined(CONFIG_DVB_VES1820) || defined(CONFIG_DVB_VES1820_MODULE) | 44 | #if defined(CONFIG_DVB_VES1820) || (defined(CONFIG_DVB_VES1820_MODULE) && defined(MODULE)) |
45 | extern struct dvb_frontend* ves1820_attach(const struct ves1820_config* config, | 45 | extern struct dvb_frontend* ves1820_attach(const struct ves1820_config* config, |
46 | struct i2c_adapter* i2c, u8 pwm); | 46 | struct i2c_adapter* i2c, u8 pwm); |
47 | #else | 47 | #else |
diff --git a/drivers/media/dvb/frontends/ves1x93.h b/drivers/media/dvb/frontends/ves1x93.h index 395fed39b286..d507f8966f81 100644 --- a/drivers/media/dvb/frontends/ves1x93.h +++ b/drivers/media/dvb/frontends/ves1x93.h | |||
@@ -40,7 +40,7 @@ struct ves1x93_config | |||
40 | u8 invert_pwm:1; | 40 | u8 invert_pwm:1; |
41 | }; | 41 | }; |
42 | 42 | ||
43 | #if defined(CONFIG_DVB_VES1X93) || defined(CONFIG_DVB_VES1X93_MODULE) | 43 | #if defined(CONFIG_DVB_VES1X93) || (defined(CONFIG_DVB_VES1X93_MODULE) && defined(MODULE)) |
44 | extern struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config, | 44 | extern struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config, |
45 | struct i2c_adapter* i2c); | 45 | struct i2c_adapter* i2c); |
46 | #else | 46 | #else |
diff --git a/drivers/media/dvb/frontends/zl10353.h b/drivers/media/dvb/frontends/zl10353.h index 79a947215c4d..0bc0109737f1 100644 --- a/drivers/media/dvb/frontends/zl10353.h +++ b/drivers/media/dvb/frontends/zl10353.h | |||
@@ -36,7 +36,7 @@ struct zl10353_config | |||
36 | int parallel_ts; | 36 | int parallel_ts; |
37 | }; | 37 | }; |
38 | 38 | ||
39 | #if defined(CONFIG_DVB_ZL10353) || defined(CONFIG_DVB_ZL10353_MODULE) | 39 | #if defined(CONFIG_DVB_ZL10353) || (defined(CONFIG_DVB_ZL10353_MODULE) && defined(MODULE)) |
40 | extern struct dvb_frontend* zl10353_attach(const struct zl10353_config *config, | 40 | extern struct dvb_frontend* zl10353_attach(const struct zl10353_config *config, |
41 | struct i2c_adapter *i2c); | 41 | struct i2c_adapter *i2c); |
42 | #else | 42 | #else |
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c index 2a2e9b400613..cd5ec489af1c 100644 --- a/drivers/media/dvb/ttpci/budget-ci.c +++ b/drivers/media/dvb/ttpci/budget-ci.c | |||
@@ -46,7 +46,14 @@ | |||
46 | #include "bsbe1.h" | 46 | #include "bsbe1.h" |
47 | #include "bsru6.h" | 47 | #include "bsru6.h" |
48 | 48 | ||
49 | #define DEBIADDR_IR 0x1234 | 49 | /* |
50 | * Regarding DEBIADDR_IR: | ||
51 | * Some CI modules hang if random addresses are read. | ||
52 | * Using address 0x4000 for the IR read means that we | ||
53 | * use the same address as for CI version, which should | ||
54 | * be a safe default. | ||
55 | */ | ||
56 | #define DEBIADDR_IR 0x4000 | ||
50 | #define DEBIADDR_CICONTROL 0x0000 | 57 | #define DEBIADDR_CICONTROL 0x0000 |
51 | #define DEBIADDR_CIVERSION 0x4000 | 58 | #define DEBIADDR_CIVERSION 0x4000 |
52 | #define DEBIADDR_IO 0x1000 | 59 | #define DEBIADDR_IO 0x1000 |
@@ -1028,6 +1035,7 @@ static void frontend_init(struct budget_ci *budget_ci) | |||
1028 | 1035 | ||
1029 | case 0x1012: // TT DVB-T CI budget (tda10046/Philips tdm1316l(tda6651tt)) | 1036 | case 0x1012: // TT DVB-T CI budget (tda10046/Philips tdm1316l(tda6651tt)) |
1030 | budget_ci->tuner_pll_address = 0x60; | 1037 | budget_ci->tuner_pll_address = 0x60; |
1038 | philips_tdm1316l_config.invert = 1; | ||
1031 | budget_ci->budget.dvb_frontend = | 1039 | budget_ci->budget.dvb_frontend = |
1032 | dvb_attach(tda10046_attach, &philips_tdm1316l_config, &budget_ci->budget.i2c_adap); | 1040 | dvb_attach(tda10046_attach, &philips_tdm1316l_config, &budget_ci->budget.i2c_adap); |
1033 | if (budget_ci->budget.dvb_frontend) { | 1041 | if (budget_ci->budget.dvb_frontend) { |
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index afb734df6e05..bf267552941f 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig | |||
@@ -186,7 +186,7 @@ config VIDEO_KS0127 | |||
186 | 186 | ||
187 | config VIDEO_SAA7110 | 187 | config VIDEO_SAA7110 |
188 | tristate "Philips SAA7110 video decoder" | 188 | tristate "Philips SAA7110 video decoder" |
189 | depends on VIDEO_V4L1 | 189 | depends on VIDEO_V4L1 && I2C |
190 | ---help--- | 190 | ---help--- |
191 | Support for the Philips SAA7110 video decoders. | 191 | Support for the Philips SAA7110 video decoders. |
192 | 192 | ||
@@ -677,6 +677,8 @@ config VIDEO_M32R_AR_M64278 | |||
677 | menu "V4L USB devices" | 677 | menu "V4L USB devices" |
678 | depends on USB && VIDEO_DEV | 678 | depends on USB && VIDEO_DEV |
679 | 679 | ||
680 | source "drivers/media/video/pvrusb2/Kconfig" | ||
681 | |||
680 | source "drivers/media/video/em28xx/Kconfig" | 682 | source "drivers/media/video/em28xx/Kconfig" |
681 | 683 | ||
682 | source "drivers/media/video/usbvideo/Kconfig" | 684 | source "drivers/media/video/usbvideo/Kconfig" |
diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c index a84903e0d810..21ebe8f13815 100644 --- a/drivers/media/video/bt8xx/bttv-cards.c +++ b/drivers/media/video/bt8xx/bttv-cards.c | |||
@@ -4001,7 +4001,7 @@ static void __devinit init_PXC200(struct bttv *btv) | |||
4001 | * - sleep 1ms | 4001 | * - sleep 1ms |
4002 | * - write 0x0E | 4002 | * - write 0x0E |
4003 | * read from GPIO_DATA into buf (uint_32) | 4003 | * read from GPIO_DATA into buf (uint_32) |
4004 | * - if ( buf>>18 & 0x01 ) || ( buf>>19 && 0x01 != 0 ) | 4004 | * - if ( buf>>18 & 0x01 ) || ( buf>>19 & 0x01 != 0 ) |
4005 | * error. ERROR_CPLD_Check_Failed. | 4005 | * error. ERROR_CPLD_Check_Failed. |
4006 | */ | 4006 | */ |
4007 | /* ----------------------------------------------------------------------- */ | 4007 | /* ----------------------------------------------------------------------- */ |
diff --git a/drivers/media/video/cx25840/cx25840-vbi.c b/drivers/media/video/cx25840/cx25840-vbi.c index 48014a254e15..f85f2084324f 100644 --- a/drivers/media/video/cx25840/cx25840-vbi.c +++ b/drivers/media/video/cx25840/cx25840-vbi.c | |||
@@ -235,6 +235,7 @@ int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg) | |||
235 | 0, 0, V4L2_SLICED_VPS, 0, 0, /* 9 */ | 235 | 0, 0, V4L2_SLICED_VPS, 0, 0, /* 9 */ |
236 | 0, 0, 0, 0 | 236 | 0, 0, 0, 0 |
237 | }; | 237 | }; |
238 | int is_pal = !(cx25840_get_v4lstd(client) & V4L2_STD_525_60); | ||
238 | int i; | 239 | int i; |
239 | 240 | ||
240 | fmt = arg; | 241 | fmt = arg; |
@@ -246,13 +247,25 @@ int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg) | |||
246 | if ((cx25840_read(client, 0x404) & 0x10) == 0) | 247 | if ((cx25840_read(client, 0x404) & 0x10) == 0) |
247 | break; | 248 | break; |
248 | 249 | ||
249 | for (i = 7; i <= 23; i++) { | 250 | if (is_pal) { |
250 | u8 v = cx25840_read(client, 0x424 + i - 7); | 251 | for (i = 7; i <= 23; i++) { |
252 | u8 v = cx25840_read(client, 0x424 + i - 7); | ||
253 | |||
254 | svbi->service_lines[0][i] = lcr2vbi[v >> 4]; | ||
255 | svbi->service_lines[1][i] = lcr2vbi[v & 0xf]; | ||
256 | svbi->service_set |= | ||
257 | svbi->service_lines[0][i] | svbi->service_lines[1][i]; | ||
258 | } | ||
259 | } | ||
260 | else { | ||
261 | for (i = 10; i <= 21; i++) { | ||
262 | u8 v = cx25840_read(client, 0x424 + i - 10); | ||
251 | 263 | ||
252 | svbi->service_lines[0][i] = lcr2vbi[v >> 4]; | 264 | svbi->service_lines[0][i] = lcr2vbi[v >> 4]; |
253 | svbi->service_lines[1][i] = lcr2vbi[v & 0xf]; | 265 | svbi->service_lines[1][i] = lcr2vbi[v & 0xf]; |
254 | svbi->service_set |= | 266 | svbi->service_set |= |
255 | svbi->service_lines[0][i] | svbi->service_lines[1][i]; | 267 | svbi->service_lines[0][i] | svbi->service_lines[1][i]; |
268 | } | ||
256 | } | 269 | } |
257 | break; | 270 | break; |
258 | } | 271 | } |
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c index af71d4225c76..f764a57c56be 100644 --- a/drivers/media/video/cx88/cx88-cards.c +++ b/drivers/media/video/cx88/cx88-cards.c | |||
@@ -1230,6 +1230,7 @@ struct cx88_board cx88_boards[] = { | |||
1230 | .vmux = 2, | 1230 | .vmux = 2, |
1231 | .gpio0 = 0x84bf, | 1231 | .gpio0 = 0x84bf, |
1232 | }}, | 1232 | }}, |
1233 | .mpeg = CX88_MPEG_DVB, | ||
1233 | }, | 1234 | }, |
1234 | [CX88_BOARD_NORWOOD_MICRO] = { | 1235 | [CX88_BOARD_NORWOOD_MICRO] = { |
1235 | .name = "Norwood Micro TV Tuner", | 1236 | .name = "Norwood Micro TV Tuner", |
@@ -1590,6 +1591,18 @@ struct cx88_subid cx88_subids[] = { | |||
1590 | .subvendor = 0x0070, | 1591 | .subvendor = 0x0070, |
1591 | .subdevice = 0x9000, | 1592 | .subdevice = 0x9000, |
1592 | .card = CX88_BOARD_HAUPPAUGE_DVB_T1, | 1593 | .card = CX88_BOARD_HAUPPAUGE_DVB_T1, |
1594 | },{ | ||
1595 | .subvendor = 0x0070, | ||
1596 | .subdevice = 0x1400, | ||
1597 | .card = CX88_BOARD_HAUPPAUGE_HVR3000, | ||
1598 | },{ | ||
1599 | .subvendor = 0x0070, | ||
1600 | .subdevice = 0x1401, | ||
1601 | .card = CX88_BOARD_HAUPPAUGE_HVR3000, | ||
1602 | },{ | ||
1603 | .subvendor = 0x0070, | ||
1604 | .subdevice = 0x1402, | ||
1605 | .card = CX88_BOARD_HAUPPAUGE_HVR3000, | ||
1593 | }, | 1606 | }, |
1594 | }; | 1607 | }; |
1595 | const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids); | 1608 | const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids); |
@@ -1633,7 +1646,15 @@ static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data) | |||
1633 | /* Make sure we support the board model */ | 1646 | /* Make sure we support the board model */ |
1634 | switch (tv.model) | 1647 | switch (tv.model) |
1635 | { | 1648 | { |
1649 | case 14009: /* WinTV-HVR3000 (Retail, IR, b/panel video, 3.5mm audio in) */ | ||
1650 | case 14019: /* WinTV-HVR3000 (Retail, IR Blaster, b/panel video, 3.5mm audio in) */ | ||
1651 | case 14029: /* WinTV-HVR3000 (Retail, IR, b/panel video, 3.5mm audio in - 880 bridge) */ | ||
1652 | case 14109: /* WinTV-HVR3000 (Retail, IR, b/panel video, 3.5mm audio in - low profile) */ | ||
1653 | case 14129: /* WinTV-HVR3000 (Retail, IR, b/panel video, 3.5mm audio in - 880 bridge - LP) */ | ||
1654 | case 14559: /* WinTV-HVR3000 (OEM, no IR, b/panel video, 3.5mm audio in) */ | ||
1636 | case 14569: /* WinTV-HVR3000 (OEM, no IR, no back panel video) */ | 1655 | case 14569: /* WinTV-HVR3000 (OEM, no IR, no back panel video) */ |
1656 | case 14659: /* WinTV-HVR3000 (OEM, no IR, b/panel video, RCA audio in - Low profile) */ | ||
1657 | case 14669: /* WinTV-HVR3000 (OEM, no IR, no b/panel video - Low profile) */ | ||
1637 | case 28552: /* WinTV-PVR 'Roslyn' (No IR) */ | 1658 | case 28552: /* WinTV-PVR 'Roslyn' (No IR) */ |
1638 | case 34519: /* WinTV-PCI-FM */ | 1659 | case 34519: /* WinTV-PCI-FM */ |
1639 | case 90002: /* Nova-T-PCI (9002) */ | 1660 | case 90002: /* Nova-T-PCI (9002) */ |
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c index bd0c8797f26d..0ef13e7efa2e 100644 --- a/drivers/media/video/cx88/cx88-dvb.c +++ b/drivers/media/video/cx88/cx88-dvb.c | |||
@@ -315,15 +315,22 @@ static struct cx22702_config hauppauge_novat_config = { | |||
315 | .demod_address = 0x43, | 315 | .demod_address = 0x43, |
316 | .output_mode = CX22702_SERIAL_OUTPUT, | 316 | .output_mode = CX22702_SERIAL_OUTPUT, |
317 | }; | 317 | }; |
318 | |||
318 | static struct cx22702_config hauppauge_hvr1100_config = { | 319 | static struct cx22702_config hauppauge_hvr1100_config = { |
319 | .demod_address = 0x63, | 320 | .demod_address = 0x63, |
320 | .output_mode = CX22702_SERIAL_OUTPUT, | 321 | .output_mode = CX22702_SERIAL_OUTPUT, |
321 | }; | 322 | }; |
323 | |||
322 | static struct cx22702_config hauppauge_hvr1300_config = { | 324 | static struct cx22702_config hauppauge_hvr1300_config = { |
323 | .demod_address = 0x63, | 325 | .demod_address = 0x63, |
324 | .output_mode = CX22702_SERIAL_OUTPUT, | 326 | .output_mode = CX22702_SERIAL_OUTPUT, |
325 | }; | 327 | }; |
326 | 328 | ||
329 | static struct cx22702_config hauppauge_hvr3000_config = { | ||
330 | .demod_address = 0x63, | ||
331 | .output_mode = CX22702_SERIAL_OUTPUT, | ||
332 | }; | ||
333 | |||
327 | static int or51132_set_ts_param(struct dvb_frontend* fe, | 334 | static int or51132_set_ts_param(struct dvb_frontend* fe, |
328 | int is_punctured) | 335 | int is_punctured) |
329 | { | 336 | { |
@@ -558,6 +565,16 @@ static int dvb_register(struct cx8802_dev *dev) | |||
558 | &dvb_pll_fmd1216me); | 565 | &dvb_pll_fmd1216me); |
559 | } | 566 | } |
560 | break; | 567 | break; |
568 | case CX88_BOARD_HAUPPAUGE_HVR3000: | ||
569 | dev->dvb.frontend = dvb_attach(cx22702_attach, | ||
570 | &hauppauge_hvr3000_config, | ||
571 | &dev->core->i2c_adap); | ||
572 | if (dev->dvb.frontend != NULL) { | ||
573 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, | ||
574 | &dev->core->i2c_adap, | ||
575 | &dvb_pll_fmd1216me); | ||
576 | } | ||
577 | break; | ||
561 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS: | 578 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS: |
562 | dev->dvb.frontend = dvb_attach(mt352_attach, | 579 | dev->dvb.frontend = dvb_attach(mt352_attach, |
563 | &dvico_fusionhdtv, | 580 | &dvico_fusionhdtv, |
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c index 83ebf7a3c054..57e1c024a547 100644 --- a/drivers/media/video/cx88/cx88-input.c +++ b/drivers/media/video/cx88/cx88-input.c | |||
@@ -196,18 +196,25 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) | |||
196 | case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: | 196 | case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: |
197 | case CX88_BOARD_HAUPPAUGE_HVR1100: | 197 | case CX88_BOARD_HAUPPAUGE_HVR1100: |
198 | case CX88_BOARD_HAUPPAUGE_HVR1300: | 198 | case CX88_BOARD_HAUPPAUGE_HVR1300: |
199 | case CX88_BOARD_HAUPPAUGE_HVR3000: | ||
199 | ir_codes = ir_codes_hauppauge_new; | 200 | ir_codes = ir_codes_hauppauge_new; |
200 | ir_type = IR_TYPE_RC5; | 201 | ir_type = IR_TYPE_RC5; |
201 | ir->sampling = 1; | 202 | ir->sampling = 1; |
202 | break; | 203 | break; |
203 | case CX88_BOARD_WINFAST_DTV2000H: | 204 | case CX88_BOARD_WINFAST_DTV2000H: |
204 | case CX88_BOARD_WINFAST2000XP_EXPERT: | ||
205 | ir_codes = ir_codes_winfast; | 205 | ir_codes = ir_codes_winfast; |
206 | ir->gpio_addr = MO_GP0_IO; | 206 | ir->gpio_addr = MO_GP0_IO; |
207 | ir->mask_keycode = 0x8f8; | 207 | ir->mask_keycode = 0x8f8; |
208 | ir->mask_keyup = 0x100; | 208 | ir->mask_keyup = 0x100; |
209 | ir->polling = 50; /* ms */ | 209 | ir->polling = 50; /* ms */ |
210 | break; | 210 | break; |
211 | case CX88_BOARD_WINFAST2000XP_EXPERT: | ||
212 | ir_codes = ir_codes_winfast; | ||
213 | ir->gpio_addr = MO_GP0_IO; | ||
214 | ir->mask_keycode = 0x8f8; | ||
215 | ir->mask_keyup = 0x100; | ||
216 | ir->polling = 1; /* ms */ | ||
217 | break; | ||
211 | case CX88_BOARD_IODATA_GVBCTV7E: | 218 | case CX88_BOARD_IODATA_GVBCTV7E: |
212 | ir_codes = ir_codes_iodata_bctv7e; | 219 | ir_codes = ir_codes_iodata_bctv7e; |
213 | ir->gpio_addr = MO_GP0_IO; | 220 | ir->gpio_addr = MO_GP0_IO; |
@@ -215,7 +222,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) | |||
215 | ir->mask_keydown = 0x02; | 222 | ir->mask_keydown = 0x02; |
216 | ir->polling = 5; /* ms */ | 223 | ir->polling = 5; /* ms */ |
217 | break; | 224 | break; |
218 | case CX88_BOARD_PROLINK_PLAYTVPVR: | 225 | case CX88_BOARD_PROLINK_PLAYTVPVR: |
219 | case CX88_BOARD_PIXELVIEW_PLAYTV_ULTRA_PRO: | 226 | case CX88_BOARD_PIXELVIEW_PLAYTV_ULTRA_PRO: |
220 | ir_codes = ir_codes_pixelview; | 227 | ir_codes = ir_codes_pixelview; |
221 | ir->gpio_addr = MO_GP1_IO; | 228 | ir->gpio_addr = MO_GP1_IO; |
@@ -419,6 +426,7 @@ void cx88_ir_irq(struct cx88_core *core) | |||
419 | case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: | 426 | case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: |
420 | case CX88_BOARD_HAUPPAUGE_HVR1100: | 427 | case CX88_BOARD_HAUPPAUGE_HVR1100: |
421 | case CX88_BOARD_HAUPPAUGE_HVR1300: | 428 | case CX88_BOARD_HAUPPAUGE_HVR1300: |
429 | case CX88_BOARD_HAUPPAUGE_HVR3000: | ||
422 | ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7); | 430 | ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7); |
423 | ir_dprintk("biphase decoded: %x\n", ircode); | 431 | ir_dprintk("biphase decoded: %x\n", ircode); |
424 | if ((ircode & 0xfffff000) != 0x3000) | 432 | if ((ircode & 0xfffff000) != 0x3000) |
diff --git a/drivers/media/video/et61x251/et61x251_core.c b/drivers/media/video/et61x251/et61x251_core.c index bc544cc7ccb8..f786ab11d2cd 100644 --- a/drivers/media/video/et61x251/et61x251_core.c +++ b/drivers/media/video/et61x251/et61x251_core.c | |||
@@ -973,16 +973,32 @@ static CLASS_DEVICE_ATTR(i2c_val, S_IRUGO | S_IWUSR, | |||
973 | et61x251_show_i2c_val, et61x251_store_i2c_val); | 973 | et61x251_show_i2c_val, et61x251_store_i2c_val); |
974 | 974 | ||
975 | 975 | ||
976 | static void et61x251_create_sysfs(struct et61x251_device* cam) | 976 | static int et61x251_create_sysfs(struct et61x251_device* cam) |
977 | { | 977 | { |
978 | struct video_device *v4ldev = cam->v4ldev; | 978 | struct video_device *v4ldev = cam->v4ldev; |
979 | int rc; | ||
979 | 980 | ||
980 | video_device_create_file(v4ldev, &class_device_attr_reg); | 981 | rc = video_device_create_file(v4ldev, &class_device_attr_reg); |
981 | video_device_create_file(v4ldev, &class_device_attr_val); | 982 | if (rc) goto err; |
983 | rc = video_device_create_file(v4ldev, &class_device_attr_val); | ||
984 | if (rc) goto err_reg; | ||
982 | if (cam->sensor.sysfs_ops) { | 985 | if (cam->sensor.sysfs_ops) { |
983 | video_device_create_file(v4ldev, &class_device_attr_i2c_reg); | 986 | rc = video_device_create_file(v4ldev, &class_device_attr_i2c_reg); |
984 | video_device_create_file(v4ldev, &class_device_attr_i2c_val); | 987 | if (rc) goto err_val; |
988 | rc = video_device_create_file(v4ldev, &class_device_attr_i2c_val); | ||
989 | if (rc) goto err_i2c_reg; | ||
985 | } | 990 | } |
991 | |||
992 | return 0; | ||
993 | |||
994 | err_i2c_reg: | ||
995 | video_device_remove_file(v4ldev, &class_device_attr_i2c_reg); | ||
996 | err_val: | ||
997 | video_device_remove_file(v4ldev, &class_device_attr_val); | ||
998 | err_reg: | ||
999 | video_device_remove_file(v4ldev, &class_device_attr_reg); | ||
1000 | err: | ||
1001 | return rc; | ||
986 | } | 1002 | } |
987 | #endif /* CONFIG_VIDEO_ADV_DEBUG */ | 1003 | #endif /* CONFIG_VIDEO_ADV_DEBUG */ |
988 | 1004 | ||
@@ -2534,7 +2550,9 @@ et61x251_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
2534 | dev_nr = (dev_nr < ET61X251_MAX_DEVICES-1) ? dev_nr+1 : 0; | 2550 | dev_nr = (dev_nr < ET61X251_MAX_DEVICES-1) ? dev_nr+1 : 0; |
2535 | 2551 | ||
2536 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 2552 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
2537 | et61x251_create_sysfs(cam); | 2553 | err = et61x251_create_sysfs(cam); |
2554 | if (err) | ||
2555 | goto fail2; | ||
2538 | DBG(2, "Optional device control through 'sysfs' interface ready"); | 2556 | DBG(2, "Optional device control through 'sysfs' interface ready"); |
2539 | #endif | 2557 | #endif |
2540 | 2558 | ||
@@ -2544,6 +2562,13 @@ et61x251_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
2544 | 2562 | ||
2545 | return 0; | 2563 | return 0; |
2546 | 2564 | ||
2565 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
2566 | fail2: | ||
2567 | video_nr[dev_nr] = -1; | ||
2568 | dev_nr = (dev_nr < ET61X251_MAX_DEVICES-1) ? dev_nr+1 : 0; | ||
2569 | mutex_unlock(&cam->dev_mutex); | ||
2570 | video_unregister_device(cam->v4ldev); | ||
2571 | #endif | ||
2547 | fail: | 2572 | fail: |
2548 | if (cam) { | 2573 | if (cam) { |
2549 | kfree(cam->control_buffer); | 2574 | kfree(cam->control_buffer); |
diff --git a/drivers/media/video/ov511.c b/drivers/media/video/ov511.c index ce4886f1528d..b4db2cbb5a84 100644 --- a/drivers/media/video/ov511.c +++ b/drivers/media/video/ov511.c | |||
@@ -5648,17 +5648,49 @@ static ssize_t show_exposure(struct class_device *cd, char *buf) | |||
5648 | } | 5648 | } |
5649 | static CLASS_DEVICE_ATTR(exposure, S_IRUGO, show_exposure, NULL); | 5649 | static CLASS_DEVICE_ATTR(exposure, S_IRUGO, show_exposure, NULL); |
5650 | 5650 | ||
5651 | static void ov_create_sysfs(struct video_device *vdev) | 5651 | static int ov_create_sysfs(struct video_device *vdev) |
5652 | { | 5652 | { |
5653 | video_device_create_file(vdev, &class_device_attr_custom_id); | 5653 | int rc; |
5654 | video_device_create_file(vdev, &class_device_attr_model); | 5654 | |
5655 | video_device_create_file(vdev, &class_device_attr_bridge); | 5655 | rc = video_device_create_file(vdev, &class_device_attr_custom_id); |
5656 | video_device_create_file(vdev, &class_device_attr_sensor); | 5656 | if (rc) goto err; |
5657 | video_device_create_file(vdev, &class_device_attr_brightness); | 5657 | rc = video_device_create_file(vdev, &class_device_attr_model); |
5658 | video_device_create_file(vdev, &class_device_attr_saturation); | 5658 | if (rc) goto err_id; |
5659 | video_device_create_file(vdev, &class_device_attr_contrast); | 5659 | rc = video_device_create_file(vdev, &class_device_attr_bridge); |
5660 | video_device_create_file(vdev, &class_device_attr_hue); | 5660 | if (rc) goto err_model; |
5661 | video_device_create_file(vdev, &class_device_attr_exposure); | 5661 | rc = video_device_create_file(vdev, &class_device_attr_sensor); |
5662 | if (rc) goto err_bridge; | ||
5663 | rc = video_device_create_file(vdev, &class_device_attr_brightness); | ||
5664 | if (rc) goto err_sensor; | ||
5665 | rc = video_device_create_file(vdev, &class_device_attr_saturation); | ||
5666 | if (rc) goto err_bright; | ||
5667 | rc = video_device_create_file(vdev, &class_device_attr_contrast); | ||
5668 | if (rc) goto err_sat; | ||
5669 | rc = video_device_create_file(vdev, &class_device_attr_hue); | ||
5670 | if (rc) goto err_contrast; | ||
5671 | rc = video_device_create_file(vdev, &class_device_attr_exposure); | ||
5672 | if (rc) goto err_hue; | ||
5673 | |||
5674 | return 0; | ||
5675 | |||
5676 | err_hue: | ||
5677 | video_device_remove_file(vdev, &class_device_attr_hue); | ||
5678 | err_contrast: | ||
5679 | video_device_remove_file(vdev, &class_device_attr_contrast); | ||
5680 | err_sat: | ||
5681 | video_device_remove_file(vdev, &class_device_attr_saturation); | ||
5682 | err_bright: | ||
5683 | video_device_remove_file(vdev, &class_device_attr_brightness); | ||
5684 | err_sensor: | ||
5685 | video_device_remove_file(vdev, &class_device_attr_sensor); | ||
5686 | err_bridge: | ||
5687 | video_device_remove_file(vdev, &class_device_attr_bridge); | ||
5688 | err_model: | ||
5689 | video_device_remove_file(vdev, &class_device_attr_model); | ||
5690 | err_id: | ||
5691 | video_device_remove_file(vdev, &class_device_attr_custom_id); | ||
5692 | err: | ||
5693 | return rc; | ||
5662 | } | 5694 | } |
5663 | 5695 | ||
5664 | /**************************************************************************** | 5696 | /**************************************************************************** |
@@ -5817,7 +5849,11 @@ ov51x_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
5817 | ov->vdev->minor); | 5849 | ov->vdev->minor); |
5818 | 5850 | ||
5819 | usb_set_intfdata(intf, ov); | 5851 | usb_set_intfdata(intf, ov); |
5820 | ov_create_sysfs(ov->vdev); | 5852 | if (ov_create_sysfs(ov->vdev)) { |
5853 | err("ov_create_sysfs failed"); | ||
5854 | goto error; | ||
5855 | } | ||
5856 | |||
5821 | return 0; | 5857 | return 0; |
5822 | 5858 | ||
5823 | error: | 5859 | error: |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c index df8feac16aee..c80c26be6e4d 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c +++ b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c | |||
@@ -221,7 +221,7 @@ static unsigned int decoder_describe(struct pvr2_v4l_cx2584x *ctxt, | |||
221 | static void decoder_reset(struct pvr2_v4l_cx2584x *ctxt) | 221 | static void decoder_reset(struct pvr2_v4l_cx2584x *ctxt) |
222 | { | 222 | { |
223 | int ret; | 223 | int ret; |
224 | ret = pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_RESET,0); | 224 | ret = pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_RESET,NULL); |
225 | pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx25840 decoder_reset (ret=%d)",ret); | 225 | pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx25840 decoder_reset (ret=%d)",ret); |
226 | } | 226 | } |
227 | 227 | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c index 97e974d9b9c3..bb40e9085977 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c +++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c | |||
@@ -711,8 +711,8 @@ static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip) | |||
711 | dip->devbase.minor,pvr2_config_get_name(dip->config)); | 711 | dip->devbase.minor,pvr2_config_get_name(dip->config)); |
712 | 712 | ||
713 | /* Paranoia */ | 713 | /* Paranoia */ |
714 | dip->v4lp = 0; | 714 | dip->v4lp = NULL; |
715 | dip->stream = 0; | 715 | dip->stream = NULL; |
716 | 716 | ||
717 | /* Actual deallocation happens later when all internal references | 717 | /* Actual deallocation happens later when all internal references |
718 | are gone. */ | 718 | are gone. */ |
@@ -1076,7 +1076,7 @@ struct pvr2_v4l2 *pvr2_v4l2_create(struct pvr2_context *mnp) | |||
1076 | vp->vdev = kmalloc(sizeof(*vp->vdev),GFP_KERNEL); | 1076 | vp->vdev = kmalloc(sizeof(*vp->vdev),GFP_KERNEL); |
1077 | if (!vp->vdev) { | 1077 | if (!vp->vdev) { |
1078 | kfree(vp); | 1078 | kfree(vp); |
1079 | return 0; | 1079 | return NULL; |
1080 | } | 1080 | } |
1081 | memset(vp->vdev,0,sizeof(*vp->vdev)); | 1081 | memset(vp->vdev,0,sizeof(*vp->vdev)); |
1082 | pvr2_channel_init(&vp->channel,mnp); | 1082 | pvr2_channel_init(&vp->channel,mnp); |
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c index c77b85cf3d80..46c114830884 100644 --- a/drivers/media/video/pwc/pwc-if.c +++ b/drivers/media/video/pwc/pwc-if.c | |||
@@ -1024,12 +1024,25 @@ static ssize_t show_snapshot_button_status(struct class_device *class_dev, char | |||
1024 | static CLASS_DEVICE_ATTR(button, S_IRUGO | S_IWUSR, show_snapshot_button_status, | 1024 | static CLASS_DEVICE_ATTR(button, S_IRUGO | S_IWUSR, show_snapshot_button_status, |
1025 | NULL); | 1025 | NULL); |
1026 | 1026 | ||
1027 | static void pwc_create_sysfs_files(struct video_device *vdev) | 1027 | static int pwc_create_sysfs_files(struct video_device *vdev) |
1028 | { | 1028 | { |
1029 | struct pwc_device *pdev = video_get_drvdata(vdev); | 1029 | struct pwc_device *pdev = video_get_drvdata(vdev); |
1030 | if (pdev->features & FEATURE_MOTOR_PANTILT) | 1030 | int rc; |
1031 | video_device_create_file(vdev, &class_device_attr_pan_tilt); | 1031 | |
1032 | video_device_create_file(vdev, &class_device_attr_button); | 1032 | rc = video_device_create_file(vdev, &class_device_attr_button); |
1033 | if (rc) | ||
1034 | goto err; | ||
1035 | if (pdev->features & FEATURE_MOTOR_PANTILT) { | ||
1036 | rc = video_device_create_file(vdev,&class_device_attr_pan_tilt); | ||
1037 | if (rc) goto err_button; | ||
1038 | } | ||
1039 | |||
1040 | return 0; | ||
1041 | |||
1042 | err_button: | ||
1043 | video_device_remove_file(vdev, &class_device_attr_button); | ||
1044 | err: | ||
1045 | return rc; | ||
1033 | } | 1046 | } |
1034 | 1047 | ||
1035 | static void pwc_remove_sysfs_files(struct video_device *vdev) | 1048 | static void pwc_remove_sysfs_files(struct video_device *vdev) |
@@ -1408,7 +1421,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
1408 | struct usb_device *udev = interface_to_usbdev(intf); | 1421 | struct usb_device *udev = interface_to_usbdev(intf); |
1409 | struct pwc_device *pdev = NULL; | 1422 | struct pwc_device *pdev = NULL; |
1410 | int vendor_id, product_id, type_id; | 1423 | int vendor_id, product_id, type_id; |
1411 | int i, hint; | 1424 | int i, hint, rc; |
1412 | int features = 0; | 1425 | int features = 0; |
1413 | int video_nr = -1; /* default: use next available device */ | 1426 | int video_nr = -1; /* default: use next available device */ |
1414 | char serial_number[30], *name; | 1427 | char serial_number[30], *name; |
@@ -1709,9 +1722,8 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
1709 | i = video_register_device(pdev->vdev, VFL_TYPE_GRABBER, video_nr); | 1722 | i = video_register_device(pdev->vdev, VFL_TYPE_GRABBER, video_nr); |
1710 | if (i < 0) { | 1723 | if (i < 0) { |
1711 | PWC_ERROR("Failed to register as video device (%d).\n", i); | 1724 | PWC_ERROR("Failed to register as video device (%d).\n", i); |
1712 | video_device_release(pdev->vdev); /* Drip... drip... drip... */ | 1725 | rc = i; |
1713 | kfree(pdev); /* Oops, no memory leaks please */ | 1726 | goto err; |
1714 | return -EIO; | ||
1715 | } | 1727 | } |
1716 | else { | 1728 | else { |
1717 | PWC_INFO("Registered as /dev/video%d.\n", pdev->vdev->minor & 0x3F); | 1729 | PWC_INFO("Registered as /dev/video%d.\n", pdev->vdev->minor & 0x3F); |
@@ -1723,13 +1735,24 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
1723 | 1735 | ||
1724 | PWC_DEBUG_PROBE("probe() function returning struct at 0x%p.\n", pdev); | 1736 | PWC_DEBUG_PROBE("probe() function returning struct at 0x%p.\n", pdev); |
1725 | usb_set_intfdata (intf, pdev); | 1737 | usb_set_intfdata (intf, pdev); |
1726 | pwc_create_sysfs_files(pdev->vdev); | 1738 | rc = pwc_create_sysfs_files(pdev->vdev); |
1739 | if (rc) | ||
1740 | goto err_unreg; | ||
1727 | 1741 | ||
1728 | /* Set the leds off */ | 1742 | /* Set the leds off */ |
1729 | pwc_set_leds(pdev, 0, 0); | 1743 | pwc_set_leds(pdev, 0, 0); |
1730 | pwc_camera_power(pdev, 0); | 1744 | pwc_camera_power(pdev, 0); |
1731 | 1745 | ||
1732 | return 0; | 1746 | return 0; |
1747 | |||
1748 | err_unreg: | ||
1749 | if (hint < MAX_DEV_HINTS) | ||
1750 | device_hint[hint].pdev = NULL; | ||
1751 | video_unregister_device(pdev->vdev); | ||
1752 | err: | ||
1753 | video_device_release(pdev->vdev); /* Drip... drip... drip... */ | ||
1754 | kfree(pdev); /* Oops, no memory leaks please */ | ||
1755 | return rc; | ||
1733 | } | 1756 | } |
1734 | 1757 | ||
1735 | /* The user janked out the cable... */ | 1758 | /* The user janked out the cable... */ |
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c index 974179d4d389..c5719f7bd1ac 100644 --- a/drivers/media/video/saa7115.c +++ b/drivers/media/video/saa7115.c | |||
@@ -960,6 +960,8 @@ static void saa711x_set_v4lstd(struct i2c_client *client, v4l2_std_id std) | |||
960 | reg |= 0x10; | 960 | reg |= 0x10; |
961 | } else if (std == V4L2_STD_NTSC_M_JP) { | 961 | } else if (std == V4L2_STD_NTSC_M_JP) { |
962 | reg |= 0x40; | 962 | reg |= 0x40; |
963 | } else if (std == V4L2_STD_SECAM) { | ||
964 | reg |= 0x50; | ||
963 | } | 965 | } |
964 | saa711x_write(client, R_0E_CHROMA_CNTL_1, reg); | 966 | saa711x_write(client, R_0E_CHROMA_CNTL_1, reg); |
965 | } else { | 967 | } else { |
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index c9d8e3b9cc37..51f0cfdcb680 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c | |||
@@ -2969,7 +2969,7 @@ struct saa7134_board saa7134_boards[] = { | |||
2969 | /* Petr Baudis <pasky@ucw.cz> */ | 2969 | /* Petr Baudis <pasky@ucw.cz> */ |
2970 | .name = "AVerMedia TV Hybrid A16AR", | 2970 | .name = "AVerMedia TV Hybrid A16AR", |
2971 | .audio_clock = 0x187de7, | 2971 | .audio_clock = 0x187de7, |
2972 | .tuner_type = TUNER_PHILIPS_TDA8290, /* untested */ | 2972 | .tuner_type = TUNER_PHILIPS_TD1316, /* untested */ |
2973 | .radio_type = TUNER_TEA5767, /* untested */ | 2973 | .radio_type = TUNER_TEA5767, /* untested */ |
2974 | .tuner_addr = ADDR_UNSET, | 2974 | .tuner_addr = ADDR_UNSET, |
2975 | .radio_addr = ADDR_UNSET, | 2975 | .radio_addr = ADDR_UNSET, |
@@ -3718,6 +3718,7 @@ int saa7134_board_init1(struct saa7134_dev *dev) | |||
3718 | case SAA7134_BOARD_AVERMEDIA_STUDIO_307: | 3718 | case SAA7134_BOARD_AVERMEDIA_STUDIO_307: |
3719 | case SAA7134_BOARD_AVERMEDIA_307: | 3719 | case SAA7134_BOARD_AVERMEDIA_307: |
3720 | case SAA7134_BOARD_AVERMEDIA_GO_007_FM: | 3720 | case SAA7134_BOARD_AVERMEDIA_GO_007_FM: |
3721 | case SAA7134_BOARD_AVERMEDIA_777: | ||
3721 | /* case SAA7134_BOARD_SABRENT_SBTTVFM: */ /* not finished yet */ | 3722 | /* case SAA7134_BOARD_SABRENT_SBTTVFM: */ /* not finished yet */ |
3722 | case SAA7134_BOARD_VIDEOMATE_TV_PVR: | 3723 | case SAA7134_BOARD_VIDEOMATE_TV_PVR: |
3723 | case SAA7134_BOARD_VIDEOMATE_GOLD_PLUS: | 3724 | case SAA7134_BOARD_VIDEOMATE_GOLD_PLUS: |
@@ -3734,6 +3735,7 @@ int saa7134_board_init1(struct saa7134_dev *dev) | |||
3734 | case SAA7134_BOARD_FLYDVBT_LR301: | 3735 | case SAA7134_BOARD_FLYDVBT_LR301: |
3735 | case SAA7134_BOARD_FLYDVBTDUO: | 3736 | case SAA7134_BOARD_FLYDVBTDUO: |
3736 | case SAA7134_BOARD_PROTEUS_2309: | 3737 | case SAA7134_BOARD_PROTEUS_2309: |
3738 | case SAA7134_BOARD_AVERMEDIA_A16AR: | ||
3737 | dev->has_remote = SAA7134_REMOTE_GPIO; | 3739 | dev->has_remote = SAA7134_REMOTE_GPIO; |
3738 | break; | 3740 | break; |
3739 | case SAA7134_BOARD_FLYDVBS_LR300: | 3741 | case SAA7134_BOARD_FLYDVBS_LR300: |
@@ -3772,7 +3774,6 @@ int saa7134_board_init1(struct saa7134_dev *dev) | |||
3772 | saa_writeb(SAA7134_GPIO_GPMODE3, 0x08); | 3774 | saa_writeb(SAA7134_GPIO_GPMODE3, 0x08); |
3773 | saa_writeb(SAA7134_GPIO_GPSTATUS3, 0x00); | 3775 | saa_writeb(SAA7134_GPIO_GPSTATUS3, 0x00); |
3774 | break; | 3776 | break; |
3775 | case SAA7134_BOARD_AVERMEDIA_A16AR: | ||
3776 | case SAA7134_BOARD_AVERMEDIA_CARDBUS: | 3777 | case SAA7134_BOARD_AVERMEDIA_CARDBUS: |
3777 | /* power-up tuner chip */ | 3778 | /* power-up tuner chip */ |
3778 | saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0xffffffff, 0xffffffff); | 3779 | saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0xffffffff, 0xffffffff); |
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c index 1ba53b525ad2..6b61d9b2fcb5 100644 --- a/drivers/media/video/saa7134/saa7134-dvb.c +++ b/drivers/media/video/saa7134/saa7134-dvb.c | |||
@@ -1147,6 +1147,8 @@ static int dvb_init(struct saa7134_dev *dev) | |||
1147 | &philips_europa_config, | 1147 | &philips_europa_config, |
1148 | &dev->i2c_adap); | 1148 | &dev->i2c_adap); |
1149 | if (dev->dvb.frontend) { | 1149 | if (dev->dvb.frontend) { |
1150 | dev->original_demod_sleep = dev->dvb.frontend->ops.sleep; | ||
1151 | dev->dvb.frontend->ops.sleep = philips_europa_demod_sleep; | ||
1150 | dev->dvb.frontend->ops.tuner_ops.init = philips_europa_tuner_init; | 1152 | dev->dvb.frontend->ops.tuner_ops.init = philips_europa_tuner_init; |
1151 | dev->dvb.frontend->ops.tuner_ops.sleep = philips_europa_tuner_sleep; | 1153 | dev->dvb.frontend->ops.tuner_ops.sleep = philips_europa_tuner_sleep; |
1152 | dev->dvb.frontend->ops.tuner_ops.set_params = philips_td1316_tuner_set_params; | 1154 | dev->dvb.frontend->ops.tuner_ops.set_params = philips_td1316_tuner_set_params; |
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index ff5991136f4e..dee83552e681 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c | |||
@@ -185,7 +185,6 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
185 | case SAA7134_BOARD_AVERMEDIA_STUDIO_305: | 185 | case SAA7134_BOARD_AVERMEDIA_STUDIO_305: |
186 | case SAA7134_BOARD_AVERMEDIA_STUDIO_307: | 186 | case SAA7134_BOARD_AVERMEDIA_STUDIO_307: |
187 | case SAA7134_BOARD_AVERMEDIA_GO_007_FM: | 187 | case SAA7134_BOARD_AVERMEDIA_GO_007_FM: |
188 | case SAA7134_BOARD_AVERMEDIA_A16AR: | ||
189 | ir_codes = ir_codes_avermedia; | 188 | ir_codes = ir_codes_avermedia; |
190 | mask_keycode = 0x0007C8; | 189 | mask_keycode = 0x0007C8; |
191 | mask_keydown = 0x000010; | 190 | mask_keydown = 0x000010; |
@@ -194,6 +193,16 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
194 | saa_setb(SAA7134_GPIO_GPMODE0, 0x4); | 193 | saa_setb(SAA7134_GPIO_GPMODE0, 0x4); |
195 | saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4); | 194 | saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4); |
196 | break; | 195 | break; |
196 | case SAA7134_BOARD_AVERMEDIA_777: | ||
197 | case SAA7134_BOARD_AVERMEDIA_A16AR: | ||
198 | ir_codes = ir_codes_avermedia; | ||
199 | mask_keycode = 0x02F200; | ||
200 | mask_keydown = 0x000400; | ||
201 | polling = 50; // ms | ||
202 | /* Without this we won't receive key up events */ | ||
203 | saa_setb(SAA7134_GPIO_GPMODE1, 0x1); | ||
204 | saa_setb(SAA7134_GPIO_GPSTATUS1, 0x1); | ||
205 | break; | ||
197 | case SAA7134_BOARD_KWORLD_TERMINATOR: | 206 | case SAA7134_BOARD_KWORLD_TERMINATOR: |
198 | ir_codes = ir_codes_pixelview; | 207 | ir_codes = ir_codes_pixelview; |
199 | mask_keycode = 0x00001f; | 208 | mask_keycode = 0x00001f; |
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c index 203302f21827..830617ea81cc 100644 --- a/drivers/media/video/saa7134/saa7134-video.c +++ b/drivers/media/video/saa7134/saa7134-video.c | |||
@@ -2248,7 +2248,11 @@ static int radio_do_ioctl(struct inode *inode, struct file *file, | |||
2248 | t->type = V4L2_TUNER_RADIO; | 2248 | t->type = V4L2_TUNER_RADIO; |
2249 | 2249 | ||
2250 | saa7134_i2c_call_clients(dev, VIDIOC_G_TUNER, t); | 2250 | saa7134_i2c_call_clients(dev, VIDIOC_G_TUNER, t); |
2251 | 2251 | if (dev->input->amux == TV) { | |
2252 | t->signal = 0xf800 - ((saa_readb(0x581) & 0x1f) << 11); | ||
2253 | t->rxsubchans = (saa_readb(0x529) & 0x08) ? | ||
2254 | V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO; | ||
2255 | } | ||
2252 | return 0; | 2256 | return 0; |
2253 | } | 2257 | } |
2254 | case VIDIOC_S_TUNER: | 2258 | case VIDIOC_S_TUNER: |
diff --git a/drivers/media/video/sn9c102/sn9c102_core.c b/drivers/media/video/sn9c102/sn9c102_core.c index 3e0ff8a78468..a4702d3c2aca 100644 --- a/drivers/media/video/sn9c102/sn9c102_core.c +++ b/drivers/media/video/sn9c102/sn9c102_core.c | |||
@@ -1240,23 +1240,53 @@ static CLASS_DEVICE_ATTR(frame_header, S_IRUGO, | |||
1240 | sn9c102_show_frame_header, NULL); | 1240 | sn9c102_show_frame_header, NULL); |
1241 | 1241 | ||
1242 | 1242 | ||
1243 | static void sn9c102_create_sysfs(struct sn9c102_device* cam) | 1243 | static int sn9c102_create_sysfs(struct sn9c102_device* cam) |
1244 | { | 1244 | { |
1245 | struct video_device *v4ldev = cam->v4ldev; | 1245 | struct video_device *v4ldev = cam->v4ldev; |
1246 | int rc; | ||
1247 | |||
1248 | rc = video_device_create_file(v4ldev, &class_device_attr_reg); | ||
1249 | if (rc) goto err; | ||
1250 | rc = video_device_create_file(v4ldev, &class_device_attr_val); | ||
1251 | if (rc) goto err_reg; | ||
1252 | rc = video_device_create_file(v4ldev, &class_device_attr_frame_header); | ||
1253 | if (rc) goto err_val; | ||
1246 | 1254 | ||
1247 | video_device_create_file(v4ldev, &class_device_attr_reg); | ||
1248 | video_device_create_file(v4ldev, &class_device_attr_val); | ||
1249 | video_device_create_file(v4ldev, &class_device_attr_frame_header); | ||
1250 | if (cam->bridge == BRIDGE_SN9C101 || cam->bridge == BRIDGE_SN9C102) | ||
1251 | video_device_create_file(v4ldev, &class_device_attr_green); | ||
1252 | else if (cam->bridge == BRIDGE_SN9C103) { | ||
1253 | video_device_create_file(v4ldev, &class_device_attr_blue); | ||
1254 | video_device_create_file(v4ldev, &class_device_attr_red); | ||
1255 | } | ||
1256 | if (cam->sensor.sysfs_ops) { | 1255 | if (cam->sensor.sysfs_ops) { |
1257 | video_device_create_file(v4ldev, &class_device_attr_i2c_reg); | 1256 | rc = video_device_create_file(v4ldev, &class_device_attr_i2c_reg); |
1258 | video_device_create_file(v4ldev, &class_device_attr_i2c_val); | 1257 | if (rc) goto err_frhead; |
1258 | rc = video_device_create_file(v4ldev, &class_device_attr_i2c_val); | ||
1259 | if (rc) goto err_i2c_reg; | ||
1260 | } | ||
1261 | |||
1262 | if (cam->bridge == BRIDGE_SN9C101 || cam->bridge == BRIDGE_SN9C102) { | ||
1263 | rc = video_device_create_file(v4ldev, &class_device_attr_green); | ||
1264 | if (rc) goto err_i2c_val; | ||
1265 | } else if (cam->bridge == BRIDGE_SN9C103) { | ||
1266 | rc = video_device_create_file(v4ldev, &class_device_attr_blue); | ||
1267 | if (rc) goto err_i2c_val; | ||
1268 | rc = video_device_create_file(v4ldev, &class_device_attr_red); | ||
1269 | if (rc) goto err_blue; | ||
1259 | } | 1270 | } |
1271 | |||
1272 | return 0; | ||
1273 | |||
1274 | err_blue: | ||
1275 | video_device_remove_file(v4ldev, &class_device_attr_blue); | ||
1276 | err_i2c_val: | ||
1277 | if (cam->sensor.sysfs_ops) | ||
1278 | video_device_remove_file(v4ldev, &class_device_attr_i2c_val); | ||
1279 | err_i2c_reg: | ||
1280 | if (cam->sensor.sysfs_ops) | ||
1281 | video_device_remove_file(v4ldev, &class_device_attr_i2c_reg); | ||
1282 | err_frhead: | ||
1283 | video_device_remove_file(v4ldev, &class_device_attr_frame_header); | ||
1284 | err_val: | ||
1285 | video_device_remove_file(v4ldev, &class_device_attr_val); | ||
1286 | err_reg: | ||
1287 | video_device_remove_file(v4ldev, &class_device_attr_reg); | ||
1288 | err: | ||
1289 | return rc; | ||
1260 | } | 1290 | } |
1261 | #endif /* CONFIG_VIDEO_ADV_DEBUG */ | 1291 | #endif /* CONFIG_VIDEO_ADV_DEBUG */ |
1262 | 1292 | ||
@@ -2809,10 +2839,7 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
2809 | DBG(1, "V4L2 device registration failed"); | 2839 | DBG(1, "V4L2 device registration failed"); |
2810 | if (err == -ENFILE && video_nr[dev_nr] == -1) | 2840 | if (err == -ENFILE && video_nr[dev_nr] == -1) |
2811 | DBG(1, "Free /dev/videoX node not found"); | 2841 | DBG(1, "Free /dev/videoX node not found"); |
2812 | video_nr[dev_nr] = -1; | 2842 | goto fail2; |
2813 | dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0; | ||
2814 | mutex_unlock(&cam->dev_mutex); | ||
2815 | goto fail; | ||
2816 | } | 2843 | } |
2817 | 2844 | ||
2818 | DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->minor); | 2845 | DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->minor); |
@@ -2823,7 +2850,9 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
2823 | dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0; | 2850 | dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0; |
2824 | 2851 | ||
2825 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 2852 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
2826 | sn9c102_create_sysfs(cam); | 2853 | err = sn9c102_create_sysfs(cam); |
2854 | if (err) | ||
2855 | goto fail3; | ||
2827 | DBG(2, "Optional device control through 'sysfs' interface ready"); | 2856 | DBG(2, "Optional device control through 'sysfs' interface ready"); |
2828 | #endif | 2857 | #endif |
2829 | 2858 | ||
@@ -2833,6 +2862,14 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
2833 | 2862 | ||
2834 | return 0; | 2863 | return 0; |
2835 | 2864 | ||
2865 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
2866 | fail3: | ||
2867 | video_unregister_device(cam->v4ldev); | ||
2868 | #endif | ||
2869 | fail2: | ||
2870 | video_nr[dev_nr] = -1; | ||
2871 | dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0; | ||
2872 | mutex_unlock(&cam->dev_mutex); | ||
2836 | fail: | 2873 | fail: |
2837 | if (cam) { | 2874 | if (cam) { |
2838 | kfree(cam->control_buffer); | 2875 | kfree(cam->control_buffer); |
diff --git a/drivers/media/video/stv680.c b/drivers/media/video/stv680.c index 87e11300181d..6d1ef1e2e8ef 100644 --- a/drivers/media/video/stv680.c +++ b/drivers/media/video/stv680.c | |||
@@ -516,16 +516,45 @@ stv680_file(frames_read, framecount, "%d\n"); | |||
516 | stv680_file(packets_dropped, dropped, "%d\n"); | 516 | stv680_file(packets_dropped, dropped, "%d\n"); |
517 | stv680_file(decoding_errors, error, "%d\n"); | 517 | stv680_file(decoding_errors, error, "%d\n"); |
518 | 518 | ||
519 | static void stv680_create_sysfs_files(struct video_device *vdev) | 519 | static int stv680_create_sysfs_files(struct video_device *vdev) |
520 | { | 520 | { |
521 | video_device_create_file(vdev, &class_device_attr_model); | 521 | int rc; |
522 | video_device_create_file(vdev, &class_device_attr_in_use); | 522 | |
523 | video_device_create_file(vdev, &class_device_attr_streaming); | 523 | rc = video_device_create_file(vdev, &class_device_attr_model); |
524 | video_device_create_file(vdev, &class_device_attr_palette); | 524 | if (rc) goto err; |
525 | video_device_create_file(vdev, &class_device_attr_frames_total); | 525 | rc = video_device_create_file(vdev, &class_device_attr_in_use); |
526 | video_device_create_file(vdev, &class_device_attr_frames_read); | 526 | if (rc) goto err_model; |
527 | video_device_create_file(vdev, &class_device_attr_packets_dropped); | 527 | rc = video_device_create_file(vdev, &class_device_attr_streaming); |
528 | video_device_create_file(vdev, &class_device_attr_decoding_errors); | 528 | if (rc) goto err_inuse; |
529 | rc = video_device_create_file(vdev, &class_device_attr_palette); | ||
530 | if (rc) goto err_stream; | ||
531 | rc = video_device_create_file(vdev, &class_device_attr_frames_total); | ||
532 | if (rc) goto err_pal; | ||
533 | rc = video_device_create_file(vdev, &class_device_attr_frames_read); | ||
534 | if (rc) goto err_framtot; | ||
535 | rc = video_device_create_file(vdev, &class_device_attr_packets_dropped); | ||
536 | if (rc) goto err_framread; | ||
537 | rc = video_device_create_file(vdev, &class_device_attr_decoding_errors); | ||
538 | if (rc) goto err_dropped; | ||
539 | |||
540 | return 0; | ||
541 | |||
542 | err_dropped: | ||
543 | video_device_remove_file(vdev, &class_device_attr_packets_dropped); | ||
544 | err_framread: | ||
545 | video_device_remove_file(vdev, &class_device_attr_frames_read); | ||
546 | err_framtot: | ||
547 | video_device_remove_file(vdev, &class_device_attr_frames_total); | ||
548 | err_pal: | ||
549 | video_device_remove_file(vdev, &class_device_attr_palette); | ||
550 | err_stream: | ||
551 | video_device_remove_file(vdev, &class_device_attr_streaming); | ||
552 | err_inuse: | ||
553 | video_device_remove_file(vdev, &class_device_attr_in_use); | ||
554 | err_model: | ||
555 | video_device_remove_file(vdev, &class_device_attr_model); | ||
556 | err: | ||
557 | return rc; | ||
529 | } | 558 | } |
530 | 559 | ||
531 | static void stv680_remove_sysfs_files(struct video_device *vdev) | 560 | static void stv680_remove_sysfs_files(struct video_device *vdev) |
@@ -1418,9 +1447,13 @@ static int stv680_probe (struct usb_interface *intf, const struct usb_device_id | |||
1418 | PDEBUG (0, "STV(i): registered new video device: video%d", stv680->vdev->minor); | 1447 | PDEBUG (0, "STV(i): registered new video device: video%d", stv680->vdev->minor); |
1419 | 1448 | ||
1420 | usb_set_intfdata (intf, stv680); | 1449 | usb_set_intfdata (intf, stv680); |
1421 | stv680_create_sysfs_files(stv680->vdev); | 1450 | retval = stv680_create_sysfs_files(stv680->vdev); |
1451 | if (retval) | ||
1452 | goto error_unreg; | ||
1422 | return 0; | 1453 | return 0; |
1423 | 1454 | ||
1455 | error_unreg: | ||
1456 | video_unregister_device(stv680->vdev); | ||
1424 | error_vdev: | 1457 | error_vdev: |
1425 | video_device_release(stv680->vdev); | 1458 | video_device_release(stv680->vdev); |
1426 | error: | 1459 | error: |
diff --git a/drivers/media/video/tuner-types.c b/drivers/media/video/tuner-types.c index 8fff642fad56..781682373b61 100644 --- a/drivers/media/video/tuner-types.c +++ b/drivers/media/video/tuner-types.c | |||
@@ -1046,7 +1046,6 @@ static struct tuner_params tuner_samsung_tcpn_2121p30a_params[] = { | |||
1046 | .type = TUNER_PARAM_TYPE_NTSC, | 1046 | .type = TUNER_PARAM_TYPE_NTSC, |
1047 | .ranges = tuner_samsung_tcpn_2121p30a_ntsc_ranges, | 1047 | .ranges = tuner_samsung_tcpn_2121p30a_ntsc_ranges, |
1048 | .count = ARRAY_SIZE(tuner_samsung_tcpn_2121p30a_ntsc_ranges), | 1048 | .count = ARRAY_SIZE(tuner_samsung_tcpn_2121p30a_ntsc_ranges), |
1049 | .has_tda9887 = 1, | ||
1050 | }, | 1049 | }, |
1051 | }; | 1050 | }; |
1052 | 1051 | ||
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c index e6baaee038bf..6b9ef731b83a 100644 --- a/drivers/media/video/tveeprom.c +++ b/drivers/media/video/tveeprom.c | |||
@@ -468,7 +468,7 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, | |||
468 | (eeprom_data[i+6] << 8) + | 468 | (eeprom_data[i+6] << 8) + |
469 | (eeprom_data[i+7] << 16); | 469 | (eeprom_data[i+7] << 16); |
470 | 470 | ||
471 | if ( (eeprom_data[i + 8] && 0xf0) && | 471 | if ( (eeprom_data[i + 8] & 0xf0) && |
472 | (tvee->serial_number < 0xffffff) ) { | 472 | (tvee->serial_number < 0xffffff) ) { |
473 | tvee->MAC_address[0] = 0x00; | 473 | tvee->MAC_address[0] = 0x00; |
474 | tvee->MAC_address[1] = 0x0D; | 474 | tvee->MAC_address[1] = 0x0D; |
diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c index 479a0675cf60..d424a4129d69 100644 --- a/drivers/media/video/videodev.c +++ b/drivers/media/video/videodev.c | |||
@@ -17,10 +17,11 @@ | |||
17 | */ | 17 | */ |
18 | 18 | ||
19 | #define dbgarg(cmd, fmt, arg...) \ | 19 | #define dbgarg(cmd, fmt, arg...) \ |
20 | if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) \ | 20 | if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) { \ |
21 | printk (KERN_DEBUG "%s: ", vfd->name); \ | 21 | printk (KERN_DEBUG "%s: ", vfd->name); \ |
22 | v4l_printk_ioctl(cmd); \ | 22 | v4l_printk_ioctl(cmd); \ |
23 | printk (KERN_DEBUG "%s: " fmt, vfd->name, ## arg); | 23 | printk (KERN_DEBUG "%s: " fmt, vfd->name, ## arg); \ |
24 | } | ||
24 | 25 | ||
25 | #define dbgarg2(fmt, arg...) \ | 26 | #define dbgarg2(fmt, arg...) \ |
26 | if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) \ | 27 | if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) \ |
@@ -1287,6 +1288,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, | |||
1287 | ret=vfd->vidioc_g_parm(file, fh, p); | 1288 | ret=vfd->vidioc_g_parm(file, fh, p); |
1288 | } else { | 1289 | } else { |
1289 | struct v4l2_standard s; | 1290 | struct v4l2_standard s; |
1291 | int i; | ||
1290 | 1292 | ||
1291 | if (!vfd->tvnormsize) { | 1293 | if (!vfd->tvnormsize) { |
1292 | printk (KERN_WARNING "%s: no TV norms defined!\n", | 1294 | printk (KERN_WARNING "%s: no TV norms defined!\n", |
@@ -1297,8 +1299,14 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, | |||
1297 | if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 1299 | if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
1298 | return -EINVAL; | 1300 | return -EINVAL; |
1299 | 1301 | ||
1300 | v4l2_video_std_construct(&s, vfd->tvnorms[vfd->current_norm].id, | 1302 | for (i = 0; i < vfd->tvnormsize; i++) |
1301 | vfd->tvnorms[vfd->current_norm].name); | 1303 | if (vfd->tvnorms[i].id == vfd->current_norm) |
1304 | break; | ||
1305 | if (i >= vfd->tvnormsize) | ||
1306 | return -EINVAL; | ||
1307 | |||
1308 | v4l2_video_std_construct(&s, vfd->current_norm, | ||
1309 | vfd->tvnorms[i].name); | ||
1302 | 1310 | ||
1303 | memset(p,0,sizeof(*p)); | 1311 | memset(p,0,sizeof(*p)); |
1304 | 1312 | ||
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c index e7c01d560b64..3c8dc72dc8e9 100644 --- a/drivers/media/video/vivi.c +++ b/drivers/media/video/vivi.c | |||
@@ -272,7 +272,7 @@ static void gen_line(struct sg_to_addr to_addr[],int inipos,int pages,int wmax, | |||
272 | 272 | ||
273 | /* Get first addr pointed to pixel position */ | 273 | /* Get first addr pointed to pixel position */ |
274 | oldpg=get_addr_pos(pos,pages,to_addr); | 274 | oldpg=get_addr_pos(pos,pages,to_addr); |
275 | pg=pfn_to_page(to_addr[oldpg].sg->dma_address >> PAGE_SHIFT); | 275 | pg=pfn_to_page(sg_dma_address(to_addr[oldpg].sg) >> PAGE_SHIFT); |
276 | basep = kmap_atomic(pg, KM_BOUNCE_READ)+to_addr[oldpg].sg->offset; | 276 | basep = kmap_atomic(pg, KM_BOUNCE_READ)+to_addr[oldpg].sg->offset; |
277 | 277 | ||
278 | /* We will just duplicate the second pixel at the packet */ | 278 | /* We will just duplicate the second pixel at the packet */ |
@@ -287,7 +287,7 @@ static void gen_line(struct sg_to_addr to_addr[],int inipos,int pages,int wmax, | |||
287 | for (color=0;color<4;color++) { | 287 | for (color=0;color<4;color++) { |
288 | pgpos=get_addr_pos(pos,pages,to_addr); | 288 | pgpos=get_addr_pos(pos,pages,to_addr); |
289 | if (pgpos!=oldpg) { | 289 | if (pgpos!=oldpg) { |
290 | pg=pfn_to_page(to_addr[pgpos].sg->dma_address >> PAGE_SHIFT); | 290 | pg=pfn_to_page(sg_dma_address(to_addr[pgpos].sg) >> PAGE_SHIFT); |
291 | kunmap_atomic(basep, KM_BOUNCE_READ); | 291 | kunmap_atomic(basep, KM_BOUNCE_READ); |
292 | basep= kmap_atomic(pg, KM_BOUNCE_READ)+to_addr[pgpos].sg->offset; | 292 | basep= kmap_atomic(pg, KM_BOUNCE_READ)+to_addr[pgpos].sg->offset; |
293 | oldpg=pgpos; | 293 | oldpg=pgpos; |
@@ -339,8 +339,8 @@ static void gen_line(struct sg_to_addr to_addr[],int inipos,int pages,int wmax, | |||
339 | for (color=0;color<4;color++) { | 339 | for (color=0;color<4;color++) { |
340 | pgpos=get_addr_pos(pos,pages,to_addr); | 340 | pgpos=get_addr_pos(pos,pages,to_addr); |
341 | if (pgpos!=oldpg) { | 341 | if (pgpos!=oldpg) { |
342 | pg=pfn_to_page(to_addr[pgpos]. | 342 | pg=pfn_to_page(sg_dma_address( |
343 | sg->dma_address | 343 | to_addr[pgpos].sg) |
344 | >> PAGE_SHIFT); | 344 | >> PAGE_SHIFT); |
345 | kunmap_atomic(basep, | 345 | kunmap_atomic(basep, |
346 | KM_BOUNCE_READ); | 346 | KM_BOUNCE_READ); |
@@ -386,7 +386,7 @@ static void vivi_fillbuff(struct vivi_dev *dev,struct vivi_buffer *buf) | |||
386 | struct timeval ts; | 386 | struct timeval ts; |
387 | 387 | ||
388 | /* Test if DMA mapping is ready */ | 388 | /* Test if DMA mapping is ready */ |
389 | if (!vb->dma.sglist[0].dma_address) | 389 | if (!sg_dma_address(&vb->dma.sglist[0])) |
390 | return; | 390 | return; |
391 | 391 | ||
392 | prep_to_addr(to_addr,vb); | 392 | prep_to_addr(to_addr,vb); |
@@ -783,7 +783,7 @@ static int vivi_map_sg(void *dev, struct scatterlist *sg, int nents, | |||
783 | for (i = 0; i < nents; i++ ) { | 783 | for (i = 0; i < nents; i++ ) { |
784 | BUG_ON(!sg[i].page); | 784 | BUG_ON(!sg[i].page); |
785 | 785 | ||
786 | sg[i].dma_address = page_to_phys(sg[i].page) + sg[i].offset; | 786 | sg_dma_address(&sg[i]) = page_to_phys(sg[i].page) + sg[i].offset; |
787 | } | 787 | } |
788 | 788 | ||
789 | return nents; | 789 | return nents; |
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index c537d71c18e4..a4afad4ecab2 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h | |||
@@ -75,8 +75,8 @@ | |||
75 | #define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR | 75 | #define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR |
76 | #endif | 76 | #endif |
77 | 77 | ||
78 | #define MPT_LINUX_VERSION_COMMON "3.04.01" | 78 | #define MPT_LINUX_VERSION_COMMON "3.04.02" |
79 | #define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.01" | 79 | #define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.02" |
80 | #define WHAT_MAGIC_STRING "@" "(" "#" ")" | 80 | #define WHAT_MAGIC_STRING "@" "(" "#" ")" |
81 | 81 | ||
82 | #define show_mptmod_ver(s,ver) \ | 82 | #define show_mptmod_ver(s,ver) \ |
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c index e57bb035a021..1dd491773150 100644 --- a/drivers/message/fusion/mptfc.c +++ b/drivers/message/fusion/mptfc.c | |||
@@ -96,6 +96,10 @@ static int mptfc_qcmd(struct scsi_cmnd *SCpnt, | |||
96 | static void mptfc_target_destroy(struct scsi_target *starget); | 96 | static void mptfc_target_destroy(struct scsi_target *starget); |
97 | static void mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout); | 97 | static void mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout); |
98 | static void __devexit mptfc_remove(struct pci_dev *pdev); | 98 | static void __devexit mptfc_remove(struct pci_dev *pdev); |
99 | static int mptfc_abort(struct scsi_cmnd *SCpnt); | ||
100 | static int mptfc_dev_reset(struct scsi_cmnd *SCpnt); | ||
101 | static int mptfc_bus_reset(struct scsi_cmnd *SCpnt); | ||
102 | static int mptfc_host_reset(struct scsi_cmnd *SCpnt); | ||
99 | 103 | ||
100 | static struct scsi_host_template mptfc_driver_template = { | 104 | static struct scsi_host_template mptfc_driver_template = { |
101 | .module = THIS_MODULE, | 105 | .module = THIS_MODULE, |
@@ -110,10 +114,10 @@ static struct scsi_host_template mptfc_driver_template = { | |||
110 | .target_destroy = mptfc_target_destroy, | 114 | .target_destroy = mptfc_target_destroy, |
111 | .slave_destroy = mptscsih_slave_destroy, | 115 | .slave_destroy = mptscsih_slave_destroy, |
112 | .change_queue_depth = mptscsih_change_queue_depth, | 116 | .change_queue_depth = mptscsih_change_queue_depth, |
113 | .eh_abort_handler = mptscsih_abort, | 117 | .eh_abort_handler = mptfc_abort, |
114 | .eh_device_reset_handler = mptscsih_dev_reset, | 118 | .eh_device_reset_handler = mptfc_dev_reset, |
115 | .eh_bus_reset_handler = mptscsih_bus_reset, | 119 | .eh_bus_reset_handler = mptfc_bus_reset, |
116 | .eh_host_reset_handler = mptscsih_host_reset, | 120 | .eh_host_reset_handler = mptfc_host_reset, |
117 | .bios_param = mptscsih_bios_param, | 121 | .bios_param = mptscsih_bios_param, |
118 | .can_queue = MPT_FC_CAN_QUEUE, | 122 | .can_queue = MPT_FC_CAN_QUEUE, |
119 | .this_id = -1, | 123 | .this_id = -1, |
@@ -171,6 +175,77 @@ static struct fc_function_template mptfc_transport_functions = { | |||
171 | .show_host_symbolic_name = 1, | 175 | .show_host_symbolic_name = 1, |
172 | }; | 176 | }; |
173 | 177 | ||
178 | static int | ||
179 | mptfc_block_error_handler(struct scsi_cmnd *SCpnt, | ||
180 | int (*func)(struct scsi_cmnd *SCpnt), | ||
181 | const char *caller) | ||
182 | { | ||
183 | struct scsi_device *sdev = SCpnt->device; | ||
184 | struct Scsi_Host *shost = sdev->host; | ||
185 | struct fc_rport *rport = starget_to_rport(scsi_target(sdev)); | ||
186 | unsigned long flags; | ||
187 | int ready; | ||
188 | |||
189 | spin_lock_irqsave(shost->host_lock, flags); | ||
190 | while ((ready = fc_remote_port_chkready(rport) >> 16) == DID_IMM_RETRY) { | ||
191 | spin_unlock_irqrestore(shost->host_lock, flags); | ||
192 | dfcprintk ((MYIOC_s_INFO_FMT | ||
193 | "mptfc_block_error_handler.%d: %d:%d, port status is " | ||
194 | "DID_IMM_RETRY, deferring %s recovery.\n", | ||
195 | ((MPT_SCSI_HOST *) shost->hostdata)->ioc->name, | ||
196 | ((MPT_SCSI_HOST *) shost->hostdata)->ioc->sh->host_no, | ||
197 | SCpnt->device->id,SCpnt->device->lun,caller)); | ||
198 | msleep(1000); | ||
199 | spin_lock_irqsave(shost->host_lock, flags); | ||
200 | } | ||
201 | spin_unlock_irqrestore(shost->host_lock, flags); | ||
202 | |||
203 | if (ready == DID_NO_CONNECT || !SCpnt->device->hostdata) { | ||
204 | dfcprintk ((MYIOC_s_INFO_FMT | ||
205 | "%s.%d: %d:%d, failing recovery, " | ||
206 | "port state %d, vdev %p.\n", caller, | ||
207 | ((MPT_SCSI_HOST *) shost->hostdata)->ioc->name, | ||
208 | ((MPT_SCSI_HOST *) shost->hostdata)->ioc->sh->host_no, | ||
209 | SCpnt->device->id,SCpnt->device->lun,ready, | ||
210 | SCpnt->device->hostdata)); | ||
211 | return FAILED; | ||
212 | } | ||
213 | dfcprintk ((MYIOC_s_INFO_FMT | ||
214 | "%s.%d: %d:%d, executing recovery.\n", caller, | ||
215 | ((MPT_SCSI_HOST *) shost->hostdata)->ioc->name, | ||
216 | ((MPT_SCSI_HOST *) shost->hostdata)->ioc->sh->host_no, | ||
217 | SCpnt->device->id,SCpnt->device->lun)); | ||
218 | return (*func)(SCpnt); | ||
219 | } | ||
220 | |||
221 | static int | ||
222 | mptfc_abort(struct scsi_cmnd *SCpnt) | ||
223 | { | ||
224 | return | ||
225 | mptfc_block_error_handler(SCpnt, mptscsih_abort, __FUNCTION__); | ||
226 | } | ||
227 | |||
228 | static int | ||
229 | mptfc_dev_reset(struct scsi_cmnd *SCpnt) | ||
230 | { | ||
231 | return | ||
232 | mptfc_block_error_handler(SCpnt, mptscsih_dev_reset, __FUNCTION__); | ||
233 | } | ||
234 | |||
235 | static int | ||
236 | mptfc_bus_reset(struct scsi_cmnd *SCpnt) | ||
237 | { | ||
238 | return | ||
239 | mptfc_block_error_handler(SCpnt, mptscsih_bus_reset, __FUNCTION__); | ||
240 | } | ||
241 | |||
242 | static int | ||
243 | mptfc_host_reset(struct scsi_cmnd *SCpnt) | ||
244 | { | ||
245 | return | ||
246 | mptfc_block_error_handler(SCpnt, mptscsih_host_reset, __FUNCTION__); | ||
247 | } | ||
248 | |||
174 | static void | 249 | static void |
175 | mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout) | 250 | mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout) |
176 | { | 251 | { |
@@ -562,6 +637,12 @@ mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) | |||
562 | return 0; | 637 | return 0; |
563 | } | 638 | } |
564 | 639 | ||
640 | if (!SCpnt->device->hostdata) { /* vdev */ | ||
641 | SCpnt->result = DID_NO_CONNECT << 16; | ||
642 | done(SCpnt); | ||
643 | return 0; | ||
644 | } | ||
645 | |||
565 | /* dd_data is null until finished adding target */ | 646 | /* dd_data is null until finished adding target */ |
566 | ri = *((struct mptfc_rport_info **)rport->dd_data); | 647 | ri = *((struct mptfc_rport_info **)rport->dd_data); |
567 | if (unlikely(!ri)) { | 648 | if (unlikely(!ri)) { |
diff --git a/drivers/message/i2o/bus-osm.c b/drivers/message/i2o/bus-osm.c index ac06f10c54ec..d96c687aee93 100644 --- a/drivers/message/i2o/bus-osm.c +++ b/drivers/message/i2o/bus-osm.c | |||
@@ -80,18 +80,26 @@ static DEVICE_ATTR(scan, S_IWUSR, NULL, i2o_bus_store_scan); | |||
80 | * @dev: device to verify if it is a I2O Bus Adapter device | 80 | * @dev: device to verify if it is a I2O Bus Adapter device |
81 | * | 81 | * |
82 | * Because we want all Bus Adapters always return 0. | 82 | * Because we want all Bus Adapters always return 0. |
83 | * Except when we fail. Then we are sad. | ||
83 | * | 84 | * |
84 | * Returns 0. | 85 | * Returns 0, except when we fail to excel. |
85 | */ | 86 | */ |
86 | static int i2o_bus_probe(struct device *dev) | 87 | static int i2o_bus_probe(struct device *dev) |
87 | { | 88 | { |
88 | struct i2o_device *i2o_dev = to_i2o_device(get_device(dev)); | 89 | struct i2o_device *i2o_dev = to_i2o_device(get_device(dev)); |
90 | int rc; | ||
89 | 91 | ||
90 | device_create_file(dev, &dev_attr_scan); | 92 | rc = device_create_file(dev, &dev_attr_scan); |
93 | if (rc) | ||
94 | goto err_out; | ||
91 | 95 | ||
92 | osm_info("device added (TID: %03x)\n", i2o_dev->lct_data.tid); | 96 | osm_info("device added (TID: %03x)\n", i2o_dev->lct_data.tid); |
93 | 97 | ||
94 | return 0; | 98 | return 0; |
99 | |||
100 | err_out: | ||
101 | put_device(dev); | ||
102 | return rc; | ||
95 | }; | 103 | }; |
96 | 104 | ||
97 | /** | 105 | /** |
diff --git a/drivers/message/i2o/exec-osm.c b/drivers/message/i2o/exec-osm.c index 7bd4d85d0b42..a2350640384b 100644 --- a/drivers/message/i2o/exec-osm.c +++ b/drivers/message/i2o/exec-osm.c | |||
@@ -124,10 +124,10 @@ static void i2o_exec_wait_free(struct i2o_exec_wait *wait) | |||
124 | int i2o_msg_post_wait_mem(struct i2o_controller *c, struct i2o_message *msg, | 124 | int i2o_msg_post_wait_mem(struct i2o_controller *c, struct i2o_message *msg, |
125 | unsigned long timeout, struct i2o_dma *dma) | 125 | unsigned long timeout, struct i2o_dma *dma) |
126 | { | 126 | { |
127 | DECLARE_WAIT_QUEUE_HEAD(wq); | 127 | DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq); |
128 | struct i2o_exec_wait *wait; | 128 | struct i2o_exec_wait *wait; |
129 | static u32 tcntxt = 0x80000000; | 129 | static u32 tcntxt = 0x80000000; |
130 | long flags; | 130 | unsigned long flags; |
131 | int rc = 0; | 131 | int rc = 0; |
132 | 132 | ||
133 | wait = i2o_exec_wait_alloc(); | 133 | wait = i2o_exec_wait_alloc(); |
@@ -325,13 +325,24 @@ static DEVICE_ATTR(product_id, S_IRUGO, i2o_exec_show_product_id, NULL); | |||
325 | static int i2o_exec_probe(struct device *dev) | 325 | static int i2o_exec_probe(struct device *dev) |
326 | { | 326 | { |
327 | struct i2o_device *i2o_dev = to_i2o_device(dev); | 327 | struct i2o_device *i2o_dev = to_i2o_device(dev); |
328 | int rc; | ||
328 | 329 | ||
329 | i2o_event_register(i2o_dev, &i2o_exec_driver, 0, 0xffffffff); | 330 | rc = i2o_event_register(i2o_dev, &i2o_exec_driver, 0, 0xffffffff); |
331 | if (rc) goto err_out; | ||
330 | 332 | ||
331 | device_create_file(dev, &dev_attr_vendor_id); | 333 | rc = device_create_file(dev, &dev_attr_vendor_id); |
332 | device_create_file(dev, &dev_attr_product_id); | 334 | if (rc) goto err_evtreg; |
335 | rc = device_create_file(dev, &dev_attr_product_id); | ||
336 | if (rc) goto err_vid; | ||
333 | 337 | ||
334 | return 0; | 338 | return 0; |
339 | |||
340 | err_vid: | ||
341 | device_remove_file(dev, &dev_attr_vendor_id); | ||
342 | err_evtreg: | ||
343 | i2o_event_register(to_i2o_device(dev), &i2o_exec_driver, 0, 0); | ||
344 | err_out: | ||
345 | return rc; | ||
335 | }; | 346 | }; |
336 | 347 | ||
337 | /** | 348 | /** |
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 3df0e7a07c46..00db31c314e0 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig | |||
@@ -28,6 +28,18 @@ config IBM_ASM | |||
28 | 28 | ||
29 | If unsure, say N. | 29 | If unsure, say N. |
30 | 30 | ||
31 | config SGI_IOC4 | ||
32 | tristate "SGI IOC4 Base IO support" | ||
33 | depends on PCI | ||
34 | ---help--- | ||
35 | This option enables basic support for the IOC4 chip on certain | ||
36 | SGI IO controller cards (IO9, IO10, and PCI-RT). This option | ||
37 | does not enable any specific functions on such a card, but provides | ||
38 | necessary infrastructure for other drivers to utilize. | ||
39 | |||
40 | If you have an SGI Altix with an IOC4-based card say Y. | ||
41 | Otherwise say N. | ||
42 | |||
31 | config TIFM_CORE | 43 | config TIFM_CORE |
32 | tristate "TI Flash Media interface support (EXPERIMENTAL)" | 44 | tristate "TI Flash Media interface support (EXPERIMENTAL)" |
33 | depends on EXPERIMENTAL | 45 | depends on EXPERIMENTAL |
@@ -57,4 +69,23 @@ config TIFM_7XX1 | |||
57 | To compile this driver as a module, choose M here: the module will | 69 | To compile this driver as a module, choose M here: the module will |
58 | be called tifm_7xx1. | 70 | be called tifm_7xx1. |
59 | 71 | ||
72 | config MSI_LAPTOP | ||
73 | tristate "MSI Laptop Extras" | ||
74 | depends on X86 | ||
75 | depends on ACPI_EC | ||
76 | depends on BACKLIGHT_CLASS_DEVICE | ||
77 | ---help--- | ||
78 | This is a driver for laptops built by MSI (MICRO-STAR | ||
79 | INTERNATIONAL): | ||
80 | |||
81 | MSI MegaBook S270 (MS-1013) | ||
82 | Cytron/TCM/Medion/Tchibo MD96100/SAM2000 | ||
83 | |||
84 | It adds support for Bluetooth, WLAN and LCD brightness control. | ||
85 | |||
86 | More information about this driver is available at | ||
87 | <http://0pointer.de/lennart/tchibo.html>. | ||
88 | |||
89 | If you have an MSI S270 laptop, say Y or M here. | ||
90 | |||
60 | endmenu | 91 | endmenu |
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index d65ece76095a..c9e98ab021c5 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile | |||
@@ -5,6 +5,8 @@ obj- := misc.o # Dummy rule to force built-in.o to be made | |||
5 | 5 | ||
6 | obj-$(CONFIG_IBM_ASM) += ibmasm/ | 6 | obj-$(CONFIG_IBM_ASM) += ibmasm/ |
7 | obj-$(CONFIG_HDPU_FEATURES) += hdpuftrs/ | 7 | obj-$(CONFIG_HDPU_FEATURES) += hdpuftrs/ |
8 | obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o | ||
8 | obj-$(CONFIG_LKDTM) += lkdtm.o | 9 | obj-$(CONFIG_LKDTM) += lkdtm.o |
9 | obj-$(CONFIG_TIFM_CORE) += tifm_core.o | 10 | obj-$(CONFIG_TIFM_CORE) += tifm_core.o |
10 | obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o | 11 | obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o |
12 | obj-$(CONFIG_SGI_IOC4) += ioc4.o | ||
diff --git a/drivers/sn/ioc4.c b/drivers/misc/ioc4.c index 8562821e6498..b995a15b7526 100644 --- a/drivers/sn/ioc4.c +++ b/drivers/misc/ioc4.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * License. See the file "COPYING" in the main directory of this archive | 3 | * License. See the file "COPYING" in the main directory of this archive |
4 | * for more details. | 4 | * for more details. |
5 | * | 5 | * |
6 | * Copyright (C) 2005 Silicon Graphics, Inc. All Rights Reserved. | 6 | * Copyright (C) 2005-2006 Silicon Graphics, Inc. All Rights Reserved. |
7 | */ | 7 | */ |
8 | 8 | ||
9 | /* This file contains the master driver module for use by SGI IOC4 subdrivers. | 9 | /* This file contains the master driver module for use by SGI IOC4 subdrivers. |
@@ -29,12 +29,10 @@ | |||
29 | #include <linux/module.h> | 29 | #include <linux/module.h> |
30 | #include <linux/pci.h> | 30 | #include <linux/pci.h> |
31 | #include <linux/ioc4.h> | 31 | #include <linux/ioc4.h> |
32 | #include <linux/mmtimer.h> | 32 | #include <linux/ktime.h> |
33 | #include <linux/rtc.h> | ||
34 | #include <linux/mutex.h> | 33 | #include <linux/mutex.h> |
35 | #include <asm/sn/addrs.h> | 34 | #include <linux/time.h> |
36 | #include <asm/sn/clksupport.h> | 35 | #include <asm/io.h> |
37 | #include <asm/sn/shub_mmr.h> | ||
38 | 36 | ||
39 | /*************** | 37 | /*************** |
40 | * Definitions * | 38 | * Definitions * |
@@ -43,7 +41,7 @@ | |||
43 | /* Tweakable values */ | 41 | /* Tweakable values */ |
44 | 42 | ||
45 | /* PCI bus speed detection/calibration */ | 43 | /* PCI bus speed detection/calibration */ |
46 | #define IOC4_CALIBRATE_COUNT 63 /* Calibration cycle period */ | 44 | #define IOC4_CALIBRATE_COUNT 63 /* Calibration cycle period */ |
47 | #define IOC4_CALIBRATE_CYCLES 256 /* Average over this many cycles */ | 45 | #define IOC4_CALIBRATE_CYCLES 256 /* Average over this many cycles */ |
48 | #define IOC4_CALIBRATE_DISCARD 2 /* Discard first few cycles */ | 46 | #define IOC4_CALIBRATE_DISCARD 2 /* Discard first few cycles */ |
49 | #define IOC4_CALIBRATE_LOW_MHZ 25 /* Lower bound on bus speed sanity */ | 47 | #define IOC4_CALIBRATE_LOW_MHZ 25 /* Lower bound on bus speed sanity */ |
@@ -143,11 +141,11 @@ ioc4_unregister_submodule(struct ioc4_submodule *is) | |||
143 | static void | 141 | static void |
144 | ioc4_clock_calibrate(struct ioc4_driver_data *idd) | 142 | ioc4_clock_calibrate(struct ioc4_driver_data *idd) |
145 | { | 143 | { |
146 | extern unsigned long sn_rtc_cycles_per_second; | ||
147 | union ioc4_int_out int_out; | 144 | union ioc4_int_out int_out; |
148 | union ioc4_gpcr gpcr; | 145 | union ioc4_gpcr gpcr; |
149 | unsigned int state, last_state = 1; | 146 | unsigned int state, last_state = 1; |
150 | uint64_t start = 0, end, period; | 147 | struct timespec start_ts, end_ts; |
148 | uint64_t start, end, period; | ||
151 | unsigned int count = 0; | 149 | unsigned int count = 0; |
152 | 150 | ||
153 | /* Enable output */ | 151 | /* Enable output */ |
@@ -175,30 +173,28 @@ ioc4_clock_calibrate(struct ioc4_driver_data *idd) | |||
175 | if (!last_state && state) { | 173 | if (!last_state && state) { |
176 | count++; | 174 | count++; |
177 | if (count == IOC4_CALIBRATE_END) { | 175 | if (count == IOC4_CALIBRATE_END) { |
178 | end = rtc_time(); | 176 | ktime_get_ts(&end_ts); |
179 | break; | 177 | break; |
180 | } else if (count == IOC4_CALIBRATE_DISCARD) | 178 | } else if (count == IOC4_CALIBRATE_DISCARD) |
181 | start = rtc_time(); | 179 | ktime_get_ts(&start_ts); |
182 | } | 180 | } |
183 | last_state = state; | 181 | last_state = state; |
184 | } while (1); | 182 | } while (1); |
185 | 183 | ||
186 | /* Calculation rearranged to preserve intermediate precision. | 184 | /* Calculation rearranged to preserve intermediate precision. |
187 | * Logically: | 185 | * Logically: |
188 | * 1. "end - start" gives us number of RTC cycles over all the | 186 | * 1. "end - start" gives us the measurement period over all |
189 | * square wave cycles measured. | 187 | * the square wave cycles. |
190 | * 2. Divide by number of square wave cycles to get number of | 188 | * 2. Divide by number of square wave cycles to get the period |
191 | * RTC cycles per square wave cycle. | 189 | * of a square wave cycle. |
192 | * 3. Divide by 2*(int_out.fields.count+1), which is the formula | 190 | * 3. Divide by 2*(int_out.fields.count+1), which is the formula |
193 | * by which the IOC4 generates the square wave, to get the | 191 | * by which the IOC4 generates the square wave, to get the |
194 | * number of RTC cycles per IOC4 INT_OUT count. | 192 | * period of an IOC4 INT_OUT count. |
195 | * 4. Divide by sn_rtc_cycles_per_second to get seconds per | ||
196 | * count. | ||
197 | * 5. Multiply by 1E9 to get nanoseconds per count. | ||
198 | */ | 193 | */ |
199 | period = ((end - start) * 1000000000) / | 194 | end = end_ts.tv_sec * NSEC_PER_SEC + end_ts.tv_nsec; |
200 | (IOC4_CALIBRATE_CYCLES * 2 * (IOC4_CALIBRATE_COUNT + 1) | 195 | start = start_ts.tv_sec * NSEC_PER_SEC + start_ts.tv_nsec; |
201 | * sn_rtc_cycles_per_second); | 196 | period = (end - start) / |
197 | (IOC4_CALIBRATE_CYCLES * 2 * (IOC4_CALIBRATE_COUNT + 1)); | ||
202 | 198 | ||
203 | /* Bounds check the result. */ | 199 | /* Bounds check the result. */ |
204 | if (period > IOC4_CALIBRATE_LOW_LIMIT || | 200 | if (period > IOC4_CALIBRATE_LOW_LIMIT || |
@@ -210,10 +206,12 @@ ioc4_clock_calibrate(struct ioc4_driver_data *idd) | |||
210 | IOC4_CALIBRATE_DEFAULT / IOC4_EXTINT_COUNT_DIVISOR); | 206 | IOC4_CALIBRATE_DEFAULT / IOC4_EXTINT_COUNT_DIVISOR); |
211 | period = IOC4_CALIBRATE_DEFAULT; | 207 | period = IOC4_CALIBRATE_DEFAULT; |
212 | } else { | 208 | } else { |
209 | u64 ns = period; | ||
210 | |||
211 | do_div(ns, IOC4_EXTINT_COUNT_DIVISOR); | ||
213 | printk(KERN_DEBUG | 212 | printk(KERN_DEBUG |
214 | "IOC4 %s: PCI clock is %ld ns.\n", | 213 | "IOC4 %s: PCI clock is %llu ns.\n", |
215 | pci_name(idd->idd_pdev), | 214 | pci_name(idd->idd_pdev), (unsigned long long)ns); |
216 | period / IOC4_EXTINT_COUNT_DIVISOR); | ||
217 | } | 215 | } |
218 | 216 | ||
219 | /* Remember results. We store the extint clock period rather | 217 | /* Remember results. We store the extint clock period rather |
diff --git a/drivers/misc/lkdtm.c b/drivers/misc/lkdtm.c index bbdba7b37e11..db9d7df75ae0 100644 --- a/drivers/misc/lkdtm.c +++ b/drivers/misc/lkdtm.c | |||
@@ -44,12 +44,14 @@ | |||
44 | */ | 44 | */ |
45 | 45 | ||
46 | #include <linux/kernel.h> | 46 | #include <linux/kernel.h> |
47 | #include <linux/fs.h> | ||
47 | #include <linux/module.h> | 48 | #include <linux/module.h> |
49 | #include <linux/buffer_head.h> | ||
48 | #include <linux/kprobes.h> | 50 | #include <linux/kprobes.h> |
49 | #include <linux/kallsyms.h> | 51 | #include <linux/list.h> |
50 | #include <linux/init.h> | 52 | #include <linux/init.h> |
51 | #include <linux/irq.h> | ||
52 | #include <linux/interrupt.h> | 53 | #include <linux/interrupt.h> |
54 | #include <linux/hrtimer.h> | ||
53 | #include <scsi/scsi_cmnd.h> | 55 | #include <scsi/scsi_cmnd.h> |
54 | 56 | ||
55 | #ifdef CONFIG_IDE | 57 | #ifdef CONFIG_IDE |
@@ -116,16 +118,16 @@ static enum ctype cptype = NONE; | |||
116 | static int count = DEFAULT_COUNT; | 118 | static int count = DEFAULT_COUNT; |
117 | 119 | ||
118 | module_param(recur_count, int, 0644); | 120 | module_param(recur_count, int, 0644); |
119 | MODULE_PARM_DESC(recur_count, "Recurcion level for the stack overflow test,\ | 121 | MODULE_PARM_DESC(recur_count, " Recursion level for the stack overflow test, "\ |
120 | default is 10"); | 122 | "default is 10"); |
121 | module_param(cpoint_name, charp, 0644); | 123 | module_param(cpoint_name, charp, 0644); |
122 | MODULE_PARM_DESC(cpoint_name, "Crash Point, where kernel is to be crashed"); | 124 | MODULE_PARM_DESC(cpoint_name, " Crash Point, where kernel is to be crashed"); |
123 | module_param(cpoint_type, charp, 06444); | 125 | module_param(cpoint_type, charp, 0644); |
124 | MODULE_PARM_DESC(cpoint_type, "Crash Point Type, action to be taken on\ | 126 | MODULE_PARM_DESC(cpoint_type, " Crash Point Type, action to be taken on "\ |
125 | hitting the crash point"); | 127 | "hitting the crash point"); |
126 | module_param(cpoint_count, int, 06444); | 128 | module_param(cpoint_count, int, 0644); |
127 | MODULE_PARM_DESC(cpoint_count, "Crash Point Count, number of times the \ | 129 | MODULE_PARM_DESC(cpoint_count, " Crash Point Count, number of times the "\ |
128 | crash point is to be hit to trigger action"); | 130 | "crash point is to be hit to trigger action"); |
129 | 131 | ||
130 | unsigned int jp_do_irq(unsigned int irq) | 132 | unsigned int jp_do_irq(unsigned int irq) |
131 | { | 133 | { |
@@ -155,8 +157,8 @@ void jp_ll_rw_block(int rw, int nr, struct buffer_head *bhs[]) | |||
155 | 157 | ||
156 | struct scan_control; | 158 | struct scan_control; |
157 | 159 | ||
158 | unsigned long jp_shrink_page_list(struct list_head *page_list, | 160 | unsigned long jp_shrink_inactive_list(unsigned long max_scan, |
159 | struct scan_control *sc) | 161 | struct zone *zone, struct scan_control *sc) |
160 | { | 162 | { |
161 | lkdtm_handler(); | 163 | lkdtm_handler(); |
162 | jprobe_return(); | 164 | jprobe_return(); |
@@ -295,8 +297,8 @@ int lkdtm_module_init(void) | |||
295 | lkdtm.entry = (kprobe_opcode_t*) jp_ll_rw_block; | 297 | lkdtm.entry = (kprobe_opcode_t*) jp_ll_rw_block; |
296 | break; | 298 | break; |
297 | case MEM_SWAPOUT: | 299 | case MEM_SWAPOUT: |
298 | lkdtm.kp.symbol_name = "shrink_page_list"; | 300 | lkdtm.kp.symbol_name = "shrink_inactive_list"; |
299 | lkdtm.entry = (kprobe_opcode_t*) jp_shrink_page_list; | 301 | lkdtm.entry = (kprobe_opcode_t*) jp_shrink_inactive_list; |
300 | break; | 302 | break; |
301 | case TIMERADD: | 303 | case TIMERADD: |
302 | lkdtm.kp.symbol_name = "hrtimer_start"; | 304 | lkdtm.kp.symbol_name = "hrtimer_start"; |
diff --git a/drivers/misc/msi-laptop.c b/drivers/misc/msi-laptop.c new file mode 100644 index 000000000000..fdb7153f4426 --- /dev/null +++ b/drivers/misc/msi-laptop.c | |||
@@ -0,0 +1,395 @@ | |||
1 | /*-*-linux-c-*-*/ | ||
2 | |||
3 | /* | ||
4 | Copyright (C) 2006 Lennart Poettering <mzxreary (at) 0pointer (dot) de> | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, but | ||
12 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
19 | 02110-1301, USA. | ||
20 | */ | ||
21 | |||
22 | /* | ||
23 | * msi-laptop.c - MSI S270 laptop support. This laptop is sold under | ||
24 | * various brands, including "Cytron/TCM/Medion/Tchibo MD96100". | ||
25 | * | ||
26 | * This driver exports a few files in /sys/devices/platform/msi-laptop-pf/: | ||
27 | * | ||
28 | * lcd_level - Screen brightness: contains a single integer in the | ||
29 | * range 0..8. (rw) | ||
30 | * | ||
31 | * auto_brightness - Enable automatic brightness control: contains | ||
32 | * either 0 or 1. If set to 1 the hardware adjusts the screen | ||
33 | * brightness automatically when the power cord is | ||
34 | * plugged/unplugged. (rw) | ||
35 | * | ||
36 | * wlan - WLAN subsystem enabled: contains either 0 or 1. (ro) | ||
37 | * | ||
38 | * bluetooth - Bluetooth subsystem enabled: contains either 0 or 1 | ||
39 | * Please note that this file is constantly 0 if no Bluetooth | ||
40 | * hardware is available. (ro) | ||
41 | * | ||
42 | * In addition to these platform device attributes the driver | ||
43 | * registers itself in the Linux backlight control subsystem and is | ||
44 | * available to userspace under /sys/class/backlight/msi-laptop-bl/. | ||
45 | * | ||
46 | * This driver might work on other laptops produced by MSI. If you | ||
47 | * want to try it you can pass force=1 as argument to the module which | ||
48 | * will force it to load even when the DMI data doesn't identify the | ||
49 | * laptop as MSI S270. YMMV. | ||
50 | */ | ||
51 | |||
52 | #include <linux/module.h> | ||
53 | #include <linux/kernel.h> | ||
54 | #include <linux/init.h> | ||
55 | #include <linux/acpi.h> | ||
56 | #include <linux/dmi.h> | ||
57 | #include <linux/backlight.h> | ||
58 | #include <linux/platform_device.h> | ||
59 | #include <linux/autoconf.h> | ||
60 | |||
61 | #define MSI_DRIVER_VERSION "0.5" | ||
62 | |||
63 | #define MSI_LCD_LEVEL_MAX 9 | ||
64 | |||
65 | #define MSI_EC_COMMAND_WIRELESS 0x10 | ||
66 | #define MSI_EC_COMMAND_LCD_LEVEL 0x11 | ||
67 | |||
68 | static int force; | ||
69 | module_param(force, bool, 0); | ||
70 | MODULE_PARM_DESC(force, "Force driver load, ignore DMI data"); | ||
71 | |||
72 | static int auto_brightness; | ||
73 | module_param(auto_brightness, int, 0); | ||
74 | MODULE_PARM_DESC(auto_brightness, "Enable automatic brightness control (0: disabled; 1: enabled; 2: don't touch)"); | ||
75 | |||
76 | /* Hardware access */ | ||
77 | |||
78 | static int set_lcd_level(int level) | ||
79 | { | ||
80 | u8 buf[2]; | ||
81 | |||
82 | if (level < 0 || level >= MSI_LCD_LEVEL_MAX) | ||
83 | return -EINVAL; | ||
84 | |||
85 | buf[0] = 0x80; | ||
86 | buf[1] = (u8) (level*31); | ||
87 | |||
88 | return ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, buf, sizeof(buf), NULL, 0); | ||
89 | } | ||
90 | |||
91 | static int get_lcd_level(void) | ||
92 | { | ||
93 | u8 wdata = 0, rdata; | ||
94 | int result; | ||
95 | |||
96 | result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, &wdata, 1, &rdata, 1); | ||
97 | if (result < 0) | ||
98 | return result; | ||
99 | |||
100 | return (int) rdata / 31; | ||
101 | } | ||
102 | |||
103 | static int get_auto_brightness(void) | ||
104 | { | ||
105 | u8 wdata = 4, rdata; | ||
106 | int result; | ||
107 | |||
108 | result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, &wdata, 1, &rdata, 1); | ||
109 | if (result < 0) | ||
110 | return result; | ||
111 | |||
112 | return !!(rdata & 8); | ||
113 | } | ||
114 | |||
115 | static int set_auto_brightness(int enable) | ||
116 | { | ||
117 | u8 wdata[2], rdata; | ||
118 | int result; | ||
119 | |||
120 | wdata[0] = 4; | ||
121 | |||
122 | result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, wdata, 1, &rdata, 1); | ||
123 | if (result < 0) | ||
124 | return result; | ||
125 | |||
126 | wdata[0] = 0x84; | ||
127 | wdata[1] = (rdata & 0xF7) | (enable ? 8 : 0); | ||
128 | |||
129 | return ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, wdata, 2, NULL, 0); | ||
130 | } | ||
131 | |||
132 | static int get_wireless_state(int *wlan, int *bluetooth) | ||
133 | { | ||
134 | u8 wdata = 0, rdata; | ||
135 | int result; | ||
136 | |||
137 | result = ec_transaction(MSI_EC_COMMAND_WIRELESS, &wdata, 1, &rdata, 1); | ||
138 | if (result < 0) | ||
139 | return -1; | ||
140 | |||
141 | if (wlan) | ||
142 | *wlan = !!(rdata & 8); | ||
143 | |||
144 | if (bluetooth) | ||
145 | *bluetooth = !!(rdata & 128); | ||
146 | |||
147 | return 0; | ||
148 | } | ||
149 | |||
150 | /* Backlight device stuff */ | ||
151 | |||
152 | static int bl_get_brightness(struct backlight_device *b) | ||
153 | { | ||
154 | return get_lcd_level(); | ||
155 | } | ||
156 | |||
157 | |||
158 | static int bl_update_status(struct backlight_device *b) | ||
159 | { | ||
160 | return set_lcd_level(b->props->brightness); | ||
161 | } | ||
162 | |||
163 | static struct backlight_properties msibl_props = { | ||
164 | .owner = THIS_MODULE, | ||
165 | .get_brightness = bl_get_brightness, | ||
166 | .update_status = bl_update_status, | ||
167 | .max_brightness = MSI_LCD_LEVEL_MAX-1, | ||
168 | }; | ||
169 | |||
170 | static struct backlight_device *msibl_device; | ||
171 | |||
172 | /* Platform device */ | ||
173 | |||
174 | static ssize_t show_wlan(struct device *dev, | ||
175 | struct device_attribute *attr, char *buf) | ||
176 | { | ||
177 | |||
178 | int ret, enabled; | ||
179 | |||
180 | ret = get_wireless_state(&enabled, NULL); | ||
181 | if (ret < 0) | ||
182 | return ret; | ||
183 | |||
184 | return sprintf(buf, "%i\n", enabled); | ||
185 | } | ||
186 | |||
187 | static ssize_t show_bluetooth(struct device *dev, | ||
188 | struct device_attribute *attr, char *buf) | ||
189 | { | ||
190 | |||
191 | int ret, enabled; | ||
192 | |||
193 | ret = get_wireless_state(NULL, &enabled); | ||
194 | if (ret < 0) | ||
195 | return ret; | ||
196 | |||
197 | return sprintf(buf, "%i\n", enabled); | ||
198 | } | ||
199 | |||
200 | static ssize_t show_lcd_level(struct device *dev, | ||
201 | struct device_attribute *attr, char *buf) | ||
202 | { | ||
203 | |||
204 | int ret; | ||
205 | |||
206 | ret = get_lcd_level(); | ||
207 | if (ret < 0) | ||
208 | return ret; | ||
209 | |||
210 | return sprintf(buf, "%i\n", ret); | ||
211 | } | ||
212 | |||
213 | static ssize_t store_lcd_level(struct device *dev, | ||
214 | struct device_attribute *attr, const char *buf, size_t count) | ||
215 | { | ||
216 | |||
217 | int level, ret; | ||
218 | |||
219 | if (sscanf(buf, "%i", &level) != 1 || (level < 0 || level >= MSI_LCD_LEVEL_MAX)) | ||
220 | return -EINVAL; | ||
221 | |||
222 | ret = set_lcd_level(level); | ||
223 | if (ret < 0) | ||
224 | return ret; | ||
225 | |||
226 | return count; | ||
227 | } | ||
228 | |||
229 | static ssize_t show_auto_brightness(struct device *dev, | ||
230 | struct device_attribute *attr, char *buf) | ||
231 | { | ||
232 | |||
233 | int ret; | ||
234 | |||
235 | ret = get_auto_brightness(); | ||
236 | if (ret < 0) | ||
237 | return ret; | ||
238 | |||
239 | return sprintf(buf, "%i\n", ret); | ||
240 | } | ||
241 | |||
242 | static ssize_t store_auto_brightness(struct device *dev, | ||
243 | struct device_attribute *attr, const char *buf, size_t count) | ||
244 | { | ||
245 | |||
246 | int enable, ret; | ||
247 | |||
248 | if (sscanf(buf, "%i", &enable) != 1 || (enable != (enable & 1))) | ||
249 | return -EINVAL; | ||
250 | |||
251 | ret = set_auto_brightness(enable); | ||
252 | if (ret < 0) | ||
253 | return ret; | ||
254 | |||
255 | return count; | ||
256 | } | ||
257 | |||
258 | static DEVICE_ATTR(lcd_level, 0644, show_lcd_level, store_lcd_level); | ||
259 | static DEVICE_ATTR(auto_brightness, 0644, show_auto_brightness, store_auto_brightness); | ||
260 | static DEVICE_ATTR(bluetooth, 0444, show_bluetooth, NULL); | ||
261 | static DEVICE_ATTR(wlan, 0444, show_wlan, NULL); | ||
262 | |||
263 | static struct attribute *msipf_attributes[] = { | ||
264 | &dev_attr_lcd_level.attr, | ||
265 | &dev_attr_auto_brightness.attr, | ||
266 | &dev_attr_bluetooth.attr, | ||
267 | &dev_attr_wlan.attr, | ||
268 | NULL | ||
269 | }; | ||
270 | |||
271 | static struct attribute_group msipf_attribute_group = { | ||
272 | .attrs = msipf_attributes | ||
273 | }; | ||
274 | |||
275 | static struct platform_driver msipf_driver = { | ||
276 | .driver = { | ||
277 | .name = "msi-laptop-pf", | ||
278 | .owner = THIS_MODULE, | ||
279 | } | ||
280 | }; | ||
281 | |||
282 | static struct platform_device *msipf_device; | ||
283 | |||
284 | /* Initialization */ | ||
285 | |||
286 | static struct dmi_system_id __initdata msi_dmi_table[] = { | ||
287 | { | ||
288 | .ident = "MSI S270", | ||
289 | .matches = { | ||
290 | DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD"), | ||
291 | DMI_MATCH(DMI_PRODUCT_NAME, "MS-1013"), | ||
292 | } | ||
293 | }, | ||
294 | { | ||
295 | .ident = "Medion MD96100", | ||
296 | .matches = { | ||
297 | DMI_MATCH(DMI_SYS_VENDOR, "NOTEBOOK"), | ||
298 | DMI_MATCH(DMI_PRODUCT_NAME, "SAM2000"), | ||
299 | } | ||
300 | }, | ||
301 | { } | ||
302 | }; | ||
303 | |||
304 | |||
305 | static int __init msi_init(void) | ||
306 | { | ||
307 | int ret; | ||
308 | |||
309 | if (acpi_disabled) | ||
310 | return -ENODEV; | ||
311 | |||
312 | if (!force && !dmi_check_system(msi_dmi_table)) | ||
313 | return -ENODEV; | ||
314 | |||
315 | if (auto_brightness < 0 || auto_brightness > 2) | ||
316 | return -EINVAL; | ||
317 | |||
318 | /* Register backlight stuff */ | ||
319 | |||
320 | msibl_device = backlight_device_register("msi-laptop-bl", NULL, &msibl_props); | ||
321 | if (IS_ERR(msibl_device)) | ||
322 | return PTR_ERR(msibl_device); | ||
323 | |||
324 | ret = platform_driver_register(&msipf_driver); | ||
325 | if (ret) | ||
326 | goto fail_backlight; | ||
327 | |||
328 | /* Register platform stuff */ | ||
329 | |||
330 | msipf_device = platform_device_alloc("msi-laptop-pf", -1); | ||
331 | if (!msipf_device) { | ||
332 | ret = -ENOMEM; | ||
333 | goto fail_platform_driver; | ||
334 | } | ||
335 | |||
336 | ret = platform_device_add(msipf_device); | ||
337 | if (ret) | ||
338 | goto fail_platform_device1; | ||
339 | |||
340 | ret = sysfs_create_group(&msipf_device->dev.kobj, &msipf_attribute_group); | ||
341 | if (ret) | ||
342 | goto fail_platform_device2; | ||
343 | |||
344 | /* Disable automatic brightness control by default because | ||
345 | * this module was probably loaded to do brightness control in | ||
346 | * software. */ | ||
347 | |||
348 | if (auto_brightness != 2) | ||
349 | set_auto_brightness(auto_brightness); | ||
350 | |||
351 | printk(KERN_INFO "msi-laptop: driver "MSI_DRIVER_VERSION" successfully loaded.\n"); | ||
352 | |||
353 | return 0; | ||
354 | |||
355 | fail_platform_device2: | ||
356 | |||
357 | platform_device_del(msipf_device); | ||
358 | |||
359 | fail_platform_device1: | ||
360 | |||
361 | platform_device_put(msipf_device); | ||
362 | |||
363 | fail_platform_driver: | ||
364 | |||
365 | platform_driver_unregister(&msipf_driver); | ||
366 | |||
367 | fail_backlight: | ||
368 | |||
369 | backlight_device_unregister(msibl_device); | ||
370 | |||
371 | return ret; | ||
372 | } | ||
373 | |||
374 | static void __exit msi_cleanup(void) | ||
375 | { | ||
376 | |||
377 | sysfs_remove_group(&msipf_device->dev.kobj, &msipf_attribute_group); | ||
378 | platform_device_unregister(msipf_device); | ||
379 | platform_driver_unregister(&msipf_driver); | ||
380 | backlight_device_unregister(msibl_device); | ||
381 | |||
382 | /* Enable automatic brightness control again */ | ||
383 | if (auto_brightness != 2) | ||
384 | set_auto_brightness(1); | ||
385 | |||
386 | printk(KERN_INFO "msi-laptop: driver unloaded.\n"); | ||
387 | } | ||
388 | |||
389 | module_init(msi_init); | ||
390 | module_exit(msi_cleanup); | ||
391 | |||
392 | MODULE_AUTHOR("Lennart Poettering"); | ||
393 | MODULE_DESCRIPTION("MSI Laptop Support"); | ||
394 | MODULE_VERSION(MSI_DRIVER_VERSION); | ||
395 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index ee8863c123e3..766bc54406e5 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c | |||
@@ -475,7 +475,7 @@ static u32 mmc_select_voltage(struct mmc_host *host, u32 ocr) | |||
475 | if (bit) { | 475 | if (bit) { |
476 | bit -= 1; | 476 | bit -= 1; |
477 | 477 | ||
478 | ocr = 3 << bit; | 478 | ocr &= 3 << bit; |
479 | 479 | ||
480 | host->ios.vdd = bit; | 480 | host->ios.vdd = bit; |
481 | mmc_set_ios(host); | 481 | mmc_set_ios(host); |
@@ -1178,14 +1178,29 @@ static void mmc_rescan(void *data) | |||
1178 | { | 1178 | { |
1179 | struct mmc_host *host = data; | 1179 | struct mmc_host *host = data; |
1180 | struct list_head *l, *n; | 1180 | struct list_head *l, *n; |
1181 | unsigned char power_mode; | ||
1181 | 1182 | ||
1182 | mmc_claim_host(host); | 1183 | mmc_claim_host(host); |
1183 | 1184 | ||
1184 | if (host->ios.power_mode == MMC_POWER_ON) | 1185 | /* |
1186 | * Check for removed cards and newly inserted ones. We check for | ||
1187 | * removed cards first so we can intelligently re-select the VDD. | ||
1188 | */ | ||
1189 | power_mode = host->ios.power_mode; | ||
1190 | if (power_mode == MMC_POWER_ON) | ||
1185 | mmc_check_cards(host); | 1191 | mmc_check_cards(host); |
1186 | 1192 | ||
1187 | mmc_setup(host); | 1193 | mmc_setup(host); |
1188 | 1194 | ||
1195 | /* | ||
1196 | * Some broken cards process CMD1 even in stand-by state. There is | ||
1197 | * no reply, but an ILLEGAL_COMMAND error is cached and returned | ||
1198 | * after next command. We poll for card status here to clear any | ||
1199 | * possibly pending error. | ||
1200 | */ | ||
1201 | if (power_mode == MMC_POWER_ON) | ||
1202 | mmc_check_cards(host); | ||
1203 | |||
1189 | if (!list_empty(&host->cards)) { | 1204 | if (!list_empty(&host->cards)) { |
1190 | /* | 1205 | /* |
1191 | * (Re-)calculate the fastest clock rate which the | 1206 | * (Re-)calculate the fastest clock rate which the |
diff --git a/drivers/mmc/tifm_sd.c b/drivers/mmc/tifm_sd.c index 2bacff60913d..0fdc55b08a6d 100644 --- a/drivers/mmc/tifm_sd.c +++ b/drivers/mmc/tifm_sd.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/mmc/protocol.h> | 14 | #include <linux/mmc/protocol.h> |
15 | #include <linux/mmc/host.h> | 15 | #include <linux/mmc/host.h> |
16 | #include <linux/highmem.h> | 16 | #include <linux/highmem.h> |
17 | #include <asm/io.h> | ||
17 | 18 | ||
18 | #define DRIVER_NAME "tifm_sd" | 19 | #define DRIVER_NAME "tifm_sd" |
19 | #define DRIVER_VERSION "0.6" | 20 | #define DRIVER_VERSION "0.6" |
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index baece61169f4..41bfcae1fbf4 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c | |||
@@ -1479,6 +1479,7 @@ static void nand_write_page_syndrome(struct mtd_info *mtd, | |||
1479 | * @buf: the data to write | 1479 | * @buf: the data to write |
1480 | * @page: page number to write | 1480 | * @page: page number to write |
1481 | * @cached: cached programming | 1481 | * @cached: cached programming |
1482 | * @raw: use _raw version of write_page | ||
1482 | */ | 1483 | */ |
1483 | static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip, | 1484 | static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip, |
1484 | const uint8_t *buf, int page, int cached, int raw) | 1485 | const uint8_t *buf, int page, int cached, int raw) |
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index ab92cc794c64..6e863aa9894c 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
@@ -486,7 +486,7 @@ config SGI_IOC3_ETH_HW_TX_CSUM | |||
486 | 486 | ||
487 | config MIPS_SIM_NET | 487 | config MIPS_SIM_NET |
488 | tristate "MIPS simulator Network device (EXPERIMENTAL)" | 488 | tristate "MIPS simulator Network device (EXPERIMENTAL)" |
489 | depends on NETDEVICES && MIPS_SIM && EXPERIMENTAL | 489 | depends on MIPS_SIM && EXPERIMENTAL |
490 | help | 490 | help |
491 | The MIPSNET device is a simple Ethernet network device which is | 491 | The MIPSNET device is a simple Ethernet network device which is |
492 | emulated by the MIPS Simulator. | 492 | emulated by the MIPS Simulator. |
@@ -2112,7 +2112,7 @@ config SKGE | |||
2112 | 2112 | ||
2113 | config SKY2 | 2113 | config SKY2 |
2114 | tristate "SysKonnect Yukon2 support (EXPERIMENTAL)" | 2114 | tristate "SysKonnect Yukon2 support (EXPERIMENTAL)" |
2115 | depends on PCI && EXPERIMENTAL | 2115 | depends on PCI |
2116 | select CRC32 | 2116 | select CRC32 |
2117 | ---help--- | 2117 | ---help--- |
2118 | This driver supports Gigabit Ethernet adapters based on the | 2118 | This driver supports Gigabit Ethernet adapters based on the |
@@ -2120,8 +2120,8 @@ config SKY2 | |||
2120 | Marvell 88E8021/88E8022/88E8035/88E8036/88E8038/88E8050/88E8052/ | 2120 | Marvell 88E8021/88E8022/88E8035/88E8036/88E8038/88E8050/88E8052/ |
2121 | 88E8053/88E8055/88E8061/88E8062, SysKonnect SK-9E21D/SK-9S21 | 2121 | 88E8053/88E8055/88E8061/88E8062, SysKonnect SK-9E21D/SK-9S21 |
2122 | 2122 | ||
2123 | This driver does not support the original Yukon chipset: a seperate | 2123 | There is companion driver for the older Marvell Yukon and |
2124 | driver, skge, is provided for Yukon-based adapters. | 2124 | Genesis based adapters: skge. |
2125 | 2125 | ||
2126 | To compile this driver as a module, choose M here: the module | 2126 | To compile this driver as a module, choose M here: the module |
2127 | will be called sky2. This is recommended. | 2127 | will be called sky2. This is recommended. |
@@ -2288,7 +2288,7 @@ config UGETH_TX_ON_DEMOND | |||
2288 | 2288 | ||
2289 | config UGETH_HAS_GIGA | 2289 | config UGETH_HAS_GIGA |
2290 | bool | 2290 | bool |
2291 | depends on UCC_GETH && MPC836x | 2291 | depends on UCC_GETH && PPC_MPC836x |
2292 | 2292 | ||
2293 | config MV643XX_ETH | 2293 | config MV643XX_ETH |
2294 | tristate "MV-643XX Ethernet support" | 2294 | tristate "MV-643XX Ethernet support" |
@@ -2467,7 +2467,7 @@ config ISERIES_VETH | |||
2467 | 2467 | ||
2468 | config RIONET | 2468 | config RIONET |
2469 | tristate "RapidIO Ethernet over messaging driver support" | 2469 | tristate "RapidIO Ethernet over messaging driver support" |
2470 | depends on NETDEVICES && RAPIDIO | 2470 | depends on RAPIDIO |
2471 | 2471 | ||
2472 | config RIONET_TX_SIZE | 2472 | config RIONET_TX_SIZE |
2473 | int "Number of outbound queue entries" | 2473 | int "Number of outbound queue entries" |
@@ -2717,6 +2717,7 @@ config PPP_MPPE | |||
2717 | select CRYPTO | 2717 | select CRYPTO |
2718 | select CRYPTO_SHA1 | 2718 | select CRYPTO_SHA1 |
2719 | select CRYPTO_ARC4 | 2719 | select CRYPTO_ARC4 |
2720 | select CRYPTO_ECB | ||
2720 | ---help--- | 2721 | ---help--- |
2721 | Support for the MPPE Encryption protocol, as employed by the | 2722 | Support for the MPPE Encryption protocol, as employed by the |
2722 | Microsoft Point-to-Point Tunneling Protocol. | 2723 | Microsoft Point-to-Point Tunneling Protocol. |
@@ -2832,7 +2833,7 @@ config NET_FC | |||
2832 | "SCSI generic support". | 2833 | "SCSI generic support". |
2833 | 2834 | ||
2834 | config SHAPER | 2835 | config SHAPER |
2835 | tristate "Traffic Shaper (EXPERIMENTAL)" | 2836 | tristate "Traffic Shaper (OBSOLETE)" |
2836 | depends on EXPERIMENTAL | 2837 | depends on EXPERIMENTAL |
2837 | ---help--- | 2838 | ---help--- |
2838 | The traffic shaper is a virtual network device that allows you to | 2839 | The traffic shaper is a virtual network device that allows you to |
@@ -2841,9 +2842,9 @@ config SHAPER | |||
2841 | these virtual devices. See | 2842 | these virtual devices. See |
2842 | <file:Documentation/networking/shaper.txt> for more information. | 2843 | <file:Documentation/networking/shaper.txt> for more information. |
2843 | 2844 | ||
2844 | An alternative to this traffic shaper is the experimental | 2845 | An alternative to this traffic shaper are traffic schedulers which |
2845 | Class-Based Queuing (CBQ) scheduling support which you get if you | 2846 | you'll get if you say Y to "QoS and/or fair queuing" in |
2846 | say Y to "QoS and/or fair queuing" above. | 2847 | "Networking options". |
2847 | 2848 | ||
2848 | To compile this driver as a module, choose M here: the module | 2849 | To compile this driver as a module, choose M here: the module |
2849 | will be called shaper. If unsure, say N. | 2850 | will be called shaper. If unsure, say N. |
diff --git a/drivers/net/arcnet/com20020.c b/drivers/net/arcnet/com20020.c index 0dc70c7b7940..aa9dd8f11269 100644 --- a/drivers/net/arcnet/com20020.c +++ b/drivers/net/arcnet/com20020.c | |||
@@ -337,13 +337,16 @@ static void com20020_set_mc_list(struct net_device *dev) | |||
337 | } | 337 | } |
338 | } | 338 | } |
339 | 339 | ||
340 | #ifdef MODULE | 340 | #if defined(CONFIG_ARCNET_COM20020_PCI_MODULE) || \ |
341 | 341 | defined(CONFIG_ARCNET_COM20020_ISA_MODULE) | |
342 | EXPORT_SYMBOL(com20020_check); | 342 | EXPORT_SYMBOL(com20020_check); |
343 | EXPORT_SYMBOL(com20020_found); | 343 | EXPORT_SYMBOL(com20020_found); |
344 | #endif | ||
344 | 345 | ||
345 | MODULE_LICENSE("GPL"); | 346 | MODULE_LICENSE("GPL"); |
346 | 347 | ||
348 | #ifdef MODULE | ||
349 | |||
347 | int init_module(void) | 350 | int init_module(void) |
348 | { | 351 | { |
349 | BUGLVL(D_NORMAL) printk(VERSION); | 352 | BUGLVL(D_NORMAL) printk(VERSION); |
diff --git a/drivers/net/arm/ep93xx_eth.c b/drivers/net/arm/ep93xx_eth.c index 127561c782fd..8ebd68e2af98 100644 --- a/drivers/net/arm/ep93xx_eth.c +++ b/drivers/net/arm/ep93xx_eth.c | |||
@@ -193,12 +193,9 @@ static struct net_device_stats *ep93xx_get_stats(struct net_device *dev) | |||
193 | static int ep93xx_rx(struct net_device *dev, int *budget) | 193 | static int ep93xx_rx(struct net_device *dev, int *budget) |
194 | { | 194 | { |
195 | struct ep93xx_priv *ep = netdev_priv(dev); | 195 | struct ep93xx_priv *ep = netdev_priv(dev); |
196 | int tail_offset; | ||
197 | int rx_done; | 196 | int rx_done; |
198 | int processed; | 197 | int processed; |
199 | 198 | ||
200 | tail_offset = rdl(ep, REG_RXSTSQCURADD) - ep->descs_dma_addr; | ||
201 | |||
202 | rx_done = 0; | 199 | rx_done = 0; |
203 | processed = 0; | 200 | processed = 0; |
204 | while (*budget > 0) { | 201 | while (*budget > 0) { |
@@ -211,36 +208,28 @@ static int ep93xx_rx(struct net_device *dev, int *budget) | |||
211 | 208 | ||
212 | entry = ep->rx_pointer; | 209 | entry = ep->rx_pointer; |
213 | rstat = ep->descs->rstat + entry; | 210 | rstat = ep->descs->rstat + entry; |
214 | if ((void *)rstat - (void *)ep->descs == tail_offset) { | 211 | |
212 | rstat0 = rstat->rstat0; | ||
213 | rstat1 = rstat->rstat1; | ||
214 | if (!(rstat0 & RSTAT0_RFP) || !(rstat1 & RSTAT1_RFP)) { | ||
215 | rx_done = 1; | 215 | rx_done = 1; |
216 | break; | 216 | break; |
217 | } | 217 | } |
218 | 218 | ||
219 | rstat0 = rstat->rstat0; | ||
220 | rstat1 = rstat->rstat1; | ||
221 | rstat->rstat0 = 0; | 219 | rstat->rstat0 = 0; |
222 | rstat->rstat1 = 0; | 220 | rstat->rstat1 = 0; |
223 | 221 | ||
224 | if (!(rstat0 & RSTAT0_RFP)) | ||
225 | printk(KERN_CRIT "ep93xx_rx: buffer not done " | ||
226 | " %.8x %.8x\n", rstat0, rstat1); | ||
227 | if (!(rstat0 & RSTAT0_EOF)) | 222 | if (!(rstat0 & RSTAT0_EOF)) |
228 | printk(KERN_CRIT "ep93xx_rx: not end-of-frame " | 223 | printk(KERN_CRIT "ep93xx_rx: not end-of-frame " |
229 | " %.8x %.8x\n", rstat0, rstat1); | 224 | " %.8x %.8x\n", rstat0, rstat1); |
230 | if (!(rstat0 & RSTAT0_EOB)) | 225 | if (!(rstat0 & RSTAT0_EOB)) |
231 | printk(KERN_CRIT "ep93xx_rx: not end-of-buffer " | 226 | printk(KERN_CRIT "ep93xx_rx: not end-of-buffer " |
232 | " %.8x %.8x\n", rstat0, rstat1); | 227 | " %.8x %.8x\n", rstat0, rstat1); |
233 | if (!(rstat1 & RSTAT1_RFP)) | ||
234 | printk(KERN_CRIT "ep93xx_rx: buffer1 not done " | ||
235 | " %.8x %.8x\n", rstat0, rstat1); | ||
236 | if ((rstat1 & RSTAT1_BUFFER_INDEX) >> 16 != entry) | 228 | if ((rstat1 & RSTAT1_BUFFER_INDEX) >> 16 != entry) |
237 | printk(KERN_CRIT "ep93xx_rx: entry mismatch " | 229 | printk(KERN_CRIT "ep93xx_rx: entry mismatch " |
238 | " %.8x %.8x\n", rstat0, rstat1); | 230 | " %.8x %.8x\n", rstat0, rstat1); |
239 | 231 | ||
240 | if (!(rstat0 & RSTAT0_RWE)) { | 232 | if (!(rstat0 & RSTAT0_RWE)) { |
241 | printk(KERN_NOTICE "ep93xx_rx: receive error " | ||
242 | " %.8x %.8x\n", rstat0, rstat1); | ||
243 | |||
244 | ep->stats.rx_errors++; | 233 | ep->stats.rx_errors++; |
245 | if (rstat0 & RSTAT0_OE) | 234 | if (rstat0 & RSTAT0_OE) |
246 | ep->stats.rx_fifo_errors++; | 235 | ep->stats.rx_fifo_errors++; |
@@ -301,13 +290,8 @@ err: | |||
301 | 290 | ||
302 | static int ep93xx_have_more_rx(struct ep93xx_priv *ep) | 291 | static int ep93xx_have_more_rx(struct ep93xx_priv *ep) |
303 | { | 292 | { |
304 | struct ep93xx_rstat *rstat; | 293 | struct ep93xx_rstat *rstat = ep->descs->rstat + ep->rx_pointer; |
305 | int tail_offset; | 294 | return !!((rstat->rstat0 & RSTAT0_RFP) && (rstat->rstat1 & RSTAT1_RFP)); |
306 | |||
307 | rstat = ep->descs->rstat + ep->rx_pointer; | ||
308 | tail_offset = rdl(ep, REG_RXSTSQCURADD) - ep->descs_dma_addr; | ||
309 | |||
310 | return !((void *)rstat - (void *)ep->descs == tail_offset); | ||
311 | } | 295 | } |
312 | 296 | ||
313 | static int ep93xx_poll(struct net_device *dev, int *budget) | 297 | static int ep93xx_poll(struct net_device *dev, int *budget) |
@@ -347,7 +331,7 @@ static int ep93xx_xmit(struct sk_buff *skb, struct net_device *dev) | |||
347 | struct ep93xx_priv *ep = netdev_priv(dev); | 331 | struct ep93xx_priv *ep = netdev_priv(dev); |
348 | int entry; | 332 | int entry; |
349 | 333 | ||
350 | if (unlikely(skb->len) > MAX_PKT_SIZE) { | 334 | if (unlikely(skb->len > MAX_PKT_SIZE)) { |
351 | ep->stats.tx_dropped++; | 335 | ep->stats.tx_dropped++; |
352 | dev_kfree_skb(skb); | 336 | dev_kfree_skb(skb); |
353 | return NETDEV_TX_OK; | 337 | return NETDEV_TX_OK; |
@@ -379,10 +363,8 @@ static int ep93xx_xmit(struct sk_buff *skb, struct net_device *dev) | |||
379 | static void ep93xx_tx_complete(struct net_device *dev) | 363 | static void ep93xx_tx_complete(struct net_device *dev) |
380 | { | 364 | { |
381 | struct ep93xx_priv *ep = netdev_priv(dev); | 365 | struct ep93xx_priv *ep = netdev_priv(dev); |
382 | int tail_offset; | ||
383 | int wake; | 366 | int wake; |
384 | 367 | ||
385 | tail_offset = rdl(ep, REG_TXSTSQCURADD) - ep->descs_dma_addr; | ||
386 | wake = 0; | 368 | wake = 0; |
387 | 369 | ||
388 | spin_lock(&ep->tx_pending_lock); | 370 | spin_lock(&ep->tx_pending_lock); |
@@ -393,15 +375,13 @@ static void ep93xx_tx_complete(struct net_device *dev) | |||
393 | 375 | ||
394 | entry = ep->tx_clean_pointer; | 376 | entry = ep->tx_clean_pointer; |
395 | tstat = ep->descs->tstat + entry; | 377 | tstat = ep->descs->tstat + entry; |
396 | if ((void *)tstat - (void *)ep->descs == tail_offset) | ||
397 | break; | ||
398 | 378 | ||
399 | tstat0 = tstat->tstat0; | 379 | tstat0 = tstat->tstat0; |
380 | if (!(tstat0 & TSTAT0_TXFP)) | ||
381 | break; | ||
382 | |||
400 | tstat->tstat0 = 0; | 383 | tstat->tstat0 = 0; |
401 | 384 | ||
402 | if (!(tstat0 & TSTAT0_TXFP)) | ||
403 | printk(KERN_CRIT "ep93xx_tx_complete: buffer not done " | ||
404 | " %.8x\n", tstat0); | ||
405 | if (tstat0 & TSTAT0_FA) | 385 | if (tstat0 & TSTAT0_FA) |
406 | printk(KERN_CRIT "ep93xx_tx_complete: frame aborted " | 386 | printk(KERN_CRIT "ep93xx_tx_complete: frame aborted " |
407 | " %.8x\n", tstat0); | 387 | " %.8x\n", tstat0); |
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c index 4873dc610d22..7db3c8af0894 100644 --- a/drivers/net/au1000_eth.c +++ b/drivers/net/au1000_eth.c | |||
@@ -102,7 +102,7 @@ static void enable_mac(struct net_device *, int); | |||
102 | // externs | 102 | // externs |
103 | extern int get_ethernet_addr(char *ethernet_addr); | 103 | extern int get_ethernet_addr(char *ethernet_addr); |
104 | extern void str2eaddr(unsigned char *ea, unsigned char *str); | 104 | extern void str2eaddr(unsigned char *ea, unsigned char *str); |
105 | extern char * __init prom_getcmdline(void); | 105 | extern char * prom_getcmdline(void); |
106 | 106 | ||
107 | /* | 107 | /* |
108 | * Theory of operation | 108 | * Theory of operation |
diff --git a/drivers/net/b44.c b/drivers/net/b44.c index b124eee4eb10..474a4e3438db 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c | |||
@@ -908,8 +908,9 @@ static irqreturn_t b44_interrupt(int irq, void *dev_id) | |||
908 | istat = br32(bp, B44_ISTAT); | 908 | istat = br32(bp, B44_ISTAT); |
909 | imask = br32(bp, B44_IMASK); | 909 | imask = br32(bp, B44_IMASK); |
910 | 910 | ||
911 | /* ??? What the fuck is the purpose of the interrupt mask | 911 | /* The interrupt mask register controls which interrupt bits |
912 | * ??? register if we have to mask it out by hand anyways? | 912 | * will actually raise an interrupt to the CPU when set by hw/firmware, |
913 | * but doesn't mask off the bits. | ||
913 | */ | 914 | */ |
914 | istat &= imask; | 915 | istat &= imask; |
915 | if (istat) { | 916 | if (istat) { |
@@ -1706,14 +1707,15 @@ static void __b44_set_rx_mode(struct net_device *dev) | |||
1706 | 1707 | ||
1707 | __b44_set_mac_addr(bp); | 1708 | __b44_set_mac_addr(bp); |
1708 | 1709 | ||
1709 | if (dev->flags & IFF_ALLMULTI) | 1710 | if ((dev->flags & IFF_ALLMULTI) || |
1711 | (dev->mc_count > B44_MCAST_TABLE_SIZE)) | ||
1710 | val |= RXCONFIG_ALLMULTI; | 1712 | val |= RXCONFIG_ALLMULTI; |
1711 | else | 1713 | else |
1712 | i = __b44_load_mcast(bp, dev); | 1714 | i = __b44_load_mcast(bp, dev); |
1713 | 1715 | ||
1714 | for (; i < 64; i++) { | 1716 | for (; i < 64; i++) |
1715 | __b44_cam_write(bp, zero, i); | 1717 | __b44_cam_write(bp, zero, i); |
1716 | } | 1718 | |
1717 | bw32(bp, B44_RXCONFIG, val); | 1719 | bw32(bp, B44_RXCONFIG, val); |
1718 | val = br32(bp, B44_CAM_CTRL); | 1720 | val = br32(bp, B44_CAM_CTRL); |
1719 | bw32(bp, B44_CAM_CTRL, val | CAM_CTRL_ENABLE); | 1721 | bw32(bp, B44_CAM_CTRL, val | CAM_CTRL_ENABLE); |
@@ -2055,7 +2057,7 @@ static int b44_read_eeprom(struct b44 *bp, u8 *data) | |||
2055 | u16 *ptr = (u16 *) data; | 2057 | u16 *ptr = (u16 *) data; |
2056 | 2058 | ||
2057 | for (i = 0; i < 128; i += 2) | 2059 | for (i = 0; i < 128; i += 2) |
2058 | ptr[i / 2] = readw(bp->regs + 4096 + i); | 2060 | ptr[i / 2] = cpu_to_le16(readw(bp->regs + 4096 + i)); |
2059 | 2061 | ||
2060 | return 0; | 2062 | return 0; |
2061 | } | 2063 | } |
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index e83bc825f6af..32923162179e 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c | |||
@@ -1433,7 +1433,7 @@ void bond_alb_monitor(struct bonding *bond) | |||
1433 | * write lock to protect from other code that also | 1433 | * write lock to protect from other code that also |
1434 | * sets the promiscuity. | 1434 | * sets the promiscuity. |
1435 | */ | 1435 | */ |
1436 | write_lock(&bond->curr_slave_lock); | 1436 | write_lock_bh(&bond->curr_slave_lock); |
1437 | 1437 | ||
1438 | if (bond_info->primary_is_promisc && | 1438 | if (bond_info->primary_is_promisc && |
1439 | (++bond_info->rlb_promisc_timeout_counter >= RLB_PROMISC_TIMEOUT)) { | 1439 | (++bond_info->rlb_promisc_timeout_counter >= RLB_PROMISC_TIMEOUT)) { |
@@ -1448,7 +1448,7 @@ void bond_alb_monitor(struct bonding *bond) | |||
1448 | bond_info->primary_is_promisc = 0; | 1448 | bond_info->primary_is_promisc = 0; |
1449 | } | 1449 | } |
1450 | 1450 | ||
1451 | write_unlock(&bond->curr_slave_lock); | 1451 | write_unlock_bh(&bond->curr_slave_lock); |
1452 | 1452 | ||
1453 | if (bond_info->rlb_rebalance) { | 1453 | if (bond_info->rlb_rebalance) { |
1454 | bond_info->rlb_rebalance = 0; | 1454 | bond_info->rlb_rebalance = 0; |
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index c0bbddae4ec4..17a461152d39 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -4692,6 +4692,8 @@ static int bond_check_params(struct bond_params *params) | |||
4692 | return 0; | 4692 | return 0; |
4693 | } | 4693 | } |
4694 | 4694 | ||
4695 | static struct lock_class_key bonding_netdev_xmit_lock_key; | ||
4696 | |||
4695 | /* Create a new bond based on the specified name and bonding parameters. | 4697 | /* Create a new bond based on the specified name and bonding parameters. |
4696 | * Caller must NOT hold rtnl_lock; we need to release it here before we | 4698 | * Caller must NOT hold rtnl_lock; we need to release it here before we |
4697 | * set up our sysfs entries. | 4699 | * set up our sysfs entries. |
@@ -4727,6 +4729,9 @@ int bond_create(char *name, struct bond_params *params, struct bonding **newbond | |||
4727 | if (res < 0) { | 4729 | if (res < 0) { |
4728 | goto out_bond; | 4730 | goto out_bond; |
4729 | } | 4731 | } |
4732 | |||
4733 | lockdep_set_class(&bond_dev->_xmit_lock, &bonding_netdev_xmit_lock_key); | ||
4734 | |||
4730 | if (newbond) | 4735 | if (newbond) |
4731 | *newbond = bond_dev->priv; | 4736 | *newbond = bond_dev->priv; |
4732 | 4737 | ||
diff --git a/drivers/net/cris/eth_v10.c b/drivers/net/cris/eth_v10.c index 966b563e42bb..a03d781f6d0a 100644 --- a/drivers/net/cris/eth_v10.c +++ b/drivers/net/cris/eth_v10.c | |||
@@ -509,6 +509,8 @@ etrax_ethernet_init(void) | |||
509 | * does not share cacheline with any other data (to avoid cache bug) | 509 | * does not share cacheline with any other data (to avoid cache bug) |
510 | */ | 510 | */ |
511 | RxDescList[i].skb = dev_alloc_skb(MAX_MEDIA_DATA_SIZE + 2 * L1_CACHE_BYTES); | 511 | RxDescList[i].skb = dev_alloc_skb(MAX_MEDIA_DATA_SIZE + 2 * L1_CACHE_BYTES); |
512 | if (!RxDescList[i].skb) | ||
513 | return -ENOMEM; | ||
512 | RxDescList[i].descr.ctrl = 0; | 514 | RxDescList[i].descr.ctrl = 0; |
513 | RxDescList[i].descr.sw_len = MAX_MEDIA_DATA_SIZE; | 515 | RxDescList[i].descr.sw_len = MAX_MEDIA_DATA_SIZE; |
514 | RxDescList[i].descr.next = virt_to_phys(&RxDescList[i + 1]); | 516 | RxDescList[i].descr.next = virt_to_phys(&RxDescList[i + 1]); |
diff --git a/drivers/net/e100.c b/drivers/net/e100.c index 27d5d2f02533..19ab3441269c 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c | |||
@@ -2039,7 +2039,6 @@ static int e100_change_mtu(struct net_device *netdev, int new_mtu) | |||
2039 | return 0; | 2039 | return 0; |
2040 | } | 2040 | } |
2041 | 2041 | ||
2042 | #ifdef CONFIG_PM | ||
2043 | static int e100_asf(struct nic *nic) | 2042 | static int e100_asf(struct nic *nic) |
2044 | { | 2043 | { |
2045 | /* ASF can be enabled from eeprom */ | 2044 | /* ASF can be enabled from eeprom */ |
@@ -2048,7 +2047,6 @@ static int e100_asf(struct nic *nic) | |||
2048 | !(nic->eeprom[eeprom_config_asf] & eeprom_gcl) && | 2047 | !(nic->eeprom[eeprom_config_asf] & eeprom_gcl) && |
2049 | ((nic->eeprom[eeprom_smbus_addr] & 0xFF) != 0xFE)); | 2048 | ((nic->eeprom[eeprom_smbus_addr] & 0xFF) != 0xFE)); |
2050 | } | 2049 | } |
2051 | #endif | ||
2052 | 2050 | ||
2053 | static int e100_up(struct nic *nic) | 2051 | static int e100_up(struct nic *nic) |
2054 | { | 2052 | { |
@@ -2715,34 +2713,35 @@ static void __devexit e100_remove(struct pci_dev *pdev) | |||
2715 | } | 2713 | } |
2716 | } | 2714 | } |
2717 | 2715 | ||
2716 | #ifdef CONFIG_PM | ||
2718 | static int e100_suspend(struct pci_dev *pdev, pm_message_t state) | 2717 | static int e100_suspend(struct pci_dev *pdev, pm_message_t state) |
2719 | { | 2718 | { |
2720 | struct net_device *netdev = pci_get_drvdata(pdev); | 2719 | struct net_device *netdev = pci_get_drvdata(pdev); |
2721 | struct nic *nic = netdev_priv(netdev); | 2720 | struct nic *nic = netdev_priv(netdev); |
2722 | 2721 | ||
2722 | #ifdef CONFIG_E100_NAPI | ||
2723 | if (netif_running(netdev)) | 2723 | if (netif_running(netdev)) |
2724 | e100_down(nic); | 2724 | netif_poll_disable(nic->netdev); |
2725 | e100_hw_reset(nic); | 2725 | #endif |
2726 | netif_device_detach(netdev); | 2726 | del_timer_sync(&nic->watchdog); |
2727 | netif_carrier_off(nic->netdev); | ||
2727 | 2728 | ||
2728 | #ifdef CONFIG_PM | ||
2729 | pci_save_state(pdev); | 2729 | pci_save_state(pdev); |
2730 | if (nic->flags & (wol_magic | e100_asf(nic))) | 2730 | |
2731 | #else | 2731 | if ((nic->flags & wol_magic) | e100_asf(nic)) { |
2732 | if (nic->flags & (wol_magic)) | 2732 | pci_enable_wake(pdev, PCI_D3hot, 1); |
2733 | #endif | 2733 | pci_enable_wake(pdev, PCI_D3cold, 1); |
2734 | pci_enable_wake(pdev, pci_choose_state(pdev, state), 1); | 2734 | } else { |
2735 | else | 2735 | pci_enable_wake(pdev, PCI_D3hot, 0); |
2736 | /* disable PME */ | 2736 | pci_enable_wake(pdev, PCI_D3cold, 0); |
2737 | pci_enable_wake(pdev, 0, 0); | 2737 | } |
2738 | 2738 | ||
2739 | pci_disable_device(pdev); | 2739 | pci_disable_device(pdev); |
2740 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | 2740 | pci_set_power_state(pdev, PCI_D3hot); |
2741 | 2741 | ||
2742 | return 0; | 2742 | return 0; |
2743 | } | 2743 | } |
2744 | 2744 | ||
2745 | #ifdef CONFIG_PM | ||
2746 | static int e100_resume(struct pci_dev *pdev) | 2745 | static int e100_resume(struct pci_dev *pdev) |
2747 | { | 2746 | { |
2748 | struct net_device *netdev = pci_get_drvdata(pdev); | 2747 | struct net_device *netdev = pci_get_drvdata(pdev); |
@@ -2764,7 +2763,26 @@ static int e100_resume(struct pci_dev *pdev) | |||
2764 | 2763 | ||
2765 | static void e100_shutdown(struct pci_dev *pdev) | 2764 | static void e100_shutdown(struct pci_dev *pdev) |
2766 | { | 2765 | { |
2767 | e100_suspend(pdev, PMSG_SUSPEND); | 2766 | struct net_device *netdev = pci_get_drvdata(pdev); |
2767 | struct nic *nic = netdev_priv(netdev); | ||
2768 | |||
2769 | #ifdef CONFIG_E100_NAPI | ||
2770 | if (netif_running(netdev)) | ||
2771 | netif_poll_disable(nic->netdev); | ||
2772 | #endif | ||
2773 | del_timer_sync(&nic->watchdog); | ||
2774 | netif_carrier_off(nic->netdev); | ||
2775 | |||
2776 | if ((nic->flags & wol_magic) | e100_asf(nic)) { | ||
2777 | pci_enable_wake(pdev, PCI_D3hot, 1); | ||
2778 | pci_enable_wake(pdev, PCI_D3cold, 1); | ||
2779 | } else { | ||
2780 | pci_enable_wake(pdev, PCI_D3hot, 0); | ||
2781 | pci_enable_wake(pdev, PCI_D3cold, 0); | ||
2782 | } | ||
2783 | |||
2784 | pci_disable_device(pdev); | ||
2785 | pci_set_power_state(pdev, PCI_D3hot); | ||
2768 | } | 2786 | } |
2769 | 2787 | ||
2770 | /* ------------------ PCI Error Recovery infrastructure -------------- */ | 2788 | /* ------------------ PCI Error Recovery infrastructure -------------- */ |
@@ -2848,9 +2866,9 @@ static struct pci_driver e100_driver = { | |||
2848 | .id_table = e100_id_table, | 2866 | .id_table = e100_id_table, |
2849 | .probe = e100_probe, | 2867 | .probe = e100_probe, |
2850 | .remove = __devexit_p(e100_remove), | 2868 | .remove = __devexit_p(e100_remove), |
2869 | #ifdef CONFIG_PM | ||
2851 | /* Power Management hooks */ | 2870 | /* Power Management hooks */ |
2852 | .suspend = e100_suspend, | 2871 | .suspend = e100_suspend, |
2853 | #ifdef CONFIG_PM | ||
2854 | .resume = e100_resume, | 2872 | .resume = e100_resume, |
2855 | #endif | 2873 | #endif |
2856 | .shutdown = e100_shutdown, | 2874 | .shutdown = e100_shutdown, |
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c index 773821e4cf57..c564adbd669b 100644 --- a/drivers/net/e1000/e1000_ethtool.c +++ b/drivers/net/e1000/e1000_ethtool.c | |||
@@ -461,7 +461,8 @@ e1000_get_regs(struct net_device *netdev, | |||
461 | regs_buff[24] = (uint32_t)phy_data; /* phy local receiver status */ | 461 | regs_buff[24] = (uint32_t)phy_data; /* phy local receiver status */ |
462 | regs_buff[25] = regs_buff[24]; /* phy remote receiver status */ | 462 | regs_buff[25] = regs_buff[24]; /* phy remote receiver status */ |
463 | if (hw->mac_type >= e1000_82540 && | 463 | if (hw->mac_type >= e1000_82540 && |
464 | hw->media_type == e1000_media_type_copper) { | 464 | hw->mac_type < e1000_82571 && |
465 | hw->media_type == e1000_media_type_copper) { | ||
465 | regs_buff[26] = E1000_READ_REG(hw, MANC); | 466 | regs_buff[26] = E1000_READ_REG(hw, MANC); |
466 | } | 467 | } |
467 | } | 468 | } |
@@ -1690,6 +1691,7 @@ static int e1000_wol_exclusion(struct e1000_adapter *adapter, struct ethtool_wol | |||
1690 | int retval = 1; /* fail by default */ | 1691 | int retval = 1; /* fail by default */ |
1691 | 1692 | ||
1692 | switch (hw->device_id) { | 1693 | switch (hw->device_id) { |
1694 | case E1000_DEV_ID_82542: | ||
1693 | case E1000_DEV_ID_82543GC_FIBER: | 1695 | case E1000_DEV_ID_82543GC_FIBER: |
1694 | case E1000_DEV_ID_82543GC_COPPER: | 1696 | case E1000_DEV_ID_82543GC_COPPER: |
1695 | case E1000_DEV_ID_82544EI_FIBER: | 1697 | case E1000_DEV_ID_82544EI_FIBER: |
diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h index 112447fd8bf2..449a60303e07 100644 --- a/drivers/net/e1000/e1000_hw.h +++ b/drivers/net/e1000/e1000_hw.h | |||
@@ -1961,9 +1961,9 @@ struct e1000_hw { | |||
1961 | #define E1000_RXDCTL_GRAN 0x01000000 /* RXDCTL Granularity */ | 1961 | #define E1000_RXDCTL_GRAN 0x01000000 /* RXDCTL Granularity */ |
1962 | 1962 | ||
1963 | /* Transmit Descriptor Control */ | 1963 | /* Transmit Descriptor Control */ |
1964 | #define E1000_TXDCTL_PTHRESH 0x000000FF /* TXDCTL Prefetch Threshold */ | 1964 | #define E1000_TXDCTL_PTHRESH 0x0000003F /* TXDCTL Prefetch Threshold */ |
1965 | #define E1000_TXDCTL_HTHRESH 0x0000FF00 /* TXDCTL Host Threshold */ | 1965 | #define E1000_TXDCTL_HTHRESH 0x00003F00 /* TXDCTL Host Threshold */ |
1966 | #define E1000_TXDCTL_WTHRESH 0x00FF0000 /* TXDCTL Writeback Threshold */ | 1966 | #define E1000_TXDCTL_WTHRESH 0x003F0000 /* TXDCTL Writeback Threshold */ |
1967 | #define E1000_TXDCTL_GRAN 0x01000000 /* TXDCTL Granularity */ | 1967 | #define E1000_TXDCTL_GRAN 0x01000000 /* TXDCTL Granularity */ |
1968 | #define E1000_TXDCTL_LWTHRESH 0xFE000000 /* TXDCTL Low Threshold */ | 1968 | #define E1000_TXDCTL_LWTHRESH 0xFE000000 /* TXDCTL Low Threshold */ |
1969 | #define E1000_TXDCTL_FULL_TX_DESC_WB 0x01010000 /* GRAN=1, WTHRESH=1 */ | 1969 | #define E1000_TXDCTL_FULL_TX_DESC_WB 0x01010000 /* GRAN=1, WTHRESH=1 */ |
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index ce0d35fe3947..726ec5e88ab2 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c | |||
@@ -35,7 +35,7 @@ static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver"; | |||
35 | #else | 35 | #else |
36 | #define DRIVERNAPI "-NAPI" | 36 | #define DRIVERNAPI "-NAPI" |
37 | #endif | 37 | #endif |
38 | #define DRV_VERSION "7.2.9-k2"DRIVERNAPI | 38 | #define DRV_VERSION "7.2.9-k4"DRIVERNAPI |
39 | char e1000_driver_version[] = DRV_VERSION; | 39 | char e1000_driver_version[] = DRV_VERSION; |
40 | static char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation."; | 40 | static char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation."; |
41 | 41 | ||
@@ -699,7 +699,10 @@ e1000_reset(struct e1000_adapter *adapter) | |||
699 | phy_data); | 699 | phy_data); |
700 | } | 700 | } |
701 | 701 | ||
702 | if ((adapter->en_mng_pt) && (adapter->hw.mac_type < e1000_82571)) { | 702 | if ((adapter->en_mng_pt) && |
703 | (adapter->hw.mac_type >= e1000_82540) && | ||
704 | (adapter->hw.mac_type < e1000_82571) && | ||
705 | (adapter->hw.media_type == e1000_media_type_copper)) { | ||
703 | manc = E1000_READ_REG(&adapter->hw, MANC); | 706 | manc = E1000_READ_REG(&adapter->hw, MANC); |
704 | manc |= (E1000_MANC_ARP_EN | E1000_MANC_EN_MNG2HOST); | 707 | manc |= (E1000_MANC_ARP_EN | E1000_MANC_EN_MNG2HOST); |
705 | E1000_WRITE_REG(&adapter->hw, MANC, manc); | 708 | E1000_WRITE_REG(&adapter->hw, MANC, manc); |
@@ -1076,8 +1079,9 @@ e1000_remove(struct pci_dev *pdev) | |||
1076 | 1079 | ||
1077 | flush_scheduled_work(); | 1080 | flush_scheduled_work(); |
1078 | 1081 | ||
1079 | if (adapter->hw.mac_type < e1000_82571 && | 1082 | if (adapter->hw.mac_type >= e1000_82540 && |
1080 | adapter->hw.media_type == e1000_media_type_copper) { | 1083 | adapter->hw.mac_type < e1000_82571 && |
1084 | adapter->hw.media_type == e1000_media_type_copper) { | ||
1081 | manc = E1000_READ_REG(&adapter->hw, MANC); | 1085 | manc = E1000_READ_REG(&adapter->hw, MANC); |
1082 | if (manc & E1000_MANC_SMBUS_EN) { | 1086 | if (manc & E1000_MANC_SMBUS_EN) { |
1083 | manc |= E1000_MANC_ARP_EN; | 1087 | manc |= E1000_MANC_ARP_EN; |
@@ -1804,9 +1808,11 @@ e1000_setup_rctl(struct e1000_adapter *adapter) | |||
1804 | * followed by the page buffers. Therefore, skb->data is | 1808 | * followed by the page buffers. Therefore, skb->data is |
1805 | * sized to hold the largest protocol header. | 1809 | * sized to hold the largest protocol header. |
1806 | */ | 1810 | */ |
1811 | /* allocations using alloc_page take too long for regular MTU | ||
1812 | * so only enable packet split for jumbo frames */ | ||
1807 | pages = PAGE_USE_COUNT(adapter->netdev->mtu); | 1813 | pages = PAGE_USE_COUNT(adapter->netdev->mtu); |
1808 | if ((adapter->hw.mac_type > e1000_82547_rev_2) && (pages <= 3) && | 1814 | if ((adapter->hw.mac_type >= e1000_82571) && (pages <= 3) && |
1809 | PAGE_SIZE <= 16384) | 1815 | PAGE_SIZE <= 16384 && (rctl & E1000_RCTL_LPE)) |
1810 | adapter->rx_ps_pages = pages; | 1816 | adapter->rx_ps_pages = pages; |
1811 | else | 1817 | else |
1812 | adapter->rx_ps_pages = 0; | 1818 | adapter->rx_ps_pages = 0; |
@@ -2986,6 +2992,11 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
2986 | return NETDEV_TX_OK; | 2992 | return NETDEV_TX_OK; |
2987 | } | 2993 | } |
2988 | 2994 | ||
2995 | /* 82571 and newer doesn't need the workaround that limited descriptor | ||
2996 | * length to 4kB */ | ||
2997 | if (adapter->hw.mac_type >= e1000_82571) | ||
2998 | max_per_txd = 8192; | ||
2999 | |||
2989 | #ifdef NETIF_F_TSO | 3000 | #ifdef NETIF_F_TSO |
2990 | mss = skb_shinfo(skb)->gso_size; | 3001 | mss = skb_shinfo(skb)->gso_size; |
2991 | /* The controller does a simple calculation to | 3002 | /* The controller does a simple calculation to |
@@ -3775,9 +3786,6 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter, | |||
3775 | 3786 | ||
3776 | length = le16_to_cpu(rx_desc->length); | 3787 | length = le16_to_cpu(rx_desc->length); |
3777 | 3788 | ||
3778 | /* adjust length to remove Ethernet CRC */ | ||
3779 | length -= 4; | ||
3780 | |||
3781 | if (unlikely(!(status & E1000_RXD_STAT_EOP))) { | 3789 | if (unlikely(!(status & E1000_RXD_STAT_EOP))) { |
3782 | /* All receives must fit into a single buffer */ | 3790 | /* All receives must fit into a single buffer */ |
3783 | E1000_DBG("%s: Receive packet consumed multiple" | 3791 | E1000_DBG("%s: Receive packet consumed multiple" |
@@ -3805,6 +3813,10 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter, | |||
3805 | } | 3813 | } |
3806 | } | 3814 | } |
3807 | 3815 | ||
3816 | /* adjust length to remove Ethernet CRC, this must be | ||
3817 | * done after the TBI_ACCEPT workaround above */ | ||
3818 | length -= 4; | ||
3819 | |||
3808 | /* code added for copybreak, this should improve | 3820 | /* code added for copybreak, this should improve |
3809 | * performance for small packets with large amounts | 3821 | * performance for small packets with large amounts |
3810 | * of reassembly being done in the stack */ | 3822 | * of reassembly being done in the stack */ |
@@ -4773,8 +4785,9 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state) | |||
4773 | pci_enable_wake(pdev, PCI_D3cold, 0); | 4785 | pci_enable_wake(pdev, PCI_D3cold, 0); |
4774 | } | 4786 | } |
4775 | 4787 | ||
4776 | if (adapter->hw.mac_type < e1000_82571 && | 4788 | if (adapter->hw.mac_type >= e1000_82540 && |
4777 | adapter->hw.media_type == e1000_media_type_copper) { | 4789 | adapter->hw.mac_type < e1000_82571 && |
4790 | adapter->hw.media_type == e1000_media_type_copper) { | ||
4778 | manc = E1000_READ_REG(&adapter->hw, MANC); | 4791 | manc = E1000_READ_REG(&adapter->hw, MANC); |
4779 | if (manc & E1000_MANC_SMBUS_EN) { | 4792 | if (manc & E1000_MANC_SMBUS_EN) { |
4780 | manc |= E1000_MANC_ARP_EN; | 4793 | manc |= E1000_MANC_ARP_EN; |
@@ -4787,6 +4800,9 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state) | |||
4787 | if (adapter->hw.phy_type == e1000_phy_igp_3) | 4800 | if (adapter->hw.phy_type == e1000_phy_igp_3) |
4788 | e1000_phy_powerdown_workaround(&adapter->hw); | 4801 | e1000_phy_powerdown_workaround(&adapter->hw); |
4789 | 4802 | ||
4803 | if (netif_running(netdev)) | ||
4804 | e1000_free_irq(adapter); | ||
4805 | |||
4790 | /* Release control of h/w to f/w. If f/w is AMT enabled, this | 4806 | /* Release control of h/w to f/w. If f/w is AMT enabled, this |
4791 | * would have already happened in close and is redundant. */ | 4807 | * would have already happened in close and is redundant. */ |
4792 | e1000_release_hw_control(adapter); | 4808 | e1000_release_hw_control(adapter); |
@@ -4817,6 +4833,10 @@ e1000_resume(struct pci_dev *pdev) | |||
4817 | pci_enable_wake(pdev, PCI_D3hot, 0); | 4833 | pci_enable_wake(pdev, PCI_D3hot, 0); |
4818 | pci_enable_wake(pdev, PCI_D3cold, 0); | 4834 | pci_enable_wake(pdev, PCI_D3cold, 0); |
4819 | 4835 | ||
4836 | if (netif_running(netdev) && (err = e1000_request_irq(adapter))) | ||
4837 | return err; | ||
4838 | |||
4839 | e1000_power_up_phy(adapter); | ||
4820 | e1000_reset(adapter); | 4840 | e1000_reset(adapter); |
4821 | E1000_WRITE_REG(&adapter->hw, WUS, ~0); | 4841 | E1000_WRITE_REG(&adapter->hw, WUS, ~0); |
4822 | 4842 | ||
@@ -4825,8 +4845,9 @@ e1000_resume(struct pci_dev *pdev) | |||
4825 | 4845 | ||
4826 | netif_device_attach(netdev); | 4846 | netif_device_attach(netdev); |
4827 | 4847 | ||
4828 | if (adapter->hw.mac_type < e1000_82571 && | 4848 | if (adapter->hw.mac_type >= e1000_82540 && |
4829 | adapter->hw.media_type == e1000_media_type_copper) { | 4849 | adapter->hw.mac_type < e1000_82571 && |
4850 | adapter->hw.media_type == e1000_media_type_copper) { | ||
4830 | manc = E1000_READ_REG(&adapter->hw, MANC); | 4851 | manc = E1000_READ_REG(&adapter->hw, MANC); |
4831 | manc &= ~(E1000_MANC_ARP_EN); | 4852 | manc &= ~(E1000_MANC_ARP_EN); |
4832 | E1000_WRITE_REG(&adapter->hw, MANC, manc); | 4853 | E1000_WRITE_REG(&adapter->hw, MANC, manc); |
@@ -4914,10 +4935,6 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev) | |||
4914 | pci_enable_wake(pdev, PCI_D3hot, 0); | 4935 | pci_enable_wake(pdev, PCI_D3hot, 0); |
4915 | pci_enable_wake(pdev, PCI_D3cold, 0); | 4936 | pci_enable_wake(pdev, PCI_D3cold, 0); |
4916 | 4937 | ||
4917 | /* Perform card reset only on one instance of the card */ | ||
4918 | if (PCI_FUNC (pdev->devfn) != 0) | ||
4919 | return PCI_ERS_RESULT_RECOVERED; | ||
4920 | |||
4921 | e1000_reset(adapter); | 4938 | e1000_reset(adapter); |
4922 | E1000_WRITE_REG(&adapter->hw, WUS, ~0); | 4939 | E1000_WRITE_REG(&adapter->hw, WUS, ~0); |
4923 | 4940 | ||
@@ -4948,6 +4965,7 @@ static void e1000_io_resume(struct pci_dev *pdev) | |||
4948 | netif_device_attach(netdev); | 4965 | netif_device_attach(netdev); |
4949 | 4966 | ||
4950 | if (adapter->hw.mac_type >= e1000_82540 && | 4967 | if (adapter->hw.mac_type >= e1000_82540 && |
4968 | adapter->hw.mac_type < e1000_82571 && | ||
4951 | adapter->hw.media_type == e1000_media_type_copper) { | 4969 | adapter->hw.media_type == e1000_media_type_copper) { |
4952 | manc = E1000_READ_REG(&adapter->hw, MANC); | 4970 | manc = E1000_READ_REG(&adapter->hw, MANC); |
4953 | manc &= ~(E1000_MANC_ARP_EN); | 4971 | manc &= ~(E1000_MANC_ARP_EN); |
diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h index 23b451a8ae12..39ad9f73d1ec 100644 --- a/drivers/net/ehea/ehea.h +++ b/drivers/net/ehea/ehea.h | |||
@@ -39,7 +39,7 @@ | |||
39 | #include <asm/io.h> | 39 | #include <asm/io.h> |
40 | 40 | ||
41 | #define DRV_NAME "ehea" | 41 | #define DRV_NAME "ehea" |
42 | #define DRV_VERSION "EHEA_0028" | 42 | #define DRV_VERSION "EHEA_0043" |
43 | 43 | ||
44 | #define EHEA_MSG_DEFAULT (NETIF_MSG_LINK | NETIF_MSG_TIMER \ | 44 | #define EHEA_MSG_DEFAULT (NETIF_MSG_LINK | NETIF_MSG_TIMER \ |
45 | | NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR) | 45 | | NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR) |
@@ -50,6 +50,7 @@ | |||
50 | #define EHEA_MAX_ENTRIES_SQ 32767 | 50 | #define EHEA_MAX_ENTRIES_SQ 32767 |
51 | #define EHEA_MIN_ENTRIES_QP 127 | 51 | #define EHEA_MIN_ENTRIES_QP 127 |
52 | 52 | ||
53 | #define EHEA_SMALL_QUEUES | ||
53 | #define EHEA_NUM_TX_QP 1 | 54 | #define EHEA_NUM_TX_QP 1 |
54 | 55 | ||
55 | #ifdef EHEA_SMALL_QUEUES | 56 | #ifdef EHEA_SMALL_QUEUES |
@@ -59,11 +60,11 @@ | |||
59 | #define EHEA_DEF_ENTRIES_RQ2 1023 | 60 | #define EHEA_DEF_ENTRIES_RQ2 1023 |
60 | #define EHEA_DEF_ENTRIES_RQ3 1023 | 61 | #define EHEA_DEF_ENTRIES_RQ3 1023 |
61 | #else | 62 | #else |
62 | #define EHEA_MAX_CQE_COUNT 32000 | 63 | #define EHEA_MAX_CQE_COUNT 4080 |
63 | #define EHEA_DEF_ENTRIES_SQ 16000 | 64 | #define EHEA_DEF_ENTRIES_SQ 4080 |
64 | #define EHEA_DEF_ENTRIES_RQ1 32080 | 65 | #define EHEA_DEF_ENTRIES_RQ1 8160 |
65 | #define EHEA_DEF_ENTRIES_RQ2 4020 | 66 | #define EHEA_DEF_ENTRIES_RQ2 2040 |
66 | #define EHEA_DEF_ENTRIES_RQ3 4020 | 67 | #define EHEA_DEF_ENTRIES_RQ3 2040 |
67 | #endif | 68 | #endif |
68 | 69 | ||
69 | #define EHEA_MAX_ENTRIES_EQ 20 | 70 | #define EHEA_MAX_ENTRIES_EQ 20 |
@@ -104,9 +105,6 @@ | |||
104 | #define EHEA_BCMC_VLANID_ALL 0x01 | 105 | #define EHEA_BCMC_VLANID_ALL 0x01 |
105 | #define EHEA_BCMC_VLANID_SINGLE 0x00 | 106 | #define EHEA_BCMC_VLANID_SINGLE 0x00 |
106 | 107 | ||
107 | /* Use this define to kmallocate pHYP control blocks */ | ||
108 | #define H_CB_ALIGNMENT 4096 | ||
109 | |||
110 | #define EHEA_CACHE_LINE 128 | 108 | #define EHEA_CACHE_LINE 128 |
111 | 109 | ||
112 | /* Memory Regions */ | 110 | /* Memory Regions */ |
diff --git a/drivers/net/ehea/ehea_ethtool.c b/drivers/net/ehea/ehea_ethtool.c index 82eb2fb8c75e..9f57c2e78ced 100644 --- a/drivers/net/ehea/ehea_ethtool.c +++ b/drivers/net/ehea/ehea_ethtool.c | |||
@@ -238,7 +238,7 @@ static void ehea_get_ethtool_stats(struct net_device *dev, | |||
238 | data[i++] = port->port_res[0].swqe_refill_th; | 238 | data[i++] = port->port_res[0].swqe_refill_th; |
239 | data[i++] = port->resets; | 239 | data[i++] = port->resets; |
240 | 240 | ||
241 | cb6 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); | 241 | cb6 = kzalloc(PAGE_SIZE, GFP_KERNEL); |
242 | if (!cb6) { | 242 | if (!cb6) { |
243 | ehea_error("no mem for cb6"); | 243 | ehea_error("no mem for cb6"); |
244 | return; | 244 | return; |
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index c6b31775e26b..6ad696101418 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c | |||
@@ -92,7 +92,7 @@ static struct net_device_stats *ehea_get_stats(struct net_device *dev) | |||
92 | 92 | ||
93 | memset(stats, 0, sizeof(*stats)); | 93 | memset(stats, 0, sizeof(*stats)); |
94 | 94 | ||
95 | cb2 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); | 95 | cb2 = kzalloc(PAGE_SIZE, GFP_KERNEL); |
96 | if (!cb2) { | 96 | if (!cb2) { |
97 | ehea_error("no mem for cb2"); | 97 | ehea_error("no mem for cb2"); |
98 | goto out; | 98 | goto out; |
@@ -586,8 +586,8 @@ int ehea_sense_port_attr(struct ehea_port *port) | |||
586 | u64 hret; | 586 | u64 hret; |
587 | struct hcp_ehea_port_cb0 *cb0; | 587 | struct hcp_ehea_port_cb0 *cb0; |
588 | 588 | ||
589 | cb0 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); | 589 | cb0 = kzalloc(PAGE_SIZE, GFP_ATOMIC); /* May be called via */ |
590 | if (!cb0) { | 590 | if (!cb0) { /* ehea_neq_tasklet() */ |
591 | ehea_error("no mem for cb0"); | 591 | ehea_error("no mem for cb0"); |
592 | ret = -ENOMEM; | 592 | ret = -ENOMEM; |
593 | goto out; | 593 | goto out; |
@@ -670,7 +670,7 @@ int ehea_set_portspeed(struct ehea_port *port, u32 port_speed) | |||
670 | u64 hret; | 670 | u64 hret; |
671 | int ret = 0; | 671 | int ret = 0; |
672 | 672 | ||
673 | cb4 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); | 673 | cb4 = kzalloc(PAGE_SIZE, GFP_KERNEL); |
674 | if (!cb4) { | 674 | if (!cb4) { |
675 | ehea_error("no mem for cb4"); | 675 | ehea_error("no mem for cb4"); |
676 | ret = -ENOMEM; | 676 | ret = -ENOMEM; |
@@ -765,8 +765,7 @@ static void ehea_parse_eqe(struct ehea_adapter *adapter, u64 eqe) | |||
765 | 765 | ||
766 | if (EHEA_BMASK_GET(NEQE_PORT_UP, eqe)) { | 766 | if (EHEA_BMASK_GET(NEQE_PORT_UP, eqe)) { |
767 | if (!netif_carrier_ok(port->netdev)) { | 767 | if (!netif_carrier_ok(port->netdev)) { |
768 | ret = ehea_sense_port_attr( | 768 | ret = ehea_sense_port_attr(port); |
769 | adapter->port[portnum]); | ||
770 | if (ret) { | 769 | if (ret) { |
771 | ehea_error("failed resensing port " | 770 | ehea_error("failed resensing port " |
772 | "attributes"); | 771 | "attributes"); |
@@ -818,7 +817,7 @@ static void ehea_parse_eqe(struct ehea_adapter *adapter, u64 eqe) | |||
818 | netif_stop_queue(port->netdev); | 817 | netif_stop_queue(port->netdev); |
819 | break; | 818 | break; |
820 | default: | 819 | default: |
821 | ehea_error("unknown event code %x", ec); | 820 | ehea_error("unknown event code %x, eqe=0x%lX", ec, eqe); |
822 | break; | 821 | break; |
823 | } | 822 | } |
824 | } | 823 | } |
@@ -986,7 +985,7 @@ static int ehea_configure_port(struct ehea_port *port) | |||
986 | struct hcp_ehea_port_cb0 *cb0; | 985 | struct hcp_ehea_port_cb0 *cb0; |
987 | 986 | ||
988 | ret = -ENOMEM; | 987 | ret = -ENOMEM; |
989 | cb0 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); | 988 | cb0 = kzalloc(PAGE_SIZE, GFP_KERNEL); |
990 | if (!cb0) | 989 | if (!cb0) |
991 | goto out; | 990 | goto out; |
992 | 991 | ||
@@ -1444,7 +1443,7 @@ static int ehea_set_mac_addr(struct net_device *dev, void *sa) | |||
1444 | goto out; | 1443 | goto out; |
1445 | } | 1444 | } |
1446 | 1445 | ||
1447 | cb0 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); | 1446 | cb0 = kzalloc(PAGE_SIZE, GFP_KERNEL); |
1448 | if (!cb0) { | 1447 | if (!cb0) { |
1449 | ehea_error("no mem for cb0"); | 1448 | ehea_error("no mem for cb0"); |
1450 | ret = -ENOMEM; | 1449 | ret = -ENOMEM; |
@@ -1502,7 +1501,7 @@ static void ehea_promiscuous(struct net_device *dev, int enable) | |||
1502 | if ((enable && port->promisc) || (!enable && !port->promisc)) | 1501 | if ((enable && port->promisc) || (!enable && !port->promisc)) |
1503 | return; | 1502 | return; |
1504 | 1503 | ||
1505 | cb7 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); | 1504 | cb7 = kzalloc(PAGE_SIZE, GFP_ATOMIC); |
1506 | if (!cb7) { | 1505 | if (!cb7) { |
1507 | ehea_error("no mem for cb7"); | 1506 | ehea_error("no mem for cb7"); |
1508 | goto out; | 1507 | goto out; |
@@ -1606,7 +1605,7 @@ static void ehea_add_multicast_entry(struct ehea_port* port, u8* mc_mac_addr) | |||
1606 | struct ehea_mc_list *ehea_mcl_entry; | 1605 | struct ehea_mc_list *ehea_mcl_entry; |
1607 | u64 hret; | 1606 | u64 hret; |
1608 | 1607 | ||
1609 | ehea_mcl_entry = kzalloc(sizeof(*ehea_mcl_entry), GFP_KERNEL); | 1608 | ehea_mcl_entry = kzalloc(sizeof(*ehea_mcl_entry), GFP_ATOMIC); |
1610 | if (!ehea_mcl_entry) { | 1609 | if (!ehea_mcl_entry) { |
1611 | ehea_error("no mem for mcl_entry"); | 1610 | ehea_error("no mem for mcl_entry"); |
1612 | return; | 1611 | return; |
@@ -1841,7 +1840,7 @@ static int ehea_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1841 | 1840 | ||
1842 | if (netif_msg_tx_queued(port)) { | 1841 | if (netif_msg_tx_queued(port)) { |
1843 | ehea_info("post swqe on QP %d", pr->qp->init_attr.qp_nr); | 1842 | ehea_info("post swqe on QP %d", pr->qp->init_attr.qp_nr); |
1844 | ehea_dump(swqe, sizeof(*swqe), "swqe"); | 1843 | ehea_dump(swqe, 512, "swqe"); |
1845 | } | 1844 | } |
1846 | 1845 | ||
1847 | ehea_post_swqe(pr->qp, swqe); | 1846 | ehea_post_swqe(pr->qp, swqe); |
@@ -1871,7 +1870,7 @@ static void ehea_vlan_rx_register(struct net_device *dev, | |||
1871 | 1870 | ||
1872 | port->vgrp = grp; | 1871 | port->vgrp = grp; |
1873 | 1872 | ||
1874 | cb1 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); | 1873 | cb1 = kzalloc(PAGE_SIZE, GFP_KERNEL); |
1875 | if (!cb1) { | 1874 | if (!cb1) { |
1876 | ehea_error("no mem for cb1"); | 1875 | ehea_error("no mem for cb1"); |
1877 | goto out; | 1876 | goto out; |
@@ -1900,7 +1899,7 @@ static void ehea_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) | |||
1900 | int index; | 1899 | int index; |
1901 | u64 hret; | 1900 | u64 hret; |
1902 | 1901 | ||
1903 | cb1 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); | 1902 | cb1 = kzalloc(PAGE_SIZE, GFP_KERNEL); |
1904 | if (!cb1) { | 1903 | if (!cb1) { |
1905 | ehea_error("no mem for cb1"); | 1904 | ehea_error("no mem for cb1"); |
1906 | goto out; | 1905 | goto out; |
@@ -1936,7 +1935,7 @@ static void ehea_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) | |||
1936 | if (port->vgrp) | 1935 | if (port->vgrp) |
1937 | port->vgrp->vlan_devices[vid] = NULL; | 1936 | port->vgrp->vlan_devices[vid] = NULL; |
1938 | 1937 | ||
1939 | cb1 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); | 1938 | cb1 = kzalloc(PAGE_SIZE, GFP_KERNEL); |
1940 | if (!cb1) { | 1939 | if (!cb1) { |
1941 | ehea_error("no mem for cb1"); | 1940 | ehea_error("no mem for cb1"); |
1942 | goto out; | 1941 | goto out; |
@@ -1969,7 +1968,7 @@ int ehea_activate_qp(struct ehea_adapter *adapter, struct ehea_qp *qp) | |||
1969 | u64 dummy64 = 0; | 1968 | u64 dummy64 = 0; |
1970 | struct hcp_modify_qp_cb0* cb0; | 1969 | struct hcp_modify_qp_cb0* cb0; |
1971 | 1970 | ||
1972 | cb0 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); | 1971 | cb0 = kzalloc(PAGE_SIZE, GFP_KERNEL); |
1973 | if (!cb0) { | 1972 | if (!cb0) { |
1974 | ret = -ENOMEM; | 1973 | ret = -ENOMEM; |
1975 | goto out; | 1974 | goto out; |
@@ -2270,7 +2269,7 @@ int ehea_sense_adapter_attr(struct ehea_adapter *adapter) | |||
2270 | u64 hret; | 2269 | u64 hret; |
2271 | int ret; | 2270 | int ret; |
2272 | 2271 | ||
2273 | cb = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); | 2272 | cb = kzalloc(PAGE_SIZE, GFP_KERNEL); |
2274 | if (!cb) { | 2273 | if (!cb) { |
2275 | ret = -ENOMEM; | 2274 | ret = -ENOMEM; |
2276 | goto out; | 2275 | goto out; |
@@ -2341,7 +2340,7 @@ static int ehea_setup_single_port(struct ehea_port *port, | |||
2341 | goto out; | 2340 | goto out; |
2342 | 2341 | ||
2343 | /* Enable Jumbo frames */ | 2342 | /* Enable Jumbo frames */ |
2344 | cb4 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); | 2343 | cb4 = kzalloc(PAGE_SIZE, GFP_KERNEL); |
2345 | if (!cb4) { | 2344 | if (!cb4) { |
2346 | ehea_error("no mem for cb4"); | 2345 | ehea_error("no mem for cb4"); |
2347 | } else { | 2346 | } else { |
diff --git a/drivers/net/ehea/ehea_phyp.c b/drivers/net/ehea/ehea_phyp.c index 4a85aca4c7e9..0cfc2bc1a27b 100644 --- a/drivers/net/ehea/ehea_phyp.c +++ b/drivers/net/ehea/ehea_phyp.c | |||
@@ -44,71 +44,99 @@ static inline u16 get_order_of_qentries(u16 queue_entries) | |||
44 | #define H_ALL_RES_TYPE_MR 5 | 44 | #define H_ALL_RES_TYPE_MR 5 |
45 | #define H_ALL_RES_TYPE_MW 6 | 45 | #define H_ALL_RES_TYPE_MW 6 |
46 | 46 | ||
47 | static long ehea_hcall_9arg_9ret(unsigned long opcode, | 47 | static long ehea_plpar_hcall_norets(unsigned long opcode, |
48 | unsigned long arg1, unsigned long arg2, | 48 | unsigned long arg1, |
49 | unsigned long arg3, unsigned long arg4, | 49 | unsigned long arg2, |
50 | unsigned long arg5, unsigned long arg6, | 50 | unsigned long arg3, |
51 | unsigned long arg7, unsigned long arg8, | 51 | unsigned long arg4, |
52 | unsigned long arg9, unsigned long *out1, | 52 | unsigned long arg5, |
53 | unsigned long *out2,unsigned long *out3, | 53 | unsigned long arg6, |
54 | unsigned long *out4,unsigned long *out5, | 54 | unsigned long arg7) |
55 | unsigned long *out6,unsigned long *out7, | ||
56 | unsigned long *out8,unsigned long *out9) | ||
57 | { | 55 | { |
58 | long hret; | 56 | long ret; |
59 | int i, sleep_msecs; | 57 | int i, sleep_msecs; |
60 | 58 | ||
61 | for (i = 0; i < 5; i++) { | 59 | for (i = 0; i < 5; i++) { |
62 | hret = plpar_hcall_9arg_9ret(opcode,arg1, arg2, arg3, arg4, | 60 | ret = plpar_hcall_norets(opcode, arg1, arg2, arg3, arg4, |
63 | arg5, arg6, arg7, arg8, arg9, out1, | 61 | arg5, arg6, arg7); |
64 | out2, out3, out4, out5, out6, out7, | 62 | |
65 | out8, out9); | 63 | if (H_IS_LONG_BUSY(ret)) { |
66 | if (H_IS_LONG_BUSY(hret)) { | 64 | sleep_msecs = get_longbusy_msecs(ret); |
67 | sleep_msecs = get_longbusy_msecs(hret); | ||
68 | msleep_interruptible(sleep_msecs); | 65 | msleep_interruptible(sleep_msecs); |
69 | continue; | 66 | continue; |
70 | } | 67 | } |
71 | 68 | ||
72 | if (hret < H_SUCCESS) | 69 | if (ret < H_SUCCESS) |
73 | ehea_error("op=%lx hret=%lx " | 70 | ehea_error("opcode=%lx ret=%lx" |
74 | "i1=%lx i2=%lx i3=%lx i4=%lx i5=%lx i6=%lx " | 71 | " arg1=%lx arg2=%lx arg3=%lx arg4=%lx" |
75 | "i7=%lx i8=%lx i9=%lx " | 72 | " arg5=%lx arg6=%lx arg7=%lx ", |
76 | "o1=%lx o2=%lx o3=%lx o4=%lx o5=%lx o6=%lx " | 73 | opcode, ret, |
77 | "o7=%lx o8=%lx o9=%lx", | 74 | arg1, arg2, arg3, arg4, arg5, |
78 | opcode, hret, arg1, arg2, arg3, arg4, arg5, | 75 | arg6, arg7); |
79 | arg6, arg7, arg8, arg9, *out1, *out2, *out3, | 76 | |
80 | *out4, *out5, *out6, *out7, *out8, *out9); | 77 | return ret; |
81 | return hret; | ||
82 | } | 78 | } |
79 | |||
83 | return H_BUSY; | 80 | return H_BUSY; |
84 | } | 81 | } |
85 | 82 | ||
86 | u64 ehea_h_query_ehea_qp(const u64 adapter_handle, const u8 qp_category, | 83 | static long ehea_plpar_hcall9(unsigned long opcode, |
87 | const u64 qp_handle, const u64 sel_mask, void *cb_addr) | 84 | unsigned long *outs, /* array of 9 outputs */ |
85 | unsigned long arg1, | ||
86 | unsigned long arg2, | ||
87 | unsigned long arg3, | ||
88 | unsigned long arg4, | ||
89 | unsigned long arg5, | ||
90 | unsigned long arg6, | ||
91 | unsigned long arg7, | ||
92 | unsigned long arg8, | ||
93 | unsigned long arg9) | ||
88 | { | 94 | { |
89 | u64 dummy; | 95 | long ret; |
96 | int i, sleep_msecs; | ||
90 | 97 | ||
91 | if ((((u64)cb_addr) & (PAGE_SIZE - 1)) != 0) { | 98 | for (i = 0; i < 5; i++) { |
92 | ehea_error("not on pageboundary"); | 99 | ret = plpar_hcall9(opcode, outs, |
93 | return H_PARAMETER; | 100 | arg1, arg2, arg3, arg4, arg5, |
101 | arg6, arg7, arg8, arg9); | ||
102 | |||
103 | if (H_IS_LONG_BUSY(ret)) { | ||
104 | sleep_msecs = get_longbusy_msecs(ret); | ||
105 | msleep_interruptible(sleep_msecs); | ||
106 | continue; | ||
107 | } | ||
108 | |||
109 | if (ret < H_SUCCESS) | ||
110 | ehea_error("opcode=%lx ret=%lx" | ||
111 | " arg1=%lx arg2=%lx arg3=%lx arg4=%lx" | ||
112 | " arg5=%lx arg6=%lx arg7=%lx arg8=%lx" | ||
113 | " arg9=%lx" | ||
114 | " out1=%lx out2=%lx out3=%lx out4=%lx" | ||
115 | " out5=%lx out6=%lx out7=%lx out8=%lx" | ||
116 | " out9=%lx", | ||
117 | opcode, ret, | ||
118 | arg1, arg2, arg3, arg4, arg5, | ||
119 | arg6, arg7, arg8, arg9, | ||
120 | outs[0], outs[1], outs[2], outs[3], | ||
121 | outs[4], outs[5], outs[6], outs[7], | ||
122 | outs[8]); | ||
123 | |||
124 | return ret; | ||
94 | } | 125 | } |
95 | 126 | ||
96 | return ehea_hcall_9arg_9ret(H_QUERY_HEA_QP, | 127 | return H_BUSY; |
97 | adapter_handle, /* R4 */ | 128 | } |
98 | qp_category, /* R5 */ | 129 | |
99 | qp_handle, /* R6 */ | 130 | u64 ehea_h_query_ehea_qp(const u64 adapter_handle, const u8 qp_category, |
100 | sel_mask, /* R7 */ | 131 | const u64 qp_handle, const u64 sel_mask, void *cb_addr) |
101 | virt_to_abs(cb_addr), /* R8 */ | 132 | { |
102 | 0, 0, 0, 0, /* R9-R12 */ | 133 | return ehea_plpar_hcall_norets(H_QUERY_HEA_QP, |
103 | &dummy, /* R4 */ | 134 | adapter_handle, /* R4 */ |
104 | &dummy, /* R5 */ | 135 | qp_category, /* R5 */ |
105 | &dummy, /* R6 */ | 136 | qp_handle, /* R6 */ |
106 | &dummy, /* R7 */ | 137 | sel_mask, /* R7 */ |
107 | &dummy, /* R8 */ | 138 | virt_to_abs(cb_addr), /* R8 */ |
108 | &dummy, /* R9 */ | 139 | 0, 0); |
109 | &dummy, /* R10 */ | ||
110 | &dummy, /* R11 */ | ||
111 | &dummy); /* R12 */ | ||
112 | } | 140 | } |
113 | 141 | ||
114 | /* input param R5 */ | 142 | /* input param R5 */ |
@@ -180,6 +208,7 @@ u64 ehea_h_alloc_resource_qp(const u64 adapter_handle, | |||
180 | u64 *qp_handle, struct h_epas *h_epas) | 208 | u64 *qp_handle, struct h_epas *h_epas) |
181 | { | 209 | { |
182 | u64 hret; | 210 | u64 hret; |
211 | u64 outs[PLPAR_HCALL9_BUFSIZE]; | ||
183 | 212 | ||
184 | u64 allocate_controls = | 213 | u64 allocate_controls = |
185 | EHEA_BMASK_SET(H_ALL_RES_QP_EQPO, init_attr->low_lat_rq1 ? 1 : 0) | 214 | EHEA_BMASK_SET(H_ALL_RES_QP_EQPO, init_attr->low_lat_rq1 ? 1 : 0) |
@@ -219,45 +248,29 @@ u64 ehea_h_alloc_resource_qp(const u64 adapter_handle, | |||
219 | EHEA_BMASK_SET(H_ALL_RES_QP_TH_RQ2, init_attr->rq2_threshold) | 248 | EHEA_BMASK_SET(H_ALL_RES_QP_TH_RQ2, init_attr->rq2_threshold) |
220 | | EHEA_BMASK_SET(H_ALL_RES_QP_TH_RQ3, init_attr->rq3_threshold); | 249 | | EHEA_BMASK_SET(H_ALL_RES_QP_TH_RQ3, init_attr->rq3_threshold); |
221 | 250 | ||
222 | u64 r5_out = 0; | 251 | hret = ehea_plpar_hcall9(H_ALLOC_HEA_RESOURCE, |
223 | u64 r6_out = 0; | 252 | outs, |
224 | u64 r7_out = 0; | 253 | adapter_handle, /* R4 */ |
225 | u64 r8_out = 0; | 254 | allocate_controls, /* R5 */ |
226 | u64 r9_out = 0; | 255 | init_attr->send_cq_handle, /* R6 */ |
227 | u64 g_la_user_out = 0; | 256 | init_attr->recv_cq_handle, /* R7 */ |
228 | u64 r11_out = 0; | 257 | init_attr->aff_eq_handle, /* R8 */ |
229 | u64 r12_out = 0; | 258 | r9_reg, /* R9 */ |
230 | 259 | max_r10_reg, /* R10 */ | |
231 | hret = ehea_hcall_9arg_9ret(H_ALLOC_HEA_RESOURCE, | 260 | r11_in, /* R11 */ |
232 | adapter_handle, /* R4 */ | 261 | threshold); /* R12 */ |
233 | allocate_controls, /* R5 */ | 262 | |
234 | init_attr->send_cq_handle, /* R6 */ | 263 | *qp_handle = outs[0]; |
235 | init_attr->recv_cq_handle, /* R7 */ | 264 | init_attr->qp_nr = (u32)outs[1]; |
236 | init_attr->aff_eq_handle, /* R8 */ | ||
237 | r9_reg, /* R9 */ | ||
238 | max_r10_reg, /* R10 */ | ||
239 | r11_in, /* R11 */ | ||
240 | threshold, /* R12 */ | ||
241 | qp_handle, /* R4 */ | ||
242 | &r5_out, /* R5 */ | ||
243 | &r6_out, /* R6 */ | ||
244 | &r7_out, /* R7 */ | ||
245 | &r8_out, /* R8 */ | ||
246 | &r9_out, /* R9 */ | ||
247 | &g_la_user_out, /* R10 */ | ||
248 | &r11_out, /* R11 */ | ||
249 | &r12_out); /* R12 */ | ||
250 | |||
251 | init_attr->qp_nr = (u32)r5_out; | ||
252 | 265 | ||
253 | init_attr->act_nr_send_wqes = | 266 | init_attr->act_nr_send_wqes = |
254 | (u16)EHEA_BMASK_GET(H_ALL_RES_QP_ACT_SWQE, r6_out); | 267 | (u16)EHEA_BMASK_GET(H_ALL_RES_QP_ACT_SWQE, outs[2]); |
255 | init_attr->act_nr_rwqes_rq1 = | 268 | init_attr->act_nr_rwqes_rq1 = |
256 | (u16)EHEA_BMASK_GET(H_ALL_RES_QP_ACT_R1WQE, r6_out); | 269 | (u16)EHEA_BMASK_GET(H_ALL_RES_QP_ACT_R1WQE, outs[2]); |
257 | init_attr->act_nr_rwqes_rq2 = | 270 | init_attr->act_nr_rwqes_rq2 = |
258 | (u16)EHEA_BMASK_GET(H_ALL_RES_QP_ACT_R2WQE, r6_out); | 271 | (u16)EHEA_BMASK_GET(H_ALL_RES_QP_ACT_R2WQE, outs[2]); |
259 | init_attr->act_nr_rwqes_rq3 = | 272 | init_attr->act_nr_rwqes_rq3 = |
260 | (u16)EHEA_BMASK_GET(H_ALL_RES_QP_ACT_R3WQE, r6_out); | 273 | (u16)EHEA_BMASK_GET(H_ALL_RES_QP_ACT_R3WQE, outs[2]); |
261 | 274 | ||
262 | init_attr->act_wqe_size_enc_sq = init_attr->wqe_size_enc_sq; | 275 | init_attr->act_wqe_size_enc_sq = init_attr->wqe_size_enc_sq; |
263 | init_attr->act_wqe_size_enc_rq1 = init_attr->wqe_size_enc_rq1; | 276 | init_attr->act_wqe_size_enc_rq1 = init_attr->wqe_size_enc_rq1; |
@@ -265,25 +278,25 @@ u64 ehea_h_alloc_resource_qp(const u64 adapter_handle, | |||
265 | init_attr->act_wqe_size_enc_rq3 = init_attr->wqe_size_enc_rq3; | 278 | init_attr->act_wqe_size_enc_rq3 = init_attr->wqe_size_enc_rq3; |
266 | 279 | ||
267 | init_attr->nr_sq_pages = | 280 | init_attr->nr_sq_pages = |
268 | (u32)EHEA_BMASK_GET(H_ALL_RES_QP_SIZE_SQ, r8_out); | 281 | (u32)EHEA_BMASK_GET(H_ALL_RES_QP_SIZE_SQ, outs[4]); |
269 | init_attr->nr_rq1_pages = | 282 | init_attr->nr_rq1_pages = |
270 | (u32)EHEA_BMASK_GET(H_ALL_RES_QP_SIZE_RQ1, r8_out); | 283 | (u32)EHEA_BMASK_GET(H_ALL_RES_QP_SIZE_RQ1, outs[4]); |
271 | init_attr->nr_rq2_pages = | 284 | init_attr->nr_rq2_pages = |
272 | (u32)EHEA_BMASK_GET(H_ALL_RES_QP_SIZE_RQ2, r9_out); | 285 | (u32)EHEA_BMASK_GET(H_ALL_RES_QP_SIZE_RQ2, outs[5]); |
273 | init_attr->nr_rq3_pages = | 286 | init_attr->nr_rq3_pages = |
274 | (u32)EHEA_BMASK_GET(H_ALL_RES_QP_SIZE_RQ3, r9_out); | 287 | (u32)EHEA_BMASK_GET(H_ALL_RES_QP_SIZE_RQ3, outs[5]); |
275 | 288 | ||
276 | init_attr->liobn_sq = | 289 | init_attr->liobn_sq = |
277 | (u32)EHEA_BMASK_GET(H_ALL_RES_QP_LIOBN_SQ, r11_out); | 290 | (u32)EHEA_BMASK_GET(H_ALL_RES_QP_LIOBN_SQ, outs[7]); |
278 | init_attr->liobn_rq1 = | 291 | init_attr->liobn_rq1 = |
279 | (u32)EHEA_BMASK_GET(H_ALL_RES_QP_LIOBN_RQ1, r11_out); | 292 | (u32)EHEA_BMASK_GET(H_ALL_RES_QP_LIOBN_RQ1, outs[7]); |
280 | init_attr->liobn_rq2 = | 293 | init_attr->liobn_rq2 = |
281 | (u32)EHEA_BMASK_GET(H_ALL_RES_QP_LIOBN_RQ2, r12_out); | 294 | (u32)EHEA_BMASK_GET(H_ALL_RES_QP_LIOBN_RQ2, outs[8]); |
282 | init_attr->liobn_rq3 = | 295 | init_attr->liobn_rq3 = |
283 | (u32)EHEA_BMASK_GET(H_ALL_RES_QP_LIOBN_RQ3, r12_out); | 296 | (u32)EHEA_BMASK_GET(H_ALL_RES_QP_LIOBN_RQ3, outs[8]); |
284 | 297 | ||
285 | if (!hret) | 298 | if (!hret) |
286 | hcp_epas_ctor(h_epas, g_la_user_out, g_la_user_out); | 299 | hcp_epas_ctor(h_epas, outs[6], outs[6]); |
287 | 300 | ||
288 | return hret; | 301 | return hret; |
289 | } | 302 | } |
@@ -292,31 +305,24 @@ u64 ehea_h_alloc_resource_cq(const u64 adapter_handle, | |||
292 | struct ehea_cq_attr *cq_attr, | 305 | struct ehea_cq_attr *cq_attr, |
293 | u64 *cq_handle, struct h_epas *epas) | 306 | u64 *cq_handle, struct h_epas *epas) |
294 | { | 307 | { |
295 | u64 hret, dummy, act_nr_of_cqes_out, act_pages_out; | 308 | u64 hret; |
296 | u64 g_la_privileged_out, g_la_user_out; | 309 | u64 outs[PLPAR_HCALL9_BUFSIZE]; |
297 | 310 | ||
298 | hret = ehea_hcall_9arg_9ret(H_ALLOC_HEA_RESOURCE, | 311 | hret = ehea_plpar_hcall9(H_ALLOC_HEA_RESOURCE, |
299 | adapter_handle, /* R4 */ | 312 | outs, |
300 | H_ALL_RES_TYPE_CQ, /* R5 */ | 313 | adapter_handle, /* R4 */ |
301 | cq_attr->eq_handle, /* R6 */ | 314 | H_ALL_RES_TYPE_CQ, /* R5 */ |
302 | cq_attr->cq_token, /* R7 */ | 315 | cq_attr->eq_handle, /* R6 */ |
303 | cq_attr->max_nr_of_cqes, /* R8 */ | 316 | cq_attr->cq_token, /* R7 */ |
304 | 0, 0, 0, 0, /* R9-R12 */ | 317 | cq_attr->max_nr_of_cqes, /* R8 */ |
305 | cq_handle, /* R4 */ | 318 | 0, 0, 0, 0); /* R9-R12 */ |
306 | &dummy, /* R5 */ | 319 | |
307 | &dummy, /* R6 */ | 320 | *cq_handle = outs[0]; |
308 | &act_nr_of_cqes_out, /* R7 */ | 321 | cq_attr->act_nr_of_cqes = outs[3]; |
309 | &act_pages_out, /* R8 */ | 322 | cq_attr->nr_pages = outs[4]; |
310 | &g_la_privileged_out, /* R9 */ | ||
311 | &g_la_user_out, /* R10 */ | ||
312 | &dummy, /* R11 */ | ||
313 | &dummy); /* R12 */ | ||
314 | |||
315 | cq_attr->act_nr_of_cqes = act_nr_of_cqes_out; | ||
316 | cq_attr->nr_pages = act_pages_out; | ||
317 | 323 | ||
318 | if (!hret) | 324 | if (!hret) |
319 | hcp_epas_ctor(epas, g_la_privileged_out, g_la_user_out); | 325 | hcp_epas_ctor(epas, outs[5], outs[6]); |
320 | 326 | ||
321 | return hret; | 327 | return hret; |
322 | } | 328 | } |
@@ -361,9 +367,8 @@ u64 ehea_h_alloc_resource_cq(const u64 adapter_handle, | |||
361 | u64 ehea_h_alloc_resource_eq(const u64 adapter_handle, | 367 | u64 ehea_h_alloc_resource_eq(const u64 adapter_handle, |
362 | struct ehea_eq_attr *eq_attr, u64 *eq_handle) | 368 | struct ehea_eq_attr *eq_attr, u64 *eq_handle) |
363 | { | 369 | { |
364 | u64 hret, dummy, eq_liobn, allocate_controls; | 370 | u64 hret, allocate_controls; |
365 | u64 ist1_out, ist2_out, ist3_out, ist4_out; | 371 | u64 outs[PLPAR_HCALL9_BUFSIZE]; |
366 | u64 act_nr_of_eqes_out, act_pages_out; | ||
367 | 372 | ||
368 | /* resource type */ | 373 | /* resource type */ |
369 | allocate_controls = | 374 | allocate_controls = |
@@ -372,27 +377,20 @@ u64 ehea_h_alloc_resource_eq(const u64 adapter_handle, | |||
372 | | EHEA_BMASK_SET(H_ALL_RES_EQ_INH_EQE_GEN, !eq_attr->eqe_gen) | 377 | | EHEA_BMASK_SET(H_ALL_RES_EQ_INH_EQE_GEN, !eq_attr->eqe_gen) |
373 | | EHEA_BMASK_SET(H_ALL_RES_EQ_NON_NEQ_ISN, 1); | 378 | | EHEA_BMASK_SET(H_ALL_RES_EQ_NON_NEQ_ISN, 1); |
374 | 379 | ||
375 | hret = ehea_hcall_9arg_9ret(H_ALLOC_HEA_RESOURCE, | 380 | hret = ehea_plpar_hcall9(H_ALLOC_HEA_RESOURCE, |
376 | adapter_handle, /* R4 */ | 381 | outs, |
377 | allocate_controls, /* R5 */ | 382 | adapter_handle, /* R4 */ |
378 | eq_attr->max_nr_of_eqes, /* R6 */ | 383 | allocate_controls, /* R5 */ |
379 | 0, 0, 0, 0, 0, 0, /* R7-R10 */ | 384 | eq_attr->max_nr_of_eqes, /* R6 */ |
380 | eq_handle, /* R4 */ | 385 | 0, 0, 0, 0, 0, 0); /* R7-R10 */ |
381 | &dummy, /* R5 */ | 386 | |
382 | &eq_liobn, /* R6 */ | 387 | *eq_handle = outs[0]; |
383 | &act_nr_of_eqes_out, /* R7 */ | 388 | eq_attr->act_nr_of_eqes = outs[3]; |
384 | &act_pages_out, /* R8 */ | 389 | eq_attr->nr_pages = outs[4]; |
385 | &ist1_out, /* R9 */ | 390 | eq_attr->ist1 = outs[5]; |
386 | &ist2_out, /* R10 */ | 391 | eq_attr->ist2 = outs[6]; |
387 | &ist3_out, /* R11 */ | 392 | eq_attr->ist3 = outs[7]; |
388 | &ist4_out); /* R12 */ | 393 | eq_attr->ist4 = outs[8]; |
389 | |||
390 | eq_attr->act_nr_of_eqes = act_nr_of_eqes_out; | ||
391 | eq_attr->nr_pages = act_pages_out; | ||
392 | eq_attr->ist1 = ist1_out; | ||
393 | eq_attr->ist2 = ist2_out; | ||
394 | eq_attr->ist3 = ist3_out; | ||
395 | eq_attr->ist4 = ist4_out; | ||
396 | 394 | ||
397 | return hret; | 395 | return hret; |
398 | } | 396 | } |
@@ -402,31 +400,22 @@ u64 ehea_h_modify_ehea_qp(const u64 adapter_handle, const u8 cat, | |||
402 | void *cb_addr, u64 *inv_attr_id, u64 *proc_mask, | 400 | void *cb_addr, u64 *inv_attr_id, u64 *proc_mask, |
403 | u16 *out_swr, u16 *out_rwr) | 401 | u16 *out_swr, u16 *out_rwr) |
404 | { | 402 | { |
405 | u64 hret, dummy, act_out_swr, act_out_rwr; | 403 | u64 hret; |
406 | 404 | u64 outs[PLPAR_HCALL9_BUFSIZE]; | |
407 | if ((((u64)cb_addr) & (PAGE_SIZE - 1)) != 0) { | 405 | |
408 | ehea_error("not on page boundary"); | 406 | hret = ehea_plpar_hcall9(H_MODIFY_HEA_QP, |
409 | return H_PARAMETER; | 407 | outs, |
410 | } | 408 | adapter_handle, /* R4 */ |
411 | 409 | (u64) cat, /* R5 */ | |
412 | hret = ehea_hcall_9arg_9ret(H_MODIFY_HEA_QP, | 410 | qp_handle, /* R6 */ |
413 | adapter_handle, /* R4 */ | 411 | sel_mask, /* R7 */ |
414 | (u64) cat, /* R5 */ | 412 | virt_to_abs(cb_addr), /* R8 */ |
415 | qp_handle, /* R6 */ | 413 | 0, 0, 0, 0); /* R9-R12 */ |
416 | sel_mask, /* R7 */ | 414 | |
417 | virt_to_abs(cb_addr), /* R8 */ | 415 | *inv_attr_id = outs[0]; |
418 | 0, 0, 0, 0, /* R9-R12 */ | 416 | *out_swr = outs[3]; |
419 | inv_attr_id, /* R4 */ | 417 | *out_rwr = outs[4]; |
420 | &dummy, /* R5 */ | 418 | *proc_mask = outs[5]; |
421 | &dummy, /* R6 */ | ||
422 | &act_out_swr, /* R7 */ | ||
423 | &act_out_rwr, /* R8 */ | ||
424 | proc_mask, /* R9 */ | ||
425 | &dummy, /* R10 */ | ||
426 | &dummy, /* R11 */ | ||
427 | &dummy); /* R12 */ | ||
428 | *out_swr = act_out_swr; | ||
429 | *out_rwr = act_out_rwr; | ||
430 | 419 | ||
431 | return hret; | 420 | return hret; |
432 | } | 421 | } |
@@ -435,122 +424,81 @@ u64 ehea_h_register_rpage(const u64 adapter_handle, const u8 pagesize, | |||
435 | const u8 queue_type, const u64 resource_handle, | 424 | const u8 queue_type, const u64 resource_handle, |
436 | const u64 log_pageaddr, u64 count) | 425 | const u64 log_pageaddr, u64 count) |
437 | { | 426 | { |
438 | u64 dummy, reg_control; | 427 | u64 reg_control; |
439 | 428 | ||
440 | reg_control = EHEA_BMASK_SET(H_REG_RPAGE_PAGE_SIZE, pagesize) | 429 | reg_control = EHEA_BMASK_SET(H_REG_RPAGE_PAGE_SIZE, pagesize) |
441 | | EHEA_BMASK_SET(H_REG_RPAGE_QT, queue_type); | 430 | | EHEA_BMASK_SET(H_REG_RPAGE_QT, queue_type); |
442 | 431 | ||
443 | return ehea_hcall_9arg_9ret(H_REGISTER_HEA_RPAGES, | 432 | return ehea_plpar_hcall_norets(H_REGISTER_HEA_RPAGES, |
444 | adapter_handle, /* R4 */ | 433 | adapter_handle, /* R4 */ |
445 | reg_control, /* R5 */ | 434 | reg_control, /* R5 */ |
446 | resource_handle, /* R6 */ | 435 | resource_handle, /* R6 */ |
447 | log_pageaddr, /* R7 */ | 436 | log_pageaddr, /* R7 */ |
448 | count, /* R8 */ | 437 | count, /* R8 */ |
449 | 0, 0, 0, 0, /* R9-R12 */ | 438 | 0, 0); /* R9-R10 */ |
450 | &dummy, /* R4 */ | ||
451 | &dummy, /* R5 */ | ||
452 | &dummy, /* R6 */ | ||
453 | &dummy, /* R7 */ | ||
454 | &dummy, /* R8 */ | ||
455 | &dummy, /* R9 */ | ||
456 | &dummy, /* R10 */ | ||
457 | &dummy, /* R11 */ | ||
458 | &dummy); /* R12 */ | ||
459 | } | 439 | } |
460 | 440 | ||
461 | u64 ehea_h_register_smr(const u64 adapter_handle, const u64 orig_mr_handle, | 441 | u64 ehea_h_register_smr(const u64 adapter_handle, const u64 orig_mr_handle, |
462 | const u64 vaddr_in, const u32 access_ctrl, const u32 pd, | 442 | const u64 vaddr_in, const u32 access_ctrl, const u32 pd, |
463 | struct ehea_mr *mr) | 443 | struct ehea_mr *mr) |
464 | { | 444 | { |
465 | u64 hret, dummy, lkey_out; | 445 | u64 hret; |
466 | 446 | u64 outs[PLPAR_HCALL9_BUFSIZE]; | |
467 | hret = ehea_hcall_9arg_9ret(H_REGISTER_SMR, | 447 | |
468 | adapter_handle , /* R4 */ | 448 | hret = ehea_plpar_hcall9(H_REGISTER_SMR, |
469 | orig_mr_handle, /* R5 */ | 449 | outs, |
470 | vaddr_in, /* R6 */ | 450 | adapter_handle , /* R4 */ |
471 | (((u64)access_ctrl) << 32ULL), /* R7 */ | 451 | orig_mr_handle, /* R5 */ |
472 | pd, /* R8 */ | 452 | vaddr_in, /* R6 */ |
473 | 0, 0, 0, 0, /* R9-R12 */ | 453 | (((u64)access_ctrl) << 32ULL), /* R7 */ |
474 | &mr->handle, /* R4 */ | 454 | pd, /* R8 */ |
475 | &dummy, /* R5 */ | 455 | 0, 0, 0, 0); /* R9-R12 */ |
476 | &lkey_out, /* R6 */ | 456 | |
477 | &dummy, /* R7 */ | 457 | mr->handle = outs[0]; |
478 | &dummy, /* R8 */ | 458 | mr->lkey = (u32)outs[2]; |
479 | &dummy, /* R9 */ | ||
480 | &dummy, /* R10 */ | ||
481 | &dummy, /* R11 */ | ||
482 | &dummy); /* R12 */ | ||
483 | mr->lkey = (u32)lkey_out; | ||
484 | 459 | ||
485 | return hret; | 460 | return hret; |
486 | } | 461 | } |
487 | 462 | ||
488 | u64 ehea_h_disable_and_get_hea(const u64 adapter_handle, const u64 qp_handle) | 463 | u64 ehea_h_disable_and_get_hea(const u64 adapter_handle, const u64 qp_handle) |
489 | { | 464 | { |
490 | u64 hret, dummy, ladr_next_sq_wqe_out; | 465 | u64 outs[PLPAR_HCALL9_BUFSIZE]; |
491 | u64 ladr_next_rq1_wqe_out, ladr_next_rq2_wqe_out, ladr_next_rq3_wqe_out; | 466 | |
492 | 467 | return ehea_plpar_hcall9(H_DISABLE_AND_GET_HEA, | |
493 | hret = ehea_hcall_9arg_9ret(H_DISABLE_AND_GET_HEA, | 468 | outs, |
494 | adapter_handle, /* R4 */ | 469 | adapter_handle, /* R4 */ |
495 | H_DISABLE_GET_EHEA_WQE_P, /* R5 */ | 470 | H_DISABLE_GET_EHEA_WQE_P, /* R5 */ |
496 | qp_handle, /* R6 */ | 471 | qp_handle, /* R6 */ |
497 | 0, 0, 0, 0, 0, 0, /* R7-R12 */ | 472 | 0, 0, 0, 0, 0, 0); /* R7-R12 */ |
498 | &ladr_next_sq_wqe_out, /* R4 */ | ||
499 | &ladr_next_rq1_wqe_out, /* R5 */ | ||
500 | &ladr_next_rq2_wqe_out, /* R6 */ | ||
501 | &ladr_next_rq3_wqe_out, /* R7 */ | ||
502 | &dummy, /* R8 */ | ||
503 | &dummy, /* R9 */ | ||
504 | &dummy, /* R10 */ | ||
505 | &dummy, /* R11 */ | ||
506 | &dummy); /* R12 */ | ||
507 | return hret; | ||
508 | } | 473 | } |
509 | 474 | ||
510 | u64 ehea_h_free_resource(const u64 adapter_handle, const u64 res_handle) | 475 | u64 ehea_h_free_resource(const u64 adapter_handle, const u64 res_handle) |
511 | { | 476 | { |
512 | u64 dummy; | 477 | return ehea_plpar_hcall_norets(H_FREE_RESOURCE, |
513 | 478 | adapter_handle, /* R4 */ | |
514 | return ehea_hcall_9arg_9ret(H_FREE_RESOURCE, | 479 | res_handle, /* R5 */ |
515 | adapter_handle, /* R4 */ | 480 | 0, 0, 0, 0, 0); /* R6-R10 */ |
516 | res_handle, /* R5 */ | ||
517 | 0, 0, 0, 0, 0, 0, 0, /* R6-R12 */ | ||
518 | &dummy, /* R4 */ | ||
519 | &dummy, /* R5 */ | ||
520 | &dummy, /* R6 */ | ||
521 | &dummy, /* R7 */ | ||
522 | &dummy, /* R8 */ | ||
523 | &dummy, /* R9 */ | ||
524 | &dummy, /* R10 */ | ||
525 | &dummy, /* R11 */ | ||
526 | &dummy); /* R12 */ | ||
527 | } | 481 | } |
528 | 482 | ||
529 | u64 ehea_h_alloc_resource_mr(const u64 adapter_handle, const u64 vaddr, | 483 | u64 ehea_h_alloc_resource_mr(const u64 adapter_handle, const u64 vaddr, |
530 | const u64 length, const u32 access_ctrl, | 484 | const u64 length, const u32 access_ctrl, |
531 | const u32 pd, u64 *mr_handle, u32 *lkey) | 485 | const u32 pd, u64 *mr_handle, u32 *lkey) |
532 | { | 486 | { |
533 | u64 hret, dummy, lkey_out; | 487 | u64 hret; |
534 | 488 | u64 outs[PLPAR_HCALL9_BUFSIZE]; | |
535 | hret = ehea_hcall_9arg_9ret(H_ALLOC_HEA_RESOURCE, | 489 | |
536 | adapter_handle, /* R4 */ | 490 | hret = ehea_plpar_hcall9(H_ALLOC_HEA_RESOURCE, |
537 | 5, /* R5 */ | 491 | outs, |
538 | vaddr, /* R6 */ | 492 | adapter_handle, /* R4 */ |
539 | length, /* R7 */ | 493 | 5, /* R5 */ |
540 | (((u64) access_ctrl) << 32ULL),/* R8 */ | 494 | vaddr, /* R6 */ |
541 | pd, /* R9 */ | 495 | length, /* R7 */ |
542 | 0, 0, 0, /* R10-R12 */ | 496 | (((u64) access_ctrl) << 32ULL), /* R8 */ |
543 | mr_handle, /* R4 */ | 497 | pd, /* R9 */ |
544 | &dummy, /* R5 */ | 498 | 0, 0, 0); /* R10-R12 */ |
545 | &lkey_out, /* R6 */ | 499 | |
546 | &dummy, /* R7 */ | 500 | *mr_handle = outs[0]; |
547 | &dummy, /* R8 */ | 501 | *lkey = (u32)outs[2]; |
548 | &dummy, /* R9 */ | ||
549 | &dummy, /* R10 */ | ||
550 | &dummy, /* R11 */ | ||
551 | &dummy); /* R12 */ | ||
552 | *lkey = (u32) lkey_out; | ||
553 | |||
554 | return hret; | 502 | return hret; |
555 | } | 503 | } |
556 | 504 | ||
@@ -558,7 +506,7 @@ u64 ehea_h_register_rpage_mr(const u64 adapter_handle, const u64 mr_handle, | |||
558 | const u8 pagesize, const u8 queue_type, | 506 | const u8 pagesize, const u8 queue_type, |
559 | const u64 log_pageaddr, const u64 count) | 507 | const u64 log_pageaddr, const u64 count) |
560 | { | 508 | { |
561 | if ((count > 1) && (log_pageaddr & 0xfff)) { | 509 | if ((count > 1) && (log_pageaddr & ~PAGE_MASK)) { |
562 | ehea_error("not on pageboundary"); | 510 | ehea_error("not on pageboundary"); |
563 | return H_PARAMETER; | 511 | return H_PARAMETER; |
564 | } | 512 | } |
@@ -570,23 +518,14 @@ u64 ehea_h_register_rpage_mr(const u64 adapter_handle, const u64 mr_handle, | |||
570 | 518 | ||
571 | u64 ehea_h_query_ehea(const u64 adapter_handle, void *cb_addr) | 519 | u64 ehea_h_query_ehea(const u64 adapter_handle, void *cb_addr) |
572 | { | 520 | { |
573 | u64 hret, dummy, cb_logaddr; | 521 | u64 hret, cb_logaddr; |
574 | 522 | ||
575 | cb_logaddr = virt_to_abs(cb_addr); | 523 | cb_logaddr = virt_to_abs(cb_addr); |
576 | 524 | ||
577 | hret = ehea_hcall_9arg_9ret(H_QUERY_HEA, | 525 | hret = ehea_plpar_hcall_norets(H_QUERY_HEA, |
578 | adapter_handle, /* R4 */ | 526 | adapter_handle, /* R4 */ |
579 | cb_logaddr, /* R5 */ | 527 | cb_logaddr, /* R5 */ |
580 | 0, 0, 0, 0, 0, 0, 0, /* R6-R12 */ | 528 | 0, 0, 0, 0, 0); /* R6-R10 */ |
581 | &dummy, /* R4 */ | ||
582 | &dummy, /* R5 */ | ||
583 | &dummy, /* R6 */ | ||
584 | &dummy, /* R7 */ | ||
585 | &dummy, /* R8 */ | ||
586 | &dummy, /* R9 */ | ||
587 | &dummy, /* R10 */ | ||
588 | &dummy, /* R11 */ | ||
589 | &dummy); /* R12 */ | ||
590 | #ifdef DEBUG | 529 | #ifdef DEBUG |
591 | ehea_dmp(cb_addr, sizeof(struct hcp_query_ehea), "hcp_query_ehea"); | 530 | ehea_dmp(cb_addr, sizeof(struct hcp_query_ehea), "hcp_query_ehea"); |
592 | #endif | 531 | #endif |
@@ -597,36 +536,28 @@ u64 ehea_h_query_ehea_port(const u64 adapter_handle, const u16 port_num, | |||
597 | const u8 cb_cat, const u64 select_mask, | 536 | const u8 cb_cat, const u64 select_mask, |
598 | void *cb_addr) | 537 | void *cb_addr) |
599 | { | 538 | { |
600 | u64 port_info, dummy; | 539 | u64 port_info; |
601 | u64 cb_logaddr = virt_to_abs(cb_addr); | 540 | u64 cb_logaddr = virt_to_abs(cb_addr); |
602 | u64 arr_index = 0; | 541 | u64 arr_index = 0; |
603 | 542 | ||
604 | port_info = EHEA_BMASK_SET(H_MEHEAPORT_CAT, cb_cat) | 543 | port_info = EHEA_BMASK_SET(H_MEHEAPORT_CAT, cb_cat) |
605 | | EHEA_BMASK_SET(H_MEHEAPORT_PN, port_num); | 544 | | EHEA_BMASK_SET(H_MEHEAPORT_PN, port_num); |
606 | 545 | ||
607 | return ehea_hcall_9arg_9ret(H_QUERY_HEA_PORT, | 546 | return ehea_plpar_hcall_norets(H_QUERY_HEA_PORT, |
608 | adapter_handle, /* R4 */ | 547 | adapter_handle, /* R4 */ |
609 | port_info, /* R5 */ | 548 | port_info, /* R5 */ |
610 | select_mask, /* R6 */ | 549 | select_mask, /* R6 */ |
611 | arr_index, /* R7 */ | 550 | arr_index, /* R7 */ |
612 | cb_logaddr, /* R8 */ | 551 | cb_logaddr, /* R8 */ |
613 | 0, 0, 0, 0, /* R9-R12 */ | 552 | 0, 0); /* R9-R10 */ |
614 | &dummy, /* R4 */ | ||
615 | &dummy, /* R5 */ | ||
616 | &dummy, /* R6 */ | ||
617 | &dummy, /* R7 */ | ||
618 | &dummy, /* R8 */ | ||
619 | &dummy, /* R9 */ | ||
620 | &dummy, /* R10 */ | ||
621 | &dummy, /* R11 */ | ||
622 | &dummy); /* R12 */ | ||
623 | } | 553 | } |
624 | 554 | ||
625 | u64 ehea_h_modify_ehea_port(const u64 adapter_handle, const u16 port_num, | 555 | u64 ehea_h_modify_ehea_port(const u64 adapter_handle, const u16 port_num, |
626 | const u8 cb_cat, const u64 select_mask, | 556 | const u8 cb_cat, const u64 select_mask, |
627 | void *cb_addr) | 557 | void *cb_addr) |
628 | { | 558 | { |
629 | u64 port_info, dummy, inv_attr_ident, proc_mask; | 559 | u64 outs[PLPAR_HCALL9_BUFSIZE]; |
560 | u64 port_info; | ||
630 | u64 arr_index = 0; | 561 | u64 arr_index = 0; |
631 | u64 cb_logaddr = virt_to_abs(cb_addr); | 562 | u64 cb_logaddr = virt_to_abs(cb_addr); |
632 | 563 | ||
@@ -635,29 +566,21 @@ u64 ehea_h_modify_ehea_port(const u64 adapter_handle, const u16 port_num, | |||
635 | #ifdef DEBUG | 566 | #ifdef DEBUG |
636 | ehea_dump(cb_addr, sizeof(struct hcp_ehea_port_cb0), "Before HCALL"); | 567 | ehea_dump(cb_addr, sizeof(struct hcp_ehea_port_cb0), "Before HCALL"); |
637 | #endif | 568 | #endif |
638 | return ehea_hcall_9arg_9ret(H_MODIFY_HEA_PORT, | 569 | return ehea_plpar_hcall9(H_MODIFY_HEA_PORT, |
639 | adapter_handle, /* R4 */ | 570 | outs, |
640 | port_info, /* R5 */ | 571 | adapter_handle, /* R4 */ |
641 | select_mask, /* R6 */ | 572 | port_info, /* R5 */ |
642 | arr_index, /* R7 */ | 573 | select_mask, /* R6 */ |
643 | cb_logaddr, /* R8 */ | 574 | arr_index, /* R7 */ |
644 | 0, 0, 0, 0, /* R9-R12 */ | 575 | cb_logaddr, /* R8 */ |
645 | &inv_attr_ident, /* R4 */ | 576 | 0, 0, 0, 0); /* R9-R12 */ |
646 | &proc_mask, /* R5 */ | ||
647 | &dummy, /* R6 */ | ||
648 | &dummy, /* R7 */ | ||
649 | &dummy, /* R8 */ | ||
650 | &dummy, /* R9 */ | ||
651 | &dummy, /* R10 */ | ||
652 | &dummy, /* R11 */ | ||
653 | &dummy); /* R12 */ | ||
654 | } | 577 | } |
655 | 578 | ||
656 | u64 ehea_h_reg_dereg_bcmc(const u64 adapter_handle, const u16 port_num, | 579 | u64 ehea_h_reg_dereg_bcmc(const u64 adapter_handle, const u16 port_num, |
657 | const u8 reg_type, const u64 mc_mac_addr, | 580 | const u8 reg_type, const u64 mc_mac_addr, |
658 | const u16 vlan_id, const u32 hcall_id) | 581 | const u16 vlan_id, const u32 hcall_id) |
659 | { | 582 | { |
660 | u64 r5_port_num, r6_reg_type, r7_mc_mac_addr, r8_vlan_id, dummy; | 583 | u64 r5_port_num, r6_reg_type, r7_mc_mac_addr, r8_vlan_id; |
661 | u64 mac_addr = mc_mac_addr >> 16; | 584 | u64 mac_addr = mc_mac_addr >> 16; |
662 | 585 | ||
663 | r5_port_num = EHEA_BMASK_SET(H_REGBCMC_PN, port_num); | 586 | r5_port_num = EHEA_BMASK_SET(H_REGBCMC_PN, port_num); |
@@ -665,41 +588,21 @@ u64 ehea_h_reg_dereg_bcmc(const u64 adapter_handle, const u16 port_num, | |||
665 | r7_mc_mac_addr = EHEA_BMASK_SET(H_REGBCMC_MACADDR, mac_addr); | 588 | r7_mc_mac_addr = EHEA_BMASK_SET(H_REGBCMC_MACADDR, mac_addr); |
666 | r8_vlan_id = EHEA_BMASK_SET(H_REGBCMC_VLANID, vlan_id); | 589 | r8_vlan_id = EHEA_BMASK_SET(H_REGBCMC_VLANID, vlan_id); |
667 | 590 | ||
668 | return ehea_hcall_9arg_9ret(hcall_id, | 591 | return ehea_plpar_hcall_norets(hcall_id, |
669 | adapter_handle, /* R4 */ | 592 | adapter_handle, /* R4 */ |
670 | r5_port_num, /* R5 */ | 593 | r5_port_num, /* R5 */ |
671 | r6_reg_type, /* R6 */ | 594 | r6_reg_type, /* R6 */ |
672 | r7_mc_mac_addr, /* R7 */ | 595 | r7_mc_mac_addr, /* R7 */ |
673 | r8_vlan_id, /* R8 */ | 596 | r8_vlan_id, /* R8 */ |
674 | 0, 0, 0, 0, /* R9-R12 */ | 597 | 0, 0); /* R9-R12 */ |
675 | &dummy, /* R4 */ | ||
676 | &dummy, /* R5 */ | ||
677 | &dummy, /* R6 */ | ||
678 | &dummy, /* R7 */ | ||
679 | &dummy, /* R8 */ | ||
680 | &dummy, /* R9 */ | ||
681 | &dummy, /* R10 */ | ||
682 | &dummy, /* R11 */ | ||
683 | &dummy); /* R12 */ | ||
684 | } | 598 | } |
685 | 599 | ||
686 | u64 ehea_h_reset_events(const u64 adapter_handle, const u64 neq_handle, | 600 | u64 ehea_h_reset_events(const u64 adapter_handle, const u64 neq_handle, |
687 | const u64 event_mask) | 601 | const u64 event_mask) |
688 | { | 602 | { |
689 | u64 dummy; | 603 | return ehea_plpar_hcall_norets(H_RESET_EVENTS, |
690 | 604 | adapter_handle, /* R4 */ | |
691 | return ehea_hcall_9arg_9ret(H_RESET_EVENTS, | 605 | neq_handle, /* R5 */ |
692 | adapter_handle, /* R4 */ | 606 | event_mask, /* R6 */ |
693 | neq_handle, /* R5 */ | 607 | 0, 0, 0, 0); /* R7-R12 */ |
694 | event_mask, /* R6 */ | ||
695 | 0, 0, 0, 0, 0, 0, /* R7-R12 */ | ||
696 | &dummy, /* R4 */ | ||
697 | &dummy, /* R5 */ | ||
698 | &dummy, /* R6 */ | ||
699 | &dummy, /* R7 */ | ||
700 | &dummy, /* R8 */ | ||
701 | &dummy, /* R9 */ | ||
702 | &dummy, /* R10 */ | ||
703 | &dummy, /* R11 */ | ||
704 | &dummy); /* R12 */ | ||
705 | } | 608 | } |
diff --git a/drivers/net/ehea/ehea_phyp.h b/drivers/net/ehea/ehea_phyp.h index fa51e3b5bb05..919f94b75933 100644 --- a/drivers/net/ehea/ehea_phyp.h +++ b/drivers/net/ehea/ehea_phyp.h | |||
@@ -81,14 +81,16 @@ static inline u32 get_longbusy_msecs(int long_busy_ret_code) | |||
81 | static inline void hcp_epas_ctor(struct h_epas *epas, u64 paddr_kernel, | 81 | static inline void hcp_epas_ctor(struct h_epas *epas, u64 paddr_kernel, |
82 | u64 paddr_user) | 82 | u64 paddr_user) |
83 | { | 83 | { |
84 | epas->kernel.addr = ioremap(paddr_kernel, PAGE_SIZE); | 84 | /* To support 64k pages we must round to 64k page boundary */ |
85 | epas->kernel.addr = ioremap((paddr_kernel & PAGE_MASK), PAGE_SIZE) + | ||
86 | (paddr_kernel & ~PAGE_MASK); | ||
85 | epas->user.addr = paddr_user; | 87 | epas->user.addr = paddr_user; |
86 | } | 88 | } |
87 | 89 | ||
88 | static inline void hcp_epas_dtor(struct h_epas *epas) | 90 | static inline void hcp_epas_dtor(struct h_epas *epas) |
89 | { | 91 | { |
90 | if (epas->kernel.addr) | 92 | if (epas->kernel.addr) |
91 | iounmap(epas->kernel.addr); | 93 | iounmap((void __iomem*)((u64)epas->kernel.addr & PAGE_MASK)); |
92 | 94 | ||
93 | epas->user.addr = 0; | 95 | epas->user.addr = 0; |
94 | epas->kernel.addr = 0; | 96 | epas->kernel.addr = 0; |
diff --git a/drivers/net/ehea/ehea_qmr.c b/drivers/net/ehea/ehea_qmr.c index 3e1862326c88..72ef7bde3346 100644 --- a/drivers/net/ehea/ehea_qmr.c +++ b/drivers/net/ehea/ehea_qmr.c | |||
@@ -209,11 +209,11 @@ int ehea_destroy_cq(struct ehea_cq *cq) | |||
209 | { | 209 | { |
210 | u64 adapter_handle, hret; | 210 | u64 adapter_handle, hret; |
211 | 211 | ||
212 | adapter_handle = cq->adapter->handle; | ||
213 | |||
214 | if (!cq) | 212 | if (!cq) |
215 | return 0; | 213 | return 0; |
216 | 214 | ||
215 | adapter_handle = cq->adapter->handle; | ||
216 | |||
217 | /* deregister all previous registered pages */ | 217 | /* deregister all previous registered pages */ |
218 | hret = ehea_h_free_resource(adapter_handle, cq->fw_handle); | 218 | hret = ehea_h_free_resource(adapter_handle, cq->fw_handle); |
219 | if (hret != H_SUCCESS) { | 219 | if (hret != H_SUCCESS) { |
@@ -512,7 +512,7 @@ int ehea_reg_mr_adapter(struct ehea_adapter *adapter) | |||
512 | 512 | ||
513 | start = KERNELBASE; | 513 | start = KERNELBASE; |
514 | end = (u64)high_memory; | 514 | end = (u64)high_memory; |
515 | nr_pages = (end - start) / PAGE_SIZE; | 515 | nr_pages = (end - start) / EHEA_PAGESIZE; |
516 | 516 | ||
517 | pt = kzalloc(PAGE_SIZE, GFP_KERNEL); | 517 | pt = kzalloc(PAGE_SIZE, GFP_KERNEL); |
518 | if (!pt) { | 518 | if (!pt) { |
@@ -538,9 +538,9 @@ int ehea_reg_mr_adapter(struct ehea_adapter *adapter) | |||
538 | if (nr_pages > 1) { | 538 | if (nr_pages > 1) { |
539 | u64 num_pages = min(nr_pages, (u64)512); | 539 | u64 num_pages = min(nr_pages, (u64)512); |
540 | for (i = 0; i < num_pages; i++) | 540 | for (i = 0; i < num_pages; i++) |
541 | pt[i] = virt_to_abs((void*)(((u64)start) | 541 | pt[i] = virt_to_abs((void*)(((u64)start) + |
542 | + ((k++) * | 542 | ((k++) * |
543 | PAGE_SIZE))); | 543 | EHEA_PAGESIZE))); |
544 | 544 | ||
545 | hret = ehea_h_register_rpage_mr(adapter->handle, | 545 | hret = ehea_h_register_rpage_mr(adapter->handle, |
546 | adapter->mr.handle, 0, | 546 | adapter->mr.handle, 0, |
@@ -548,8 +548,9 @@ int ehea_reg_mr_adapter(struct ehea_adapter *adapter) | |||
548 | num_pages); | 548 | num_pages); |
549 | nr_pages -= num_pages; | 549 | nr_pages -= num_pages; |
550 | } else { | 550 | } else { |
551 | u64 abs_adr = virt_to_abs((void*)(((u64)start) | 551 | u64 abs_adr = virt_to_abs((void*)(((u64)start) + |
552 | + (k * PAGE_SIZE))); | 552 | (k * EHEA_PAGESIZE))); |
553 | |||
553 | hret = ehea_h_register_rpage_mr(adapter->handle, | 554 | hret = ehea_h_register_rpage_mr(adapter->handle, |
554 | adapter->mr.handle, 0, | 555 | adapter->mr.handle, 0, |
555 | 0, abs_adr,1); | 556 | 0, abs_adr,1); |
diff --git a/drivers/net/eth16i.c b/drivers/net/eth16i.c index 8cc3c331aca8..b7b8bc2a6307 100644 --- a/drivers/net/eth16i.c +++ b/drivers/net/eth16i.c | |||
@@ -162,9 +162,9 @@ static char *version = | |||
162 | #include <linux/skbuff.h> | 162 | #include <linux/skbuff.h> |
163 | #include <linux/bitops.h> | 163 | #include <linux/bitops.h> |
164 | #include <linux/jiffies.h> | 164 | #include <linux/jiffies.h> |
165 | #include <linux/io.h> | ||
165 | 166 | ||
166 | #include <asm/system.h> | 167 | #include <asm/system.h> |
167 | #include <asm/io.h> | ||
168 | #include <asm/dma.h> | 168 | #include <asm/dma.h> |
169 | 169 | ||
170 | 170 | ||
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 99b7a411db28..c5ed635bce36 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c | |||
@@ -2497,6 +2497,7 @@ static irqreturn_t nv_nic_irq_tx(int foo, void *data) | |||
2497 | u8 __iomem *base = get_hwbase(dev); | 2497 | u8 __iomem *base = get_hwbase(dev); |
2498 | u32 events; | 2498 | u32 events; |
2499 | int i; | 2499 | int i; |
2500 | unsigned long flags; | ||
2500 | 2501 | ||
2501 | dprintk(KERN_DEBUG "%s: nv_nic_irq_tx\n", dev->name); | 2502 | dprintk(KERN_DEBUG "%s: nv_nic_irq_tx\n", dev->name); |
2502 | 2503 | ||
@@ -2508,16 +2509,16 @@ static irqreturn_t nv_nic_irq_tx(int foo, void *data) | |||
2508 | if (!(events & np->irqmask)) | 2509 | if (!(events & np->irqmask)) |
2509 | break; | 2510 | break; |
2510 | 2511 | ||
2511 | spin_lock_irq(&np->lock); | 2512 | spin_lock_irqsave(&np->lock, flags); |
2512 | nv_tx_done(dev); | 2513 | nv_tx_done(dev); |
2513 | spin_unlock_irq(&np->lock); | 2514 | spin_unlock_irqrestore(&np->lock, flags); |
2514 | 2515 | ||
2515 | if (events & (NVREG_IRQ_TX_ERR)) { | 2516 | if (events & (NVREG_IRQ_TX_ERR)) { |
2516 | dprintk(KERN_DEBUG "%s: received irq with events 0x%x. Probably TX fail.\n", | 2517 | dprintk(KERN_DEBUG "%s: received irq with events 0x%x. Probably TX fail.\n", |
2517 | dev->name, events); | 2518 | dev->name, events); |
2518 | } | 2519 | } |
2519 | if (i > max_interrupt_work) { | 2520 | if (i > max_interrupt_work) { |
2520 | spin_lock_irq(&np->lock); | 2521 | spin_lock_irqsave(&np->lock, flags); |
2521 | /* disable interrupts on the nic */ | 2522 | /* disable interrupts on the nic */ |
2522 | writel(NVREG_IRQ_TX_ALL, base + NvRegIrqMask); | 2523 | writel(NVREG_IRQ_TX_ALL, base + NvRegIrqMask); |
2523 | pci_push(base); | 2524 | pci_push(base); |
@@ -2527,7 +2528,7 @@ static irqreturn_t nv_nic_irq_tx(int foo, void *data) | |||
2527 | mod_timer(&np->nic_poll, jiffies + POLL_WAIT); | 2528 | mod_timer(&np->nic_poll, jiffies + POLL_WAIT); |
2528 | } | 2529 | } |
2529 | printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_tx.\n", dev->name, i); | 2530 | printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_tx.\n", dev->name, i); |
2530 | spin_unlock_irq(&np->lock); | 2531 | spin_unlock_irqrestore(&np->lock, flags); |
2531 | break; | 2532 | break; |
2532 | } | 2533 | } |
2533 | 2534 | ||
@@ -2601,6 +2602,7 @@ static irqreturn_t nv_nic_irq_rx(int foo, void *data) | |||
2601 | u8 __iomem *base = get_hwbase(dev); | 2602 | u8 __iomem *base = get_hwbase(dev); |
2602 | u32 events; | 2603 | u32 events; |
2603 | int i; | 2604 | int i; |
2605 | unsigned long flags; | ||
2604 | 2606 | ||
2605 | dprintk(KERN_DEBUG "%s: nv_nic_irq_rx\n", dev->name); | 2607 | dprintk(KERN_DEBUG "%s: nv_nic_irq_rx\n", dev->name); |
2606 | 2608 | ||
@@ -2614,14 +2616,14 @@ static irqreturn_t nv_nic_irq_rx(int foo, void *data) | |||
2614 | 2616 | ||
2615 | nv_rx_process(dev, dev->weight); | 2617 | nv_rx_process(dev, dev->weight); |
2616 | if (nv_alloc_rx(dev)) { | 2618 | if (nv_alloc_rx(dev)) { |
2617 | spin_lock_irq(&np->lock); | 2619 | spin_lock_irqsave(&np->lock, flags); |
2618 | if (!np->in_shutdown) | 2620 | if (!np->in_shutdown) |
2619 | mod_timer(&np->oom_kick, jiffies + OOM_REFILL); | 2621 | mod_timer(&np->oom_kick, jiffies + OOM_REFILL); |
2620 | spin_unlock_irq(&np->lock); | 2622 | spin_unlock_irqrestore(&np->lock, flags); |
2621 | } | 2623 | } |
2622 | 2624 | ||
2623 | if (i > max_interrupt_work) { | 2625 | if (i > max_interrupt_work) { |
2624 | spin_lock_irq(&np->lock); | 2626 | spin_lock_irqsave(&np->lock, flags); |
2625 | /* disable interrupts on the nic */ | 2627 | /* disable interrupts on the nic */ |
2626 | writel(NVREG_IRQ_RX_ALL, base + NvRegIrqMask); | 2628 | writel(NVREG_IRQ_RX_ALL, base + NvRegIrqMask); |
2627 | pci_push(base); | 2629 | pci_push(base); |
@@ -2631,7 +2633,7 @@ static irqreturn_t nv_nic_irq_rx(int foo, void *data) | |||
2631 | mod_timer(&np->nic_poll, jiffies + POLL_WAIT); | 2633 | mod_timer(&np->nic_poll, jiffies + POLL_WAIT); |
2632 | } | 2634 | } |
2633 | printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_rx.\n", dev->name, i); | 2635 | printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_rx.\n", dev->name, i); |
2634 | spin_unlock_irq(&np->lock); | 2636 | spin_unlock_irqrestore(&np->lock, flags); |
2635 | break; | 2637 | break; |
2636 | } | 2638 | } |
2637 | } | 2639 | } |
@@ -2648,6 +2650,7 @@ static irqreturn_t nv_nic_irq_other(int foo, void *data) | |||
2648 | u8 __iomem *base = get_hwbase(dev); | 2650 | u8 __iomem *base = get_hwbase(dev); |
2649 | u32 events; | 2651 | u32 events; |
2650 | int i; | 2652 | int i; |
2653 | unsigned long flags; | ||
2651 | 2654 | ||
2652 | dprintk(KERN_DEBUG "%s: nv_nic_irq_other\n", dev->name); | 2655 | dprintk(KERN_DEBUG "%s: nv_nic_irq_other\n", dev->name); |
2653 | 2656 | ||
@@ -2660,14 +2663,14 @@ static irqreturn_t nv_nic_irq_other(int foo, void *data) | |||
2660 | break; | 2663 | break; |
2661 | 2664 | ||
2662 | if (events & NVREG_IRQ_LINK) { | 2665 | if (events & NVREG_IRQ_LINK) { |
2663 | spin_lock_irq(&np->lock); | 2666 | spin_lock_irqsave(&np->lock, flags); |
2664 | nv_link_irq(dev); | 2667 | nv_link_irq(dev); |
2665 | spin_unlock_irq(&np->lock); | 2668 | spin_unlock_irqrestore(&np->lock, flags); |
2666 | } | 2669 | } |
2667 | if (np->need_linktimer && time_after(jiffies, np->link_timeout)) { | 2670 | if (np->need_linktimer && time_after(jiffies, np->link_timeout)) { |
2668 | spin_lock_irq(&np->lock); | 2671 | spin_lock_irqsave(&np->lock, flags); |
2669 | nv_linkchange(dev); | 2672 | nv_linkchange(dev); |
2670 | spin_unlock_irq(&np->lock); | 2673 | spin_unlock_irqrestore(&np->lock, flags); |
2671 | np->link_timeout = jiffies + LINK_TIMEOUT; | 2674 | np->link_timeout = jiffies + LINK_TIMEOUT; |
2672 | } | 2675 | } |
2673 | if (events & (NVREG_IRQ_UNKNOWN)) { | 2676 | if (events & (NVREG_IRQ_UNKNOWN)) { |
@@ -2675,7 +2678,7 @@ static irqreturn_t nv_nic_irq_other(int foo, void *data) | |||
2675 | dev->name, events); | 2678 | dev->name, events); |
2676 | } | 2679 | } |
2677 | if (i > max_interrupt_work) { | 2680 | if (i > max_interrupt_work) { |
2678 | spin_lock_irq(&np->lock); | 2681 | spin_lock_irqsave(&np->lock, flags); |
2679 | /* disable interrupts on the nic */ | 2682 | /* disable interrupts on the nic */ |
2680 | writel(NVREG_IRQ_OTHER, base + NvRegIrqMask); | 2683 | writel(NVREG_IRQ_OTHER, base + NvRegIrqMask); |
2681 | pci_push(base); | 2684 | pci_push(base); |
@@ -2685,7 +2688,7 @@ static irqreturn_t nv_nic_irq_other(int foo, void *data) | |||
2685 | mod_timer(&np->nic_poll, jiffies + POLL_WAIT); | 2688 | mod_timer(&np->nic_poll, jiffies + POLL_WAIT); |
2686 | } | 2689 | } |
2687 | printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_other.\n", dev->name, i); | 2690 | printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_other.\n", dev->name, i); |
2688 | spin_unlock_irq(&np->lock); | 2691 | spin_unlock_irqrestore(&np->lock, flags); |
2689 | break; | 2692 | break; |
2690 | } | 2693 | } |
2691 | 2694 | ||
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index 4bac3cd8f235..44c9f993dcc4 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c | |||
@@ -212,7 +212,8 @@ static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter, struc | |||
212 | break; | 212 | break; |
213 | } | 213 | } |
214 | 214 | ||
215 | free_index = pool->consumer_index++ % pool->size; | 215 | free_index = pool->consumer_index; |
216 | pool->consumer_index = (pool->consumer_index + 1) % pool->size; | ||
216 | index = pool->free_map[free_index]; | 217 | index = pool->free_map[free_index]; |
217 | 218 | ||
218 | ibmveth_assert(index != IBM_VETH_INVALID_MAP); | 219 | ibmveth_assert(index != IBM_VETH_INVALID_MAP); |
@@ -238,7 +239,10 @@ static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter, struc | |||
238 | if(lpar_rc != H_SUCCESS) { | 239 | if(lpar_rc != H_SUCCESS) { |
239 | pool->free_map[free_index] = index; | 240 | pool->free_map[free_index] = index; |
240 | pool->skbuff[index] = NULL; | 241 | pool->skbuff[index] = NULL; |
241 | pool->consumer_index--; | 242 | if (pool->consumer_index == 0) |
243 | pool->consumer_index = pool->size - 1; | ||
244 | else | ||
245 | pool->consumer_index--; | ||
242 | dma_unmap_single(&adapter->vdev->dev, | 246 | dma_unmap_single(&adapter->vdev->dev, |
243 | pool->dma_addr[index], pool->buff_size, | 247 | pool->dma_addr[index], pool->buff_size, |
244 | DMA_FROM_DEVICE); | 248 | DMA_FROM_DEVICE); |
@@ -325,7 +329,10 @@ static void ibmveth_remove_buffer_from_pool(struct ibmveth_adapter *adapter, u64 | |||
325 | adapter->rx_buff_pool[pool].buff_size, | 329 | adapter->rx_buff_pool[pool].buff_size, |
326 | DMA_FROM_DEVICE); | 330 | DMA_FROM_DEVICE); |
327 | 331 | ||
328 | free_index = adapter->rx_buff_pool[pool].producer_index++ % adapter->rx_buff_pool[pool].size; | 332 | free_index = adapter->rx_buff_pool[pool].producer_index; |
333 | adapter->rx_buff_pool[pool].producer_index | ||
334 | = (adapter->rx_buff_pool[pool].producer_index + 1) | ||
335 | % adapter->rx_buff_pool[pool].size; | ||
329 | adapter->rx_buff_pool[pool].free_map[free_index] = index; | 336 | adapter->rx_buff_pool[pool].free_map[free_index] = index; |
330 | 337 | ||
331 | mb(); | 338 | mb(); |
@@ -437,6 +444,31 @@ static void ibmveth_cleanup(struct ibmveth_adapter *adapter) | |||
437 | &adapter->rx_buff_pool[i]); | 444 | &adapter->rx_buff_pool[i]); |
438 | } | 445 | } |
439 | 446 | ||
447 | static int ibmveth_register_logical_lan(struct ibmveth_adapter *adapter, | ||
448 | union ibmveth_buf_desc rxq_desc, u64 mac_address) | ||
449 | { | ||
450 | int rc, try_again = 1; | ||
451 | |||
452 | /* After a kexec the adapter will still be open, so our attempt to | ||
453 | * open it will fail. So if we get a failure we free the adapter and | ||
454 | * try again, but only once. */ | ||
455 | retry: | ||
456 | rc = h_register_logical_lan(adapter->vdev->unit_address, | ||
457 | adapter->buffer_list_dma, rxq_desc.desc, | ||
458 | adapter->filter_list_dma, mac_address); | ||
459 | |||
460 | if (rc != H_SUCCESS && try_again) { | ||
461 | do { | ||
462 | rc = h_free_logical_lan(adapter->vdev->unit_address); | ||
463 | } while (H_IS_LONG_BUSY(rc) || (rc == H_BUSY)); | ||
464 | |||
465 | try_again = 0; | ||
466 | goto retry; | ||
467 | } | ||
468 | |||
469 | return rc; | ||
470 | } | ||
471 | |||
440 | static int ibmveth_open(struct net_device *netdev) | 472 | static int ibmveth_open(struct net_device *netdev) |
441 | { | 473 | { |
442 | struct ibmveth_adapter *adapter = netdev->priv; | 474 | struct ibmveth_adapter *adapter = netdev->priv; |
@@ -502,12 +534,9 @@ static int ibmveth_open(struct net_device *netdev) | |||
502 | ibmveth_debug_printk("filter list @ 0x%p\n", adapter->filter_list_addr); | 534 | ibmveth_debug_printk("filter list @ 0x%p\n", adapter->filter_list_addr); |
503 | ibmveth_debug_printk("receive q @ 0x%p\n", adapter->rx_queue.queue_addr); | 535 | ibmveth_debug_printk("receive q @ 0x%p\n", adapter->rx_queue.queue_addr); |
504 | 536 | ||
537 | h_vio_signal(adapter->vdev->unit_address, VIO_IRQ_DISABLE); | ||
505 | 538 | ||
506 | lpar_rc = h_register_logical_lan(adapter->vdev->unit_address, | 539 | lpar_rc = ibmveth_register_logical_lan(adapter, rxq_desc, mac_address); |
507 | adapter->buffer_list_dma, | ||
508 | rxq_desc.desc, | ||
509 | adapter->filter_list_dma, | ||
510 | mac_address); | ||
511 | 540 | ||
512 | if(lpar_rc != H_SUCCESS) { | 541 | if(lpar_rc != H_SUCCESS) { |
513 | ibmveth_error_printk("h_register_logical_lan failed with %ld\n", lpar_rc); | 542 | ibmveth_error_printk("h_register_logical_lan failed with %ld\n", lpar_rc); |
@@ -905,6 +934,14 @@ static int ibmveth_change_mtu(struct net_device *dev, int new_mtu) | |||
905 | return -EINVAL; | 934 | return -EINVAL; |
906 | } | 935 | } |
907 | 936 | ||
937 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
938 | static void ibmveth_poll_controller(struct net_device *dev) | ||
939 | { | ||
940 | ibmveth_replenish_task(dev->priv); | ||
941 | ibmveth_interrupt(dev->irq, dev); | ||
942 | } | ||
943 | #endif | ||
944 | |||
908 | static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id) | 945 | static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id) |
909 | { | 946 | { |
910 | int rc, i; | 947 | int rc, i; |
@@ -977,6 +1014,9 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_ | |||
977 | netdev->ethtool_ops = &netdev_ethtool_ops; | 1014 | netdev->ethtool_ops = &netdev_ethtool_ops; |
978 | netdev->change_mtu = ibmveth_change_mtu; | 1015 | netdev->change_mtu = ibmveth_change_mtu; |
979 | SET_NETDEV_DEV(netdev, &dev->dev); | 1016 | SET_NETDEV_DEV(netdev, &dev->dev); |
1017 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
1018 | netdev->poll_controller = ibmveth_poll_controller; | ||
1019 | #endif | ||
980 | netdev->features |= NETIF_F_LLTX; | 1020 | netdev->features |= NETIF_F_LLTX; |
981 | spin_lock_init(&adapter->stats_lock); | 1021 | spin_lock_init(&adapter->stats_lock); |
982 | 1022 | ||
@@ -1132,7 +1172,9 @@ static void ibmveth_proc_register_adapter(struct ibmveth_adapter *adapter) | |||
1132 | { | 1172 | { |
1133 | struct proc_dir_entry *entry; | 1173 | struct proc_dir_entry *entry; |
1134 | if (ibmveth_proc_dir) { | 1174 | if (ibmveth_proc_dir) { |
1135 | entry = create_proc_entry(adapter->netdev->name, S_IFREG, ibmveth_proc_dir); | 1175 | char u_addr[10]; |
1176 | sprintf(u_addr, "%x", adapter->vdev->unit_address); | ||
1177 | entry = create_proc_entry(u_addr, S_IFREG, ibmveth_proc_dir); | ||
1136 | if (!entry) { | 1178 | if (!entry) { |
1137 | ibmveth_error_printk("Cannot create adapter proc entry"); | 1179 | ibmveth_error_printk("Cannot create adapter proc entry"); |
1138 | } else { | 1180 | } else { |
@@ -1147,7 +1189,9 @@ static void ibmveth_proc_register_adapter(struct ibmveth_adapter *adapter) | |||
1147 | static void ibmveth_proc_unregister_adapter(struct ibmveth_adapter *adapter) | 1189 | static void ibmveth_proc_unregister_adapter(struct ibmveth_adapter *adapter) |
1148 | { | 1190 | { |
1149 | if (ibmveth_proc_dir) { | 1191 | if (ibmveth_proc_dir) { |
1150 | remove_proc_entry(adapter->netdev->name, ibmveth_proc_dir); | 1192 | char u_addr[10]; |
1193 | sprintf(u_addr, "%x", adapter->vdev->unit_address); | ||
1194 | remove_proc_entry(u_addr, ibmveth_proc_dir); | ||
1151 | } | 1195 | } |
1152 | } | 1196 | } |
1153 | 1197 | ||
diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c index e963dbf816be..f56b00ee385e 100644 --- a/drivers/net/ioc3-eth.c +++ b/drivers/net/ioc3-eth.c | |||
@@ -1017,7 +1017,7 @@ static void ioc3_init(struct net_device *dev) | |||
1017 | struct ioc3_private *ip = netdev_priv(dev); | 1017 | struct ioc3_private *ip = netdev_priv(dev); |
1018 | struct ioc3 *ioc3 = ip->regs; | 1018 | struct ioc3 *ioc3 = ip->regs; |
1019 | 1019 | ||
1020 | del_timer(&ip->ioc3_timer); /* Kill if running */ | 1020 | del_timer_sync(&ip->ioc3_timer); /* Kill if running */ |
1021 | 1021 | ||
1022 | ioc3_w_emcr(EMCR_RST); /* Reset */ | 1022 | ioc3_w_emcr(EMCR_RST); /* Reset */ |
1023 | (void) ioc3_r_emcr(); /* Flush WB */ | 1023 | (void) ioc3_r_emcr(); /* Flush WB */ |
@@ -1081,7 +1081,7 @@ static int ioc3_close(struct net_device *dev) | |||
1081 | { | 1081 | { |
1082 | struct ioc3_private *ip = netdev_priv(dev); | 1082 | struct ioc3_private *ip = netdev_priv(dev); |
1083 | 1083 | ||
1084 | del_timer(&ip->ioc3_timer); | 1084 | del_timer_sync(&ip->ioc3_timer); |
1085 | 1085 | ||
1086 | netif_stop_queue(dev); | 1086 | netif_stop_queue(dev); |
1087 | 1087 | ||
diff --git a/drivers/net/irda/stir4200.c b/drivers/net/irda/stir4200.c index be8a66e702b0..3b4c47875935 100644 --- a/drivers/net/irda/stir4200.c +++ b/drivers/net/irda/stir4200.c | |||
@@ -15,8 +15,7 @@ | |||
15 | * | 15 | * |
16 | * This program is free software; you can redistribute it and/or modify | 16 | * This program is free software; you can redistribute it and/or modify |
17 | * it under the terms of the GNU General Public License as published by | 17 | * it under the terms of the GNU General Public License as published by |
18 | * the Free Software Foundation; either version 2 of the License, or | 18 | * the Free Software Foundation; either version 2 of the License. |
19 | * (at your option) any later version. | ||
20 | * | 19 | * |
21 | * This program is distributed in the hope that it will be useful, | 20 | * This program is distributed in the hope that it will be useful, |
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 21 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c index 4178b4b1d2df..82c10dec1b5a 100644 --- a/drivers/net/loopback.c +++ b/drivers/net/loopback.c | |||
@@ -58,7 +58,11 @@ | |||
58 | #include <linux/tcp.h> | 58 | #include <linux/tcp.h> |
59 | #include <linux/percpu.h> | 59 | #include <linux/percpu.h> |
60 | 60 | ||
61 | static DEFINE_PER_CPU(struct net_device_stats, loopback_stats); | 61 | struct pcpu_lstats { |
62 | unsigned long packets; | ||
63 | unsigned long bytes; | ||
64 | }; | ||
65 | static DEFINE_PER_CPU(struct pcpu_lstats, pcpu_lstats); | ||
62 | 66 | ||
63 | #define LOOPBACK_OVERHEAD (128 + MAX_HEADER + 16 + 16) | 67 | #define LOOPBACK_OVERHEAD (128 + MAX_HEADER + 16 + 16) |
64 | 68 | ||
@@ -128,7 +132,7 @@ static void emulate_large_send_offload(struct sk_buff *skb) | |||
128 | */ | 132 | */ |
129 | static int loopback_xmit(struct sk_buff *skb, struct net_device *dev) | 133 | static int loopback_xmit(struct sk_buff *skb, struct net_device *dev) |
130 | { | 134 | { |
131 | struct net_device_stats *lb_stats; | 135 | struct pcpu_lstats *lb_stats; |
132 | 136 | ||
133 | skb_orphan(skb); | 137 | skb_orphan(skb); |
134 | 138 | ||
@@ -149,16 +153,14 @@ static int loopback_xmit(struct sk_buff *skb, struct net_device *dev) | |||
149 | #endif | 153 | #endif |
150 | dev->last_rx = jiffies; | 154 | dev->last_rx = jiffies; |
151 | 155 | ||
152 | lb_stats = &per_cpu(loopback_stats, get_cpu()); | 156 | /* it's OK to use __get_cpu_var() because BHs are off */ |
153 | lb_stats->rx_bytes += skb->len; | 157 | lb_stats = &__get_cpu_var(pcpu_lstats); |
154 | lb_stats->tx_bytes = lb_stats->rx_bytes; | 158 | lb_stats->bytes += skb->len; |
155 | lb_stats->rx_packets++; | 159 | lb_stats->packets++; |
156 | lb_stats->tx_packets = lb_stats->rx_packets; | ||
157 | put_cpu(); | ||
158 | 160 | ||
159 | netif_rx(skb); | 161 | netif_rx(skb); |
160 | 162 | ||
161 | return(0); | 163 | return 0; |
162 | } | 164 | } |
163 | 165 | ||
164 | static struct net_device_stats loopback_stats; | 166 | static struct net_device_stats loopback_stats; |
@@ -166,20 +168,21 @@ static struct net_device_stats loopback_stats; | |||
166 | static struct net_device_stats *get_stats(struct net_device *dev) | 168 | static struct net_device_stats *get_stats(struct net_device *dev) |
167 | { | 169 | { |
168 | struct net_device_stats *stats = &loopback_stats; | 170 | struct net_device_stats *stats = &loopback_stats; |
171 | unsigned long bytes = 0; | ||
172 | unsigned long packets = 0; | ||
169 | int i; | 173 | int i; |
170 | 174 | ||
171 | memset(stats, 0, sizeof(struct net_device_stats)); | ||
172 | |||
173 | for_each_possible_cpu(i) { | 175 | for_each_possible_cpu(i) { |
174 | struct net_device_stats *lb_stats; | 176 | const struct pcpu_lstats *lb_stats; |
175 | 177 | ||
176 | lb_stats = &per_cpu(loopback_stats, i); | 178 | lb_stats = &per_cpu(pcpu_lstats, i); |
177 | stats->rx_bytes += lb_stats->rx_bytes; | 179 | bytes += lb_stats->bytes; |
178 | stats->tx_bytes += lb_stats->tx_bytes; | 180 | packets += lb_stats->packets; |
179 | stats->rx_packets += lb_stats->rx_packets; | ||
180 | stats->tx_packets += lb_stats->tx_packets; | ||
181 | } | 181 | } |
182 | 182 | stats->rx_packets = packets; | |
183 | stats->tx_packets = packets; | ||
184 | stats->rx_bytes = bytes; | ||
185 | stats->tx_bytes = bytes; | ||
183 | return stats; | 186 | return stats; |
184 | } | 187 | } |
185 | 188 | ||
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index 2ffa3a59e704..9997081c6dae 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c | |||
@@ -2155,7 +2155,7 @@ static void eth_update_mib_counters(struct mv643xx_private *mp) | |||
2155 | for (offset = ETH_MIB_BAD_OCTETS_RECEIVED; | 2155 | for (offset = ETH_MIB_BAD_OCTETS_RECEIVED; |
2156 | offset <= ETH_MIB_FRAMES_1024_TO_MAX_OCTETS; | 2156 | offset <= ETH_MIB_FRAMES_1024_TO_MAX_OCTETS; |
2157 | offset += 4) | 2157 | offset += 4) |
2158 | *(u32 *)((char *)p + offset) = read_mib(mp, offset); | 2158 | *(u32 *)((char *)p + offset) += read_mib(mp, offset); |
2159 | 2159 | ||
2160 | p->good_octets_sent += read_mib(mp, ETH_MIB_GOOD_OCTETS_SENT_LOW); | 2160 | p->good_octets_sent += read_mib(mp, ETH_MIB_GOOD_OCTETS_SENT_LOW); |
2161 | p->good_octets_sent += | 2161 | p->good_octets_sent += |
@@ -2164,7 +2164,7 @@ static void eth_update_mib_counters(struct mv643xx_private *mp) | |||
2164 | for (offset = ETH_MIB_GOOD_FRAMES_SENT; | 2164 | for (offset = ETH_MIB_GOOD_FRAMES_SENT; |
2165 | offset <= ETH_MIB_LATE_COLLISION; | 2165 | offset <= ETH_MIB_LATE_COLLISION; |
2166 | offset += 4) | 2166 | offset += 4) |
2167 | *(u32 *)((char *)p + offset) = read_mib(mp, offset); | 2167 | *(u32 *)((char *)p + offset) += read_mib(mp, offset); |
2168 | } | 2168 | } |
2169 | 2169 | ||
2170 | /* | 2170 | /* |
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index fdbb0d7213b0..806081b59733 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c | |||
@@ -2416,7 +2416,6 @@ static void myri10ge_enable_ecrc(struct myri10ge_priv *mgp) | |||
2416 | * firmware image, and set tx.boundary to 4KB. | 2416 | * firmware image, and set tx.boundary to 4KB. |
2417 | */ | 2417 | */ |
2418 | 2418 | ||
2419 | #define PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE 0x0132 | ||
2420 | #define PCI_DEVICE_ID_INTEL_E5000_PCIE23 0x25f7 | 2419 | #define PCI_DEVICE_ID_INTEL_E5000_PCIE23 0x25f7 |
2421 | #define PCI_DEVICE_ID_INTEL_E5000_PCIE47 0x25fa | 2420 | #define PCI_DEVICE_ID_INTEL_E5000_PCIE47 0x25fa |
2422 | 2421 | ||
diff --git a/drivers/net/myri_code.h b/drivers/net/myri_code.h index e21ec9b2c706..ba7b8652c501 100644 --- a/drivers/net/myri_code.h +++ b/drivers/net/myri_code.h | |||
@@ -1,8 +1,8 @@ | |||
1 | /* This is the Myrinet MCP code for LANai4.x */ | 1 | /* This is the Myrinet MCP code for LANai4.x */ |
2 | /* Generated by cat $MYRI_HOME/lib/lanai/mcp4.dat > myri_code4.h */ | 2 | /* Generated by cat $MYRI_HOME/lib/lanai/mcp4.dat > myri_code4.h */ |
3 | 3 | ||
4 | static unsigned int lanai4_code_off = 0x0000; /* half-word offset */ | 4 | static unsigned int __devinitdata lanai4_code_off = 0x0000; /* half-word offset */ |
5 | static unsigned char lanai4_code[76256] __initdata = { | 5 | static unsigned char __devinitdata lanai4_code[76256] = { |
6 | 0xF2,0x0E, | 6 | 0xF2,0x0E, |
7 | 0xFE,0x00, 0xC2,0x90, 0x00,0x00, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x01,0x4C, 0x97,0x93, | 7 | 0xFE,0x00, 0xC2,0x90, 0x00,0x00, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x01,0x4C, 0x97,0x93, |
8 | 0xFF,0xFC, 0xE0,0x00, 0x00,0x14, 0x00,0x00, 0x00,0x01, 0x00,0x00, 0x00,0x00, 0x92,0x93, | 8 | 0xFF,0xFC, 0xE0,0x00, 0x00,0x14, 0x00,0x00, 0x00,0x01, 0x00,0x00, 0x00,0x00, 0x92,0x93, |
@@ -4774,8 +4774,8 @@ static unsigned char lanai4_code[76256] __initdata = { | |||
4774 | 4774 | ||
4775 | /* This is the LANai data */ | 4775 | /* This is the LANai data */ |
4776 | 4776 | ||
4777 | static unsigned int lanai4_data_off = 0x94F0; /* half-word offset */ | 4777 | static unsigned int __devinitdata lanai4_data_off = 0x94F0; /* half-word offset */ |
4778 | static unsigned char lanai4_data[20472] __initdata; | 4778 | static unsigned char __devinitdata lanai4_data[20472]; |
4779 | 4779 | ||
4780 | 4780 | ||
4781 | #ifdef SYMBOL_DEFINES_COMPILED | 4781 | #ifdef SYMBOL_DEFINES_COMPILED |
diff --git a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c index 466b484c9fa4..7747bfd99f91 100644 --- a/drivers/net/myri_sbus.c +++ b/drivers/net/myri_sbus.c | |||
@@ -168,7 +168,7 @@ static int myri_do_handshake(struct myri_eth *mp) | |||
168 | return 0; | 168 | return 0; |
169 | } | 169 | } |
170 | 170 | ||
171 | static int myri_load_lanai(struct myri_eth *mp) | 171 | static int __devinit myri_load_lanai(struct myri_eth *mp) |
172 | { | 172 | { |
173 | struct net_device *dev = mp->dev; | 173 | struct net_device *dev = mp->dev; |
174 | struct myri_shmem __iomem *shmem = mp->shmem; | 174 | struct myri_shmem __iomem *shmem = mp->shmem; |
@@ -891,7 +891,7 @@ static void dump_eeprom(struct myri_eth *mp) | |||
891 | } | 891 | } |
892 | #endif | 892 | #endif |
893 | 893 | ||
894 | static int __init myri_ether_init(struct sbus_dev *sdev) | 894 | static int __devinit myri_ether_init(struct sbus_dev *sdev) |
895 | { | 895 | { |
896 | static int num; | 896 | static int num; |
897 | static unsigned version_printed; | 897 | static unsigned version_printed; |
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index f1c75751cab7..27f90b2139c0 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c | |||
@@ -214,6 +214,7 @@ static struct pci_device_id rtl8169_pci_tbl[] = { | |||
214 | { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8168), 0, 0, RTL_CFG_2 }, | 214 | { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8168), 0, 0, RTL_CFG_2 }, |
215 | { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8169), 0, 0, RTL_CFG_0 }, | 215 | { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8169), 0, 0, RTL_CFG_0 }, |
216 | { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4300), 0, 0, RTL_CFG_0 }, | 216 | { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4300), 0, 0, RTL_CFG_0 }, |
217 | { PCI_DEVICE(0x1259, 0xc107), 0, 0, RTL_CFG_0 }, | ||
217 | { PCI_DEVICE(0x16ec, 0x0116), 0, 0, RTL_CFG_0 }, | 218 | { PCI_DEVICE(0x16ec, 0x0116), 0, 0, RTL_CFG_0 }, |
218 | { PCI_VENDOR_ID_LINKSYS, 0x1032, | 219 | { PCI_VENDOR_ID_LINKSYS, 0x1032, |
219 | PCI_ANY_ID, 0x0024, 0, 0, RTL_CFG_0 }, | 220 | PCI_ANY_ID, 0x0024, 0, 0, RTL_CFG_0 }, |
@@ -1396,41 +1397,6 @@ static void rtl8169_netpoll(struct net_device *dev) | |||
1396 | } | 1397 | } |
1397 | #endif | 1398 | #endif |
1398 | 1399 | ||
1399 | static void __rtl8169_set_mac_addr(struct net_device *dev, void __iomem *ioaddr) | ||
1400 | { | ||
1401 | unsigned int i, j; | ||
1402 | |||
1403 | RTL_W8(Cfg9346, Cfg9346_Unlock); | ||
1404 | for (i = 0; i < 2; i++) { | ||
1405 | __le32 l = 0; | ||
1406 | |||
1407 | for (j = 0; j < 4; j++) { | ||
1408 | l <<= 8; | ||
1409 | l |= dev->dev_addr[4*i + j]; | ||
1410 | } | ||
1411 | RTL_W32(MAC0 + 4*i, cpu_to_be32(l)); | ||
1412 | } | ||
1413 | RTL_W8(Cfg9346, Cfg9346_Lock); | ||
1414 | } | ||
1415 | |||
1416 | static int rtl8169_set_mac_addr(struct net_device *dev, void *p) | ||
1417 | { | ||
1418 | struct rtl8169_private *tp = netdev_priv(dev); | ||
1419 | struct sockaddr *addr = p; | ||
1420 | |||
1421 | if (!is_valid_ether_addr(addr->sa_data)) | ||
1422 | return -EINVAL; | ||
1423 | |||
1424 | memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); | ||
1425 | |||
1426 | if (netif_running(dev)) { | ||
1427 | spin_lock_irq(&tp->lock); | ||
1428 | __rtl8169_set_mac_addr(dev, tp->mmio_addr); | ||
1429 | spin_unlock_irq(&tp->lock); | ||
1430 | } | ||
1431 | return 0; | ||
1432 | } | ||
1433 | |||
1434 | static void rtl8169_release_board(struct pci_dev *pdev, struct net_device *dev, | 1400 | static void rtl8169_release_board(struct pci_dev *pdev, struct net_device *dev, |
1435 | void __iomem *ioaddr) | 1401 | void __iomem *ioaddr) |
1436 | { | 1402 | { |
@@ -1680,7 +1646,6 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1680 | dev->stop = rtl8169_close; | 1646 | dev->stop = rtl8169_close; |
1681 | dev->tx_timeout = rtl8169_tx_timeout; | 1647 | dev->tx_timeout = rtl8169_tx_timeout; |
1682 | dev->set_multicast_list = rtl8169_set_rx_mode; | 1648 | dev->set_multicast_list = rtl8169_set_rx_mode; |
1683 | dev->set_mac_address = rtl8169_set_mac_addr; | ||
1684 | dev->watchdog_timeo = RTL8169_TX_TIMEOUT; | 1649 | dev->watchdog_timeo = RTL8169_TX_TIMEOUT; |
1685 | dev->irq = pdev->irq; | 1650 | dev->irq = pdev->irq; |
1686 | dev->base_addr = (unsigned long) ioaddr; | 1651 | dev->base_addr = (unsigned long) ioaddr; |
@@ -1928,8 +1893,6 @@ rtl8169_hw_start(struct net_device *dev) | |||
1928 | /* Enable all known interrupts by setting the interrupt mask. */ | 1893 | /* Enable all known interrupts by setting the interrupt mask. */ |
1929 | RTL_W16(IntrMask, rtl8169_intr_mask); | 1894 | RTL_W16(IntrMask, rtl8169_intr_mask); |
1930 | 1895 | ||
1931 | __rtl8169_set_mac_addr(dev, ioaddr); | ||
1932 | |||
1933 | netif_start_queue(dev); | 1896 | netif_start_queue(dev); |
1934 | } | 1897 | } |
1935 | 1898 | ||
@@ -2700,6 +2663,7 @@ static void rtl8169_down(struct net_device *dev) | |||
2700 | struct rtl8169_private *tp = netdev_priv(dev); | 2663 | struct rtl8169_private *tp = netdev_priv(dev); |
2701 | void __iomem *ioaddr = tp->mmio_addr; | 2664 | void __iomem *ioaddr = tp->mmio_addr; |
2702 | unsigned int poll_locked = 0; | 2665 | unsigned int poll_locked = 0; |
2666 | unsigned int intrmask; | ||
2703 | 2667 | ||
2704 | rtl8169_delete_timer(dev); | 2668 | rtl8169_delete_timer(dev); |
2705 | 2669 | ||
@@ -2738,8 +2702,11 @@ core_down: | |||
2738 | * 2) dev->change_mtu | 2702 | * 2) dev->change_mtu |
2739 | * -> rtl8169_poll can not be issued again and re-enable the | 2703 | * -> rtl8169_poll can not be issued again and re-enable the |
2740 | * interruptions. Let's simply issue the IRQ down sequence again. | 2704 | * interruptions. Let's simply issue the IRQ down sequence again. |
2705 | * | ||
2706 | * No loop if hotpluged or major error (0xffff). | ||
2741 | */ | 2707 | */ |
2742 | if (RTL_R16(IntrMask)) | 2708 | intrmask = RTL_R16(IntrMask); |
2709 | if (intrmask && (intrmask != 0xffff)) | ||
2743 | goto core_down; | 2710 | goto core_down; |
2744 | 2711 | ||
2745 | rtl8169_tx_clear(tp); | 2712 | rtl8169_tx_clear(tp); |
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index a231ab7d28dd..33569ec9dbfc 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c | |||
@@ -5985,6 +5985,11 @@ static int set_rxd_buffer_pointer(nic_t *sp, RxD_t *rxdp, buffAdd_t *ba, | |||
5985 | ((RxD3_t*)rxdp)->Buffer1_ptr = *temp1; | 5985 | ((RxD3_t*)rxdp)->Buffer1_ptr = *temp1; |
5986 | } else { | 5986 | } else { |
5987 | *skb = dev_alloc_skb(size); | 5987 | *skb = dev_alloc_skb(size); |
5988 | if (!(*skb)) { | ||
5989 | DBG_PRINT(ERR_DBG, "%s: dev_alloc_skb failed\n", | ||
5990 | dev->name); | ||
5991 | return -ENOMEM; | ||
5992 | } | ||
5988 | ((RxD3_t*)rxdp)->Buffer2_ptr = *temp2 = | 5993 | ((RxD3_t*)rxdp)->Buffer2_ptr = *temp2 = |
5989 | pci_map_single(sp->pdev, (*skb)->data, | 5994 | pci_map_single(sp->pdev, (*skb)->data, |
5990 | dev->mtu + 4, | 5995 | dev->mtu + 4, |
@@ -6007,7 +6012,11 @@ static int set_rxd_buffer_pointer(nic_t *sp, RxD_t *rxdp, buffAdd_t *ba, | |||
6007 | ((RxD3_t*)rxdp)->Buffer2_ptr = *temp2; | 6012 | ((RxD3_t*)rxdp)->Buffer2_ptr = *temp2; |
6008 | } else { | 6013 | } else { |
6009 | *skb = dev_alloc_skb(size); | 6014 | *skb = dev_alloc_skb(size); |
6010 | 6015 | if (!(*skb)) { | |
6016 | DBG_PRINT(ERR_DBG, "%s: dev_alloc_skb failed\n", | ||
6017 | dev->name); | ||
6018 | return -ENOMEM; | ||
6019 | } | ||
6011 | ((RxD3_t*)rxdp)->Buffer0_ptr = *temp0 = | 6020 | ((RxD3_t*)rxdp)->Buffer0_ptr = *temp0 = |
6012 | pci_map_single(sp->pdev, ba->ba_0, BUF0_LEN, | 6021 | pci_map_single(sp->pdev, ba->ba_0, BUF0_LEN, |
6013 | PCI_DMA_FROMDEVICE); | 6022 | PCI_DMA_FROMDEVICE); |
diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c index db2324939b69..1eae16b72b4b 100644 --- a/drivers/net/sb1250-mac.c +++ b/drivers/net/sb1250-mac.c | |||
@@ -2903,7 +2903,7 @@ sbmac_init_module(void) | |||
2903 | 2903 | ||
2904 | dev = alloc_etherdev(sizeof(struct sbmac_softc)); | 2904 | dev = alloc_etherdev(sizeof(struct sbmac_softc)); |
2905 | if (!dev) | 2905 | if (!dev) |
2906 | return -ENOMEM; /* return ENOMEM */ | 2906 | return -ENOMEM; |
2907 | 2907 | ||
2908 | printk(KERN_DEBUG "sbmac: configuring MAC at %lx\n", port); | 2908 | printk(KERN_DEBUG "sbmac: configuring MAC at %lx\n", port); |
2909 | 2909 | ||
diff --git a/drivers/net/skge.c b/drivers/net/skge.c index a4a58e4e93a1..b2949035f66a 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c | |||
@@ -11,8 +11,7 @@ | |||
11 | * | 11 | * |
12 | * This program is free software; you can redistribute it and/or modify | 12 | * This program is free software; you can redistribute it and/or modify |
13 | * it under the terms of the GNU General Public License as published by | 13 | * it under the terms of the GNU General Public License as published by |
14 | * the Free Software Foundation; either version 2 of the License, or | 14 | * the Free Software Foundation; either version 2 of the License. |
15 | * (at your option) any later version. | ||
16 | * | 15 | * |
17 | * This program is distributed in the hope that it will be useful, | 16 | * This program is distributed in the hope that it will be useful, |
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
@@ -43,7 +42,7 @@ | |||
43 | #include "skge.h" | 42 | #include "skge.h" |
44 | 43 | ||
45 | #define DRV_NAME "skge" | 44 | #define DRV_NAME "skge" |
46 | #define DRV_VERSION "1.8" | 45 | #define DRV_VERSION "1.9" |
47 | #define PFX DRV_NAME " " | 46 | #define PFX DRV_NAME " " |
48 | 47 | ||
49 | #define DEFAULT_TX_RING_SIZE 128 | 48 | #define DEFAULT_TX_RING_SIZE 128 |
@@ -197,8 +196,8 @@ static u32 skge_supported_modes(const struct skge_hw *hw) | |||
197 | else if (hw->chip_id == CHIP_ID_YUKON) | 196 | else if (hw->chip_id == CHIP_ID_YUKON) |
198 | supported &= ~SUPPORTED_1000baseT_Half; | 197 | supported &= ~SUPPORTED_1000baseT_Half; |
199 | } else | 198 | } else |
200 | supported = SUPPORTED_1000baseT_Full | SUPPORTED_FIBRE | 199 | supported = SUPPORTED_1000baseT_Full | SUPPORTED_1000baseT_Half |
201 | | SUPPORTED_Autoneg; | 200 | | SUPPORTED_FIBRE | SUPPORTED_Autoneg; |
202 | 201 | ||
203 | return supported; | 202 | return supported; |
204 | } | 203 | } |
@@ -487,31 +486,37 @@ static void skge_get_pauseparam(struct net_device *dev, | |||
487 | { | 486 | { |
488 | struct skge_port *skge = netdev_priv(dev); | 487 | struct skge_port *skge = netdev_priv(dev); |
489 | 488 | ||
490 | ecmd->tx_pause = (skge->flow_control == FLOW_MODE_LOC_SEND) | 489 | ecmd->rx_pause = (skge->flow_control == FLOW_MODE_SYMMETRIC) |
491 | || (skge->flow_control == FLOW_MODE_SYMMETRIC); | 490 | || (skge->flow_control == FLOW_MODE_SYM_OR_REM); |
492 | ecmd->rx_pause = (skge->flow_control == FLOW_MODE_REM_SEND) | 491 | ecmd->tx_pause = ecmd->rx_pause || (skge->flow_control == FLOW_MODE_LOC_SEND); |
493 | || (skge->flow_control == FLOW_MODE_SYMMETRIC); | ||
494 | 492 | ||
495 | ecmd->autoneg = skge->autoneg; | 493 | ecmd->autoneg = ecmd->rx_pause || ecmd->tx_pause; |
496 | } | 494 | } |
497 | 495 | ||
498 | static int skge_set_pauseparam(struct net_device *dev, | 496 | static int skge_set_pauseparam(struct net_device *dev, |
499 | struct ethtool_pauseparam *ecmd) | 497 | struct ethtool_pauseparam *ecmd) |
500 | { | 498 | { |
501 | struct skge_port *skge = netdev_priv(dev); | 499 | struct skge_port *skge = netdev_priv(dev); |
500 | struct ethtool_pauseparam old; | ||
502 | 501 | ||
503 | skge->autoneg = ecmd->autoneg; | 502 | skge_get_pauseparam(dev, &old); |
504 | if (ecmd->rx_pause && ecmd->tx_pause) | 503 | |
505 | skge->flow_control = FLOW_MODE_SYMMETRIC; | 504 | if (ecmd->autoneg != old.autoneg) |
506 | else if (ecmd->rx_pause && !ecmd->tx_pause) | 505 | skge->flow_control = ecmd->autoneg ? FLOW_MODE_NONE : FLOW_MODE_SYMMETRIC; |
507 | skge->flow_control = FLOW_MODE_REM_SEND; | 506 | else { |
508 | else if (!ecmd->rx_pause && ecmd->tx_pause) | 507 | if (ecmd->rx_pause && ecmd->tx_pause) |
509 | skge->flow_control = FLOW_MODE_LOC_SEND; | 508 | skge->flow_control = FLOW_MODE_SYMMETRIC; |
510 | else | 509 | else if (ecmd->rx_pause && !ecmd->tx_pause) |
511 | skge->flow_control = FLOW_MODE_NONE; | 510 | skge->flow_control = FLOW_MODE_SYM_OR_REM; |
511 | else if (!ecmd->rx_pause && ecmd->tx_pause) | ||
512 | skge->flow_control = FLOW_MODE_LOC_SEND; | ||
513 | else | ||
514 | skge->flow_control = FLOW_MODE_NONE; | ||
515 | } | ||
512 | 516 | ||
513 | if (netif_running(dev)) | 517 | if (netif_running(dev)) |
514 | skge_phy_reset(skge); | 518 | skge_phy_reset(skge); |
519 | |||
515 | return 0; | 520 | return 0; |
516 | } | 521 | } |
517 | 522 | ||
@@ -854,6 +859,23 @@ static int skge_rx_fill(struct net_device *dev) | |||
854 | return 0; | 859 | return 0; |
855 | } | 860 | } |
856 | 861 | ||
862 | static const char *skge_pause(enum pause_status status) | ||
863 | { | ||
864 | switch(status) { | ||
865 | case FLOW_STAT_NONE: | ||
866 | return "none"; | ||
867 | case FLOW_STAT_REM_SEND: | ||
868 | return "rx only"; | ||
869 | case FLOW_STAT_LOC_SEND: | ||
870 | return "tx_only"; | ||
871 | case FLOW_STAT_SYMMETRIC: /* Both station may send PAUSE */ | ||
872 | return "both"; | ||
873 | default: | ||
874 | return "indeterminated"; | ||
875 | } | ||
876 | } | ||
877 | |||
878 | |||
857 | static void skge_link_up(struct skge_port *skge) | 879 | static void skge_link_up(struct skge_port *skge) |
858 | { | 880 | { |
859 | skge_write8(skge->hw, SK_REG(skge->port, LNK_LED_REG), | 881 | skge_write8(skge->hw, SK_REG(skge->port, LNK_LED_REG), |
@@ -862,16 +884,13 @@ static void skge_link_up(struct skge_port *skge) | |||
862 | netif_carrier_on(skge->netdev); | 884 | netif_carrier_on(skge->netdev); |
863 | netif_wake_queue(skge->netdev); | 885 | netif_wake_queue(skge->netdev); |
864 | 886 | ||
865 | if (netif_msg_link(skge)) | 887 | if (netif_msg_link(skge)) { |
866 | printk(KERN_INFO PFX | 888 | printk(KERN_INFO PFX |
867 | "%s: Link is up at %d Mbps, %s duplex, flow control %s\n", | 889 | "%s: Link is up at %d Mbps, %s duplex, flow control %s\n", |
868 | skge->netdev->name, skge->speed, | 890 | skge->netdev->name, skge->speed, |
869 | skge->duplex == DUPLEX_FULL ? "full" : "half", | 891 | skge->duplex == DUPLEX_FULL ? "full" : "half", |
870 | (skge->flow_control == FLOW_MODE_NONE) ? "none" : | 892 | skge_pause(skge->flow_status)); |
871 | (skge->flow_control == FLOW_MODE_LOC_SEND) ? "tx only" : | 893 | } |
872 | (skge->flow_control == FLOW_MODE_REM_SEND) ? "rx only" : | ||
873 | (skge->flow_control == FLOW_MODE_SYMMETRIC) ? "tx and rx" : | ||
874 | "unknown"); | ||
875 | } | 894 | } |
876 | 895 | ||
877 | static void skge_link_down(struct skge_port *skge) | 896 | static void skge_link_down(struct skge_port *skge) |
@@ -884,6 +903,29 @@ static void skge_link_down(struct skge_port *skge) | |||
884 | printk(KERN_INFO PFX "%s: Link is down.\n", skge->netdev->name); | 903 | printk(KERN_INFO PFX "%s: Link is down.\n", skge->netdev->name); |
885 | } | 904 | } |
886 | 905 | ||
906 | |||
907 | static void xm_link_down(struct skge_hw *hw, int port) | ||
908 | { | ||
909 | struct net_device *dev = hw->dev[port]; | ||
910 | struct skge_port *skge = netdev_priv(dev); | ||
911 | u16 cmd, msk; | ||
912 | |||
913 | if (hw->phy_type == SK_PHY_XMAC) { | ||
914 | msk = xm_read16(hw, port, XM_IMSK); | ||
915 | msk |= XM_IS_INP_ASS | XM_IS_LIPA_RC | XM_IS_RX_PAGE | XM_IS_AND; | ||
916 | xm_write16(hw, port, XM_IMSK, msk); | ||
917 | } | ||
918 | |||
919 | cmd = xm_read16(hw, port, XM_MMU_CMD); | ||
920 | cmd &= ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX); | ||
921 | xm_write16(hw, port, XM_MMU_CMD, cmd); | ||
922 | /* dummy read to ensure writing */ | ||
923 | (void) xm_read16(hw, port, XM_MMU_CMD); | ||
924 | |||
925 | if (netif_carrier_ok(dev)) | ||
926 | skge_link_down(skge); | ||
927 | } | ||
928 | |||
887 | static int __xm_phy_read(struct skge_hw *hw, int port, u16 reg, u16 *val) | 929 | static int __xm_phy_read(struct skge_hw *hw, int port, u16 reg, u16 *val) |
888 | { | 930 | { |
889 | int i; | 931 | int i; |
@@ -992,7 +1034,15 @@ static const u16 phy_pause_map[] = { | |||
992 | [FLOW_MODE_NONE] = 0, | 1034 | [FLOW_MODE_NONE] = 0, |
993 | [FLOW_MODE_LOC_SEND] = PHY_AN_PAUSE_ASYM, | 1035 | [FLOW_MODE_LOC_SEND] = PHY_AN_PAUSE_ASYM, |
994 | [FLOW_MODE_SYMMETRIC] = PHY_AN_PAUSE_CAP, | 1036 | [FLOW_MODE_SYMMETRIC] = PHY_AN_PAUSE_CAP, |
995 | [FLOW_MODE_REM_SEND] = PHY_AN_PAUSE_CAP | PHY_AN_PAUSE_ASYM, | 1037 | [FLOW_MODE_SYM_OR_REM] = PHY_AN_PAUSE_CAP | PHY_AN_PAUSE_ASYM, |
1038 | }; | ||
1039 | |||
1040 | /* special defines for FIBER (88E1011S only) */ | ||
1041 | static const u16 fiber_pause_map[] = { | ||
1042 | [FLOW_MODE_NONE] = PHY_X_P_NO_PAUSE, | ||
1043 | [FLOW_MODE_LOC_SEND] = PHY_X_P_ASYM_MD, | ||
1044 | [FLOW_MODE_SYMMETRIC] = PHY_X_P_SYM_MD, | ||
1045 | [FLOW_MODE_SYM_OR_REM] = PHY_X_P_BOTH_MD, | ||
996 | }; | 1046 | }; |
997 | 1047 | ||
998 | 1048 | ||
@@ -1008,14 +1058,7 @@ static void bcom_check_link(struct skge_hw *hw, int port) | |||
1008 | status = xm_phy_read(hw, port, PHY_BCOM_STAT); | 1058 | status = xm_phy_read(hw, port, PHY_BCOM_STAT); |
1009 | 1059 | ||
1010 | if ((status & PHY_ST_LSYNC) == 0) { | 1060 | if ((status & PHY_ST_LSYNC) == 0) { |
1011 | u16 cmd = xm_read16(hw, port, XM_MMU_CMD); | 1061 | xm_link_down(hw, port); |
1012 | cmd &= ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX); | ||
1013 | xm_write16(hw, port, XM_MMU_CMD, cmd); | ||
1014 | /* dummy read to ensure writing */ | ||
1015 | (void) xm_read16(hw, port, XM_MMU_CMD); | ||
1016 | |||
1017 | if (netif_carrier_ok(dev)) | ||
1018 | skge_link_down(skge); | ||
1019 | return; | 1062 | return; |
1020 | } | 1063 | } |
1021 | 1064 | ||
@@ -1048,20 +1091,19 @@ static void bcom_check_link(struct skge_hw *hw, int port) | |||
1048 | return; | 1091 | return; |
1049 | } | 1092 | } |
1050 | 1093 | ||
1051 | |||
1052 | /* We are using IEEE 802.3z/D5.0 Table 37-4 */ | 1094 | /* We are using IEEE 802.3z/D5.0 Table 37-4 */ |
1053 | switch (aux & PHY_B_AS_PAUSE_MSK) { | 1095 | switch (aux & PHY_B_AS_PAUSE_MSK) { |
1054 | case PHY_B_AS_PAUSE_MSK: | 1096 | case PHY_B_AS_PAUSE_MSK: |
1055 | skge->flow_control = FLOW_MODE_SYMMETRIC; | 1097 | skge->flow_status = FLOW_STAT_SYMMETRIC; |
1056 | break; | 1098 | break; |
1057 | case PHY_B_AS_PRR: | 1099 | case PHY_B_AS_PRR: |
1058 | skge->flow_control = FLOW_MODE_REM_SEND; | 1100 | skge->flow_status = FLOW_STAT_REM_SEND; |
1059 | break; | 1101 | break; |
1060 | case PHY_B_AS_PRT: | 1102 | case PHY_B_AS_PRT: |
1061 | skge->flow_control = FLOW_MODE_LOC_SEND; | 1103 | skge->flow_status = FLOW_STAT_LOC_SEND; |
1062 | break; | 1104 | break; |
1063 | default: | 1105 | default: |
1064 | skge->flow_control = FLOW_MODE_NONE; | 1106 | skge->flow_status = FLOW_STAT_NONE; |
1065 | } | 1107 | } |
1066 | skge->speed = SPEED_1000; | 1108 | skge->speed = SPEED_1000; |
1067 | } | 1109 | } |
@@ -1191,17 +1233,7 @@ static void xm_phy_init(struct skge_port *skge) | |||
1191 | if (skge->advertising & ADVERTISED_1000baseT_Full) | 1233 | if (skge->advertising & ADVERTISED_1000baseT_Full) |
1192 | ctrl |= PHY_X_AN_FD; | 1234 | ctrl |= PHY_X_AN_FD; |
1193 | 1235 | ||
1194 | switch(skge->flow_control) { | 1236 | ctrl |= fiber_pause_map[skge->flow_control]; |
1195 | case FLOW_MODE_NONE: | ||
1196 | ctrl |= PHY_X_P_NO_PAUSE; | ||
1197 | break; | ||
1198 | case FLOW_MODE_LOC_SEND: | ||
1199 | ctrl |= PHY_X_P_ASYM_MD; | ||
1200 | break; | ||
1201 | case FLOW_MODE_SYMMETRIC: | ||
1202 | ctrl |= PHY_X_P_BOTH_MD; | ||
1203 | break; | ||
1204 | } | ||
1205 | 1237 | ||
1206 | xm_phy_write(hw, port, PHY_XMAC_AUNE_ADV, ctrl); | 1238 | xm_phy_write(hw, port, PHY_XMAC_AUNE_ADV, ctrl); |
1207 | 1239 | ||
@@ -1235,14 +1267,7 @@ static void xm_check_link(struct net_device *dev) | |||
1235 | status = xm_phy_read(hw, port, PHY_XMAC_STAT); | 1267 | status = xm_phy_read(hw, port, PHY_XMAC_STAT); |
1236 | 1268 | ||
1237 | if ((status & PHY_ST_LSYNC) == 0) { | 1269 | if ((status & PHY_ST_LSYNC) == 0) { |
1238 | u16 cmd = xm_read16(hw, port, XM_MMU_CMD); | 1270 | xm_link_down(hw, port); |
1239 | cmd &= ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX); | ||
1240 | xm_write16(hw, port, XM_MMU_CMD, cmd); | ||
1241 | /* dummy read to ensure writing */ | ||
1242 | (void) xm_read16(hw, port, XM_MMU_CMD); | ||
1243 | |||
1244 | if (netif_carrier_ok(dev)) | ||
1245 | skge_link_down(skge); | ||
1246 | return; | 1271 | return; |
1247 | } | 1272 | } |
1248 | 1273 | ||
@@ -1276,15 +1301,20 @@ static void xm_check_link(struct net_device *dev) | |||
1276 | } | 1301 | } |
1277 | 1302 | ||
1278 | /* We are using IEEE 802.3z/D5.0 Table 37-4 */ | 1303 | /* We are using IEEE 802.3z/D5.0 Table 37-4 */ |
1279 | if (lpa & PHY_X_P_SYM_MD) | 1304 | if ((skge->flow_control == FLOW_MODE_SYMMETRIC || |
1280 | skge->flow_control = FLOW_MODE_SYMMETRIC; | 1305 | skge->flow_control == FLOW_MODE_SYM_OR_REM) && |
1281 | else if ((lpa & PHY_X_RS_PAUSE) == PHY_X_P_ASYM_MD) | 1306 | (lpa & PHY_X_P_SYM_MD)) |
1282 | skge->flow_control = FLOW_MODE_REM_SEND; | 1307 | skge->flow_status = FLOW_STAT_SYMMETRIC; |
1283 | else if ((lpa & PHY_X_RS_PAUSE) == PHY_X_P_BOTH_MD) | 1308 | else if (skge->flow_control == FLOW_MODE_SYM_OR_REM && |
1284 | skge->flow_control = FLOW_MODE_LOC_SEND; | 1309 | (lpa & PHY_X_RS_PAUSE) == PHY_X_P_ASYM_MD) |
1310 | /* Enable PAUSE receive, disable PAUSE transmit */ | ||
1311 | skge->flow_status = FLOW_STAT_REM_SEND; | ||
1312 | else if (skge->flow_control == FLOW_MODE_LOC_SEND && | ||
1313 | (lpa & PHY_X_RS_PAUSE) == PHY_X_P_BOTH_MD) | ||
1314 | /* Disable PAUSE receive, enable PAUSE transmit */ | ||
1315 | skge->flow_status = FLOW_STAT_LOC_SEND; | ||
1285 | else | 1316 | else |
1286 | skge->flow_control = FLOW_MODE_NONE; | 1317 | skge->flow_status = FLOW_STAT_NONE; |
1287 | |||
1288 | 1318 | ||
1289 | skge->speed = SPEED_1000; | 1319 | skge->speed = SPEED_1000; |
1290 | } | 1320 | } |
@@ -1568,6 +1598,10 @@ static void genesis_mac_intr(struct skge_hw *hw, int port) | |||
1568 | printk(KERN_DEBUG PFX "%s: mac interrupt status 0x%x\n", | 1598 | printk(KERN_DEBUG PFX "%s: mac interrupt status 0x%x\n", |
1569 | skge->netdev->name, status); | 1599 | skge->netdev->name, status); |
1570 | 1600 | ||
1601 | if (hw->phy_type == SK_PHY_XMAC && | ||
1602 | (status & (XM_IS_INP_ASS | XM_IS_LIPA_RC))) | ||
1603 | xm_link_down(hw, port); | ||
1604 | |||
1571 | if (status & XM_IS_TXF_UR) { | 1605 | if (status & XM_IS_TXF_UR) { |
1572 | xm_write32(hw, port, XM_MODE, XM_MD_FTF); | 1606 | xm_write32(hw, port, XM_MODE, XM_MD_FTF); |
1573 | ++skge->net_stats.tx_fifo_errors; | 1607 | ++skge->net_stats.tx_fifo_errors; |
@@ -1582,7 +1616,7 @@ static void genesis_link_up(struct skge_port *skge) | |||
1582 | { | 1616 | { |
1583 | struct skge_hw *hw = skge->hw; | 1617 | struct skge_hw *hw = skge->hw; |
1584 | int port = skge->port; | 1618 | int port = skge->port; |
1585 | u16 cmd; | 1619 | u16 cmd, msk; |
1586 | u32 mode; | 1620 | u32 mode; |
1587 | 1621 | ||
1588 | cmd = xm_read16(hw, port, XM_MMU_CMD); | 1622 | cmd = xm_read16(hw, port, XM_MMU_CMD); |
@@ -1591,8 +1625,8 @@ static void genesis_link_up(struct skge_port *skge) | |||
1591 | * enabling pause frame reception is required for 1000BT | 1625 | * enabling pause frame reception is required for 1000BT |
1592 | * because the XMAC is not reset if the link is going down | 1626 | * because the XMAC is not reset if the link is going down |
1593 | */ | 1627 | */ |
1594 | if (skge->flow_control == FLOW_MODE_NONE || | 1628 | if (skge->flow_status == FLOW_STAT_NONE || |
1595 | skge->flow_control == FLOW_MODE_LOC_SEND) | 1629 | skge->flow_status == FLOW_STAT_LOC_SEND) |
1596 | /* Disable Pause Frame Reception */ | 1630 | /* Disable Pause Frame Reception */ |
1597 | cmd |= XM_MMU_IGN_PF; | 1631 | cmd |= XM_MMU_IGN_PF; |
1598 | else | 1632 | else |
@@ -1602,8 +1636,8 @@ static void genesis_link_up(struct skge_port *skge) | |||
1602 | xm_write16(hw, port, XM_MMU_CMD, cmd); | 1636 | xm_write16(hw, port, XM_MMU_CMD, cmd); |
1603 | 1637 | ||
1604 | mode = xm_read32(hw, port, XM_MODE); | 1638 | mode = xm_read32(hw, port, XM_MODE); |
1605 | if (skge->flow_control == FLOW_MODE_SYMMETRIC || | 1639 | if (skge->flow_status== FLOW_STAT_SYMMETRIC || |
1606 | skge->flow_control == FLOW_MODE_LOC_SEND) { | 1640 | skge->flow_status == FLOW_STAT_LOC_SEND) { |
1607 | /* | 1641 | /* |
1608 | * Configure Pause Frame Generation | 1642 | * Configure Pause Frame Generation |
1609 | * Use internal and external Pause Frame Generation. | 1643 | * Use internal and external Pause Frame Generation. |
@@ -1631,7 +1665,11 @@ static void genesis_link_up(struct skge_port *skge) | |||
1631 | } | 1665 | } |
1632 | 1666 | ||
1633 | xm_write32(hw, port, XM_MODE, mode); | 1667 | xm_write32(hw, port, XM_MODE, mode); |
1634 | xm_write16(hw, port, XM_IMSK, XM_DEF_MSK); | 1668 | msk = XM_DEF_MSK; |
1669 | if (hw->phy_type != SK_PHY_XMAC) | ||
1670 | msk |= XM_IS_INP_ASS; /* disable GP0 interrupt bit */ | ||
1671 | |||
1672 | xm_write16(hw, port, XM_IMSK, msk); | ||
1635 | xm_read16(hw, port, XM_ISRC); | 1673 | xm_read16(hw, port, XM_ISRC); |
1636 | 1674 | ||
1637 | /* get MMU Command Reg. */ | 1675 | /* get MMU Command Reg. */ |
@@ -1779,11 +1817,17 @@ static void yukon_init(struct skge_hw *hw, int port) | |||
1779 | adv |= PHY_M_AN_10_FD; | 1817 | adv |= PHY_M_AN_10_FD; |
1780 | if (skge->advertising & ADVERTISED_10baseT_Half) | 1818 | if (skge->advertising & ADVERTISED_10baseT_Half) |
1781 | adv |= PHY_M_AN_10_HD; | 1819 | adv |= PHY_M_AN_10_HD; |
1782 | } else /* special defines for FIBER (88E1011S only) */ | ||
1783 | adv |= PHY_M_AN_1000X_AHD | PHY_M_AN_1000X_AFD; | ||
1784 | 1820 | ||
1785 | /* Set Flow-control capabilities */ | 1821 | /* Set Flow-control capabilities */ |
1786 | adv |= phy_pause_map[skge->flow_control]; | 1822 | adv |= phy_pause_map[skge->flow_control]; |
1823 | } else { | ||
1824 | if (skge->advertising & ADVERTISED_1000baseT_Full) | ||
1825 | adv |= PHY_M_AN_1000X_AFD; | ||
1826 | if (skge->advertising & ADVERTISED_1000baseT_Half) | ||
1827 | adv |= PHY_M_AN_1000X_AHD; | ||
1828 | |||
1829 | adv |= fiber_pause_map[skge->flow_control]; | ||
1830 | } | ||
1787 | 1831 | ||
1788 | /* Restart Auto-negotiation */ | 1832 | /* Restart Auto-negotiation */ |
1789 | ctrl |= PHY_CT_ANE | PHY_CT_RE_CFG; | 1833 | ctrl |= PHY_CT_ANE | PHY_CT_RE_CFG; |
@@ -1917,6 +1961,11 @@ static void yukon_mac_init(struct skge_hw *hw, int port) | |||
1917 | case FLOW_MODE_LOC_SEND: | 1961 | case FLOW_MODE_LOC_SEND: |
1918 | /* disable Rx flow-control */ | 1962 | /* disable Rx flow-control */ |
1919 | reg |= GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS; | 1963 | reg |= GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS; |
1964 | break; | ||
1965 | case FLOW_MODE_SYMMETRIC: | ||
1966 | case FLOW_MODE_SYM_OR_REM: | ||
1967 | /* enable Tx & Rx flow-control */ | ||
1968 | break; | ||
1920 | } | 1969 | } |
1921 | 1970 | ||
1922 | gma_write16(hw, port, GM_GP_CTRL, reg); | 1971 | gma_write16(hw, port, GM_GP_CTRL, reg); |
@@ -2111,13 +2160,11 @@ static void yukon_link_down(struct skge_port *skge) | |||
2111 | ctrl &= ~(GM_GPCR_RX_ENA | GM_GPCR_TX_ENA); | 2160 | ctrl &= ~(GM_GPCR_RX_ENA | GM_GPCR_TX_ENA); |
2112 | gma_write16(hw, port, GM_GP_CTRL, ctrl); | 2161 | gma_write16(hw, port, GM_GP_CTRL, ctrl); |
2113 | 2162 | ||
2114 | if (skge->flow_control == FLOW_MODE_REM_SEND) { | 2163 | if (skge->flow_status == FLOW_STAT_REM_SEND) { |
2164 | ctrl = gm_phy_read(hw, port, PHY_MARV_AUNE_ADV); | ||
2165 | ctrl |= PHY_M_AN_ASP; | ||
2115 | /* restore Asymmetric Pause bit */ | 2166 | /* restore Asymmetric Pause bit */ |
2116 | gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, | 2167 | gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, ctrl); |
2117 | gm_phy_read(hw, port, | ||
2118 | PHY_MARV_AUNE_ADV) | ||
2119 | | PHY_M_AN_ASP); | ||
2120 | |||
2121 | } | 2168 | } |
2122 | 2169 | ||
2123 | yukon_reset(hw, port); | 2170 | yukon_reset(hw, port); |
@@ -2164,19 +2211,19 @@ static void yukon_phy_intr(struct skge_port *skge) | |||
2164 | /* We are using IEEE 802.3z/D5.0 Table 37-4 */ | 2211 | /* We are using IEEE 802.3z/D5.0 Table 37-4 */ |
2165 | switch (phystat & PHY_M_PS_PAUSE_MSK) { | 2212 | switch (phystat & PHY_M_PS_PAUSE_MSK) { |
2166 | case PHY_M_PS_PAUSE_MSK: | 2213 | case PHY_M_PS_PAUSE_MSK: |
2167 | skge->flow_control = FLOW_MODE_SYMMETRIC; | 2214 | skge->flow_status = FLOW_STAT_SYMMETRIC; |
2168 | break; | 2215 | break; |
2169 | case PHY_M_PS_RX_P_EN: | 2216 | case PHY_M_PS_RX_P_EN: |
2170 | skge->flow_control = FLOW_MODE_REM_SEND; | 2217 | skge->flow_status = FLOW_STAT_REM_SEND; |
2171 | break; | 2218 | break; |
2172 | case PHY_M_PS_TX_P_EN: | 2219 | case PHY_M_PS_TX_P_EN: |
2173 | skge->flow_control = FLOW_MODE_LOC_SEND; | 2220 | skge->flow_status = FLOW_STAT_LOC_SEND; |
2174 | break; | 2221 | break; |
2175 | default: | 2222 | default: |
2176 | skge->flow_control = FLOW_MODE_NONE; | 2223 | skge->flow_status = FLOW_STAT_NONE; |
2177 | } | 2224 | } |
2178 | 2225 | ||
2179 | if (skge->flow_control == FLOW_MODE_NONE || | 2226 | if (skge->flow_status == FLOW_STAT_NONE || |
2180 | (skge->speed < SPEED_1000 && skge->duplex == DUPLEX_HALF)) | 2227 | (skge->speed < SPEED_1000 && skge->duplex == DUPLEX_HALF)) |
2181 | skge_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF); | 2228 | skge_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF); |
2182 | else | 2229 | else |
@@ -3399,7 +3446,7 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port, | |||
3399 | 3446 | ||
3400 | /* Auto speed and flow control */ | 3447 | /* Auto speed and flow control */ |
3401 | skge->autoneg = AUTONEG_ENABLE; | 3448 | skge->autoneg = AUTONEG_ENABLE; |
3402 | skge->flow_control = FLOW_MODE_SYMMETRIC; | 3449 | skge->flow_control = FLOW_MODE_SYM_OR_REM; |
3403 | skge->duplex = -1; | 3450 | skge->duplex = -1; |
3404 | skge->speed = -1; | 3451 | skge->speed = -1; |
3405 | skge->advertising = skge_supported_modes(hw); | 3452 | skge->advertising = skge_supported_modes(hw); |
diff --git a/drivers/net/skge.h b/drivers/net/skge.h index d0b47d46cf9d..537c0aaa1db8 100644 --- a/drivers/net/skge.h +++ b/drivers/net/skge.h | |||
@@ -2195,7 +2195,8 @@ enum { | |||
2195 | XM_IS_RX_COMP = 1<<0, /* Bit 0: Frame Rx Complete */ | 2195 | XM_IS_RX_COMP = 1<<0, /* Bit 0: Frame Rx Complete */ |
2196 | }; | 2196 | }; |
2197 | 2197 | ||
2198 | #define XM_DEF_MSK (~(XM_IS_RXC_OV | XM_IS_TXC_OV | XM_IS_RXF_OV | XM_IS_TXF_UR)) | 2198 | #define XM_DEF_MSK (~(XM_IS_INP_ASS | XM_IS_LIPA_RC | \ |
2199 | XM_IS_RXF_OV | XM_IS_TXF_UR)) | ||
2199 | 2200 | ||
2200 | 2201 | ||
2201 | /* XM_HW_CFG 16 bit r/w Hardware Config Register */ | 2202 | /* XM_HW_CFG 16 bit r/w Hardware Config Register */ |
@@ -2426,13 +2427,24 @@ struct skge_hw { | |||
2426 | struct mutex phy_mutex; | 2427 | struct mutex phy_mutex; |
2427 | }; | 2428 | }; |
2428 | 2429 | ||
2429 | enum { | 2430 | enum pause_control { |
2430 | FLOW_MODE_NONE = 0, /* No Flow-Control */ | 2431 | FLOW_MODE_NONE = 1, /* No Flow-Control */ |
2431 | FLOW_MODE_LOC_SEND = 1, /* Local station sends PAUSE */ | 2432 | FLOW_MODE_LOC_SEND = 2, /* Local station sends PAUSE */ |
2432 | FLOW_MODE_REM_SEND = 2, /* Symmetric or just remote */ | ||
2433 | FLOW_MODE_SYMMETRIC = 3, /* Both stations may send PAUSE */ | 2433 | FLOW_MODE_SYMMETRIC = 3, /* Both stations may send PAUSE */ |
2434 | FLOW_MODE_SYM_OR_REM = 4, /* Both stations may send PAUSE or | ||
2435 | * just the remote station may send PAUSE | ||
2436 | */ | ||
2437 | }; | ||
2438 | |||
2439 | enum pause_status { | ||
2440 | FLOW_STAT_INDETERMINATED=0, /* indeterminated */ | ||
2441 | FLOW_STAT_NONE, /* No Flow Control */ | ||
2442 | FLOW_STAT_REM_SEND, /* Remote Station sends PAUSE */ | ||
2443 | FLOW_STAT_LOC_SEND, /* Local station sends PAUSE */ | ||
2444 | FLOW_STAT_SYMMETRIC, /* Both station may send PAUSE */ | ||
2434 | }; | 2445 | }; |
2435 | 2446 | ||
2447 | |||
2436 | struct skge_port { | 2448 | struct skge_port { |
2437 | u32 msg_enable; | 2449 | u32 msg_enable; |
2438 | struct skge_hw *hw; | 2450 | struct skge_hw *hw; |
@@ -2445,9 +2457,10 @@ struct skge_port { | |||
2445 | struct net_device_stats net_stats; | 2457 | struct net_device_stats net_stats; |
2446 | 2458 | ||
2447 | struct work_struct link_thread; | 2459 | struct work_struct link_thread; |
2460 | enum pause_control flow_control; | ||
2461 | enum pause_status flow_status; | ||
2448 | u8 rx_csum; | 2462 | u8 rx_csum; |
2449 | u8 blink_on; | 2463 | u8 blink_on; |
2450 | u8 flow_control; | ||
2451 | u8 wol; | 2464 | u8 wol; |
2452 | u8 autoneg; /* AUTONEG_ENABLE, AUTONEG_DISABLE */ | 2465 | u8 autoneg; /* AUTONEG_ENABLE, AUTONEG_DISABLE */ |
2453 | u8 duplex; /* DUPLEX_HALF, DUPLEX_FULL */ | 2466 | u8 duplex; /* DUPLEX_HALF, DUPLEX_FULL */ |
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 459c845d6648..16616f5440d0 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -10,8 +10,7 @@ | |||
10 | * | 10 | * |
11 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
12 | * it under the terms of the GNU General Public License as published by | 12 | * it under the terms of the GNU General Public License as published by |
13 | * the Free Software Foundation; either version 2 of the License, or | 13 | * the Free Software Foundation; either version 2 of the License. |
14 | * (at your option) any later version. | ||
15 | * | 14 | * |
16 | * This program is distributed in the hope that it will be useful, | 15 | * This program is distributed in the hope that it will be useful, |
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
@@ -50,7 +49,7 @@ | |||
50 | #include "sky2.h" | 49 | #include "sky2.h" |
51 | 50 | ||
52 | #define DRV_NAME "sky2" | 51 | #define DRV_NAME "sky2" |
53 | #define DRV_VERSION "1.9" | 52 | #define DRV_VERSION "1.10" |
54 | #define PFX DRV_NAME " " | 53 | #define PFX DRV_NAME " " |
55 | 54 | ||
56 | /* | 55 | /* |
@@ -96,9 +95,9 @@ static int disable_msi = 0; | |||
96 | module_param(disable_msi, int, 0); | 95 | module_param(disable_msi, int, 0); |
97 | MODULE_PARM_DESC(disable_msi, "Disable Message Signaled Interrupt (MSI)"); | 96 | MODULE_PARM_DESC(disable_msi, "Disable Message Signaled Interrupt (MSI)"); |
98 | 97 | ||
99 | static int idle_timeout = 100; | 98 | static int idle_timeout = 0; |
100 | module_param(idle_timeout, int, 0); | 99 | module_param(idle_timeout, int, 0); |
101 | MODULE_PARM_DESC(idle_timeout, "Idle timeout workaround for lost interrupts (ms)"); | 100 | MODULE_PARM_DESC(idle_timeout, "Watchdog timer for lost interrupts (ms)"); |
102 | 101 | ||
103 | static const struct pci_device_id sky2_id_table[] = { | 102 | static const struct pci_device_id sky2_id_table[] = { |
104 | { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9000) }, | 103 | { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9000) }, |
@@ -284,6 +283,31 @@ static void sky2_gmac_reset(struct sky2_hw *hw, unsigned port) | |||
284 | gma_write16(hw, port, GM_RX_CTRL, reg); | 283 | gma_write16(hw, port, GM_RX_CTRL, reg); |
285 | } | 284 | } |
286 | 285 | ||
286 | /* flow control to advertise bits */ | ||
287 | static const u16 copper_fc_adv[] = { | ||
288 | [FC_NONE] = 0, | ||
289 | [FC_TX] = PHY_M_AN_ASP, | ||
290 | [FC_RX] = PHY_M_AN_PC, | ||
291 | [FC_BOTH] = PHY_M_AN_PC | PHY_M_AN_ASP, | ||
292 | }; | ||
293 | |||
294 | /* flow control to advertise bits when using 1000BaseX */ | ||
295 | static const u16 fiber_fc_adv[] = { | ||
296 | [FC_BOTH] = PHY_M_P_BOTH_MD_X, | ||
297 | [FC_TX] = PHY_M_P_ASYM_MD_X, | ||
298 | [FC_RX] = PHY_M_P_SYM_MD_X, | ||
299 | [FC_NONE] = PHY_M_P_NO_PAUSE_X, | ||
300 | }; | ||
301 | |||
302 | /* flow control to GMA disable bits */ | ||
303 | static const u16 gm_fc_disable[] = { | ||
304 | [FC_NONE] = GM_GPCR_FC_RX_DIS | GM_GPCR_FC_TX_DIS, | ||
305 | [FC_TX] = GM_GPCR_FC_RX_DIS, | ||
306 | [FC_RX] = GM_GPCR_FC_TX_DIS, | ||
307 | [FC_BOTH] = 0, | ||
308 | }; | ||
309 | |||
310 | |||
287 | static void sky2_phy_init(struct sky2_hw *hw, unsigned port) | 311 | static void sky2_phy_init(struct sky2_hw *hw, unsigned port) |
288 | { | 312 | { |
289 | struct sky2_port *sky2 = netdev_priv(hw->dev[port]); | 313 | struct sky2_port *sky2 = netdev_priv(hw->dev[port]); |
@@ -356,16 +380,7 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) | |||
356 | gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg); | 380 | gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg); |
357 | } | 381 | } |
358 | 382 | ||
359 | ctrl = gm_phy_read(hw, port, PHY_MARV_CTRL); | 383 | ctrl = PHY_CT_RESET; |
360 | if (sky2->autoneg == AUTONEG_DISABLE) | ||
361 | ctrl &= ~PHY_CT_ANE; | ||
362 | else | ||
363 | ctrl |= PHY_CT_ANE; | ||
364 | |||
365 | ctrl |= PHY_CT_RESET; | ||
366 | gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl); | ||
367 | |||
368 | ctrl = 0; | ||
369 | ct1000 = 0; | 384 | ct1000 = 0; |
370 | adv = PHY_AN_CSMA; | 385 | adv = PHY_AN_CSMA; |
371 | reg = 0; | 386 | reg = 0; |
@@ -384,20 +399,16 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) | |||
384 | adv |= PHY_M_AN_10_FD; | 399 | adv |= PHY_M_AN_10_FD; |
385 | if (sky2->advertising & ADVERTISED_10baseT_Half) | 400 | if (sky2->advertising & ADVERTISED_10baseT_Half) |
386 | adv |= PHY_M_AN_10_HD; | 401 | adv |= PHY_M_AN_10_HD; |
402 | |||
403 | adv |= copper_fc_adv[sky2->flow_mode]; | ||
387 | } else { /* special defines for FIBER (88E1040S only) */ | 404 | } else { /* special defines for FIBER (88E1040S only) */ |
388 | if (sky2->advertising & ADVERTISED_1000baseT_Full) | 405 | if (sky2->advertising & ADVERTISED_1000baseT_Full) |
389 | adv |= PHY_M_AN_1000X_AFD; | 406 | adv |= PHY_M_AN_1000X_AFD; |
390 | if (sky2->advertising & ADVERTISED_1000baseT_Half) | 407 | if (sky2->advertising & ADVERTISED_1000baseT_Half) |
391 | adv |= PHY_M_AN_1000X_AHD; | 408 | adv |= PHY_M_AN_1000X_AHD; |
392 | } | ||
393 | 409 | ||
394 | /* Set Flow-control capabilities */ | 410 | adv |= fiber_fc_adv[sky2->flow_mode]; |
395 | if (sky2->tx_pause && sky2->rx_pause) | 411 | } |
396 | adv |= PHY_AN_PAUSE_CAP; /* symmetric */ | ||
397 | else if (sky2->rx_pause && !sky2->tx_pause) | ||
398 | adv |= PHY_AN_PAUSE_ASYM | PHY_AN_PAUSE_CAP; | ||
399 | else if (!sky2->rx_pause && sky2->tx_pause) | ||
400 | adv |= PHY_AN_PAUSE_ASYM; /* local */ | ||
401 | 412 | ||
402 | /* Restart Auto-negotiation */ | 413 | /* Restart Auto-negotiation */ |
403 | ctrl |= PHY_CT_ANE | PHY_CT_RE_CFG; | 414 | ctrl |= PHY_CT_ANE | PHY_CT_RE_CFG; |
@@ -422,25 +433,17 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) | |||
422 | if (sky2->duplex == DUPLEX_FULL) { | 433 | if (sky2->duplex == DUPLEX_FULL) { |
423 | reg |= GM_GPCR_DUP_FULL; | 434 | reg |= GM_GPCR_DUP_FULL; |
424 | ctrl |= PHY_CT_DUP_MD; | 435 | ctrl |= PHY_CT_DUP_MD; |
425 | } else if (sky2->speed != SPEED_1000 && hw->chip_id != CHIP_ID_YUKON_EC_U) { | 436 | } else if (sky2->speed < SPEED_1000) |
426 | /* Turn off flow control for 10/100mbps */ | 437 | sky2->flow_mode = FC_NONE; |
427 | sky2->rx_pause = 0; | ||
428 | sky2->tx_pause = 0; | ||
429 | } | ||
430 | 438 | ||
431 | if (!sky2->rx_pause) | ||
432 | reg |= GM_GPCR_FC_RX_DIS; | ||
433 | 439 | ||
434 | if (!sky2->tx_pause) | 440 | reg |= gm_fc_disable[sky2->flow_mode]; |
435 | reg |= GM_GPCR_FC_TX_DIS; | ||
436 | 441 | ||
437 | /* Forward pause packets to GMAC? */ | 442 | /* Forward pause packets to GMAC? */ |
438 | if (sky2->tx_pause || sky2->rx_pause) | 443 | if (sky2->flow_mode & FC_RX) |
439 | sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_ON); | 444 | sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_ON); |
440 | else | 445 | else |
441 | sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF); | 446 | sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF); |
442 | |||
443 | ctrl |= PHY_CT_RESET; | ||
444 | } | 447 | } |
445 | 448 | ||
446 | gma_write16(hw, port, GM_GP_CTRL, reg); | 449 | gma_write16(hw, port, GM_GP_CTRL, reg); |
@@ -683,7 +686,7 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port) | |||
683 | sky2_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON); | 686 | sky2_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON); |
684 | 687 | ||
685 | if (hw->chip_id == CHIP_ID_YUKON_EC_U) { | 688 | if (hw->chip_id == CHIP_ID_YUKON_EC_U) { |
686 | sky2_write8(hw, SK_REG(port, RX_GMF_LP_THR), 768/8); | 689 | sky2_write8(hw, SK_REG(port, RX_GMF_LP_THR), 512/8); |
687 | sky2_write8(hw, SK_REG(port, RX_GMF_UP_THR), 1024/8); | 690 | sky2_write8(hw, SK_REG(port, RX_GMF_UP_THR), 1024/8); |
688 | if (hw->dev[port]->mtu > ETH_DATA_LEN) { | 691 | if (hw->dev[port]->mtu > ETH_DATA_LEN) { |
689 | /* set Tx GMAC FIFO Almost Empty Threshold */ | 692 | /* set Tx GMAC FIFO Almost Empty Threshold */ |
@@ -695,16 +698,10 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port) | |||
695 | 698 | ||
696 | } | 699 | } |
697 | 700 | ||
698 | /* Assign Ram Buffer allocation. | 701 | /* Assign Ram Buffer allocation in units of 64bit (8 bytes) */ |
699 | * start and end are in units of 4k bytes | 702 | static void sky2_ramset(struct sky2_hw *hw, u16 q, u32 start, u32 end) |
700 | * ram registers are in units of 64bit words | ||
701 | */ | ||
702 | static void sky2_ramset(struct sky2_hw *hw, u16 q, u8 startk, u8 endk) | ||
703 | { | 703 | { |
704 | u32 start, end; | 704 | pr_debug(PFX "q %d %#x %#x\n", q, start, end); |
705 | |||
706 | start = startk * 4096/8; | ||
707 | end = (endk * 4096/8) - 1; | ||
708 | 705 | ||
709 | sky2_write8(hw, RB_ADDR(q, RB_CTRL), RB_RST_CLR); | 706 | sky2_write8(hw, RB_ADDR(q, RB_CTRL), RB_RST_CLR); |
710 | sky2_write32(hw, RB_ADDR(q, RB_START), start); | 707 | sky2_write32(hw, RB_ADDR(q, RB_START), start); |
@@ -713,7 +710,7 @@ static void sky2_ramset(struct sky2_hw *hw, u16 q, u8 startk, u8 endk) | |||
713 | sky2_write32(hw, RB_ADDR(q, RB_RP), start); | 710 | sky2_write32(hw, RB_ADDR(q, RB_RP), start); |
714 | 711 | ||
715 | if (q == Q_R1 || q == Q_R2) { | 712 | if (q == Q_R1 || q == Q_R2) { |
716 | u32 space = (endk - startk) * 4096/8; | 713 | u32 space = end - start + 1; |
717 | u32 tp = space - space/4; | 714 | u32 tp = space - space/4; |
718 | 715 | ||
719 | /* On receive queue's set the thresholds | 716 | /* On receive queue's set the thresholds |
@@ -1195,19 +1192,16 @@ static int sky2_up(struct net_device *dev) | |||
1195 | 1192 | ||
1196 | sky2_mac_init(hw, port); | 1193 | sky2_mac_init(hw, port); |
1197 | 1194 | ||
1198 | /* Determine available ram buffer space (in 4K blocks). | 1195 | /* Determine available ram buffer space in qwords. */ |
1199 | * Note: not sure about the FE setting below yet | 1196 | ramsize = sky2_read8(hw, B2_E_0) * 4096/8; |
1200 | */ | ||
1201 | if (hw->chip_id == CHIP_ID_YUKON_FE) | ||
1202 | ramsize = 4; | ||
1203 | else | ||
1204 | ramsize = sky2_read8(hw, B2_E_0); | ||
1205 | 1197 | ||
1206 | /* Give transmitter one third (rounded up) */ | 1198 | if (ramsize > 6*1024/8) |
1207 | rxspace = ramsize - (ramsize + 2) / 3; | 1199 | rxspace = ramsize - (ramsize + 2) / 3; |
1200 | else | ||
1201 | rxspace = ramsize / 2; | ||
1208 | 1202 | ||
1209 | sky2_ramset(hw, rxqaddr[port], 0, rxspace); | 1203 | sky2_ramset(hw, rxqaddr[port], 0, rxspace-1); |
1210 | sky2_ramset(hw, txqaddr[port], rxspace, ramsize); | 1204 | sky2_ramset(hw, txqaddr[port], rxspace, ramsize-1); |
1211 | 1205 | ||
1212 | /* Make sure SyncQ is disabled */ | 1206 | /* Make sure SyncQ is disabled */ |
1213 | sky2_write8(hw, RB_ADDR(port == 0 ? Q_XS1 : Q_XS2, RB_CTRL), | 1207 | sky2_write8(hw, RB_ADDR(port == 0 ? Q_XS1 : Q_XS2, RB_CTRL), |
@@ -1499,6 +1493,11 @@ static int sky2_down(struct net_device *dev) | |||
1499 | /* Stop more packets from being queued */ | 1493 | /* Stop more packets from being queued */ |
1500 | netif_stop_queue(dev); | 1494 | netif_stop_queue(dev); |
1501 | 1495 | ||
1496 | /* Disable port IRQ */ | ||
1497 | imask = sky2_read32(hw, B0_IMSK); | ||
1498 | imask &= ~portirq_msk[port]; | ||
1499 | sky2_write32(hw, B0_IMSK, imask); | ||
1500 | |||
1502 | sky2_gmac_reset(hw, port); | 1501 | sky2_gmac_reset(hw, port); |
1503 | 1502 | ||
1504 | /* Stop transmitter */ | 1503 | /* Stop transmitter */ |
@@ -1549,11 +1548,6 @@ static int sky2_down(struct net_device *dev) | |||
1549 | sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET); | 1548 | sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET); |
1550 | sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET); | 1549 | sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET); |
1551 | 1550 | ||
1552 | /* Disable port IRQ */ | ||
1553 | imask = sky2_read32(hw, B0_IMSK); | ||
1554 | imask &= ~portirq_msk[port]; | ||
1555 | sky2_write32(hw, B0_IMSK, imask); | ||
1556 | |||
1557 | sky2_phy_power(hw, port, 0); | 1551 | sky2_phy_power(hw, port, 0); |
1558 | 1552 | ||
1559 | /* turn off LED's */ | 1553 | /* turn off LED's */ |
@@ -1605,6 +1599,12 @@ static void sky2_link_up(struct sky2_port *sky2) | |||
1605 | struct sky2_hw *hw = sky2->hw; | 1599 | struct sky2_hw *hw = sky2->hw; |
1606 | unsigned port = sky2->port; | 1600 | unsigned port = sky2->port; |
1607 | u16 reg; | 1601 | u16 reg; |
1602 | static const char *fc_name[] = { | ||
1603 | [FC_NONE] = "none", | ||
1604 | [FC_TX] = "tx", | ||
1605 | [FC_RX] = "rx", | ||
1606 | [FC_BOTH] = "both", | ||
1607 | }; | ||
1608 | 1608 | ||
1609 | /* enable Rx/Tx */ | 1609 | /* enable Rx/Tx */ |
1610 | reg = gma_read16(hw, port, GM_GP_CTRL); | 1610 | reg = gma_read16(hw, port, GM_GP_CTRL); |
@@ -1648,8 +1648,7 @@ static void sky2_link_up(struct sky2_port *sky2) | |||
1648 | "%s: Link is up at %d Mbps, %s duplex, flow control %s\n", | 1648 | "%s: Link is up at %d Mbps, %s duplex, flow control %s\n", |
1649 | sky2->netdev->name, sky2->speed, | 1649 | sky2->netdev->name, sky2->speed, |
1650 | sky2->duplex == DUPLEX_FULL ? "full" : "half", | 1650 | sky2->duplex == DUPLEX_FULL ? "full" : "half", |
1651 | (sky2->tx_pause && sky2->rx_pause) ? "both" : | 1651 | fc_name[sky2->flow_status]); |
1652 | sky2->tx_pause ? "tx" : sky2->rx_pause ? "rx" : "none"); | ||
1653 | } | 1652 | } |
1654 | 1653 | ||
1655 | static void sky2_link_down(struct sky2_port *sky2) | 1654 | static void sky2_link_down(struct sky2_port *sky2) |
@@ -1664,7 +1663,7 @@ static void sky2_link_down(struct sky2_port *sky2) | |||
1664 | reg &= ~(GM_GPCR_RX_ENA | GM_GPCR_TX_ENA); | 1663 | reg &= ~(GM_GPCR_RX_ENA | GM_GPCR_TX_ENA); |
1665 | gma_write16(hw, port, GM_GP_CTRL, reg); | 1664 | gma_write16(hw, port, GM_GP_CTRL, reg); |
1666 | 1665 | ||
1667 | if (sky2->rx_pause && !sky2->tx_pause) { | 1666 | if (sky2->flow_status == FC_RX) { |
1668 | /* restore Asymmetric Pause bit */ | 1667 | /* restore Asymmetric Pause bit */ |
1669 | gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, | 1668 | gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, |
1670 | gm_phy_read(hw, port, PHY_MARV_AUNE_ADV) | 1669 | gm_phy_read(hw, port, PHY_MARV_AUNE_ADV) |
@@ -1683,6 +1682,14 @@ static void sky2_link_down(struct sky2_port *sky2) | |||
1683 | sky2_phy_init(hw, port); | 1682 | sky2_phy_init(hw, port); |
1684 | } | 1683 | } |
1685 | 1684 | ||
1685 | static enum flow_control sky2_flow(int rx, int tx) | ||
1686 | { | ||
1687 | if (rx) | ||
1688 | return tx ? FC_BOTH : FC_RX; | ||
1689 | else | ||
1690 | return tx ? FC_TX : FC_NONE; | ||
1691 | } | ||
1692 | |||
1686 | static int sky2_autoneg_done(struct sky2_port *sky2, u16 aux) | 1693 | static int sky2_autoneg_done(struct sky2_port *sky2, u16 aux) |
1687 | { | 1694 | { |
1688 | struct sky2_hw *hw = sky2->hw; | 1695 | struct sky2_hw *hw = sky2->hw; |
@@ -1703,39 +1710,20 @@ static int sky2_autoneg_done(struct sky2_port *sky2, u16 aux) | |||
1703 | } | 1710 | } |
1704 | 1711 | ||
1705 | sky2->speed = sky2_phy_speed(hw, aux); | 1712 | sky2->speed = sky2_phy_speed(hw, aux); |
1706 | if (sky2->speed == SPEED_1000) { | 1713 | sky2->duplex = (aux & PHY_M_PS_FULL_DUP) ? DUPLEX_FULL : DUPLEX_HALF; |
1707 | u16 ctl2 = gm_phy_read(hw, port, PHY_MARV_1000T_CTRL); | ||
1708 | u16 lpa2 = gm_phy_read(hw, port, PHY_MARV_1000T_STAT); | ||
1709 | if (lpa2 & PHY_B_1000S_MSF) { | ||
1710 | printk(KERN_ERR PFX "%s: master/slave fault", | ||
1711 | sky2->netdev->name); | ||
1712 | return -1; | ||
1713 | } | ||
1714 | |||
1715 | if ((ctl2 & PHY_M_1000C_AFD) && (lpa2 & PHY_B_1000S_LP_FD)) | ||
1716 | sky2->duplex = DUPLEX_FULL; | ||
1717 | else | ||
1718 | sky2->duplex = DUPLEX_HALF; | ||
1719 | } else { | ||
1720 | u16 adv = gm_phy_read(hw, port, PHY_MARV_AUNE_ADV); | ||
1721 | if ((aux & adv) & PHY_AN_FULL) | ||
1722 | sky2->duplex = DUPLEX_FULL; | ||
1723 | else | ||
1724 | sky2->duplex = DUPLEX_HALF; | ||
1725 | } | ||
1726 | 1714 | ||
1727 | /* Pause bits are offset (9..8) */ | 1715 | /* Pause bits are offset (9..8) */ |
1728 | if (hw->chip_id == CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U) | 1716 | if (hw->chip_id == CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U) |
1729 | aux >>= 6; | 1717 | aux >>= 6; |
1730 | 1718 | ||
1731 | sky2->rx_pause = (aux & PHY_M_PS_RX_P_EN) != 0; | 1719 | sky2->flow_status = sky2_flow(aux & PHY_M_PS_RX_P_EN, |
1732 | sky2->tx_pause = (aux & PHY_M_PS_TX_P_EN) != 0; | 1720 | aux & PHY_M_PS_TX_P_EN); |
1733 | 1721 | ||
1734 | if (sky2->duplex == DUPLEX_HALF && sky2->speed != SPEED_1000 | 1722 | if (sky2->duplex == DUPLEX_HALF && sky2->speed < SPEED_1000 |
1735 | && hw->chip_id != CHIP_ID_YUKON_EC_U) | 1723 | && hw->chip_id != CHIP_ID_YUKON_EC_U) |
1736 | sky2->rx_pause = sky2->tx_pause = 0; | 1724 | sky2->flow_status = FC_NONE; |
1737 | 1725 | ||
1738 | if (sky2->rx_pause || sky2->tx_pause) | 1726 | if (aux & PHY_M_PS_RX_P_EN) |
1739 | sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_ON); | 1727 | sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_ON); |
1740 | else | 1728 | else |
1741 | sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF); | 1729 | sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF); |
@@ -1750,13 +1738,13 @@ static void sky2_phy_intr(struct sky2_hw *hw, unsigned port) | |||
1750 | struct sky2_port *sky2 = netdev_priv(dev); | 1738 | struct sky2_port *sky2 = netdev_priv(dev); |
1751 | u16 istatus, phystat; | 1739 | u16 istatus, phystat; |
1752 | 1740 | ||
1741 | if (!netif_running(dev)) | ||
1742 | return; | ||
1743 | |||
1753 | spin_lock(&sky2->phy_lock); | 1744 | spin_lock(&sky2->phy_lock); |
1754 | istatus = gm_phy_read(hw, port, PHY_MARV_INT_STAT); | 1745 | istatus = gm_phy_read(hw, port, PHY_MARV_INT_STAT); |
1755 | phystat = gm_phy_read(hw, port, PHY_MARV_PHY_STAT); | 1746 | phystat = gm_phy_read(hw, port, PHY_MARV_PHY_STAT); |
1756 | 1747 | ||
1757 | if (!netif_running(dev)) | ||
1758 | goto out; | ||
1759 | |||
1760 | if (netif_msg_intr(sky2)) | 1748 | if (netif_msg_intr(sky2)) |
1761 | printk(KERN_INFO PFX "%s: phy interrupt status 0x%x 0x%x\n", | 1749 | printk(KERN_INFO PFX "%s: phy interrupt status 0x%x 0x%x\n", |
1762 | sky2->netdev->name, istatus, phystat); | 1750 | sky2->netdev->name, istatus, phystat); |
@@ -1907,7 +1895,7 @@ static struct sk_buff *receive_copy(struct sky2_port *sky2, | |||
1907 | pci_dma_sync_single_for_device(sky2->hw->pdev, re->data_addr, | 1895 | pci_dma_sync_single_for_device(sky2->hw->pdev, re->data_addr, |
1908 | length, PCI_DMA_FROMDEVICE); | 1896 | length, PCI_DMA_FROMDEVICE); |
1909 | re->skb->ip_summed = CHECKSUM_NONE; | 1897 | re->skb->ip_summed = CHECKSUM_NONE; |
1910 | __skb_put(skb, length); | 1898 | skb_put(skb, length); |
1911 | } | 1899 | } |
1912 | return skb; | 1900 | return skb; |
1913 | } | 1901 | } |
@@ -1970,7 +1958,7 @@ static struct sk_buff *receive_new(struct sky2_port *sky2, | |||
1970 | if (skb_shinfo(skb)->nr_frags) | 1958 | if (skb_shinfo(skb)->nr_frags) |
1971 | skb_put_frags(skb, hdr_space, length); | 1959 | skb_put_frags(skb, hdr_space, length); |
1972 | else | 1960 | else |
1973 | skb_put(skb, hdr_space); | 1961 | skb_put(skb, length); |
1974 | return skb; | 1962 | return skb; |
1975 | } | 1963 | } |
1976 | 1964 | ||
@@ -2016,6 +2004,10 @@ oversize: | |||
2016 | 2004 | ||
2017 | error: | 2005 | error: |
2018 | ++sky2->net_stats.rx_errors; | 2006 | ++sky2->net_stats.rx_errors; |
2007 | if (status & GMR_FS_RX_FF_OV) { | ||
2008 | sky2->net_stats.rx_fifo_errors++; | ||
2009 | goto resubmit; | ||
2010 | } | ||
2019 | 2011 | ||
2020 | if (netif_msg_rx_err(sky2) && net_ratelimit()) | 2012 | if (netif_msg_rx_err(sky2) && net_ratelimit()) |
2021 | printk(KERN_INFO PFX "%s: rx error, status 0x%x length %d\n", | 2013 | printk(KERN_INFO PFX "%s: rx error, status 0x%x length %d\n", |
@@ -2027,8 +2019,6 @@ error: | |||
2027 | sky2->net_stats.rx_frame_errors++; | 2019 | sky2->net_stats.rx_frame_errors++; |
2028 | if (status & GMR_FS_CRC_ERR) | 2020 | if (status & GMR_FS_CRC_ERR) |
2029 | sky2->net_stats.rx_crc_errors++; | 2021 | sky2->net_stats.rx_crc_errors++; |
2030 | if (status & GMR_FS_RX_FF_OV) | ||
2031 | sky2->net_stats.rx_fifo_errors++; | ||
2032 | 2022 | ||
2033 | goto resubmit; | 2023 | goto resubmit; |
2034 | } | 2024 | } |
@@ -2220,8 +2210,7 @@ static void sky2_hw_intr(struct sky2_hw *hw) | |||
2220 | /* PCI-Express uncorrectable Error occurred */ | 2210 | /* PCI-Express uncorrectable Error occurred */ |
2221 | u32 pex_err; | 2211 | u32 pex_err; |
2222 | 2212 | ||
2223 | pex_err = sky2_pci_read32(hw, | 2213 | pex_err = sky2_pci_read32(hw, PEX_UNC_ERR_STAT); |
2224 | hw->err_cap + PCI_ERR_UNCOR_STATUS); | ||
2225 | 2214 | ||
2226 | if (net_ratelimit()) | 2215 | if (net_ratelimit()) |
2227 | printk(KERN_ERR PFX "%s: pci express error (0x%x)\n", | 2216 | printk(KERN_ERR PFX "%s: pci express error (0x%x)\n", |
@@ -2229,20 +2218,15 @@ static void sky2_hw_intr(struct sky2_hw *hw) | |||
2229 | 2218 | ||
2230 | /* clear the interrupt */ | 2219 | /* clear the interrupt */ |
2231 | sky2_write32(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); | 2220 | sky2_write32(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); |
2232 | sky2_pci_write32(hw, | 2221 | sky2_pci_write32(hw, PEX_UNC_ERR_STAT, |
2233 | hw->err_cap + PCI_ERR_UNCOR_STATUS, | 2222 | 0xffffffffUL); |
2234 | 0xffffffffUL); | ||
2235 | sky2_write32(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); | 2223 | sky2_write32(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); |
2236 | 2224 | ||
2237 | 2225 | if (pex_err & PEX_FATAL_ERRORS) { | |
2238 | /* In case of fatal error mask off to keep from getting stuck */ | ||
2239 | if (pex_err & (PCI_ERR_UNC_POISON_TLP | PCI_ERR_UNC_FCP | ||
2240 | | PCI_ERR_UNC_DLP)) { | ||
2241 | u32 hwmsk = sky2_read32(hw, B0_HWE_IMSK); | 2226 | u32 hwmsk = sky2_read32(hw, B0_HWE_IMSK); |
2242 | hwmsk &= ~Y2_IS_PCI_EXP; | 2227 | hwmsk &= ~Y2_IS_PCI_EXP; |
2243 | sky2_write32(hw, B0_HWE_IMSK, hwmsk); | 2228 | sky2_write32(hw, B0_HWE_IMSK, hwmsk); |
2244 | } | 2229 | } |
2245 | |||
2246 | } | 2230 | } |
2247 | 2231 | ||
2248 | if (status & Y2_HWE_L1_MASK) | 2232 | if (status & Y2_HWE_L1_MASK) |
@@ -2423,7 +2407,6 @@ static int sky2_reset(struct sky2_hw *hw) | |||
2423 | u16 status; | 2407 | u16 status; |
2424 | u8 t8; | 2408 | u8 t8; |
2425 | int i; | 2409 | int i; |
2426 | u32 msk; | ||
2427 | 2410 | ||
2428 | sky2_write8(hw, B0_CTST, CS_RST_CLR); | 2411 | sky2_write8(hw, B0_CTST, CS_RST_CLR); |
2429 | 2412 | ||
@@ -2464,13 +2447,9 @@ static int sky2_reset(struct sky2_hw *hw) | |||
2464 | sky2_write8(hw, B0_CTST, CS_MRST_CLR); | 2447 | sky2_write8(hw, B0_CTST, CS_MRST_CLR); |
2465 | 2448 | ||
2466 | /* clear any PEX errors */ | 2449 | /* clear any PEX errors */ |
2467 | if (pci_find_capability(hw->pdev, PCI_CAP_ID_EXP)) { | 2450 | if (pci_find_capability(hw->pdev, PCI_CAP_ID_EXP)) |
2468 | hw->err_cap = pci_find_ext_capability(hw->pdev, PCI_EXT_CAP_ID_ERR); | 2451 | sky2_pci_write32(hw, PEX_UNC_ERR_STAT, 0xffffffffUL); |
2469 | if (hw->err_cap) | 2452 | |
2470 | sky2_pci_write32(hw, | ||
2471 | hw->err_cap + PCI_ERR_UNCOR_STATUS, | ||
2472 | 0xffffffffUL); | ||
2473 | } | ||
2474 | 2453 | ||
2475 | hw->pmd_type = sky2_read8(hw, B2_PMD_TYP); | 2454 | hw->pmd_type = sky2_read8(hw, B2_PMD_TYP); |
2476 | hw->ports = 1; | 2455 | hw->ports = 1; |
@@ -2527,10 +2506,7 @@ static int sky2_reset(struct sky2_hw *hw) | |||
2527 | sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_XS2), SK_RI_TO_53); | 2506 | sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_XS2), SK_RI_TO_53); |
2528 | } | 2507 | } |
2529 | 2508 | ||
2530 | msk = Y2_HWE_ALL_MASK; | 2509 | sky2_write32(hw, B0_HWE_IMSK, Y2_HWE_ALL_MASK); |
2531 | if (!hw->err_cap) | ||
2532 | msk &= ~Y2_IS_PCI_EXP; | ||
2533 | sky2_write32(hw, B0_HWE_IMSK, msk); | ||
2534 | 2510 | ||
2535 | for (i = 0; i < hw->ports; i++) | 2511 | for (i = 0; i < hw->ports; i++) |
2536 | sky2_gmac_reset(hw, i); | 2512 | sky2_gmac_reset(hw, i); |
@@ -2762,7 +2738,7 @@ static int sky2_nway_reset(struct net_device *dev) | |||
2762 | { | 2738 | { |
2763 | struct sky2_port *sky2 = netdev_priv(dev); | 2739 | struct sky2_port *sky2 = netdev_priv(dev); |
2764 | 2740 | ||
2765 | if (sky2->autoneg != AUTONEG_ENABLE) | 2741 | if (!netif_running(dev) || sky2->autoneg != AUTONEG_ENABLE) |
2766 | return -EINVAL; | 2742 | return -EINVAL; |
2767 | 2743 | ||
2768 | sky2_phy_reinit(sky2); | 2744 | sky2_phy_reinit(sky2); |
@@ -2864,6 +2840,14 @@ static int sky2_set_mac_address(struct net_device *dev, void *p) | |||
2864 | return 0; | 2840 | return 0; |
2865 | } | 2841 | } |
2866 | 2842 | ||
2843 | static void inline sky2_add_filter(u8 filter[8], const u8 *addr) | ||
2844 | { | ||
2845 | u32 bit; | ||
2846 | |||
2847 | bit = ether_crc(ETH_ALEN, addr) & 63; | ||
2848 | filter[bit >> 3] |= 1 << (bit & 7); | ||
2849 | } | ||
2850 | |||
2867 | static void sky2_set_multicast(struct net_device *dev) | 2851 | static void sky2_set_multicast(struct net_device *dev) |
2868 | { | 2852 | { |
2869 | struct sky2_port *sky2 = netdev_priv(dev); | 2853 | struct sky2_port *sky2 = netdev_priv(dev); |
@@ -2872,7 +2856,10 @@ static void sky2_set_multicast(struct net_device *dev) | |||
2872 | struct dev_mc_list *list = dev->mc_list; | 2856 | struct dev_mc_list *list = dev->mc_list; |
2873 | u16 reg; | 2857 | u16 reg; |
2874 | u8 filter[8]; | 2858 | u8 filter[8]; |
2859 | int rx_pause; | ||
2860 | static const u8 pause_mc_addr[ETH_ALEN] = { 0x1, 0x80, 0xc2, 0x0, 0x0, 0x1 }; | ||
2875 | 2861 | ||
2862 | rx_pause = (sky2->flow_status == FC_RX || sky2->flow_status == FC_BOTH); | ||
2876 | memset(filter, 0, sizeof(filter)); | 2863 | memset(filter, 0, sizeof(filter)); |
2877 | 2864 | ||
2878 | reg = gma_read16(hw, port, GM_RX_CTRL); | 2865 | reg = gma_read16(hw, port, GM_RX_CTRL); |
@@ -2880,18 +2867,19 @@ static void sky2_set_multicast(struct net_device *dev) | |||
2880 | 2867 | ||
2881 | if (dev->flags & IFF_PROMISC) /* promiscuous */ | 2868 | if (dev->flags & IFF_PROMISC) /* promiscuous */ |
2882 | reg &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA); | 2869 | reg &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA); |
2883 | else if ((dev->flags & IFF_ALLMULTI) || dev->mc_count > 16) /* all multicast */ | 2870 | else if (dev->flags & IFF_ALLMULTI) |
2884 | memset(filter, 0xff, sizeof(filter)); | 2871 | memset(filter, 0xff, sizeof(filter)); |
2885 | else if (dev->mc_count == 0) /* no multicast */ | 2872 | else if (dev->mc_count == 0 && !rx_pause) |
2886 | reg &= ~GM_RXCR_MCF_ENA; | 2873 | reg &= ~GM_RXCR_MCF_ENA; |
2887 | else { | 2874 | else { |
2888 | int i; | 2875 | int i; |
2889 | reg |= GM_RXCR_MCF_ENA; | 2876 | reg |= GM_RXCR_MCF_ENA; |
2890 | 2877 | ||
2891 | for (i = 0; list && i < dev->mc_count; i++, list = list->next) { | 2878 | if (rx_pause) |
2892 | u32 bit = ether_crc(ETH_ALEN, list->dmi_addr) & 0x3f; | 2879 | sky2_add_filter(filter, pause_mc_addr); |
2893 | filter[bit / 8] |= 1 << (bit % 8); | 2880 | |
2894 | } | 2881 | for (i = 0; list && i < dev->mc_count; i++, list = list->next) |
2882 | sky2_add_filter(filter, list->dmi_addr); | ||
2895 | } | 2883 | } |
2896 | 2884 | ||
2897 | gma_write16(hw, port, GM_MC_ADDR_H1, | 2885 | gma_write16(hw, port, GM_MC_ADDR_H1, |
@@ -3004,8 +2992,20 @@ static void sky2_get_pauseparam(struct net_device *dev, | |||
3004 | { | 2992 | { |
3005 | struct sky2_port *sky2 = netdev_priv(dev); | 2993 | struct sky2_port *sky2 = netdev_priv(dev); |
3006 | 2994 | ||
3007 | ecmd->tx_pause = sky2->tx_pause; | 2995 | switch (sky2->flow_mode) { |
3008 | ecmd->rx_pause = sky2->rx_pause; | 2996 | case FC_NONE: |
2997 | ecmd->tx_pause = ecmd->rx_pause = 0; | ||
2998 | break; | ||
2999 | case FC_TX: | ||
3000 | ecmd->tx_pause = 1, ecmd->rx_pause = 0; | ||
3001 | break; | ||
3002 | case FC_RX: | ||
3003 | ecmd->tx_pause = 0, ecmd->rx_pause = 1; | ||
3004 | break; | ||
3005 | case FC_BOTH: | ||
3006 | ecmd->tx_pause = ecmd->rx_pause = 1; | ||
3007 | } | ||
3008 | |||
3009 | ecmd->autoneg = sky2->autoneg; | 3009 | ecmd->autoneg = sky2->autoneg; |
3010 | } | 3010 | } |
3011 | 3011 | ||
@@ -3015,10 +3015,10 @@ static int sky2_set_pauseparam(struct net_device *dev, | |||
3015 | struct sky2_port *sky2 = netdev_priv(dev); | 3015 | struct sky2_port *sky2 = netdev_priv(dev); |
3016 | 3016 | ||
3017 | sky2->autoneg = ecmd->autoneg; | 3017 | sky2->autoneg = ecmd->autoneg; |
3018 | sky2->tx_pause = ecmd->tx_pause != 0; | 3018 | sky2->flow_mode = sky2_flow(ecmd->rx_pause, ecmd->tx_pause); |
3019 | sky2->rx_pause = ecmd->rx_pause != 0; | ||
3020 | 3019 | ||
3021 | sky2_phy_reinit(sky2); | 3020 | if (netif_running(dev)) |
3021 | sky2_phy_reinit(sky2); | ||
3022 | 3022 | ||
3023 | return 0; | 3023 | return 0; |
3024 | } | 3024 | } |
@@ -3238,7 +3238,11 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw, | |||
3238 | dev->poll = sky2_poll; | 3238 | dev->poll = sky2_poll; |
3239 | dev->weight = NAPI_WEIGHT; | 3239 | dev->weight = NAPI_WEIGHT; |
3240 | #ifdef CONFIG_NET_POLL_CONTROLLER | 3240 | #ifdef CONFIG_NET_POLL_CONTROLLER |
3241 | dev->poll_controller = sky2_netpoll; | 3241 | /* Network console (only works on port 0) |
3242 | * because netpoll makes assumptions about NAPI | ||
3243 | */ | ||
3244 | if (port == 0) | ||
3245 | dev->poll_controller = sky2_netpoll; | ||
3242 | #endif | 3246 | #endif |
3243 | 3247 | ||
3244 | sky2 = netdev_priv(dev); | 3248 | sky2 = netdev_priv(dev); |
@@ -3248,8 +3252,8 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw, | |||
3248 | 3252 | ||
3249 | /* Auto speed and flow control */ | 3253 | /* Auto speed and flow control */ |
3250 | sky2->autoneg = AUTONEG_ENABLE; | 3254 | sky2->autoneg = AUTONEG_ENABLE; |
3251 | sky2->tx_pause = 1; | 3255 | sky2->flow_mode = FC_BOTH; |
3252 | sky2->rx_pause = 1; | 3256 | |
3253 | sky2->duplex = -1; | 3257 | sky2->duplex = -1; |
3254 | sky2->speed = -1; | 3258 | sky2->speed = -1; |
3255 | sky2->advertising = sky2_supported_modes(hw); | 3259 | sky2->advertising = sky2_supported_modes(hw); |
@@ -3340,9 +3344,8 @@ static int __devinit sky2_test_msi(struct sky2_hw *hw) | |||
3340 | 3344 | ||
3341 | if (!hw->msi_detected) { | 3345 | if (!hw->msi_detected) { |
3342 | /* MSI test failed, go back to INTx mode */ | 3346 | /* MSI test failed, go back to INTx mode */ |
3343 | printk(KERN_WARNING PFX "%s: No interrupt was generated using MSI, " | 3347 | printk(KERN_INFO PFX "%s: No interrupt generated using MSI, " |
3344 | "switching to INTx mode. Please report this failure to " | 3348 | "switching to INTx mode.\n", |
3345 | "the PCI maintainer and include system chipset information.\n", | ||
3346 | pci_name(pdev)); | 3349 | pci_name(pdev)); |
3347 | 3350 | ||
3348 | err = -EOPNOTSUPP; | 3351 | err = -EOPNOTSUPP; |
@@ -3350,6 +3353,7 @@ static int __devinit sky2_test_msi(struct sky2_hw *hw) | |||
3350 | } | 3353 | } |
3351 | 3354 | ||
3352 | sky2_write32(hw, B0_IMSK, 0); | 3355 | sky2_write32(hw, B0_IMSK, 0); |
3356 | sky2_read32(hw, B0_IMSK); | ||
3353 | 3357 | ||
3354 | free_irq(pdev->irq, hw); | 3358 | free_irq(pdev->irq, hw); |
3355 | 3359 | ||
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h index f66109a96d95..6d2a23f66c9a 100644 --- a/drivers/net/sky2.h +++ b/drivers/net/sky2.h | |||
@@ -6,15 +6,24 @@ | |||
6 | 6 | ||
7 | #define ETH_JUMBO_MTU 9000 /* Maximum MTU supported */ | 7 | #define ETH_JUMBO_MTU 9000 /* Maximum MTU supported */ |
8 | 8 | ||
9 | /* PCI device specific config registers */ | 9 | /* PCI config registers */ |
10 | enum { | 10 | enum { |
11 | PCI_DEV_REG1 = 0x40, | 11 | PCI_DEV_REG1 = 0x40, |
12 | PCI_DEV_REG2 = 0x44, | 12 | PCI_DEV_REG2 = 0x44, |
13 | PCI_DEV_STATUS = 0x7c, | ||
13 | PCI_DEV_REG3 = 0x80, | 14 | PCI_DEV_REG3 = 0x80, |
14 | PCI_DEV_REG4 = 0x84, | 15 | PCI_DEV_REG4 = 0x84, |
15 | PCI_DEV_REG5 = 0x88, | 16 | PCI_DEV_REG5 = 0x88, |
16 | }; | 17 | }; |
17 | 18 | ||
19 | enum { | ||
20 | PEX_DEV_CAP = 0xe4, | ||
21 | PEX_DEV_CTRL = 0xe8, | ||
22 | PEX_DEV_STA = 0xea, | ||
23 | PEX_LNK_STAT = 0xf2, | ||
24 | PEX_UNC_ERR_STAT= 0x104, | ||
25 | }; | ||
26 | |||
18 | /* Yukon-2 */ | 27 | /* Yukon-2 */ |
19 | enum pci_dev_reg_1 { | 28 | enum pci_dev_reg_1 { |
20 | PCI_Y2_PIG_ENA = 1<<31, /* Enable Plug-in-Go (YUKON-2) */ | 29 | PCI_Y2_PIG_ENA = 1<<31, /* Enable Plug-in-Go (YUKON-2) */ |
@@ -63,6 +72,39 @@ enum pci_dev_reg_4 { | |||
63 | PCI_STATUS_REC_MASTER_ABORT | \ | 72 | PCI_STATUS_REC_MASTER_ABORT | \ |
64 | PCI_STATUS_REC_TARGET_ABORT | \ | 73 | PCI_STATUS_REC_TARGET_ABORT | \ |
65 | PCI_STATUS_PARITY) | 74 | PCI_STATUS_PARITY) |
75 | |||
76 | enum pex_dev_ctrl { | ||
77 | PEX_DC_MAX_RRS_MSK = 7<<12, /* Bit 14..12: Max. Read Request Size */ | ||
78 | PEX_DC_EN_NO_SNOOP = 1<<11,/* Enable No Snoop */ | ||
79 | PEX_DC_EN_AUX_POW = 1<<10,/* Enable AUX Power */ | ||
80 | PEX_DC_EN_PHANTOM = 1<<9, /* Enable Phantom Functions */ | ||
81 | PEX_DC_EN_EXT_TAG = 1<<8, /* Enable Extended Tag Field */ | ||
82 | PEX_DC_MAX_PLS_MSK = 7<<5, /* Bit 7.. 5: Max. Payload Size Mask */ | ||
83 | PEX_DC_EN_REL_ORD = 1<<4, /* Enable Relaxed Ordering */ | ||
84 | PEX_DC_EN_UNS_RQ_RP = 1<<3, /* Enable Unsupported Request Reporting */ | ||
85 | PEX_DC_EN_FAT_ER_RP = 1<<2, /* Enable Fatal Error Reporting */ | ||
86 | PEX_DC_EN_NFA_ER_RP = 1<<1, /* Enable Non-Fatal Error Reporting */ | ||
87 | PEX_DC_EN_COR_ER_RP = 1<<0, /* Enable Correctable Error Reporting */ | ||
88 | }; | ||
89 | #define PEX_DC_MAX_RD_RQ_SIZE(x) (((x)<<12) & PEX_DC_MAX_RRS_MSK) | ||
90 | |||
91 | /* PEX_UNC_ERR_STAT PEX Uncorrectable Errors Status Register (Yukon-2) */ | ||
92 | enum pex_err { | ||
93 | PEX_UNSUP_REQ = 1<<20, /* Unsupported Request Error */ | ||
94 | |||
95 | PEX_MALFOR_TLP = 1<<18, /* Malformed TLP */ | ||
96 | |||
97 | PEX_UNEXP_COMP = 1<<16, /* Unexpected Completion */ | ||
98 | |||
99 | PEX_COMP_TO = 1<<14, /* Completion Timeout */ | ||
100 | PEX_FLOW_CTRL_P = 1<<13, /* Flow Control Protocol Error */ | ||
101 | PEX_POIS_TLP = 1<<12, /* Poisoned TLP */ | ||
102 | |||
103 | PEX_DATA_LINK_P = 1<<4, /* Data Link Protocol Error */ | ||
104 | PEX_FATAL_ERRORS= (PEX_MALFOR_TLP | PEX_FLOW_CTRL_P | PEX_DATA_LINK_P), | ||
105 | }; | ||
106 | |||
107 | |||
66 | enum csr_regs { | 108 | enum csr_regs { |
67 | B0_RAP = 0x0000, | 109 | B0_RAP = 0x0000, |
68 | B0_CTST = 0x0004, | 110 | B0_CTST = 0x0004, |
@@ -1534,7 +1576,7 @@ enum { | |||
1534 | 1576 | ||
1535 | GMR_FS_ANY_ERR = GMR_FS_RX_FF_OV | GMR_FS_CRC_ERR | | 1577 | GMR_FS_ANY_ERR = GMR_FS_RX_FF_OV | GMR_FS_CRC_ERR | |
1536 | GMR_FS_FRAGMENT | GMR_FS_LONG_ERR | | 1578 | GMR_FS_FRAGMENT | GMR_FS_LONG_ERR | |
1537 | GMR_FS_MII_ERR | GMR_FS_BAD_FC | | 1579 | GMR_FS_MII_ERR | GMR_FS_GOOD_FC | GMR_FS_BAD_FC | |
1538 | GMR_FS_UN_SIZE | GMR_FS_JABBER, | 1580 | GMR_FS_UN_SIZE | GMR_FS_JABBER, |
1539 | }; | 1581 | }; |
1540 | 1582 | ||
@@ -1786,6 +1828,13 @@ struct rx_ring_info { | |||
1786 | dma_addr_t frag_addr[ETH_JUMBO_MTU >> PAGE_SHIFT]; | 1828 | dma_addr_t frag_addr[ETH_JUMBO_MTU >> PAGE_SHIFT]; |
1787 | }; | 1829 | }; |
1788 | 1830 | ||
1831 | enum flow_control { | ||
1832 | FC_NONE = 0, | ||
1833 | FC_TX = 1, | ||
1834 | FC_RX = 2, | ||
1835 | FC_BOTH = 3, | ||
1836 | }; | ||
1837 | |||
1789 | struct sky2_port { | 1838 | struct sky2_port { |
1790 | struct sky2_hw *hw; | 1839 | struct sky2_hw *hw; |
1791 | struct net_device *netdev; | 1840 | struct net_device *netdev; |
@@ -1818,13 +1867,13 @@ struct sky2_port { | |||
1818 | 1867 | ||
1819 | dma_addr_t rx_le_map; | 1868 | dma_addr_t rx_le_map; |
1820 | dma_addr_t tx_le_map; | 1869 | dma_addr_t tx_le_map; |
1821 | u32 advertising; /* ADVERTISED_ bits */ | 1870 | u16 advertising; /* ADVERTISED_ bits */ |
1822 | u16 speed; /* SPEED_1000, SPEED_100, ... */ | 1871 | u16 speed; /* SPEED_1000, SPEED_100, ... */ |
1823 | u8 autoneg; /* AUTONEG_ENABLE, AUTONEG_DISABLE */ | 1872 | u8 autoneg; /* AUTONEG_ENABLE, AUTONEG_DISABLE */ |
1824 | u8 duplex; /* DUPLEX_HALF, DUPLEX_FULL */ | 1873 | u8 duplex; /* DUPLEX_HALF, DUPLEX_FULL */ |
1825 | u8 rx_pause; | ||
1826 | u8 tx_pause; | ||
1827 | u8 rx_csum; | 1874 | u8 rx_csum; |
1875 | enum flow_control flow_mode; | ||
1876 | enum flow_control flow_status; | ||
1828 | 1877 | ||
1829 | struct net_device_stats net_stats; | 1878 | struct net_device_stats net_stats; |
1830 | 1879 | ||
@@ -1836,7 +1885,6 @@ struct sky2_hw { | |||
1836 | struct net_device *dev[2]; | 1885 | struct net_device *dev[2]; |
1837 | 1886 | ||
1838 | int pm_cap; | 1887 | int pm_cap; |
1839 | int err_cap; | ||
1840 | u8 chip_id; | 1888 | u8 chip_id; |
1841 | u8 chip_rev; | 1889 | u8 chip_rev; |
1842 | u8 pmd_type; | 1890 | u8 pmd_type; |
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h index 636dbfcdf8cb..a8640169fc77 100644 --- a/drivers/net/smc91x.h +++ b/drivers/net/smc91x.h | |||
@@ -398,6 +398,42 @@ static inline void LPD7_SMC_outsw (unsigned char* a, int r, | |||
398 | 398 | ||
399 | #define SMC_IRQ_FLAGS (0) | 399 | #define SMC_IRQ_FLAGS (0) |
400 | 400 | ||
401 | #elif defined(CONFIG_ARCH_VERSATILE) | ||
402 | |||
403 | #define SMC_CAN_USE_8BIT 1 | ||
404 | #define SMC_CAN_USE_16BIT 1 | ||
405 | #define SMC_CAN_USE_32BIT 1 | ||
406 | #define SMC_NOWAIT 1 | ||
407 | |||
408 | #define SMC_inb(a, r) readb((a) + (r)) | ||
409 | #define SMC_inw(a, r) readw((a) + (r)) | ||
410 | #define SMC_inl(a, r) readl((a) + (r)) | ||
411 | #define SMC_outb(v, a, r) writeb(v, (a) + (r)) | ||
412 | #define SMC_outw(v, a, r) writew(v, (a) + (r)) | ||
413 | #define SMC_outl(v, a, r) writel(v, (a) + (r)) | ||
414 | #define SMC_insl(a, r, p, l) readsl((a) + (r), p, l) | ||
415 | #define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l) | ||
416 | |||
417 | #define SMC_IRQ_FLAGS (0) | ||
418 | |||
419 | #elif defined(CONFIG_ARCH_VERSATILE) | ||
420 | |||
421 | #define SMC_CAN_USE_8BIT 1 | ||
422 | #define SMC_CAN_USE_16BIT 1 | ||
423 | #define SMC_CAN_USE_32BIT 1 | ||
424 | #define SMC_NOWAIT 1 | ||
425 | |||
426 | #define SMC_inb(a, r) readb((a) + (r)) | ||
427 | #define SMC_inw(a, r) readw((a) + (r)) | ||
428 | #define SMC_inl(a, r) readl((a) + (r)) | ||
429 | #define SMC_outb(v, a, r) writeb(v, (a) + (r)) | ||
430 | #define SMC_outw(v, a, r) writew(v, (a) + (r)) | ||
431 | #define SMC_outl(v, a, r) writel(v, (a) + (r)) | ||
432 | #define SMC_insl(a, r, p, l) readsl((a) + (r), p, l) | ||
433 | #define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l) | ||
434 | |||
435 | #define SMC_IRQ_FLAGS (0) | ||
436 | |||
401 | #else | 437 | #else |
402 | 438 | ||
403 | #define SMC_CAN_USE_8BIT 1 | 439 | #define SMC_CAN_USE_8BIT 1 |
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c index 46a009085f7c..418138dd6c68 100644 --- a/drivers/net/spider_net.c +++ b/drivers/net/spider_net.c | |||
@@ -55,12 +55,13 @@ MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com> and Jens Osterkamp " \ | |||
55 | "<Jens.Osterkamp@de.ibm.com>"); | 55 | "<Jens.Osterkamp@de.ibm.com>"); |
56 | MODULE_DESCRIPTION("Spider Southbridge Gigabit Ethernet driver"); | 56 | MODULE_DESCRIPTION("Spider Southbridge Gigabit Ethernet driver"); |
57 | MODULE_LICENSE("GPL"); | 57 | MODULE_LICENSE("GPL"); |
58 | MODULE_VERSION(VERSION); | ||
58 | 59 | ||
59 | static int rx_descriptors = SPIDER_NET_RX_DESCRIPTORS_DEFAULT; | 60 | static int rx_descriptors = SPIDER_NET_RX_DESCRIPTORS_DEFAULT; |
60 | static int tx_descriptors = SPIDER_NET_TX_DESCRIPTORS_DEFAULT; | 61 | static int tx_descriptors = SPIDER_NET_TX_DESCRIPTORS_DEFAULT; |
61 | 62 | ||
62 | module_param(rx_descriptors, int, 0644); | 63 | module_param(rx_descriptors, int, 0444); |
63 | module_param(tx_descriptors, int, 0644); | 64 | module_param(tx_descriptors, int, 0444); |
64 | 65 | ||
65 | MODULE_PARM_DESC(rx_descriptors, "number of descriptors used " \ | 66 | MODULE_PARM_DESC(rx_descriptors, "number of descriptors used " \ |
66 | "in rx chains"); | 67 | "in rx chains"); |
@@ -300,7 +301,7 @@ static int | |||
300 | spider_net_init_chain(struct spider_net_card *card, | 301 | spider_net_init_chain(struct spider_net_card *card, |
301 | struct spider_net_descr_chain *chain, | 302 | struct spider_net_descr_chain *chain, |
302 | struct spider_net_descr *start_descr, | 303 | struct spider_net_descr *start_descr, |
303 | int direction, int no) | 304 | int no) |
304 | { | 305 | { |
305 | int i; | 306 | int i; |
306 | struct spider_net_descr *descr; | 307 | struct spider_net_descr *descr; |
@@ -315,7 +316,7 @@ spider_net_init_chain(struct spider_net_card *card, | |||
315 | 316 | ||
316 | buf = pci_map_single(card->pdev, descr, | 317 | buf = pci_map_single(card->pdev, descr, |
317 | SPIDER_NET_DESCR_SIZE, | 318 | SPIDER_NET_DESCR_SIZE, |
318 | direction); | 319 | PCI_DMA_BIDIRECTIONAL); |
319 | 320 | ||
320 | if (pci_dma_mapping_error(buf)) | 321 | if (pci_dma_mapping_error(buf)) |
321 | goto iommu_error; | 322 | goto iommu_error; |
@@ -329,11 +330,6 @@ spider_net_init_chain(struct spider_net_card *card, | |||
329 | (descr-1)->next = start_descr; | 330 | (descr-1)->next = start_descr; |
330 | start_descr->prev = descr-1; | 331 | start_descr->prev = descr-1; |
331 | 332 | ||
332 | descr = start_descr; | ||
333 | if (direction == PCI_DMA_FROMDEVICE) | ||
334 | for (i=0; i < no; i++, descr++) | ||
335 | descr->next_descr_addr = descr->next->bus_addr; | ||
336 | |||
337 | spin_lock_init(&chain->lock); | 333 | spin_lock_init(&chain->lock); |
338 | chain->head = start_descr; | 334 | chain->head = start_descr; |
339 | chain->tail = start_descr; | 335 | chain->tail = start_descr; |
@@ -346,7 +342,7 @@ iommu_error: | |||
346 | if (descr->bus_addr) | 342 | if (descr->bus_addr) |
347 | pci_unmap_single(card->pdev, descr->bus_addr, | 343 | pci_unmap_single(card->pdev, descr->bus_addr, |
348 | SPIDER_NET_DESCR_SIZE, | 344 | SPIDER_NET_DESCR_SIZE, |
349 | direction); | 345 | PCI_DMA_BIDIRECTIONAL); |
350 | return -ENOMEM; | 346 | return -ENOMEM; |
351 | } | 347 | } |
352 | 348 | ||
@@ -362,15 +358,15 @@ spider_net_free_rx_chain_contents(struct spider_net_card *card) | |||
362 | struct spider_net_descr *descr; | 358 | struct spider_net_descr *descr; |
363 | 359 | ||
364 | descr = card->rx_chain.head; | 360 | descr = card->rx_chain.head; |
365 | while (descr->next != card->rx_chain.head) { | 361 | do { |
366 | if (descr->skb) { | 362 | if (descr->skb) { |
367 | dev_kfree_skb(descr->skb); | 363 | dev_kfree_skb(descr->skb); |
368 | pci_unmap_single(card->pdev, descr->buf_addr, | 364 | pci_unmap_single(card->pdev, descr->buf_addr, |
369 | SPIDER_NET_MAX_FRAME, | 365 | SPIDER_NET_MAX_FRAME, |
370 | PCI_DMA_FROMDEVICE); | 366 | PCI_DMA_BIDIRECTIONAL); |
371 | } | 367 | } |
372 | descr = descr->next; | 368 | descr = descr->next; |
373 | } | 369 | } while (descr != card->rx_chain.head); |
374 | } | 370 | } |
375 | 371 | ||
376 | /** | 372 | /** |
@@ -645,26 +641,41 @@ static int | |||
645 | spider_net_prepare_tx_descr(struct spider_net_card *card, | 641 | spider_net_prepare_tx_descr(struct spider_net_card *card, |
646 | struct sk_buff *skb) | 642 | struct sk_buff *skb) |
647 | { | 643 | { |
648 | struct spider_net_descr *descr = card->tx_chain.head; | 644 | struct spider_net_descr *descr; |
649 | dma_addr_t buf; | 645 | dma_addr_t buf; |
646 | unsigned long flags; | ||
647 | int length; | ||
650 | 648 | ||
651 | buf = pci_map_single(card->pdev, skb->data, skb->len, PCI_DMA_TODEVICE); | 649 | length = skb->len; |
650 | if (length < ETH_ZLEN) { | ||
651 | if (skb_pad(skb, ETH_ZLEN-length)) | ||
652 | return 0; | ||
653 | length = ETH_ZLEN; | ||
654 | } | ||
655 | |||
656 | buf = pci_map_single(card->pdev, skb->data, length, PCI_DMA_TODEVICE); | ||
652 | if (pci_dma_mapping_error(buf)) { | 657 | if (pci_dma_mapping_error(buf)) { |
653 | if (netif_msg_tx_err(card) && net_ratelimit()) | 658 | if (netif_msg_tx_err(card) && net_ratelimit()) |
654 | pr_err("could not iommu-map packet (%p, %i). " | 659 | pr_err("could not iommu-map packet (%p, %i). " |
655 | "Dropping packet\n", skb->data, skb->len); | 660 | "Dropping packet\n", skb->data, length); |
656 | card->spider_stats.tx_iommu_map_error++; | 661 | card->spider_stats.tx_iommu_map_error++; |
657 | return -ENOMEM; | 662 | return -ENOMEM; |
658 | } | 663 | } |
659 | 664 | ||
665 | spin_lock_irqsave(&card->tx_chain.lock, flags); | ||
666 | descr = card->tx_chain.head; | ||
667 | card->tx_chain.head = descr->next; | ||
668 | |||
660 | descr->buf_addr = buf; | 669 | descr->buf_addr = buf; |
661 | descr->buf_size = skb->len; | 670 | descr->buf_size = length; |
662 | descr->next_descr_addr = 0; | 671 | descr->next_descr_addr = 0; |
663 | descr->skb = skb; | 672 | descr->skb = skb; |
664 | descr->data_status = 0; | 673 | descr->data_status = 0; |
665 | 674 | ||
666 | descr->dmac_cmd_status = | 675 | descr->dmac_cmd_status = |
667 | SPIDER_NET_DESCR_CARDOWNED | SPIDER_NET_DMAC_NOCS; | 676 | SPIDER_NET_DESCR_CARDOWNED | SPIDER_NET_DMAC_NOCS; |
677 | spin_unlock_irqrestore(&card->tx_chain.lock, flags); | ||
678 | |||
668 | if (skb->protocol == htons(ETH_P_IP)) | 679 | if (skb->protocol == htons(ETH_P_IP)) |
669 | switch (skb->nh.iph->protocol) { | 680 | switch (skb->nh.iph->protocol) { |
670 | case IPPROTO_TCP: | 681 | case IPPROTO_TCP: |
@@ -675,32 +686,51 @@ spider_net_prepare_tx_descr(struct spider_net_card *card, | |||
675 | break; | 686 | break; |
676 | } | 687 | } |
677 | 688 | ||
689 | /* Chain the bus address, so that the DMA engine finds this descr. */ | ||
678 | descr->prev->next_descr_addr = descr->bus_addr; | 690 | descr->prev->next_descr_addr = descr->bus_addr; |
679 | 691 | ||
692 | card->netdev->trans_start = jiffies; /* set netdev watchdog timer */ | ||
680 | return 0; | 693 | return 0; |
681 | } | 694 | } |
682 | 695 | ||
683 | /** | 696 | static int |
684 | * spider_net_release_tx_descr - processes a used tx descriptor | 697 | spider_net_set_low_watermark(struct spider_net_card *card) |
685 | * @card: card structure | ||
686 | * @descr: descriptor to release | ||
687 | * | ||
688 | * releases a used tx descriptor (unmapping, freeing of skb) | ||
689 | */ | ||
690 | static inline void | ||
691 | spider_net_release_tx_descr(struct spider_net_card *card) | ||
692 | { | 698 | { |
699 | unsigned long flags; | ||
700 | int status; | ||
701 | int cnt=0; | ||
702 | int i; | ||
693 | struct spider_net_descr *descr = card->tx_chain.tail; | 703 | struct spider_net_descr *descr = card->tx_chain.tail; |
694 | struct sk_buff *skb; | ||
695 | 704 | ||
696 | card->tx_chain.tail = card->tx_chain.tail->next; | 705 | /* Measure the length of the queue. Measurement does not |
697 | descr->dmac_cmd_status |= SPIDER_NET_DESCR_NOT_IN_USE; | 706 | * need to be precise -- does not need a lock. */ |
707 | while (descr != card->tx_chain.head) { | ||
708 | status = descr->dmac_cmd_status & SPIDER_NET_DESCR_NOT_IN_USE; | ||
709 | if (status == SPIDER_NET_DESCR_NOT_IN_USE) | ||
710 | break; | ||
711 | descr = descr->next; | ||
712 | cnt++; | ||
713 | } | ||
698 | 714 | ||
699 | /* unmap the skb */ | 715 | /* If TX queue is short, don't even bother with interrupts */ |
700 | skb = descr->skb; | 716 | if (cnt < card->num_tx_desc/4) |
701 | pci_unmap_single(card->pdev, descr->buf_addr, skb->len, | 717 | return cnt; |
702 | PCI_DMA_TODEVICE); | 718 | |
703 | dev_kfree_skb_any(skb); | 719 | /* Set low-watermark 3/4th's of the way into the queue. */ |
720 | descr = card->tx_chain.tail; | ||
721 | cnt = (cnt*3)/4; | ||
722 | for (i=0;i<cnt; i++) | ||
723 | descr = descr->next; | ||
724 | |||
725 | /* Set the new watermark, clear the old watermark */ | ||
726 | spin_lock_irqsave(&card->tx_chain.lock, flags); | ||
727 | descr->dmac_cmd_status |= SPIDER_NET_DESCR_TXDESFLG; | ||
728 | if (card->low_watermark && card->low_watermark != descr) | ||
729 | card->low_watermark->dmac_cmd_status = | ||
730 | card->low_watermark->dmac_cmd_status & ~SPIDER_NET_DESCR_TXDESFLG; | ||
731 | card->low_watermark = descr; | ||
732 | spin_unlock_irqrestore(&card->tx_chain.lock, flags); | ||
733 | return cnt; | ||
704 | } | 734 | } |
705 | 735 | ||
706 | /** | 736 | /** |
@@ -719,21 +749,29 @@ static int | |||
719 | spider_net_release_tx_chain(struct spider_net_card *card, int brutal) | 749 | spider_net_release_tx_chain(struct spider_net_card *card, int brutal) |
720 | { | 750 | { |
721 | struct spider_net_descr_chain *chain = &card->tx_chain; | 751 | struct spider_net_descr_chain *chain = &card->tx_chain; |
752 | struct spider_net_descr *descr; | ||
753 | struct sk_buff *skb; | ||
754 | u32 buf_addr; | ||
755 | unsigned long flags; | ||
722 | int status; | 756 | int status; |
723 | 757 | ||
724 | spider_net_read_reg(card, SPIDER_NET_GDTDMACCNTR); | ||
725 | |||
726 | while (chain->tail != chain->head) { | 758 | while (chain->tail != chain->head) { |
727 | status = spider_net_get_descr_status(chain->tail); | 759 | spin_lock_irqsave(&chain->lock, flags); |
760 | descr = chain->tail; | ||
761 | |||
762 | status = spider_net_get_descr_status(descr); | ||
728 | switch (status) { | 763 | switch (status) { |
729 | case SPIDER_NET_DESCR_COMPLETE: | 764 | case SPIDER_NET_DESCR_COMPLETE: |
730 | card->netdev_stats.tx_packets++; | 765 | card->netdev_stats.tx_packets++; |
731 | card->netdev_stats.tx_bytes += chain->tail->skb->len; | 766 | card->netdev_stats.tx_bytes += descr->skb->len; |
732 | break; | 767 | break; |
733 | 768 | ||
734 | case SPIDER_NET_DESCR_CARDOWNED: | 769 | case SPIDER_NET_DESCR_CARDOWNED: |
735 | if (!brutal) | 770 | if (!brutal) { |
771 | spin_unlock_irqrestore(&chain->lock, flags); | ||
736 | return 1; | 772 | return 1; |
773 | } | ||
774 | |||
737 | /* fallthrough, if we release the descriptors | 775 | /* fallthrough, if we release the descriptors |
738 | * brutally (then we don't care about | 776 | * brutally (then we don't care about |
739 | * SPIDER_NET_DESCR_CARDOWNED) */ | 777 | * SPIDER_NET_DESCR_CARDOWNED) */ |
@@ -750,11 +788,25 @@ spider_net_release_tx_chain(struct spider_net_card *card, int brutal) | |||
750 | 788 | ||
751 | default: | 789 | default: |
752 | card->netdev_stats.tx_dropped++; | 790 | card->netdev_stats.tx_dropped++; |
753 | return 1; | 791 | if (!brutal) { |
792 | spin_unlock_irqrestore(&chain->lock, flags); | ||
793 | return 1; | ||
794 | } | ||
754 | } | 795 | } |
755 | spider_net_release_tx_descr(card); | ||
756 | } | ||
757 | 796 | ||
797 | chain->tail = descr->next; | ||
798 | descr->dmac_cmd_status |= SPIDER_NET_DESCR_NOT_IN_USE; | ||
799 | skb = descr->skb; | ||
800 | buf_addr = descr->buf_addr; | ||
801 | spin_unlock_irqrestore(&chain->lock, flags); | ||
802 | |||
803 | /* unmap the skb */ | ||
804 | if (skb) { | ||
805 | int len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len; | ||
806 | pci_unmap_single(card->pdev, buf_addr, len, PCI_DMA_TODEVICE); | ||
807 | dev_kfree_skb(skb); | ||
808 | } | ||
809 | } | ||
758 | return 0; | 810 | return 0; |
759 | } | 811 | } |
760 | 812 | ||
@@ -763,8 +815,12 @@ spider_net_release_tx_chain(struct spider_net_card *card, int brutal) | |||
763 | * @card: card structure | 815 | * @card: card structure |
764 | * @descr: descriptor address to enable TX processing at | 816 | * @descr: descriptor address to enable TX processing at |
765 | * | 817 | * |
766 | * spider_net_kick_tx_dma writes the current tx chain head as start address | 818 | * This routine will start the transmit DMA running if |
767 | * of the tx descriptor chain and enables the transmission DMA engine | 819 | * it is not already running. This routine ned only be |
820 | * called when queueing a new packet to an empty tx queue. | ||
821 | * Writes the current tx chain head as start address | ||
822 | * of the tx descriptor chain and enables the transmission | ||
823 | * DMA engine. | ||
768 | */ | 824 | */ |
769 | static inline void | 825 | static inline void |
770 | spider_net_kick_tx_dma(struct spider_net_card *card) | 826 | spider_net_kick_tx_dma(struct spider_net_card *card) |
@@ -804,65 +860,43 @@ out: | |||
804 | static int | 860 | static int |
805 | spider_net_xmit(struct sk_buff *skb, struct net_device *netdev) | 861 | spider_net_xmit(struct sk_buff *skb, struct net_device *netdev) |
806 | { | 862 | { |
863 | int cnt; | ||
807 | struct spider_net_card *card = netdev_priv(netdev); | 864 | struct spider_net_card *card = netdev_priv(netdev); |
808 | struct spider_net_descr_chain *chain = &card->tx_chain; | 865 | struct spider_net_descr_chain *chain = &card->tx_chain; |
809 | struct spider_net_descr *descr = chain->head; | ||
810 | unsigned long flags; | ||
811 | int result; | ||
812 | |||
813 | spin_lock_irqsave(&chain->lock, flags); | ||
814 | 866 | ||
815 | spider_net_release_tx_chain(card, 0); | 867 | spider_net_release_tx_chain(card, 0); |
816 | 868 | ||
817 | if (chain->head->next == chain->tail->prev) { | 869 | if ((chain->head->next == chain->tail->prev) || |
818 | card->netdev_stats.tx_dropped++; | 870 | (spider_net_prepare_tx_descr(card, skb) != 0)) { |
819 | result = NETDEV_TX_LOCKED; | ||
820 | goto out; | ||
821 | } | ||
822 | 871 | ||
823 | if (spider_net_get_descr_status(descr) != SPIDER_NET_DESCR_NOT_IN_USE) { | ||
824 | card->netdev_stats.tx_dropped++; | 872 | card->netdev_stats.tx_dropped++; |
825 | result = NETDEV_TX_LOCKED; | 873 | netif_stop_queue(netdev); |
826 | goto out; | 874 | return NETDEV_TX_BUSY; |
827 | } | 875 | } |
828 | 876 | ||
829 | if (spider_net_prepare_tx_descr(card, skb) != 0) { | 877 | cnt = spider_net_set_low_watermark(card); |
830 | card->netdev_stats.tx_dropped++; | 878 | if (cnt < 5) |
831 | result = NETDEV_TX_BUSY; | 879 | spider_net_kick_tx_dma(card); |
832 | goto out; | 880 | return NETDEV_TX_OK; |
833 | } | ||
834 | |||
835 | result = NETDEV_TX_OK; | ||
836 | |||
837 | spider_net_kick_tx_dma(card); | ||
838 | card->tx_chain.head = card->tx_chain.head->next; | ||
839 | |||
840 | out: | ||
841 | spin_unlock_irqrestore(&chain->lock, flags); | ||
842 | netif_wake_queue(netdev); | ||
843 | return result; | ||
844 | } | 881 | } |
845 | 882 | ||
846 | /** | 883 | /** |
847 | * spider_net_cleanup_tx_ring - cleans up the TX ring | 884 | * spider_net_cleanup_tx_ring - cleans up the TX ring |
848 | * @card: card structure | 885 | * @card: card structure |
849 | * | 886 | * |
850 | * spider_net_cleanup_tx_ring is called by the tx_timer (as we don't use | 887 | * spider_net_cleanup_tx_ring is called by either the tx_timer |
851 | * interrupts to cleanup our TX ring) and returns sent packets to the stack | 888 | * or from the NAPI polling routine. |
852 | * by freeing them | 889 | * This routine releases resources associted with transmitted |
890 | * packets, including updating the queue tail pointer. | ||
853 | */ | 891 | */ |
854 | static void | 892 | static void |
855 | spider_net_cleanup_tx_ring(struct spider_net_card *card) | 893 | spider_net_cleanup_tx_ring(struct spider_net_card *card) |
856 | { | 894 | { |
857 | unsigned long flags; | ||
858 | |||
859 | spin_lock_irqsave(&card->tx_chain.lock, flags); | ||
860 | |||
861 | if ((spider_net_release_tx_chain(card, 0) != 0) && | 895 | if ((spider_net_release_tx_chain(card, 0) != 0) && |
862 | (card->netdev->flags & IFF_UP)) | 896 | (card->netdev->flags & IFF_UP)) { |
863 | spider_net_kick_tx_dma(card); | 897 | spider_net_kick_tx_dma(card); |
864 | 898 | netif_wake_queue(card->netdev); | |
865 | spin_unlock_irqrestore(&card->tx_chain.lock, flags); | 899 | } |
866 | } | 900 | } |
867 | 901 | ||
868 | /** | 902 | /** |
@@ -1053,6 +1087,7 @@ spider_net_poll(struct net_device *netdev, int *budget) | |||
1053 | int packets_to_do, packets_done = 0; | 1087 | int packets_to_do, packets_done = 0; |
1054 | int no_more_packets = 0; | 1088 | int no_more_packets = 0; |
1055 | 1089 | ||
1090 | spider_net_cleanup_tx_ring(card); | ||
1056 | packets_to_do = min(*budget, netdev->quota); | 1091 | packets_to_do = min(*budget, netdev->quota); |
1057 | 1092 | ||
1058 | while (packets_to_do) { | 1093 | while (packets_to_do) { |
@@ -1243,12 +1278,15 @@ spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg) | |||
1243 | case SPIDER_NET_PHYINT: | 1278 | case SPIDER_NET_PHYINT: |
1244 | case SPIDER_NET_GMAC2INT: | 1279 | case SPIDER_NET_GMAC2INT: |
1245 | case SPIDER_NET_GMAC1INT: | 1280 | case SPIDER_NET_GMAC1INT: |
1246 | case SPIDER_NET_GIPSINT: | ||
1247 | case SPIDER_NET_GFIFOINT: | 1281 | case SPIDER_NET_GFIFOINT: |
1248 | case SPIDER_NET_DMACINT: | 1282 | case SPIDER_NET_DMACINT: |
1249 | case SPIDER_NET_GSYSINT: | 1283 | case SPIDER_NET_GSYSINT: |
1250 | break; */ | 1284 | break; */ |
1251 | 1285 | ||
1286 | case SPIDER_NET_GIPSINT: | ||
1287 | show_error = 0; | ||
1288 | break; | ||
1289 | |||
1252 | case SPIDER_NET_GPWOPCMPINT: | 1290 | case SPIDER_NET_GPWOPCMPINT: |
1253 | /* PHY write operation completed */ | 1291 | /* PHY write operation completed */ |
1254 | show_error = 0; | 1292 | show_error = 0; |
@@ -1307,9 +1345,10 @@ spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg) | |||
1307 | case SPIDER_NET_GDTDCEINT: | 1345 | case SPIDER_NET_GDTDCEINT: |
1308 | /* chain end. If a descriptor should be sent, kick off | 1346 | /* chain end. If a descriptor should be sent, kick off |
1309 | * tx dma | 1347 | * tx dma |
1310 | if (card->tx_chain.tail == card->tx_chain.head) | 1348 | if (card->tx_chain.tail != card->tx_chain.head) |
1311 | spider_net_kick_tx_dma(card); | 1349 | spider_net_kick_tx_dma(card); |
1312 | show_error = 0; */ | 1350 | */ |
1351 | show_error = 0; | ||
1313 | break; | 1352 | break; |
1314 | 1353 | ||
1315 | /* case SPIDER_NET_G1TMCNTINT: not used. print a message */ | 1354 | /* case SPIDER_NET_G1TMCNTINT: not used. print a message */ |
@@ -1354,7 +1393,7 @@ spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg) | |||
1354 | if (netif_msg_intr(card)) | 1393 | if (netif_msg_intr(card)) |
1355 | pr_err("got descriptor chain end interrupt, " | 1394 | pr_err("got descriptor chain end interrupt, " |
1356 | "restarting DMAC %c.\n", | 1395 | "restarting DMAC %c.\n", |
1357 | 'D'+i-SPIDER_NET_GDDDCEINT); | 1396 | 'D'-(i-SPIDER_NET_GDDDCEINT)/3); |
1358 | spider_net_refill_rx_chain(card); | 1397 | spider_net_refill_rx_chain(card); |
1359 | spider_net_enable_rxdmac(card); | 1398 | spider_net_enable_rxdmac(card); |
1360 | show_error = 0; | 1399 | show_error = 0; |
@@ -1423,8 +1462,9 @@ spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg) | |||
1423 | } | 1462 | } |
1424 | 1463 | ||
1425 | if ((show_error) && (netif_msg_intr(card))) | 1464 | if ((show_error) && (netif_msg_intr(card))) |
1426 | pr_err("Got error interrupt, GHIINT0STS = 0x%08x, " | 1465 | pr_err("Got error interrupt on %s, GHIINT0STS = 0x%08x, " |
1427 | "GHIINT1STS = 0x%08x, GHIINT2STS = 0x%08x\n", | 1466 | "GHIINT1STS = 0x%08x, GHIINT2STS = 0x%08x\n", |
1467 | card->netdev->name, | ||
1428 | status_reg, error_reg1, error_reg2); | 1468 | status_reg, error_reg1, error_reg2); |
1429 | 1469 | ||
1430 | /* clear interrupt sources */ | 1470 | /* clear interrupt sources */ |
@@ -1460,6 +1500,8 @@ spider_net_interrupt(int irq, void *ptr) | |||
1460 | spider_net_rx_irq_off(card); | 1500 | spider_net_rx_irq_off(card); |
1461 | netif_rx_schedule(netdev); | 1501 | netif_rx_schedule(netdev); |
1462 | } | 1502 | } |
1503 | if (status_reg & SPIDER_NET_TXINT) | ||
1504 | netif_rx_schedule(netdev); | ||
1463 | 1505 | ||
1464 | if (status_reg & SPIDER_NET_ERRINT ) | 1506 | if (status_reg & SPIDER_NET_ERRINT ) |
1465 | spider_net_handle_error_irq(card, status_reg); | 1507 | spider_net_handle_error_irq(card, status_reg); |
@@ -1599,7 +1641,7 @@ spider_net_enable_card(struct spider_net_card *card) | |||
1599 | SPIDER_NET_INT2_MASK_VALUE); | 1641 | SPIDER_NET_INT2_MASK_VALUE); |
1600 | 1642 | ||
1601 | spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR, | 1643 | spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR, |
1602 | SPIDER_NET_GDTDCEIDIS); | 1644 | SPIDER_NET_GDTBSTA | SPIDER_NET_GDTDCEIDIS); |
1603 | } | 1645 | } |
1604 | 1646 | ||
1605 | /** | 1647 | /** |
@@ -1615,17 +1657,26 @@ int | |||
1615 | spider_net_open(struct net_device *netdev) | 1657 | spider_net_open(struct net_device *netdev) |
1616 | { | 1658 | { |
1617 | struct spider_net_card *card = netdev_priv(netdev); | 1659 | struct spider_net_card *card = netdev_priv(netdev); |
1618 | int result; | 1660 | struct spider_net_descr *descr; |
1661 | int i, result; | ||
1619 | 1662 | ||
1620 | result = -ENOMEM; | 1663 | result = -ENOMEM; |
1621 | if (spider_net_init_chain(card, &card->tx_chain, card->descr, | 1664 | if (spider_net_init_chain(card, &card->tx_chain, card->descr, |
1622 | PCI_DMA_TODEVICE, card->tx_desc)) | 1665 | card->num_tx_desc)) |
1623 | goto alloc_tx_failed; | 1666 | goto alloc_tx_failed; |
1667 | |||
1668 | card->low_watermark = NULL; | ||
1669 | |||
1670 | /* rx_chain is after tx_chain, so offset is descr + tx_count */ | ||
1624 | if (spider_net_init_chain(card, &card->rx_chain, | 1671 | if (spider_net_init_chain(card, &card->rx_chain, |
1625 | card->descr + card->rx_desc, | 1672 | card->descr + card->num_tx_desc, |
1626 | PCI_DMA_FROMDEVICE, card->rx_desc)) | 1673 | card->num_rx_desc)) |
1627 | goto alloc_rx_failed; | 1674 | goto alloc_rx_failed; |
1628 | 1675 | ||
1676 | descr = card->rx_chain.head; | ||
1677 | for (i=0; i < card->num_rx_desc; i++, descr++) | ||
1678 | descr->next_descr_addr = descr->next->bus_addr; | ||
1679 | |||
1629 | /* allocate rx skbs */ | 1680 | /* allocate rx skbs */ |
1630 | if (spider_net_alloc_rx_skbs(card)) | 1681 | if (spider_net_alloc_rx_skbs(card)) |
1631 | goto alloc_skbs_failed; | 1682 | goto alloc_skbs_failed; |
@@ -1878,10 +1929,7 @@ spider_net_stop(struct net_device *netdev) | |||
1878 | spider_net_disable_rxdmac(card); | 1929 | spider_net_disable_rxdmac(card); |
1879 | 1930 | ||
1880 | /* release chains */ | 1931 | /* release chains */ |
1881 | if (spin_trylock(&card->tx_chain.lock)) { | 1932 | spider_net_release_tx_chain(card, 1); |
1882 | spider_net_release_tx_chain(card, 1); | ||
1883 | spin_unlock(&card->tx_chain.lock); | ||
1884 | } | ||
1885 | 1933 | ||
1886 | spider_net_free_chain(card, &card->tx_chain); | 1934 | spider_net_free_chain(card, &card->tx_chain); |
1887 | spider_net_free_chain(card, &card->rx_chain); | 1935 | spider_net_free_chain(card, &card->rx_chain); |
@@ -2012,8 +2060,8 @@ spider_net_setup_netdev(struct spider_net_card *card) | |||
2012 | 2060 | ||
2013 | card->options.rx_csum = SPIDER_NET_RX_CSUM_DEFAULT; | 2061 | card->options.rx_csum = SPIDER_NET_RX_CSUM_DEFAULT; |
2014 | 2062 | ||
2015 | card->tx_desc = tx_descriptors; | 2063 | card->num_tx_desc = tx_descriptors; |
2016 | card->rx_desc = rx_descriptors; | 2064 | card->num_rx_desc = rx_descriptors; |
2017 | 2065 | ||
2018 | spider_net_setup_netdev_ops(netdev); | 2066 | spider_net_setup_netdev_ops(netdev); |
2019 | 2067 | ||
@@ -2252,6 +2300,8 @@ static struct pci_driver spider_net_driver = { | |||
2252 | */ | 2300 | */ |
2253 | static int __init spider_net_init(void) | 2301 | static int __init spider_net_init(void) |
2254 | { | 2302 | { |
2303 | printk(KERN_INFO "Spidernet version %s.\n", VERSION); | ||
2304 | |||
2255 | if (rx_descriptors < SPIDER_NET_RX_DESCRIPTORS_MIN) { | 2305 | if (rx_descriptors < SPIDER_NET_RX_DESCRIPTORS_MIN) { |
2256 | rx_descriptors = SPIDER_NET_RX_DESCRIPTORS_MIN; | 2306 | rx_descriptors = SPIDER_NET_RX_DESCRIPTORS_MIN; |
2257 | pr_info("adjusting rx descriptors to %i.\n", rx_descriptors); | 2307 | pr_info("adjusting rx descriptors to %i.\n", rx_descriptors); |
diff --git a/drivers/net/spider_net.h b/drivers/net/spider_net.h index a59deda2f95e..b3b46119b424 100644 --- a/drivers/net/spider_net.h +++ b/drivers/net/spider_net.h | |||
@@ -24,6 +24,8 @@ | |||
24 | #ifndef _SPIDER_NET_H | 24 | #ifndef _SPIDER_NET_H |
25 | #define _SPIDER_NET_H | 25 | #define _SPIDER_NET_H |
26 | 26 | ||
27 | #define VERSION "1.1 A" | ||
28 | |||
27 | #include "sungem_phy.h" | 29 | #include "sungem_phy.h" |
28 | 30 | ||
29 | extern int spider_net_stop(struct net_device *netdev); | 31 | extern int spider_net_stop(struct net_device *netdev); |
@@ -47,7 +49,7 @@ extern char spider_net_driver_name[]; | |||
47 | #define SPIDER_NET_TX_DESCRIPTORS_MIN 16 | 49 | #define SPIDER_NET_TX_DESCRIPTORS_MIN 16 |
48 | #define SPIDER_NET_TX_DESCRIPTORS_MAX 512 | 50 | #define SPIDER_NET_TX_DESCRIPTORS_MAX 512 |
49 | 51 | ||
50 | #define SPIDER_NET_TX_TIMER 20 | 52 | #define SPIDER_NET_TX_TIMER (HZ/5) |
51 | 53 | ||
52 | #define SPIDER_NET_RX_CSUM_DEFAULT 1 | 54 | #define SPIDER_NET_RX_CSUM_DEFAULT 1 |
53 | 55 | ||
@@ -189,7 +191,9 @@ extern char spider_net_driver_name[]; | |||
189 | #define SPIDER_NET_MACMODE_VALUE 0x00000001 | 191 | #define SPIDER_NET_MACMODE_VALUE 0x00000001 |
190 | #define SPIDER_NET_BURSTLMT_VALUE 0x00000200 /* about 16 us */ | 192 | #define SPIDER_NET_BURSTLMT_VALUE 0x00000200 /* about 16 us */ |
191 | 193 | ||
192 | /* 1(0) enable r/tx dma | 194 | /* DMAC control register GDMACCNTR |
195 | * | ||
196 | * 1(0) enable r/tx dma | ||
193 | * 0000000 fixed to 0 | 197 | * 0000000 fixed to 0 |
194 | * | 198 | * |
195 | * 000000 fixed to 0 | 199 | * 000000 fixed to 0 |
@@ -198,6 +202,7 @@ extern char spider_net_driver_name[]; | |||
198 | * | 202 | * |
199 | * 000000 fixed to 0 | 203 | * 000000 fixed to 0 |
200 | * 00 burst alignment: 128 bytes | 204 | * 00 burst alignment: 128 bytes |
205 | * 11 burst alignment: 1024 bytes | ||
201 | * | 206 | * |
202 | * 00000 fixed to 0 | 207 | * 00000 fixed to 0 |
203 | * 0 descr writeback size 32 bytes | 208 | * 0 descr writeback size 32 bytes |
@@ -208,10 +213,13 @@ extern char spider_net_driver_name[]; | |||
208 | #define SPIDER_NET_DMA_RX_VALUE 0x80000000 | 213 | #define SPIDER_NET_DMA_RX_VALUE 0x80000000 |
209 | #define SPIDER_NET_DMA_RX_FEND_VALUE 0x00030003 | 214 | #define SPIDER_NET_DMA_RX_FEND_VALUE 0x00030003 |
210 | /* to set TX_DMA_EN */ | 215 | /* to set TX_DMA_EN */ |
211 | #define SPIDER_NET_TX_DMA_EN 0x80000000 | 216 | #define SPIDER_NET_TX_DMA_EN 0x80000000 |
212 | #define SPIDER_NET_GDTDCEIDIS 0x00000002 | 217 | #define SPIDER_NET_GDTBSTA 0x00000300 |
213 | #define SPIDER_NET_DMA_TX_VALUE SPIDER_NET_TX_DMA_EN | \ | 218 | #define SPIDER_NET_GDTDCEIDIS 0x00000002 |
214 | SPIDER_NET_GDTDCEIDIS | 219 | #define SPIDER_NET_DMA_TX_VALUE SPIDER_NET_TX_DMA_EN | \ |
220 | SPIDER_NET_GDTBSTA | \ | ||
221 | SPIDER_NET_GDTDCEIDIS | ||
222 | |||
215 | #define SPIDER_NET_DMA_TX_FEND_VALUE 0x00030003 | 223 | #define SPIDER_NET_DMA_TX_FEND_VALUE 0x00030003 |
216 | 224 | ||
217 | /* SPIDER_NET_UA_DESCR_VALUE is OR'ed with the unicast address */ | 225 | /* SPIDER_NET_UA_DESCR_VALUE is OR'ed with the unicast address */ |
@@ -320,13 +328,10 @@ enum spider_net_int2_status { | |||
320 | SPIDER_NET_GRISPDNGINT | 328 | SPIDER_NET_GRISPDNGINT |
321 | }; | 329 | }; |
322 | 330 | ||
323 | #define SPIDER_NET_TXINT ( (1 << SPIDER_NET_GTTEDINT) | \ | 331 | #define SPIDER_NET_TXINT ( (1 << SPIDER_NET_GDTFDCINT) ) |
324 | (1 << SPIDER_NET_GDTDCEINT) | \ | ||
325 | (1 << SPIDER_NET_GDTFDCINT) ) | ||
326 | 332 | ||
327 | /* we rely on flagged descriptor interrupts*/ | 333 | /* We rely on flagged descriptor interrupts */ |
328 | #define SPIDER_NET_RXINT ( (1 << SPIDER_NET_GDAFDCINT) | \ | 334 | #define SPIDER_NET_RXINT ( (1 << SPIDER_NET_GDAFDCINT) ) |
329 | (1 << SPIDER_NET_GRMFLLINT) ) | ||
330 | 335 | ||
331 | #define SPIDER_NET_ERRINT ( 0xffffffff & \ | 336 | #define SPIDER_NET_ERRINT ( 0xffffffff & \ |
332 | (~SPIDER_NET_TXINT) & \ | 337 | (~SPIDER_NET_TXINT) & \ |
@@ -349,6 +354,7 @@ enum spider_net_int2_status { | |||
349 | #define SPIDER_NET_DESCR_FORCE_END 0x50000000 /* used in rx and tx */ | 354 | #define SPIDER_NET_DESCR_FORCE_END 0x50000000 /* used in rx and tx */ |
350 | #define SPIDER_NET_DESCR_CARDOWNED 0xA0000000 /* used in rx and tx */ | 355 | #define SPIDER_NET_DESCR_CARDOWNED 0xA0000000 /* used in rx and tx */ |
351 | #define SPIDER_NET_DESCR_NOT_IN_USE 0xF0000000 | 356 | #define SPIDER_NET_DESCR_NOT_IN_USE 0xF0000000 |
357 | #define SPIDER_NET_DESCR_TXDESFLG 0x00800000 | ||
352 | 358 | ||
353 | struct spider_net_descr { | 359 | struct spider_net_descr { |
354 | /* as defined by the hardware */ | 360 | /* as defined by the hardware */ |
@@ -433,6 +439,7 @@ struct spider_net_card { | |||
433 | 439 | ||
434 | struct spider_net_descr_chain tx_chain; | 440 | struct spider_net_descr_chain tx_chain; |
435 | struct spider_net_descr_chain rx_chain; | 441 | struct spider_net_descr_chain rx_chain; |
442 | struct spider_net_descr *low_watermark; | ||
436 | 443 | ||
437 | struct net_device_stats netdev_stats; | 444 | struct net_device_stats netdev_stats; |
438 | 445 | ||
@@ -448,8 +455,8 @@ struct spider_net_card { | |||
448 | 455 | ||
449 | /* for ethtool */ | 456 | /* for ethtool */ |
450 | int msg_enable; | 457 | int msg_enable; |
451 | int rx_desc; | 458 | int num_rx_desc; |
452 | int tx_desc; | 459 | int num_tx_desc; |
453 | struct spider_net_extra_stats spider_stats; | 460 | struct spider_net_extra_stats spider_stats; |
454 | 461 | ||
455 | struct spider_net_descr descr[0]; | 462 | struct spider_net_descr descr[0]; |
diff --git a/drivers/net/spider_net_ethtool.c b/drivers/net/spider_net_ethtool.c index 589e43658dee..91b995102915 100644 --- a/drivers/net/spider_net_ethtool.c +++ b/drivers/net/spider_net_ethtool.c | |||
@@ -76,7 +76,7 @@ spider_net_ethtool_get_drvinfo(struct net_device *netdev, | |||
76 | /* clear and fill out info */ | 76 | /* clear and fill out info */ |
77 | memset(drvinfo, 0, sizeof(struct ethtool_drvinfo)); | 77 | memset(drvinfo, 0, sizeof(struct ethtool_drvinfo)); |
78 | strncpy(drvinfo->driver, spider_net_driver_name, 32); | 78 | strncpy(drvinfo->driver, spider_net_driver_name, 32); |
79 | strncpy(drvinfo->version, "0.1", 32); | 79 | strncpy(drvinfo->version, VERSION, 32); |
80 | strcpy(drvinfo->fw_version, "no information"); | 80 | strcpy(drvinfo->fw_version, "no information"); |
81 | strncpy(drvinfo->bus_info, pci_name(card->pdev), 32); | 81 | strncpy(drvinfo->bus_info, pci_name(card->pdev), 32); |
82 | } | 82 | } |
@@ -158,9 +158,9 @@ spider_net_ethtool_get_ringparam(struct net_device *netdev, | |||
158 | struct spider_net_card *card = netdev->priv; | 158 | struct spider_net_card *card = netdev->priv; |
159 | 159 | ||
160 | ering->tx_max_pending = SPIDER_NET_TX_DESCRIPTORS_MAX; | 160 | ering->tx_max_pending = SPIDER_NET_TX_DESCRIPTORS_MAX; |
161 | ering->tx_pending = card->tx_desc; | 161 | ering->tx_pending = card->num_tx_desc; |
162 | ering->rx_max_pending = SPIDER_NET_RX_DESCRIPTORS_MAX; | 162 | ering->rx_max_pending = SPIDER_NET_RX_DESCRIPTORS_MAX; |
163 | ering->rx_pending = card->rx_desc; | 163 | ering->rx_pending = card->num_rx_desc; |
164 | } | 164 | } |
165 | 165 | ||
166 | static int spider_net_get_stats_count(struct net_device *netdev) | 166 | static int spider_net_get_stats_count(struct net_device *netdev) |
diff --git a/drivers/net/sun3_82586.c b/drivers/net/sun3_82586.c index d1d1885b0295..a3220a96524f 100644 --- a/drivers/net/sun3_82586.c +++ b/drivers/net/sun3_82586.c | |||
@@ -330,7 +330,7 @@ out2: | |||
330 | out1: | 330 | out1: |
331 | free_netdev(dev); | 331 | free_netdev(dev); |
332 | out: | 332 | out: |
333 | iounmap((void *)ioaddr); | 333 | iounmap((void __iomem *)ioaddr); |
334 | return ERR_PTR(err); | 334 | return ERR_PTR(err); |
335 | } | 335 | } |
336 | 336 | ||
diff --git a/drivers/net/sun3lance.c b/drivers/net/sun3lance.c index 91c76544e4dd..b865db363ba0 100644 --- a/drivers/net/sun3lance.c +++ b/drivers/net/sun3lance.c | |||
@@ -286,7 +286,7 @@ struct net_device * __init sun3lance_probe(int unit) | |||
286 | 286 | ||
287 | out1: | 287 | out1: |
288 | #ifdef CONFIG_SUN3 | 288 | #ifdef CONFIG_SUN3 |
289 | iounmap((void *)dev->base_addr); | 289 | iounmap((void __iomem *)dev->base_addr); |
290 | #endif | 290 | #endif |
291 | out: | 291 | out: |
292 | free_netdev(dev); | 292 | free_netdev(dev); |
@@ -326,7 +326,7 @@ static int __init lance_probe( struct net_device *dev) | |||
326 | ioaddr_probe[1] = tmp2; | 326 | ioaddr_probe[1] = tmp2; |
327 | 327 | ||
328 | #ifdef CONFIG_SUN3 | 328 | #ifdef CONFIG_SUN3 |
329 | iounmap((void *)ioaddr); | 329 | iounmap((void __iomem *)ioaddr); |
330 | #endif | 330 | #endif |
331 | return 0; | 331 | return 0; |
332 | } | 332 | } |
@@ -956,7 +956,7 @@ void cleanup_module(void) | |||
956 | { | 956 | { |
957 | unregister_netdev(sun3lance_dev); | 957 | unregister_netdev(sun3lance_dev); |
958 | #ifdef CONFIG_SUN3 | 958 | #ifdef CONFIG_SUN3 |
959 | iounmap((void *)sun3lance_dev->base_addr); | 959 | iounmap((void __iomem *)sun3lance_dev->base_addr); |
960 | #endif | 960 | #endif |
961 | free_netdev(sun3lance_dev); | 961 | free_netdev(sun3lance_dev); |
962 | } | 962 | } |
diff --git a/drivers/net/sunbmac.c b/drivers/net/sunbmac.c index 6439b0cef1e4..18f88853e1e5 100644 --- a/drivers/net/sunbmac.c +++ b/drivers/net/sunbmac.c | |||
@@ -42,7 +42,7 @@ | |||
42 | #define DRV_RELDATE "11/24/03" | 42 | #define DRV_RELDATE "11/24/03" |
43 | #define DRV_AUTHOR "David S. Miller (davem@redhat.com)" | 43 | #define DRV_AUTHOR "David S. Miller (davem@redhat.com)" |
44 | 44 | ||
45 | static char version[] __initdata = | 45 | static char version[] = |
46 | DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " " DRV_AUTHOR "\n"; | 46 | DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " " DRV_AUTHOR "\n"; |
47 | 47 | ||
48 | MODULE_VERSION(DRV_VERSION); | 48 | MODULE_VERSION(DRV_VERSION); |
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 327836b1014e..c20bb998e0e5 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -68,8 +68,8 @@ | |||
68 | 68 | ||
69 | #define DRV_MODULE_NAME "tg3" | 69 | #define DRV_MODULE_NAME "tg3" |
70 | #define PFX DRV_MODULE_NAME ": " | 70 | #define PFX DRV_MODULE_NAME ": " |
71 | #define DRV_MODULE_VERSION "3.66" | 71 | #define DRV_MODULE_VERSION "3.69" |
72 | #define DRV_MODULE_RELDATE "September 23, 2006" | 72 | #define DRV_MODULE_RELDATE "November 15, 2006" |
73 | 73 | ||
74 | #define TG3_DEF_MAC_MODE 0 | 74 | #define TG3_DEF_MAC_MODE 0 |
75 | #define TG3_DEF_RX_MODE 0 | 75 | #define TG3_DEF_RX_MODE 0 |
@@ -129,7 +129,7 @@ | |||
129 | #define RX_JUMBO_PKT_BUF_SZ (9046 + tp->rx_offset + 64) | 129 | #define RX_JUMBO_PKT_BUF_SZ (9046 + tp->rx_offset + 64) |
130 | 130 | ||
131 | /* minimum number of free TX descriptors required to wake up TX process */ | 131 | /* minimum number of free TX descriptors required to wake up TX process */ |
132 | #define TG3_TX_WAKEUP_THRESH (TG3_TX_RING_SIZE / 4) | 132 | #define TG3_TX_WAKEUP_THRESH(tp) ((tp)->tx_pending / 4) |
133 | 133 | ||
134 | /* number of ETHTOOL_GSTATS u64's */ | 134 | /* number of ETHTOOL_GSTATS u64's */ |
135 | #define TG3_NUM_STATS (sizeof(struct tg3_ethtool_stats)/sizeof(u64)) | 135 | #define TG3_NUM_STATS (sizeof(struct tg3_ethtool_stats)/sizeof(u64)) |
@@ -3075,10 +3075,10 @@ static void tg3_tx(struct tg3 *tp) | |||
3075 | smp_mb(); | 3075 | smp_mb(); |
3076 | 3076 | ||
3077 | if (unlikely(netif_queue_stopped(tp->dev) && | 3077 | if (unlikely(netif_queue_stopped(tp->dev) && |
3078 | (tg3_tx_avail(tp) > TG3_TX_WAKEUP_THRESH))) { | 3078 | (tg3_tx_avail(tp) > TG3_TX_WAKEUP_THRESH(tp)))) { |
3079 | netif_tx_lock(tp->dev); | 3079 | netif_tx_lock(tp->dev); |
3080 | if (netif_queue_stopped(tp->dev) && | 3080 | if (netif_queue_stopped(tp->dev) && |
3081 | (tg3_tx_avail(tp) > TG3_TX_WAKEUP_THRESH)) | 3081 | (tg3_tx_avail(tp) > TG3_TX_WAKEUP_THRESH(tp))) |
3082 | netif_wake_queue(tp->dev); | 3082 | netif_wake_queue(tp->dev); |
3083 | netif_tx_unlock(tp->dev); | 3083 | netif_tx_unlock(tp->dev); |
3084 | } | 3084 | } |
@@ -3928,7 +3928,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3928 | tp->tx_prod = entry; | 3928 | tp->tx_prod = entry; |
3929 | if (unlikely(tg3_tx_avail(tp) <= (MAX_SKB_FRAGS + 1))) { | 3929 | if (unlikely(tg3_tx_avail(tp) <= (MAX_SKB_FRAGS + 1))) { |
3930 | netif_stop_queue(dev); | 3930 | netif_stop_queue(dev); |
3931 | if (tg3_tx_avail(tp) > TG3_TX_WAKEUP_THRESH) | 3931 | if (tg3_tx_avail(tp) > TG3_TX_WAKEUP_THRESH(tp)) |
3932 | netif_wake_queue(tp->dev); | 3932 | netif_wake_queue(tp->dev); |
3933 | } | 3933 | } |
3934 | 3934 | ||
@@ -4143,7 +4143,7 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev) | |||
4143 | tp->tx_prod = entry; | 4143 | tp->tx_prod = entry; |
4144 | if (unlikely(tg3_tx_avail(tp) <= (MAX_SKB_FRAGS + 1))) { | 4144 | if (unlikely(tg3_tx_avail(tp) <= (MAX_SKB_FRAGS + 1))) { |
4145 | netif_stop_queue(dev); | 4145 | netif_stop_queue(dev); |
4146 | if (tg3_tx_avail(tp) > TG3_TX_WAKEUP_THRESH) | 4146 | if (tg3_tx_avail(tp) > TG3_TX_WAKEUP_THRESH(tp)) |
4147 | netif_wake_queue(tp->dev); | 4147 | netif_wake_queue(tp->dev); |
4148 | } | 4148 | } |
4149 | 4149 | ||
@@ -4728,10 +4728,11 @@ static int tg3_poll_fw(struct tg3 *tp) | |||
4728 | u32 val; | 4728 | u32 val; |
4729 | 4729 | ||
4730 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { | 4730 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { |
4731 | for (i = 0; i < 400; i++) { | 4731 | /* Wait up to 20ms for init done. */ |
4732 | for (i = 0; i < 200; i++) { | ||
4732 | if (tr32(VCPU_STATUS) & VCPU_STATUS_INIT_DONE) | 4733 | if (tr32(VCPU_STATUS) & VCPU_STATUS_INIT_DONE) |
4733 | return 0; | 4734 | return 0; |
4734 | udelay(10); | 4735 | udelay(100); |
4735 | } | 4736 | } |
4736 | return -ENODEV; | 4737 | return -ENODEV; |
4737 | } | 4738 | } |
@@ -6014,7 +6015,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) | |||
6014 | tg3_abort_hw(tp, 1); | 6015 | tg3_abort_hw(tp, 1); |
6015 | } | 6016 | } |
6016 | 6017 | ||
6017 | if ((tp->tg3_flags2 & TG3_FLG2_MII_SERDES) && reset_phy) | 6018 | if (reset_phy) |
6018 | tg3_phy_reset(tp); | 6019 | tg3_phy_reset(tp); |
6019 | 6020 | ||
6020 | err = tg3_chip_reset(tp); | 6021 | err = tg3_chip_reset(tp); |
@@ -6574,7 +6575,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) | |||
6574 | tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl); | 6575 | tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl); |
6575 | } | 6576 | } |
6576 | 6577 | ||
6577 | err = tg3_setup_phy(tp, reset_phy); | 6578 | err = tg3_setup_phy(tp, 0); |
6578 | if (err) | 6579 | if (err) |
6579 | return err; | 6580 | return err; |
6580 | 6581 | ||
@@ -6978,8 +6979,10 @@ static int tg3_open(struct net_device *dev) | |||
6978 | tg3_full_lock(tp, 0); | 6979 | tg3_full_lock(tp, 0); |
6979 | 6980 | ||
6980 | err = tg3_set_power_state(tp, PCI_D0); | 6981 | err = tg3_set_power_state(tp, PCI_D0); |
6981 | if (err) | 6982 | if (err) { |
6983 | tg3_full_unlock(tp); | ||
6982 | return err; | 6984 | return err; |
6985 | } | ||
6983 | 6986 | ||
6984 | tg3_disable_ints(tp); | 6987 | tg3_disable_ints(tp); |
6985 | tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE; | 6988 | tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE; |
@@ -8106,7 +8109,10 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e | |||
8106 | 8109 | ||
8107 | if ((ering->rx_pending > TG3_RX_RING_SIZE - 1) || | 8110 | if ((ering->rx_pending > TG3_RX_RING_SIZE - 1) || |
8108 | (ering->rx_jumbo_pending > TG3_RX_JUMBO_RING_SIZE - 1) || | 8111 | (ering->rx_jumbo_pending > TG3_RX_JUMBO_RING_SIZE - 1) || |
8109 | (ering->tx_pending > TG3_TX_RING_SIZE - 1)) | 8112 | (ering->tx_pending > TG3_TX_RING_SIZE - 1) || |
8113 | (ering->tx_pending <= MAX_SKB_FRAGS) || | ||
8114 | ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_1_BUG) && | ||
8115 | (ering->tx_pending <= (MAX_SKB_FRAGS * 3)))) | ||
8110 | return -EINVAL; | 8116 | return -EINVAL; |
8111 | 8117 | ||
8112 | if (netif_running(dev)) { | 8118 | if (netif_running(dev)) { |
@@ -10209,7 +10215,7 @@ skip_phy_reset: | |||
10209 | static void __devinit tg3_read_partno(struct tg3 *tp) | 10215 | static void __devinit tg3_read_partno(struct tg3 *tp) |
10210 | { | 10216 | { |
10211 | unsigned char vpd_data[256]; | 10217 | unsigned char vpd_data[256]; |
10212 | int i; | 10218 | unsigned int i; |
10213 | u32 magic; | 10219 | u32 magic; |
10214 | 10220 | ||
10215 | if (tg3_nvram_read_swab(tp, 0x0, &magic)) | 10221 | if (tg3_nvram_read_swab(tp, 0x0, &magic)) |
@@ -10255,9 +10261,9 @@ static void __devinit tg3_read_partno(struct tg3 *tp) | |||
10255 | } | 10261 | } |
10256 | 10262 | ||
10257 | /* Now parse and find the part number. */ | 10263 | /* Now parse and find the part number. */ |
10258 | for (i = 0; i < 256; ) { | 10264 | for (i = 0; i < 254; ) { |
10259 | unsigned char val = vpd_data[i]; | 10265 | unsigned char val = vpd_data[i]; |
10260 | int block_end; | 10266 | unsigned int block_end; |
10261 | 10267 | ||
10262 | if (val == 0x82 || val == 0x91) { | 10268 | if (val == 0x82 || val == 0x91) { |
10263 | i = (i + 3 + | 10269 | i = (i + 3 + |
@@ -10273,21 +10279,26 @@ static void __devinit tg3_read_partno(struct tg3 *tp) | |||
10273 | (vpd_data[i + 1] + | 10279 | (vpd_data[i + 1] + |
10274 | (vpd_data[i + 2] << 8))); | 10280 | (vpd_data[i + 2] << 8))); |
10275 | i += 3; | 10281 | i += 3; |
10276 | while (i < block_end) { | 10282 | |
10283 | if (block_end > 256) | ||
10284 | goto out_not_found; | ||
10285 | |||
10286 | while (i < (block_end - 2)) { | ||
10277 | if (vpd_data[i + 0] == 'P' && | 10287 | if (vpd_data[i + 0] == 'P' && |
10278 | vpd_data[i + 1] == 'N') { | 10288 | vpd_data[i + 1] == 'N') { |
10279 | int partno_len = vpd_data[i + 2]; | 10289 | int partno_len = vpd_data[i + 2]; |
10280 | 10290 | ||
10281 | if (partno_len > 24) | 10291 | i += 3; |
10292 | if (partno_len > 24 || (partno_len + i) > 256) | ||
10282 | goto out_not_found; | 10293 | goto out_not_found; |
10283 | 10294 | ||
10284 | memcpy(tp->board_part_number, | 10295 | memcpy(tp->board_part_number, |
10285 | &vpd_data[i + 3], | 10296 | &vpd_data[i], partno_len); |
10286 | partno_len); | ||
10287 | 10297 | ||
10288 | /* Success. */ | 10298 | /* Success. */ |
10289 | return; | 10299 | return; |
10290 | } | 10300 | } |
10301 | i += 3 + vpd_data[i + 2]; | ||
10291 | } | 10302 | } |
10292 | 10303 | ||
10293 | /* Part number not found. */ | 10304 | /* Part number not found. */ |
@@ -10357,7 +10368,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) | |||
10357 | u32 pci_state_reg, grc_misc_cfg; | 10368 | u32 pci_state_reg, grc_misc_cfg; |
10358 | u32 val; | 10369 | u32 val; |
10359 | u16 pci_cmd; | 10370 | u16 pci_cmd; |
10360 | int err; | 10371 | int err, pcie_cap; |
10361 | 10372 | ||
10362 | /* Force memory write invalidate off. If we leave it on, | 10373 | /* Force memory write invalidate off. If we leave it on, |
10363 | * then on 5700_BX chips we have to enable a workaround. | 10374 | * then on 5700_BX chips we have to enable a workaround. |
@@ -10532,8 +10543,19 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) | |||
10532 | GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906) | 10543 | GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906) |
10533 | tp->tg3_flags2 |= TG3_FLG2_JUMBO_CAPABLE; | 10544 | tp->tg3_flags2 |= TG3_FLG2_JUMBO_CAPABLE; |
10534 | 10545 | ||
10535 | if (pci_find_capability(tp->pdev, PCI_CAP_ID_EXP) != 0) | 10546 | pcie_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_EXP); |
10547 | if (pcie_cap != 0) { | ||
10536 | tp->tg3_flags2 |= TG3_FLG2_PCI_EXPRESS; | 10548 | tp->tg3_flags2 |= TG3_FLG2_PCI_EXPRESS; |
10549 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { | ||
10550 | u16 lnkctl; | ||
10551 | |||
10552 | pci_read_config_word(tp->pdev, | ||
10553 | pcie_cap + PCI_EXP_LNKCTL, | ||
10554 | &lnkctl); | ||
10555 | if (lnkctl & PCI_EXP_LNKCTL_CLKREQ_EN) | ||
10556 | tp->tg3_flags2 &= ~TG3_FLG2_HW_TSO_2; | ||
10557 | } | ||
10558 | } | ||
10537 | 10559 | ||
10538 | /* If we have an AMD 762 or VIA K8T800 chipset, write | 10560 | /* If we have an AMD 762 or VIA K8T800 chipset, write |
10539 | * reordering to the mailbox registers done by the host | 10561 | * reordering to the mailbox registers done by the host |
@@ -11800,6 +11822,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, | |||
11800 | else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || | 11822 | else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || |
11801 | GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 || | 11823 | GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 || |
11802 | tp->pci_chip_rev_id == CHIPREV_ID_5705_A0 || | 11824 | tp->pci_chip_rev_id == CHIPREV_ID_5705_A0 || |
11825 | GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906 || | ||
11803 | (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0) { | 11826 | (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0) { |
11804 | tp->tg3_flags2 &= ~TG3_FLG2_TSO_CAPABLE; | 11827 | tp->tg3_flags2 &= ~TG3_FLG2_TSO_CAPABLE; |
11805 | } else { | 11828 | } else { |
diff --git a/drivers/net/tokenring/proteon.c b/drivers/net/tokenring/proteon.c index 4f756960db2a..cb7dbb63c9d9 100644 --- a/drivers/net/tokenring/proteon.c +++ b/drivers/net/tokenring/proteon.c | |||
@@ -370,6 +370,10 @@ static int __init proteon_init(void) | |||
370 | dev->dma = dma[i]; | 370 | dev->dma = dma[i]; |
371 | pdev = platform_device_register_simple("proteon", | 371 | pdev = platform_device_register_simple("proteon", |
372 | i, NULL, 0); | 372 | i, NULL, 0); |
373 | if (IS_ERR(pdev)) { | ||
374 | free_netdev(dev); | ||
375 | continue; | ||
376 | } | ||
373 | err = setup_card(dev, &pdev->dev); | 377 | err = setup_card(dev, &pdev->dev); |
374 | if (!err) { | 378 | if (!err) { |
375 | proteon_dev[i] = pdev; | 379 | proteon_dev[i] = pdev; |
@@ -385,9 +389,10 @@ static int __init proteon_init(void) | |||
385 | /* Probe for cards. */ | 389 | /* Probe for cards. */ |
386 | if (num == 0) { | 390 | if (num == 0) { |
387 | printk(KERN_NOTICE "proteon.c: No cards found.\n"); | 391 | printk(KERN_NOTICE "proteon.c: No cards found.\n"); |
388 | return (-ENODEV); | 392 | platform_driver_unregister(&proteon_driver); |
393 | return -ENODEV; | ||
389 | } | 394 | } |
390 | return (0); | 395 | return 0; |
391 | } | 396 | } |
392 | 397 | ||
393 | static void __exit proteon_cleanup(void) | 398 | static void __exit proteon_cleanup(void) |
diff --git a/drivers/net/tokenring/skisa.c b/drivers/net/tokenring/skisa.c index d6ba41cf3110..33afea31d87b 100644 --- a/drivers/net/tokenring/skisa.c +++ b/drivers/net/tokenring/skisa.c | |||
@@ -380,6 +380,10 @@ static int __init sk_isa_init(void) | |||
380 | dev->dma = dma[i]; | 380 | dev->dma = dma[i]; |
381 | pdev = platform_device_register_simple("skisa", | 381 | pdev = platform_device_register_simple("skisa", |
382 | i, NULL, 0); | 382 | i, NULL, 0); |
383 | if (IS_ERR(pdev)) { | ||
384 | free_netdev(dev); | ||
385 | continue; | ||
386 | } | ||
383 | err = setup_card(dev, &pdev->dev); | 387 | err = setup_card(dev, &pdev->dev); |
384 | if (!err) { | 388 | if (!err) { |
385 | sk_isa_dev[i] = pdev; | 389 | sk_isa_dev[i] = pdev; |
@@ -395,9 +399,10 @@ static int __init sk_isa_init(void) | |||
395 | /* Probe for cards. */ | 399 | /* Probe for cards. */ |
396 | if (num == 0) { | 400 | if (num == 0) { |
397 | printk(KERN_NOTICE "skisa.c: No cards found.\n"); | 401 | printk(KERN_NOTICE "skisa.c: No cards found.\n"); |
398 | return (-ENODEV); | 402 | platform_driver_unregister(&sk_isa_driver); |
403 | return -ENODEV; | ||
399 | } | 404 | } |
400 | return (0); | 405 | return 0; |
401 | } | 406 | } |
402 | 407 | ||
403 | static void __exit sk_isa_cleanup(void) | 408 | static void __exit sk_isa_cleanup(void) |
diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c index 2cfd9634895a..f6b3a94e97bf 100644 --- a/drivers/net/tulip/de2104x.c +++ b/drivers/net/tulip/de2104x.c | |||
@@ -1730,7 +1730,7 @@ static void __init de21040_get_media_info(struct de_private *de) | |||
1730 | } | 1730 | } |
1731 | 1731 | ||
1732 | /* Note: this routine returns extra data bits for size detection. */ | 1732 | /* Note: this routine returns extra data bits for size detection. */ |
1733 | static unsigned __init tulip_read_eeprom(void __iomem *regs, int location, int addr_len) | 1733 | static unsigned __devinit tulip_read_eeprom(void __iomem *regs, int location, int addr_len) |
1734 | { | 1734 | { |
1735 | int i; | 1735 | int i; |
1736 | unsigned retval = 0; | 1736 | unsigned retval = 0; |
@@ -1926,7 +1926,7 @@ bad_srom: | |||
1926 | goto fill_defaults; | 1926 | goto fill_defaults; |
1927 | } | 1927 | } |
1928 | 1928 | ||
1929 | static int __init de_init_one (struct pci_dev *pdev, | 1929 | static int __devinit de_init_one (struct pci_dev *pdev, |
1930 | const struct pci_device_id *ent) | 1930 | const struct pci_device_id *ent) |
1931 | { | 1931 | { |
1932 | struct net_device *dev; | 1932 | struct net_device *dev; |
@@ -2082,7 +2082,7 @@ err_out_free: | |||
2082 | return rc; | 2082 | return rc; |
2083 | } | 2083 | } |
2084 | 2084 | ||
2085 | static void __exit de_remove_one (struct pci_dev *pdev) | 2085 | static void __devexit de_remove_one (struct pci_dev *pdev) |
2086 | { | 2086 | { |
2087 | struct net_device *dev = pci_get_drvdata(pdev); | 2087 | struct net_device *dev = pci_get_drvdata(pdev); |
2088 | struct de_private *de = dev->priv; | 2088 | struct de_private *de = dev->priv; |
@@ -2164,7 +2164,7 @@ static struct pci_driver de_driver = { | |||
2164 | .name = DRV_NAME, | 2164 | .name = DRV_NAME, |
2165 | .id_table = de_pci_tbl, | 2165 | .id_table = de_pci_tbl, |
2166 | .probe = de_init_one, | 2166 | .probe = de_init_one, |
2167 | .remove = __exit_p(de_remove_one), | 2167 | .remove = __devexit_p(de_remove_one), |
2168 | #ifdef CONFIG_PM | 2168 | #ifdef CONFIG_PM |
2169 | .suspend = de_suspend, | 2169 | .suspend = de_suspend, |
2170 | .resume = de_resume, | 2170 | .resume = de_resume, |
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 12cd7b561f35..b37888011067 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c | |||
@@ -2,14 +2,11 @@ | |||
2 | * Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved. | 2 | * Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved. |
3 | * | 3 | * |
4 | * Author: Shlomi Gridish <gridish@freescale.com> | 4 | * Author: Shlomi Gridish <gridish@freescale.com> |
5 | * Li Yang <leoli@freescale.com> | ||
5 | * | 6 | * |
6 | * Description: | 7 | * Description: |
7 | * QE UCC Gigabit Ethernet Driver | 8 | * QE UCC Gigabit Ethernet Driver |
8 | * | 9 | * |
9 | * Changelog: | ||
10 | * Jul 6, 2006 Li Yang <LeoLi@freescale.com> | ||
11 | * - Rearrange code and style fixes | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify it | 10 | * This program is free software; you can redistribute it and/or modify it |
14 | * under the terms of the GNU General Public License as published by the | 11 | * under the terms of the GNU General Public License as published by the |
15 | * Free Software Foundation; either version 2 of the License, or (at your | 12 | * Free Software Foundation; either version 2 of the License, or (at your |
@@ -31,9 +28,9 @@ | |||
31 | #include <linux/dma-mapping.h> | 28 | #include <linux/dma-mapping.h> |
32 | #include <linux/fsl_devices.h> | 29 | #include <linux/fsl_devices.h> |
33 | #include <linux/ethtool.h> | 30 | #include <linux/ethtool.h> |
34 | #include <linux/platform_device.h> | ||
35 | #include <linux/mii.h> | 31 | #include <linux/mii.h> |
36 | 32 | ||
33 | #include <asm/of_device.h> | ||
37 | #include <asm/uaccess.h> | 34 | #include <asm/uaccess.h> |
38 | #include <asm/irq.h> | 35 | #include <asm/irq.h> |
39 | #include <asm/io.h> | 36 | #include <asm/io.h> |
@@ -70,7 +67,7 @@ | |||
70 | 67 | ||
71 | static DEFINE_SPINLOCK(ugeth_lock); | 68 | static DEFINE_SPINLOCK(ugeth_lock); |
72 | 69 | ||
73 | static ucc_geth_info_t ugeth_primary_info = { | 70 | static struct ucc_geth_info ugeth_primary_info = { |
74 | .uf_info = { | 71 | .uf_info = { |
75 | .bd_mem_part = MEM_PART_SYSTEM, | 72 | .bd_mem_part = MEM_PART_SYSTEM, |
76 | .rtsm = UCC_FAST_SEND_IDLES_BETWEEN_FRAMES, | 73 | .rtsm = UCC_FAST_SEND_IDLES_BETWEEN_FRAMES, |
@@ -163,7 +160,7 @@ static ucc_geth_info_t ugeth_primary_info = { | |||
163 | .riscRx = QE_RISC_ALLOCATION_RISC1_AND_RISC2, | 160 | .riscRx = QE_RISC_ALLOCATION_RISC1_AND_RISC2, |
164 | }; | 161 | }; |
165 | 162 | ||
166 | static ucc_geth_info_t ugeth_info[8]; | 163 | static struct ucc_geth_info ugeth_info[8]; |
167 | 164 | ||
168 | #ifdef DEBUG | 165 | #ifdef DEBUG |
169 | static void mem_disp(u8 *addr, int size) | 166 | static void mem_disp(u8 *addr, int size) |
@@ -219,8 +216,8 @@ static struct list_head *dequeue(struct list_head *lh) | |||
219 | } | 216 | } |
220 | } | 217 | } |
221 | 218 | ||
222 | static int get_interface_details(enet_interface_e enet_interface, | 219 | static int get_interface_details(enum enet_interface enet_interface, |
223 | enet_speed_e *speed, | 220 | enum enet_speed *speed, |
224 | int *r10m, | 221 | int *r10m, |
225 | int *rmm, | 222 | int *rmm, |
226 | int *rpm, | 223 | int *rpm, |
@@ -283,7 +280,7 @@ static int get_interface_details(enet_interface_e enet_interface, | |||
283 | return 0; | 280 | return 0; |
284 | } | 281 | } |
285 | 282 | ||
286 | static struct sk_buff *get_new_skb(ucc_geth_private_t *ugeth, u8 *bd) | 283 | static struct sk_buff *get_new_skb(struct ucc_geth_private *ugeth, u8 *bd) |
287 | { | 284 | { |
288 | struct sk_buff *skb = NULL; | 285 | struct sk_buff *skb = NULL; |
289 | 286 | ||
@@ -303,21 +300,19 @@ static struct sk_buff *get_new_skb(ucc_geth_private_t *ugeth, u8 *bd) | |||
303 | 300 | ||
304 | skb->dev = ugeth->dev; | 301 | skb->dev = ugeth->dev; |
305 | 302 | ||
306 | BD_BUFFER_SET(bd, | 303 | out_be32(&((struct qe_bd *)bd)->buf, |
307 | dma_map_single(NULL, | 304 | dma_map_single(NULL, |
308 | skb->data, | 305 | skb->data, |
309 | ugeth->ug_info->uf_info.max_rx_buf_length + | 306 | ugeth->ug_info->uf_info.max_rx_buf_length + |
310 | UCC_GETH_RX_DATA_BUF_ALIGNMENT, | 307 | UCC_GETH_RX_DATA_BUF_ALIGNMENT, |
311 | DMA_FROM_DEVICE)); | 308 | DMA_FROM_DEVICE)); |
312 | 309 | ||
313 | BD_STATUS_AND_LENGTH_SET(bd, | 310 | out_be32((u32 *)bd, (R_E | R_I | (in_be32((u32 *)bd) & R_W))); |
314 | (R_E | R_I | | ||
315 | (BD_STATUS_AND_LENGTH(bd) & R_W))); | ||
316 | 311 | ||
317 | return skb; | 312 | return skb; |
318 | } | 313 | } |
319 | 314 | ||
320 | static int rx_bd_buffer_set(ucc_geth_private_t *ugeth, u8 rxQ) | 315 | static int rx_bd_buffer_set(struct ucc_geth_private *ugeth, u8 rxQ) |
321 | { | 316 | { |
322 | u8 *bd; | 317 | u8 *bd; |
323 | u32 bd_status; | 318 | u32 bd_status; |
@@ -328,7 +323,7 @@ static int rx_bd_buffer_set(ucc_geth_private_t *ugeth, u8 rxQ) | |||
328 | i = 0; | 323 | i = 0; |
329 | 324 | ||
330 | do { | 325 | do { |
331 | bd_status = BD_STATUS_AND_LENGTH(bd); | 326 | bd_status = in_be32((u32*)bd); |
332 | skb = get_new_skb(ugeth, bd); | 327 | skb = get_new_skb(ugeth, bd); |
333 | 328 | ||
334 | if (!skb) /* If can not allocate data buffer, | 329 | if (!skb) /* If can not allocate data buffer, |
@@ -338,19 +333,19 @@ static int rx_bd_buffer_set(ucc_geth_private_t *ugeth, u8 rxQ) | |||
338 | ugeth->rx_skbuff[rxQ][i] = skb; | 333 | ugeth->rx_skbuff[rxQ][i] = skb; |
339 | 334 | ||
340 | /* advance the BD pointer */ | 335 | /* advance the BD pointer */ |
341 | bd += UCC_GETH_SIZE_OF_BD; | 336 | bd += sizeof(struct qe_bd); |
342 | i++; | 337 | i++; |
343 | } while (!(bd_status & R_W)); | 338 | } while (!(bd_status & R_W)); |
344 | 339 | ||
345 | return 0; | 340 | return 0; |
346 | } | 341 | } |
347 | 342 | ||
348 | static int fill_init_enet_entries(ucc_geth_private_t *ugeth, | 343 | static int fill_init_enet_entries(struct ucc_geth_private *ugeth, |
349 | volatile u32 *p_start, | 344 | volatile u32 *p_start, |
350 | u8 num_entries, | 345 | u8 num_entries, |
351 | u32 thread_size, | 346 | u32 thread_size, |
352 | u32 thread_alignment, | 347 | u32 thread_alignment, |
353 | qe_risc_allocation_e risc, | 348 | enum qe_risc_allocation risc, |
354 | int skip_page_for_first_entry) | 349 | int skip_page_for_first_entry) |
355 | { | 350 | { |
356 | u32 init_enet_offset; | 351 | u32 init_enet_offset; |
@@ -383,10 +378,10 @@ static int fill_init_enet_entries(ucc_geth_private_t *ugeth, | |||
383 | return 0; | 378 | return 0; |
384 | } | 379 | } |
385 | 380 | ||
386 | static int return_init_enet_entries(ucc_geth_private_t *ugeth, | 381 | static int return_init_enet_entries(struct ucc_geth_private *ugeth, |
387 | volatile u32 *p_start, | 382 | volatile u32 *p_start, |
388 | u8 num_entries, | 383 | u8 num_entries, |
389 | qe_risc_allocation_e risc, | 384 | enum qe_risc_allocation risc, |
390 | int skip_page_for_first_entry) | 385 | int skip_page_for_first_entry) |
391 | { | 386 | { |
392 | u32 init_enet_offset; | 387 | u32 init_enet_offset; |
@@ -416,11 +411,11 @@ static int return_init_enet_entries(ucc_geth_private_t *ugeth, | |||
416 | } | 411 | } |
417 | 412 | ||
418 | #ifdef DEBUG | 413 | #ifdef DEBUG |
419 | static int dump_init_enet_entries(ucc_geth_private_t *ugeth, | 414 | static int dump_init_enet_entries(struct ucc_geth_private *ugeth, |
420 | volatile u32 *p_start, | 415 | volatile u32 *p_start, |
421 | u8 num_entries, | 416 | u8 num_entries, |
422 | u32 thread_size, | 417 | u32 thread_size, |
423 | qe_risc_allocation_e risc, | 418 | enum qe_risc_allocation risc, |
424 | int skip_page_for_first_entry) | 419 | int skip_page_for_first_entry) |
425 | { | 420 | { |
426 | u32 init_enet_offset; | 421 | u32 init_enet_offset; |
@@ -456,14 +451,14 @@ static int dump_init_enet_entries(ucc_geth_private_t *ugeth, | |||
456 | #endif | 451 | #endif |
457 | 452 | ||
458 | #ifdef CONFIG_UGETH_FILTERING | 453 | #ifdef CONFIG_UGETH_FILTERING |
459 | static enet_addr_container_t *get_enet_addr_container(void) | 454 | static struct enet_addr_container *get_enet_addr_container(void) |
460 | { | 455 | { |
461 | enet_addr_container_t *enet_addr_cont; | 456 | struct enet_addr_container *enet_addr_cont; |
462 | 457 | ||
463 | /* allocate memory */ | 458 | /* allocate memory */ |
464 | enet_addr_cont = kmalloc(sizeof(enet_addr_container_t), GFP_KERNEL); | 459 | enet_addr_cont = kmalloc(sizeof(struct enet_addr_container), GFP_KERNEL); |
465 | if (!enet_addr_cont) { | 460 | if (!enet_addr_cont) { |
466 | ugeth_err("%s: No memory for enet_addr_container_t object.", | 461 | ugeth_err("%s: No memory for enet_addr_container object.", |
467 | __FUNCTION__); | 462 | __FUNCTION__); |
468 | return NULL; | 463 | return NULL; |
469 | } | 464 | } |
@@ -472,45 +467,43 @@ static enet_addr_container_t *get_enet_addr_container(void) | |||
472 | } | 467 | } |
473 | #endif /* CONFIG_UGETH_FILTERING */ | 468 | #endif /* CONFIG_UGETH_FILTERING */ |
474 | 469 | ||
475 | static void put_enet_addr_container(enet_addr_container_t *enet_addr_cont) | 470 | static void put_enet_addr_container(struct enet_addr_container *enet_addr_cont) |
476 | { | 471 | { |
477 | kfree(enet_addr_cont); | 472 | kfree(enet_addr_cont); |
478 | } | 473 | } |
479 | 474 | ||
475 | static int set_mac_addr(__be16 __iomem *reg, u8 *mac) | ||
476 | { | ||
477 | out_be16(®[0], ((u16)mac[5] << 8) | mac[4]); | ||
478 | out_be16(®[1], ((u16)mac[3] << 8) | mac[2]); | ||
479 | out_be16(®[2], ((u16)mac[1] << 8) | mac[0]); | ||
480 | } | ||
481 | |||
480 | #ifdef CONFIG_UGETH_FILTERING | 482 | #ifdef CONFIG_UGETH_FILTERING |
481 | static int hw_add_addr_in_paddr(ucc_geth_private_t *ugeth, | 483 | static int hw_add_addr_in_paddr(struct ucc_geth_private *ugeth, |
482 | enet_addr_t *p_enet_addr, u8 paddr_num) | 484 | u8 *p_enet_addr, u8 paddr_num) |
483 | { | 485 | { |
484 | ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt; | 486 | struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt; |
485 | 487 | ||
486 | if (!(paddr_num < NUM_OF_PADDRS)) { | 488 | if (!(paddr_num < NUM_OF_PADDRS)) { |
487 | ugeth_warn("%s: Illagel paddr_num.", __FUNCTION__); | 489 | ugeth_warn("%s: Illegal paddr_num.", __FUNCTION__); |
488 | return -EINVAL; | 490 | return -EINVAL; |
489 | } | 491 | } |
490 | 492 | ||
491 | p_82xx_addr_filt = | 493 | p_82xx_addr_filt = |
492 | (ucc_geth_82xx_address_filtering_pram_t *) ugeth->p_rx_glbl_pram-> | 494 | (struct ucc_geth_82xx_address_filtering_pram *) ugeth->p_rx_glbl_pram-> |
493 | addressfiltering; | 495 | addressfiltering; |
494 | 496 | ||
495 | /* Ethernet frames are defined in Little Endian mode, */ | 497 | /* Ethernet frames are defined in Little Endian mode, */ |
496 | /* therefore to insert the address we reverse the bytes. */ | 498 | /* therefore to insert the address we reverse the bytes. */ |
497 | out_be16(&p_82xx_addr_filt->paddr[paddr_num].h, | 499 | set_mac_addr(&p_82xx_addr_filt->paddr[paddr_num].h, p_enet_addr); |
498 | (u16) (((u16) (((u16) ((*p_enet_addr)[5])) << 8)) | | ||
499 | (u16) (*p_enet_addr)[4])); | ||
500 | out_be16(&p_82xx_addr_filt->paddr[paddr_num].m, | ||
501 | (u16) (((u16) (((u16) ((*p_enet_addr)[3])) << 8)) | | ||
502 | (u16) (*p_enet_addr)[2])); | ||
503 | out_be16(&p_82xx_addr_filt->paddr[paddr_num].l, | ||
504 | (u16) (((u16) (((u16) ((*p_enet_addr)[1])) << 8)) | | ||
505 | (u16) (*p_enet_addr)[0])); | ||
506 | |||
507 | return 0; | 500 | return 0; |
508 | } | 501 | } |
509 | #endif /* CONFIG_UGETH_FILTERING */ | 502 | #endif /* CONFIG_UGETH_FILTERING */ |
510 | 503 | ||
511 | static int hw_clear_addr_in_paddr(ucc_geth_private_t *ugeth, u8 paddr_num) | 504 | static int hw_clear_addr_in_paddr(struct ucc_geth_private *ugeth, u8 paddr_num) |
512 | { | 505 | { |
513 | ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt; | 506 | struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt; |
514 | 507 | ||
515 | if (!(paddr_num < NUM_OF_PADDRS)) { | 508 | if (!(paddr_num < NUM_OF_PADDRS)) { |
516 | ugeth_warn("%s: Illagel paddr_num.", __FUNCTION__); | 509 | ugeth_warn("%s: Illagel paddr_num.", __FUNCTION__); |
@@ -518,7 +511,7 @@ static int hw_clear_addr_in_paddr(ucc_geth_private_t *ugeth, u8 paddr_num) | |||
518 | } | 511 | } |
519 | 512 | ||
520 | p_82xx_addr_filt = | 513 | p_82xx_addr_filt = |
521 | (ucc_geth_82xx_address_filtering_pram_t *) ugeth->p_rx_glbl_pram-> | 514 | (struct ucc_geth_82xx_address_filtering_pram *) ugeth->p_rx_glbl_pram-> |
522 | addressfiltering; | 515 | addressfiltering; |
523 | 516 | ||
524 | /* Writing address ff.ff.ff.ff.ff.ff disables address | 517 | /* Writing address ff.ff.ff.ff.ff.ff disables address |
@@ -530,14 +523,14 @@ static int hw_clear_addr_in_paddr(ucc_geth_private_t *ugeth, u8 paddr_num) | |||
530 | return 0; | 523 | return 0; |
531 | } | 524 | } |
532 | 525 | ||
533 | static void hw_add_addr_in_hash(ucc_geth_private_t *ugeth, | 526 | static void hw_add_addr_in_hash(struct ucc_geth_private *ugeth, |
534 | enet_addr_t *p_enet_addr) | 527 | u8 *p_enet_addr) |
535 | { | 528 | { |
536 | ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt; | 529 | struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt; |
537 | u32 cecr_subblock; | 530 | u32 cecr_subblock; |
538 | 531 | ||
539 | p_82xx_addr_filt = | 532 | p_82xx_addr_filt = |
540 | (ucc_geth_82xx_address_filtering_pram_t *) ugeth->p_rx_glbl_pram-> | 533 | (struct ucc_geth_82xx_address_filtering_pram *) ugeth->p_rx_glbl_pram-> |
541 | addressfiltering; | 534 | addressfiltering; |
542 | 535 | ||
543 | cecr_subblock = | 536 | cecr_subblock = |
@@ -546,25 +539,18 @@ static void hw_add_addr_in_hash(ucc_geth_private_t *ugeth, | |||
546 | /* Ethernet frames are defined in Little Endian mode, | 539 | /* Ethernet frames are defined in Little Endian mode, |
547 | therefor to insert */ | 540 | therefor to insert */ |
548 | /* the address to the hash (Big Endian mode), we reverse the bytes.*/ | 541 | /* the address to the hash (Big Endian mode), we reverse the bytes.*/ |
549 | out_be16(&p_82xx_addr_filt->taddr.h, | 542 | |
550 | (u16) (((u16) (((u16) ((*p_enet_addr)[5])) << 8)) | | 543 | set_mac_addr(&p_82xx_addr_filt->taddr.h, p_enet_addr); |
551 | (u16) (*p_enet_addr)[4])); | ||
552 | out_be16(&p_82xx_addr_filt->taddr.m, | ||
553 | (u16) (((u16) (((u16) ((*p_enet_addr)[3])) << 8)) | | ||
554 | (u16) (*p_enet_addr)[2])); | ||
555 | out_be16(&p_82xx_addr_filt->taddr.l, | ||
556 | (u16) (((u16) (((u16) ((*p_enet_addr)[1])) << 8)) | | ||
557 | (u16) (*p_enet_addr)[0])); | ||
558 | 544 | ||
559 | qe_issue_cmd(QE_SET_GROUP_ADDRESS, cecr_subblock, | 545 | qe_issue_cmd(QE_SET_GROUP_ADDRESS, cecr_subblock, |
560 | (u8) QE_CR_PROTOCOL_ETHERNET, 0); | 546 | QE_CR_PROTOCOL_ETHERNET, 0); |
561 | } | 547 | } |
562 | 548 | ||
563 | #ifdef CONFIG_UGETH_MAGIC_PACKET | 549 | #ifdef CONFIG_UGETH_MAGIC_PACKET |
564 | static void magic_packet_detection_enable(ucc_geth_private_t *ugeth) | 550 | static void magic_packet_detection_enable(struct ucc_geth_private *ugeth) |
565 | { | 551 | { |
566 | ucc_fast_private_t *uccf; | 552 | struct ucc_fast_private *uccf; |
567 | ucc_geth_t *ug_regs; | 553 | struct ucc_geth *ug_regs; |
568 | u32 maccfg2, uccm; | 554 | u32 maccfg2, uccm; |
569 | 555 | ||
570 | uccf = ugeth->uccf; | 556 | uccf = ugeth->uccf; |
@@ -581,10 +567,10 @@ static void magic_packet_detection_enable(ucc_geth_private_t *ugeth) | |||
581 | out_be32(&ug_regs->maccfg2, maccfg2); | 567 | out_be32(&ug_regs->maccfg2, maccfg2); |
582 | } | 568 | } |
583 | 569 | ||
584 | static void magic_packet_detection_disable(ucc_geth_private_t *ugeth) | 570 | static void magic_packet_detection_disable(struct ucc_geth_private *ugeth) |
585 | { | 571 | { |
586 | ucc_fast_private_t *uccf; | 572 | struct ucc_fast_private *uccf; |
587 | ucc_geth_t *ug_regs; | 573 | struct ucc_geth *ug_regs; |
588 | u32 maccfg2, uccm; | 574 | u32 maccfg2, uccm; |
589 | 575 | ||
590 | uccf = ugeth->uccf; | 576 | uccf = ugeth->uccf; |
@@ -602,26 +588,26 @@ static void magic_packet_detection_disable(ucc_geth_private_t *ugeth) | |||
602 | } | 588 | } |
603 | #endif /* MAGIC_PACKET */ | 589 | #endif /* MAGIC_PACKET */ |
604 | 590 | ||
605 | static inline int compare_addr(enet_addr_t *addr1, enet_addr_t *addr2) | 591 | static inline int compare_addr(u8 **addr1, u8 **addr2) |
606 | { | 592 | { |
607 | return memcmp(addr1, addr2, ENET_NUM_OCTETS_PER_ADDRESS); | 593 | return memcmp(addr1, addr2, ENET_NUM_OCTETS_PER_ADDRESS); |
608 | } | 594 | } |
609 | 595 | ||
610 | #ifdef DEBUG | 596 | #ifdef DEBUG |
611 | static void get_statistics(ucc_geth_private_t *ugeth, | 597 | static void get_statistics(struct ucc_geth_private *ugeth, |
612 | ucc_geth_tx_firmware_statistics_t * | 598 | struct ucc_geth_tx_firmware_statistics * |
613 | tx_firmware_statistics, | 599 | tx_firmware_statistics, |
614 | ucc_geth_rx_firmware_statistics_t * | 600 | struct ucc_geth_rx_firmware_statistics * |
615 | rx_firmware_statistics, | 601 | rx_firmware_statistics, |
616 | ucc_geth_hardware_statistics_t *hardware_statistics) | 602 | struct ucc_geth_hardware_statistics *hardware_statistics) |
617 | { | 603 | { |
618 | ucc_fast_t *uf_regs; | 604 | struct ucc_fast *uf_regs; |
619 | ucc_geth_t *ug_regs; | 605 | struct ucc_geth *ug_regs; |
620 | ucc_geth_tx_firmware_statistics_pram_t *p_tx_fw_statistics_pram; | 606 | struct ucc_geth_tx_firmware_statistics_pram *p_tx_fw_statistics_pram; |
621 | ucc_geth_rx_firmware_statistics_pram_t *p_rx_fw_statistics_pram; | 607 | struct ucc_geth_rx_firmware_statistics_pram *p_rx_fw_statistics_pram; |
622 | 608 | ||
623 | ug_regs = ugeth->ug_regs; | 609 | ug_regs = ugeth->ug_regs; |
624 | uf_regs = (ucc_fast_t *) ug_regs; | 610 | uf_regs = (struct ucc_fast *) ug_regs; |
625 | p_tx_fw_statistics_pram = ugeth->p_tx_fw_statistics_pram; | 611 | p_tx_fw_statistics_pram = ugeth->p_tx_fw_statistics_pram; |
626 | p_rx_fw_statistics_pram = ugeth->p_rx_fw_statistics_pram; | 612 | p_rx_fw_statistics_pram = ugeth->p_rx_fw_statistics_pram; |
627 | 613 | ||
@@ -727,7 +713,7 @@ static void get_statistics(ucc_geth_private_t *ugeth, | |||
727 | } | 713 | } |
728 | } | 714 | } |
729 | 715 | ||
730 | static void dump_bds(ucc_geth_private_t *ugeth) | 716 | static void dump_bds(struct ucc_geth_private *ugeth) |
731 | { | 717 | { |
732 | int i; | 718 | int i; |
733 | int length; | 719 | int length; |
@@ -736,7 +722,7 @@ static void dump_bds(ucc_geth_private_t *ugeth) | |||
736 | if (ugeth->p_tx_bd_ring[i]) { | 722 | if (ugeth->p_tx_bd_ring[i]) { |
737 | length = | 723 | length = |
738 | (ugeth->ug_info->bdRingLenTx[i] * | 724 | (ugeth->ug_info->bdRingLenTx[i] * |
739 | UCC_GETH_SIZE_OF_BD); | 725 | sizeof(struct qe_bd)); |
740 | ugeth_info("TX BDs[%d]", i); | 726 | ugeth_info("TX BDs[%d]", i); |
741 | mem_disp(ugeth->p_tx_bd_ring[i], length); | 727 | mem_disp(ugeth->p_tx_bd_ring[i], length); |
742 | } | 728 | } |
@@ -745,14 +731,14 @@ static void dump_bds(ucc_geth_private_t *ugeth) | |||
745 | if (ugeth->p_rx_bd_ring[i]) { | 731 | if (ugeth->p_rx_bd_ring[i]) { |
746 | length = | 732 | length = |
747 | (ugeth->ug_info->bdRingLenRx[i] * | 733 | (ugeth->ug_info->bdRingLenRx[i] * |
748 | UCC_GETH_SIZE_OF_BD); | 734 | sizeof(struct qe_bd)); |
749 | ugeth_info("RX BDs[%d]", i); | 735 | ugeth_info("RX BDs[%d]", i); |
750 | mem_disp(ugeth->p_rx_bd_ring[i], length); | 736 | mem_disp(ugeth->p_rx_bd_ring[i], length); |
751 | } | 737 | } |
752 | } | 738 | } |
753 | } | 739 | } |
754 | 740 | ||
755 | static void dump_regs(ucc_geth_private_t *ugeth) | 741 | static void dump_regs(struct ucc_geth_private *ugeth) |
756 | { | 742 | { |
757 | int i; | 743 | int i; |
758 | 744 | ||
@@ -893,7 +879,7 @@ static void dump_regs(ucc_geth_private_t *ugeth) | |||
893 | ugeth_info("Base address: 0x%08x", | 879 | ugeth_info("Base address: 0x%08x", |
894 | (u32) & ugeth->p_thread_data_tx[i]); | 880 | (u32) & ugeth->p_thread_data_tx[i]); |
895 | mem_disp((u8 *) & ugeth->p_thread_data_tx[i], | 881 | mem_disp((u8 *) & ugeth->p_thread_data_tx[i], |
896 | sizeof(ucc_geth_thread_data_tx_t)); | 882 | sizeof(struct ucc_geth_thread_data_tx)); |
897 | } | 883 | } |
898 | } | 884 | } |
899 | if (ugeth->p_thread_data_rx) { | 885 | if (ugeth->p_thread_data_rx) { |
@@ -927,7 +913,7 @@ static void dump_regs(ucc_geth_private_t *ugeth) | |||
927 | ugeth_info("Base address: 0x%08x", | 913 | ugeth_info("Base address: 0x%08x", |
928 | (u32) & ugeth->p_thread_data_rx[i]); | 914 | (u32) & ugeth->p_thread_data_rx[i]); |
929 | mem_disp((u8 *) & ugeth->p_thread_data_rx[i], | 915 | mem_disp((u8 *) & ugeth->p_thread_data_rx[i], |
930 | sizeof(ucc_geth_thread_data_rx_t)); | 916 | sizeof(struct ucc_geth_thread_data_rx)); |
931 | } | 917 | } |
932 | } | 918 | } |
933 | if (ugeth->p_exf_glbl_param) { | 919 | if (ugeth->p_exf_glbl_param) { |
@@ -1105,7 +1091,7 @@ static void dump_regs(ucc_geth_private_t *ugeth) | |||
1105 | ugeth_info("Base address: 0x%08x", | 1091 | ugeth_info("Base address: 0x%08x", |
1106 | (u32) & ugeth->p_send_q_mem_reg->sqqd[i]); | 1092 | (u32) & ugeth->p_send_q_mem_reg->sqqd[i]); |
1107 | mem_disp((u8 *) & ugeth->p_send_q_mem_reg->sqqd[i], | 1093 | mem_disp((u8 *) & ugeth->p_send_q_mem_reg->sqqd[i], |
1108 | sizeof(ucc_geth_send_queue_qd_t)); | 1094 | sizeof(struct ucc_geth_send_queue_qd)); |
1109 | } | 1095 | } |
1110 | } | 1096 | } |
1111 | if (ugeth->p_scheduler) { | 1097 | if (ugeth->p_scheduler) { |
@@ -1187,7 +1173,7 @@ static void dump_regs(ucc_geth_private_t *ugeth) | |||
1187 | qe_muram_addr(in_be32 | 1173 | qe_muram_addr(in_be32 |
1188 | (&ugeth->p_rx_bd_qs_tbl[i]. | 1174 | (&ugeth->p_rx_bd_qs_tbl[i]. |
1189 | bdbaseptr)), | 1175 | bdbaseptr)), |
1190 | sizeof(ucc_geth_rx_prefetched_bds_t)); | 1176 | sizeof(struct ucc_geth_rx_prefetched_bds)); |
1191 | } | 1177 | } |
1192 | } | 1178 | } |
1193 | if (ugeth->p_init_enet_param_shadow) { | 1179 | if (ugeth->p_init_enet_param_shadow) { |
@@ -1198,7 +1184,7 @@ static void dump_regs(ucc_geth_private_t *ugeth) | |||
1198 | mem_disp((u8 *) ugeth->p_init_enet_param_shadow, | 1184 | mem_disp((u8 *) ugeth->p_init_enet_param_shadow, |
1199 | sizeof(*ugeth->p_init_enet_param_shadow)); | 1185 | sizeof(*ugeth->p_init_enet_param_shadow)); |
1200 | 1186 | ||
1201 | size = sizeof(ucc_geth_thread_rx_pram_t); | 1187 | size = sizeof(struct ucc_geth_thread_rx_pram); |
1202 | if (ugeth->ug_info->rxExtendedFiltering) { | 1188 | if (ugeth->ug_info->rxExtendedFiltering) { |
1203 | size += | 1189 | size += |
1204 | THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING; | 1190 | THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING; |
@@ -1216,7 +1202,7 @@ static void dump_regs(ucc_geth_private_t *ugeth) | |||
1216 | &(ugeth->p_init_enet_param_shadow-> | 1202 | &(ugeth->p_init_enet_param_shadow-> |
1217 | txthread[0]), | 1203 | txthread[0]), |
1218 | ENET_INIT_PARAM_MAX_ENTRIES_TX, | 1204 | ENET_INIT_PARAM_MAX_ENTRIES_TX, |
1219 | sizeof(ucc_geth_thread_tx_pram_t), | 1205 | sizeof(struct ucc_geth_thread_tx_pram), |
1220 | ugeth->ug_info->riscTx, 0); | 1206 | ugeth->ug_info->riscTx, 0); |
1221 | dump_init_enet_entries(ugeth, | 1207 | dump_init_enet_entries(ugeth, |
1222 | &(ugeth->p_init_enet_param_shadow-> | 1208 | &(ugeth->p_init_enet_param_shadow-> |
@@ -1578,12 +1564,12 @@ static int init_min_frame_len(u16 min_frame_length, | |||
1578 | return 0; | 1564 | return 0; |
1579 | } | 1565 | } |
1580 | 1566 | ||
1581 | static int adjust_enet_interface(ucc_geth_private_t *ugeth) | 1567 | static int adjust_enet_interface(struct ucc_geth_private *ugeth) |
1582 | { | 1568 | { |
1583 | ucc_geth_info_t *ug_info; | 1569 | struct ucc_geth_info *ug_info; |
1584 | ucc_geth_t *ug_regs; | 1570 | struct ucc_geth *ug_regs; |
1585 | ucc_fast_t *uf_regs; | 1571 | struct ucc_fast *uf_regs; |
1586 | enet_speed_e speed; | 1572 | enum enet_speed speed; |
1587 | int ret_val, rpm = 0, tbi = 0, r10m = 0, rmm = | 1573 | int ret_val, rpm = 0, tbi = 0, r10m = 0, rmm = |
1588 | 0, limited_to_full_duplex = 0; | 1574 | 0, limited_to_full_duplex = 0; |
1589 | u32 upsmr, maccfg2, utbipar, tbiBaseAddress; | 1575 | u32 upsmr, maccfg2, utbipar, tbiBaseAddress; |
@@ -1691,8 +1677,8 @@ static int adjust_enet_interface(ucc_geth_private_t *ugeth) | |||
1691 | */ | 1677 | */ |
1692 | static void adjust_link(struct net_device *dev) | 1678 | static void adjust_link(struct net_device *dev) |
1693 | { | 1679 | { |
1694 | ucc_geth_private_t *ugeth = netdev_priv(dev); | 1680 | struct ucc_geth_private *ugeth = netdev_priv(dev); |
1695 | ucc_geth_t *ug_regs; | 1681 | struct ucc_geth *ug_regs; |
1696 | u32 tempval; | 1682 | u32 tempval; |
1697 | struct ugeth_mii_info *mii_info = ugeth->mii_info; | 1683 | struct ugeth_mii_info *mii_info = ugeth->mii_info; |
1698 | 1684 | ||
@@ -1722,7 +1708,7 @@ static void adjust_link(struct net_device *dev) | |||
1722 | if (mii_info->speed != ugeth->oldspeed) { | 1708 | if (mii_info->speed != ugeth->oldspeed) { |
1723 | switch (mii_info->speed) { | 1709 | switch (mii_info->speed) { |
1724 | case 1000: | 1710 | case 1000: |
1725 | #ifdef CONFIG_MPC836x | 1711 | #ifdef CONFIG_PPC_MPC836x |
1726 | /* FIXME: This code is for 100Mbs BUG fixing, | 1712 | /* FIXME: This code is for 100Mbs BUG fixing, |
1727 | remove this when it is fixed!!! */ | 1713 | remove this when it is fixed!!! */ |
1728 | if (ugeth->ug_info->enet_interface == | 1714 | if (ugeth->ug_info->enet_interface == |
@@ -1768,7 +1754,7 @@ remove this when it is fixed!!! */ | |||
1768 | break; | 1754 | break; |
1769 | case 100: | 1755 | case 100: |
1770 | case 10: | 1756 | case 10: |
1771 | #ifdef CONFIG_MPC836x | 1757 | #ifdef CONFIG_PPC_MPC836x |
1772 | /* FIXME: This code is for 100Mbs BUG fixing, | 1758 | /* FIXME: This code is for 100Mbs BUG fixing, |
1773 | remove this lines when it will be fixed!!! */ | 1759 | remove this lines when it will be fixed!!! */ |
1774 | ugeth->ug_info->enet_interface = ENET_100_RGMII; | 1760 | ugeth->ug_info->enet_interface = ENET_100_RGMII; |
@@ -1827,9 +1813,9 @@ remove this lines when it will be fixed!!! */ | |||
1827 | */ | 1813 | */ |
1828 | static int init_phy(struct net_device *dev) | 1814 | static int init_phy(struct net_device *dev) |
1829 | { | 1815 | { |
1830 | ucc_geth_private_t *ugeth = netdev_priv(dev); | 1816 | struct ucc_geth_private *ugeth = netdev_priv(dev); |
1831 | struct phy_info *curphy; | 1817 | struct phy_info *curphy; |
1832 | ucc_mii_mng_t *mii_regs; | 1818 | struct ucc_mii_mng *mii_regs; |
1833 | struct ugeth_mii_info *mii_info; | 1819 | struct ugeth_mii_info *mii_info; |
1834 | int err; | 1820 | int err; |
1835 | 1821 | ||
@@ -1914,17 +1900,17 @@ static int init_phy(struct net_device *dev) | |||
1914 | } | 1900 | } |
1915 | 1901 | ||
1916 | #ifdef CONFIG_UGETH_TX_ON_DEMOND | 1902 | #ifdef CONFIG_UGETH_TX_ON_DEMOND |
1917 | static int ugeth_transmit_on_demand(ucc_geth_private_t *ugeth) | 1903 | static int ugeth_transmit_on_demand(struct ucc_geth_private *ugeth) |
1918 | { | 1904 | { |
1919 | ucc_fast_transmit_on_demand(ugeth->uccf); | 1905 | struct ucc_fastransmit_on_demand(ugeth->uccf); |
1920 | 1906 | ||
1921 | return 0; | 1907 | return 0; |
1922 | } | 1908 | } |
1923 | #endif | 1909 | #endif |
1924 | 1910 | ||
1925 | static int ugeth_graceful_stop_tx(ucc_geth_private_t *ugeth) | 1911 | static int ugeth_graceful_stop_tx(struct ucc_geth_private *ugeth) |
1926 | { | 1912 | { |
1927 | ucc_fast_private_t *uccf; | 1913 | struct ucc_fast_private *uccf; |
1928 | u32 cecr_subblock; | 1914 | u32 cecr_subblock; |
1929 | u32 temp; | 1915 | u32 temp; |
1930 | 1916 | ||
@@ -1940,7 +1926,7 @@ static int ugeth_graceful_stop_tx(ucc_geth_private_t *ugeth) | |||
1940 | cecr_subblock = | 1926 | cecr_subblock = |
1941 | ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num); | 1927 | ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num); |
1942 | qe_issue_cmd(QE_GRACEFUL_STOP_TX, cecr_subblock, | 1928 | qe_issue_cmd(QE_GRACEFUL_STOP_TX, cecr_subblock, |
1943 | (u8) QE_CR_PROTOCOL_ETHERNET, 0); | 1929 | QE_CR_PROTOCOL_ETHERNET, 0); |
1944 | 1930 | ||
1945 | /* Wait for command to complete */ | 1931 | /* Wait for command to complete */ |
1946 | do { | 1932 | do { |
@@ -1952,9 +1938,9 @@ static int ugeth_graceful_stop_tx(ucc_geth_private_t *ugeth) | |||
1952 | return 0; | 1938 | return 0; |
1953 | } | 1939 | } |
1954 | 1940 | ||
1955 | static int ugeth_graceful_stop_rx(ucc_geth_private_t * ugeth) | 1941 | static int ugeth_graceful_stop_rx(struct ucc_geth_private * ugeth) |
1956 | { | 1942 | { |
1957 | ucc_fast_private_t *uccf; | 1943 | struct ucc_fast_private *uccf; |
1958 | u32 cecr_subblock; | 1944 | u32 cecr_subblock; |
1959 | u8 temp; | 1945 | u8 temp; |
1960 | 1946 | ||
@@ -1973,7 +1959,7 @@ static int ugeth_graceful_stop_rx(ucc_geth_private_t * ugeth) | |||
1973 | ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info. | 1959 | ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info. |
1974 | ucc_num); | 1960 | ucc_num); |
1975 | qe_issue_cmd(QE_GRACEFUL_STOP_RX, cecr_subblock, | 1961 | qe_issue_cmd(QE_GRACEFUL_STOP_RX, cecr_subblock, |
1976 | (u8) QE_CR_PROTOCOL_ETHERNET, 0); | 1962 | QE_CR_PROTOCOL_ETHERNET, 0); |
1977 | 1963 | ||
1978 | temp = ugeth->p_rx_glbl_pram->rxgstpack; | 1964 | temp = ugeth->p_rx_glbl_pram->rxgstpack; |
1979 | } while (!(temp & GRACEFUL_STOP_ACKNOWLEDGE_RX)); | 1965 | } while (!(temp & GRACEFUL_STOP_ACKNOWLEDGE_RX)); |
@@ -1983,41 +1969,40 @@ static int ugeth_graceful_stop_rx(ucc_geth_private_t * ugeth) | |||
1983 | return 0; | 1969 | return 0; |
1984 | } | 1970 | } |
1985 | 1971 | ||
1986 | static int ugeth_restart_tx(ucc_geth_private_t *ugeth) | 1972 | static int ugeth_restart_tx(struct ucc_geth_private *ugeth) |
1987 | { | 1973 | { |
1988 | ucc_fast_private_t *uccf; | 1974 | struct ucc_fast_private *uccf; |
1989 | u32 cecr_subblock; | 1975 | u32 cecr_subblock; |
1990 | 1976 | ||
1991 | uccf = ugeth->uccf; | 1977 | uccf = ugeth->uccf; |
1992 | 1978 | ||
1993 | cecr_subblock = | 1979 | cecr_subblock = |
1994 | ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num); | 1980 | ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num); |
1995 | qe_issue_cmd(QE_RESTART_TX, cecr_subblock, (u8) QE_CR_PROTOCOL_ETHERNET, | 1981 | qe_issue_cmd(QE_RESTART_TX, cecr_subblock, QE_CR_PROTOCOL_ETHERNET, 0); |
1996 | 0); | ||
1997 | uccf->stopped_tx = 0; | 1982 | uccf->stopped_tx = 0; |
1998 | 1983 | ||
1999 | return 0; | 1984 | return 0; |
2000 | } | 1985 | } |
2001 | 1986 | ||
2002 | static int ugeth_restart_rx(ucc_geth_private_t *ugeth) | 1987 | static int ugeth_restart_rx(struct ucc_geth_private *ugeth) |
2003 | { | 1988 | { |
2004 | ucc_fast_private_t *uccf; | 1989 | struct ucc_fast_private *uccf; |
2005 | u32 cecr_subblock; | 1990 | u32 cecr_subblock; |
2006 | 1991 | ||
2007 | uccf = ugeth->uccf; | 1992 | uccf = ugeth->uccf; |
2008 | 1993 | ||
2009 | cecr_subblock = | 1994 | cecr_subblock = |
2010 | ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num); | 1995 | ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num); |
2011 | qe_issue_cmd(QE_RESTART_RX, cecr_subblock, (u8) QE_CR_PROTOCOL_ETHERNET, | 1996 | qe_issue_cmd(QE_RESTART_RX, cecr_subblock, QE_CR_PROTOCOL_ETHERNET, |
2012 | 0); | 1997 | 0); |
2013 | uccf->stopped_rx = 0; | 1998 | uccf->stopped_rx = 0; |
2014 | 1999 | ||
2015 | return 0; | 2000 | return 0; |
2016 | } | 2001 | } |
2017 | 2002 | ||
2018 | static int ugeth_enable(ucc_geth_private_t *ugeth, comm_dir_e mode) | 2003 | static int ugeth_enable(struct ucc_geth_private *ugeth, enum comm_dir mode) |
2019 | { | 2004 | { |
2020 | ucc_fast_private_t *uccf; | 2005 | struct ucc_fast_private *uccf; |
2021 | int enabled_tx, enabled_rx; | 2006 | int enabled_tx, enabled_rx; |
2022 | 2007 | ||
2023 | uccf = ugeth->uccf; | 2008 | uccf = ugeth->uccf; |
@@ -2044,9 +2029,9 @@ static int ugeth_enable(ucc_geth_private_t *ugeth, comm_dir_e mode) | |||
2044 | 2029 | ||
2045 | } | 2030 | } |
2046 | 2031 | ||
2047 | static int ugeth_disable(ucc_geth_private_t * ugeth, comm_dir_e mode) | 2032 | static int ugeth_disable(struct ucc_geth_private * ugeth, enum comm_dir mode) |
2048 | { | 2033 | { |
2049 | ucc_fast_private_t *uccf; | 2034 | struct ucc_fast_private *uccf; |
2050 | 2035 | ||
2051 | uccf = ugeth->uccf; | 2036 | uccf = ugeth->uccf; |
2052 | 2037 | ||
@@ -2069,7 +2054,7 @@ static int ugeth_disable(ucc_geth_private_t * ugeth, comm_dir_e mode) | |||
2069 | return 0; | 2054 | return 0; |
2070 | } | 2055 | } |
2071 | 2056 | ||
2072 | static void ugeth_dump_regs(ucc_geth_private_t *ugeth) | 2057 | static void ugeth_dump_regs(struct ucc_geth_private *ugeth) |
2073 | { | 2058 | { |
2074 | #ifdef DEBUG | 2059 | #ifdef DEBUG |
2075 | ucc_fast_dump_regs(ugeth->uccf); | 2060 | ucc_fast_dump_regs(ugeth->uccf); |
@@ -2079,9 +2064,9 @@ static void ugeth_dump_regs(ucc_geth_private_t *ugeth) | |||
2079 | } | 2064 | } |
2080 | 2065 | ||
2081 | #ifdef CONFIG_UGETH_FILTERING | 2066 | #ifdef CONFIG_UGETH_FILTERING |
2082 | static int ugeth_ext_filtering_serialize_tad(ucc_geth_tad_params_t * | 2067 | static int ugeth_ext_filtering_serialize_tad(struct ucc_geth_tad_params * |
2083 | p_UccGethTadParams, | 2068 | p_UccGethTadParams, |
2084 | qe_fltr_tad_t *qe_fltr_tad) | 2069 | struct qe_fltr_tad *qe_fltr_tad) |
2085 | { | 2070 | { |
2086 | u16 temp; | 2071 | u16 temp; |
2087 | 2072 | ||
@@ -2119,11 +2104,11 @@ static int ugeth_ext_filtering_serialize_tad(ucc_geth_tad_params_t * | |||
2119 | return 0; | 2104 | return 0; |
2120 | } | 2105 | } |
2121 | 2106 | ||
2122 | static enet_addr_container_t | 2107 | static struct enet_addr_container_t |
2123 | *ugeth_82xx_filtering_get_match_addr_in_hash(ucc_geth_private_t *ugeth, | 2108 | *ugeth_82xx_filtering_get_match_addr_in_hash(struct ucc_geth_private *ugeth, |
2124 | enet_addr_t *p_enet_addr) | 2109 | struct enet_addr *p_enet_addr) |
2125 | { | 2110 | { |
2126 | enet_addr_container_t *enet_addr_cont; | 2111 | struct enet_addr_container *enet_addr_cont; |
2127 | struct list_head *p_lh; | 2112 | struct list_head *p_lh; |
2128 | u16 i, num; | 2113 | u16 i, num; |
2129 | int32_t j; | 2114 | int32_t j; |
@@ -2144,7 +2129,7 @@ static enet_addr_container_t | |||
2144 | 2129 | ||
2145 | for (i = 0; i < num; i++) { | 2130 | for (i = 0; i < num; i++) { |
2146 | enet_addr_cont = | 2131 | enet_addr_cont = |
2147 | (enet_addr_container_t *) | 2132 | (struct enet_addr_container *) |
2148 | ENET_ADDR_CONT_ENTRY(dequeue(p_lh)); | 2133 | ENET_ADDR_CONT_ENTRY(dequeue(p_lh)); |
2149 | for (j = ENET_NUM_OCTETS_PER_ADDRESS - 1; j >= 0; j--) { | 2134 | for (j = ENET_NUM_OCTETS_PER_ADDRESS - 1; j >= 0; j--) { |
2150 | if ((*p_enet_addr)[j] != (enet_addr_cont->address)[j]) | 2135 | if ((*p_enet_addr)[j] != (enet_addr_cont->address)[j]) |
@@ -2157,11 +2142,11 @@ static enet_addr_container_t | |||
2157 | return NULL; | 2142 | return NULL; |
2158 | } | 2143 | } |
2159 | 2144 | ||
2160 | static int ugeth_82xx_filtering_add_addr_in_hash(ucc_geth_private_t *ugeth, | 2145 | static int ugeth_82xx_filtering_add_addr_in_hash(struct ucc_geth_private *ugeth, |
2161 | enet_addr_t *p_enet_addr) | 2146 | struct enet_addr *p_enet_addr) |
2162 | { | 2147 | { |
2163 | ucc_geth_enet_address_recognition_location_e location; | 2148 | enum ucc_geth_enet_address_recognition_location location; |
2164 | enet_addr_container_t *enet_addr_cont; | 2149 | struct enet_addr_container *enet_addr_cont; |
2165 | struct list_head *p_lh; | 2150 | struct list_head *p_lh; |
2166 | u8 i; | 2151 | u8 i; |
2167 | u32 limit; | 2152 | u32 limit; |
@@ -2196,18 +2181,17 @@ static int ugeth_82xx_filtering_add_addr_in_hash(ucc_geth_private_t *ugeth, | |||
2196 | enqueue(p_lh, &enet_addr_cont->node); /* Put it back */ | 2181 | enqueue(p_lh, &enet_addr_cont->node); /* Put it back */ |
2197 | ++(*p_counter); | 2182 | ++(*p_counter); |
2198 | 2183 | ||
2199 | hw_add_addr_in_hash(ugeth, &(enet_addr_cont->address)); | 2184 | hw_add_addr_in_hash(ugeth, enet_addr_cont->address); |
2200 | |||
2201 | return 0; | 2185 | return 0; |
2202 | } | 2186 | } |
2203 | 2187 | ||
2204 | static int ugeth_82xx_filtering_clear_addr_in_hash(ucc_geth_private_t *ugeth, | 2188 | static int ugeth_82xx_filtering_clear_addr_in_hash(struct ucc_geth_private *ugeth, |
2205 | enet_addr_t *p_enet_addr) | 2189 | struct enet_addr *p_enet_addr) |
2206 | { | 2190 | { |
2207 | ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt; | 2191 | struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt; |
2208 | enet_addr_container_t *enet_addr_cont; | 2192 | struct enet_addr_container *enet_addr_cont; |
2209 | ucc_fast_private_t *uccf; | 2193 | struct ucc_fast_private *uccf; |
2210 | comm_dir_e comm_dir; | 2194 | enum comm_dir comm_dir; |
2211 | u16 i, num; | 2195 | u16 i, num; |
2212 | struct list_head *p_lh; | 2196 | struct list_head *p_lh; |
2213 | u32 *addr_h, *addr_l; | 2197 | u32 *addr_h, *addr_l; |
@@ -2216,7 +2200,7 @@ static int ugeth_82xx_filtering_clear_addr_in_hash(ucc_geth_private_t *ugeth, | |||
2216 | uccf = ugeth->uccf; | 2200 | uccf = ugeth->uccf; |
2217 | 2201 | ||
2218 | p_82xx_addr_filt = | 2202 | p_82xx_addr_filt = |
2219 | (ucc_geth_82xx_address_filtering_pram_t *) ugeth->p_rx_glbl_pram-> | 2203 | (struct ucc_geth_82xx_address_filtering_pram *) ugeth->p_rx_glbl_pram-> |
2220 | addressfiltering; | 2204 | addressfiltering; |
2221 | 2205 | ||
2222 | if (! | 2206 | if (! |
@@ -2256,9 +2240,9 @@ static int ugeth_82xx_filtering_clear_addr_in_hash(ucc_geth_private_t *ugeth, | |||
2256 | num = --(*p_counter); | 2240 | num = --(*p_counter); |
2257 | for (i = 0; i < num; i++) { | 2241 | for (i = 0; i < num; i++) { |
2258 | enet_addr_cont = | 2242 | enet_addr_cont = |
2259 | (enet_addr_container_t *) | 2243 | (struct enet_addr_container *) |
2260 | ENET_ADDR_CONT_ENTRY(dequeue(p_lh)); | 2244 | ENET_ADDR_CONT_ENTRY(dequeue(p_lh)); |
2261 | hw_add_addr_in_hash(ugeth, &(enet_addr_cont->address)); | 2245 | hw_add_addr_in_hash(ugeth, enet_addr_cont->address); |
2262 | enqueue(p_lh, &enet_addr_cont->node); /* Put it back */ | 2246 | enqueue(p_lh, &enet_addr_cont->node); /* Put it back */ |
2263 | } | 2247 | } |
2264 | 2248 | ||
@@ -2269,14 +2253,14 @@ static int ugeth_82xx_filtering_clear_addr_in_hash(ucc_geth_private_t *ugeth, | |||
2269 | } | 2253 | } |
2270 | #endif /* CONFIG_UGETH_FILTERING */ | 2254 | #endif /* CONFIG_UGETH_FILTERING */ |
2271 | 2255 | ||
2272 | static int ugeth_82xx_filtering_clear_all_addr_in_hash(ucc_geth_private_t * | 2256 | static int ugeth_82xx_filtering_clear_all_addr_in_hash(struct ucc_geth_private * |
2273 | ugeth, | 2257 | ugeth, |
2274 | enet_addr_type_e | 2258 | enum enet_addr_type |
2275 | enet_addr_type) | 2259 | enet_addr_type) |
2276 | { | 2260 | { |
2277 | ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt; | 2261 | struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt; |
2278 | ucc_fast_private_t *uccf; | 2262 | struct ucc_fast_private *uccf; |
2279 | comm_dir_e comm_dir; | 2263 | enum comm_dir comm_dir; |
2280 | struct list_head *p_lh; | 2264 | struct list_head *p_lh; |
2281 | u16 i, num; | 2265 | u16 i, num; |
2282 | u32 *addr_h, *addr_l; | 2266 | u32 *addr_h, *addr_l; |
@@ -2285,7 +2269,7 @@ static int ugeth_82xx_filtering_clear_all_addr_in_hash(ucc_geth_private_t * | |||
2285 | uccf = ugeth->uccf; | 2269 | uccf = ugeth->uccf; |
2286 | 2270 | ||
2287 | p_82xx_addr_filt = | 2271 | p_82xx_addr_filt = |
2288 | (ucc_geth_82xx_address_filtering_pram_t *) ugeth->p_rx_glbl_pram-> | 2272 | (struct ucc_geth_82xx_address_filtering_pram *) ugeth->p_rx_glbl_pram-> |
2289 | addressfiltering; | 2273 | addressfiltering; |
2290 | 2274 | ||
2291 | if (enet_addr_type == ENET_ADDR_TYPE_GROUP) { | 2275 | if (enet_addr_type == ENET_ADDR_TYPE_GROUP) { |
@@ -2331,8 +2315,8 @@ static int ugeth_82xx_filtering_clear_all_addr_in_hash(ucc_geth_private_t * | |||
2331 | } | 2315 | } |
2332 | 2316 | ||
2333 | #ifdef CONFIG_UGETH_FILTERING | 2317 | #ifdef CONFIG_UGETH_FILTERING |
2334 | static int ugeth_82xx_filtering_add_addr_in_paddr(ucc_geth_private_t *ugeth, | 2318 | static int ugeth_82xx_filtering_add_addr_in_paddr(struct ucc_geth_private *ugeth, |
2335 | enet_addr_t *p_enet_addr, | 2319 | struct enet_addr *p_enet_addr, |
2336 | u8 paddr_num) | 2320 | u8 paddr_num) |
2337 | { | 2321 | { |
2338 | int i; | 2322 | int i; |
@@ -2352,14 +2336,14 @@ static int ugeth_82xx_filtering_add_addr_in_paddr(ucc_geth_private_t *ugeth, | |||
2352 | } | 2336 | } |
2353 | #endif /* CONFIG_UGETH_FILTERING */ | 2337 | #endif /* CONFIG_UGETH_FILTERING */ |
2354 | 2338 | ||
2355 | static int ugeth_82xx_filtering_clear_addr_in_paddr(ucc_geth_private_t *ugeth, | 2339 | static int ugeth_82xx_filtering_clear_addr_in_paddr(struct ucc_geth_private *ugeth, |
2356 | u8 paddr_num) | 2340 | u8 paddr_num) |
2357 | { | 2341 | { |
2358 | ugeth->indAddrRegUsed[paddr_num] = 0; /* mark this paddr as not used */ | 2342 | ugeth->indAddrRegUsed[paddr_num] = 0; /* mark this paddr as not used */ |
2359 | return hw_clear_addr_in_paddr(ugeth, paddr_num);/* clear in hardware */ | 2343 | return hw_clear_addr_in_paddr(ugeth, paddr_num);/* clear in hardware */ |
2360 | } | 2344 | } |
2361 | 2345 | ||
2362 | static void ucc_geth_memclean(ucc_geth_private_t *ugeth) | 2346 | static void ucc_geth_memclean(struct ucc_geth_private *ugeth) |
2363 | { | 2347 | { |
2364 | u16 i, j; | 2348 | u16 i, j; |
2365 | u8 *bd; | 2349 | u8 *bd; |
@@ -2433,8 +2417,8 @@ static void ucc_geth_memclean(ucc_geth_private_t *ugeth) | |||
2433 | for (j = 0; j < ugeth->ug_info->bdRingLenTx[i]; j++) { | 2417 | for (j = 0; j < ugeth->ug_info->bdRingLenTx[i]; j++) { |
2434 | if (ugeth->tx_skbuff[i][j]) { | 2418 | if (ugeth->tx_skbuff[i][j]) { |
2435 | dma_unmap_single(NULL, | 2419 | dma_unmap_single(NULL, |
2436 | BD_BUFFER_ARG(bd), | 2420 | ((qe_bd_t *)bd)->buf, |
2437 | (BD_STATUS_AND_LENGTH(bd) & | 2421 | (in_be32((u32 *)bd) & |
2438 | BD_LENGTH_MASK), | 2422 | BD_LENGTH_MASK), |
2439 | DMA_TO_DEVICE); | 2423 | DMA_TO_DEVICE); |
2440 | dev_kfree_skb_any(ugeth->tx_skbuff[i][j]); | 2424 | dev_kfree_skb_any(ugeth->tx_skbuff[i][j]); |
@@ -2460,18 +2444,17 @@ static void ucc_geth_memclean(ucc_geth_private_t *ugeth) | |||
2460 | bd = ugeth->p_rx_bd_ring[i]; | 2444 | bd = ugeth->p_rx_bd_ring[i]; |
2461 | for (j = 0; j < ugeth->ug_info->bdRingLenRx[i]; j++) { | 2445 | for (j = 0; j < ugeth->ug_info->bdRingLenRx[i]; j++) { |
2462 | if (ugeth->rx_skbuff[i][j]) { | 2446 | if (ugeth->rx_skbuff[i][j]) { |
2463 | dma_unmap_single(NULL, BD_BUFFER(bd), | 2447 | dma_unmap_single(NULL, |
2464 | ugeth->ug_info-> | 2448 | ((struct qe_bd *)bd)->buf, |
2465 | uf_info. | 2449 | ugeth->ug_info-> |
2466 | max_rx_buf_length + | 2450 | uf_info.max_rx_buf_length + |
2467 | UCC_GETH_RX_DATA_BUF_ALIGNMENT, | 2451 | UCC_GETH_RX_DATA_BUF_ALIGNMENT, |
2468 | DMA_FROM_DEVICE); | 2452 | DMA_FROM_DEVICE); |
2469 | 2453 | dev_kfree_skb_any( | |
2470 | dev_kfree_skb_any(ugeth-> | 2454 | ugeth->rx_skbuff[i][j]); |
2471 | rx_skbuff[i][j]); | ||
2472 | ugeth->rx_skbuff[i][j] = NULL; | 2455 | ugeth->rx_skbuff[i][j] = NULL; |
2473 | } | 2456 | } |
2474 | bd += UCC_GETH_SIZE_OF_BD; | 2457 | bd += sizeof(struct qe_bd); |
2475 | } | 2458 | } |
2476 | 2459 | ||
2477 | kfree(ugeth->rx_skbuff[i]); | 2460 | kfree(ugeth->rx_skbuff[i]); |
@@ -2496,11 +2479,11 @@ static void ucc_geth_memclean(ucc_geth_private_t *ugeth) | |||
2496 | 2479 | ||
2497 | static void ucc_geth_set_multi(struct net_device *dev) | 2480 | static void ucc_geth_set_multi(struct net_device *dev) |
2498 | { | 2481 | { |
2499 | ucc_geth_private_t *ugeth; | 2482 | struct ucc_geth_private *ugeth; |
2500 | struct dev_mc_list *dmi; | 2483 | struct dev_mc_list *dmi; |
2501 | ucc_fast_t *uf_regs; | 2484 | struct ucc_fast *uf_regs; |
2502 | ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt; | 2485 | struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt; |
2503 | enet_addr_t tempaddr; | 2486 | u8 tempaddr[6]; |
2504 | u8 *mcptr, *tdptr; | 2487 | u8 *mcptr, *tdptr; |
2505 | int i, j; | 2488 | int i, j; |
2506 | 2489 | ||
@@ -2517,7 +2500,7 @@ static void ucc_geth_set_multi(struct net_device *dev) | |||
2517 | uf_regs->upsmr &= ~UPSMR_PRO; | 2500 | uf_regs->upsmr &= ~UPSMR_PRO; |
2518 | 2501 | ||
2519 | p_82xx_addr_filt = | 2502 | p_82xx_addr_filt = |
2520 | (ucc_geth_82xx_address_filtering_pram_t *) ugeth-> | 2503 | (struct ucc_geth_82xx_address_filtering_pram *) ugeth-> |
2521 | p_rx_glbl_pram->addressfiltering; | 2504 | p_rx_glbl_pram->addressfiltering; |
2522 | 2505 | ||
2523 | if (dev->flags & IFF_ALLMULTI) { | 2506 | if (dev->flags & IFF_ALLMULTI) { |
@@ -2546,23 +2529,22 @@ static void ucc_geth_set_multi(struct net_device *dev) | |||
2546 | * copy bytes MSB first from dmi_addr. | 2529 | * copy bytes MSB first from dmi_addr. |
2547 | */ | 2530 | */ |
2548 | mcptr = (u8 *) dmi->dmi_addr + 5; | 2531 | mcptr = (u8 *) dmi->dmi_addr + 5; |
2549 | tdptr = (u8 *) & tempaddr; | 2532 | tdptr = (u8 *) tempaddr; |
2550 | for (j = 0; j < 6; j++) | 2533 | for (j = 0; j < 6; j++) |
2551 | *tdptr++ = *mcptr--; | 2534 | *tdptr++ = *mcptr--; |
2552 | 2535 | ||
2553 | /* Ask CPM to run CRC and set bit in | 2536 | /* Ask CPM to run CRC and set bit in |
2554 | * filter mask. | 2537 | * filter mask. |
2555 | */ | 2538 | */ |
2556 | hw_add_addr_in_hash(ugeth, &tempaddr); | 2539 | hw_add_addr_in_hash(ugeth, tempaddr); |
2557 | |||
2558 | } | 2540 | } |
2559 | } | 2541 | } |
2560 | } | 2542 | } |
2561 | } | 2543 | } |
2562 | 2544 | ||
2563 | static void ucc_geth_stop(ucc_geth_private_t *ugeth) | 2545 | static void ucc_geth_stop(struct ucc_geth_private *ugeth) |
2564 | { | 2546 | { |
2565 | ucc_geth_t *ug_regs = ugeth->ug_regs; | 2547 | struct ucc_geth *ug_regs = ugeth->ug_regs; |
2566 | u32 tempval; | 2548 | u32 tempval; |
2567 | 2549 | ||
2568 | ugeth_vdbg("%s: IN", __FUNCTION__); | 2550 | ugeth_vdbg("%s: IN", __FUNCTION__); |
@@ -2605,15 +2587,15 @@ static void ucc_geth_stop(ucc_geth_private_t *ugeth) | |||
2605 | ucc_geth_memclean(ugeth); | 2587 | ucc_geth_memclean(ugeth); |
2606 | } | 2588 | } |
2607 | 2589 | ||
2608 | static int ucc_geth_startup(ucc_geth_private_t *ugeth) | 2590 | static int ucc_geth_startup(struct ucc_geth_private *ugeth) |
2609 | { | 2591 | { |
2610 | ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt; | 2592 | struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt; |
2611 | ucc_geth_init_pram_t *p_init_enet_pram; | 2593 | struct ucc_geth_init_pram *p_init_enet_pram; |
2612 | ucc_fast_private_t *uccf; | 2594 | struct ucc_fast_private *uccf; |
2613 | ucc_geth_info_t *ug_info; | 2595 | struct ucc_geth_info *ug_info; |
2614 | ucc_fast_info_t *uf_info; | 2596 | struct ucc_fast_info *uf_info; |
2615 | ucc_fast_t *uf_regs; | 2597 | struct ucc_fast *uf_regs; |
2616 | ucc_geth_t *ug_regs; | 2598 | struct ucc_geth *ug_regs; |
2617 | int ret_val = -EINVAL; | 2599 | int ret_val = -EINVAL; |
2618 | u32 remoder = UCC_GETH_REMODER_INIT; | 2600 | u32 remoder = UCC_GETH_REMODER_INIT; |
2619 | u32 init_enet_pram_offset, cecr_subblock, command, maccfg1; | 2601 | u32 init_enet_pram_offset, cecr_subblock, command, maccfg1; |
@@ -2788,7 +2770,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) | |||
2788 | UCC_GETH_VLAN_OPERATION_NON_TAGGED_NOP); | 2770 | UCC_GETH_VLAN_OPERATION_NON_TAGGED_NOP); |
2789 | 2771 | ||
2790 | uf_regs = uccf->uf_regs; | 2772 | uf_regs = uccf->uf_regs; |
2791 | ug_regs = (ucc_geth_t *) (uccf->uf_regs); | 2773 | ug_regs = (struct ucc_geth *) (uccf->uf_regs); |
2792 | ugeth->ug_regs = ug_regs; | 2774 | ugeth->ug_regs = ug_regs; |
2793 | 2775 | ||
2794 | init_default_reg_vals(&uf_regs->upsmr, | 2776 | init_default_reg_vals(&uf_regs->upsmr, |
@@ -2869,10 +2851,10 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) | |||
2869 | /* Allocate in multiple of | 2851 | /* Allocate in multiple of |
2870 | UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT, | 2852 | UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT, |
2871 | according to spec */ | 2853 | according to spec */ |
2872 | length = ((ug_info->bdRingLenTx[j] * UCC_GETH_SIZE_OF_BD) | 2854 | length = ((ug_info->bdRingLenTx[j] * sizeof(struct qe_bd)) |
2873 | / UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT) | 2855 | / UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT) |
2874 | * UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT; | 2856 | * UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT; |
2875 | if ((ug_info->bdRingLenTx[j] * UCC_GETH_SIZE_OF_BD) % | 2857 | if ((ug_info->bdRingLenTx[j] * sizeof(struct qe_bd)) % |
2876 | UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT) | 2858 | UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT) |
2877 | length += UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT; | 2859 | length += UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT; |
2878 | if (uf_info->bd_mem_part == MEM_PART_SYSTEM) { | 2860 | if (uf_info->bd_mem_part == MEM_PART_SYSTEM) { |
@@ -2904,13 +2886,13 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) | |||
2904 | } | 2886 | } |
2905 | /* Zero unused end of bd ring, according to spec */ | 2887 | /* Zero unused end of bd ring, according to spec */ |
2906 | memset(ugeth->p_tx_bd_ring[j] + | 2888 | memset(ugeth->p_tx_bd_ring[j] + |
2907 | ug_info->bdRingLenTx[j] * UCC_GETH_SIZE_OF_BD, 0, | 2889 | ug_info->bdRingLenTx[j] * sizeof(struct qe_bd), 0, |
2908 | length - ug_info->bdRingLenTx[j] * UCC_GETH_SIZE_OF_BD); | 2890 | length - ug_info->bdRingLenTx[j] * sizeof(struct qe_bd)); |
2909 | } | 2891 | } |
2910 | 2892 | ||
2911 | /* Allocate Rx bds */ | 2893 | /* Allocate Rx bds */ |
2912 | for (j = 0; j < ug_info->numQueuesRx; j++) { | 2894 | for (j = 0; j < ug_info->numQueuesRx; j++) { |
2913 | length = ug_info->bdRingLenRx[j] * UCC_GETH_SIZE_OF_BD; | 2895 | length = ug_info->bdRingLenRx[j] * sizeof(struct qe_bd); |
2914 | if (uf_info->bd_mem_part == MEM_PART_SYSTEM) { | 2896 | if (uf_info->bd_mem_part == MEM_PART_SYSTEM) { |
2915 | u32 align = 4; | 2897 | u32 align = 4; |
2916 | if (UCC_GETH_RX_BD_RING_ALIGNMENT > 4) | 2898 | if (UCC_GETH_RX_BD_RING_ALIGNMENT > 4) |
@@ -2960,12 +2942,15 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) | |||
2960 | ugeth->skb_curtx[j] = ugeth->skb_dirtytx[j] = 0; | 2942 | ugeth->skb_curtx[j] = ugeth->skb_dirtytx[j] = 0; |
2961 | bd = ugeth->confBd[j] = ugeth->txBd[j] = ugeth->p_tx_bd_ring[j]; | 2943 | bd = ugeth->confBd[j] = ugeth->txBd[j] = ugeth->p_tx_bd_ring[j]; |
2962 | for (i = 0; i < ug_info->bdRingLenTx[j]; i++) { | 2944 | for (i = 0; i < ug_info->bdRingLenTx[j]; i++) { |
2963 | BD_BUFFER_CLEAR(bd); | 2945 | /* clear bd buffer */ |
2964 | BD_STATUS_AND_LENGTH_SET(bd, 0); | 2946 | out_be32(&((struct qe_bd *)bd)->buf, 0); |
2965 | bd += UCC_GETH_SIZE_OF_BD; | 2947 | /* set bd status and length */ |
2948 | out_be32((u32 *)bd, 0); | ||
2949 | bd += sizeof(struct qe_bd); | ||
2966 | } | 2950 | } |
2967 | bd -= UCC_GETH_SIZE_OF_BD; | 2951 | bd -= sizeof(struct qe_bd); |
2968 | BD_STATUS_AND_LENGTH_SET(bd, T_W);/* for last BD set Wrap bit */ | 2952 | /* set bd status and length */ |
2953 | out_be32((u32 *)bd, T_W); /* for last BD set Wrap bit */ | ||
2969 | } | 2954 | } |
2970 | 2955 | ||
2971 | /* Init Rx bds */ | 2956 | /* Init Rx bds */ |
@@ -2989,12 +2974,15 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) | |||
2989 | ugeth->skb_currx[j] = 0; | 2974 | ugeth->skb_currx[j] = 0; |
2990 | bd = ugeth->rxBd[j] = ugeth->p_rx_bd_ring[j]; | 2975 | bd = ugeth->rxBd[j] = ugeth->p_rx_bd_ring[j]; |
2991 | for (i = 0; i < ug_info->bdRingLenRx[j]; i++) { | 2976 | for (i = 0; i < ug_info->bdRingLenRx[j]; i++) { |
2992 | BD_STATUS_AND_LENGTH_SET(bd, R_I); | 2977 | /* set bd status and length */ |
2993 | BD_BUFFER_CLEAR(bd); | 2978 | out_be32((u32 *)bd, R_I); |
2994 | bd += UCC_GETH_SIZE_OF_BD; | 2979 | /* clear bd buffer */ |
2980 | out_be32(&((struct qe_bd *)bd)->buf, 0); | ||
2981 | bd += sizeof(struct qe_bd); | ||
2995 | } | 2982 | } |
2996 | bd -= UCC_GETH_SIZE_OF_BD; | 2983 | bd -= sizeof(struct qe_bd); |
2997 | BD_STATUS_AND_LENGTH_SET(bd, R_W);/* for last BD set Wrap bit */ | 2984 | /* set bd status and length */ |
2985 | out_be32((u32 *)bd, R_W); /* for last BD set Wrap bit */ | ||
2998 | } | 2986 | } |
2999 | 2987 | ||
3000 | /* | 2988 | /* |
@@ -3003,7 +2991,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) | |||
3003 | /* Tx global PRAM */ | 2991 | /* Tx global PRAM */ |
3004 | /* Allocate global tx parameter RAM page */ | 2992 | /* Allocate global tx parameter RAM page */ |
3005 | ugeth->tx_glbl_pram_offset = | 2993 | ugeth->tx_glbl_pram_offset = |
3006 | qe_muram_alloc(sizeof(ucc_geth_tx_global_pram_t), | 2994 | qe_muram_alloc(sizeof(struct ucc_geth_tx_global_pram), |
3007 | UCC_GETH_TX_GLOBAL_PRAM_ALIGNMENT); | 2995 | UCC_GETH_TX_GLOBAL_PRAM_ALIGNMENT); |
3008 | if (IS_MURAM_ERR(ugeth->tx_glbl_pram_offset)) { | 2996 | if (IS_MURAM_ERR(ugeth->tx_glbl_pram_offset)) { |
3009 | ugeth_err | 2997 | ugeth_err |
@@ -3013,10 +3001,10 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) | |||
3013 | return -ENOMEM; | 3001 | return -ENOMEM; |
3014 | } | 3002 | } |
3015 | ugeth->p_tx_glbl_pram = | 3003 | ugeth->p_tx_glbl_pram = |
3016 | (ucc_geth_tx_global_pram_t *) qe_muram_addr(ugeth-> | 3004 | (struct ucc_geth_tx_global_pram *) qe_muram_addr(ugeth-> |
3017 | tx_glbl_pram_offset); | 3005 | tx_glbl_pram_offset); |
3018 | /* Zero out p_tx_glbl_pram */ | 3006 | /* Zero out p_tx_glbl_pram */ |
3019 | memset(ugeth->p_tx_glbl_pram, 0, sizeof(ucc_geth_tx_global_pram_t)); | 3007 | memset(ugeth->p_tx_glbl_pram, 0, sizeof(struct ucc_geth_tx_global_pram)); |
3020 | 3008 | ||
3021 | /* Fill global PRAM */ | 3009 | /* Fill global PRAM */ |
3022 | 3010 | ||
@@ -3024,7 +3012,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) | |||
3024 | /* Size varies with number of Tx threads */ | 3012 | /* Size varies with number of Tx threads */ |
3025 | ugeth->thread_dat_tx_offset = | 3013 | ugeth->thread_dat_tx_offset = |
3026 | qe_muram_alloc(numThreadsTxNumerical * | 3014 | qe_muram_alloc(numThreadsTxNumerical * |
3027 | sizeof(ucc_geth_thread_data_tx_t) + | 3015 | sizeof(struct ucc_geth_thread_data_tx) + |
3028 | 32 * (numThreadsTxNumerical == 1), | 3016 | 32 * (numThreadsTxNumerical == 1), |
3029 | UCC_GETH_THREAD_DATA_ALIGNMENT); | 3017 | UCC_GETH_THREAD_DATA_ALIGNMENT); |
3030 | if (IS_MURAM_ERR(ugeth->thread_dat_tx_offset)) { | 3018 | if (IS_MURAM_ERR(ugeth->thread_dat_tx_offset)) { |
@@ -3036,7 +3024,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) | |||
3036 | } | 3024 | } |
3037 | 3025 | ||
3038 | ugeth->p_thread_data_tx = | 3026 | ugeth->p_thread_data_tx = |
3039 | (ucc_geth_thread_data_tx_t *) qe_muram_addr(ugeth-> | 3027 | (struct ucc_geth_thread_data_tx *) qe_muram_addr(ugeth-> |
3040 | thread_dat_tx_offset); | 3028 | thread_dat_tx_offset); |
3041 | out_be32(&ugeth->p_tx_glbl_pram->tqptr, ugeth->thread_dat_tx_offset); | 3029 | out_be32(&ugeth->p_tx_glbl_pram->tqptr, ugeth->thread_dat_tx_offset); |
3042 | 3030 | ||
@@ -3053,7 +3041,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) | |||
3053 | /* Size varies with number of Tx queues */ | 3041 | /* Size varies with number of Tx queues */ |
3054 | ugeth->send_q_mem_reg_offset = | 3042 | ugeth->send_q_mem_reg_offset = |
3055 | qe_muram_alloc(ug_info->numQueuesTx * | 3043 | qe_muram_alloc(ug_info->numQueuesTx * |
3056 | sizeof(ucc_geth_send_queue_qd_t), | 3044 | sizeof(struct ucc_geth_send_queue_qd), |
3057 | UCC_GETH_SEND_QUEUE_QUEUE_DESCRIPTOR_ALIGNMENT); | 3045 | UCC_GETH_SEND_QUEUE_QUEUE_DESCRIPTOR_ALIGNMENT); |
3058 | if (IS_MURAM_ERR(ugeth->send_q_mem_reg_offset)) { | 3046 | if (IS_MURAM_ERR(ugeth->send_q_mem_reg_offset)) { |
3059 | ugeth_err | 3047 | ugeth_err |
@@ -3064,7 +3052,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) | |||
3064 | } | 3052 | } |
3065 | 3053 | ||
3066 | ugeth->p_send_q_mem_reg = | 3054 | ugeth->p_send_q_mem_reg = |
3067 | (ucc_geth_send_queue_mem_region_t *) qe_muram_addr(ugeth-> | 3055 | (struct ucc_geth_send_queue_mem_region *) qe_muram_addr(ugeth-> |
3068 | send_q_mem_reg_offset); | 3056 | send_q_mem_reg_offset); |
3069 | out_be32(&ugeth->p_tx_glbl_pram->sqptr, ugeth->send_q_mem_reg_offset); | 3057 | out_be32(&ugeth->p_tx_glbl_pram->sqptr, ugeth->send_q_mem_reg_offset); |
3070 | 3058 | ||
@@ -3073,7 +3061,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) | |||
3073 | for (i = 0; i < ug_info->numQueuesTx; i++) { | 3061 | for (i = 0; i < ug_info->numQueuesTx; i++) { |
3074 | endOfRing = | 3062 | endOfRing = |
3075 | ugeth->p_tx_bd_ring[i] + (ug_info->bdRingLenTx[i] - | 3063 | ugeth->p_tx_bd_ring[i] + (ug_info->bdRingLenTx[i] - |
3076 | 1) * UCC_GETH_SIZE_OF_BD; | 3064 | 1) * sizeof(struct qe_bd); |
3077 | if (ugeth->ug_info->uf_info.bd_mem_part == MEM_PART_SYSTEM) { | 3065 | if (ugeth->ug_info->uf_info.bd_mem_part == MEM_PART_SYSTEM) { |
3078 | out_be32(&ugeth->p_send_q_mem_reg->sqqd[i].bd_ring_base, | 3066 | out_be32(&ugeth->p_send_q_mem_reg->sqqd[i].bd_ring_base, |
3079 | (u32) virt_to_phys(ugeth->p_tx_bd_ring[i])); | 3067 | (u32) virt_to_phys(ugeth->p_tx_bd_ring[i])); |
@@ -3096,7 +3084,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) | |||
3096 | if (ug_info->numQueuesTx > 1) { | 3084 | if (ug_info->numQueuesTx > 1) { |
3097 | /* scheduler exists only if more than 1 tx queue */ | 3085 | /* scheduler exists only if more than 1 tx queue */ |
3098 | ugeth->scheduler_offset = | 3086 | ugeth->scheduler_offset = |
3099 | qe_muram_alloc(sizeof(ucc_geth_scheduler_t), | 3087 | qe_muram_alloc(sizeof(struct ucc_geth_scheduler), |
3100 | UCC_GETH_SCHEDULER_ALIGNMENT); | 3088 | UCC_GETH_SCHEDULER_ALIGNMENT); |
3101 | if (IS_MURAM_ERR(ugeth->scheduler_offset)) { | 3089 | if (IS_MURAM_ERR(ugeth->scheduler_offset)) { |
3102 | ugeth_err | 3090 | ugeth_err |
@@ -3107,12 +3095,12 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) | |||
3107 | } | 3095 | } |
3108 | 3096 | ||
3109 | ugeth->p_scheduler = | 3097 | ugeth->p_scheduler = |
3110 | (ucc_geth_scheduler_t *) qe_muram_addr(ugeth-> | 3098 | (struct ucc_geth_scheduler *) qe_muram_addr(ugeth-> |
3111 | scheduler_offset); | 3099 | scheduler_offset); |
3112 | out_be32(&ugeth->p_tx_glbl_pram->schedulerbasepointer, | 3100 | out_be32(&ugeth->p_tx_glbl_pram->schedulerbasepointer, |
3113 | ugeth->scheduler_offset); | 3101 | ugeth->scheduler_offset); |
3114 | /* Zero out p_scheduler */ | 3102 | /* Zero out p_scheduler */ |
3115 | memset(ugeth->p_scheduler, 0, sizeof(ucc_geth_scheduler_t)); | 3103 | memset(ugeth->p_scheduler, 0, sizeof(struct ucc_geth_scheduler)); |
3116 | 3104 | ||
3117 | /* Set values in scheduler */ | 3105 | /* Set values in scheduler */ |
3118 | out_be32(&ugeth->p_scheduler->mblinterval, | 3106 | out_be32(&ugeth->p_scheduler->mblinterval, |
@@ -3144,7 +3132,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) | |||
3144 | statisticsMode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_TX) { | 3132 | statisticsMode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_TX) { |
3145 | ugeth->tx_fw_statistics_pram_offset = | 3133 | ugeth->tx_fw_statistics_pram_offset = |
3146 | qe_muram_alloc(sizeof | 3134 | qe_muram_alloc(sizeof |
3147 | (ucc_geth_tx_firmware_statistics_pram_t), | 3135 | (struct ucc_geth_tx_firmware_statistics_pram), |
3148 | UCC_GETH_TX_STATISTICS_ALIGNMENT); | 3136 | UCC_GETH_TX_STATISTICS_ALIGNMENT); |
3149 | if (IS_MURAM_ERR(ugeth->tx_fw_statistics_pram_offset)) { | 3137 | if (IS_MURAM_ERR(ugeth->tx_fw_statistics_pram_offset)) { |
3150 | ugeth_err | 3138 | ugeth_err |
@@ -3154,11 +3142,11 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) | |||
3154 | return -ENOMEM; | 3142 | return -ENOMEM; |
3155 | } | 3143 | } |
3156 | ugeth->p_tx_fw_statistics_pram = | 3144 | ugeth->p_tx_fw_statistics_pram = |
3157 | (ucc_geth_tx_firmware_statistics_pram_t *) | 3145 | (struct ucc_geth_tx_firmware_statistics_pram *) |
3158 | qe_muram_addr(ugeth->tx_fw_statistics_pram_offset); | 3146 | qe_muram_addr(ugeth->tx_fw_statistics_pram_offset); |
3159 | /* Zero out p_tx_fw_statistics_pram */ | 3147 | /* Zero out p_tx_fw_statistics_pram */ |
3160 | memset(ugeth->p_tx_fw_statistics_pram, | 3148 | memset(ugeth->p_tx_fw_statistics_pram, |
3161 | 0, sizeof(ucc_geth_tx_firmware_statistics_pram_t)); | 3149 | 0, sizeof(struct ucc_geth_tx_firmware_statistics_pram)); |
3162 | } | 3150 | } |
3163 | 3151 | ||
3164 | /* temoder */ | 3152 | /* temoder */ |
@@ -3183,7 +3171,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) | |||
3183 | /* Rx global PRAM */ | 3171 | /* Rx global PRAM */ |
3184 | /* Allocate global rx parameter RAM page */ | 3172 | /* Allocate global rx parameter RAM page */ |
3185 | ugeth->rx_glbl_pram_offset = | 3173 | ugeth->rx_glbl_pram_offset = |
3186 | qe_muram_alloc(sizeof(ucc_geth_rx_global_pram_t), | 3174 | qe_muram_alloc(sizeof(struct ucc_geth_rx_global_pram), |
3187 | UCC_GETH_RX_GLOBAL_PRAM_ALIGNMENT); | 3175 | UCC_GETH_RX_GLOBAL_PRAM_ALIGNMENT); |
3188 | if (IS_MURAM_ERR(ugeth->rx_glbl_pram_offset)) { | 3176 | if (IS_MURAM_ERR(ugeth->rx_glbl_pram_offset)) { |
3189 | ugeth_err | 3177 | ugeth_err |
@@ -3193,10 +3181,10 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) | |||
3193 | return -ENOMEM; | 3181 | return -ENOMEM; |
3194 | } | 3182 | } |
3195 | ugeth->p_rx_glbl_pram = | 3183 | ugeth->p_rx_glbl_pram = |
3196 | (ucc_geth_rx_global_pram_t *) qe_muram_addr(ugeth-> | 3184 | (struct ucc_geth_rx_global_pram *) qe_muram_addr(ugeth-> |
3197 | rx_glbl_pram_offset); | 3185 | rx_glbl_pram_offset); |
3198 | /* Zero out p_rx_glbl_pram */ | 3186 | /* Zero out p_rx_glbl_pram */ |
3199 | memset(ugeth->p_rx_glbl_pram, 0, sizeof(ucc_geth_rx_global_pram_t)); | 3187 | memset(ugeth->p_rx_glbl_pram, 0, sizeof(struct ucc_geth_rx_global_pram)); |
3200 | 3188 | ||
3201 | /* Fill global PRAM */ | 3189 | /* Fill global PRAM */ |
3202 | 3190 | ||
@@ -3204,7 +3192,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) | |||
3204 | /* Size varies with number of Rx threads */ | 3192 | /* Size varies with number of Rx threads */ |
3205 | ugeth->thread_dat_rx_offset = | 3193 | ugeth->thread_dat_rx_offset = |
3206 | qe_muram_alloc(numThreadsRxNumerical * | 3194 | qe_muram_alloc(numThreadsRxNumerical * |
3207 | sizeof(ucc_geth_thread_data_rx_t), | 3195 | sizeof(struct ucc_geth_thread_data_rx), |
3208 | UCC_GETH_THREAD_DATA_ALIGNMENT); | 3196 | UCC_GETH_THREAD_DATA_ALIGNMENT); |
3209 | if (IS_MURAM_ERR(ugeth->thread_dat_rx_offset)) { | 3197 | if (IS_MURAM_ERR(ugeth->thread_dat_rx_offset)) { |
3210 | ugeth_err | 3198 | ugeth_err |
@@ -3215,7 +3203,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) | |||
3215 | } | 3203 | } |
3216 | 3204 | ||
3217 | ugeth->p_thread_data_rx = | 3205 | ugeth->p_thread_data_rx = |
3218 | (ucc_geth_thread_data_rx_t *) qe_muram_addr(ugeth-> | 3206 | (struct ucc_geth_thread_data_rx *) qe_muram_addr(ugeth-> |
3219 | thread_dat_rx_offset); | 3207 | thread_dat_rx_offset); |
3220 | out_be32(&ugeth->p_rx_glbl_pram->rqptr, ugeth->thread_dat_rx_offset); | 3208 | out_be32(&ugeth->p_rx_glbl_pram->rqptr, ugeth->thread_dat_rx_offset); |
3221 | 3209 | ||
@@ -3227,7 +3215,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) | |||
3227 | statisticsMode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_RX) { | 3215 | statisticsMode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_RX) { |
3228 | ugeth->rx_fw_statistics_pram_offset = | 3216 | ugeth->rx_fw_statistics_pram_offset = |
3229 | qe_muram_alloc(sizeof | 3217 | qe_muram_alloc(sizeof |
3230 | (ucc_geth_rx_firmware_statistics_pram_t), | 3218 | (struct ucc_geth_rx_firmware_statistics_pram), |
3231 | UCC_GETH_RX_STATISTICS_ALIGNMENT); | 3219 | UCC_GETH_RX_STATISTICS_ALIGNMENT); |
3232 | if (IS_MURAM_ERR(ugeth->rx_fw_statistics_pram_offset)) { | 3220 | if (IS_MURAM_ERR(ugeth->rx_fw_statistics_pram_offset)) { |
3233 | ugeth_err | 3221 | ugeth_err |
@@ -3237,11 +3225,11 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) | |||
3237 | return -ENOMEM; | 3225 | return -ENOMEM; |
3238 | } | 3226 | } |
3239 | ugeth->p_rx_fw_statistics_pram = | 3227 | ugeth->p_rx_fw_statistics_pram = |
3240 | (ucc_geth_rx_firmware_statistics_pram_t *) | 3228 | (struct ucc_geth_rx_firmware_statistics_pram *) |
3241 | qe_muram_addr(ugeth->rx_fw_statistics_pram_offset); | 3229 | qe_muram_addr(ugeth->rx_fw_statistics_pram_offset); |
3242 | /* Zero out p_rx_fw_statistics_pram */ | 3230 | /* Zero out p_rx_fw_statistics_pram */ |
3243 | memset(ugeth->p_rx_fw_statistics_pram, 0, | 3231 | memset(ugeth->p_rx_fw_statistics_pram, 0, |
3244 | sizeof(ucc_geth_rx_firmware_statistics_pram_t)); | 3232 | sizeof(struct ucc_geth_rx_firmware_statistics_pram)); |
3245 | } | 3233 | } |
3246 | 3234 | ||
3247 | /* intCoalescingPtr */ | 3235 | /* intCoalescingPtr */ |
@@ -3249,7 +3237,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) | |||
3249 | /* Size varies with number of Rx queues */ | 3237 | /* Size varies with number of Rx queues */ |
3250 | ugeth->rx_irq_coalescing_tbl_offset = | 3238 | ugeth->rx_irq_coalescing_tbl_offset = |
3251 | qe_muram_alloc(ug_info->numQueuesRx * | 3239 | qe_muram_alloc(ug_info->numQueuesRx * |
3252 | sizeof(ucc_geth_rx_interrupt_coalescing_entry_t), | 3240 | sizeof(struct ucc_geth_rx_interrupt_coalescing_entry), |
3253 | UCC_GETH_RX_INTERRUPT_COALESCING_ALIGNMENT); | 3241 | UCC_GETH_RX_INTERRUPT_COALESCING_ALIGNMENT); |
3254 | if (IS_MURAM_ERR(ugeth->rx_irq_coalescing_tbl_offset)) { | 3242 | if (IS_MURAM_ERR(ugeth->rx_irq_coalescing_tbl_offset)) { |
3255 | ugeth_err | 3243 | ugeth_err |
@@ -3260,7 +3248,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) | |||
3260 | } | 3248 | } |
3261 | 3249 | ||
3262 | ugeth->p_rx_irq_coalescing_tbl = | 3250 | ugeth->p_rx_irq_coalescing_tbl = |
3263 | (ucc_geth_rx_interrupt_coalescing_table_t *) | 3251 | (struct ucc_geth_rx_interrupt_coalescing_table *) |
3264 | qe_muram_addr(ugeth->rx_irq_coalescing_tbl_offset); | 3252 | qe_muram_addr(ugeth->rx_irq_coalescing_tbl_offset); |
3265 | out_be32(&ugeth->p_rx_glbl_pram->intcoalescingptr, | 3253 | out_be32(&ugeth->p_rx_glbl_pram->intcoalescingptr, |
3266 | ugeth->rx_irq_coalescing_tbl_offset); | 3254 | ugeth->rx_irq_coalescing_tbl_offset); |
@@ -3300,7 +3288,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) | |||
3300 | l3qt = 0; | 3288 | l3qt = 0; |
3301 | for (i = 0; i < 8; i++) | 3289 | for (i = 0; i < 8; i++) |
3302 | l3qt |= (ug_info->l3qt[j + i] << (28 - 4 * i)); | 3290 | l3qt |= (ug_info->l3qt[j + i] << (28 - 4 * i)); |
3303 | out_be32(&ugeth->p_rx_glbl_pram->l3qt[j], l3qt); | 3291 | out_be32(&ugeth->p_rx_glbl_pram->l3qt[j/8], l3qt); |
3304 | } | 3292 | } |
3305 | 3293 | ||
3306 | /* vlantype */ | 3294 | /* vlantype */ |
@@ -3316,8 +3304,8 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) | |||
3316 | /* Size varies with number of Rx queues */ | 3304 | /* Size varies with number of Rx queues */ |
3317 | ugeth->rx_bd_qs_tbl_offset = | 3305 | ugeth->rx_bd_qs_tbl_offset = |
3318 | qe_muram_alloc(ug_info->numQueuesRx * | 3306 | qe_muram_alloc(ug_info->numQueuesRx * |
3319 | (sizeof(ucc_geth_rx_bd_queues_entry_t) + | 3307 | (sizeof(struct ucc_geth_rx_bd_queues_entry) + |
3320 | sizeof(ucc_geth_rx_prefetched_bds_t)), | 3308 | sizeof(struct ucc_geth_rx_prefetched_bds)), |
3321 | UCC_GETH_RX_BD_QUEUES_ALIGNMENT); | 3309 | UCC_GETH_RX_BD_QUEUES_ALIGNMENT); |
3322 | if (IS_MURAM_ERR(ugeth->rx_bd_qs_tbl_offset)) { | 3310 | if (IS_MURAM_ERR(ugeth->rx_bd_qs_tbl_offset)) { |
3323 | ugeth_err | 3311 | ugeth_err |
@@ -3328,14 +3316,14 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) | |||
3328 | } | 3316 | } |
3329 | 3317 | ||
3330 | ugeth->p_rx_bd_qs_tbl = | 3318 | ugeth->p_rx_bd_qs_tbl = |
3331 | (ucc_geth_rx_bd_queues_entry_t *) qe_muram_addr(ugeth-> | 3319 | (struct ucc_geth_rx_bd_queues_entry *) qe_muram_addr(ugeth-> |
3332 | rx_bd_qs_tbl_offset); | 3320 | rx_bd_qs_tbl_offset); |
3333 | out_be32(&ugeth->p_rx_glbl_pram->rbdqptr, ugeth->rx_bd_qs_tbl_offset); | 3321 | out_be32(&ugeth->p_rx_glbl_pram->rbdqptr, ugeth->rx_bd_qs_tbl_offset); |
3334 | /* Zero out p_rx_bd_qs_tbl */ | 3322 | /* Zero out p_rx_bd_qs_tbl */ |
3335 | memset(ugeth->p_rx_bd_qs_tbl, | 3323 | memset(ugeth->p_rx_bd_qs_tbl, |
3336 | 0, | 3324 | 0, |
3337 | ug_info->numQueuesRx * (sizeof(ucc_geth_rx_bd_queues_entry_t) + | 3325 | ug_info->numQueuesRx * (sizeof(struct ucc_geth_rx_bd_queues_entry) + |
3338 | sizeof(ucc_geth_rx_prefetched_bds_t))); | 3326 | sizeof(struct ucc_geth_rx_prefetched_bds))); |
3339 | 3327 | ||
3340 | /* Setup the table */ | 3328 | /* Setup the table */ |
3341 | /* Assume BD rings are already established */ | 3329 | /* Assume BD rings are already established */ |
@@ -3406,7 +3394,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) | |||
3406 | /* Allocate memory for extended filtering Mode Global | 3394 | /* Allocate memory for extended filtering Mode Global |
3407 | Parameters */ | 3395 | Parameters */ |
3408 | ugeth->exf_glbl_param_offset = | 3396 | ugeth->exf_glbl_param_offset = |
3409 | qe_muram_alloc(sizeof(ucc_geth_exf_global_pram_t), | 3397 | qe_muram_alloc(sizeof(struct ucc_geth_exf_global_pram), |
3410 | UCC_GETH_RX_EXTENDED_FILTERING_GLOBAL_PARAMETERS_ALIGNMENT); | 3398 | UCC_GETH_RX_EXTENDED_FILTERING_GLOBAL_PARAMETERS_ALIGNMENT); |
3411 | if (IS_MURAM_ERR(ugeth->exf_glbl_param_offset)) { | 3399 | if (IS_MURAM_ERR(ugeth->exf_glbl_param_offset)) { |
3412 | ugeth_err | 3400 | ugeth_err |
@@ -3417,7 +3405,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) | |||
3417 | } | 3405 | } |
3418 | 3406 | ||
3419 | ugeth->p_exf_glbl_param = | 3407 | ugeth->p_exf_glbl_param = |
3420 | (ucc_geth_exf_global_pram_t *) qe_muram_addr(ugeth-> | 3408 | (struct ucc_geth_exf_global_pram *) qe_muram_addr(ugeth-> |
3421 | exf_glbl_param_offset); | 3409 | exf_glbl_param_offset); |
3422 | out_be32(&ugeth->p_rx_glbl_pram->exfGlobalParam, | 3410 | out_be32(&ugeth->p_rx_glbl_pram->exfGlobalParam, |
3423 | ugeth->exf_glbl_param_offset); | 3411 | ugeth->exf_glbl_param_offset); |
@@ -3439,7 +3427,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) | |||
3439 | INIT_LIST_HEAD(&ugeth->ind_hash_q); | 3427 | INIT_LIST_HEAD(&ugeth->ind_hash_q); |
3440 | } | 3428 | } |
3441 | p_82xx_addr_filt = | 3429 | p_82xx_addr_filt = |
3442 | (ucc_geth_82xx_address_filtering_pram_t *) ugeth-> | 3430 | (struct ucc_geth_82xx_address_filtering_pram *) ugeth-> |
3443 | p_rx_glbl_pram->addressfiltering; | 3431 | p_rx_glbl_pram->addressfiltering; |
3444 | 3432 | ||
3445 | ugeth_82xx_filtering_clear_all_addr_in_hash(ugeth, | 3433 | ugeth_82xx_filtering_clear_all_addr_in_hash(ugeth, |
@@ -3462,7 +3450,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) | |||
3462 | * allocated resources can be released when the channel is freed. | 3450 | * allocated resources can be released when the channel is freed. |
3463 | */ | 3451 | */ |
3464 | if (!(ugeth->p_init_enet_param_shadow = | 3452 | if (!(ugeth->p_init_enet_param_shadow = |
3465 | (ucc_geth_init_pram_t *) kmalloc(sizeof(ucc_geth_init_pram_t), | 3453 | (struct ucc_geth_init_pram *) kmalloc(sizeof(struct ucc_geth_init_pram), |
3466 | GFP_KERNEL))) { | 3454 | GFP_KERNEL))) { |
3467 | ugeth_err | 3455 | ugeth_err |
3468 | ("%s: Can not allocate memory for" | 3456 | ("%s: Can not allocate memory for" |
@@ -3472,7 +3460,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) | |||
3472 | } | 3460 | } |
3473 | /* Zero out *p_init_enet_param_shadow */ | 3461 | /* Zero out *p_init_enet_param_shadow */ |
3474 | memset((char *)ugeth->p_init_enet_param_shadow, | 3462 | memset((char *)ugeth->p_init_enet_param_shadow, |
3475 | 0, sizeof(ucc_geth_init_pram_t)); | 3463 | 0, sizeof(struct ucc_geth_init_pram)); |
3476 | 3464 | ||
3477 | /* Fill shadow InitEnet command parameter structure */ | 3465 | /* Fill shadow InitEnet command parameter structure */ |
3478 | 3466 | ||
@@ -3506,7 +3494,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) | |||
3506 | } | 3494 | } |
3507 | ugeth->p_init_enet_param_shadow->largestexternallookupkeysize = | 3495 | ugeth->p_init_enet_param_shadow->largestexternallookupkeysize = |
3508 | ug_info->largestexternallookupkeysize; | 3496 | ug_info->largestexternallookupkeysize; |
3509 | size = sizeof(ucc_geth_thread_rx_pram_t); | 3497 | size = sizeof(struct ucc_geth_thread_rx_pram); |
3510 | if (ug_info->rxExtendedFiltering) { | 3498 | if (ug_info->rxExtendedFiltering) { |
3511 | size += THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING; | 3499 | size += THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING; |
3512 | if (ug_info->largestexternallookupkeysize == | 3500 | if (ug_info->largestexternallookupkeysize == |
@@ -3537,7 +3525,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) | |||
3537 | fill_init_enet_entries(ugeth, | 3525 | fill_init_enet_entries(ugeth, |
3538 | &(ugeth->p_init_enet_param_shadow-> | 3526 | &(ugeth->p_init_enet_param_shadow-> |
3539 | txthread[0]), numThreadsTxNumerical, | 3527 | txthread[0]), numThreadsTxNumerical, |
3540 | sizeof(ucc_geth_thread_tx_pram_t), | 3528 | sizeof(struct ucc_geth_thread_tx_pram), |
3541 | UCC_GETH_THREAD_TX_PRAM_ALIGNMENT, | 3529 | UCC_GETH_THREAD_TX_PRAM_ALIGNMENT, |
3542 | ug_info->riscTx, 0)) != 0) { | 3530 | ug_info->riscTx, 0)) != 0) { |
3543 | ugeth_err("%s: Can not fill p_init_enet_param_shadow.", | 3531 | ugeth_err("%s: Can not fill p_init_enet_param_shadow.", |
@@ -3557,7 +3545,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) | |||
3557 | } | 3545 | } |
3558 | 3546 | ||
3559 | /* Allocate InitEnet command parameter structure */ | 3547 | /* Allocate InitEnet command parameter structure */ |
3560 | init_enet_pram_offset = qe_muram_alloc(sizeof(ucc_geth_init_pram_t), 4); | 3548 | init_enet_pram_offset = qe_muram_alloc(sizeof(struct ucc_geth_init_pram), 4); |
3561 | if (IS_MURAM_ERR(init_enet_pram_offset)) { | 3549 | if (IS_MURAM_ERR(init_enet_pram_offset)) { |
3562 | ugeth_err | 3550 | ugeth_err |
3563 | ("%s: Can not allocate DPRAM memory for p_init_enet_pram.", | 3551 | ("%s: Can not allocate DPRAM memory for p_init_enet_pram.", |
@@ -3566,7 +3554,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) | |||
3566 | return -ENOMEM; | 3554 | return -ENOMEM; |
3567 | } | 3555 | } |
3568 | p_init_enet_pram = | 3556 | p_init_enet_pram = |
3569 | (ucc_geth_init_pram_t *) qe_muram_addr(init_enet_pram_offset); | 3557 | (struct ucc_geth_init_pram *) qe_muram_addr(init_enet_pram_offset); |
3570 | 3558 | ||
3571 | /* Copy shadow InitEnet command parameter structure into PRAM */ | 3559 | /* Copy shadow InitEnet command parameter structure into PRAM */ |
3572 | p_init_enet_pram->resinit1 = ugeth->p_init_enet_param_shadow->resinit1; | 3560 | p_init_enet_pram->resinit1 = ugeth->p_init_enet_param_shadow->resinit1; |
@@ -3591,7 +3579,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) | |||
3591 | /* Issue QE command */ | 3579 | /* Issue QE command */ |
3592 | cecr_subblock = | 3580 | cecr_subblock = |
3593 | ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num); | 3581 | ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num); |
3594 | qe_issue_cmd(command, cecr_subblock, (u8) QE_CR_PROTOCOL_ETHERNET, | 3582 | qe_issue_cmd(command, cecr_subblock, QE_CR_PROTOCOL_ETHERNET, |
3595 | init_enet_pram_offset); | 3583 | init_enet_pram_offset); |
3596 | 3584 | ||
3597 | /* Free InitEnet command parameter */ | 3585 | /* Free InitEnet command parameter */ |
@@ -3603,7 +3591,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth) | |||
3603 | /* returns a net_device_stats structure pointer */ | 3591 | /* returns a net_device_stats structure pointer */ |
3604 | static struct net_device_stats *ucc_geth_get_stats(struct net_device *dev) | 3592 | static struct net_device_stats *ucc_geth_get_stats(struct net_device *dev) |
3605 | { | 3593 | { |
3606 | ucc_geth_private_t *ugeth = netdev_priv(dev); | 3594 | struct ucc_geth_private *ugeth = netdev_priv(dev); |
3607 | 3595 | ||
3608 | return &(ugeth->stats); | 3596 | return &(ugeth->stats); |
3609 | } | 3597 | } |
@@ -3614,7 +3602,7 @@ static struct net_device_stats *ucc_geth_get_stats(struct net_device *dev) | |||
3614 | * starting over will fix the problem. */ | 3602 | * starting over will fix the problem. */ |
3615 | static void ucc_geth_timeout(struct net_device *dev) | 3603 | static void ucc_geth_timeout(struct net_device *dev) |
3616 | { | 3604 | { |
3617 | ucc_geth_private_t *ugeth = netdev_priv(dev); | 3605 | struct ucc_geth_private *ugeth = netdev_priv(dev); |
3618 | 3606 | ||
3619 | ugeth_vdbg("%s: IN", __FUNCTION__); | 3607 | ugeth_vdbg("%s: IN", __FUNCTION__); |
3620 | 3608 | ||
@@ -3634,7 +3622,7 @@ static void ucc_geth_timeout(struct net_device *dev) | |||
3634 | /* It is pointed to by the dev->hard_start_xmit function pointer */ | 3622 | /* It is pointed to by the dev->hard_start_xmit function pointer */ |
3635 | static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev) | 3623 | static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev) |
3636 | { | 3624 | { |
3637 | ucc_geth_private_t *ugeth = netdev_priv(dev); | 3625 | struct ucc_geth_private *ugeth = netdev_priv(dev); |
3638 | u8 *bd; /* BD pointer */ | 3626 | u8 *bd; /* BD pointer */ |
3639 | u32 bd_status; | 3627 | u32 bd_status; |
3640 | u8 txQ = 0; | 3628 | u8 txQ = 0; |
@@ -3647,7 +3635,7 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3647 | 3635 | ||
3648 | /* Start from the next BD that should be filled */ | 3636 | /* Start from the next BD that should be filled */ |
3649 | bd = ugeth->txBd[txQ]; | 3637 | bd = ugeth->txBd[txQ]; |
3650 | bd_status = BD_STATUS_AND_LENGTH(bd); | 3638 | bd_status = in_be32((u32 *)bd); |
3651 | /* Save the skb pointer so we can free it later */ | 3639 | /* Save the skb pointer so we can free it later */ |
3652 | ugeth->tx_skbuff[txQ][ugeth->skb_curtx[txQ]] = skb; | 3640 | ugeth->tx_skbuff[txQ][ugeth->skb_curtx[txQ]] = skb; |
3653 | 3641 | ||
@@ -3657,20 +3645,21 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3657 | 1) & TX_RING_MOD_MASK(ugeth->ug_info->bdRingLenTx[txQ]); | 3645 | 1) & TX_RING_MOD_MASK(ugeth->ug_info->bdRingLenTx[txQ]); |
3658 | 3646 | ||
3659 | /* set up the buffer descriptor */ | 3647 | /* set up the buffer descriptor */ |
3660 | BD_BUFFER_SET(bd, | 3648 | out_be32(&((struct qe_bd *)bd)->buf, |
3661 | dma_map_single(NULL, skb->data, skb->len, DMA_TO_DEVICE)); | 3649 | dma_map_single(NULL, skb->data, skb->len, DMA_TO_DEVICE)); |
3662 | 3650 | ||
3663 | //printk(KERN_DEBUG"skb->data is 0x%x\n",skb->data); | 3651 | /* printk(KERN_DEBUG"skb->data is 0x%x\n",skb->data); */ |
3664 | 3652 | ||
3665 | bd_status = (bd_status & T_W) | T_R | T_I | T_L | skb->len; | 3653 | bd_status = (bd_status & T_W) | T_R | T_I | T_L | skb->len; |
3666 | 3654 | ||
3667 | BD_STATUS_AND_LENGTH_SET(bd, bd_status); | 3655 | /* set bd status and length */ |
3656 | out_be32((u32 *)bd, bd_status); | ||
3668 | 3657 | ||
3669 | dev->trans_start = jiffies; | 3658 | dev->trans_start = jiffies; |
3670 | 3659 | ||
3671 | /* Move to next BD in the ring */ | 3660 | /* Move to next BD in the ring */ |
3672 | if (!(bd_status & T_W)) | 3661 | if (!(bd_status & T_W)) |
3673 | ugeth->txBd[txQ] = bd + UCC_GETH_SIZE_OF_BD; | 3662 | ugeth->txBd[txQ] = bd + sizeof(struct qe_bd); |
3674 | else | 3663 | else |
3675 | ugeth->txBd[txQ] = ugeth->p_tx_bd_ring[txQ]; | 3664 | ugeth->txBd[txQ] = ugeth->p_tx_bd_ring[txQ]; |
3676 | 3665 | ||
@@ -3695,7 +3684,7 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3695 | return 0; | 3684 | return 0; |
3696 | } | 3685 | } |
3697 | 3686 | ||
3698 | static int ucc_geth_rx(ucc_geth_private_t *ugeth, u8 rxQ, int rx_work_limit) | 3687 | static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit) |
3699 | { | 3688 | { |
3700 | struct sk_buff *skb; | 3689 | struct sk_buff *skb; |
3701 | u8 *bd; | 3690 | u8 *bd; |
@@ -3709,11 +3698,11 @@ static int ucc_geth_rx(ucc_geth_private_t *ugeth, u8 rxQ, int rx_work_limit) | |||
3709 | /* collect received buffers */ | 3698 | /* collect received buffers */ |
3710 | bd = ugeth->rxBd[rxQ]; | 3699 | bd = ugeth->rxBd[rxQ]; |
3711 | 3700 | ||
3712 | bd_status = BD_STATUS_AND_LENGTH(bd); | 3701 | bd_status = in_be32((u32 *)bd); |
3713 | 3702 | ||
3714 | /* while there are received buffers and BD is full (~R_E) */ | 3703 | /* while there are received buffers and BD is full (~R_E) */ |
3715 | while (!((bd_status & (R_E)) || (--rx_work_limit < 0))) { | 3704 | while (!((bd_status & (R_E)) || (--rx_work_limit < 0))) { |
3716 | bdBuffer = (u8 *) BD_BUFFER(bd); | 3705 | bdBuffer = (u8 *) in_be32(&((struct qe_bd *)bd)->buf); |
3717 | length = (u16) ((bd_status & BD_LENGTH_MASK) - 4); | 3706 | length = (u16) ((bd_status & BD_LENGTH_MASK) - 4); |
3718 | skb = ugeth->rx_skbuff[rxQ][ugeth->skb_currx[rxQ]]; | 3707 | skb = ugeth->rx_skbuff[rxQ][ugeth->skb_currx[rxQ]]; |
3719 | 3708 | ||
@@ -3768,9 +3757,9 @@ static int ucc_geth_rx(ucc_geth_private_t *ugeth, u8 rxQ, int rx_work_limit) | |||
3768 | if (bd_status & R_W) | 3757 | if (bd_status & R_W) |
3769 | bd = ugeth->p_rx_bd_ring[rxQ]; | 3758 | bd = ugeth->p_rx_bd_ring[rxQ]; |
3770 | else | 3759 | else |
3771 | bd += UCC_GETH_SIZE_OF_BD; | 3760 | bd += sizeof(struct qe_bd); |
3772 | 3761 | ||
3773 | bd_status = BD_STATUS_AND_LENGTH(bd); | 3762 | bd_status = in_be32((u32 *)bd); |
3774 | } | 3763 | } |
3775 | 3764 | ||
3776 | ugeth->rxBd[rxQ] = bd; | 3765 | ugeth->rxBd[rxQ] = bd; |
@@ -3781,12 +3770,12 @@ static int ucc_geth_rx(ucc_geth_private_t *ugeth, u8 rxQ, int rx_work_limit) | |||
3781 | static int ucc_geth_tx(struct net_device *dev, u8 txQ) | 3770 | static int ucc_geth_tx(struct net_device *dev, u8 txQ) |
3782 | { | 3771 | { |
3783 | /* Start from the next BD that should be filled */ | 3772 | /* Start from the next BD that should be filled */ |
3784 | ucc_geth_private_t *ugeth = netdev_priv(dev); | 3773 | struct ucc_geth_private *ugeth = netdev_priv(dev); |
3785 | u8 *bd; /* BD pointer */ | 3774 | u8 *bd; /* BD pointer */ |
3786 | u32 bd_status; | 3775 | u32 bd_status; |
3787 | 3776 | ||
3788 | bd = ugeth->confBd[txQ]; | 3777 | bd = ugeth->confBd[txQ]; |
3789 | bd_status = BD_STATUS_AND_LENGTH(bd); | 3778 | bd_status = in_be32((u32 *)bd); |
3790 | 3779 | ||
3791 | /* Normal processing. */ | 3780 | /* Normal processing. */ |
3792 | while ((bd_status & T_R) == 0) { | 3781 | while ((bd_status & T_R) == 0) { |
@@ -3813,7 +3802,7 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ) | |||
3813 | 3802 | ||
3814 | /* Advance the confirmation BD pointer */ | 3803 | /* Advance the confirmation BD pointer */ |
3815 | if (!(bd_status & T_W)) | 3804 | if (!(bd_status & T_W)) |
3816 | ugeth->confBd[txQ] += UCC_GETH_SIZE_OF_BD; | 3805 | ugeth->confBd[txQ] += sizeof(struct qe_bd); |
3817 | else | 3806 | else |
3818 | ugeth->confBd[txQ] = ugeth->p_tx_bd_ring[txQ]; | 3807 | ugeth->confBd[txQ] = ugeth->p_tx_bd_ring[txQ]; |
3819 | } | 3808 | } |
@@ -3823,7 +3812,7 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ) | |||
3823 | #ifdef CONFIG_UGETH_NAPI | 3812 | #ifdef CONFIG_UGETH_NAPI |
3824 | static int ucc_geth_poll(struct net_device *dev, int *budget) | 3813 | static int ucc_geth_poll(struct net_device *dev, int *budget) |
3825 | { | 3814 | { |
3826 | ucc_geth_private_t *ugeth = netdev_priv(dev); | 3815 | struct ucc_geth_private *ugeth = netdev_priv(dev); |
3827 | int howmany; | 3816 | int howmany; |
3828 | int rx_work_limit = *budget; | 3817 | int rx_work_limit = *budget; |
3829 | u8 rxQ = 0; | 3818 | u8 rxQ = 0; |
@@ -3847,9 +3836,9 @@ static int ucc_geth_poll(struct net_device *dev, int *budget) | |||
3847 | static irqreturn_t ucc_geth_irq_handler(int irq, void *info) | 3836 | static irqreturn_t ucc_geth_irq_handler(int irq, void *info) |
3848 | { | 3837 | { |
3849 | struct net_device *dev = (struct net_device *)info; | 3838 | struct net_device *dev = (struct net_device *)info; |
3850 | ucc_geth_private_t *ugeth = netdev_priv(dev); | 3839 | struct ucc_geth_private *ugeth = netdev_priv(dev); |
3851 | ucc_fast_private_t *uccf; | 3840 | struct ucc_fast_private *uccf; |
3852 | ucc_geth_info_t *ug_info; | 3841 | struct ucc_geth_info *ug_info; |
3853 | register u32 ucce = 0; | 3842 | register u32 ucce = 0; |
3854 | register u32 bit_mask = UCCE_RXBF_SINGLE_MASK; | 3843 | register u32 bit_mask = UCCE_RXBF_SINGLE_MASK; |
3855 | register u32 tx_mask = UCCE_TXBF_SINGLE_MASK; | 3844 | register u32 tx_mask = UCCE_TXBF_SINGLE_MASK; |
@@ -3912,7 +3901,7 @@ static irqreturn_t ucc_geth_irq_handler(int irq, void *info) | |||
3912 | static irqreturn_t phy_interrupt(int irq, void *dev_id) | 3901 | static irqreturn_t phy_interrupt(int irq, void *dev_id) |
3913 | { | 3902 | { |
3914 | struct net_device *dev = (struct net_device *)dev_id; | 3903 | struct net_device *dev = (struct net_device *)dev_id; |
3915 | ucc_geth_private_t *ugeth = netdev_priv(dev); | 3904 | struct ucc_geth_private *ugeth = netdev_priv(dev); |
3916 | 3905 | ||
3917 | ugeth_vdbg("%s: IN", __FUNCTION__); | 3906 | ugeth_vdbg("%s: IN", __FUNCTION__); |
3918 | 3907 | ||
@@ -3932,8 +3921,8 @@ static irqreturn_t phy_interrupt(int irq, void *dev_id) | |||
3932 | static void ugeth_phy_change(void *data) | 3921 | static void ugeth_phy_change(void *data) |
3933 | { | 3922 | { |
3934 | struct net_device *dev = (struct net_device *)data; | 3923 | struct net_device *dev = (struct net_device *)data; |
3935 | ucc_geth_private_t *ugeth = netdev_priv(dev); | 3924 | struct ucc_geth_private *ugeth = netdev_priv(dev); |
3936 | ucc_geth_t *ug_regs; | 3925 | struct ucc_geth *ug_regs; |
3937 | int result = 0; | 3926 | int result = 0; |
3938 | 3927 | ||
3939 | ugeth_vdbg("%s: IN", __FUNCTION__); | 3928 | ugeth_vdbg("%s: IN", __FUNCTION__); |
@@ -3963,7 +3952,7 @@ static void ugeth_phy_change(void *data) | |||
3963 | static void ugeth_phy_timer(unsigned long data) | 3952 | static void ugeth_phy_timer(unsigned long data) |
3964 | { | 3953 | { |
3965 | struct net_device *dev = (struct net_device *)data; | 3954 | struct net_device *dev = (struct net_device *)data; |
3966 | ucc_geth_private_t *ugeth = netdev_priv(dev); | 3955 | struct ucc_geth_private *ugeth = netdev_priv(dev); |
3967 | 3956 | ||
3968 | schedule_work(&ugeth->tq); | 3957 | schedule_work(&ugeth->tq); |
3969 | 3958 | ||
@@ -3979,7 +3968,7 @@ static void ugeth_phy_timer(unsigned long data) | |||
3979 | static void ugeth_phy_startup_timer(unsigned long data) | 3968 | static void ugeth_phy_startup_timer(unsigned long data) |
3980 | { | 3969 | { |
3981 | struct ugeth_mii_info *mii_info = (struct ugeth_mii_info *)data; | 3970 | struct ugeth_mii_info *mii_info = (struct ugeth_mii_info *)data; |
3982 | ucc_geth_private_t *ugeth = netdev_priv(mii_info->dev); | 3971 | struct ucc_geth_private *ugeth = netdev_priv(mii_info->dev); |
3983 | static int secondary = UGETH_AN_TIMEOUT; | 3972 | static int secondary = UGETH_AN_TIMEOUT; |
3984 | int result; | 3973 | int result; |
3985 | 3974 | ||
@@ -4034,7 +4023,7 @@ static void ugeth_phy_startup_timer(unsigned long data) | |||
4034 | /* Returns 0 for success. */ | 4023 | /* Returns 0 for success. */ |
4035 | static int ucc_geth_open(struct net_device *dev) | 4024 | static int ucc_geth_open(struct net_device *dev) |
4036 | { | 4025 | { |
4037 | ucc_geth_private_t *ugeth = netdev_priv(dev); | 4026 | struct ucc_geth_private *ugeth = netdev_priv(dev); |
4038 | int err; | 4027 | int err; |
4039 | 4028 | ||
4040 | ugeth_vdbg("%s: IN", __FUNCTION__); | 4029 | ugeth_vdbg("%s: IN", __FUNCTION__); |
@@ -4111,7 +4100,7 @@ static int ucc_geth_open(struct net_device *dev) | |||
4111 | /* Stops the kernel queue, and halts the controller */ | 4100 | /* Stops the kernel queue, and halts the controller */ |
4112 | static int ucc_geth_close(struct net_device *dev) | 4101 | static int ucc_geth_close(struct net_device *dev) |
4113 | { | 4102 | { |
4114 | ucc_geth_private_t *ugeth = netdev_priv(dev); | 4103 | struct ucc_geth_private *ugeth = netdev_priv(dev); |
4115 | 4104 | ||
4116 | ugeth_vdbg("%s: IN", __FUNCTION__); | 4105 | ugeth_vdbg("%s: IN", __FUNCTION__); |
4117 | 4106 | ||
@@ -4130,30 +4119,53 @@ static int ucc_geth_close(struct net_device *dev) | |||
4130 | 4119 | ||
4131 | const struct ethtool_ops ucc_geth_ethtool_ops = { }; | 4120 | const struct ethtool_ops ucc_geth_ethtool_ops = { }; |
4132 | 4121 | ||
4133 | static int ucc_geth_probe(struct device *device) | 4122 | static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *match) |
4134 | { | 4123 | { |
4135 | struct platform_device *pdev = to_platform_device(device); | 4124 | struct device *device = &ofdev->dev; |
4136 | struct ucc_geth_platform_data *ugeth_pdata; | 4125 | struct device_node *np = ofdev->node; |
4137 | struct net_device *dev = NULL; | 4126 | struct net_device *dev = NULL; |
4138 | struct ucc_geth_private *ugeth = NULL; | 4127 | struct ucc_geth_private *ugeth = NULL; |
4139 | struct ucc_geth_info *ug_info; | 4128 | struct ucc_geth_info *ug_info; |
4140 | int err; | 4129 | struct resource res; |
4130 | struct device_node *phy; | ||
4131 | int err, ucc_num, phy_interface; | ||
4141 | static int mii_mng_configured = 0; | 4132 | static int mii_mng_configured = 0; |
4133 | const phandle *ph; | ||
4134 | const unsigned int *prop; | ||
4142 | 4135 | ||
4143 | ugeth_vdbg("%s: IN", __FUNCTION__); | 4136 | ugeth_vdbg("%s: IN", __FUNCTION__); |
4144 | 4137 | ||
4145 | ugeth_pdata = (struct ucc_geth_platform_data *)pdev->dev.platform_data; | 4138 | prop = get_property(np, "device-id", NULL); |
4139 | ucc_num = *prop - 1; | ||
4140 | if ((ucc_num < 0) || (ucc_num > 7)) | ||
4141 | return -ENODEV; | ||
4142 | |||
4143 | ug_info = &ugeth_info[ucc_num]; | ||
4144 | ug_info->uf_info.ucc_num = ucc_num; | ||
4145 | prop = get_property(np, "rx-clock", NULL); | ||
4146 | ug_info->uf_info.rx_clock = *prop; | ||
4147 | prop = get_property(np, "tx-clock", NULL); | ||
4148 | ug_info->uf_info.tx_clock = *prop; | ||
4149 | err = of_address_to_resource(np, 0, &res); | ||
4150 | if (err) | ||
4151 | return -EINVAL; | ||
4152 | |||
4153 | ug_info->uf_info.regs = res.start; | ||
4154 | ug_info->uf_info.irq = irq_of_parse_and_map(np, 0); | ||
4155 | |||
4156 | ph = get_property(np, "phy-handle", NULL); | ||
4157 | phy = of_find_node_by_phandle(*ph); | ||
4146 | 4158 | ||
4147 | ug_info = &ugeth_info[pdev->id]; | 4159 | if (phy == NULL) |
4148 | ug_info->uf_info.ucc_num = pdev->id; | 4160 | return -ENODEV; |
4149 | ug_info->uf_info.rx_clock = ugeth_pdata->rx_clock; | 4161 | |
4150 | ug_info->uf_info.tx_clock = ugeth_pdata->tx_clock; | 4162 | prop = get_property(phy, "reg", NULL); |
4151 | ug_info->uf_info.regs = ugeth_pdata->phy_reg_addr; | 4163 | ug_info->phy_address = *prop; |
4152 | ug_info->uf_info.irq = platform_get_irq(pdev, 0); | 4164 | prop = get_property(phy, "interface", NULL); |
4153 | ug_info->phy_address = ugeth_pdata->phy_id; | 4165 | ug_info->enet_interface = *prop; |
4154 | ug_info->enet_interface = ugeth_pdata->phy_interface; | 4166 | ug_info->phy_interrupt = irq_of_parse_and_map(phy, 0); |
4155 | ug_info->board_flags = ugeth_pdata->board_flags; | 4167 | ug_info->board_flags = (ug_info->phy_interrupt == NO_IRQ)? |
4156 | ug_info->phy_interrupt = ugeth_pdata->phy_interrupt; | 4168 | 0:FSL_UGETH_BRD_HAS_PHY_INTR; |
4157 | 4169 | ||
4158 | printk(KERN_INFO "ucc_geth: UCC%1d at 0x%8x (irq = %d) \n", | 4170 | printk(KERN_INFO "ucc_geth: UCC%1d at 0x%8x (irq = %d) \n", |
4159 | ug_info->uf_info.ucc_num + 1, ug_info->uf_info.regs, | 4171 | ug_info->uf_info.ucc_num + 1, ug_info->uf_info.regs, |
@@ -4161,12 +4173,44 @@ static int ucc_geth_probe(struct device *device) | |||
4161 | 4173 | ||
4162 | if (ug_info == NULL) { | 4174 | if (ug_info == NULL) { |
4163 | ugeth_err("%s: [%d] Missing additional data!", __FUNCTION__, | 4175 | ugeth_err("%s: [%d] Missing additional data!", __FUNCTION__, |
4164 | pdev->id); | 4176 | ucc_num); |
4165 | return -ENODEV; | 4177 | return -ENODEV; |
4166 | } | 4178 | } |
4167 | 4179 | ||
4180 | /* FIXME: Work around for early chip rev. */ | ||
4181 | /* There's a bug in initial chip rev(s) in the RGMII ac */ | ||
4182 | /* timing. */ | ||
4183 | /* The following compensates by writing to the reserved */ | ||
4184 | /* QE Port Output Hold Registers (CPOH1?). */ | ||
4185 | prop = get_property(phy, "interface", NULL); | ||
4186 | phy_interface = *prop; | ||
4187 | if ((phy_interface == ENET_1000_RGMII) || | ||
4188 | (phy_interface == ENET_100_RGMII) || | ||
4189 | (phy_interface == ENET_10_RGMII)) { | ||
4190 | struct device_node *soc; | ||
4191 | phys_addr_t immrbase = -1; | ||
4192 | u32 *tmp_reg; | ||
4193 | u32 tmp_val; | ||
4194 | |||
4195 | soc = of_find_node_by_type(NULL, "soc"); | ||
4196 | if (soc) { | ||
4197 | unsigned int size; | ||
4198 | const void *prop = get_property(soc, "reg", &size); | ||
4199 | immrbase = of_translate_address(soc, prop); | ||
4200 | of_node_put(soc); | ||
4201 | }; | ||
4202 | |||
4203 | tmp_reg = (u32 *) ioremap(immrbase + 0x14A8, 0x4); | ||
4204 | tmp_val = in_be32(tmp_reg); | ||
4205 | if (ucc_num == 1) | ||
4206 | out_be32(tmp_reg, tmp_val | 0x00003000); | ||
4207 | else if (ucc_num == 2) | ||
4208 | out_be32(tmp_reg, tmp_val | 0x0c000000); | ||
4209 | iounmap(tmp_reg); | ||
4210 | } | ||
4211 | |||
4168 | if (!mii_mng_configured) { | 4212 | if (!mii_mng_configured) { |
4169 | ucc_set_qe_mux_mii_mng(ug_info->uf_info.ucc_num); | 4213 | ucc_set_qe_mux_mii_mng(ucc_num); |
4170 | mii_mng_configured = 1; | 4214 | mii_mng_configured = 1; |
4171 | } | 4215 | } |
4172 | 4216 | ||
@@ -4213,13 +4257,14 @@ static int ucc_geth_probe(struct device *device) | |||
4213 | 4257 | ||
4214 | ugeth->ug_info = ug_info; | 4258 | ugeth->ug_info = ug_info; |
4215 | ugeth->dev = dev; | 4259 | ugeth->dev = dev; |
4216 | memcpy(dev->dev_addr, ugeth_pdata->mac_addr, 6); | 4260 | memcpy(dev->dev_addr, get_property(np, "mac-address", NULL), 6); |
4217 | 4261 | ||
4218 | return 0; | 4262 | return 0; |
4219 | } | 4263 | } |
4220 | 4264 | ||
4221 | static int ucc_geth_remove(struct device *device) | 4265 | static int ucc_geth_remove(struct of_device* ofdev) |
4222 | { | 4266 | { |
4267 | struct device *device = &ofdev->dev; | ||
4223 | struct net_device *dev = dev_get_drvdata(device); | 4268 | struct net_device *dev = dev_get_drvdata(device); |
4224 | struct ucc_geth_private *ugeth = netdev_priv(dev); | 4269 | struct ucc_geth_private *ugeth = netdev_priv(dev); |
4225 | 4270 | ||
@@ -4230,28 +4275,38 @@ static int ucc_geth_remove(struct device *device) | |||
4230 | return 0; | 4275 | return 0; |
4231 | } | 4276 | } |
4232 | 4277 | ||
4233 | /* Structure for a device driver */ | 4278 | static struct of_device_id ucc_geth_match[] = { |
4234 | static struct device_driver ucc_geth_driver = { | 4279 | { |
4235 | .name = DRV_NAME, | 4280 | .type = "network", |
4236 | .bus = &platform_bus_type, | 4281 | .compatible = "ucc_geth", |
4237 | .probe = ucc_geth_probe, | 4282 | }, |
4238 | .remove = ucc_geth_remove, | 4283 | {}, |
4284 | }; | ||
4285 | |||
4286 | MODULE_DEVICE_TABLE(of, ucc_geth_match); | ||
4287 | |||
4288 | static struct of_platform_driver ucc_geth_driver = { | ||
4289 | .name = DRV_NAME, | ||
4290 | .match_table = ucc_geth_match, | ||
4291 | .probe = ucc_geth_probe, | ||
4292 | .remove = ucc_geth_remove, | ||
4239 | }; | 4293 | }; |
4240 | 4294 | ||
4241 | static int __init ucc_geth_init(void) | 4295 | static int __init ucc_geth_init(void) |
4242 | { | 4296 | { |
4243 | int i; | 4297 | int i; |
4298 | |||
4244 | printk(KERN_INFO "ucc_geth: " DRV_DESC "\n"); | 4299 | printk(KERN_INFO "ucc_geth: " DRV_DESC "\n"); |
4245 | for (i = 0; i < 8; i++) | 4300 | for (i = 0; i < 8; i++) |
4246 | memcpy(&(ugeth_info[i]), &ugeth_primary_info, | 4301 | memcpy(&(ugeth_info[i]), &ugeth_primary_info, |
4247 | sizeof(ugeth_primary_info)); | 4302 | sizeof(ugeth_primary_info)); |
4248 | 4303 | ||
4249 | return driver_register(&ucc_geth_driver); | 4304 | return of_register_driver(&ucc_geth_driver); |
4250 | } | 4305 | } |
4251 | 4306 | ||
4252 | static void __exit ucc_geth_exit(void) | 4307 | static void __exit ucc_geth_exit(void) |
4253 | { | 4308 | { |
4254 | driver_unregister(&ucc_geth_driver); | 4309 | of_unregister_driver(&ucc_geth_driver); |
4255 | } | 4310 | } |
4256 | 4311 | ||
4257 | module_init(ucc_geth_init); | 4312 | module_init(ucc_geth_init); |
diff --git a/drivers/net/ucc_geth.h b/drivers/net/ucc_geth.h index 005965f5dd9b..a66561253593 100644 --- a/drivers/net/ucc_geth.h +++ b/drivers/net/ucc_geth.h | |||
@@ -36,24 +36,24 @@ | |||
36 | #define ENET_INIT_PARAM_MAX_ENTRIES_RX 9 | 36 | #define ENET_INIT_PARAM_MAX_ENTRIES_RX 9 |
37 | #define ENET_INIT_PARAM_MAX_ENTRIES_TX 8 | 37 | #define ENET_INIT_PARAM_MAX_ENTRIES_TX 8 |
38 | 38 | ||
39 | typedef struct ucc_mii_mng { | 39 | struct ucc_mii_mng { |
40 | u32 miimcfg; /* MII management configuration reg */ | 40 | u32 miimcfg; /* MII management configuration reg */ |
41 | u32 miimcom; /* MII management command reg */ | 41 | u32 miimcom; /* MII management command reg */ |
42 | u32 miimadd; /* MII management address reg */ | 42 | u32 miimadd; /* MII management address reg */ |
43 | u32 miimcon; /* MII management control reg */ | 43 | u32 miimcon; /* MII management control reg */ |
44 | u32 miimstat; /* MII management status reg */ | 44 | u32 miimstat; /* MII management status reg */ |
45 | u32 miimind; /* MII management indication reg */ | 45 | u32 miimind; /* MII management indication reg */ |
46 | } __attribute__ ((packed)) ucc_mii_mng_t; | 46 | } __attribute__ ((packed)); |
47 | 47 | ||
48 | typedef struct ucc_geth { | 48 | struct ucc_geth { |
49 | ucc_fast_t uccf; | 49 | struct ucc_fast uccf; |
50 | 50 | ||
51 | u32 maccfg1; /* mac configuration reg. 1 */ | 51 | u32 maccfg1; /* mac configuration reg. 1 */ |
52 | u32 maccfg2; /* mac configuration reg. 2 */ | 52 | u32 maccfg2; /* mac configuration reg. 2 */ |
53 | u32 ipgifg; /* interframe gap reg. */ | 53 | u32 ipgifg; /* interframe gap reg. */ |
54 | u32 hafdup; /* half-duplex reg. */ | 54 | u32 hafdup; /* half-duplex reg. */ |
55 | u8 res1[0x10]; | 55 | u8 res1[0x10]; |
56 | ucc_mii_mng_t miimng; /* MII management structure */ | 56 | struct ucc_mii_mng miimng; /* MII management structure */ |
57 | u32 ifctl; /* interface control reg */ | 57 | u32 ifctl; /* interface control reg */ |
58 | u32 ifstat; /* interface statux reg */ | 58 | u32 ifstat; /* interface statux reg */ |
59 | u32 macstnaddr1; /* mac station address part 1 reg */ | 59 | u32 macstnaddr1; /* mac station address part 1 reg */ |
@@ -111,7 +111,7 @@ typedef struct ucc_geth { | |||
111 | u32 scar; /* Statistics carry register */ | 111 | u32 scar; /* Statistics carry register */ |
112 | u32 scam; /* Statistics caryy mask register */ | 112 | u32 scam; /* Statistics caryy mask register */ |
113 | u8 res5[0x200 - 0x1c4]; | 113 | u8 res5[0x200 - 0x1c4]; |
114 | } __attribute__ ((packed)) ucc_geth_t; | 114 | } __attribute__ ((packed)); |
115 | 115 | ||
116 | /* UCC GETH TEMODR Register */ | 116 | /* UCC GETH TEMODR Register */ |
117 | #define TEMODER_TX_RMON_STATISTICS_ENABLE 0x0100 /* enable Tx statistics | 117 | #define TEMODER_TX_RMON_STATISTICS_ENABLE 0x0100 /* enable Tx statistics |
@@ -508,39 +508,39 @@ typedef struct ucc_geth { | |||
508 | /* UCC GETH UDSR (Data Synchronization Register) */ | 508 | /* UCC GETH UDSR (Data Synchronization Register) */ |
509 | #define UDSR_MAGIC 0x067E | 509 | #define UDSR_MAGIC 0x067E |
510 | 510 | ||
511 | typedef struct ucc_geth_thread_data_tx { | 511 | struct ucc_geth_thread_data_tx { |
512 | u8 res0[104]; | 512 | u8 res0[104]; |
513 | } __attribute__ ((packed)) ucc_geth_thread_data_tx_t; | 513 | } __attribute__ ((packed)); |
514 | 514 | ||
515 | typedef struct ucc_geth_thread_data_rx { | 515 | struct ucc_geth_thread_data_rx { |
516 | u8 res0[40]; | 516 | u8 res0[40]; |
517 | } __attribute__ ((packed)) ucc_geth_thread_data_rx_t; | 517 | } __attribute__ ((packed)); |
518 | 518 | ||
519 | /* Send Queue Queue-Descriptor */ | 519 | /* Send Queue Queue-Descriptor */ |
520 | typedef struct ucc_geth_send_queue_qd { | 520 | struct ucc_geth_send_queue_qd { |
521 | u32 bd_ring_base; /* pointer to BD ring base address */ | 521 | u32 bd_ring_base; /* pointer to BD ring base address */ |
522 | u8 res0[0x8]; | 522 | u8 res0[0x8]; |
523 | u32 last_bd_completed_address;/* initialize to last entry in BD ring */ | 523 | u32 last_bd_completed_address;/* initialize to last entry in BD ring */ |
524 | u8 res1[0x30]; | 524 | u8 res1[0x30]; |
525 | } __attribute__ ((packed)) ucc_geth_send_queue_qd_t; | 525 | } __attribute__ ((packed)); |
526 | 526 | ||
527 | typedef struct ucc_geth_send_queue_mem_region { | 527 | struct ucc_geth_send_queue_mem_region { |
528 | ucc_geth_send_queue_qd_t sqqd[NUM_TX_QUEUES]; | 528 | struct ucc_geth_send_queue_qd sqqd[NUM_TX_QUEUES]; |
529 | } __attribute__ ((packed)) ucc_geth_send_queue_mem_region_t; | 529 | } __attribute__ ((packed)); |
530 | 530 | ||
531 | typedef struct ucc_geth_thread_tx_pram { | 531 | struct ucc_geth_thread_tx_pram { |
532 | u8 res0[64]; | 532 | u8 res0[64]; |
533 | } __attribute__ ((packed)) ucc_geth_thread_tx_pram_t; | 533 | } __attribute__ ((packed)); |
534 | 534 | ||
535 | typedef struct ucc_geth_thread_rx_pram { | 535 | struct ucc_geth_thread_rx_pram { |
536 | u8 res0[128]; | 536 | u8 res0[128]; |
537 | } __attribute__ ((packed)) ucc_geth_thread_rx_pram_t; | 537 | } __attribute__ ((packed)); |
538 | 538 | ||
539 | #define THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING 64 | 539 | #define THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING 64 |
540 | #define THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING_8 64 | 540 | #define THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING_8 64 |
541 | #define THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING_16 96 | 541 | #define THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING_16 96 |
542 | 542 | ||
543 | typedef struct ucc_geth_scheduler { | 543 | struct ucc_geth_scheduler { |
544 | u16 cpucount0; /* CPU packet counter */ | 544 | u16 cpucount0; /* CPU packet counter */ |
545 | u16 cpucount1; /* CPU packet counter */ | 545 | u16 cpucount1; /* CPU packet counter */ |
546 | u16 cecount0; /* QE packet counter */ | 546 | u16 cecount0; /* QE packet counter */ |
@@ -574,9 +574,9 @@ typedef struct ucc_geth_scheduler { | |||
574 | /**< weight factor for queues */ | 574 | /**< weight factor for queues */ |
575 | u32 minw; /* temporary variable handled by QE */ | 575 | u32 minw; /* temporary variable handled by QE */ |
576 | u8 res1[0x70 - 0x64]; | 576 | u8 res1[0x70 - 0x64]; |
577 | } __attribute__ ((packed)) ucc_geth_scheduler_t; | 577 | } __attribute__ ((packed)); |
578 | 578 | ||
579 | typedef struct ucc_geth_tx_firmware_statistics_pram { | 579 | struct ucc_geth_tx_firmware_statistics_pram { |
580 | u32 sicoltx; /* single collision */ | 580 | u32 sicoltx; /* single collision */ |
581 | u32 mulcoltx; /* multiple collision */ | 581 | u32 mulcoltx; /* multiple collision */ |
582 | u32 latecoltxfr; /* late collision */ | 582 | u32 latecoltxfr; /* late collision */ |
@@ -596,9 +596,9 @@ typedef struct ucc_geth_tx_firmware_statistics_pram { | |||
596 | and 1518 octets */ | 596 | and 1518 octets */ |
597 | u32 txpktsjumbo; /* total packets (including bad) between 1024 | 597 | u32 txpktsjumbo; /* total packets (including bad) between 1024 |
598 | and MAXLength octets */ | 598 | and MAXLength octets */ |
599 | } __attribute__ ((packed)) ucc_geth_tx_firmware_statistics_pram_t; | 599 | } __attribute__ ((packed)); |
600 | 600 | ||
601 | typedef struct ucc_geth_rx_firmware_statistics_pram { | 601 | struct ucc_geth_rx_firmware_statistics_pram { |
602 | u32 frrxfcser; /* frames with crc error */ | 602 | u32 frrxfcser; /* frames with crc error */ |
603 | u32 fraligner; /* frames with alignment error */ | 603 | u32 fraligner; /* frames with alignment error */ |
604 | u32 inrangelenrxer; /* in range length error */ | 604 | u32 inrangelenrxer; /* in range length error */ |
@@ -630,33 +630,33 @@ typedef struct ucc_geth_rx_firmware_statistics_pram { | |||
630 | replaced */ | 630 | replaced */ |
631 | u32 insertvlan; /* total frames that had their VLAN tag | 631 | u32 insertvlan; /* total frames that had their VLAN tag |
632 | inserted */ | 632 | inserted */ |
633 | } __attribute__ ((packed)) ucc_geth_rx_firmware_statistics_pram_t; | 633 | } __attribute__ ((packed)); |
634 | 634 | ||
635 | typedef struct ucc_geth_rx_interrupt_coalescing_entry { | 635 | struct ucc_geth_rx_interrupt_coalescing_entry { |
636 | u32 interruptcoalescingmaxvalue; /* interrupt coalescing max | 636 | u32 interruptcoalescingmaxvalue; /* interrupt coalescing max |
637 | value */ | 637 | value */ |
638 | u32 interruptcoalescingcounter; /* interrupt coalescing counter, | 638 | u32 interruptcoalescingcounter; /* interrupt coalescing counter, |
639 | initialize to | 639 | initialize to |
640 | interruptcoalescingmaxvalue */ | 640 | interruptcoalescingmaxvalue */ |
641 | } __attribute__ ((packed)) ucc_geth_rx_interrupt_coalescing_entry_t; | 641 | } __attribute__ ((packed)); |
642 | 642 | ||
643 | typedef struct ucc_geth_rx_interrupt_coalescing_table { | 643 | struct ucc_geth_rx_interrupt_coalescing_table { |
644 | ucc_geth_rx_interrupt_coalescing_entry_t coalescingentry[NUM_RX_QUEUES]; | 644 | struct ucc_geth_rx_interrupt_coalescing_entry coalescingentry[NUM_RX_QUEUES]; |
645 | /**< interrupt coalescing entry */ | 645 | /**< interrupt coalescing entry */ |
646 | } __attribute__ ((packed)) ucc_geth_rx_interrupt_coalescing_table_t; | 646 | } __attribute__ ((packed)); |
647 | 647 | ||
648 | typedef struct ucc_geth_rx_prefetched_bds { | 648 | struct ucc_geth_rx_prefetched_bds { |
649 | qe_bd_t bd[NUM_BDS_IN_PREFETCHED_BDS]; /* prefetched bd */ | 649 | struct qe_bd bd[NUM_BDS_IN_PREFETCHED_BDS]; /* prefetched bd */ |
650 | } __attribute__ ((packed)) ucc_geth_rx_prefetched_bds_t; | 650 | } __attribute__ ((packed)); |
651 | 651 | ||
652 | typedef struct ucc_geth_rx_bd_queues_entry { | 652 | struct ucc_geth_rx_bd_queues_entry { |
653 | u32 bdbaseptr; /* BD base pointer */ | 653 | u32 bdbaseptr; /* BD base pointer */ |
654 | u32 bdptr; /* BD pointer */ | 654 | u32 bdptr; /* BD pointer */ |
655 | u32 externalbdbaseptr; /* external BD base pointer */ | 655 | u32 externalbdbaseptr; /* external BD base pointer */ |
656 | u32 externalbdptr; /* external BD pointer */ | 656 | u32 externalbdptr; /* external BD pointer */ |
657 | } __attribute__ ((packed)) ucc_geth_rx_bd_queues_entry_t; | 657 | } __attribute__ ((packed)); |
658 | 658 | ||
659 | typedef struct ucc_geth_tx_global_pram { | 659 | struct ucc_geth_tx_global_pram { |
660 | u16 temoder; | 660 | u16 temoder; |
661 | u8 res0[0x38 - 0x02]; | 661 | u8 res0[0x38 - 0x02]; |
662 | u32 sqptr; /* a base pointer to send queue memory region */ | 662 | u32 sqptr; /* a base pointer to send queue memory region */ |
@@ -670,15 +670,15 @@ typedef struct ucc_geth_tx_global_pram { | |||
670 | u32 tqptr; /* a base pointer to the Tx Queues Memory | 670 | u32 tqptr; /* a base pointer to the Tx Queues Memory |
671 | Region */ | 671 | Region */ |
672 | u8 res2[0x80 - 0x74]; | 672 | u8 res2[0x80 - 0x74]; |
673 | } __attribute__ ((packed)) ucc_geth_tx_global_pram_t; | 673 | } __attribute__ ((packed)); |
674 | 674 | ||
675 | /* structure representing Extended Filtering Global Parameters in PRAM */ | 675 | /* structure representing Extended Filtering Global Parameters in PRAM */ |
676 | typedef struct ucc_geth_exf_global_pram { | 676 | struct ucc_geth_exf_global_pram { |
677 | u32 l2pcdptr; /* individual address filter, high */ | 677 | u32 l2pcdptr; /* individual address filter, high */ |
678 | u8 res0[0x10 - 0x04]; | 678 | u8 res0[0x10 - 0x04]; |
679 | } __attribute__ ((packed)) ucc_geth_exf_global_pram_t; | 679 | } __attribute__ ((packed)); |
680 | 680 | ||
681 | typedef struct ucc_geth_rx_global_pram { | 681 | struct ucc_geth_rx_global_pram { |
682 | u32 remoder; /* ethernet mode reg. */ | 682 | u32 remoder; /* ethernet mode reg. */ |
683 | u32 rqptr; /* base pointer to the Rx Queues Memory Region*/ | 683 | u32 rqptr; /* base pointer to the Rx Queues Memory Region*/ |
684 | u32 res0[0x1]; | 684 | u32 res0[0x1]; |
@@ -710,12 +710,12 @@ typedef struct ucc_geth_rx_global_pram { | |||
710 | u32 exfGlobalParam; /* base address for extended filtering global | 710 | u32 exfGlobalParam; /* base address for extended filtering global |
711 | parameters */ | 711 | parameters */ |
712 | u8 res6[0x100 - 0xC4]; /* Initialize to zero */ | 712 | u8 res6[0x100 - 0xC4]; /* Initialize to zero */ |
713 | } __attribute__ ((packed)) ucc_geth_rx_global_pram_t; | 713 | } __attribute__ ((packed)); |
714 | 714 | ||
715 | #define GRACEFUL_STOP_ACKNOWLEDGE_RX 0x01 | 715 | #define GRACEFUL_STOP_ACKNOWLEDGE_RX 0x01 |
716 | 716 | ||
717 | /* structure representing InitEnet command */ | 717 | /* structure representing InitEnet command */ |
718 | typedef struct ucc_geth_init_pram { | 718 | struct ucc_geth_init_pram { |
719 | u8 resinit1; | 719 | u8 resinit1; |
720 | u8 resinit2; | 720 | u8 resinit2; |
721 | u8 resinit3; | 721 | u8 resinit3; |
@@ -729,7 +729,7 @@ typedef struct ucc_geth_init_pram { | |||
729 | u32 txglobal; /* tx global */ | 729 | u32 txglobal; /* tx global */ |
730 | u32 txthread[ENET_INIT_PARAM_MAX_ENTRIES_TX]; /* tx threads */ | 730 | u32 txthread[ENET_INIT_PARAM_MAX_ENTRIES_TX]; /* tx threads */ |
731 | u8 res3[0x1]; | 731 | u8 res3[0x1]; |
732 | } __attribute__ ((packed)) ucc_geth_init_pram_t; | 732 | } __attribute__ ((packed)); |
733 | 733 | ||
734 | #define ENET_INIT_PARAM_RGF_SHIFT (32 - 4) | 734 | #define ENET_INIT_PARAM_RGF_SHIFT (32 - 4) |
735 | #define ENET_INIT_PARAM_TGF_SHIFT (32 - 8) | 735 | #define ENET_INIT_PARAM_TGF_SHIFT (32 - 8) |
@@ -746,27 +746,27 @@ typedef struct ucc_geth_init_pram { | |||
746 | #define ENET_INIT_PARAM_MAGIC_RES_INIT5 0x0400 | 746 | #define ENET_INIT_PARAM_MAGIC_RES_INIT5 0x0400 |
747 | 747 | ||
748 | /* structure representing 82xx Address Filtering Enet Address in PRAM */ | 748 | /* structure representing 82xx Address Filtering Enet Address in PRAM */ |
749 | typedef struct ucc_geth_82xx_enet_address { | 749 | struct ucc_geth_82xx_enet_address { |
750 | u8 res1[0x2]; | 750 | u8 res1[0x2]; |
751 | u16 h; /* address (MSB) */ | 751 | u16 h; /* address (MSB) */ |
752 | u16 m; /* address */ | 752 | u16 m; /* address */ |
753 | u16 l; /* address (LSB) */ | 753 | u16 l; /* address (LSB) */ |
754 | } __attribute__ ((packed)) ucc_geth_82xx_enet_address_t; | 754 | } __attribute__ ((packed)); |
755 | 755 | ||
756 | /* structure representing 82xx Address Filtering PRAM */ | 756 | /* structure representing 82xx Address Filtering PRAM */ |
757 | typedef struct ucc_geth_82xx_address_filtering_pram { | 757 | struct ucc_geth_82xx_address_filtering_pram { |
758 | u32 iaddr_h; /* individual address filter, high */ | 758 | u32 iaddr_h; /* individual address filter, high */ |
759 | u32 iaddr_l; /* individual address filter, low */ | 759 | u32 iaddr_l; /* individual address filter, low */ |
760 | u32 gaddr_h; /* group address filter, high */ | 760 | u32 gaddr_h; /* group address filter, high */ |
761 | u32 gaddr_l; /* group address filter, low */ | 761 | u32 gaddr_l; /* group address filter, low */ |
762 | ucc_geth_82xx_enet_address_t taddr; | 762 | struct ucc_geth_82xx_enet_address taddr; |
763 | ucc_geth_82xx_enet_address_t paddr[NUM_OF_PADDRS]; | 763 | struct ucc_geth_82xx_enet_address paddr[NUM_OF_PADDRS]; |
764 | u8 res0[0x40 - 0x38]; | 764 | u8 res0[0x40 - 0x38]; |
765 | } __attribute__ ((packed)) ucc_geth_82xx_address_filtering_pram_t; | 765 | } __attribute__ ((packed)); |
766 | 766 | ||
767 | /* GETH Tx firmware statistics structure, used when calling | 767 | /* GETH Tx firmware statistics structure, used when calling |
768 | UCC_GETH_GetStatistics. */ | 768 | UCC_GETH_GetStatistics. */ |
769 | typedef struct ucc_geth_tx_firmware_statistics { | 769 | struct ucc_geth_tx_firmware_statistics { |
770 | u32 sicoltx; /* single collision */ | 770 | u32 sicoltx; /* single collision */ |
771 | u32 mulcoltx; /* multiple collision */ | 771 | u32 mulcoltx; /* multiple collision */ |
772 | u32 latecoltxfr; /* late collision */ | 772 | u32 latecoltxfr; /* late collision */ |
@@ -786,11 +786,11 @@ typedef struct ucc_geth_tx_firmware_statistics { | |||
786 | and 1518 octets */ | 786 | and 1518 octets */ |
787 | u32 txpktsjumbo; /* total packets (including bad) between 1024 | 787 | u32 txpktsjumbo; /* total packets (including bad) between 1024 |
788 | and MAXLength octets */ | 788 | and MAXLength octets */ |
789 | } __attribute__ ((packed)) ucc_geth_tx_firmware_statistics_t; | 789 | } __attribute__ ((packed)); |
790 | 790 | ||
791 | /* GETH Rx firmware statistics structure, used when calling | 791 | /* GETH Rx firmware statistics structure, used when calling |
792 | UCC_GETH_GetStatistics. */ | 792 | UCC_GETH_GetStatistics. */ |
793 | typedef struct ucc_geth_rx_firmware_statistics { | 793 | struct ucc_geth_rx_firmware_statistics { |
794 | u32 frrxfcser; /* frames with crc error */ | 794 | u32 frrxfcser; /* frames with crc error */ |
795 | u32 fraligner; /* frames with alignment error */ | 795 | u32 fraligner; /* frames with alignment error */ |
796 | u32 inrangelenrxer; /* in range length error */ | 796 | u32 inrangelenrxer; /* in range length error */ |
@@ -822,11 +822,11 @@ typedef struct ucc_geth_rx_firmware_statistics { | |||
822 | replaced */ | 822 | replaced */ |
823 | u32 insertvlan; /* total frames that had their VLAN tag | 823 | u32 insertvlan; /* total frames that had their VLAN tag |
824 | inserted */ | 824 | inserted */ |
825 | } __attribute__ ((packed)) ucc_geth_rx_firmware_statistics_t; | 825 | } __attribute__ ((packed)); |
826 | 826 | ||
827 | /* GETH hardware statistics structure, used when calling | 827 | /* GETH hardware statistics structure, used when calling |
828 | UCC_GETH_GetStatistics. */ | 828 | UCC_GETH_GetStatistics. */ |
829 | typedef struct ucc_geth_hardware_statistics { | 829 | struct ucc_geth_hardware_statistics { |
830 | u32 tx64; /* Total number of frames (including bad | 830 | u32 tx64; /* Total number of frames (including bad |
831 | frames) transmitted that were exactly of the | 831 | frames) transmitted that were exactly of the |
832 | minimal length (64 for un tagged, 68 for | 832 | minimal length (64 for un tagged, 68 for |
@@ -871,7 +871,7 @@ typedef struct ucc_geth_hardware_statistics { | |||
871 | u32 rbca; /* Total number of frames received succesfully | 871 | u32 rbca; /* Total number of frames received succesfully |
872 | that had destination address equal to the | 872 | that had destination address equal to the |
873 | broadcast address */ | 873 | broadcast address */ |
874 | } __attribute__ ((packed)) ucc_geth_hardware_statistics_t; | 874 | } __attribute__ ((packed)); |
875 | 875 | ||
876 | /* UCC GETH Tx errors returned via TxConf callback */ | 876 | /* UCC GETH Tx errors returned via TxConf callback */ |
877 | #define TX_ERRORS_DEF 0x0200 | 877 | #define TX_ERRORS_DEF 0x0200 |
@@ -1013,21 +1013,21 @@ typedef struct ucc_geth_hardware_statistics { | |||
1013 | (MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_112) | 1013 | (MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_112) |
1014 | 1014 | ||
1015 | /* Ethernet speed */ | 1015 | /* Ethernet speed */ |
1016 | typedef enum enet_speed { | 1016 | enum enet_speed { |
1017 | ENET_SPEED_10BT, /* 10 Base T */ | 1017 | ENET_SPEED_10BT, /* 10 Base T */ |
1018 | ENET_SPEED_100BT, /* 100 Base T */ | 1018 | ENET_SPEED_100BT, /* 100 Base T */ |
1019 | ENET_SPEED_1000BT /* 1000 Base T */ | 1019 | ENET_SPEED_1000BT /* 1000 Base T */ |
1020 | } enet_speed_e; | 1020 | }; |
1021 | 1021 | ||
1022 | /* Ethernet Address Type. */ | 1022 | /* Ethernet Address Type. */ |
1023 | typedef enum enet_addr_type { | 1023 | enum enet_addr_type { |
1024 | ENET_ADDR_TYPE_INDIVIDUAL, | 1024 | ENET_ADDR_TYPE_INDIVIDUAL, |
1025 | ENET_ADDR_TYPE_GROUP, | 1025 | ENET_ADDR_TYPE_GROUP, |
1026 | ENET_ADDR_TYPE_BROADCAST | 1026 | ENET_ADDR_TYPE_BROADCAST |
1027 | } enet_addr_type_e; | 1027 | }; |
1028 | 1028 | ||
1029 | /* TBI / MII Set Register */ | 1029 | /* TBI / MII Set Register */ |
1030 | typedef enum enet_tbi_mii_reg { | 1030 | enum enet_tbi_mii_reg { |
1031 | ENET_TBI_MII_CR = 0x00, /* Control (CR ) */ | 1031 | ENET_TBI_MII_CR = 0x00, /* Control (CR ) */ |
1032 | ENET_TBI_MII_SR = 0x01, /* Status (SR ) */ | 1032 | ENET_TBI_MII_SR = 0x01, /* Status (SR ) */ |
1033 | ENET_TBI_MII_ANA = 0x04, /* AN advertisement (ANA ) */ | 1033 | ENET_TBI_MII_ANA = 0x04, /* AN advertisement (ANA ) */ |
@@ -1040,10 +1040,10 @@ typedef enum enet_tbi_mii_reg { | |||
1040 | ENET_TBI_MII_EXST = 0x0F, /* Extended status (EXST ) */ | 1040 | ENET_TBI_MII_EXST = 0x0F, /* Extended status (EXST ) */ |
1041 | ENET_TBI_MII_JD = 0x10, /* Jitter diagnostics (JD ) */ | 1041 | ENET_TBI_MII_JD = 0x10, /* Jitter diagnostics (JD ) */ |
1042 | ENET_TBI_MII_TBICON = 0x11 /* TBI control (TBICON ) */ | 1042 | ENET_TBI_MII_TBICON = 0x11 /* TBI control (TBICON ) */ |
1043 | } enet_tbi_mii_reg_e; | 1043 | }; |
1044 | 1044 | ||
1045 | /* UCC GETH 82xx Ethernet Address Recognition Location */ | 1045 | /* UCC GETH 82xx Ethernet Address Recognition Location */ |
1046 | typedef enum ucc_geth_enet_address_recognition_location { | 1046 | enum ucc_geth_enet_address_recognition_location { |
1047 | UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_STATION_ADDRESS,/* station | 1047 | UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_STATION_ADDRESS,/* station |
1048 | address */ | 1048 | address */ |
1049 | UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_PADDR_FIRST, /* additional | 1049 | UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_PADDR_FIRST, /* additional |
@@ -1065,10 +1065,10 @@ typedef enum ucc_geth_enet_address_recognition_location { | |||
1065 | UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_GROUP_HASH, /* group hash */ | 1065 | UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_GROUP_HASH, /* group hash */ |
1066 | UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_INDIVIDUAL_HASH /* individual | 1066 | UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_INDIVIDUAL_HASH /* individual |
1067 | hash */ | 1067 | hash */ |
1068 | } ucc_geth_enet_address_recognition_location_e; | 1068 | }; |
1069 | 1069 | ||
1070 | /* UCC GETH vlan operation tagged */ | 1070 | /* UCC GETH vlan operation tagged */ |
1071 | typedef enum ucc_geth_vlan_operation_tagged { | 1071 | enum ucc_geth_vlan_operation_tagged { |
1072 | UCC_GETH_VLAN_OPERATION_TAGGED_NOP = 0x0, /* Tagged - nop */ | 1072 | UCC_GETH_VLAN_OPERATION_TAGGED_NOP = 0x0, /* Tagged - nop */ |
1073 | UCC_GETH_VLAN_OPERATION_TAGGED_REPLACE_VID_PORTION_OF_Q_TAG | 1073 | UCC_GETH_VLAN_OPERATION_TAGGED_REPLACE_VID_PORTION_OF_Q_TAG |
1074 | = 0x1, /* Tagged - replace vid portion of q tag */ | 1074 | = 0x1, /* Tagged - replace vid portion of q tag */ |
@@ -1076,18 +1076,18 @@ typedef enum ucc_geth_vlan_operation_tagged { | |||
1076 | = 0x2, /* Tagged - if vid0 replace vid with default value */ | 1076 | = 0x2, /* Tagged - if vid0 replace vid with default value */ |
1077 | UCC_GETH_VLAN_OPERATION_TAGGED_EXTRACT_Q_TAG_FROM_FRAME | 1077 | UCC_GETH_VLAN_OPERATION_TAGGED_EXTRACT_Q_TAG_FROM_FRAME |
1078 | = 0x3 /* Tagged - extract q tag from frame */ | 1078 | = 0x3 /* Tagged - extract q tag from frame */ |
1079 | } ucc_geth_vlan_operation_tagged_e; | 1079 | }; |
1080 | 1080 | ||
1081 | /* UCC GETH vlan operation non-tagged */ | 1081 | /* UCC GETH vlan operation non-tagged */ |
1082 | typedef enum ucc_geth_vlan_operation_non_tagged { | 1082 | enum ucc_geth_vlan_operation_non_tagged { |
1083 | UCC_GETH_VLAN_OPERATION_NON_TAGGED_NOP = 0x0, /* Non tagged - nop */ | 1083 | UCC_GETH_VLAN_OPERATION_NON_TAGGED_NOP = 0x0, /* Non tagged - nop */ |
1084 | UCC_GETH_VLAN_OPERATION_NON_TAGGED_Q_TAG_INSERT = 0x1 /* Non tagged - | 1084 | UCC_GETH_VLAN_OPERATION_NON_TAGGED_Q_TAG_INSERT = 0x1 /* Non tagged - |
1085 | q tag insert | 1085 | q tag insert |
1086 | */ | 1086 | */ |
1087 | } ucc_geth_vlan_operation_non_tagged_e; | 1087 | }; |
1088 | 1088 | ||
1089 | /* UCC GETH Rx Quality of Service Mode */ | 1089 | /* UCC GETH Rx Quality of Service Mode */ |
1090 | typedef enum ucc_geth_qos_mode { | 1090 | enum ucc_geth_qos_mode { |
1091 | UCC_GETH_QOS_MODE_DEFAULT = 0x0, /* default queue */ | 1091 | UCC_GETH_QOS_MODE_DEFAULT = 0x0, /* default queue */ |
1092 | UCC_GETH_QOS_MODE_QUEUE_NUM_FROM_L2_CRITERIA = 0x1, /* queue | 1092 | UCC_GETH_QOS_MODE_QUEUE_NUM_FROM_L2_CRITERIA = 0x1, /* queue |
1093 | determined | 1093 | determined |
@@ -1097,11 +1097,11 @@ typedef enum ucc_geth_qos_mode { | |||
1097 | determined | 1097 | determined |
1098 | by L3 | 1098 | by L3 |
1099 | criteria */ | 1099 | criteria */ |
1100 | } ucc_geth_qos_mode_e; | 1100 | }; |
1101 | 1101 | ||
1102 | /* UCC GETH Statistics Gathering Mode - These are bit flags, 'or' them together | 1102 | /* UCC GETH Statistics Gathering Mode - These are bit flags, 'or' them together |
1103 | for combined functionality */ | 1103 | for combined functionality */ |
1104 | typedef enum ucc_geth_statistics_gathering_mode { | 1104 | enum ucc_geth_statistics_gathering_mode { |
1105 | UCC_GETH_STATISTICS_GATHERING_MODE_NONE = 0x00000000, /* No | 1105 | UCC_GETH_STATISTICS_GATHERING_MODE_NONE = 0x00000000, /* No |
1106 | statistics | 1106 | statistics |
1107 | gathering */ | 1107 | gathering */ |
@@ -1122,10 +1122,10 @@ typedef enum ucc_geth_statistics_gathering_mode { | |||
1122 | statistics | 1122 | statistics |
1123 | gathering | 1123 | gathering |
1124 | */ | 1124 | */ |
1125 | } ucc_geth_statistics_gathering_mode_e; | 1125 | }; |
1126 | 1126 | ||
1127 | /* UCC GETH Pad and CRC Mode - Note, Padding without CRC is not possible */ | 1127 | /* UCC GETH Pad and CRC Mode - Note, Padding without CRC is not possible */ |
1128 | typedef enum ucc_geth_maccfg2_pad_and_crc_mode { | 1128 | enum ucc_geth_maccfg2_pad_and_crc_mode { |
1129 | UCC_GETH_PAD_AND_CRC_MODE_NONE | 1129 | UCC_GETH_PAD_AND_CRC_MODE_NONE |
1130 | = MACCFG2_PAD_AND_CRC_MODE_NONE, /* Neither Padding | 1130 | = MACCFG2_PAD_AND_CRC_MODE_NONE, /* Neither Padding |
1131 | short frames | 1131 | short frames |
@@ -1135,61 +1135,59 @@ typedef enum ucc_geth_maccfg2_pad_and_crc_mode { | |||
1135 | CRC only */ | 1135 | CRC only */ |
1136 | UCC_GETH_PAD_AND_CRC_MODE_PAD_AND_CRC = | 1136 | UCC_GETH_PAD_AND_CRC_MODE_PAD_AND_CRC = |
1137 | MACCFG2_PAD_AND_CRC_MODE_PAD_AND_CRC | 1137 | MACCFG2_PAD_AND_CRC_MODE_PAD_AND_CRC |
1138 | } ucc_geth_maccfg2_pad_and_crc_mode_e; | 1138 | }; |
1139 | 1139 | ||
1140 | /* UCC GETH upsmr Flow Control Mode */ | 1140 | /* UCC GETH upsmr Flow Control Mode */ |
1141 | typedef enum ucc_geth_flow_control_mode { | 1141 | enum ucc_geth_flow_control_mode { |
1142 | UPSMR_AUTOMATIC_FLOW_CONTROL_MODE_NONE = 0x00000000, /* No automatic | 1142 | UPSMR_AUTOMATIC_FLOW_CONTROL_MODE_NONE = 0x00000000, /* No automatic |
1143 | flow control | 1143 | flow control |
1144 | */ | 1144 | */ |
1145 | UPSMR_AUTOMATIC_FLOW_CONTROL_MODE_PAUSE_WHEN_EMERGENCY | 1145 | UPSMR_AUTOMATIC_FLOW_CONTROL_MODE_PAUSE_WHEN_EMERGENCY |
1146 | = 0x00004000 /* Send pause frame when RxFIFO reaches its | 1146 | = 0x00004000 /* Send pause frame when RxFIFO reaches its |
1147 | emergency threshold */ | 1147 | emergency threshold */ |
1148 | } ucc_geth_flow_control_mode_e; | 1148 | }; |
1149 | 1149 | ||
1150 | /* UCC GETH number of threads */ | 1150 | /* UCC GETH number of threads */ |
1151 | typedef enum ucc_geth_num_of_threads { | 1151 | enum ucc_geth_num_of_threads { |
1152 | UCC_GETH_NUM_OF_THREADS_1 = 0x1, /* 1 */ | 1152 | UCC_GETH_NUM_OF_THREADS_1 = 0x1, /* 1 */ |
1153 | UCC_GETH_NUM_OF_THREADS_2 = 0x2, /* 2 */ | 1153 | UCC_GETH_NUM_OF_THREADS_2 = 0x2, /* 2 */ |
1154 | UCC_GETH_NUM_OF_THREADS_4 = 0x0, /* 4 */ | 1154 | UCC_GETH_NUM_OF_THREADS_4 = 0x0, /* 4 */ |
1155 | UCC_GETH_NUM_OF_THREADS_6 = 0x3, /* 6 */ | 1155 | UCC_GETH_NUM_OF_THREADS_6 = 0x3, /* 6 */ |
1156 | UCC_GETH_NUM_OF_THREADS_8 = 0x4 /* 8 */ | 1156 | UCC_GETH_NUM_OF_THREADS_8 = 0x4 /* 8 */ |
1157 | } ucc_geth_num_of_threads_e; | 1157 | }; |
1158 | 1158 | ||
1159 | /* UCC GETH number of station addresses */ | 1159 | /* UCC GETH number of station addresses */ |
1160 | typedef enum ucc_geth_num_of_station_addresses { | 1160 | enum ucc_geth_num_of_station_addresses { |
1161 | UCC_GETH_NUM_OF_STATION_ADDRESSES_1, /* 1 */ | 1161 | UCC_GETH_NUM_OF_STATION_ADDRESSES_1, /* 1 */ |
1162 | UCC_GETH_NUM_OF_STATION_ADDRESSES_5 /* 5 */ | 1162 | UCC_GETH_NUM_OF_STATION_ADDRESSES_5 /* 5 */ |
1163 | } ucc_geth_num_of_station_addresses_e; | 1163 | }; |
1164 | |||
1165 | typedef u8 enet_addr_t[ENET_NUM_OCTETS_PER_ADDRESS]; | ||
1166 | 1164 | ||
1167 | /* UCC GETH 82xx Ethernet Address Container */ | 1165 | /* UCC GETH 82xx Ethernet Address Container */ |
1168 | typedef struct enet_addr_container { | 1166 | struct enet_addr_container { |
1169 | enet_addr_t address; /* ethernet address */ | 1167 | u8 address[ENET_NUM_OCTETS_PER_ADDRESS]; /* ethernet address */ |
1170 | ucc_geth_enet_address_recognition_location_e location; /* location in | 1168 | enum ucc_geth_enet_address_recognition_location location; /* location in |
1171 | 82xx address | 1169 | 82xx address |
1172 | recognition | 1170 | recognition |
1173 | hardware */ | 1171 | hardware */ |
1174 | struct list_head node; | 1172 | struct list_head node; |
1175 | } enet_addr_container_t; | 1173 | }; |
1176 | 1174 | ||
1177 | #define ENET_ADDR_CONT_ENTRY(ptr) list_entry(ptr, enet_addr_container_t, node) | 1175 | #define ENET_ADDR_CONT_ENTRY(ptr) list_entry(ptr, struct enet_addr_container, node) |
1178 | 1176 | ||
1179 | /* UCC GETH Termination Action Descriptor (TAD) structure. */ | 1177 | /* UCC GETH Termination Action Descriptor (TAD) structure. */ |
1180 | typedef struct ucc_geth_tad_params { | 1178 | struct ucc_geth_tad_params { |
1181 | int rx_non_dynamic_extended_features_mode; | 1179 | int rx_non_dynamic_extended_features_mode; |
1182 | int reject_frame; | 1180 | int reject_frame; |
1183 | ucc_geth_vlan_operation_tagged_e vtag_op; | 1181 | enum ucc_geth_vlan_operation_tagged vtag_op; |
1184 | ucc_geth_vlan_operation_non_tagged_e vnontag_op; | 1182 | enum ucc_geth_vlan_operation_non_tagged vnontag_op; |
1185 | ucc_geth_qos_mode_e rqos; | 1183 | enum ucc_geth_qos_mode rqos; |
1186 | u8 vpri; | 1184 | u8 vpri; |
1187 | u16 vid; | 1185 | u16 vid; |
1188 | } ucc_geth_tad_params_t; | 1186 | }; |
1189 | 1187 | ||
1190 | /* GETH protocol initialization structure */ | 1188 | /* GETH protocol initialization structure */ |
1191 | typedef struct ucc_geth_info { | 1189 | struct ucc_geth_info { |
1192 | ucc_fast_info_t uf_info; | 1190 | struct ucc_fast_info uf_info; |
1193 | u8 numQueuesTx; | 1191 | u8 numQueuesTx; |
1194 | u8 numQueuesRx; | 1192 | u8 numQueuesRx; |
1195 | int ipCheckSumCheck; | 1193 | int ipCheckSumCheck; |
@@ -1251,51 +1249,51 @@ typedef struct ucc_geth_info { | |||
1251 | u8 iphoffset[TX_IP_OFFSET_ENTRY_MAX]; | 1249 | u8 iphoffset[TX_IP_OFFSET_ENTRY_MAX]; |
1252 | u16 bdRingLenTx[NUM_TX_QUEUES]; | 1250 | u16 bdRingLenTx[NUM_TX_QUEUES]; |
1253 | u16 bdRingLenRx[NUM_RX_QUEUES]; | 1251 | u16 bdRingLenRx[NUM_RX_QUEUES]; |
1254 | enet_interface_e enet_interface; | 1252 | enum enet_interface enet_interface; |
1255 | ucc_geth_num_of_station_addresses_e numStationAddresses; | 1253 | enum ucc_geth_num_of_station_addresses numStationAddresses; |
1256 | qe_fltr_largest_external_tbl_lookup_key_size_e | 1254 | enum qe_fltr_largest_external_tbl_lookup_key_size |
1257 | largestexternallookupkeysize; | 1255 | largestexternallookupkeysize; |
1258 | ucc_geth_statistics_gathering_mode_e statisticsMode; | 1256 | enum ucc_geth_statistics_gathering_mode statisticsMode; |
1259 | ucc_geth_vlan_operation_tagged_e vlanOperationTagged; | 1257 | enum ucc_geth_vlan_operation_tagged vlanOperationTagged; |
1260 | ucc_geth_vlan_operation_non_tagged_e vlanOperationNonTagged; | 1258 | enum ucc_geth_vlan_operation_non_tagged vlanOperationNonTagged; |
1261 | ucc_geth_qos_mode_e rxQoSMode; | 1259 | enum ucc_geth_qos_mode rxQoSMode; |
1262 | ucc_geth_flow_control_mode_e aufc; | 1260 | enum ucc_geth_flow_control_mode aufc; |
1263 | ucc_geth_maccfg2_pad_and_crc_mode_e padAndCrc; | 1261 | enum ucc_geth_maccfg2_pad_and_crc_mode padAndCrc; |
1264 | ucc_geth_num_of_threads_e numThreadsTx; | 1262 | enum ucc_geth_num_of_threads numThreadsTx; |
1265 | ucc_geth_num_of_threads_e numThreadsRx; | 1263 | enum ucc_geth_num_of_threads numThreadsRx; |
1266 | qe_risc_allocation_e riscTx; | 1264 | enum qe_risc_allocation riscTx; |
1267 | qe_risc_allocation_e riscRx; | 1265 | enum qe_risc_allocation riscRx; |
1268 | } ucc_geth_info_t; | 1266 | }; |
1269 | 1267 | ||
1270 | /* structure representing UCC GETH */ | 1268 | /* structure representing UCC GETH */ |
1271 | typedef struct ucc_geth_private { | 1269 | struct ucc_geth_private { |
1272 | ucc_geth_info_t *ug_info; | 1270 | struct ucc_geth_info *ug_info; |
1273 | ucc_fast_private_t *uccf; | 1271 | struct ucc_fast_private *uccf; |
1274 | struct net_device *dev; | 1272 | struct net_device *dev; |
1275 | struct net_device_stats stats; /* linux network statistics */ | 1273 | struct net_device_stats stats; /* linux network statistics */ |
1276 | ucc_geth_t *ug_regs; | 1274 | struct ucc_geth *ug_regs; |
1277 | ucc_geth_init_pram_t *p_init_enet_param_shadow; | 1275 | struct ucc_geth_init_pram *p_init_enet_param_shadow; |
1278 | ucc_geth_exf_global_pram_t *p_exf_glbl_param; | 1276 | struct ucc_geth_exf_global_pram *p_exf_glbl_param; |
1279 | u32 exf_glbl_param_offset; | 1277 | u32 exf_glbl_param_offset; |
1280 | ucc_geth_rx_global_pram_t *p_rx_glbl_pram; | 1278 | struct ucc_geth_rx_global_pram *p_rx_glbl_pram; |
1281 | u32 rx_glbl_pram_offset; | 1279 | u32 rx_glbl_pram_offset; |
1282 | ucc_geth_tx_global_pram_t *p_tx_glbl_pram; | 1280 | struct ucc_geth_tx_global_pram *p_tx_glbl_pram; |
1283 | u32 tx_glbl_pram_offset; | 1281 | u32 tx_glbl_pram_offset; |
1284 | ucc_geth_send_queue_mem_region_t *p_send_q_mem_reg; | 1282 | struct ucc_geth_send_queue_mem_region *p_send_q_mem_reg; |
1285 | u32 send_q_mem_reg_offset; | 1283 | u32 send_q_mem_reg_offset; |
1286 | ucc_geth_thread_data_tx_t *p_thread_data_tx; | 1284 | struct ucc_geth_thread_data_tx *p_thread_data_tx; |
1287 | u32 thread_dat_tx_offset; | 1285 | u32 thread_dat_tx_offset; |
1288 | ucc_geth_thread_data_rx_t *p_thread_data_rx; | 1286 | struct ucc_geth_thread_data_rx *p_thread_data_rx; |
1289 | u32 thread_dat_rx_offset; | 1287 | u32 thread_dat_rx_offset; |
1290 | ucc_geth_scheduler_t *p_scheduler; | 1288 | struct ucc_geth_scheduler *p_scheduler; |
1291 | u32 scheduler_offset; | 1289 | u32 scheduler_offset; |
1292 | ucc_geth_tx_firmware_statistics_pram_t *p_tx_fw_statistics_pram; | 1290 | struct ucc_geth_tx_firmware_statistics_pram *p_tx_fw_statistics_pram; |
1293 | u32 tx_fw_statistics_pram_offset; | 1291 | u32 tx_fw_statistics_pram_offset; |
1294 | ucc_geth_rx_firmware_statistics_pram_t *p_rx_fw_statistics_pram; | 1292 | struct ucc_geth_rx_firmware_statistics_pram *p_rx_fw_statistics_pram; |
1295 | u32 rx_fw_statistics_pram_offset; | 1293 | u32 rx_fw_statistics_pram_offset; |
1296 | ucc_geth_rx_interrupt_coalescing_table_t *p_rx_irq_coalescing_tbl; | 1294 | struct ucc_geth_rx_interrupt_coalescing_table *p_rx_irq_coalescing_tbl; |
1297 | u32 rx_irq_coalescing_tbl_offset; | 1295 | u32 rx_irq_coalescing_tbl_offset; |
1298 | ucc_geth_rx_bd_queues_entry_t *p_rx_bd_qs_tbl; | 1296 | struct ucc_geth_rx_bd_queues_entry *p_rx_bd_qs_tbl; |
1299 | u32 rx_bd_qs_tbl_offset; | 1297 | u32 rx_bd_qs_tbl_offset; |
1300 | u8 *p_tx_bd_ring[NUM_TX_QUEUES]; | 1298 | u8 *p_tx_bd_ring[NUM_TX_QUEUES]; |
1301 | u32 tx_bd_ring_offset[NUM_TX_QUEUES]; | 1299 | u32 tx_bd_ring_offset[NUM_TX_QUEUES]; |
@@ -1308,7 +1306,7 @@ typedef struct ucc_geth_private { | |||
1308 | u16 cpucount[NUM_TX_QUEUES]; | 1306 | u16 cpucount[NUM_TX_QUEUES]; |
1309 | volatile u16 *p_cpucount[NUM_TX_QUEUES]; | 1307 | volatile u16 *p_cpucount[NUM_TX_QUEUES]; |
1310 | int indAddrRegUsed[NUM_OF_PADDRS]; | 1308 | int indAddrRegUsed[NUM_OF_PADDRS]; |
1311 | enet_addr_t paddr[NUM_OF_PADDRS]; | 1309 | u8 paddr[NUM_OF_PADDRS][ENET_NUM_OCTETS_PER_ADDRESS]; /* ethernet address */ |
1312 | u8 numGroupAddrInHash; | 1310 | u8 numGroupAddrInHash; |
1313 | u8 numIndAddrInHash; | 1311 | u8 numIndAddrInHash; |
1314 | u8 numIndAddrInReg; | 1312 | u8 numIndAddrInReg; |
@@ -1334,6 +1332,6 @@ typedef struct ucc_geth_private { | |||
1334 | int oldspeed; | 1332 | int oldspeed; |
1335 | int oldduplex; | 1333 | int oldduplex; |
1336 | int oldlink; | 1334 | int oldlink; |
1337 | } ucc_geth_private_t; | 1335 | }; |
1338 | 1336 | ||
1339 | #endif /* __UCC_GETH_H__ */ | 1337 | #endif /* __UCC_GETH_H__ */ |
diff --git a/drivers/net/ucc_geth_phy.c b/drivers/net/ucc_geth_phy.c index 67260eb3188a..5360ec05eaa3 100644 --- a/drivers/net/ucc_geth_phy.c +++ b/drivers/net/ucc_geth_phy.c | |||
@@ -42,7 +42,6 @@ | |||
42 | 42 | ||
43 | #include "ucc_geth.h" | 43 | #include "ucc_geth.h" |
44 | #include "ucc_geth_phy.h" | 44 | #include "ucc_geth_phy.h" |
45 | #include <platforms/83xx/mpc8360e_pb.h> | ||
46 | 45 | ||
47 | #define ugphy_printk(level, format, arg...) \ | 46 | #define ugphy_printk(level, format, arg...) \ |
48 | printk(level format "\n", ## arg) | 47 | printk(level format "\n", ## arg) |
@@ -72,16 +71,14 @@ static int genmii_read_status(struct ugeth_mii_info *mii_info); | |||
72 | u16 phy_read(struct ugeth_mii_info *mii_info, u16 regnum); | 71 | u16 phy_read(struct ugeth_mii_info *mii_info, u16 regnum); |
73 | void phy_write(struct ugeth_mii_info *mii_info, u16 regnum, u16 val); | 72 | void phy_write(struct ugeth_mii_info *mii_info, u16 regnum, u16 val); |
74 | 73 | ||
75 | static u8 *bcsr_regs = NULL; | ||
76 | |||
77 | /* Write value to the PHY for this device to the register at regnum, */ | 74 | /* Write value to the PHY for this device to the register at regnum, */ |
78 | /* waiting until the write is done before it returns. All PHY */ | 75 | /* waiting until the write is done before it returns. All PHY */ |
79 | /* configuration has to be done through the TSEC1 MIIM regs */ | 76 | /* configuration has to be done through the TSEC1 MIIM regs */ |
80 | void write_phy_reg(struct net_device *dev, int mii_id, int regnum, int value) | 77 | void write_phy_reg(struct net_device *dev, int mii_id, int regnum, int value) |
81 | { | 78 | { |
82 | ucc_geth_private_t *ugeth = netdev_priv(dev); | 79 | struct ucc_geth_private *ugeth = netdev_priv(dev); |
83 | ucc_mii_mng_t *mii_regs; | 80 | struct ucc_mii_mng *mii_regs; |
84 | enet_tbi_mii_reg_e mii_reg = (enet_tbi_mii_reg_e) regnum; | 81 | enum enet_tbi_mii_reg mii_reg = (enum enet_tbi_mii_reg) regnum; |
85 | u32 tmp_reg; | 82 | u32 tmp_reg; |
86 | 83 | ||
87 | ugphy_vdbg("%s: IN", __FUNCTION__); | 84 | ugphy_vdbg("%s: IN", __FUNCTION__); |
@@ -116,9 +113,9 @@ void write_phy_reg(struct net_device *dev, int mii_id, int regnum, int value) | |||
116 | /* configuration has to be done through the TSEC1 MIIM regs */ | 113 | /* configuration has to be done through the TSEC1 MIIM regs */ |
117 | int read_phy_reg(struct net_device *dev, int mii_id, int regnum) | 114 | int read_phy_reg(struct net_device *dev, int mii_id, int regnum) |
118 | { | 115 | { |
119 | ucc_geth_private_t *ugeth = netdev_priv(dev); | 116 | struct ucc_geth_private *ugeth = netdev_priv(dev); |
120 | ucc_mii_mng_t *mii_regs; | 117 | struct ucc_mii_mng *mii_regs; |
121 | enet_tbi_mii_reg_e mii_reg = (enet_tbi_mii_reg_e) regnum; | 118 | enum enet_tbi_mii_reg mii_reg = (enum enet_tbi_mii_reg) regnum; |
122 | u32 tmp_reg; | 119 | u32 tmp_reg; |
123 | u16 value; | 120 | u16 value; |
124 | 121 | ||
@@ -634,11 +631,6 @@ static void dm9161_close(struct ugeth_mii_info *mii_info) | |||
634 | 631 | ||
635 | static int dm9161_ack_interrupt(struct ugeth_mii_info *mii_info) | 632 | static int dm9161_ack_interrupt(struct ugeth_mii_info *mii_info) |
636 | { | 633 | { |
637 | /* FIXME: This lines are for BUG fixing in the mpc8325. | ||
638 | Remove this from here when it's fixed */ | ||
639 | if (bcsr_regs == NULL) | ||
640 | bcsr_regs = (u8 *) ioremap(BCSR_PHYS_ADDR, BCSR_SIZE); | ||
641 | bcsr_regs[14] |= 0x40; | ||
642 | ugphy_vdbg("%s: IN", __FUNCTION__); | 634 | ugphy_vdbg("%s: IN", __FUNCTION__); |
643 | 635 | ||
644 | /* Clear the interrupts by reading the reg */ | 636 | /* Clear the interrupts by reading the reg */ |
@@ -650,12 +642,6 @@ Remove this from here when it's fixed */ | |||
650 | 642 | ||
651 | static int dm9161_config_intr(struct ugeth_mii_info *mii_info) | 643 | static int dm9161_config_intr(struct ugeth_mii_info *mii_info) |
652 | { | 644 | { |
653 | /* FIXME: This lines are for BUG fixing in the mpc8325. | ||
654 | Remove this from here when it's fixed */ | ||
655 | if (bcsr_regs == NULL) { | ||
656 | bcsr_regs = (u8 *) ioremap(BCSR_PHYS_ADDR, BCSR_SIZE); | ||
657 | bcsr_regs[14] &= ~0x40; | ||
658 | } | ||
659 | ugphy_vdbg("%s: IN", __FUNCTION__); | 645 | ugphy_vdbg("%s: IN", __FUNCTION__); |
660 | 646 | ||
661 | if (mii_info->interrupts == MII_INTERRUPT_ENABLED) | 647 | if (mii_info->interrupts == MII_INTERRUPT_ENABLED) |
diff --git a/drivers/net/ucc_geth_phy.h b/drivers/net/ucc_geth_phy.h index 2f98b8f1bb0a..f5740783670f 100644 --- a/drivers/net/ucc_geth_phy.h +++ b/drivers/net/ucc_geth_phy.h | |||
@@ -126,7 +126,7 @@ struct ugeth_mii_info { | |||
126 | /* And management functions */ | 126 | /* And management functions */ |
127 | struct phy_info *phyinfo; | 127 | struct phy_info *phyinfo; |
128 | 128 | ||
129 | ucc_mii_mng_t *mii_regs; | 129 | struct ucc_mii_mng *mii_regs; |
130 | 130 | ||
131 | /* forced speed & duplex (no autoneg) | 131 | /* forced speed & duplex (no autoneg) |
132 | * partner speed & duplex & pause (autoneg) | 132 | * partner speed & duplex & pause (autoneg) |
diff --git a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig index 58b7efbb0750..b5d0d7fb647a 100644 --- a/drivers/net/wan/Kconfig +++ b/drivers/net/wan/Kconfig | |||
@@ -127,7 +127,7 @@ config LANMEDIA | |||
127 | # There is no way to detect a Sealevel board. Force it modular | 127 | # There is no way to detect a Sealevel board. Force it modular |
128 | config SEALEVEL_4021 | 128 | config SEALEVEL_4021 |
129 | tristate "Sealevel Systems 4021 support" | 129 | tristate "Sealevel Systems 4021 support" |
130 | depends on WAN && ISA && m && ISA_DMA_API | 130 | depends on WAN && ISA && m && ISA_DMA_API && INET |
131 | help | 131 | help |
132 | This is a driver for the Sealevel Systems ACB 56 serial I/O adapter. | 132 | This is a driver for the Sealevel Systems ACB 56 serial I/O adapter. |
133 | 133 | ||
diff --git a/drivers/net/wan/n2.c b/drivers/net/wan/n2.c index dcf46add3adf..5c322dfb79f6 100644 --- a/drivers/net/wan/n2.c +++ b/drivers/net/wan/n2.c | |||
@@ -500,7 +500,7 @@ static int __init n2_init(void) | |||
500 | #ifdef MODULE | 500 | #ifdef MODULE |
501 | printk(KERN_INFO "n2: no card initialized\n"); | 501 | printk(KERN_INFO "n2: no card initialized\n"); |
502 | #endif | 502 | #endif |
503 | return -ENOSYS; /* no parameters specified, abort */ | 503 | return -EINVAL; /* no parameters specified, abort */ |
504 | } | 504 | } |
505 | 505 | ||
506 | printk(KERN_INFO "%s\n", version); | 506 | printk(KERN_INFO "%s\n", version); |
@@ -538,11 +538,11 @@ static int __init n2_init(void) | |||
538 | n2_run(io, irq, ram, valid[0], valid[1]); | 538 | n2_run(io, irq, ram, valid[0], valid[1]); |
539 | 539 | ||
540 | if (*hw == '\x0') | 540 | if (*hw == '\x0') |
541 | return first_card ? 0 : -ENOSYS; | 541 | return first_card ? 0 : -EINVAL; |
542 | }while(*hw++ == ':'); | 542 | }while(*hw++ == ':'); |
543 | 543 | ||
544 | printk(KERN_ERR "n2: invalid hardware parameters\n"); | 544 | printk(KERN_ERR "n2: invalid hardware parameters\n"); |
545 | return first_card ? 0 : -ENOSYS; | 545 | return first_card ? 0 : -EINVAL; |
546 | } | 546 | } |
547 | 547 | ||
548 | 548 | ||
diff --git a/drivers/net/wan/pc300_drv.c b/drivers/net/wan/pc300_drv.c index 5823e3bca178..36d1c3ff7078 100644 --- a/drivers/net/wan/pc300_drv.c +++ b/drivers/net/wan/pc300_drv.c | |||
@@ -2867,7 +2867,6 @@ static int ch_config(pc300dev_t * d) | |||
2867 | uclong clktype = chan->conf.phys_settings.clock_type; | 2867 | uclong clktype = chan->conf.phys_settings.clock_type; |
2868 | ucshort encoding = chan->conf.proto_settings.encoding; | 2868 | ucshort encoding = chan->conf.proto_settings.encoding; |
2869 | ucshort parity = chan->conf.proto_settings.parity; | 2869 | ucshort parity = chan->conf.proto_settings.parity; |
2870 | int tmc, br; | ||
2871 | ucchar md0, md2; | 2870 | ucchar md0, md2; |
2872 | 2871 | ||
2873 | /* Reset the channel */ | 2872 | /* Reset the channel */ |
@@ -2940,8 +2939,12 @@ static int ch_config(pc300dev_t * d) | |||
2940 | case PC300_RSV: | 2939 | case PC300_RSV: |
2941 | case PC300_X21: | 2940 | case PC300_X21: |
2942 | if (clktype == CLOCK_INT || clktype == CLOCK_TXINT) { | 2941 | if (clktype == CLOCK_INT || clktype == CLOCK_TXINT) { |
2942 | int tmc, br; | ||
2943 | |||
2943 | /* Calculate the clkrate parameters */ | 2944 | /* Calculate the clkrate parameters */ |
2944 | tmc = clock_rate_calc(clkrate, card->hw.clock, &br); | 2945 | tmc = clock_rate_calc(clkrate, card->hw.clock, &br); |
2946 | if (tmc < 0) | ||
2947 | return -EIO; | ||
2945 | cpc_writeb(scabase + M_REG(TMCT, ch), tmc); | 2948 | cpc_writeb(scabase + M_REG(TMCT, ch), tmc); |
2946 | cpc_writeb(scabase + M_REG(TXS, ch), | 2949 | cpc_writeb(scabase + M_REG(TXS, ch), |
2947 | (TXS_DTRXC | TXS_IBRG | br)); | 2950 | (TXS_DTRXC | TXS_IBRG | br)); |
@@ -3097,14 +3100,16 @@ static int cpc_attach(struct net_device *dev, unsigned short encoding, | |||
3097 | return 0; | 3100 | return 0; |
3098 | } | 3101 | } |
3099 | 3102 | ||
3100 | static void cpc_opench(pc300dev_t * d) | 3103 | static int cpc_opench(pc300dev_t * d) |
3101 | { | 3104 | { |
3102 | pc300ch_t *chan = (pc300ch_t *) d->chan; | 3105 | pc300ch_t *chan = (pc300ch_t *) d->chan; |
3103 | pc300_t *card = (pc300_t *) chan->card; | 3106 | pc300_t *card = (pc300_t *) chan->card; |
3104 | int ch = chan->channel; | 3107 | int ch = chan->channel, rc; |
3105 | void __iomem *scabase = card->hw.scabase; | 3108 | void __iomem *scabase = card->hw.scabase; |
3106 | 3109 | ||
3107 | ch_config(d); | 3110 | rc = ch_config(d); |
3111 | if (rc) | ||
3112 | return rc; | ||
3108 | 3113 | ||
3109 | rx_config(d); | 3114 | rx_config(d); |
3110 | 3115 | ||
@@ -3113,6 +3118,8 @@ static void cpc_opench(pc300dev_t * d) | |||
3113 | /* Assert RTS and DTR */ | 3118 | /* Assert RTS and DTR */ |
3114 | cpc_writeb(scabase + M_REG(CTL, ch), | 3119 | cpc_writeb(scabase + M_REG(CTL, ch), |
3115 | cpc_readb(scabase + M_REG(CTL, ch)) & ~(CTL_RTS | CTL_DTR)); | 3120 | cpc_readb(scabase + M_REG(CTL, ch)) & ~(CTL_RTS | CTL_DTR)); |
3121 | |||
3122 | return 0; | ||
3116 | } | 3123 | } |
3117 | 3124 | ||
3118 | static void cpc_closech(pc300dev_t * d) | 3125 | static void cpc_closech(pc300dev_t * d) |
@@ -3168,9 +3175,16 @@ int cpc_open(struct net_device *dev) | |||
3168 | } | 3175 | } |
3169 | 3176 | ||
3170 | sprintf(ifr.ifr_name, "%s", dev->name); | 3177 | sprintf(ifr.ifr_name, "%s", dev->name); |
3171 | cpc_opench(d); | 3178 | result = cpc_opench(d); |
3179 | if (result) | ||
3180 | goto err_out; | ||
3181 | |||
3172 | netif_start_queue(dev); | 3182 | netif_start_queue(dev); |
3173 | return 0; | 3183 | return 0; |
3184 | |||
3185 | err_out: | ||
3186 | hdlc_close(dev); | ||
3187 | return result; | ||
3174 | } | 3188 | } |
3175 | 3189 | ||
3176 | static int cpc_close(struct net_device *dev) | 3190 | static int cpc_close(struct net_device *dev) |
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index 0a33c8a56e13..efcdaf1c5f73 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c | |||
@@ -2897,6 +2897,8 @@ static struct net_device *_init_airo_card( unsigned short irq, int port, | |||
2897 | goto err_out_map; | 2897 | goto err_out_map; |
2898 | } | 2898 | } |
2899 | ai->wifidev = init_wifidev(ai, dev); | 2899 | ai->wifidev = init_wifidev(ai, dev); |
2900 | if (!ai->wifidev) | ||
2901 | goto err_out_reg; | ||
2900 | 2902 | ||
2901 | set_bit(FLAG_REGISTERED,&ai->flags); | 2903 | set_bit(FLAG_REGISTERED,&ai->flags); |
2902 | airo_print_info(dev->name, "MAC enabled %x:%x:%x:%x:%x:%x", | 2904 | airo_print_info(dev->name, "MAC enabled %x:%x:%x:%x:%x:%x", |
@@ -2908,11 +2910,18 @@ static struct net_device *_init_airo_card( unsigned short irq, int port, | |||
2908 | for( i = 0; i < MAX_FIDS; i++ ) | 2910 | for( i = 0; i < MAX_FIDS; i++ ) |
2909 | ai->fids[i] = transmit_allocate(ai,AIRO_DEF_MTU,i>=MAX_FIDS/2); | 2911 | ai->fids[i] = transmit_allocate(ai,AIRO_DEF_MTU,i>=MAX_FIDS/2); |
2910 | 2912 | ||
2911 | setup_proc_entry( dev, dev->priv ); /* XXX check for failure */ | 2913 | if (setup_proc_entry(dev, dev->priv) < 0) |
2914 | goto err_out_wifi; | ||
2915 | |||
2912 | netif_start_queue(dev); | 2916 | netif_start_queue(dev); |
2913 | SET_MODULE_OWNER(dev); | 2917 | SET_MODULE_OWNER(dev); |
2914 | return dev; | 2918 | return dev; |
2915 | 2919 | ||
2920 | err_out_wifi: | ||
2921 | unregister_netdev(ai->wifidev); | ||
2922 | free_netdev(ai->wifidev); | ||
2923 | err_out_reg: | ||
2924 | unregister_netdev(dev); | ||
2916 | err_out_map: | 2925 | err_out_map: |
2917 | if (test_bit(FLAG_MPI,&ai->flags) && pci) { | 2926 | if (test_bit(FLAG_MPI,&ai->flags) && pci) { |
2918 | pci_free_consistent(pci, PCI_SHARED_LEN, ai->shared, ai->shared_dma); | 2927 | pci_free_consistent(pci, PCI_SHARED_LEN, ai->shared, ai->shared_dma); |
@@ -3089,7 +3098,8 @@ static int airo_thread(void *data) { | |||
3089 | set_bit(JOB_AUTOWEP, &ai->jobs); | 3098 | set_bit(JOB_AUTOWEP, &ai->jobs); |
3090 | break; | 3099 | break; |
3091 | } | 3100 | } |
3092 | if (!kthread_should_stop()) { | 3101 | if (!kthread_should_stop() && |
3102 | !freezing(current)) { | ||
3093 | unsigned long wake_at; | 3103 | unsigned long wake_at; |
3094 | if (!ai->expires || !ai->scan_timeout) { | 3104 | if (!ai->expires || !ai->scan_timeout) { |
3095 | wake_at = max(ai->expires, | 3105 | wake_at = max(ai->expires, |
@@ -3101,7 +3111,8 @@ static int airo_thread(void *data) { | |||
3101 | schedule_timeout(wake_at - jiffies); | 3111 | schedule_timeout(wake_at - jiffies); |
3102 | continue; | 3112 | continue; |
3103 | } | 3113 | } |
3104 | } else if (!kthread_should_stop()) { | 3114 | } else if (!kthread_should_stop() && |
3115 | !freezing(current)) { | ||
3105 | schedule(); | 3116 | schedule(); |
3106 | continue; | 3117 | continue; |
3107 | } | 3118 | } |
@@ -4495,91 +4506,128 @@ static int setup_proc_entry( struct net_device *dev, | |||
4495 | apriv->proc_entry = create_proc_entry(apriv->proc_name, | 4506 | apriv->proc_entry = create_proc_entry(apriv->proc_name, |
4496 | S_IFDIR|airo_perm, | 4507 | S_IFDIR|airo_perm, |
4497 | airo_entry); | 4508 | airo_entry); |
4498 | apriv->proc_entry->uid = proc_uid; | 4509 | if (!apriv->proc_entry) |
4499 | apriv->proc_entry->gid = proc_gid; | 4510 | goto fail; |
4500 | apriv->proc_entry->owner = THIS_MODULE; | 4511 | apriv->proc_entry->uid = proc_uid; |
4512 | apriv->proc_entry->gid = proc_gid; | ||
4513 | apriv->proc_entry->owner = THIS_MODULE; | ||
4501 | 4514 | ||
4502 | /* Setup the StatsDelta */ | 4515 | /* Setup the StatsDelta */ |
4503 | entry = create_proc_entry("StatsDelta", | 4516 | entry = create_proc_entry("StatsDelta", |
4504 | S_IFREG | (S_IRUGO&proc_perm), | 4517 | S_IFREG | (S_IRUGO&proc_perm), |
4505 | apriv->proc_entry); | 4518 | apriv->proc_entry); |
4506 | entry->uid = proc_uid; | 4519 | if (!entry) |
4507 | entry->gid = proc_gid; | 4520 | goto fail_stats_delta; |
4521 | entry->uid = proc_uid; | ||
4522 | entry->gid = proc_gid; | ||
4508 | entry->data = dev; | 4523 | entry->data = dev; |
4509 | entry->owner = THIS_MODULE; | 4524 | entry->owner = THIS_MODULE; |
4510 | SETPROC_OPS(entry, proc_statsdelta_ops); | 4525 | SETPROC_OPS(entry, proc_statsdelta_ops); |
4511 | 4526 | ||
4512 | /* Setup the Stats */ | 4527 | /* Setup the Stats */ |
4513 | entry = create_proc_entry("Stats", | 4528 | entry = create_proc_entry("Stats", |
4514 | S_IFREG | (S_IRUGO&proc_perm), | 4529 | S_IFREG | (S_IRUGO&proc_perm), |
4515 | apriv->proc_entry); | 4530 | apriv->proc_entry); |
4516 | entry->uid = proc_uid; | 4531 | if (!entry) |
4517 | entry->gid = proc_gid; | 4532 | goto fail_stats; |
4533 | entry->uid = proc_uid; | ||
4534 | entry->gid = proc_gid; | ||
4518 | entry->data = dev; | 4535 | entry->data = dev; |
4519 | entry->owner = THIS_MODULE; | 4536 | entry->owner = THIS_MODULE; |
4520 | SETPROC_OPS(entry, proc_stats_ops); | 4537 | SETPROC_OPS(entry, proc_stats_ops); |
4521 | 4538 | ||
4522 | /* Setup the Status */ | 4539 | /* Setup the Status */ |
4523 | entry = create_proc_entry("Status", | 4540 | entry = create_proc_entry("Status", |
4524 | S_IFREG | (S_IRUGO&proc_perm), | 4541 | S_IFREG | (S_IRUGO&proc_perm), |
4525 | apriv->proc_entry); | 4542 | apriv->proc_entry); |
4526 | entry->uid = proc_uid; | 4543 | if (!entry) |
4527 | entry->gid = proc_gid; | 4544 | goto fail_status; |
4545 | entry->uid = proc_uid; | ||
4546 | entry->gid = proc_gid; | ||
4528 | entry->data = dev; | 4547 | entry->data = dev; |
4529 | entry->owner = THIS_MODULE; | 4548 | entry->owner = THIS_MODULE; |
4530 | SETPROC_OPS(entry, proc_status_ops); | 4549 | SETPROC_OPS(entry, proc_status_ops); |
4531 | 4550 | ||
4532 | /* Setup the Config */ | 4551 | /* Setup the Config */ |
4533 | entry = create_proc_entry("Config", | 4552 | entry = create_proc_entry("Config", |
4534 | S_IFREG | proc_perm, | 4553 | S_IFREG | proc_perm, |
4535 | apriv->proc_entry); | 4554 | apriv->proc_entry); |
4536 | entry->uid = proc_uid; | 4555 | if (!entry) |
4537 | entry->gid = proc_gid; | 4556 | goto fail_config; |
4557 | entry->uid = proc_uid; | ||
4558 | entry->gid = proc_gid; | ||
4538 | entry->data = dev; | 4559 | entry->data = dev; |
4539 | entry->owner = THIS_MODULE; | 4560 | entry->owner = THIS_MODULE; |
4540 | SETPROC_OPS(entry, proc_config_ops); | 4561 | SETPROC_OPS(entry, proc_config_ops); |
4541 | 4562 | ||
4542 | /* Setup the SSID */ | 4563 | /* Setup the SSID */ |
4543 | entry = create_proc_entry("SSID", | 4564 | entry = create_proc_entry("SSID", |
4544 | S_IFREG | proc_perm, | 4565 | S_IFREG | proc_perm, |
4545 | apriv->proc_entry); | 4566 | apriv->proc_entry); |
4546 | entry->uid = proc_uid; | 4567 | if (!entry) |
4547 | entry->gid = proc_gid; | 4568 | goto fail_ssid; |
4569 | entry->uid = proc_uid; | ||
4570 | entry->gid = proc_gid; | ||
4548 | entry->data = dev; | 4571 | entry->data = dev; |
4549 | entry->owner = THIS_MODULE; | 4572 | entry->owner = THIS_MODULE; |
4550 | SETPROC_OPS(entry, proc_SSID_ops); | 4573 | SETPROC_OPS(entry, proc_SSID_ops); |
4551 | 4574 | ||
4552 | /* Setup the APList */ | 4575 | /* Setup the APList */ |
4553 | entry = create_proc_entry("APList", | 4576 | entry = create_proc_entry("APList", |
4554 | S_IFREG | proc_perm, | 4577 | S_IFREG | proc_perm, |
4555 | apriv->proc_entry); | 4578 | apriv->proc_entry); |
4556 | entry->uid = proc_uid; | 4579 | if (!entry) |
4557 | entry->gid = proc_gid; | 4580 | goto fail_aplist; |
4581 | entry->uid = proc_uid; | ||
4582 | entry->gid = proc_gid; | ||
4558 | entry->data = dev; | 4583 | entry->data = dev; |
4559 | entry->owner = THIS_MODULE; | 4584 | entry->owner = THIS_MODULE; |
4560 | SETPROC_OPS(entry, proc_APList_ops); | 4585 | SETPROC_OPS(entry, proc_APList_ops); |
4561 | 4586 | ||
4562 | /* Setup the BSSList */ | 4587 | /* Setup the BSSList */ |
4563 | entry = create_proc_entry("BSSList", | 4588 | entry = create_proc_entry("BSSList", |
4564 | S_IFREG | proc_perm, | 4589 | S_IFREG | proc_perm, |
4565 | apriv->proc_entry); | 4590 | apriv->proc_entry); |
4591 | if (!entry) | ||
4592 | goto fail_bsslist; | ||
4566 | entry->uid = proc_uid; | 4593 | entry->uid = proc_uid; |
4567 | entry->gid = proc_gid; | 4594 | entry->gid = proc_gid; |
4568 | entry->data = dev; | 4595 | entry->data = dev; |
4569 | entry->owner = THIS_MODULE; | 4596 | entry->owner = THIS_MODULE; |
4570 | SETPROC_OPS(entry, proc_BSSList_ops); | 4597 | SETPROC_OPS(entry, proc_BSSList_ops); |
4571 | 4598 | ||
4572 | /* Setup the WepKey */ | 4599 | /* Setup the WepKey */ |
4573 | entry = create_proc_entry("WepKey", | 4600 | entry = create_proc_entry("WepKey", |
4574 | S_IFREG | proc_perm, | 4601 | S_IFREG | proc_perm, |
4575 | apriv->proc_entry); | 4602 | apriv->proc_entry); |
4576 | entry->uid = proc_uid; | 4603 | if (!entry) |
4577 | entry->gid = proc_gid; | 4604 | goto fail_wepkey; |
4605 | entry->uid = proc_uid; | ||
4606 | entry->gid = proc_gid; | ||
4578 | entry->data = dev; | 4607 | entry->data = dev; |
4579 | entry->owner = THIS_MODULE; | 4608 | entry->owner = THIS_MODULE; |
4580 | SETPROC_OPS(entry, proc_wepkey_ops); | 4609 | SETPROC_OPS(entry, proc_wepkey_ops); |
4581 | 4610 | ||
4582 | return 0; | 4611 | return 0; |
4612 | |||
4613 | fail_wepkey: | ||
4614 | remove_proc_entry("BSSList", apriv->proc_entry); | ||
4615 | fail_bsslist: | ||
4616 | remove_proc_entry("APList", apriv->proc_entry); | ||
4617 | fail_aplist: | ||
4618 | remove_proc_entry("SSID", apriv->proc_entry); | ||
4619 | fail_ssid: | ||
4620 | remove_proc_entry("Config", apriv->proc_entry); | ||
4621 | fail_config: | ||
4622 | remove_proc_entry("Status", apriv->proc_entry); | ||
4623 | fail_status: | ||
4624 | remove_proc_entry("Stats", apriv->proc_entry); | ||
4625 | fail_stats: | ||
4626 | remove_proc_entry("StatsDelta", apriv->proc_entry); | ||
4627 | fail_stats_delta: | ||
4628 | remove_proc_entry(apriv->proc_name, airo_entry); | ||
4629 | fail: | ||
4630 | return -ENOMEM; | ||
4583 | } | 4631 | } |
4584 | 4632 | ||
4585 | static int takedown_proc_entry( struct net_device *dev, | 4633 | static int takedown_proc_entry( struct net_device *dev, |
@@ -5924,7 +5972,6 @@ static int airo_get_essid(struct net_device *dev, | |||
5924 | 5972 | ||
5925 | /* Get the current SSID */ | 5973 | /* Get the current SSID */ |
5926 | memcpy(extra, status_rid.SSID, status_rid.SSIDlen); | 5974 | memcpy(extra, status_rid.SSID, status_rid.SSIDlen); |
5927 | extra[status_rid.SSIDlen] = '\0'; | ||
5928 | /* If none, we may want to get the one that was set */ | 5975 | /* If none, we may want to get the one that was set */ |
5929 | 5976 | ||
5930 | /* Push it out ! */ | 5977 | /* Push it out ! */ |
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c index 31eed85de60f..0c07b8b7250d 100644 --- a/drivers/net/wireless/atmel.c +++ b/drivers/net/wireless/atmel.c | |||
@@ -1678,11 +1678,9 @@ static int atmel_get_essid(struct net_device *dev, | |||
1678 | /* Get the current SSID */ | 1678 | /* Get the current SSID */ |
1679 | if (priv->new_SSID_size != 0) { | 1679 | if (priv->new_SSID_size != 0) { |
1680 | memcpy(extra, priv->new_SSID, priv->new_SSID_size); | 1680 | memcpy(extra, priv->new_SSID, priv->new_SSID_size); |
1681 | extra[priv->new_SSID_size] = '\0'; | ||
1682 | dwrq->length = priv->new_SSID_size; | 1681 | dwrq->length = priv->new_SSID_size; |
1683 | } else { | 1682 | } else { |
1684 | memcpy(extra, priv->SSID, priv->SSID_size); | 1683 | memcpy(extra, priv->SSID, priv->SSID_size); |
1685 | extra[priv->SSID_size] = '\0'; | ||
1686 | dwrq->length = priv->SSID_size; | 1684 | dwrq->length = priv->SSID_size; |
1687 | } | 1685 | } |
1688 | 1686 | ||
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_dma.c b/drivers/net/wireless/bcm43xx/bcm43xx_dma.c index 76e3aed4b471..978ed099e285 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_dma.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_dma.c | |||
@@ -705,11 +705,30 @@ int bcm43xx_dma_init(struct bcm43xx_private *bcm) | |||
705 | struct bcm43xx_dmaring *ring; | 705 | struct bcm43xx_dmaring *ring; |
706 | int err = -ENOMEM; | 706 | int err = -ENOMEM; |
707 | int dma64 = 0; | 707 | int dma64 = 0; |
708 | u32 sbtmstatehi; | 708 | u64 mask = bcm43xx_get_supported_dma_mask(bcm); |
709 | int nobits; | ||
709 | 710 | ||
710 | sbtmstatehi = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH); | 711 | if (mask == DMA_64BIT_MASK) { |
711 | if (sbtmstatehi & BCM43xx_SBTMSTATEHIGH_DMA64BIT) | ||
712 | dma64 = 1; | 712 | dma64 = 1; |
713 | nobits = 64; | ||
714 | } else if (mask == DMA_32BIT_MASK) | ||
715 | nobits = 32; | ||
716 | else | ||
717 | nobits = 30; | ||
718 | err = pci_set_dma_mask(bcm->pci_dev, mask); | ||
719 | err |= pci_set_consistent_dma_mask(bcm->pci_dev, mask); | ||
720 | if (err) { | ||
721 | #ifdef CONFIG_BCM43XX_PIO | ||
722 | printk(KERN_WARNING PFX "DMA not supported on this device." | ||
723 | " Falling back to PIO.\n"); | ||
724 | bcm->__using_pio = 1; | ||
725 | return -ENOSYS; | ||
726 | #else | ||
727 | printk(KERN_ERR PFX "FATAL: DMA not supported and PIO not configured. " | ||
728 | "Please recompile the driver with PIO support.\n"); | ||
729 | return -ENODEV; | ||
730 | #endif /* CONFIG_BCM43XX_PIO */ | ||
731 | } | ||
713 | 732 | ||
714 | /* setup TX DMA channels. */ | 733 | /* setup TX DMA channels. */ |
715 | ring = bcm43xx_setup_dmaring(bcm, 0, 1, dma64); | 734 | ring = bcm43xx_setup_dmaring(bcm, 0, 1, dma64); |
@@ -755,8 +774,7 @@ int bcm43xx_dma_init(struct bcm43xx_private *bcm) | |||
755 | dma->rx_ring3 = ring; | 774 | dma->rx_ring3 = ring; |
756 | } | 775 | } |
757 | 776 | ||
758 | dprintk(KERN_INFO PFX "%s DMA initialized\n", | 777 | dprintk(KERN_INFO PFX "%d-bit DMA initialized\n", nobits); |
759 | dma64 ? "64-bit" : "32-bit"); | ||
760 | err = 0; | 778 | err = 0; |
761 | out: | 779 | out: |
762 | return err; | 780 | return err; |
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_dma.h b/drivers/net/wireless/bcm43xx/bcm43xx_dma.h index e04bcaddd1d0..d1105e569a41 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_dma.h +++ b/drivers/net/wireless/bcm43xx/bcm43xx_dma.h | |||
@@ -4,6 +4,7 @@ | |||
4 | #include <linux/list.h> | 4 | #include <linux/list.h> |
5 | #include <linux/spinlock.h> | 5 | #include <linux/spinlock.h> |
6 | #include <linux/workqueue.h> | 6 | #include <linux/workqueue.h> |
7 | #include <linux/dma-mapping.h> | ||
7 | #include <linux/linkage.h> | 8 | #include <linux/linkage.h> |
8 | #include <asm/atomic.h> | 9 | #include <asm/atomic.h> |
9 | 10 | ||
@@ -314,6 +315,23 @@ int bcm43xx_dma_tx(struct bcm43xx_private *bcm, | |||
314 | struct ieee80211_txb *txb); | 315 | struct ieee80211_txb *txb); |
315 | void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring); | 316 | void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring); |
316 | 317 | ||
318 | /* Helper function that returns the dma mask for this device. */ | ||
319 | static inline | ||
320 | u64 bcm43xx_get_supported_dma_mask(struct bcm43xx_private *bcm) | ||
321 | { | ||
322 | int dma64 = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH) & | ||
323 | BCM43xx_SBTMSTATEHIGH_DMA64BIT; | ||
324 | u16 mmio_base = bcm43xx_dmacontroller_base(dma64, 0); | ||
325 | u32 mask = BCM43xx_DMA32_TXADDREXT_MASK; | ||
326 | |||
327 | if (dma64) | ||
328 | return DMA_64BIT_MASK; | ||
329 | bcm43xx_write32(bcm, mmio_base + BCM43xx_DMA32_TXCTL, mask); | ||
330 | if (bcm43xx_read32(bcm, mmio_base + BCM43xx_DMA32_TXCTL) & mask) | ||
331 | return DMA_32BIT_MASK; | ||
332 | return DMA_30BIT_MASK; | ||
333 | } | ||
334 | |||
317 | #else /* CONFIG_BCM43XX_DMA */ | 335 | #else /* CONFIG_BCM43XX_DMA */ |
318 | 336 | ||
319 | 337 | ||
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_leds.c b/drivers/net/wireless/bcm43xx/bcm43xx_leds.c index c3f90c8563d9..7d383a27b927 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_leds.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_leds.c | |||
@@ -189,20 +189,24 @@ void bcm43xx_leds_update(struct bcm43xx_private *bcm, int activity) | |||
189 | case BCM43xx_LED_INACTIVE: | 189 | case BCM43xx_LED_INACTIVE: |
190 | continue; | 190 | continue; |
191 | case BCM43xx_LED_OFF: | 191 | case BCM43xx_LED_OFF: |
192 | case BCM43xx_LED_BCM4303_3: | ||
192 | break; | 193 | break; |
193 | case BCM43xx_LED_ON: | 194 | case BCM43xx_LED_ON: |
194 | turn_on = 1; | 195 | turn_on = 1; |
195 | break; | 196 | break; |
196 | case BCM43xx_LED_ACTIVITY: | 197 | case BCM43xx_LED_ACTIVITY: |
198 | case BCM43xx_LED_BCM4303_0: | ||
197 | turn_on = activity; | 199 | turn_on = activity; |
198 | break; | 200 | break; |
199 | case BCM43xx_LED_RADIO_ALL: | 201 | case BCM43xx_LED_RADIO_ALL: |
200 | turn_on = radio->enabled; | 202 | turn_on = radio->enabled; |
201 | break; | 203 | break; |
202 | case BCM43xx_LED_RADIO_A: | 204 | case BCM43xx_LED_RADIO_A: |
205 | case BCM43xx_LED_BCM4303_2: | ||
203 | turn_on = (radio->enabled && phy->type == BCM43xx_PHYTYPE_A); | 206 | turn_on = (radio->enabled && phy->type == BCM43xx_PHYTYPE_A); |
204 | break; | 207 | break; |
205 | case BCM43xx_LED_RADIO_B: | 208 | case BCM43xx_LED_RADIO_B: |
209 | case BCM43xx_LED_BCM4303_1: | ||
206 | turn_on = (radio->enabled && | 210 | turn_on = (radio->enabled && |
207 | (phy->type == BCM43xx_PHYTYPE_B || | 211 | (phy->type == BCM43xx_PHYTYPE_B || |
208 | phy->type == BCM43xx_PHYTYPE_G)); | 212 | phy->type == BCM43xx_PHYTYPE_G)); |
@@ -242,7 +246,7 @@ void bcm43xx_leds_update(struct bcm43xx_private *bcm, int activity) | |||
242 | //TODO | 246 | //TODO |
243 | break; | 247 | break; |
244 | case BCM43xx_LED_ASSOC: | 248 | case BCM43xx_LED_ASSOC: |
245 | if (bcm->softmac->associated) | 249 | if (bcm->softmac->associnfo.associated) |
246 | turn_on = 1; | 250 | turn_on = 1; |
247 | break; | 251 | break; |
248 | #ifdef CONFIG_BCM43XX_DEBUG | 252 | #ifdef CONFIG_BCM43XX_DEBUG |
@@ -257,7 +261,8 @@ void bcm43xx_leds_update(struct bcm43xx_private *bcm, int activity) | |||
257 | continue; | 261 | continue; |
258 | #endif /* CONFIG_BCM43XX_DEBUG */ | 262 | #endif /* CONFIG_BCM43XX_DEBUG */ |
259 | default: | 263 | default: |
260 | assert(0); | 264 | dprintkl(KERN_INFO PFX "Bad value in leds_update," |
265 | " led->behaviour: 0x%x\n", led->behaviour); | ||
261 | }; | 266 | }; |
262 | 267 | ||
263 | if (led->activelow) | 268 | if (led->activelow) |
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_leds.h b/drivers/net/wireless/bcm43xx/bcm43xx_leds.h index d3716cf3aebc..811e14a81198 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_leds.h +++ b/drivers/net/wireless/bcm43xx/bcm43xx_leds.h | |||
@@ -46,6 +46,12 @@ enum { /* LED behaviour values */ | |||
46 | BCM43xx_LED_TEST_BLINKSLOW, | 46 | BCM43xx_LED_TEST_BLINKSLOW, |
47 | BCM43xx_LED_TEST_BLINKMEDIUM, | 47 | BCM43xx_LED_TEST_BLINKMEDIUM, |
48 | BCM43xx_LED_TEST_BLINKFAST, | 48 | BCM43xx_LED_TEST_BLINKFAST, |
49 | |||
50 | /* Misc values for BCM4303 */ | ||
51 | BCM43xx_LED_BCM4303_0 = 0x2B, | ||
52 | BCM43xx_LED_BCM4303_1 = 0x78, | ||
53 | BCM43xx_LED_BCM4303_2 = 0x2E, | ||
54 | BCM43xx_LED_BCM4303_3 = 0x19, | ||
49 | }; | 55 | }; |
50 | 56 | ||
51 | int bcm43xx_leds_init(struct bcm43xx_private *bcm); | 57 | int bcm43xx_leds_init(struct bcm43xx_private *bcm); |
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c index bad3452ea893..a1b783813d8e 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c | |||
@@ -746,7 +746,7 @@ int bcm43xx_sprom_write(struct bcm43xx_private *bcm, const u16 *sprom) | |||
746 | if (err) | 746 | if (err) |
747 | goto err_ctlreg; | 747 | goto err_ctlreg; |
748 | spromctl |= 0x10; /* SPROM WRITE enable. */ | 748 | spromctl |= 0x10; /* SPROM WRITE enable. */ |
749 | bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_SPROMCTL, spromctl); | 749 | err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_SPROMCTL, spromctl); |
750 | if (err) | 750 | if (err) |
751 | goto err_ctlreg; | 751 | goto err_ctlreg; |
752 | /* We must burn lots of CPU cycles here, but that does not | 752 | /* We must burn lots of CPU cycles here, but that does not |
@@ -768,7 +768,7 @@ int bcm43xx_sprom_write(struct bcm43xx_private *bcm, const u16 *sprom) | |||
768 | mdelay(20); | 768 | mdelay(20); |
769 | } | 769 | } |
770 | spromctl &= ~0x10; /* SPROM WRITE enable. */ | 770 | spromctl &= ~0x10; /* SPROM WRITE enable. */ |
771 | bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_SPROMCTL, spromctl); | 771 | err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_SPROMCTL, spromctl); |
772 | if (err) | 772 | if (err) |
773 | goto err_ctlreg; | 773 | goto err_ctlreg; |
774 | mdelay(500); | 774 | mdelay(500); |
@@ -1463,6 +1463,23 @@ static void handle_irq_transmit_status(struct bcm43xx_private *bcm) | |||
1463 | } | 1463 | } |
1464 | } | 1464 | } |
1465 | 1465 | ||
1466 | static void drain_txstatus_queue(struct bcm43xx_private *bcm) | ||
1467 | { | ||
1468 | u32 dummy; | ||
1469 | |||
1470 | if (bcm->current_core->rev < 5) | ||
1471 | return; | ||
1472 | /* Read all entries from the microcode TXstatus FIFO | ||
1473 | * and throw them away. | ||
1474 | */ | ||
1475 | while (1) { | ||
1476 | dummy = bcm43xx_read32(bcm, BCM43xx_MMIO_XMITSTAT_0); | ||
1477 | if (!dummy) | ||
1478 | break; | ||
1479 | dummy = bcm43xx_read32(bcm, BCM43xx_MMIO_XMITSTAT_1); | ||
1480 | } | ||
1481 | } | ||
1482 | |||
1466 | static void bcm43xx_generate_noise_sample(struct bcm43xx_private *bcm) | 1483 | static void bcm43xx_generate_noise_sample(struct bcm43xx_private *bcm) |
1467 | { | 1484 | { |
1468 | bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x408, 0x7F7F); | 1485 | bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x408, 0x7F7F); |
@@ -2925,10 +2942,13 @@ static int bcm43xx_wireless_core_init(struct bcm43xx_private *bcm, | |||
2925 | bcm43xx_write16(bcm, 0x043C, 0x000C); | 2942 | bcm43xx_write16(bcm, 0x043C, 0x000C); |
2926 | 2943 | ||
2927 | if (active_wlcore) { | 2944 | if (active_wlcore) { |
2928 | if (bcm43xx_using_pio(bcm)) | 2945 | if (bcm43xx_using_pio(bcm)) { |
2929 | err = bcm43xx_pio_init(bcm); | 2946 | err = bcm43xx_pio_init(bcm); |
2930 | else | 2947 | } else { |
2931 | err = bcm43xx_dma_init(bcm); | 2948 | err = bcm43xx_dma_init(bcm); |
2949 | if (err == -ENOSYS) | ||
2950 | err = bcm43xx_pio_init(bcm); | ||
2951 | } | ||
2932 | if (err) | 2952 | if (err) |
2933 | goto err_chip_cleanup; | 2953 | goto err_chip_cleanup; |
2934 | } | 2954 | } |
@@ -3160,17 +3180,30 @@ static int estimate_periodic_work_badness(unsigned int state) | |||
3160 | static void bcm43xx_periodic_work_handler(void *d) | 3180 | static void bcm43xx_periodic_work_handler(void *d) |
3161 | { | 3181 | { |
3162 | struct bcm43xx_private *bcm = d; | 3182 | struct bcm43xx_private *bcm = d; |
3183 | struct net_device *net_dev = bcm->net_dev; | ||
3163 | unsigned long flags; | 3184 | unsigned long flags; |
3164 | u32 savedirqs = 0; | 3185 | u32 savedirqs = 0; |
3165 | int badness; | 3186 | int badness; |
3187 | unsigned long orig_trans_start = 0; | ||
3166 | 3188 | ||
3189 | mutex_lock(&bcm->mutex); | ||
3167 | badness = estimate_periodic_work_badness(bcm->periodic_state); | 3190 | badness = estimate_periodic_work_badness(bcm->periodic_state); |
3168 | if (badness > BADNESS_LIMIT) { | 3191 | if (badness > BADNESS_LIMIT) { |
3169 | /* Periodic work will take a long time, so we want it to | 3192 | /* Periodic work will take a long time, so we want it to |
3170 | * be preemtible. | 3193 | * be preemtible. |
3171 | */ | 3194 | */ |
3172 | mutex_lock(&bcm->mutex); | 3195 | |
3173 | netif_tx_disable(bcm->net_dev); | 3196 | netif_tx_lock_bh(net_dev); |
3197 | /* We must fake a started transmission here, as we are going to | ||
3198 | * disable TX. If we wouldn't fake a TX, it would be possible to | ||
3199 | * trigger the netdev watchdog, if the last real TX is already | ||
3200 | * some time on the past (slightly less than 5secs) | ||
3201 | */ | ||
3202 | orig_trans_start = net_dev->trans_start; | ||
3203 | net_dev->trans_start = jiffies; | ||
3204 | netif_stop_queue(net_dev); | ||
3205 | netif_tx_unlock_bh(net_dev); | ||
3206 | |||
3174 | spin_lock_irqsave(&bcm->irq_lock, flags); | 3207 | spin_lock_irqsave(&bcm->irq_lock, flags); |
3175 | bcm43xx_mac_suspend(bcm); | 3208 | bcm43xx_mac_suspend(bcm); |
3176 | if (bcm43xx_using_pio(bcm)) | 3209 | if (bcm43xx_using_pio(bcm)) |
@@ -3182,7 +3215,6 @@ static void bcm43xx_periodic_work_handler(void *d) | |||
3182 | /* Periodic work should take short time, so we want low | 3215 | /* Periodic work should take short time, so we want low |
3183 | * locking overhead. | 3216 | * locking overhead. |
3184 | */ | 3217 | */ |
3185 | mutex_lock(&bcm->mutex); | ||
3186 | spin_lock_irqsave(&bcm->irq_lock, flags); | 3218 | spin_lock_irqsave(&bcm->irq_lock, flags); |
3187 | } | 3219 | } |
3188 | 3220 | ||
@@ -3196,6 +3228,7 @@ static void bcm43xx_periodic_work_handler(void *d) | |||
3196 | bcm43xx_pio_thaw_txqueues(bcm); | 3228 | bcm43xx_pio_thaw_txqueues(bcm); |
3197 | bcm43xx_mac_enable(bcm); | 3229 | bcm43xx_mac_enable(bcm); |
3198 | netif_wake_queue(bcm->net_dev); | 3230 | netif_wake_queue(bcm->net_dev); |
3231 | net_dev->trans_start = orig_trans_start; | ||
3199 | } | 3232 | } |
3200 | mmiowb(); | 3233 | mmiowb(); |
3201 | spin_unlock_irqrestore(&bcm->irq_lock, flags); | 3234 | spin_unlock_irqrestore(&bcm->irq_lock, flags); |
@@ -3516,6 +3549,7 @@ int bcm43xx_select_wireless_core(struct bcm43xx_private *bcm, | |||
3516 | bcm43xx_macfilter_clear(bcm, BCM43xx_MACFILTER_ASSOC); | 3549 | bcm43xx_macfilter_clear(bcm, BCM43xx_MACFILTER_ASSOC); |
3517 | bcm43xx_macfilter_set(bcm, BCM43xx_MACFILTER_SELF, (u8 *)(bcm->net_dev->dev_addr)); | 3550 | bcm43xx_macfilter_set(bcm, BCM43xx_MACFILTER_SELF, (u8 *)(bcm->net_dev->dev_addr)); |
3518 | bcm43xx_security_init(bcm); | 3551 | bcm43xx_security_init(bcm); |
3552 | drain_txstatus_queue(bcm); | ||
3519 | ieee80211softmac_start(bcm->net_dev); | 3553 | ieee80211softmac_start(bcm->net_dev); |
3520 | 3554 | ||
3521 | /* Let's go! Be careful after enabling the IRQs. | 3555 | /* Let's go! Be careful after enabling the IRQs. |
@@ -3993,8 +4027,6 @@ static int bcm43xx_init_private(struct bcm43xx_private *bcm, | |||
3993 | struct net_device *net_dev, | 4027 | struct net_device *net_dev, |
3994 | struct pci_dev *pci_dev) | 4028 | struct pci_dev *pci_dev) |
3995 | { | 4029 | { |
3996 | int err; | ||
3997 | |||
3998 | bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT); | 4030 | bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT); |
3999 | bcm->ieee = netdev_priv(net_dev); | 4031 | bcm->ieee = netdev_priv(net_dev); |
4000 | bcm->softmac = ieee80211_priv(net_dev); | 4032 | bcm->softmac = ieee80211_priv(net_dev); |
@@ -4012,22 +4044,8 @@ static int bcm43xx_init_private(struct bcm43xx_private *bcm, | |||
4012 | (void (*)(unsigned long))bcm43xx_interrupt_tasklet, | 4044 | (void (*)(unsigned long))bcm43xx_interrupt_tasklet, |
4013 | (unsigned long)bcm); | 4045 | (unsigned long)bcm); |
4014 | tasklet_disable_nosync(&bcm->isr_tasklet); | 4046 | tasklet_disable_nosync(&bcm->isr_tasklet); |
4015 | if (modparam_pio) { | 4047 | if (modparam_pio) |
4016 | bcm->__using_pio = 1; | 4048 | bcm->__using_pio = 1; |
4017 | } else { | ||
4018 | err = pci_set_dma_mask(pci_dev, DMA_30BIT_MASK); | ||
4019 | err |= pci_set_consistent_dma_mask(pci_dev, DMA_30BIT_MASK); | ||
4020 | if (err) { | ||
4021 | #ifdef CONFIG_BCM43XX_PIO | ||
4022 | printk(KERN_WARNING PFX "DMA not supported. Falling back to PIO.\n"); | ||
4023 | bcm->__using_pio = 1; | ||
4024 | #else | ||
4025 | printk(KERN_ERR PFX "FATAL: DMA not supported and PIO not configured. " | ||
4026 | "Recompile the driver with PIO support, please.\n"); | ||
4027 | return -ENODEV; | ||
4028 | #endif /* CONFIG_BCM43XX_PIO */ | ||
4029 | } | ||
4030 | } | ||
4031 | bcm->rts_threshold = BCM43xx_DEFAULT_RTS_THRESHOLD; | 4049 | bcm->rts_threshold = BCM43xx_DEFAULT_RTS_THRESHOLD; |
4032 | 4050 | ||
4033 | /* default to sw encryption for now */ | 4051 | /* default to sw encryption for now */ |
@@ -4208,7 +4226,11 @@ static int bcm43xx_resume(struct pci_dev *pdev) | |||
4208 | dprintk(KERN_INFO PFX "Resuming...\n"); | 4226 | dprintk(KERN_INFO PFX "Resuming...\n"); |
4209 | 4227 | ||
4210 | pci_set_power_state(pdev, 0); | 4228 | pci_set_power_state(pdev, 0); |
4211 | pci_enable_device(pdev); | 4229 | err = pci_enable_device(pdev); |
4230 | if (err) { | ||
4231 | printk(KERN_ERR PFX "Failure with pci_enable_device!\n"); | ||
4232 | return err; | ||
4233 | } | ||
4212 | pci_restore_state(pdev); | 4234 | pci_restore_state(pdev); |
4213 | 4235 | ||
4214 | bcm43xx_chipset_attach(bcm); | 4236 | bcm43xx_chipset_attach(bcm); |
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c index 9b7b15cf6561..d27016f8c736 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c | |||
@@ -847,7 +847,7 @@ static struct iw_statistics *bcm43xx_get_wireless_stats(struct net_device *net_d | |||
847 | unsigned long flags; | 847 | unsigned long flags; |
848 | 848 | ||
849 | wstats = &bcm->stats.wstats; | 849 | wstats = &bcm->stats.wstats; |
850 | if (!mac->associated) { | 850 | if (!mac->associnfo.associated) { |
851 | wstats->miss.beacon = 0; | 851 | wstats->miss.beacon = 0; |
852 | // bcm->ieee->ieee_stats.tx_retry_limit_exceeded = 0; // FIXME: should this be cleared here? | 852 | // bcm->ieee->ieee_stats.tx_retry_limit_exceeded = 0; // FIXME: should this be cleared here? |
853 | wstats->discard.retries = 0; | 853 | wstats->discard.retries = 0; |
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c index 686d895116de..f63909e4bc32 100644 --- a/drivers/net/wireless/hostap/hostap_cs.c +++ b/drivers/net/wireless/hostap/hostap_cs.c | |||
@@ -887,6 +887,13 @@ static struct pcmcia_device_id hostap_cs_ids[] = { | |||
887 | PCMCIA_DEVICE_PROD_ID123( | 887 | PCMCIA_DEVICE_PROD_ID123( |
888 | "U.S. Robotics", "IEEE 802.11b PC-CARD", "Version 01.02", | 888 | "U.S. Robotics", "IEEE 802.11b PC-CARD", "Version 01.02", |
889 | 0xc7b8df9d, 0x1700d087, 0x4b74baa0), | 889 | 0xc7b8df9d, 0x1700d087, 0x4b74baa0), |
890 | PCMCIA_DEVICE_PROD_ID123( | ||
891 | "Allied Telesyn", "AT-WCL452 Wireless PCMCIA Radio", | ||
892 | "Ver. 1.00", | ||
893 | 0x5cd01705, 0x4271660f, 0x9d08ee12), | ||
894 | PCMCIA_DEVICE_PROD_ID123( | ||
895 | "corega", "WL PCCL-11", "ISL37300P", | ||
896 | 0xa21501a, 0x59868926, 0xc9049a39), | ||
890 | PCMCIA_DEVICE_NULL | 897 | PCMCIA_DEVICE_NULL |
891 | }; | 898 | }; |
892 | MODULE_DEVICE_TABLE(pcmcia, hostap_cs_ids); | 899 | MODULE_DEVICE_TABLE(pcmcia, hostap_cs_ids); |
diff --git a/drivers/net/wireless/hostap/hostap_plx.c b/drivers/net/wireless/hostap/hostap_plx.c index 6dfa041be66d..bc81b13a5a2a 100644 --- a/drivers/net/wireless/hostap/hostap_plx.c +++ b/drivers/net/wireless/hostap/hostap_plx.c | |||
@@ -364,7 +364,7 @@ static int prism2_plx_check_cis(void __iomem *attr_mem, int attr_len, | |||
364 | 364 | ||
365 | pos = 0; | 365 | pos = 0; |
366 | while (pos < CIS_MAX_LEN - 1 && cis[pos] != CISTPL_END) { | 366 | while (pos < CIS_MAX_LEN - 1 && cis[pos] != CISTPL_END) { |
367 | if (pos + cis[pos + 1] >= CIS_MAX_LEN) | 367 | if (pos + 2 + cis[pos + 1] > CIS_MAX_LEN) |
368 | goto cis_error; | 368 | goto cis_error; |
369 | 369 | ||
370 | switch (cis[pos]) { | 370 | switch (cis[pos]) { |
@@ -391,7 +391,7 @@ static int prism2_plx_check_cis(void __iomem *attr_mem, int attr_len, | |||
391 | break; | 391 | break; |
392 | 392 | ||
393 | case CISTPL_MANFID: | 393 | case CISTPL_MANFID: |
394 | if (cis[pos + 1] < 5) | 394 | if (cis[pos + 1] < 4) |
395 | goto cis_error; | 395 | goto cis_error; |
396 | manfid1 = cis[pos + 2] + (cis[pos + 3] << 8); | 396 | manfid1 = cis[pos + 2] + (cis[pos + 3] << 8); |
397 | manfid2 = cis[pos + 4] + (cis[pos + 5] << 8); | 397 | manfid2 = cis[pos + 4] + (cis[pos + 5] << 8); |
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c index b779c7dcc1a8..336cabac13b3 100644 --- a/drivers/net/wireless/orinoco.c +++ b/drivers/net/wireless/orinoco.c | |||
@@ -2457,6 +2457,7 @@ void free_orinocodev(struct net_device *dev) | |||
2457 | /* Wireless extensions */ | 2457 | /* Wireless extensions */ |
2458 | /********************************************************************/ | 2458 | /********************************************************************/ |
2459 | 2459 | ||
2460 | /* Return : < 0 -> error code ; >= 0 -> length */ | ||
2460 | static int orinoco_hw_get_essid(struct orinoco_private *priv, int *active, | 2461 | static int orinoco_hw_get_essid(struct orinoco_private *priv, int *active, |
2461 | char buf[IW_ESSID_MAX_SIZE+1]) | 2462 | char buf[IW_ESSID_MAX_SIZE+1]) |
2462 | { | 2463 | { |
@@ -2501,9 +2502,9 @@ static int orinoco_hw_get_essid(struct orinoco_private *priv, int *active, | |||
2501 | len = le16_to_cpu(essidbuf.len); | 2502 | len = le16_to_cpu(essidbuf.len); |
2502 | BUG_ON(len > IW_ESSID_MAX_SIZE); | 2503 | BUG_ON(len > IW_ESSID_MAX_SIZE); |
2503 | 2504 | ||
2504 | memset(buf, 0, IW_ESSID_MAX_SIZE+1); | 2505 | memset(buf, 0, IW_ESSID_MAX_SIZE); |
2505 | memcpy(buf, p, len); | 2506 | memcpy(buf, p, len); |
2506 | buf[len] = '\0'; | 2507 | err = len; |
2507 | 2508 | ||
2508 | fail_unlock: | 2509 | fail_unlock: |
2509 | orinoco_unlock(priv, &flags); | 2510 | orinoco_unlock(priv, &flags); |
@@ -3027,17 +3028,18 @@ static int orinoco_ioctl_getessid(struct net_device *dev, | |||
3027 | 3028 | ||
3028 | if (netif_running(dev)) { | 3029 | if (netif_running(dev)) { |
3029 | err = orinoco_hw_get_essid(priv, &active, essidbuf); | 3030 | err = orinoco_hw_get_essid(priv, &active, essidbuf); |
3030 | if (err) | 3031 | if (err < 0) |
3031 | return err; | 3032 | return err; |
3033 | erq->length = err; | ||
3032 | } else { | 3034 | } else { |
3033 | if (orinoco_lock(priv, &flags) != 0) | 3035 | if (orinoco_lock(priv, &flags) != 0) |
3034 | return -EBUSY; | 3036 | return -EBUSY; |
3035 | memcpy(essidbuf, priv->desired_essid, IW_ESSID_MAX_SIZE + 1); | 3037 | memcpy(essidbuf, priv->desired_essid, IW_ESSID_MAX_SIZE); |
3038 | erq->length = strlen(priv->desired_essid); | ||
3036 | orinoco_unlock(priv, &flags); | 3039 | orinoco_unlock(priv, &flags); |
3037 | } | 3040 | } |
3038 | 3041 | ||
3039 | erq->flags = 1; | 3042 | erq->flags = 1; |
3040 | erq->length = strlen(essidbuf); | ||
3041 | 3043 | ||
3042 | return 0; | 3044 | return 0; |
3043 | } | 3045 | } |
@@ -3075,10 +3077,10 @@ static int orinoco_ioctl_getnick(struct net_device *dev, | |||
3075 | if (orinoco_lock(priv, &flags) != 0) | 3077 | if (orinoco_lock(priv, &flags) != 0) |
3076 | return -EBUSY; | 3078 | return -EBUSY; |
3077 | 3079 | ||
3078 | memcpy(nickbuf, priv->nick, IW_ESSID_MAX_SIZE+1); | 3080 | memcpy(nickbuf, priv->nick, IW_ESSID_MAX_SIZE); |
3079 | orinoco_unlock(priv, &flags); | 3081 | orinoco_unlock(priv, &flags); |
3080 | 3082 | ||
3081 | nrq->length = strlen(nickbuf); | 3083 | nrq->length = strlen(priv->nick); |
3082 | 3084 | ||
3083 | return 0; | 3085 | return 0; |
3084 | } | 3086 | } |
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c index 0b381d77015c..7fbfc9e41d07 100644 --- a/drivers/net/wireless/ray_cs.c +++ b/drivers/net/wireless/ray_cs.c | |||
@@ -1198,7 +1198,6 @@ static int ray_get_essid(struct net_device *dev, | |||
1198 | 1198 | ||
1199 | /* Get the essid that was set */ | 1199 | /* Get the essid that was set */ |
1200 | memcpy(extra, local->sparm.b5.a_current_ess_id, IW_ESSID_MAX_SIZE); | 1200 | memcpy(extra, local->sparm.b5.a_current_ess_id, IW_ESSID_MAX_SIZE); |
1201 | extra[IW_ESSID_MAX_SIZE] = '\0'; | ||
1202 | 1201 | ||
1203 | /* Push it out ! */ | 1202 | /* Push it out ! */ |
1204 | dwrq->length = strlen(extra); | 1203 | dwrq->length = strlen(extra); |
diff --git a/drivers/net/wireless/zd1201.c b/drivers/net/wireless/zd1201.c index 30057a335a7b..36b29ff05814 100644 --- a/drivers/net/wireless/zd1201.c +++ b/drivers/net/wireless/zd1201.c | |||
@@ -193,10 +193,8 @@ static void zd1201_usbrx(struct urb *urb) | |||
193 | struct sk_buff *skb; | 193 | struct sk_buff *skb; |
194 | unsigned char type; | 194 | unsigned char type; |
195 | 195 | ||
196 | if (!zd) { | 196 | if (!zd) |
197 | free = 1; | 197 | return; |
198 | goto exit; | ||
199 | } | ||
200 | 198 | ||
201 | switch(urb->status) { | 199 | switch(urb->status) { |
202 | case -EILSEQ: | 200 | case -EILSEQ: |
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 2d12837052b0..a7d29bddb298 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c | |||
@@ -1099,7 +1099,7 @@ static void link_led_handler(void *p) | |||
1099 | int r; | 1099 | int r; |
1100 | 1100 | ||
1101 | spin_lock_irq(&mac->lock); | 1101 | spin_lock_irq(&mac->lock); |
1102 | is_associated = sm->associated != 0; | 1102 | is_associated = sm->associnfo.associated != 0; |
1103 | spin_unlock_irq(&mac->lock); | 1103 | spin_unlock_irq(&mac->lock); |
1104 | 1104 | ||
1105 | r = zd_chip_control_leds(chip, | 1105 | r = zd_chip_control_leds(chip, |
diff --git a/drivers/parport/parport_ip32.c b/drivers/parport/parport_ip32.c index e3e19277030a..ec44efdbb84e 100644 --- a/drivers/parport/parport_ip32.c +++ b/drivers/parport/parport_ip32.c | |||
@@ -780,7 +780,7 @@ static irqreturn_t parport_ip32_interrupt(int irq, void *dev_id) | |||
780 | enum parport_ip32_irq_mode irq_mode = priv->irq_mode; | 780 | enum parport_ip32_irq_mode irq_mode = priv->irq_mode; |
781 | switch (irq_mode) { | 781 | switch (irq_mode) { |
782 | case PARPORT_IP32_IRQ_FWD: | 782 | case PARPORT_IP32_IRQ_FWD: |
783 | parport_generic_irq(irq, p, regs); | 783 | parport_generic_irq(irq, p); |
784 | break; | 784 | break; |
785 | case PARPORT_IP32_IRQ_HERE: | 785 | case PARPORT_IP32_IRQ_HERE: |
786 | parport_ip32_wakeup(p); | 786 | parport_ip32_wakeup(p); |
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 30294127a0aa..5f1b9f58070e 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig | |||
@@ -19,7 +19,7 @@ config PCI_MSI | |||
19 | 19 | ||
20 | config PCI_MULTITHREAD_PROBE | 20 | config PCI_MULTITHREAD_PROBE |
21 | bool "PCI Multi-threaded probe (EXPERIMENTAL)" | 21 | bool "PCI Multi-threaded probe (EXPERIMENTAL)" |
22 | depends on PCI && EXPERIMENTAL | 22 | depends on PCI && EXPERIMENTAL && BROKEN |
23 | help | 23 | help |
24 | Say Y here if you want the PCI core to spawn a new thread for | 24 | Say Y here if you want the PCI core to spawn a new thread for |
25 | every PCI device that is probed. This can cause a huge | 25 | every PCI device that is probed. This can cause a huge |
@@ -55,7 +55,7 @@ config PCI_DEBUG | |||
55 | config HT_IRQ | 55 | config HT_IRQ |
56 | bool "Interrupts on hypertransport devices" | 56 | bool "Interrupts on hypertransport devices" |
57 | default y | 57 | default y |
58 | depends on X86_LOCAL_APIC && X86_IO_APIC | 58 | depends on PCI && X86_LOCAL_APIC && X86_IO_APIC |
59 | help | 59 | help |
60 | This allows native hypertransport devices to use interrupts. | 60 | This allows native hypertransport devices to use interrupts. |
61 | 61 | ||
diff --git a/drivers/pci/hotplug/acpi_pcihp.c b/drivers/pci/hotplug/acpi_pcihp.c index 51cb9f817c22..270a33cc08f6 100644 --- a/drivers/pci/hotplug/acpi_pcihp.c +++ b/drivers/pci/hotplug/acpi_pcihp.c | |||
@@ -29,10 +29,10 @@ | |||
29 | #include <linux/kernel.h> | 29 | #include <linux/kernel.h> |
30 | #include <linux/types.h> | 30 | #include <linux/types.h> |
31 | #include <linux/pci.h> | 31 | #include <linux/pci.h> |
32 | #include <linux/pci_hotplug.h> | ||
32 | #include <acpi/acpi.h> | 33 | #include <acpi/acpi.h> |
33 | #include <acpi/acpi_bus.h> | 34 | #include <acpi/acpi_bus.h> |
34 | #include <acpi/actypes.h> | 35 | #include <acpi/actypes.h> |
35 | #include "pci_hotplug.h" | ||
36 | 36 | ||
37 | #define MY_NAME "acpi_pcihp" | 37 | #define MY_NAME "acpi_pcihp" |
38 | 38 | ||
diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h index 7fff07e877c7..59c5b242d86d 100644 --- a/drivers/pci/hotplug/acpiphp.h +++ b/drivers/pci/hotplug/acpiphp.h | |||
@@ -38,7 +38,7 @@ | |||
38 | #include <linux/acpi.h> | 38 | #include <linux/acpi.h> |
39 | #include <linux/kobject.h> /* for KOBJ_NAME_LEN */ | 39 | #include <linux/kobject.h> /* for KOBJ_NAME_LEN */ |
40 | #include <linux/mutex.h> | 40 | #include <linux/mutex.h> |
41 | #include "pci_hotplug.h" | 41 | #include <linux/pci_hotplug.h> |
42 | 42 | ||
43 | #define dbg(format, arg...) \ | 43 | #define dbg(format, arg...) \ |
44 | do { \ | 44 | do { \ |
diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c index e2fef60c2d06..c57d9d5ce84e 100644 --- a/drivers/pci/hotplug/acpiphp_core.c +++ b/drivers/pci/hotplug/acpiphp_core.c | |||
@@ -37,10 +37,10 @@ | |||
37 | 37 | ||
38 | #include <linux/kernel.h> | 38 | #include <linux/kernel.h> |
39 | #include <linux/pci.h> | 39 | #include <linux/pci.h> |
40 | #include <linux/pci_hotplug.h> | ||
40 | #include <linux/slab.h> | 41 | #include <linux/slab.h> |
41 | #include <linux/smp.h> | 42 | #include <linux/smp.h> |
42 | #include <linux/smp_lock.h> | 43 | #include <linux/smp_lock.h> |
43 | #include "pci_hotplug.h" | ||
44 | #include "acpiphp.h" | 44 | #include "acpiphp.h" |
45 | 45 | ||
46 | #define MY_NAME "acpiphp" | 46 | #define MY_NAME "acpiphp" |
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 83e8e4412de5..16167b016266 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -45,11 +45,11 @@ | |||
45 | 45 | ||
46 | #include <linux/kernel.h> | 46 | #include <linux/kernel.h> |
47 | #include <linux/pci.h> | 47 | #include <linux/pci.h> |
48 | #include <linux/pci_hotplug.h> | ||
48 | #include <linux/smp_lock.h> | 49 | #include <linux/smp_lock.h> |
49 | #include <linux/mutex.h> | 50 | #include <linux/mutex.h> |
50 | 51 | ||
51 | #include "../pci.h" | 52 | #include "../pci.h" |
52 | #include "pci_hotplug.h" | ||
53 | #include "acpiphp.h" | 53 | #include "acpiphp.h" |
54 | 54 | ||
55 | static LIST_HEAD(bridge_list); | 55 | static LIST_HEAD(bridge_list); |
@@ -1807,8 +1807,8 @@ u8 acpiphp_get_power_status(struct acpiphp_slot *slot) | |||
1807 | 1807 | ||
1808 | 1808 | ||
1809 | /* | 1809 | /* |
1810 | * latch closed: 1 | 1810 | * latch open: 1 |
1811 | * latch open: 0 | 1811 | * latch closed: 0 |
1812 | */ | 1812 | */ |
1813 | u8 acpiphp_get_latch_status(struct acpiphp_slot *slot) | 1813 | u8 acpiphp_get_latch_status(struct acpiphp_slot *slot) |
1814 | { | 1814 | { |
@@ -1816,7 +1816,7 @@ u8 acpiphp_get_latch_status(struct acpiphp_slot *slot) | |||
1816 | 1816 | ||
1817 | sta = get_slot_status(slot); | 1817 | sta = get_slot_status(slot); |
1818 | 1818 | ||
1819 | return (sta & ACPI_STA_SHOW_IN_UI) ? 1 : 0; | 1819 | return (sta & ACPI_STA_SHOW_IN_UI) ? 0 : 1; |
1820 | } | 1820 | } |
1821 | 1821 | ||
1822 | 1822 | ||
diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c index d0a07d9ab30c..bd40aee10e16 100644 --- a/drivers/pci/hotplug/acpiphp_ibm.c +++ b/drivers/pci/hotplug/acpiphp_ibm.c | |||
@@ -35,7 +35,6 @@ | |||
35 | #include <linux/moduleparam.h> | 35 | #include <linux/moduleparam.h> |
36 | 36 | ||
37 | #include "acpiphp.h" | 37 | #include "acpiphp.h" |
38 | #include "pci_hotplug.h" | ||
39 | 38 | ||
40 | #define DRIVER_VERSION "1.0.1" | 39 | #define DRIVER_VERSION "1.0.1" |
41 | #define DRIVER_AUTHOR "Irene Zubarev <zubarev@us.ibm.com>, Vernon Mauery <vernux@us.ibm.com>" | 40 | #define DRIVER_AUTHOR "Irene Zubarev <zubarev@us.ibm.com>, Vernon Mauery <vernux@us.ibm.com>" |
diff --git a/drivers/pci/hotplug/cpci_hotplug_core.c b/drivers/pci/hotplug/cpci_hotplug_core.c index d06ab4045134..684551559d44 100644 --- a/drivers/pci/hotplug/cpci_hotplug_core.c +++ b/drivers/pci/hotplug/cpci_hotplug_core.c | |||
@@ -29,12 +29,12 @@ | |||
29 | #include <linux/kernel.h> | 29 | #include <linux/kernel.h> |
30 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
31 | #include <linux/pci.h> | 31 | #include <linux/pci.h> |
32 | #include <linux/pci_hotplug.h> | ||
32 | #include <linux/init.h> | 33 | #include <linux/init.h> |
33 | #include <linux/interrupt.h> | 34 | #include <linux/interrupt.h> |
34 | #include <linux/smp_lock.h> | 35 | #include <linux/smp_lock.h> |
35 | #include <asm/atomic.h> | 36 | #include <asm/atomic.h> |
36 | #include <linux/delay.h> | 37 | #include <linux/delay.h> |
37 | #include "pci_hotplug.h" | ||
38 | #include "cpci_hotplug.h" | 38 | #include "cpci_hotplug.h" |
39 | 39 | ||
40 | #define DRIVER_AUTHOR "Scott Murray <scottm@somanetworks.com>" | 40 | #define DRIVER_AUTHOR "Scott Murray <scottm@somanetworks.com>" |
diff --git a/drivers/pci/hotplug/cpci_hotplug_pci.c b/drivers/pci/hotplug/cpci_hotplug_pci.c index 4afcaffd031c..7b1beaad2752 100644 --- a/drivers/pci/hotplug/cpci_hotplug_pci.c +++ b/drivers/pci/hotplug/cpci_hotplug_pci.c | |||
@@ -26,9 +26,9 @@ | |||
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
28 | #include <linux/pci.h> | 28 | #include <linux/pci.h> |
29 | #include <linux/pci_hotplug.h> | ||
29 | #include <linux/proc_fs.h> | 30 | #include <linux/proc_fs.h> |
30 | #include "../pci.h" | 31 | #include "../pci.h" |
31 | #include "pci_hotplug.h" | ||
32 | #include "cpci_hotplug.h" | 32 | #include "cpci_hotplug.h" |
33 | 33 | ||
34 | #define MY_NAME "cpci_hotplug" | 34 | #define MY_NAME "cpci_hotplug" |
diff --git a/drivers/pci/hotplug/cpcihp_generic.c b/drivers/pci/hotplug/cpcihp_generic.c index e847f0d6c7fe..f3852a6b74ea 100644 --- a/drivers/pci/hotplug/cpcihp_generic.c +++ b/drivers/pci/hotplug/cpcihp_generic.c | |||
@@ -84,7 +84,7 @@ static int __init validate_parameters(void) | |||
84 | 84 | ||
85 | if(!bridge) { | 85 | if(!bridge) { |
86 | info("not configured, disabling."); | 86 | info("not configured, disabling."); |
87 | return 1; | 87 | return -EINVAL; |
88 | } | 88 | } |
89 | str = bridge; | 89 | str = bridge; |
90 | if(!*str) | 90 | if(!*str) |
@@ -147,7 +147,7 @@ static int __init cpcihp_generic_init(void) | |||
147 | 147 | ||
148 | info(DRIVER_DESC " version: " DRIVER_VERSION); | 148 | info(DRIVER_DESC " version: " DRIVER_VERSION); |
149 | status = validate_parameters(); | 149 | status = validate_parameters(); |
150 | if(status != 0) | 150 | if (status) |
151 | return status; | 151 | return status; |
152 | 152 | ||
153 | r = request_region(port, 1, "#ENUM hotswap signal register"); | 153 | r = request_region(port, 1, "#ENUM hotswap signal register"); |
diff --git a/drivers/pci/hotplug/cpqphp.h b/drivers/pci/hotplug/cpqphp.h index ea040c32f47d..298ad7f3f4f4 100644 --- a/drivers/pci/hotplug/cpqphp.h +++ b/drivers/pci/hotplug/cpqphp.h | |||
@@ -28,7 +28,6 @@ | |||
28 | #ifndef _CPQPHP_H | 28 | #ifndef _CPQPHP_H |
29 | #define _CPQPHP_H | 29 | #define _CPQPHP_H |
30 | 30 | ||
31 | #include "pci_hotplug.h" | ||
32 | #include <linux/interrupt.h> | 31 | #include <linux/interrupt.h> |
33 | #include <asm/io.h> /* for read? and write? functions */ | 32 | #include <asm/io.h> /* for read? and write? functions */ |
34 | #include <linux/delay.h> /* for delays */ | 33 | #include <linux/delay.h> /* for delays */ |
diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c index 1fc259913b68..5617cfdadc5c 100644 --- a/drivers/pci/hotplug/cpqphp_core.c +++ b/drivers/pci/hotplug/cpqphp_core.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/slab.h> | 37 | #include <linux/slab.h> |
38 | #include <linux/workqueue.h> | 38 | #include <linux/workqueue.h> |
39 | #include <linux/pci.h> | 39 | #include <linux/pci.h> |
40 | #include <linux/pci_hotplug.h> | ||
40 | #include <linux/init.h> | 41 | #include <linux/init.h> |
41 | #include <linux/interrupt.h> | 42 | #include <linux/interrupt.h> |
42 | 43 | ||
diff --git a/drivers/pci/hotplug/cpqphp_ctrl.c b/drivers/pci/hotplug/cpqphp_ctrl.c index 3ec2ad7db49a..79ff6b4de3a6 100644 --- a/drivers/pci/hotplug/cpqphp_ctrl.c +++ b/drivers/pci/hotplug/cpqphp_ctrl.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/wait.h> | 36 | #include <linux/wait.h> |
37 | #include <linux/smp_lock.h> | 37 | #include <linux/smp_lock.h> |
38 | #include <linux/pci.h> | 38 | #include <linux/pci.h> |
39 | #include <linux/pci_hotplug.h> | ||
39 | #include "cpqphp.h" | 40 | #include "cpqphp.h" |
40 | 41 | ||
41 | static u32 configure_new_device(struct controller* ctrl, struct pci_func *func, | 42 | static u32 configure_new_device(struct controller* ctrl, struct pci_func *func, |
diff --git a/drivers/pci/hotplug/cpqphp_nvram.c b/drivers/pci/hotplug/cpqphp_nvram.c index cf0878917537..298a6cfd8406 100644 --- a/drivers/pci/hotplug/cpqphp_nvram.c +++ b/drivers/pci/hotplug/cpqphp_nvram.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/slab.h> | 33 | #include <linux/slab.h> |
34 | #include <linux/workqueue.h> | 34 | #include <linux/workqueue.h> |
35 | #include <linux/pci.h> | 35 | #include <linux/pci.h> |
36 | #include <linux/pci_hotplug.h> | ||
36 | #include <linux/init.h> | 37 | #include <linux/init.h> |
37 | #include <asm/uaccess.h> | 38 | #include <asm/uaccess.h> |
38 | #include "cpqphp.h" | 39 | #include "cpqphp.h" |
diff --git a/drivers/pci/hotplug/cpqphp_pci.c b/drivers/pci/hotplug/cpqphp_pci.c index 0d9688952f4a..fc7c74d72595 100644 --- a/drivers/pci/hotplug/cpqphp_pci.c +++ b/drivers/pci/hotplug/cpqphp_pci.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/workqueue.h> | 33 | #include <linux/workqueue.h> |
34 | #include <linux/proc_fs.h> | 34 | #include <linux/proc_fs.h> |
35 | #include <linux/pci.h> | 35 | #include <linux/pci.h> |
36 | #include <linux/pci_hotplug.h> | ||
36 | #include "../pci.h" | 37 | #include "../pci.h" |
37 | #include "cpqphp.h" | 38 | #include "cpqphp.h" |
38 | #include "cpqphp_nvram.h" | 39 | #include "cpqphp_nvram.h" |
diff --git a/drivers/pci/hotplug/cpqphp_sysfs.c b/drivers/pci/hotplug/cpqphp_sysfs.c index 5bab666cd67e..634f74d919d3 100644 --- a/drivers/pci/hotplug/cpqphp_sysfs.c +++ b/drivers/pci/hotplug/cpqphp_sysfs.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/proc_fs.h> | 32 | #include <linux/proc_fs.h> |
33 | #include <linux/workqueue.h> | 33 | #include <linux/workqueue.h> |
34 | #include <linux/pci.h> | 34 | #include <linux/pci.h> |
35 | #include <linux/pci_hotplug.h> | ||
35 | #include <linux/debugfs.h> | 36 | #include <linux/debugfs.h> |
36 | #include "cpqphp.h" | 37 | #include "cpqphp.h" |
37 | 38 | ||
diff --git a/drivers/pci/hotplug/fakephp.c b/drivers/pci/hotplug/fakephp.c index 05a4f0f90186..e27907c91d92 100644 --- a/drivers/pci/hotplug/fakephp.c +++ b/drivers/pci/hotplug/fakephp.c | |||
@@ -35,10 +35,10 @@ | |||
35 | #include <linux/kernel.h> | 35 | #include <linux/kernel.h> |
36 | #include <linux/module.h> | 36 | #include <linux/module.h> |
37 | #include <linux/pci.h> | 37 | #include <linux/pci.h> |
38 | #include <linux/pci_hotplug.h> | ||
38 | #include <linux/init.h> | 39 | #include <linux/init.h> |
39 | #include <linux/string.h> | 40 | #include <linux/string.h> |
40 | #include <linux/slab.h> | 41 | #include <linux/slab.h> |
41 | #include "pci_hotplug.h" | ||
42 | #include "../pci.h" | 42 | #include "../pci.h" |
43 | 43 | ||
44 | #if !defined(MODULE) | 44 | #if !defined(MODULE) |
@@ -181,7 +181,9 @@ static void pci_rescan_slot(struct pci_dev *temp) | |||
181 | 181 | ||
182 | if (!pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type)) { | 182 | if (!pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type)) { |
183 | temp->hdr_type = hdr_type & 0x7f; | 183 | temp->hdr_type = hdr_type & 0x7f; |
184 | if (!pci_find_slot(bus->number, temp->devfn)) { | 184 | if ((dev = pci_get_slot(bus, temp->devfn)) != NULL) |
185 | pci_dev_put(dev); | ||
186 | else { | ||
185 | dev = pci_scan_single_device(bus, temp->devfn); | 187 | dev = pci_scan_single_device(bus, temp->devfn); |
186 | if (dev) { | 188 | if (dev) { |
187 | dbg("New device on %s function %x:%x\n", | 189 | dbg("New device on %s function %x:%x\n", |
@@ -205,7 +207,9 @@ static void pci_rescan_slot(struct pci_dev *temp) | |||
205 | continue; | 207 | continue; |
206 | temp->hdr_type = hdr_type & 0x7f; | 208 | temp->hdr_type = hdr_type & 0x7f; |
207 | 209 | ||
208 | if (!pci_find_slot(bus->number, temp->devfn)) { | 210 | if ((dev = pci_get_slot(bus, temp->devfn)) != NULL) |
211 | pci_dev_put(dev); | ||
212 | else { | ||
209 | dev = pci_scan_single_device(bus, temp->devfn); | 213 | dev = pci_scan_single_device(bus, temp->devfn); |
210 | if (dev) { | 214 | if (dev) { |
211 | dbg("New device on %s function %x:%x\n", | 215 | dbg("New device on %s function %x:%x\n", |
@@ -305,7 +309,7 @@ static int disable_slot(struct hotplug_slot *slot) | |||
305 | /* search for subfunctions and disable them first */ | 309 | /* search for subfunctions and disable them first */ |
306 | if (!(dslot->dev->devfn & 7)) { | 310 | if (!(dslot->dev->devfn & 7)) { |
307 | for (func = 1; func < 8; func++) { | 311 | for (func = 1; func < 8; func++) { |
308 | dev = pci_find_slot(dslot->dev->bus->number, | 312 | dev = pci_get_slot(dslot->dev->bus, |
309 | dslot->dev->devfn + func); | 313 | dslot->dev->devfn + func); |
310 | if (dev) { | 314 | if (dev) { |
311 | hslot = get_slot_from_dev(dev); | 315 | hslot = get_slot_from_dev(dev); |
@@ -315,6 +319,7 @@ static int disable_slot(struct hotplug_slot *slot) | |||
315 | err("Hotplug slot not found for subfunction of PCI device\n"); | 319 | err("Hotplug slot not found for subfunction of PCI device\n"); |
316 | return -ENODEV; | 320 | return -ENODEV; |
317 | } | 321 | } |
322 | pci_dev_put(dev); | ||
318 | } else | 323 | } else |
319 | dbg("No device in slot found\n"); | 324 | dbg("No device in slot found\n"); |
320 | } | 325 | } |
diff --git a/drivers/pci/hotplug/ibmphp.h b/drivers/pci/hotplug/ibmphp.h index dba6d8ca9bda..612d96301509 100644 --- a/drivers/pci/hotplug/ibmphp.h +++ b/drivers/pci/hotplug/ibmphp.h | |||
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | */ | 31 | */ |
32 | 32 | ||
33 | #include "pci_hotplug.h" | 33 | #include <linux/pci_hotplug.h> |
34 | 34 | ||
35 | extern int ibmphp_debug; | 35 | extern int ibmphp_debug; |
36 | 36 | ||
diff --git a/drivers/pci/hotplug/pci_hotplug.h b/drivers/pci/hotplug/pci_hotplug.h deleted file mode 100644 index 772523dc3860..000000000000 --- a/drivers/pci/hotplug/pci_hotplug.h +++ /dev/null | |||
@@ -1,236 +0,0 @@ | |||
1 | /* | ||
2 | * PCI HotPlug Core Functions | ||
3 | * | ||
4 | * Copyright (C) 1995,2001 Compaq Computer Corporation | ||
5 | * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com) | ||
6 | * Copyright (C) 2001 IBM Corp. | ||
7 | * | ||
8 | * All rights reserved. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or (at | ||
13 | * your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, but | ||
16 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or | ||
18 | * NON INFRINGEMENT. See the GNU General Public License for more | ||
19 | * details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License | ||
22 | * along with this program; if not, write to the Free Software | ||
23 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
24 | * | ||
25 | * Send feedback to <greg@kroah.com> | ||
26 | * | ||
27 | */ | ||
28 | #ifndef _PCI_HOTPLUG_H | ||
29 | #define _PCI_HOTPLUG_H | ||
30 | |||
31 | |||
32 | /* These values come from the PCI Hotplug Spec */ | ||
33 | enum pci_bus_speed { | ||
34 | PCI_SPEED_33MHz = 0x00, | ||
35 | PCI_SPEED_66MHz = 0x01, | ||
36 | PCI_SPEED_66MHz_PCIX = 0x02, | ||
37 | PCI_SPEED_100MHz_PCIX = 0x03, | ||
38 | PCI_SPEED_133MHz_PCIX = 0x04, | ||
39 | PCI_SPEED_66MHz_PCIX_ECC = 0x05, | ||
40 | PCI_SPEED_100MHz_PCIX_ECC = 0x06, | ||
41 | PCI_SPEED_133MHz_PCIX_ECC = 0x07, | ||
42 | PCI_SPEED_66MHz_PCIX_266 = 0x09, | ||
43 | PCI_SPEED_100MHz_PCIX_266 = 0x0a, | ||
44 | PCI_SPEED_133MHz_PCIX_266 = 0x0b, | ||
45 | PCI_SPEED_66MHz_PCIX_533 = 0x11, | ||
46 | PCI_SPEED_100MHz_PCIX_533 = 0x12, | ||
47 | PCI_SPEED_133MHz_PCIX_533 = 0x13, | ||
48 | PCI_SPEED_UNKNOWN = 0xff, | ||
49 | }; | ||
50 | |||
51 | /* These values come from the PCI Express Spec */ | ||
52 | enum pcie_link_width { | ||
53 | PCIE_LNK_WIDTH_RESRV = 0x00, | ||
54 | PCIE_LNK_X1 = 0x01, | ||
55 | PCIE_LNK_X2 = 0x02, | ||
56 | PCIE_LNK_X4 = 0x04, | ||
57 | PCIE_LNK_X8 = 0x08, | ||
58 | PCIE_LNK_X12 = 0x0C, | ||
59 | PCIE_LNK_X16 = 0x10, | ||
60 | PCIE_LNK_X32 = 0x20, | ||
61 | PCIE_LNK_WIDTH_UNKNOWN = 0xFF, | ||
62 | }; | ||
63 | |||
64 | enum pcie_link_speed { | ||
65 | PCIE_2PT5GB = 0x14, | ||
66 | PCIE_LNK_SPEED_UNKNOWN = 0xFF, | ||
67 | }; | ||
68 | |||
69 | struct hotplug_slot; | ||
70 | struct hotplug_slot_attribute { | ||
71 | struct attribute attr; | ||
72 | ssize_t (*show)(struct hotplug_slot *, char *); | ||
73 | ssize_t (*store)(struct hotplug_slot *, const char *, size_t); | ||
74 | }; | ||
75 | #define to_hotplug_attr(n) container_of(n, struct hotplug_slot_attribute, attr); | ||
76 | |||
77 | /** | ||
78 | * struct hotplug_slot_ops -the callbacks that the hotplug pci core can use | ||
79 | * @owner: The module owner of this structure | ||
80 | * @enable_slot: Called when the user wants to enable a specific pci slot | ||
81 | * @disable_slot: Called when the user wants to disable a specific pci slot | ||
82 | * @set_attention_status: Called to set the specific slot's attention LED to | ||
83 | * the specified value | ||
84 | * @hardware_test: Called to run a specified hardware test on the specified | ||
85 | * slot. | ||
86 | * @get_power_status: Called to get the current power status of a slot. | ||
87 | * If this field is NULL, the value passed in the struct hotplug_slot_info | ||
88 | * will be used when this value is requested by a user. | ||
89 | * @get_attention_status: Called to get the current attention status of a slot. | ||
90 | * If this field is NULL, the value passed in the struct hotplug_slot_info | ||
91 | * will be used when this value is requested by a user. | ||
92 | * @get_latch_status: Called to get the current latch status of a slot. | ||
93 | * If this field is NULL, the value passed in the struct hotplug_slot_info | ||
94 | * will be used when this value is requested by a user. | ||
95 | * @get_adapter_status: Called to get see if an adapter is present in the slot or not. | ||
96 | * If this field is NULL, the value passed in the struct hotplug_slot_info | ||
97 | * will be used when this value is requested by a user. | ||
98 | * @get_address: Called to get pci address of a slot. | ||
99 | * If this field is NULL, the value passed in the struct hotplug_slot_info | ||
100 | * will be used when this value is requested by a user. | ||
101 | * @get_max_bus_speed: Called to get the max bus speed for a slot. | ||
102 | * If this field is NULL, the value passed in the struct hotplug_slot_info | ||
103 | * will be used when this value is requested by a user. | ||
104 | * @get_cur_bus_speed: Called to get the current bus speed for a slot. | ||
105 | * If this field is NULL, the value passed in the struct hotplug_slot_info | ||
106 | * will be used when this value is requested by a user. | ||
107 | * | ||
108 | * The table of function pointers that is passed to the hotplug pci core by a | ||
109 | * hotplug pci driver. These functions are called by the hotplug pci core when | ||
110 | * the user wants to do something to a specific slot (query it for information, | ||
111 | * set an LED, enable / disable power, etc.) | ||
112 | */ | ||
113 | struct hotplug_slot_ops { | ||
114 | struct module *owner; | ||
115 | int (*enable_slot) (struct hotplug_slot *slot); | ||
116 | int (*disable_slot) (struct hotplug_slot *slot); | ||
117 | int (*set_attention_status) (struct hotplug_slot *slot, u8 value); | ||
118 | int (*hardware_test) (struct hotplug_slot *slot, u32 value); | ||
119 | int (*get_power_status) (struct hotplug_slot *slot, u8 *value); | ||
120 | int (*get_attention_status) (struct hotplug_slot *slot, u8 *value); | ||
121 | int (*get_latch_status) (struct hotplug_slot *slot, u8 *value); | ||
122 | int (*get_adapter_status) (struct hotplug_slot *slot, u8 *value); | ||
123 | int (*get_address) (struct hotplug_slot *slot, u32 *value); | ||
124 | int (*get_max_bus_speed) (struct hotplug_slot *slot, enum pci_bus_speed *value); | ||
125 | int (*get_cur_bus_speed) (struct hotplug_slot *slot, enum pci_bus_speed *value); | ||
126 | }; | ||
127 | |||
128 | /** | ||
129 | * struct hotplug_slot_info - used to notify the hotplug pci core of the state of the slot | ||
130 | * @power: if power is enabled or not (1/0) | ||
131 | * @attention_status: if the attention light is enabled or not (1/0) | ||
132 | * @latch_status: if the latch (if any) is open or closed (1/0) | ||
133 | * @adapter_present: if there is a pci board present in the slot or not (1/0) | ||
134 | * @address: (domain << 16 | bus << 8 | dev) | ||
135 | * | ||
136 | * Used to notify the hotplug pci core of the status of a specific slot. | ||
137 | */ | ||
138 | struct hotplug_slot_info { | ||
139 | u8 power_status; | ||
140 | u8 attention_status; | ||
141 | u8 latch_status; | ||
142 | u8 adapter_status; | ||
143 | u32 address; | ||
144 | enum pci_bus_speed max_bus_speed; | ||
145 | enum pci_bus_speed cur_bus_speed; | ||
146 | }; | ||
147 | |||
148 | /** | ||
149 | * struct hotplug_slot - used to register a physical slot with the hotplug pci core | ||
150 | * @name: the name of the slot being registered. This string must | ||
151 | * be unique amoung slots registered on this system. | ||
152 | * @ops: pointer to the &struct hotplug_slot_ops to be used for this slot | ||
153 | * @info: pointer to the &struct hotplug_slot_info for the initial values for | ||
154 | * this slot. | ||
155 | * @release: called during pci_hp_deregister to free memory allocated in a | ||
156 | * hotplug_slot structure. | ||
157 | * @private: used by the hotplug pci controller driver to store whatever it | ||
158 | * needs. | ||
159 | */ | ||
160 | struct hotplug_slot { | ||
161 | char *name; | ||
162 | struct hotplug_slot_ops *ops; | ||
163 | struct hotplug_slot_info *info; | ||
164 | void (*release) (struct hotplug_slot *slot); | ||
165 | void *private; | ||
166 | |||
167 | /* Variables below this are for use only by the hotplug pci core. */ | ||
168 | struct list_head slot_list; | ||
169 | struct kobject kobj; | ||
170 | }; | ||
171 | #define to_hotplug_slot(n) container_of(n, struct hotplug_slot, kobj) | ||
172 | |||
173 | extern int pci_hp_register (struct hotplug_slot *slot); | ||
174 | extern int pci_hp_deregister (struct hotplug_slot *slot); | ||
175 | extern int __must_check pci_hp_change_slot_info (struct hotplug_slot *slot, | ||
176 | struct hotplug_slot_info *info); | ||
177 | extern struct subsystem pci_hotplug_slots_subsys; | ||
178 | |||
179 | /* PCI Setting Record (Type 0) */ | ||
180 | struct hpp_type0 { | ||
181 | u32 revision; | ||
182 | u8 cache_line_size; | ||
183 | u8 latency_timer; | ||
184 | u8 enable_serr; | ||
185 | u8 enable_perr; | ||
186 | }; | ||
187 | |||
188 | /* PCI-X Setting Record (Type 1) */ | ||
189 | struct hpp_type1 { | ||
190 | u32 revision; | ||
191 | u8 max_mem_read; | ||
192 | u8 avg_max_split; | ||
193 | u16 tot_max_split; | ||
194 | }; | ||
195 | |||
196 | /* PCI Express Setting Record (Type 2) */ | ||
197 | struct hpp_type2 { | ||
198 | u32 revision; | ||
199 | u32 unc_err_mask_and; | ||
200 | u32 unc_err_mask_or; | ||
201 | u32 unc_err_sever_and; | ||
202 | u32 unc_err_sever_or; | ||
203 | u32 cor_err_mask_and; | ||
204 | u32 cor_err_mask_or; | ||
205 | u32 adv_err_cap_and; | ||
206 | u32 adv_err_cap_or; | ||
207 | u16 pci_exp_devctl_and; | ||
208 | u16 pci_exp_devctl_or; | ||
209 | u16 pci_exp_lnkctl_and; | ||
210 | u16 pci_exp_lnkctl_or; | ||
211 | u32 sec_unc_err_sever_and; | ||
212 | u32 sec_unc_err_sever_or; | ||
213 | u32 sec_unc_err_mask_and; | ||
214 | u32 sec_unc_err_mask_or; | ||
215 | }; | ||
216 | |||
217 | struct hotplug_params { | ||
218 | struct hpp_type0 *t0; /* Type0: NULL if not available */ | ||
219 | struct hpp_type1 *t1; /* Type1: NULL if not available */ | ||
220 | struct hpp_type2 *t2; /* Type2: NULL if not available */ | ||
221 | struct hpp_type0 type0_data; | ||
222 | struct hpp_type1 type1_data; | ||
223 | struct hpp_type2 type2_data; | ||
224 | }; | ||
225 | |||
226 | #ifdef CONFIG_ACPI | ||
227 | #include <acpi/acpi.h> | ||
228 | #include <acpi/acpi_bus.h> | ||
229 | #include <acpi/actypes.h> | ||
230 | extern acpi_status acpi_run_oshp(acpi_handle handle); | ||
231 | extern acpi_status acpi_get_hp_params_from_firmware(struct pci_bus *bus, | ||
232 | struct hotplug_params *hpp); | ||
233 | int acpi_root_bridge(acpi_handle handle); | ||
234 | #endif | ||
235 | #endif | ||
236 | |||
diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c index e2823ea9c4ed..f5d632e72323 100644 --- a/drivers/pci/hotplug/pci_hotplug_core.c +++ b/drivers/pci/hotplug/pci_hotplug_core.c | |||
@@ -21,9 +21,7 @@ | |||
21 | * along with this program; if not, write to the Free Software | 21 | * along with this program; if not, write to the Free Software |
22 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 22 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
23 | * | 23 | * |
24 | * Send feedback to <greg@kroah.com> | 24 | * Send feedback to <kristen.c.accardi@intel.com> |
25 | * | ||
26 | * Filesystem portion based on work done by Pat Mochel on ddfs/driverfs | ||
27 | * | 25 | * |
28 | */ | 26 | */ |
29 | 27 | ||
@@ -32,6 +30,8 @@ | |||
32 | #include <linux/kernel.h> | 30 | #include <linux/kernel.h> |
33 | #include <linux/types.h> | 31 | #include <linux/types.h> |
34 | #include <linux/list.h> | 32 | #include <linux/list.h> |
33 | #include <linux/kobject.h> | ||
34 | #include <linux/sysfs.h> | ||
35 | #include <linux/pagemap.h> | 35 | #include <linux/pagemap.h> |
36 | #include <linux/slab.h> | 36 | #include <linux/slab.h> |
37 | #include <linux/smp_lock.h> | 37 | #include <linux/smp_lock.h> |
@@ -39,11 +39,8 @@ | |||
39 | #include <linux/mount.h> | 39 | #include <linux/mount.h> |
40 | #include <linux/namei.h> | 40 | #include <linux/namei.h> |
41 | #include <linux/pci.h> | 41 | #include <linux/pci.h> |
42 | #include <linux/pci_hotplug.h> | ||
42 | #include <asm/uaccess.h> | 43 | #include <asm/uaccess.h> |
43 | #include <linux/kobject.h> | ||
44 | #include <linux/sysfs.h> | ||
45 | #include "pci_hotplug.h" | ||
46 | |||
47 | 44 | ||
48 | #define MY_NAME "pci_hotplug" | 45 | #define MY_NAME "pci_hotplug" |
49 | 46 | ||
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index eaea9d36a1bb..4fb12fcda563 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h | |||
@@ -31,11 +31,11 @@ | |||
31 | 31 | ||
32 | #include <linux/types.h> | 32 | #include <linux/types.h> |
33 | #include <linux/pci.h> | 33 | #include <linux/pci.h> |
34 | #include <linux/pci_hotplug.h> | ||
34 | #include <linux/delay.h> | 35 | #include <linux/delay.h> |
35 | #include <linux/sched.h> /* signal_pending() */ | 36 | #include <linux/sched.h> /* signal_pending() */ |
36 | #include <linux/pcieport_if.h> | 37 | #include <linux/pcieport_if.h> |
37 | #include <linux/mutex.h> | 38 | #include <linux/mutex.h> |
38 | #include "pci_hotplug.h" | ||
39 | 39 | ||
40 | #define MY_NAME "pciehp" | 40 | #define MY_NAME "pciehp" |
41 | 41 | ||
@@ -92,6 +92,7 @@ struct php_ctlr_state_s { | |||
92 | struct controller { | 92 | struct controller { |
93 | struct controller *next; | 93 | struct controller *next; |
94 | struct mutex crit_sect; /* critical section mutex */ | 94 | struct mutex crit_sect; /* critical section mutex */ |
95 | struct mutex ctrl_lock; /* controller lock */ | ||
95 | struct php_ctlr_state_s *hpc_ctlr_handle; /* HPC controller handle */ | 96 | struct php_ctlr_state_s *hpc_ctlr_handle; /* HPC controller handle */ |
96 | int num_slots; /* Number of slots on ctlr */ | 97 | int num_slots; /* Number of slots on ctlr */ |
97 | int slot_num_inc; /* 1 or -1 */ | 98 | int slot_num_inc; /* 1 or -1 */ |
@@ -166,10 +167,10 @@ struct controller { | |||
166 | * error Messages | 167 | * error Messages |
167 | */ | 168 | */ |
168 | #define msg_initialization_err "Initialization failure, error=%d\n" | 169 | #define msg_initialization_err "Initialization failure, error=%d\n" |
169 | #define msg_button_on "PCI slot #%d - powering on due to button press.\n" | 170 | #define msg_button_on "PCI slot #%s - powering on due to button press.\n" |
170 | #define msg_button_off "PCI slot #%d - powering off due to button press.\n" | 171 | #define msg_button_off "PCI slot #%s - powering off due to button press.\n" |
171 | #define msg_button_cancel "PCI slot #%d - action canceled due to button press.\n" | 172 | #define msg_button_cancel "PCI slot #%s - action canceled due to button press.\n" |
172 | #define msg_button_ignore "PCI slot #%d - button press ignored. (action in progress...)\n" | 173 | #define msg_button_ignore "PCI slot #%s - button press ignored. (action in progress...)\n" |
173 | 174 | ||
174 | /* controller functions */ | 175 | /* controller functions */ |
175 | extern int pciehp_event_start_thread (void); | 176 | extern int pciehp_event_start_thread (void); |
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index c67b7c3f1ddf..f93e81e2d2c7 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c | |||
@@ -448,7 +448,7 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ | |||
448 | } | 448 | } |
449 | 449 | ||
450 | /* Wait for exclusive access to hardware */ | 450 | /* Wait for exclusive access to hardware */ |
451 | mutex_lock(&ctrl->crit_sect); | 451 | mutex_lock(&ctrl->ctrl_lock); |
452 | 452 | ||
453 | t_slot->hpc_ops->get_adapter_status(t_slot, &value); /* Check if slot is occupied */ | 453 | t_slot->hpc_ops->get_adapter_status(t_slot, &value); /* Check if slot is occupied */ |
454 | 454 | ||
@@ -456,7 +456,7 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ | |||
456 | rc = t_slot->hpc_ops->power_off_slot(t_slot); /* Power off slot if not occupied*/ | 456 | rc = t_slot->hpc_ops->power_off_slot(t_slot); /* Power off slot if not occupied*/ |
457 | if (rc) { | 457 | if (rc) { |
458 | /* Done with exclusive hardware access */ | 458 | /* Done with exclusive hardware access */ |
459 | mutex_unlock(&ctrl->crit_sect); | 459 | mutex_unlock(&ctrl->ctrl_lock); |
460 | goto err_out_free_ctrl_slot; | 460 | goto err_out_free_ctrl_slot; |
461 | } else | 461 | } else |
462 | /* Wait for the command to complete */ | 462 | /* Wait for the command to complete */ |
@@ -464,7 +464,7 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ | |||
464 | } | 464 | } |
465 | 465 | ||
466 | /* Done with exclusive hardware access */ | 466 | /* Done with exclusive hardware access */ |
467 | mutex_unlock(&ctrl->crit_sect); | 467 | mutex_unlock(&ctrl->ctrl_lock); |
468 | 468 | ||
469 | return 0; | 469 | return 0; |
470 | 470 | ||
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c index 41290a106bd8..372c63e35aa9 100644 --- a/drivers/pci/hotplug/pciehp_ctrl.c +++ b/drivers/pci/hotplug/pciehp_ctrl.c | |||
@@ -43,6 +43,11 @@ static int event_finished; | |||
43 | static unsigned long pushbutton_pending; /* = 0 */ | 43 | static unsigned long pushbutton_pending; /* = 0 */ |
44 | static unsigned long surprise_rm_pending; /* = 0 */ | 44 | static unsigned long surprise_rm_pending; /* = 0 */ |
45 | 45 | ||
46 | static inline char *slot_name(struct slot *p_slot) | ||
47 | { | ||
48 | return p_slot->hotplug_slot->name; | ||
49 | } | ||
50 | |||
46 | u8 pciehp_handle_attention_button(u8 hp_slot, void *inst_id) | 51 | u8 pciehp_handle_attention_button(u8 hp_slot, void *inst_id) |
47 | { | 52 | { |
48 | struct controller *ctrl = (struct controller *) inst_id; | 53 | struct controller *ctrl = (struct controller *) inst_id; |
@@ -68,7 +73,7 @@ u8 pciehp_handle_attention_button(u8 hp_slot, void *inst_id) | |||
68 | /* | 73 | /* |
69 | * Button pressed - See if need to TAKE ACTION!!! | 74 | * Button pressed - See if need to TAKE ACTION!!! |
70 | */ | 75 | */ |
71 | info("Button pressed on Slot(%d)\n", ctrl->first_slot + hp_slot); | 76 | info("Button pressed on Slot(%s)\n", slot_name(p_slot)); |
72 | taskInfo->event_type = INT_BUTTON_PRESS; | 77 | taskInfo->event_type = INT_BUTTON_PRESS; |
73 | 78 | ||
74 | if ((p_slot->state == BLINKINGON_STATE) | 79 | if ((p_slot->state == BLINKINGON_STATE) |
@@ -78,7 +83,7 @@ u8 pciehp_handle_attention_button(u8 hp_slot, void *inst_id) | |||
78 | * or hot-remove | 83 | * or hot-remove |
79 | */ | 84 | */ |
80 | taskInfo->event_type = INT_BUTTON_CANCEL; | 85 | taskInfo->event_type = INT_BUTTON_CANCEL; |
81 | info("Button cancel on Slot(%d)\n", ctrl->first_slot + hp_slot); | 86 | info("Button cancel on Slot(%s)\n", slot_name(p_slot)); |
82 | } else if ((p_slot->state == POWERON_STATE) | 87 | } else if ((p_slot->state == POWERON_STATE) |
83 | || (p_slot->state == POWEROFF_STATE)) { | 88 | || (p_slot->state == POWEROFF_STATE)) { |
84 | /* Ignore if the slot is on power-on or power-off state; this | 89 | /* Ignore if the slot is on power-on or power-off state; this |
@@ -86,7 +91,7 @@ u8 pciehp_handle_attention_button(u8 hp_slot, void *inst_id) | |||
86 | * hot-remove is undergoing | 91 | * hot-remove is undergoing |
87 | */ | 92 | */ |
88 | taskInfo->event_type = INT_BUTTON_IGNORE; | 93 | taskInfo->event_type = INT_BUTTON_IGNORE; |
89 | info("Button ignore on Slot(%d)\n", ctrl->first_slot + hp_slot); | 94 | info("Button ignore on Slot(%s)\n", slot_name(p_slot)); |
90 | } | 95 | } |
91 | 96 | ||
92 | if (rc) | 97 | if (rc) |
@@ -122,13 +127,13 @@ u8 pciehp_handle_switch_change(u8 hp_slot, void *inst_id) | |||
122 | /* | 127 | /* |
123 | * Switch opened | 128 | * Switch opened |
124 | */ | 129 | */ |
125 | info("Latch open on Slot(%d)\n", ctrl->first_slot + hp_slot); | 130 | info("Latch open on Slot(%s)\n", slot_name(p_slot)); |
126 | taskInfo->event_type = INT_SWITCH_OPEN; | 131 | taskInfo->event_type = INT_SWITCH_OPEN; |
127 | } else { | 132 | } else { |
128 | /* | 133 | /* |
129 | * Switch closed | 134 | * Switch closed |
130 | */ | 135 | */ |
131 | info("Latch close on Slot(%d)\n", ctrl->first_slot + hp_slot); | 136 | info("Latch close on Slot(%s)\n", slot_name(p_slot)); |
132 | taskInfo->event_type = INT_SWITCH_CLOSE; | 137 | taskInfo->event_type = INT_SWITCH_CLOSE; |
133 | } | 138 | } |
134 | 139 | ||
@@ -166,13 +171,13 @@ u8 pciehp_handle_presence_change(u8 hp_slot, void *inst_id) | |||
166 | /* | 171 | /* |
167 | * Card Present | 172 | * Card Present |
168 | */ | 173 | */ |
169 | info("Card present on Slot(%d)\n", ctrl->first_slot + hp_slot); | 174 | info("Card present on Slot(%s)\n", slot_name(p_slot)); |
170 | taskInfo->event_type = INT_PRESENCE_ON; | 175 | taskInfo->event_type = INT_PRESENCE_ON; |
171 | } else { | 176 | } else { |
172 | /* | 177 | /* |
173 | * Not Present | 178 | * Not Present |
174 | */ | 179 | */ |
175 | info("Card not present on Slot(%d)\n", ctrl->first_slot + hp_slot); | 180 | info("Card not present on Slot(%s)\n", slot_name(p_slot)); |
176 | taskInfo->event_type = INT_PRESENCE_OFF; | 181 | taskInfo->event_type = INT_PRESENCE_OFF; |
177 | } | 182 | } |
178 | 183 | ||
@@ -206,13 +211,13 @@ u8 pciehp_handle_power_fault(u8 hp_slot, void *inst_id) | |||
206 | /* | 211 | /* |
207 | * power fault Cleared | 212 | * power fault Cleared |
208 | */ | 213 | */ |
209 | info("Power fault cleared on Slot(%d)\n", ctrl->first_slot + hp_slot); | 214 | info("Power fault cleared on Slot(%s)\n", slot_name(p_slot)); |
210 | taskInfo->event_type = INT_POWER_FAULT_CLEAR; | 215 | taskInfo->event_type = INT_POWER_FAULT_CLEAR; |
211 | } else { | 216 | } else { |
212 | /* | 217 | /* |
213 | * power fault | 218 | * power fault |
214 | */ | 219 | */ |
215 | info("Power fault on Slot(%d)\n", ctrl->first_slot + hp_slot); | 220 | info("Power fault on Slot(%s)\n", slot_name(p_slot)); |
216 | taskInfo->event_type = INT_POWER_FAULT; | 221 | taskInfo->event_type = INT_POWER_FAULT; |
217 | info("power fault bit %x set\n", hp_slot); | 222 | info("power fault bit %x set\n", hp_slot); |
218 | } | 223 | } |
@@ -229,13 +234,13 @@ u8 pciehp_handle_power_fault(u8 hp_slot, void *inst_id) | |||
229 | static void set_slot_off(struct controller *ctrl, struct slot * pslot) | 234 | static void set_slot_off(struct controller *ctrl, struct slot * pslot) |
230 | { | 235 | { |
231 | /* Wait for exclusive access to hardware */ | 236 | /* Wait for exclusive access to hardware */ |
232 | mutex_lock(&ctrl->crit_sect); | 237 | mutex_lock(&ctrl->ctrl_lock); |
233 | 238 | ||
234 | /* turn off slot, turn on Amber LED, turn off Green LED if supported*/ | 239 | /* turn off slot, turn on Amber LED, turn off Green LED if supported*/ |
235 | if (POWER_CTRL(ctrl->ctrlcap)) { | 240 | if (POWER_CTRL(ctrl->ctrlcap)) { |
236 | if (pslot->hpc_ops->power_off_slot(pslot)) { | 241 | if (pslot->hpc_ops->power_off_slot(pslot)) { |
237 | err("%s: Issue of Slot Power Off command failed\n", __FUNCTION__); | 242 | err("%s: Issue of Slot Power Off command failed\n", __FUNCTION__); |
238 | mutex_unlock(&ctrl->crit_sect); | 243 | mutex_unlock(&ctrl->ctrl_lock); |
239 | return; | 244 | return; |
240 | } | 245 | } |
241 | wait_for_ctrl_irq (ctrl); | 246 | wait_for_ctrl_irq (ctrl); |
@@ -249,14 +254,14 @@ static void set_slot_off(struct controller *ctrl, struct slot * pslot) | |||
249 | if (ATTN_LED(ctrl->ctrlcap)) { | 254 | if (ATTN_LED(ctrl->ctrlcap)) { |
250 | if (pslot->hpc_ops->set_attention_status(pslot, 1)) { | 255 | if (pslot->hpc_ops->set_attention_status(pslot, 1)) { |
251 | err("%s: Issue of Set Attention Led command failed\n", __FUNCTION__); | 256 | err("%s: Issue of Set Attention Led command failed\n", __FUNCTION__); |
252 | mutex_unlock(&ctrl->crit_sect); | 257 | mutex_unlock(&ctrl->ctrl_lock); |
253 | return; | 258 | return; |
254 | } | 259 | } |
255 | wait_for_ctrl_irq (ctrl); | 260 | wait_for_ctrl_irq (ctrl); |
256 | } | 261 | } |
257 | 262 | ||
258 | /* Done with exclusive hardware access */ | 263 | /* Done with exclusive hardware access */ |
259 | mutex_unlock(&ctrl->crit_sect); | 264 | mutex_unlock(&ctrl->ctrl_lock); |
260 | } | 265 | } |
261 | 266 | ||
262 | /** | 267 | /** |
@@ -279,13 +284,13 @@ static int board_added(struct slot *p_slot) | |||
279 | ctrl->slot_device_offset, hp_slot); | 284 | ctrl->slot_device_offset, hp_slot); |
280 | 285 | ||
281 | /* Wait for exclusive access to hardware */ | 286 | /* Wait for exclusive access to hardware */ |
282 | mutex_lock(&ctrl->crit_sect); | 287 | mutex_lock(&ctrl->ctrl_lock); |
283 | 288 | ||
284 | if (POWER_CTRL(ctrl->ctrlcap)) { | 289 | if (POWER_CTRL(ctrl->ctrlcap)) { |
285 | /* Power on slot */ | 290 | /* Power on slot */ |
286 | rc = p_slot->hpc_ops->power_on_slot(p_slot); | 291 | rc = p_slot->hpc_ops->power_on_slot(p_slot); |
287 | if (rc) { | 292 | if (rc) { |
288 | mutex_unlock(&ctrl->crit_sect); | 293 | mutex_unlock(&ctrl->ctrl_lock); |
289 | return -1; | 294 | return -1; |
290 | } | 295 | } |
291 | 296 | ||
@@ -301,7 +306,7 @@ static int board_added(struct slot *p_slot) | |||
301 | } | 306 | } |
302 | 307 | ||
303 | /* Done with exclusive hardware access */ | 308 | /* Done with exclusive hardware access */ |
304 | mutex_unlock(&ctrl->crit_sect); | 309 | mutex_unlock(&ctrl->ctrl_lock); |
305 | 310 | ||
306 | /* Wait for ~1 second */ | 311 | /* Wait for ~1 second */ |
307 | wait_for_ctrl_irq (ctrl); | 312 | wait_for_ctrl_irq (ctrl); |
@@ -335,7 +340,7 @@ static int board_added(struct slot *p_slot) | |||
335 | pci_fixup_device(pci_fixup_final, ctrl->pci_dev); | 340 | pci_fixup_device(pci_fixup_final, ctrl->pci_dev); |
336 | if (PWR_LED(ctrl->ctrlcap)) { | 341 | if (PWR_LED(ctrl->ctrlcap)) { |
337 | /* Wait for exclusive access to hardware */ | 342 | /* Wait for exclusive access to hardware */ |
338 | mutex_lock(&ctrl->crit_sect); | 343 | mutex_lock(&ctrl->ctrl_lock); |
339 | 344 | ||
340 | p_slot->hpc_ops->green_led_on(p_slot); | 345 | p_slot->hpc_ops->green_led_on(p_slot); |
341 | 346 | ||
@@ -343,7 +348,7 @@ static int board_added(struct slot *p_slot) | |||
343 | wait_for_ctrl_irq (ctrl); | 348 | wait_for_ctrl_irq (ctrl); |
344 | 349 | ||
345 | /* Done with exclusive hardware access */ | 350 | /* Done with exclusive hardware access */ |
346 | mutex_unlock(&ctrl->crit_sect); | 351 | mutex_unlock(&ctrl->ctrl_lock); |
347 | } | 352 | } |
348 | return 0; | 353 | return 0; |
349 | 354 | ||
@@ -375,14 +380,14 @@ static int remove_board(struct slot *p_slot) | |||
375 | dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot); | 380 | dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot); |
376 | 381 | ||
377 | /* Wait for exclusive access to hardware */ | 382 | /* Wait for exclusive access to hardware */ |
378 | mutex_lock(&ctrl->crit_sect); | 383 | mutex_lock(&ctrl->ctrl_lock); |
379 | 384 | ||
380 | if (POWER_CTRL(ctrl->ctrlcap)) { | 385 | if (POWER_CTRL(ctrl->ctrlcap)) { |
381 | /* power off slot */ | 386 | /* power off slot */ |
382 | rc = p_slot->hpc_ops->power_off_slot(p_slot); | 387 | rc = p_slot->hpc_ops->power_off_slot(p_slot); |
383 | if (rc) { | 388 | if (rc) { |
384 | err("%s: Issue of Slot Disable command failed\n", __FUNCTION__); | 389 | err("%s: Issue of Slot Disable command failed\n", __FUNCTION__); |
385 | mutex_unlock(&ctrl->crit_sect); | 390 | mutex_unlock(&ctrl->ctrl_lock); |
386 | return rc; | 391 | return rc; |
387 | } | 392 | } |
388 | /* Wait for the command to complete */ | 393 | /* Wait for the command to complete */ |
@@ -398,7 +403,7 @@ static int remove_board(struct slot *p_slot) | |||
398 | } | 403 | } |
399 | 404 | ||
400 | /* Done with exclusive hardware access */ | 405 | /* Done with exclusive hardware access */ |
401 | mutex_unlock(&ctrl->crit_sect); | 406 | mutex_unlock(&ctrl->ctrl_lock); |
402 | 407 | ||
403 | return 0; | 408 | return 0; |
404 | } | 409 | } |
@@ -445,7 +450,7 @@ static void pciehp_pushbutton_thread(unsigned long slot) | |||
445 | 450 | ||
446 | if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) { | 451 | if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) { |
447 | /* Wait for exclusive access to hardware */ | 452 | /* Wait for exclusive access to hardware */ |
448 | mutex_lock(&p_slot->ctrl->crit_sect); | 453 | mutex_lock(&p_slot->ctrl->ctrl_lock); |
449 | 454 | ||
450 | p_slot->hpc_ops->green_led_off(p_slot); | 455 | p_slot->hpc_ops->green_led_off(p_slot); |
451 | 456 | ||
@@ -453,7 +458,7 @@ static void pciehp_pushbutton_thread(unsigned long slot) | |||
453 | wait_for_ctrl_irq (p_slot->ctrl); | 458 | wait_for_ctrl_irq (p_slot->ctrl); |
454 | 459 | ||
455 | /* Done with exclusive hardware access */ | 460 | /* Done with exclusive hardware access */ |
456 | mutex_unlock(&p_slot->ctrl->crit_sect); | 461 | mutex_unlock(&p_slot->ctrl->ctrl_lock); |
457 | } | 462 | } |
458 | p_slot->state = STATIC_STATE; | 463 | p_slot->state = STATIC_STATE; |
459 | } | 464 | } |
@@ -495,7 +500,7 @@ static void pciehp_surprise_rm_thread(unsigned long slot) | |||
495 | 500 | ||
496 | if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) { | 501 | if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) { |
497 | /* Wait for exclusive access to hardware */ | 502 | /* Wait for exclusive access to hardware */ |
498 | mutex_lock(&p_slot->ctrl->crit_sect); | 503 | mutex_lock(&p_slot->ctrl->ctrl_lock); |
499 | 504 | ||
500 | p_slot->hpc_ops->green_led_off(p_slot); | 505 | p_slot->hpc_ops->green_led_off(p_slot); |
501 | 506 | ||
@@ -503,7 +508,7 @@ static void pciehp_surprise_rm_thread(unsigned long slot) | |||
503 | wait_for_ctrl_irq (p_slot->ctrl); | 508 | wait_for_ctrl_irq (p_slot->ctrl); |
504 | 509 | ||
505 | /* Done with exclusive hardware access */ | 510 | /* Done with exclusive hardware access */ |
506 | mutex_unlock(&p_slot->ctrl->crit_sect); | 511 | mutex_unlock(&p_slot->ctrl->ctrl_lock); |
507 | } | 512 | } |
508 | p_slot->state = STATIC_STATE; | 513 | p_slot->state = STATIC_STATE; |
509 | } | 514 | } |
@@ -616,7 +621,7 @@ static void interrupt_event_handler(struct controller *ctrl) | |||
616 | switch (p_slot->state) { | 621 | switch (p_slot->state) { |
617 | case BLINKINGOFF_STATE: | 622 | case BLINKINGOFF_STATE: |
618 | /* Wait for exclusive access to hardware */ | 623 | /* Wait for exclusive access to hardware */ |
619 | mutex_lock(&ctrl->crit_sect); | 624 | mutex_lock(&ctrl->ctrl_lock); |
620 | 625 | ||
621 | if (PWR_LED(ctrl->ctrlcap)) { | 626 | if (PWR_LED(ctrl->ctrlcap)) { |
622 | p_slot->hpc_ops->green_led_on(p_slot); | 627 | p_slot->hpc_ops->green_led_on(p_slot); |
@@ -630,11 +635,11 @@ static void interrupt_event_handler(struct controller *ctrl) | |||
630 | wait_for_ctrl_irq (ctrl); | 635 | wait_for_ctrl_irq (ctrl); |
631 | } | 636 | } |
632 | /* Done with exclusive hardware access */ | 637 | /* Done with exclusive hardware access */ |
633 | mutex_unlock(&ctrl->crit_sect); | 638 | mutex_unlock(&ctrl->ctrl_lock); |
634 | break; | 639 | break; |
635 | case BLINKINGON_STATE: | 640 | case BLINKINGON_STATE: |
636 | /* Wait for exclusive access to hardware */ | 641 | /* Wait for exclusive access to hardware */ |
637 | mutex_lock(&ctrl->crit_sect); | 642 | mutex_lock(&ctrl->ctrl_lock); |
638 | 643 | ||
639 | if (PWR_LED(ctrl->ctrlcap)) { | 644 | if (PWR_LED(ctrl->ctrlcap)) { |
640 | p_slot->hpc_ops->green_led_off(p_slot); | 645 | p_slot->hpc_ops->green_led_off(p_slot); |
@@ -647,14 +652,14 @@ static void interrupt_event_handler(struct controller *ctrl) | |||
647 | wait_for_ctrl_irq (ctrl); | 652 | wait_for_ctrl_irq (ctrl); |
648 | } | 653 | } |
649 | /* Done with exclusive hardware access */ | 654 | /* Done with exclusive hardware access */ |
650 | mutex_unlock(&ctrl->crit_sect); | 655 | mutex_unlock(&ctrl->ctrl_lock); |
651 | 656 | ||
652 | break; | 657 | break; |
653 | default: | 658 | default: |
654 | warn("Not a valid state\n"); | 659 | warn("Not a valid state\n"); |
655 | return; | 660 | return; |
656 | } | 661 | } |
657 | info(msg_button_cancel, p_slot->number); | 662 | info(msg_button_cancel, slot_name(p_slot)); |
658 | p_slot->state = STATIC_STATE; | 663 | p_slot->state = STATIC_STATE; |
659 | } | 664 | } |
660 | /* ***********Button Pressed (No action on 1st press...) */ | 665 | /* ***********Button Pressed (No action on 1st press...) */ |
@@ -667,16 +672,16 @@ static void interrupt_event_handler(struct controller *ctrl) | |||
667 | /* slot is on */ | 672 | /* slot is on */ |
668 | dbg("slot is on\n"); | 673 | dbg("slot is on\n"); |
669 | p_slot->state = BLINKINGOFF_STATE; | 674 | p_slot->state = BLINKINGOFF_STATE; |
670 | info(msg_button_off, p_slot->number); | 675 | info(msg_button_off, slot_name(p_slot)); |
671 | } else { | 676 | } else { |
672 | /* slot is off */ | 677 | /* slot is off */ |
673 | dbg("slot is off\n"); | 678 | dbg("slot is off\n"); |
674 | p_slot->state = BLINKINGON_STATE; | 679 | p_slot->state = BLINKINGON_STATE; |
675 | info(msg_button_on, p_slot->number); | 680 | info(msg_button_on, slot_name(p_slot)); |
676 | } | 681 | } |
677 | 682 | ||
678 | /* Wait for exclusive access to hardware */ | 683 | /* Wait for exclusive access to hardware */ |
679 | mutex_lock(&ctrl->crit_sect); | 684 | mutex_lock(&ctrl->ctrl_lock); |
680 | 685 | ||
681 | /* blink green LED and turn off amber */ | 686 | /* blink green LED and turn off amber */ |
682 | if (PWR_LED(ctrl->ctrlcap)) { | 687 | if (PWR_LED(ctrl->ctrlcap)) { |
@@ -693,7 +698,7 @@ static void interrupt_event_handler(struct controller *ctrl) | |||
693 | } | 698 | } |
694 | 699 | ||
695 | /* Done with exclusive hardware access */ | 700 | /* Done with exclusive hardware access */ |
696 | mutex_unlock(&ctrl->crit_sect); | 701 | mutex_unlock(&ctrl->ctrl_lock); |
697 | 702 | ||
698 | init_timer(&p_slot->task_event); | 703 | init_timer(&p_slot->task_event); |
699 | p_slot->task_event.expires = jiffies + 5 * HZ; /* 5 second delay */ | 704 | p_slot->task_event.expires = jiffies + 5 * HZ; /* 5 second delay */ |
@@ -708,7 +713,7 @@ static void interrupt_event_handler(struct controller *ctrl) | |||
708 | if (POWER_CTRL(ctrl->ctrlcap)) { | 713 | if (POWER_CTRL(ctrl->ctrlcap)) { |
709 | dbg("power fault\n"); | 714 | dbg("power fault\n"); |
710 | /* Wait for exclusive access to hardware */ | 715 | /* Wait for exclusive access to hardware */ |
711 | mutex_lock(&ctrl->crit_sect); | 716 | mutex_lock(&ctrl->ctrl_lock); |
712 | 717 | ||
713 | if (ATTN_LED(ctrl->ctrlcap)) { | 718 | if (ATTN_LED(ctrl->ctrlcap)) { |
714 | p_slot->hpc_ops->set_attention_status(p_slot, 1); | 719 | p_slot->hpc_ops->set_attention_status(p_slot, 1); |
@@ -721,7 +726,7 @@ static void interrupt_event_handler(struct controller *ctrl) | |||
721 | } | 726 | } |
722 | 727 | ||
723 | /* Done with exclusive hardware access */ | 728 | /* Done with exclusive hardware access */ |
724 | mutex_unlock(&ctrl->crit_sect); | 729 | mutex_unlock(&ctrl->ctrl_lock); |
725 | } | 730 | } |
726 | } | 731 | } |
727 | /***********SURPRISE REMOVAL********************/ | 732 | /***********SURPRISE REMOVAL********************/ |
@@ -760,14 +765,16 @@ int pciehp_enable_slot(struct slot *p_slot) | |||
760 | 765 | ||
761 | rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); | 766 | rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); |
762 | if (rc || !getstatus) { | 767 | if (rc || !getstatus) { |
763 | info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number); | 768 | info("%s: no adapter on slot(%s)\n", __FUNCTION__, |
769 | slot_name(p_slot)); | ||
764 | mutex_unlock(&p_slot->ctrl->crit_sect); | 770 | mutex_unlock(&p_slot->ctrl->crit_sect); |
765 | return -ENODEV; | 771 | return -ENODEV; |
766 | } | 772 | } |
767 | if (MRL_SENS(p_slot->ctrl->ctrlcap)) { | 773 | if (MRL_SENS(p_slot->ctrl->ctrlcap)) { |
768 | rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); | 774 | rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); |
769 | if (rc || getstatus) { | 775 | if (rc || getstatus) { |
770 | info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); | 776 | info("%s: latch open on slot(%s)\n", __FUNCTION__, |
777 | slot_name(p_slot)); | ||
771 | mutex_unlock(&p_slot->ctrl->crit_sect); | 778 | mutex_unlock(&p_slot->ctrl->crit_sect); |
772 | return -ENODEV; | 779 | return -ENODEV; |
773 | } | 780 | } |
@@ -776,12 +783,12 @@ int pciehp_enable_slot(struct slot *p_slot) | |||
776 | if (POWER_CTRL(p_slot->ctrl->ctrlcap)) { | 783 | if (POWER_CTRL(p_slot->ctrl->ctrlcap)) { |
777 | rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); | 784 | rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); |
778 | if (rc || getstatus) { | 785 | if (rc || getstatus) { |
779 | info("%s: already enabled on slot(%x)\n", __FUNCTION__, p_slot->number); | 786 | info("%s: already enabled on slot(%s)\n", __FUNCTION__, |
787 | slot_name(p_slot)); | ||
780 | mutex_unlock(&p_slot->ctrl->crit_sect); | 788 | mutex_unlock(&p_slot->ctrl->crit_sect); |
781 | return -EINVAL; | 789 | return -EINVAL; |
782 | } | 790 | } |
783 | } | 791 | } |
784 | mutex_unlock(&p_slot->ctrl->crit_sect); | ||
785 | 792 | ||
786 | p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); | 793 | p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); |
787 | 794 | ||
@@ -790,9 +797,9 @@ int pciehp_enable_slot(struct slot *p_slot) | |||
790 | p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); | 797 | p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); |
791 | } | 798 | } |
792 | 799 | ||
793 | if (p_slot) | 800 | update_slot_info(p_slot); |
794 | update_slot_info(p_slot); | ||
795 | 801 | ||
802 | mutex_unlock(&p_slot->ctrl->crit_sect); | ||
796 | return rc; | 803 | return rc; |
797 | } | 804 | } |
798 | 805 | ||
@@ -811,7 +818,8 @@ int pciehp_disable_slot(struct slot *p_slot) | |||
811 | if (!HP_SUPR_RM(p_slot->ctrl->ctrlcap)) { | 818 | if (!HP_SUPR_RM(p_slot->ctrl->ctrlcap)) { |
812 | ret = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); | 819 | ret = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); |
813 | if (ret || !getstatus) { | 820 | if (ret || !getstatus) { |
814 | info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number); | 821 | info("%s: no adapter on slot(%s)\n", __FUNCTION__, |
822 | slot_name(p_slot)); | ||
815 | mutex_unlock(&p_slot->ctrl->crit_sect); | 823 | mutex_unlock(&p_slot->ctrl->crit_sect); |
816 | return -ENODEV; | 824 | return -ENODEV; |
817 | } | 825 | } |
@@ -820,7 +828,8 @@ int pciehp_disable_slot(struct slot *p_slot) | |||
820 | if (MRL_SENS(p_slot->ctrl->ctrlcap)) { | 828 | if (MRL_SENS(p_slot->ctrl->ctrlcap)) { |
821 | ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); | 829 | ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); |
822 | if (ret || getstatus) { | 830 | if (ret || getstatus) { |
823 | info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); | 831 | info("%s: latch open on slot(%s)\n", __FUNCTION__, |
832 | slot_name(p_slot)); | ||
824 | mutex_unlock(&p_slot->ctrl->crit_sect); | 833 | mutex_unlock(&p_slot->ctrl->crit_sect); |
825 | return -ENODEV; | 834 | return -ENODEV; |
826 | } | 835 | } |
@@ -829,16 +838,17 @@ int pciehp_disable_slot(struct slot *p_slot) | |||
829 | if (POWER_CTRL(p_slot->ctrl->ctrlcap)) { | 838 | if (POWER_CTRL(p_slot->ctrl->ctrlcap)) { |
830 | ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); | 839 | ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); |
831 | if (ret || !getstatus) { | 840 | if (ret || !getstatus) { |
832 | info("%s: already disabled slot(%x)\n", __FUNCTION__, p_slot->number); | 841 | info("%s: already disabled slot(%s)\n", __FUNCTION__, |
842 | slot_name(p_slot)); | ||
833 | mutex_unlock(&p_slot->ctrl->crit_sect); | 843 | mutex_unlock(&p_slot->ctrl->crit_sect); |
834 | return -EINVAL; | 844 | return -EINVAL; |
835 | } | 845 | } |
836 | } | 846 | } |
837 | 847 | ||
838 | mutex_unlock(&p_slot->ctrl->crit_sect); | ||
839 | |||
840 | ret = remove_board(p_slot); | 848 | ret = remove_board(p_slot); |
841 | update_slot_info(p_slot); | 849 | update_slot_info(p_slot); |
850 | |||
851 | mutex_unlock(&p_slot->ctrl->crit_sect); | ||
842 | return ret; | 852 | return ret; |
843 | } | 853 | } |
844 | 854 | ||
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 703a64a39fe8..1c551c697c35 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c | |||
@@ -1402,6 +1402,8 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) | |||
1402 | pdev->subsystem_vendor, pdev->subsystem_device); | 1402 | pdev->subsystem_vendor, pdev->subsystem_device); |
1403 | 1403 | ||
1404 | mutex_init(&ctrl->crit_sect); | 1404 | mutex_init(&ctrl->crit_sect); |
1405 | mutex_init(&ctrl->ctrl_lock); | ||
1406 | |||
1405 | /* setup wait queue */ | 1407 | /* setup wait queue */ |
1406 | init_waitqueue_head(&ctrl->queue); | 1408 | init_waitqueue_head(&ctrl->queue); |
1407 | 1409 | ||
diff --git a/drivers/pci/hotplug/pcihp_skeleton.c b/drivers/pci/hotplug/pcihp_skeleton.c index 2b9e10e38613..50bcd3fe61da 100644 --- a/drivers/pci/hotplug/pcihp_skeleton.c +++ b/drivers/pci/hotplug/pcihp_skeleton.c | |||
@@ -33,8 +33,8 @@ | |||
33 | #include <linux/kernel.h> | 33 | #include <linux/kernel.h> |
34 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
35 | #include <linux/pci.h> | 35 | #include <linux/pci.h> |
36 | #include <linux/pci_hotplug.h> | ||
36 | #include <linux/init.h> | 37 | #include <linux/init.h> |
37 | #include "pci_hotplug.h" | ||
38 | 38 | ||
39 | #define SLOT_NAME_SIZE 10 | 39 | #define SLOT_NAME_SIZE 10 |
40 | struct slot { | 40 | struct slot { |
diff --git a/drivers/pci/hotplug/rpadlpar_sysfs.c b/drivers/pci/hotplug/rpadlpar_sysfs.c index db69be85b458..6c5be3ff578c 100644 --- a/drivers/pci/hotplug/rpadlpar_sysfs.c +++ b/drivers/pci/hotplug/rpadlpar_sysfs.c | |||
@@ -14,7 +14,7 @@ | |||
14 | */ | 14 | */ |
15 | #include <linux/kobject.h> | 15 | #include <linux/kobject.h> |
16 | #include <linux/string.h> | 16 | #include <linux/string.h> |
17 | #include "pci_hotplug.h" | 17 | #include <linux/pci_hotplug.h> |
18 | #include "rpadlpar.h" | 18 | #include "rpadlpar.h" |
19 | 19 | ||
20 | #define DLPAR_KOBJ_NAME "control" | 20 | #define DLPAR_KOBJ_NAME "control" |
diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h index 310b6186c0e5..2e7accf0f734 100644 --- a/drivers/pci/hotplug/rpaphp.h +++ b/drivers/pci/hotplug/rpaphp.h | |||
@@ -28,7 +28,7 @@ | |||
28 | #define _PPC64PHP_H | 28 | #define _PPC64PHP_H |
29 | 29 | ||
30 | #include <linux/pci.h> | 30 | #include <linux/pci.h> |
31 | #include "pci_hotplug.h" | 31 | #include <linux/pci_hotplug.h> |
32 | 32 | ||
33 | #define DR_INDICATOR 9002 | 33 | #define DR_INDICATOR 9002 |
34 | #define DR_ENTITY_SENSE 9003 | 34 | #define DR_ENTITY_SENSE 9003 |
diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c index 7288a3eccfb3..141486df235b 100644 --- a/drivers/pci/hotplug/rpaphp_core.c +++ b/drivers/pci/hotplug/rpaphp_core.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/moduleparam.h> | 27 | #include <linux/moduleparam.h> |
28 | #include <linux/pci.h> | 28 | #include <linux/pci.h> |
29 | #include <linux/pci_hotplug.h> | ||
29 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
30 | #include <linux/smp.h> | 31 | #include <linux/smp.h> |
31 | #include <linux/smp_lock.h> | 32 | #include <linux/smp_lock.h> |
@@ -36,7 +37,6 @@ | |||
36 | #include "../pci.h" /* for pci_add_new_bus */ | 37 | #include "../pci.h" /* for pci_add_new_bus */ |
37 | /* and pci_do_scan_bus */ | 38 | /* and pci_do_scan_bus */ |
38 | #include "rpaphp.h" | 39 | #include "rpaphp.h" |
39 | #include "pci_hotplug.h" | ||
40 | 40 | ||
41 | int debug; | 41 | int debug; |
42 | static struct semaphore rpaphp_sem; | 42 | static struct semaphore rpaphp_sem; |
diff --git a/drivers/pci/hotplug/sgi_hotplug.c b/drivers/pci/hotplug/sgi_hotplug.c index f31d83c2c633..b62ad31a9739 100644 --- a/drivers/pci/hotplug/sgi_hotplug.c +++ b/drivers/pci/hotplug/sgi_hotplug.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/pci.h> | 15 | #include <linux/pci.h> |
16 | #include <linux/pci_hotplug.h> | ||
16 | #include <linux/proc_fs.h> | 17 | #include <linux/proc_fs.h> |
17 | #include <linux/types.h> | 18 | #include <linux/types.h> |
18 | #include <linux/mutex.h> | 19 | #include <linux/mutex.h> |
@@ -29,7 +30,6 @@ | |||
29 | #include <asm/sn/types.h> | 30 | #include <asm/sn/types.h> |
30 | 31 | ||
31 | #include "../pci.h" | 32 | #include "../pci.h" |
32 | #include "pci_hotplug.h" | ||
33 | 33 | ||
34 | MODULE_LICENSE("GPL"); | 34 | MODULE_LICENSE("GPL"); |
35 | MODULE_AUTHOR("SGI (prarit@sgi.com, dickie@sgi.com, habeck@sgi.com)"); | 35 | MODULE_AUTHOR("SGI (prarit@sgi.com, dickie@sgi.com, habeck@sgi.com)"); |
diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h index c7103ac5cd06..ea2087c34149 100644 --- a/drivers/pci/hotplug/shpchp.h +++ b/drivers/pci/hotplug/shpchp.h | |||
@@ -31,12 +31,11 @@ | |||
31 | 31 | ||
32 | #include <linux/types.h> | 32 | #include <linux/types.h> |
33 | #include <linux/pci.h> | 33 | #include <linux/pci.h> |
34 | #include <linux/pci_hotplug.h> | ||
34 | #include <linux/delay.h> | 35 | #include <linux/delay.h> |
35 | #include <linux/sched.h> /* signal_pending(), struct timer_list */ | 36 | #include <linux/sched.h> /* signal_pending(), struct timer_list */ |
36 | #include <linux/mutex.h> | 37 | #include <linux/mutex.h> |
37 | 38 | ||
38 | #include "pci_hotplug.h" | ||
39 | |||
40 | #if !defined(MODULE) | 39 | #if !defined(MODULE) |
41 | #define MY_NAME "shpchp" | 40 | #define MY_NAME "shpchp" |
42 | #else | 41 | #else |
@@ -103,7 +102,6 @@ struct controller { | |||
103 | u32 cap_offset; | 102 | u32 cap_offset; |
104 | unsigned long mmio_base; | 103 | unsigned long mmio_base; |
105 | unsigned long mmio_size; | 104 | unsigned long mmio_size; |
106 | volatile int cmd_busy; | ||
107 | }; | 105 | }; |
108 | 106 | ||
109 | 107 | ||
diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c index 4d8aee119134..83a5226ba9ed 100644 --- a/drivers/pci/hotplug/shpchp_hpc.c +++ b/drivers/pci/hotplug/shpchp_hpc.c | |||
@@ -302,21 +302,51 @@ static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int sec) | |||
302 | add_timer(&php_ctlr->int_poll_timer); | 302 | add_timer(&php_ctlr->int_poll_timer); |
303 | } | 303 | } |
304 | 304 | ||
305 | static inline int is_ctrl_busy(struct controller *ctrl) | ||
306 | { | ||
307 | u16 cmd_status = shpc_readw(ctrl, CMD_STATUS); | ||
308 | return cmd_status & 0x1; | ||
309 | } | ||
310 | |||
311 | /* | ||
312 | * Returns 1 if SHPC finishes executing a command within 1 sec, | ||
313 | * otherwise returns 0. | ||
314 | */ | ||
315 | static inline int shpc_poll_ctrl_busy(struct controller *ctrl) | ||
316 | { | ||
317 | int i; | ||
318 | |||
319 | if (!is_ctrl_busy(ctrl)) | ||
320 | return 1; | ||
321 | |||
322 | /* Check every 0.1 sec for a total of 1 sec */ | ||
323 | for (i = 0; i < 10; i++) { | ||
324 | msleep(100); | ||
325 | if (!is_ctrl_busy(ctrl)) | ||
326 | return 1; | ||
327 | } | ||
328 | |||
329 | return 0; | ||
330 | } | ||
331 | |||
305 | static inline int shpc_wait_cmd(struct controller *ctrl) | 332 | static inline int shpc_wait_cmd(struct controller *ctrl) |
306 | { | 333 | { |
307 | int retval = 0; | 334 | int retval = 0; |
308 | unsigned int timeout_msec = shpchp_poll_mode ? 2000 : 1000; | 335 | unsigned long timeout = msecs_to_jiffies(1000); |
309 | unsigned long timeout = msecs_to_jiffies(timeout_msec); | 336 | int rc; |
310 | int rc = wait_event_interruptible_timeout(ctrl->queue, | 337 | |
311 | !ctrl->cmd_busy, timeout); | 338 | if (shpchp_poll_mode) |
312 | if (!rc) { | 339 | rc = shpc_poll_ctrl_busy(ctrl); |
340 | else | ||
341 | rc = wait_event_interruptible_timeout(ctrl->queue, | ||
342 | !is_ctrl_busy(ctrl), timeout); | ||
343 | if (!rc && is_ctrl_busy(ctrl)) { | ||
313 | retval = -EIO; | 344 | retval = -EIO; |
314 | err("Command not completed in %d msec\n", timeout_msec); | 345 | err("Command not completed in 1000 msec\n"); |
315 | } else if (rc < 0) { | 346 | } else if (rc < 0) { |
316 | retval = -EINTR; | 347 | retval = -EINTR; |
317 | info("Command was interrupted by a signal\n"); | 348 | info("Command was interrupted by a signal\n"); |
318 | } | 349 | } |
319 | ctrl->cmd_busy = 0; | ||
320 | 350 | ||
321 | return retval; | 351 | return retval; |
322 | } | 352 | } |
@@ -327,26 +357,15 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd) | |||
327 | u16 cmd_status; | 357 | u16 cmd_status; |
328 | int retval = 0; | 358 | int retval = 0; |
329 | u16 temp_word; | 359 | u16 temp_word; |
330 | int i; | ||
331 | 360 | ||
332 | DBG_ENTER_ROUTINE | 361 | DBG_ENTER_ROUTINE |
333 | 362 | ||
334 | mutex_lock(&slot->ctrl->cmd_lock); | 363 | mutex_lock(&slot->ctrl->cmd_lock); |
335 | 364 | ||
336 | for (i = 0; i < 10; i++) { | 365 | if (!shpc_poll_ctrl_busy(ctrl)) { |
337 | cmd_status = shpc_readw(ctrl, CMD_STATUS); | ||
338 | |||
339 | if (!(cmd_status & 0x1)) | ||
340 | break; | ||
341 | /* Check every 0.1 sec for a total of 1 sec*/ | ||
342 | msleep(100); | ||
343 | } | ||
344 | |||
345 | cmd_status = shpc_readw(ctrl, CMD_STATUS); | ||
346 | |||
347 | if (cmd_status & 0x1) { | ||
348 | /* After 1 sec and and the controller is still busy */ | 366 | /* After 1 sec and and the controller is still busy */ |
349 | err("%s : Controller is still busy after 1 sec.\n", __FUNCTION__); | 367 | err("%s : Controller is still busy after 1 sec.\n", |
368 | __FUNCTION__); | ||
350 | retval = -EBUSY; | 369 | retval = -EBUSY; |
351 | goto out; | 370 | goto out; |
352 | } | 371 | } |
@@ -358,7 +377,6 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd) | |||
358 | /* To make sure the Controller Busy bit is 0 before we send out the | 377 | /* To make sure the Controller Busy bit is 0 before we send out the |
359 | * command. | 378 | * command. |
360 | */ | 379 | */ |
361 | slot->ctrl->cmd_busy = 1; | ||
362 | shpc_writew(ctrl, CMD, temp_word); | 380 | shpc_writew(ctrl, CMD, temp_word); |
363 | 381 | ||
364 | /* | 382 | /* |
@@ -908,7 +926,6 @@ static irqreturn_t shpc_isr(int irq, void *dev_id) | |||
908 | serr_int &= ~SERR_INTR_RSVDZ_MASK; | 926 | serr_int &= ~SERR_INTR_RSVDZ_MASK; |
909 | shpc_writel(ctrl, SERR_INTR_ENABLE, serr_int); | 927 | shpc_writel(ctrl, SERR_INTR_ENABLE, serr_int); |
910 | 928 | ||
911 | ctrl->cmd_busy = 0; | ||
912 | wake_up_interruptible(&ctrl->queue); | 929 | wake_up_interruptible(&ctrl->queue); |
913 | } | 930 | } |
914 | 931 | ||
@@ -1101,7 +1118,7 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) | |||
1101 | { | 1118 | { |
1102 | struct php_ctlr_state_s *php_ctlr, *p; | 1119 | struct php_ctlr_state_s *php_ctlr, *p; |
1103 | void *instance_id = ctrl; | 1120 | void *instance_id = ctrl; |
1104 | int rc, num_slots = 0; | 1121 | int rc = -1, num_slots = 0; |
1105 | u8 hp_slot; | 1122 | u8 hp_slot; |
1106 | u32 shpc_base_offset; | 1123 | u32 shpc_base_offset; |
1107 | u32 tempdword, slot_reg, slot_config; | 1124 | u32 tempdword, slot_reg, slot_config; |
@@ -1167,11 +1184,15 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) | |||
1167 | info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", pdev->vendor, pdev->device, pdev->subsystem_vendor, | 1184 | info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", pdev->vendor, pdev->device, pdev->subsystem_vendor, |
1168 | pdev->subsystem_device); | 1185 | pdev->subsystem_device); |
1169 | 1186 | ||
1170 | if (pci_enable_device(pdev)) | 1187 | rc = pci_enable_device(pdev); |
1188 | if (rc) { | ||
1189 | err("%s: pci_enable_device failed\n", __FUNCTION__); | ||
1171 | goto abort_free_ctlr; | 1190 | goto abort_free_ctlr; |
1191 | } | ||
1172 | 1192 | ||
1173 | if (!request_mem_region(ctrl->mmio_base, ctrl->mmio_size, MY_NAME)) { | 1193 | if (!request_mem_region(ctrl->mmio_base, ctrl->mmio_size, MY_NAME)) { |
1174 | err("%s: cannot reserve MMIO region\n", __FUNCTION__); | 1194 | err("%s: cannot reserve MMIO region\n", __FUNCTION__); |
1195 | rc = -1; | ||
1175 | goto abort_free_ctlr; | 1196 | goto abort_free_ctlr; |
1176 | } | 1197 | } |
1177 | 1198 | ||
@@ -1180,6 +1201,7 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) | |||
1180 | err("%s: cannot remap MMIO region %lx @ %lx\n", __FUNCTION__, | 1201 | err("%s: cannot remap MMIO region %lx @ %lx\n", __FUNCTION__, |
1181 | ctrl->mmio_size, ctrl->mmio_base); | 1202 | ctrl->mmio_size, ctrl->mmio_base); |
1182 | release_mem_region(ctrl->mmio_base, ctrl->mmio_size); | 1203 | release_mem_region(ctrl->mmio_base, ctrl->mmio_size); |
1204 | rc = -1; | ||
1183 | goto abort_free_ctlr; | 1205 | goto abort_free_ctlr; |
1184 | } | 1206 | } |
1185 | dbg("%s: php_ctlr->creg %p\n", __FUNCTION__, php_ctlr->creg); | 1207 | dbg("%s: php_ctlr->creg %p\n", __FUNCTION__, php_ctlr->creg); |
@@ -1282,8 +1304,10 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) | |||
1282 | */ | 1304 | */ |
1283 | if (atomic_add_return(1, &shpchp_num_controllers) == 1) { | 1305 | if (atomic_add_return(1, &shpchp_num_controllers) == 1) { |
1284 | shpchp_wq = create_singlethread_workqueue("shpchpd"); | 1306 | shpchp_wq = create_singlethread_workqueue("shpchpd"); |
1285 | if (!shpchp_wq) | 1307 | if (!shpchp_wq) { |
1286 | return -ENOMEM; | 1308 | rc = -ENOMEM; |
1309 | goto abort_free_ctlr; | ||
1310 | } | ||
1287 | } | 1311 | } |
1288 | 1312 | ||
1289 | /* | 1313 | /* |
@@ -1313,8 +1337,10 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) | |||
1313 | 1337 | ||
1314 | /* We end up here for the many possible ways to fail this API. */ | 1338 | /* We end up here for the many possible ways to fail this API. */ |
1315 | abort_free_ctlr: | 1339 | abort_free_ctlr: |
1340 | if (php_ctlr->creg) | ||
1341 | iounmap(php_ctlr->creg); | ||
1316 | kfree(php_ctlr); | 1342 | kfree(php_ctlr); |
1317 | abort: | 1343 | abort: |
1318 | DBG_LEAVE_ROUTINE | 1344 | DBG_LEAVE_ROUTINE |
1319 | return -1; | 1345 | return rc; |
1320 | } | 1346 | } |
diff --git a/drivers/pci/htirq.c b/drivers/pci/htirq.c index 0e27f2404a83..0a8d1cce9fa0 100644 --- a/drivers/pci/htirq.c +++ b/drivers/pci/htirq.c | |||
@@ -25,97 +25,72 @@ static DEFINE_SPINLOCK(ht_irq_lock); | |||
25 | 25 | ||
26 | struct ht_irq_cfg { | 26 | struct ht_irq_cfg { |
27 | struct pci_dev *dev; | 27 | struct pci_dev *dev; |
28 | /* Update callback used to cope with buggy hardware */ | ||
29 | ht_irq_update_t *update; | ||
28 | unsigned pos; | 30 | unsigned pos; |
29 | unsigned idx; | 31 | unsigned idx; |
32 | struct ht_irq_msg msg; | ||
30 | }; | 33 | }; |
31 | 34 | ||
32 | void write_ht_irq_low(unsigned int irq, u32 data) | ||
33 | { | ||
34 | struct ht_irq_cfg *cfg = get_irq_data(irq); | ||
35 | unsigned long flags; | ||
36 | spin_lock_irqsave(&ht_irq_lock, flags); | ||
37 | pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx); | ||
38 | pci_write_config_dword(cfg->dev, cfg->pos + 4, data); | ||
39 | spin_unlock_irqrestore(&ht_irq_lock, flags); | ||
40 | } | ||
41 | 35 | ||
42 | void write_ht_irq_high(unsigned int irq, u32 data) | 36 | void write_ht_irq_msg(unsigned int irq, struct ht_irq_msg *msg) |
43 | { | 37 | { |
44 | struct ht_irq_cfg *cfg = get_irq_data(irq); | 38 | struct ht_irq_cfg *cfg = get_irq_data(irq); |
45 | unsigned long flags; | 39 | unsigned long flags; |
46 | spin_lock_irqsave(&ht_irq_lock, flags); | 40 | spin_lock_irqsave(&ht_irq_lock, flags); |
47 | pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx + 1); | 41 | if (cfg->msg.address_lo != msg->address_lo) { |
48 | pci_write_config_dword(cfg->dev, cfg->pos + 4, data); | 42 | pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx); |
49 | spin_unlock_irqrestore(&ht_irq_lock, flags); | 43 | pci_write_config_dword(cfg->dev, cfg->pos + 4, msg->address_lo); |
50 | } | 44 | } |
51 | 45 | if (cfg->msg.address_hi != msg->address_hi) { | |
52 | u32 read_ht_irq_low(unsigned int irq) | 46 | pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx + 1); |
53 | { | 47 | pci_write_config_dword(cfg->dev, cfg->pos + 4, msg->address_hi); |
54 | struct ht_irq_cfg *cfg = get_irq_data(irq); | 48 | } |
55 | unsigned long flags; | 49 | if (cfg->update) |
56 | u32 data; | 50 | cfg->update(cfg->dev, irq, msg); |
57 | spin_lock_irqsave(&ht_irq_lock, flags); | ||
58 | pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx); | ||
59 | pci_read_config_dword(cfg->dev, cfg->pos + 4, &data); | ||
60 | spin_unlock_irqrestore(&ht_irq_lock, flags); | 51 | spin_unlock_irqrestore(&ht_irq_lock, flags); |
61 | return data; | 52 | cfg->msg = *msg; |
62 | } | 53 | } |
63 | 54 | ||
64 | u32 read_ht_irq_high(unsigned int irq) | 55 | void fetch_ht_irq_msg(unsigned int irq, struct ht_irq_msg *msg) |
65 | { | 56 | { |
66 | struct ht_irq_cfg *cfg = get_irq_data(irq); | 57 | struct ht_irq_cfg *cfg = get_irq_data(irq); |
67 | unsigned long flags; | 58 | *msg = cfg->msg; |
68 | u32 data; | ||
69 | spin_lock_irqsave(&ht_irq_lock, flags); | ||
70 | pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx + 1); | ||
71 | pci_read_config_dword(cfg->dev, cfg->pos + 4, &data); | ||
72 | spin_unlock_irqrestore(&ht_irq_lock, flags); | ||
73 | return data; | ||
74 | } | 59 | } |
75 | 60 | ||
76 | void mask_ht_irq(unsigned int irq) | 61 | void mask_ht_irq(unsigned int irq) |
77 | { | 62 | { |
78 | struct ht_irq_cfg *cfg; | 63 | struct ht_irq_cfg *cfg; |
79 | unsigned long flags; | 64 | struct ht_irq_msg msg; |
80 | u32 data; | ||
81 | 65 | ||
82 | cfg = get_irq_data(irq); | 66 | cfg = get_irq_data(irq); |
83 | 67 | ||
84 | spin_lock_irqsave(&ht_irq_lock, flags); | 68 | msg = cfg->msg; |
85 | pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx); | 69 | msg.address_lo |= 1; |
86 | pci_read_config_dword(cfg->dev, cfg->pos + 4, &data); | 70 | write_ht_irq_msg(irq, &msg); |
87 | data |= 1; | ||
88 | pci_write_config_dword(cfg->dev, cfg->pos + 4, data); | ||
89 | spin_unlock_irqrestore(&ht_irq_lock, flags); | ||
90 | } | 71 | } |
91 | 72 | ||
92 | void unmask_ht_irq(unsigned int irq) | 73 | void unmask_ht_irq(unsigned int irq) |
93 | { | 74 | { |
94 | struct ht_irq_cfg *cfg; | 75 | struct ht_irq_cfg *cfg; |
95 | unsigned long flags; | 76 | struct ht_irq_msg msg; |
96 | u32 data; | ||
97 | 77 | ||
98 | cfg = get_irq_data(irq); | 78 | cfg = get_irq_data(irq); |
99 | 79 | ||
100 | spin_lock_irqsave(&ht_irq_lock, flags); | 80 | msg = cfg->msg; |
101 | pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx); | 81 | msg.address_lo &= ~1; |
102 | pci_read_config_dword(cfg->dev, cfg->pos + 4, &data); | 82 | write_ht_irq_msg(irq, &msg); |
103 | data &= ~1; | ||
104 | pci_write_config_dword(cfg->dev, cfg->pos + 4, data); | ||
105 | spin_unlock_irqrestore(&ht_irq_lock, flags); | ||
106 | } | 83 | } |
107 | 84 | ||
108 | /** | 85 | /** |
109 | * ht_create_irq - create an irq and attach it to a device. | 86 | * __ht_create_irq - create an irq and attach it to a device. |
110 | * @dev: The hypertransport device to find the irq capability on. | 87 | * @dev: The hypertransport device to find the irq capability on. |
111 | * @idx: Which of the possible irqs to attach to. | 88 | * @idx: Which of the possible irqs to attach to. |
112 | * | 89 | * @update: Function to be called when changing the htirq message |
113 | * ht_create_irq is needs to be called for all hypertransport devices | ||
114 | * that generate irqs. | ||
115 | * | 90 | * |
116 | * The irq number of the new irq or a negative error value is returned. | 91 | * The irq number of the new irq or a negative error value is returned. |
117 | */ | 92 | */ |
118 | int ht_create_irq(struct pci_dev *dev, int idx) | 93 | int __ht_create_irq(struct pci_dev *dev, int idx, ht_irq_update_t *update) |
119 | { | 94 | { |
120 | struct ht_irq_cfg *cfg; | 95 | struct ht_irq_cfg *cfg; |
121 | unsigned long flags; | 96 | unsigned long flags; |
@@ -150,8 +125,12 @@ int ht_create_irq(struct pci_dev *dev, int idx) | |||
150 | return -ENOMEM; | 125 | return -ENOMEM; |
151 | 126 | ||
152 | cfg->dev = dev; | 127 | cfg->dev = dev; |
128 | cfg->update = update; | ||
153 | cfg->pos = pos; | 129 | cfg->pos = pos; |
154 | cfg->idx = 0x10 + (idx * 2); | 130 | cfg->idx = 0x10 + (idx * 2); |
131 | /* Initialize msg to a value that will never match the first write. */ | ||
132 | cfg->msg.address_lo = 0xffffffff; | ||
133 | cfg->msg.address_hi = 0xffffffff; | ||
155 | 134 | ||
156 | irq = create_irq(); | 135 | irq = create_irq(); |
157 | if (irq < 0) { | 136 | if (irq < 0) { |
@@ -169,6 +148,21 @@ int ht_create_irq(struct pci_dev *dev, int idx) | |||
169 | } | 148 | } |
170 | 149 | ||
171 | /** | 150 | /** |
151 | * ht_create_irq - create an irq and attach it to a device. | ||
152 | * @dev: The hypertransport device to find the irq capability on. | ||
153 | * @idx: Which of the possible irqs to attach to. | ||
154 | * | ||
155 | * ht_create_irq needs to be called for all hypertransport devices | ||
156 | * that generate irqs. | ||
157 | * | ||
158 | * The irq number of the new irq or a negative error value is returned. | ||
159 | */ | ||
160 | int ht_create_irq(struct pci_dev *dev, int idx) | ||
161 | { | ||
162 | return __ht_create_irq(dev, idx, NULL); | ||
163 | } | ||
164 | |||
165 | /** | ||
172 | * ht_destroy_irq - destroy an irq created with ht_create_irq | 166 | * ht_destroy_irq - destroy an irq created with ht_create_irq |
173 | * | 167 | * |
174 | * This reverses ht_create_irq removing the specified irq from | 168 | * This reverses ht_create_irq removing the specified irq from |
@@ -186,5 +180,6 @@ void ht_destroy_irq(unsigned int irq) | |||
186 | kfree(cfg); | 180 | kfree(cfg); |
187 | } | 181 | } |
188 | 182 | ||
183 | EXPORT_SYMBOL(__ht_create_irq); | ||
189 | EXPORT_SYMBOL(ht_create_irq); | 184 | EXPORT_SYMBOL(ht_create_irq); |
190 | EXPORT_SYMBOL(ht_destroy_irq); | 185 | EXPORT_SYMBOL(ht_destroy_irq); |
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index f9fdc54473c4..9fc9a34ef24a 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
@@ -627,22 +627,24 @@ static int msix_capability_init(struct pci_dev *dev, | |||
627 | * pci_msi_supported - check whether MSI may be enabled on device | 627 | * pci_msi_supported - check whether MSI may be enabled on device |
628 | * @dev: pointer to the pci_dev data structure of MSI device function | 628 | * @dev: pointer to the pci_dev data structure of MSI device function |
629 | * | 629 | * |
630 | * MSI must be globally enabled and supported by the device and its root | 630 | * Look at global flags, the device itself, and its parent busses |
631 | * bus. But, the root bus is not easy to find since some architectures | 631 | * to return 0 if MSI are supported for the device. |
632 | * have virtual busses on top of the PCI hierarchy (for instance the | ||
633 | * hypertransport bus), while the actual bus where MSI must be supported | ||
634 | * is below. So we test the MSI flag on all parent busses and assume | ||
635 | * that no quirk will ever set the NO_MSI flag on a non-root bus. | ||
636 | **/ | 632 | **/ |
637 | static | 633 | static |
638 | int pci_msi_supported(struct pci_dev * dev) | 634 | int pci_msi_supported(struct pci_dev * dev) |
639 | { | 635 | { |
640 | struct pci_bus *bus; | 636 | struct pci_bus *bus; |
641 | 637 | ||
638 | /* MSI must be globally enabled and supported by the device */ | ||
642 | if (!pci_msi_enable || !dev || dev->no_msi) | 639 | if (!pci_msi_enable || !dev || dev->no_msi) |
643 | return -EINVAL; | 640 | return -EINVAL; |
644 | 641 | ||
645 | /* check MSI flags of all parent busses */ | 642 | /* Any bridge which does NOT route MSI transactions from it's |
643 | * secondary bus to it's primary bus must set NO_MSI flag on | ||
644 | * the secondary pci_bus. | ||
645 | * We expect only arch-specific PCI host bus controller driver | ||
646 | * or quirks for specific PCI bridges to be setting NO_MSI. | ||
647 | */ | ||
646 | for (bus = dev->bus; bus; bus = bus->parent) | 648 | for (bus = dev->bus; bus; bus = bus->parent) |
647 | if (bus->bus_flags & PCI_BUS_FLAGS_NO_MSI) | 649 | if (bus->bus_flags & PCI_BUS_FLAGS_NO_MSI) |
648 | return -EINVAL; | 650 | return -EINVAL; |
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index b1c0c707d96c..194f1d21d3d7 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c | |||
@@ -265,6 +265,13 @@ static int pci_device_remove(struct device * dev) | |||
265 | } | 265 | } |
266 | 266 | ||
267 | /* | 267 | /* |
268 | * If the device is still on, set the power state as "unknown", | ||
269 | * since it might change by the next time we load the driver. | ||
270 | */ | ||
271 | if (pci_dev->current_state == PCI_D0) | ||
272 | pci_dev->current_state = PCI_UNKNOWN; | ||
273 | |||
274 | /* | ||
268 | * We would love to complain here if pci_dev->is_enabled is set, that | 275 | * We would love to complain here if pci_dev->is_enabled is set, that |
269 | * the driver should have called pci_disable_device(), but the | 276 | * the driver should have called pci_disable_device(), but the |
270 | * unfortunate fact is there are too many odd BIOS and bridge setups | 277 | * unfortunate fact is there are too many odd BIOS and bridge setups |
@@ -288,6 +295,12 @@ static int pci_device_suspend(struct device * dev, pm_message_t state) | |||
288 | suspend_report_result(drv->suspend, i); | 295 | suspend_report_result(drv->suspend, i); |
289 | } else { | 296 | } else { |
290 | pci_save_state(pci_dev); | 297 | pci_save_state(pci_dev); |
298 | /* | ||
299 | * mark its power state as "unknown", since we don't know if | ||
300 | * e.g. the BIOS will change its device state when we suspend. | ||
301 | */ | ||
302 | if (pci_dev->current_state == PCI_D0) | ||
303 | pci_dev->current_state = PCI_UNKNOWN; | ||
291 | } | 304 | } |
292 | return i; | 305 | return i; |
293 | } | 306 | } |
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index a1d2e979b17f..f952bfea48a6 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
@@ -642,6 +642,9 @@ err: | |||
642 | */ | 642 | */ |
643 | void pci_remove_sysfs_dev_files(struct pci_dev *pdev) | 643 | void pci_remove_sysfs_dev_files(struct pci_dev *pdev) |
644 | { | 644 | { |
645 | if (!sysfs_initialized) | ||
646 | return; | ||
647 | |||
645 | if (pdev->cfg_size < 4096) | 648 | if (pdev->cfg_size < 4096) |
646 | sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr); | 649 | sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr); |
647 | else | 650 | else |
diff --git a/drivers/pci/pcie/portdrv.h b/drivers/pci/pcie/portdrv.h index 67fcd176babd..3656e0349dd1 100644 --- a/drivers/pci/pcie/portdrv.h +++ b/drivers/pci/pcie/portdrv.h | |||
@@ -9,6 +9,8 @@ | |||
9 | #ifndef _PORTDRV_H_ | 9 | #ifndef _PORTDRV_H_ |
10 | #define _PORTDRV_H_ | 10 | #define _PORTDRV_H_ |
11 | 11 | ||
12 | #include <linux/compiler.h> | ||
13 | |||
12 | #if !defined(PCI_CAP_ID_PME) | 14 | #if !defined(PCI_CAP_ID_PME) |
13 | #define PCI_CAP_ID_PME 1 | 15 | #define PCI_CAP_ID_PME 1 |
14 | #endif | 16 | #endif |
@@ -39,7 +41,7 @@ extern int pcie_port_device_suspend(struct pci_dev *dev, pm_message_t state); | |||
39 | extern int pcie_port_device_resume(struct pci_dev *dev); | 41 | extern int pcie_port_device_resume(struct pci_dev *dev); |
40 | #endif | 42 | #endif |
41 | extern void pcie_port_device_remove(struct pci_dev *dev); | 43 | extern void pcie_port_device_remove(struct pci_dev *dev); |
42 | extern int pcie_port_bus_register(void); | 44 | extern int __must_check pcie_port_bus_register(void); |
43 | extern void pcie_port_bus_unregister(void); | 45 | extern void pcie_port_bus_unregister(void); |
44 | 46 | ||
45 | #endif /* _PORTDRV_H_ */ | 47 | #endif /* _PORTDRV_H_ */ |
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c index bd6615b4d40e..b20a9b81dae2 100644 --- a/drivers/pci/pcie/portdrv_core.c +++ b/drivers/pci/pcie/portdrv_core.c | |||
@@ -6,7 +6,6 @@ | |||
6 | * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com) | 6 | * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com) |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/compiler.h> | ||
10 | #include <linux/module.h> | 9 | #include <linux/module.h> |
11 | #include <linux/pci.h> | 10 | #include <linux/pci.h> |
12 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
@@ -401,7 +400,7 @@ void pcie_port_device_remove(struct pci_dev *dev) | |||
401 | pci_disable_msi(dev); | 400 | pci_disable_msi(dev); |
402 | } | 401 | } |
403 | 402 | ||
404 | int __must_check pcie_port_bus_register(void) | 403 | int pcie_port_bus_register(void) |
405 | { | 404 | { |
406 | return bus_register(&pcie_port_bus_type); | 405 | return bus_register(&pcie_port_bus_type); |
407 | } | 406 | } |
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index 037690e08f5f..b4da7954611e 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c | |||
@@ -37,7 +37,6 @@ static int pcie_portdrv_save_config(struct pci_dev *dev) | |||
37 | return pci_save_state(dev); | 37 | return pci_save_state(dev); |
38 | } | 38 | } |
39 | 39 | ||
40 | #ifdef CONFIG_PM | ||
41 | static int pcie_portdrv_restore_config(struct pci_dev *dev) | 40 | static int pcie_portdrv_restore_config(struct pci_dev *dev) |
42 | { | 41 | { |
43 | int retval; | 42 | int retval; |
@@ -50,6 +49,7 @@ static int pcie_portdrv_restore_config(struct pci_dev *dev) | |||
50 | return 0; | 49 | return 0; |
51 | } | 50 | } |
52 | 51 | ||
52 | #ifdef CONFIG_PM | ||
53 | static int pcie_portdrv_suspend(struct pci_dev *dev, pm_message_t state) | 53 | static int pcie_portdrv_suspend(struct pci_dev *dev, pm_message_t state) |
54 | { | 54 | { |
55 | int ret = pcie_port_device_suspend(dev, state); | 55 | int ret = pcie_port_device_suspend(dev, state); |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index a3b0a5eb5054..e159d6604494 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -1067,3 +1067,95 @@ EXPORT_SYMBOL(pci_scan_bridge); | |||
1067 | EXPORT_SYMBOL(pci_scan_single_device); | 1067 | EXPORT_SYMBOL(pci_scan_single_device); |
1068 | EXPORT_SYMBOL_GPL(pci_scan_child_bus); | 1068 | EXPORT_SYMBOL_GPL(pci_scan_child_bus); |
1069 | #endif | 1069 | #endif |
1070 | |||
1071 | static int __init pci_sort_bf_cmp(const struct pci_dev *a, const struct pci_dev *b) | ||
1072 | { | ||
1073 | if (pci_domain_nr(a->bus) < pci_domain_nr(b->bus)) return -1; | ||
1074 | else if (pci_domain_nr(a->bus) > pci_domain_nr(b->bus)) return 1; | ||
1075 | |||
1076 | if (a->bus->number < b->bus->number) return -1; | ||
1077 | else if (a->bus->number > b->bus->number) return 1; | ||
1078 | |||
1079 | if (a->devfn < b->devfn) return -1; | ||
1080 | else if (a->devfn > b->devfn) return 1; | ||
1081 | |||
1082 | return 0; | ||
1083 | } | ||
1084 | |||
1085 | /* | ||
1086 | * Yes, this forcably breaks the klist abstraction temporarily. It | ||
1087 | * just wants to sort the klist, not change reference counts and | ||
1088 | * take/drop locks rapidly in the process. It does all this while | ||
1089 | * holding the lock for the list, so objects can't otherwise be | ||
1090 | * added/removed while we're swizzling. | ||
1091 | */ | ||
1092 | static void __init pci_insertion_sort_klist(struct pci_dev *a, struct list_head *list) | ||
1093 | { | ||
1094 | struct list_head *pos; | ||
1095 | struct klist_node *n; | ||
1096 | struct device *dev; | ||
1097 | struct pci_dev *b; | ||
1098 | |||
1099 | list_for_each(pos, list) { | ||
1100 | n = container_of(pos, struct klist_node, n_node); | ||
1101 | dev = container_of(n, struct device, knode_bus); | ||
1102 | b = to_pci_dev(dev); | ||
1103 | if (pci_sort_bf_cmp(a, b) <= 0) { | ||
1104 | list_move_tail(&a->dev.knode_bus.n_node, &b->dev.knode_bus.n_node); | ||
1105 | return; | ||
1106 | } | ||
1107 | } | ||
1108 | list_move_tail(&a->dev.knode_bus.n_node, list); | ||
1109 | } | ||
1110 | |||
1111 | static void __init pci_sort_breadthfirst_klist(void) | ||
1112 | { | ||
1113 | LIST_HEAD(sorted_devices); | ||
1114 | struct list_head *pos, *tmp; | ||
1115 | struct klist_node *n; | ||
1116 | struct device *dev; | ||
1117 | struct pci_dev *pdev; | ||
1118 | |||
1119 | spin_lock(&pci_bus_type.klist_devices.k_lock); | ||
1120 | list_for_each_safe(pos, tmp, &pci_bus_type.klist_devices.k_list) { | ||
1121 | n = container_of(pos, struct klist_node, n_node); | ||
1122 | dev = container_of(n, struct device, knode_bus); | ||
1123 | pdev = to_pci_dev(dev); | ||
1124 | pci_insertion_sort_klist(pdev, &sorted_devices); | ||
1125 | } | ||
1126 | list_splice(&sorted_devices, &pci_bus_type.klist_devices.k_list); | ||
1127 | spin_unlock(&pci_bus_type.klist_devices.k_lock); | ||
1128 | } | ||
1129 | |||
1130 | static void __init pci_insertion_sort_devices(struct pci_dev *a, struct list_head *list) | ||
1131 | { | ||
1132 | struct pci_dev *b; | ||
1133 | |||
1134 | list_for_each_entry(b, list, global_list) { | ||
1135 | if (pci_sort_bf_cmp(a, b) <= 0) { | ||
1136 | list_move_tail(&a->global_list, &b->global_list); | ||
1137 | return; | ||
1138 | } | ||
1139 | } | ||
1140 | list_move_tail(&a->global_list, list); | ||
1141 | } | ||
1142 | |||
1143 | static void __init pci_sort_breadthfirst_devices(void) | ||
1144 | { | ||
1145 | LIST_HEAD(sorted_devices); | ||
1146 | struct pci_dev *dev, *tmp; | ||
1147 | |||
1148 | down_write(&pci_bus_sem); | ||
1149 | list_for_each_entry_safe(dev, tmp, &pci_devices, global_list) { | ||
1150 | pci_insertion_sort_devices(dev, &sorted_devices); | ||
1151 | } | ||
1152 | list_splice(&sorted_devices, &pci_devices); | ||
1153 | up_write(&pci_bus_sem); | ||
1154 | } | ||
1155 | |||
1156 | void __init pci_sort_breadthfirst(void) | ||
1157 | { | ||
1158 | pci_sort_breadthfirst_devices(); | ||
1159 | pci_sort_breadthfirst_klist(); | ||
1160 | } | ||
1161 | |||
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 23b599d6a9d5..5b4483811691 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -453,6 +453,12 @@ static void __devinit quirk_ich6_lpc_acpi(struct pci_dev *dev) | |||
453 | } | 453 | } |
454 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0, quirk_ich6_lpc_acpi ); | 454 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0, quirk_ich6_lpc_acpi ); |
455 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, quirk_ich6_lpc_acpi ); | 455 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, quirk_ich6_lpc_acpi ); |
456 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0, quirk_ich6_lpc_acpi ); | ||
457 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1, quirk_ich6_lpc_acpi ); | ||
458 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_31, quirk_ich6_lpc_acpi ); | ||
459 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_0, quirk_ich6_lpc_acpi ); | ||
460 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_2, quirk_ich6_lpc_acpi ); | ||
461 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_3, quirk_ich6_lpc_acpi ); | ||
456 | 462 | ||
457 | /* | 463 | /* |
458 | * VIA ACPI: One IO region pointed to by longword at | 464 | * VIA ACPI: One IO region pointed to by longword at |
@@ -648,11 +654,43 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_vi | |||
648 | * Some of the on-chip devices are actually '586 devices' so they are | 654 | * Some of the on-chip devices are actually '586 devices' so they are |
649 | * listed here. | 655 | * listed here. |
650 | */ | 656 | */ |
657 | |||
658 | static int via_irq_fixup_needed = -1; | ||
659 | |||
660 | /* | ||
661 | * As some VIA hardware is available in PCI-card form, we need to restrict | ||
662 | * this quirk to VIA PCI hardware built onto VIA-based motherboards only. | ||
663 | * We try to locate a VIA southbridge before deciding whether the quirk | ||
664 | * should be applied. | ||
665 | */ | ||
666 | static const struct pci_device_id via_irq_fixup_tbl[] = { | ||
667 | { | ||
668 | .vendor = PCI_VENDOR_ID_VIA, | ||
669 | .device = PCI_ANY_ID, | ||
670 | .subvendor = PCI_ANY_ID, | ||
671 | .subdevice = PCI_ANY_ID, | ||
672 | .class = PCI_CLASS_BRIDGE_ISA << 8, | ||
673 | .class_mask = 0xffff00, | ||
674 | }, | ||
675 | { 0, }, | ||
676 | }; | ||
677 | |||
651 | static void quirk_via_irq(struct pci_dev *dev) | 678 | static void quirk_via_irq(struct pci_dev *dev) |
652 | { | 679 | { |
653 | u8 irq, new_irq; | 680 | u8 irq, new_irq; |
654 | 681 | ||
655 | new_irq = dev->irq & 0xf; | 682 | if (via_irq_fixup_needed == -1) |
683 | via_irq_fixup_needed = pci_dev_present(via_irq_fixup_tbl); | ||
684 | |||
685 | if (!via_irq_fixup_needed) | ||
686 | return; | ||
687 | |||
688 | new_irq = dev->irq; | ||
689 | |||
690 | /* Don't quirk interrupts outside the legacy IRQ range */ | ||
691 | if (!new_irq || new_irq > 15) | ||
692 | return; | ||
693 | |||
656 | pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); | 694 | pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); |
657 | if (new_irq != irq) { | 695 | if (new_irq != irq) { |
658 | printk(KERN_INFO "PCI: VIA IRQ fixup for %s, from %d to %d\n", | 696 | printk(KERN_INFO "PCI: VIA IRQ fixup for %s, from %d to %d\n", |
@@ -661,14 +699,7 @@ static void quirk_via_irq(struct pci_dev *dev) | |||
661 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, new_irq); | 699 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, new_irq); |
662 | } | 700 | } |
663 | } | 701 | } |
664 | DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_0, quirk_via_irq); | 702 | DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_irq); |
665 | DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, quirk_via_irq); | ||
666 | DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2, quirk_via_irq); | ||
667 | DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_via_irq); | ||
668 | DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235_USB_2, quirk_via_irq); | ||
669 | DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_irq); | ||
670 | DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_via_irq); | ||
671 | DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_5, quirk_via_irq); | ||
672 | 703 | ||
673 | /* | 704 | /* |
674 | * VIA VT82C598 has its device ID settable and many BIOSes | 705 | * VIA VT82C598 has its device ID settable and many BIOSes |
@@ -683,33 +714,6 @@ static void __devinit quirk_vt82c598_id(struct pci_dev *dev) | |||
683 | } | 714 | } |
684 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C597_0, quirk_vt82c598_id ); | 715 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C597_0, quirk_vt82c598_id ); |
685 | 716 | ||
686 | #ifdef CONFIG_ACPI_SLEEP | ||
687 | |||
688 | /* | ||
689 | * Some VIA systems boot with the abnormal status flag set. This can cause | ||
690 | * the BIOS to re-POST the system on resume rather than passing control | ||
691 | * back to the OS. Clear the flag on boot | ||
692 | */ | ||
693 | static void __devinit quirk_via_abnormal_poweroff(struct pci_dev *dev) | ||
694 | { | ||
695 | u32 reg; | ||
696 | |||
697 | acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_STATUS, | ||
698 | ®); | ||
699 | |||
700 | if (reg & 0x800) { | ||
701 | printk("Clearing abnormal poweroff flag\n"); | ||
702 | acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, | ||
703 | ACPI_REGISTER_PM1_STATUS, | ||
704 | (u16)0x800); | ||
705 | } | ||
706 | } | ||
707 | |||
708 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, quirk_via_abnormal_poweroff); | ||
709 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, quirk_via_abnormal_poweroff); | ||
710 | |||
711 | #endif | ||
712 | |||
713 | /* | 717 | /* |
714 | * CardBus controllers have a legacy base address that enables them | 718 | * CardBus controllers have a legacy base address that enables them |
715 | * to respond as i82365 pcmcia controllers. We don't want them to | 719 | * to respond as i82365 pcmcia controllers. We don't want them to |
@@ -1456,33 +1460,6 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2609, quirk_intel_pcie_pm); | |||
1456 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x260a, quirk_intel_pcie_pm); | 1460 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x260a, quirk_intel_pcie_pm); |
1457 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x260b, quirk_intel_pcie_pm); | 1461 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x260b, quirk_intel_pcie_pm); |
1458 | 1462 | ||
1459 | /* | ||
1460 | * Fixup the cardbus bridges on the IBM Dock II docking station | ||
1461 | */ | ||
1462 | static void __devinit quirk_ibm_dock2_cardbus(struct pci_dev *dev) | ||
1463 | { | ||
1464 | u32 val; | ||
1465 | |||
1466 | /* | ||
1467 | * tie the 2 interrupt pins to INTA, and configure the | ||
1468 | * multifunction routing register to handle this. | ||
1469 | */ | ||
1470 | if ((dev->subsystem_vendor == PCI_VENDOR_ID_IBM) && | ||
1471 | (dev->subsystem_device == 0x0148)) { | ||
1472 | printk(KERN_INFO "PCI: Found IBM Dock II Cardbus Bridge " | ||
1473 | "applying quirk\n"); | ||
1474 | pci_read_config_dword(dev, 0x8c, &val); | ||
1475 | val = ((val & 0xffffff00) | 0x1002); | ||
1476 | pci_write_config_dword(dev, 0x8c, val); | ||
1477 | pci_read_config_dword(dev, 0x80, &val); | ||
1478 | val = ((val & 0x00ffff00) | 0x2864c077); | ||
1479 | pci_write_config_dword(dev, 0x80, val); | ||
1480 | } | ||
1481 | } | ||
1482 | |||
1483 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1420, | ||
1484 | quirk_ibm_dock2_cardbus); | ||
1485 | |||
1486 | static void __devinit quirk_netmos(struct pci_dev *dev) | 1463 | static void __devinit quirk_netmos(struct pci_dev *dev) |
1487 | { | 1464 | { |
1488 | unsigned int num_parallel = (dev->subsystem_device & 0xf0) >> 4; | 1465 | unsigned int num_parallel = (dev->subsystem_device & 0xf0) >> 4; |
@@ -1588,7 +1565,6 @@ static void __devinit fixup_rev1_53c810(struct pci_dev* dev) | |||
1588 | } | 1565 | } |
1589 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, fixup_rev1_53c810); | 1566 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, fixup_rev1_53c810); |
1590 | 1567 | ||
1591 | |||
1592 | static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_fixup *end) | 1568 | static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_fixup *end) |
1593 | { | 1569 | { |
1594 | while (f < end) { | 1570 | while (f < end) { |
@@ -1764,7 +1740,7 @@ static void __devinit quirk_nvidia_ck804_msi_ht_cap(struct pci_dev *dev) | |||
1764 | /* check HT MSI cap on this chipset and the root one. | 1740 | /* check HT MSI cap on this chipset and the root one. |
1765 | * a single one having MSI is enough to be sure that MSI are supported. | 1741 | * a single one having MSI is enough to be sure that MSI are supported. |
1766 | */ | 1742 | */ |
1767 | pdev = pci_find_slot(dev->bus->number, 0); | 1743 | pdev = pci_get_slot(dev->bus, 0); |
1768 | if (dev->subordinate && !msi_ht_cap_enabled(dev) | 1744 | if (dev->subordinate && !msi_ht_cap_enabled(dev) |
1769 | && !msi_ht_cap_enabled(pdev)) { | 1745 | && !msi_ht_cap_enabled(pdev)) { |
1770 | printk(KERN_WARNING "PCI: MSI quirk detected. " | 1746 | printk(KERN_WARNING "PCI: MSI quirk detected. " |
@@ -1772,6 +1748,7 @@ static void __devinit quirk_nvidia_ck804_msi_ht_cap(struct pci_dev *dev) | |||
1772 | pci_name(dev)); | 1748 | pci_name(dev)); |
1773 | dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI; | 1749 | dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI; |
1774 | } | 1750 | } |
1751 | pci_dev_put(pdev); | ||
1775 | } | 1752 | } |
1776 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE, | 1753 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE, |
1777 | quirk_nvidia_ck804_msi_ht_cap); | 1754 | quirk_nvidia_ck804_msi_ht_cap); |
diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c index f5ee7ce16fa6..e1dcefc69bb4 100644 --- a/drivers/pci/rom.c +++ b/drivers/pci/rom.c | |||
@@ -71,7 +71,11 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size) | |||
71 | void __iomem *image; | 71 | void __iomem *image; |
72 | int last_image; | 72 | int last_image; |
73 | 73 | ||
74 | /* IORESOURCE_ROM_SHADOW only set on x86 */ | 74 | /* |
75 | * IORESOURCE_ROM_SHADOW set on x86, x86_64 and IA64 supports legacy | ||
76 | * memory map if the VGA enable bit of the Bridge Control register is | ||
77 | * set for embedded VGA. | ||
78 | */ | ||
75 | if (res->flags & IORESOURCE_ROM_SHADOW) { | 79 | if (res->flags & IORESOURCE_ROM_SHADOW) { |
76 | /* primary video rom always starts here */ | 80 | /* primary video rom always starts here */ |
77 | start = (loff_t)0xC0000; | 81 | start = (loff_t)0xC0000; |
diff --git a/drivers/pci/search.c b/drivers/pci/search.c index d529462d1b53..2f13eba5d5ae 100644 --- a/drivers/pci/search.c +++ b/drivers/pci/search.c | |||
@@ -140,6 +140,31 @@ struct pci_dev * pci_get_slot(struct pci_bus *bus, unsigned int devfn) | |||
140 | } | 140 | } |
141 | 141 | ||
142 | /** | 142 | /** |
143 | * pci_get_bus_and_slot - locate PCI device from a given PCI slot | ||
144 | * @bus: number of PCI bus on which desired PCI device resides | ||
145 | * @devfn: encodes number of PCI slot in which the desired PCI | ||
146 | * device resides and the logical device number within that slot | ||
147 | * in case of multi-function devices. | ||
148 | * | ||
149 | * Given a PCI bus and slot/function number, the desired PCI device | ||
150 | * is located in system global list of PCI devices. If the device | ||
151 | * is found, a pointer to its data structure is returned. If no | ||
152 | * device is found, %NULL is returned. The returned device has its | ||
153 | * reference count bumped by one. | ||
154 | */ | ||
155 | |||
156 | struct pci_dev * pci_get_bus_and_slot(unsigned int bus, unsigned int devfn) | ||
157 | { | ||
158 | struct pci_dev *dev = NULL; | ||
159 | |||
160 | while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { | ||
161 | if (dev->bus->number == bus && dev->devfn == devfn) | ||
162 | return dev; | ||
163 | } | ||
164 | return NULL; | ||
165 | } | ||
166 | |||
167 | /** | ||
143 | * pci_find_subsys - begin or continue searching for a PCI device by vendor/subvendor/device/subdevice id | 168 | * pci_find_subsys - begin or continue searching for a PCI device by vendor/subvendor/device/subdevice id |
144 | * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids | 169 | * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids |
145 | * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids | 170 | * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids |
@@ -274,6 +299,45 @@ pci_get_device(unsigned int vendor, unsigned int device, struct pci_dev *from) | |||
274 | return pci_get_subsys(vendor, device, PCI_ANY_ID, PCI_ANY_ID, from); | 299 | return pci_get_subsys(vendor, device, PCI_ANY_ID, PCI_ANY_ID, from); |
275 | } | 300 | } |
276 | 301 | ||
302 | /** | ||
303 | * pci_get_device_reverse - begin or continue searching for a PCI device by vendor/device id | ||
304 | * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids | ||
305 | * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids | ||
306 | * @from: Previous PCI device found in search, or %NULL for new search. | ||
307 | * | ||
308 | * Iterates through the list of known PCI devices in the reverse order of | ||
309 | * pci_get_device. | ||
310 | * If a PCI device is found with a matching @vendor and @device, the reference | ||
311 | * count to the device is incremented and a pointer to its device structure | ||
312 | * is returned Otherwise, %NULL is returned. A new search is initiated by | ||
313 | * passing %NULL as the @from argument. Otherwise if @from is not %NULL, | ||
314 | * searches continue from next device on the global list. The reference | ||
315 | * count for @from is always decremented if it is not %NULL. | ||
316 | */ | ||
317 | struct pci_dev * | ||
318 | pci_get_device_reverse(unsigned int vendor, unsigned int device, struct pci_dev *from) | ||
319 | { | ||
320 | struct list_head *n; | ||
321 | struct pci_dev *dev; | ||
322 | |||
323 | WARN_ON(in_interrupt()); | ||
324 | down_read(&pci_bus_sem); | ||
325 | n = from ? from->global_list.prev : pci_devices.prev; | ||
326 | |||
327 | while (n && (n != &pci_devices)) { | ||
328 | dev = pci_dev_g(n); | ||
329 | if ((vendor == PCI_ANY_ID || dev->vendor == vendor) && | ||
330 | (device == PCI_ANY_ID || dev->device == device)) | ||
331 | goto exit; | ||
332 | n = n->prev; | ||
333 | } | ||
334 | dev = NULL; | ||
335 | exit: | ||
336 | dev = pci_dev_get(dev); | ||
337 | up_read(&pci_bus_sem); | ||
338 | pci_dev_put(from); | ||
339 | return dev; | ||
340 | } | ||
277 | 341 | ||
278 | /** | 342 | /** |
279 | * pci_find_device_reverse - begin or continue searching for a PCI device by vendor/device id | 343 | * pci_find_device_reverse - begin or continue searching for a PCI device by vendor/device id |
@@ -382,12 +446,16 @@ exit: | |||
382 | } | 446 | } |
383 | EXPORT_SYMBOL(pci_dev_present); | 447 | EXPORT_SYMBOL(pci_dev_present); |
384 | 448 | ||
385 | EXPORT_SYMBOL(pci_find_bus); | ||
386 | EXPORT_SYMBOL(pci_find_next_bus); | ||
387 | EXPORT_SYMBOL(pci_find_device); | 449 | EXPORT_SYMBOL(pci_find_device); |
388 | EXPORT_SYMBOL(pci_find_device_reverse); | 450 | EXPORT_SYMBOL(pci_find_device_reverse); |
389 | EXPORT_SYMBOL(pci_find_slot); | 451 | EXPORT_SYMBOL(pci_find_slot); |
452 | /* For boot time work */ | ||
453 | EXPORT_SYMBOL(pci_find_bus); | ||
454 | EXPORT_SYMBOL(pci_find_next_bus); | ||
455 | /* For everyone */ | ||
390 | EXPORT_SYMBOL(pci_get_device); | 456 | EXPORT_SYMBOL(pci_get_device); |
457 | EXPORT_SYMBOL(pci_get_device_reverse); | ||
391 | EXPORT_SYMBOL(pci_get_subsys); | 458 | EXPORT_SYMBOL(pci_get_subsys); |
392 | EXPORT_SYMBOL(pci_get_slot); | 459 | EXPORT_SYMBOL(pci_get_slot); |
460 | EXPORT_SYMBOL(pci_get_bus_and_slot); | ||
393 | EXPORT_SYMBOL(pci_get_class); | 461 | EXPORT_SYMBOL(pci_get_class); |
diff --git a/drivers/pcmcia/at91_cf.c b/drivers/pcmcia/at91_cf.c index 7f5df9a9f393..3bcb7dc32995 100644 --- a/drivers/pcmcia/at91_cf.c +++ b/drivers/pcmcia/at91_cf.c | |||
@@ -241,12 +241,6 @@ static int __init at91_cf_probe(struct platform_device *pdev) | |||
241 | csa = at91_sys_read(AT91_EBI_CSA); | 241 | csa = at91_sys_read(AT91_EBI_CSA); |
242 | at91_sys_write(AT91_EBI_CSA, csa | AT91_EBI_CS4A_SMC_COMPACTFLASH); | 242 | at91_sys_write(AT91_EBI_CSA, csa | AT91_EBI_CS4A_SMC_COMPACTFLASH); |
243 | 243 | ||
244 | /* force poweron defaults for these pins ... */ | ||
245 | (void) at91_set_A_periph(AT91_PIN_PC9, 0); /* A25/CFRNW */ | ||
246 | (void) at91_set_A_periph(AT91_PIN_PC10, 0); /* NCS4/CFCS */ | ||
247 | (void) at91_set_A_periph(AT91_PIN_PC11, 0); /* NCS5/CFCE1 */ | ||
248 | (void) at91_set_A_periph(AT91_PIN_PC12, 0); /* NCS6/CFCE2 */ | ||
249 | |||
250 | /* nWAIT is _not_ a default setting */ | 244 | /* nWAIT is _not_ a default setting */ |
251 | (void) at91_set_A_periph(AT91_PIN_PC6, 1); /* nWAIT */ | 245 | (void) at91_set_A_periph(AT91_PIN_PC6, 1); /* nWAIT */ |
252 | 246 | ||
@@ -316,12 +310,14 @@ static int __init at91_cf_probe(struct platform_device *pdev) | |||
316 | return 0; | 310 | return 0; |
317 | 311 | ||
318 | fail2: | 312 | fail2: |
319 | iounmap((void __iomem *) cf->socket.io_offset); | ||
320 | release_mem_region(io->start, io->end + 1 - io->start); | 313 | release_mem_region(io->start, io->end + 1 - io->start); |
321 | fail1: | 314 | fail1: |
315 | if (cf->socket.io_offset) | ||
316 | iounmap((void __iomem *) cf->socket.io_offset); | ||
322 | if (board->irq_pin) | 317 | if (board->irq_pin) |
323 | free_irq(board->irq_pin, cf); | 318 | free_irq(board->irq_pin, cf); |
324 | fail0a: | 319 | fail0a: |
320 | device_init_wakeup(&pdev->dev, 0); | ||
325 | free_irq(board->det_pin, cf); | 321 | free_irq(board->det_pin, cf); |
326 | device_init_wakeup(&pdev->dev, 0); | 322 | device_init_wakeup(&pdev->dev, 0); |
327 | fail0: | 323 | fail0: |
@@ -360,26 +356,20 @@ static int at91_cf_suspend(struct platform_device *pdev, pm_message_t mesg) | |||
360 | struct at91_cf_data *board = cf->board; | 356 | struct at91_cf_data *board = cf->board; |
361 | 357 | ||
362 | pcmcia_socket_dev_suspend(&pdev->dev, mesg); | 358 | pcmcia_socket_dev_suspend(&pdev->dev, mesg); |
363 | if (device_may_wakeup(&pdev->dev)) | 359 | if (device_may_wakeup(&pdev->dev)) { |
364 | enable_irq_wake(board->det_pin); | 360 | enable_irq_wake(board->det_pin); |
365 | else { | 361 | if (board->irq_pin) |
362 | enable_irq_wake(board->irq_pin); | ||
363 | } else { | ||
366 | disable_irq_wake(board->det_pin); | 364 | disable_irq_wake(board->det_pin); |
367 | disable_irq(board->det_pin); | 365 | if (board->irq_pin) |
366 | disable_irq_wake(board->irq_pin); | ||
368 | } | 367 | } |
369 | if (board->irq_pin) | ||
370 | disable_irq(board->irq_pin); | ||
371 | return 0; | 368 | return 0; |
372 | } | 369 | } |
373 | 370 | ||
374 | static int at91_cf_resume(struct platform_device *pdev) | 371 | static int at91_cf_resume(struct platform_device *pdev) |
375 | { | 372 | { |
376 | struct at91_cf_socket *cf = platform_get_drvdata(pdev); | ||
377 | struct at91_cf_data *board = cf->board; | ||
378 | |||
379 | if (board->irq_pin) | ||
380 | enable_irq(board->irq_pin); | ||
381 | if (!device_may_wakeup(&pdev->dev)) | ||
382 | enable_irq(board->det_pin); | ||
383 | pcmcia_socket_dev_resume(&pdev->dev); | 373 | pcmcia_socket_dev_resume(&pdev->dev); |
384 | return 0; | 374 | return 0; |
385 | } | 375 | } |
diff --git a/drivers/pcmcia/au1000_generic.c b/drivers/pcmcia/au1000_generic.c index d5dd0ce65536..551bde5d9430 100644 --- a/drivers/pcmcia/au1000_generic.c +++ b/drivers/pcmcia/au1000_generic.c | |||
@@ -351,6 +351,7 @@ struct skt_dev_info { | |||
351 | int au1x00_pcmcia_socket_probe(struct device *dev, struct pcmcia_low_level *ops, int first, int nr) | 351 | int au1x00_pcmcia_socket_probe(struct device *dev, struct pcmcia_low_level *ops, int first, int nr) |
352 | { | 352 | { |
353 | struct skt_dev_info *sinfo; | 353 | struct skt_dev_info *sinfo; |
354 | struct au1000_pcmcia_socket *skt; | ||
354 | int ret, i; | 355 | int ret, i; |
355 | 356 | ||
356 | sinfo = kzalloc(sizeof(struct skt_dev_info), GFP_KERNEL); | 357 | sinfo = kzalloc(sizeof(struct skt_dev_info), GFP_KERNEL); |
@@ -365,7 +366,7 @@ int au1x00_pcmcia_socket_probe(struct device *dev, struct pcmcia_low_level *ops, | |||
365 | * Initialise the per-socket structure. | 366 | * Initialise the per-socket structure. |
366 | */ | 367 | */ |
367 | for (i = 0; i < nr; i++) { | 368 | for (i = 0; i < nr; i++) { |
368 | struct au1000_pcmcia_socket *skt = PCMCIA_SOCKET(i); | 369 | skt = PCMCIA_SOCKET(i); |
369 | memset(skt, 0, sizeof(*skt)); | 370 | memset(skt, 0, sizeof(*skt)); |
370 | 371 | ||
371 | skt->socket.resource_ops = &pccard_static_ops; | 372 | skt->socket.resource_ops = &pccard_static_ops; |
@@ -438,17 +439,29 @@ int au1x00_pcmcia_socket_probe(struct device *dev, struct pcmcia_low_level *ops, | |||
438 | dev_set_drvdata(dev, sinfo); | 439 | dev_set_drvdata(dev, sinfo); |
439 | return 0; | 440 | return 0; |
440 | 441 | ||
441 | do { | 442 | |
442 | struct au1000_pcmcia_socket *skt = PCMCIA_SOCKET(i); | 443 | out_err: |
444 | flush_scheduled_work(); | ||
445 | ops->hw_shutdown(skt); | ||
446 | while (i-- > 0) { | ||
447 | skt = PCMCIA_SOCKET(i); | ||
443 | 448 | ||
444 | del_timer_sync(&skt->poll_timer); | 449 | del_timer_sync(&skt->poll_timer); |
445 | pcmcia_unregister_socket(&skt->socket); | 450 | pcmcia_unregister_socket(&skt->socket); |
446 | out_err: | ||
447 | flush_scheduled_work(); | 451 | flush_scheduled_work(); |
452 | if (i == 0) { | ||
453 | iounmap(skt->virt_io + (u32)mips_io_port_base); | ||
454 | skt->virt_io = NULL; | ||
455 | } | ||
456 | #ifndef CONFIG_MIPS_XXS1500 | ||
457 | else { | ||
458 | iounmap(skt->virt_io + (u32)mips_io_port_base); | ||
459 | skt->virt_io = NULL; | ||
460 | } | ||
461 | #endif | ||
448 | ops->hw_shutdown(skt); | 462 | ops->hw_shutdown(skt); |
449 | 463 | ||
450 | i--; | 464 | } |
451 | } while (i > 0); | ||
452 | kfree(sinfo); | 465 | kfree(sinfo); |
453 | out: | 466 | out: |
454 | return ret; | 467 | return ret; |
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 74b3124e8247..a20d84d707d9 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c | |||
@@ -717,6 +717,7 @@ static int pcmcia_requery(struct device *dev, void * _data) | |||
717 | static void pcmcia_bus_rescan(struct pcmcia_socket *skt) | 717 | static void pcmcia_bus_rescan(struct pcmcia_socket *skt) |
718 | { | 718 | { |
719 | int no_devices=0; | 719 | int no_devices=0; |
720 | int ret = 0; | ||
720 | unsigned long flags; | 721 | unsigned long flags; |
721 | 722 | ||
722 | /* must be called with skt_mutex held */ | 723 | /* must be called with skt_mutex held */ |
@@ -729,7 +730,7 @@ static void pcmcia_bus_rescan(struct pcmcia_socket *skt) | |||
729 | * missing resource information or other trouble, we need to | 730 | * missing resource information or other trouble, we need to |
730 | * do this now. */ | 731 | * do this now. */ |
731 | if (no_devices) { | 732 | if (no_devices) { |
732 | int ret = pcmcia_card_add(skt); | 733 | ret = pcmcia_card_add(skt); |
733 | if (ret) | 734 | if (ret) |
734 | return; | 735 | return; |
735 | } | 736 | } |
@@ -741,7 +742,9 @@ static void pcmcia_bus_rescan(struct pcmcia_socket *skt) | |||
741 | 742 | ||
742 | /* we re-scan all devices, not just the ones connected to this | 743 | /* we re-scan all devices, not just the ones connected to this |
743 | * socket. This does not matter, though. */ | 744 | * socket. This does not matter, though. */ |
744 | bus_rescan_devices(&pcmcia_bus_type); | 745 | ret = bus_rescan_devices(&pcmcia_bus_type); |
746 | if (ret) | ||
747 | printk(KERN_INFO "pcmcia: bus_rescan_devices failed\n"); | ||
745 | } | 748 | } |
746 | 749 | ||
747 | static inline int pcmcia_devmatch(struct pcmcia_device *dev, | 750 | static inline int pcmcia_devmatch(struct pcmcia_device *dev, |
@@ -1001,6 +1004,7 @@ static ssize_t pcmcia_store_allow_func_id_match(struct device *dev, | |||
1001 | struct device_attribute *attr, const char *buf, size_t count) | 1004 | struct device_attribute *attr, const char *buf, size_t count) |
1002 | { | 1005 | { |
1003 | struct pcmcia_device *p_dev = to_pcmcia_dev(dev); | 1006 | struct pcmcia_device *p_dev = to_pcmcia_dev(dev); |
1007 | int ret; | ||
1004 | 1008 | ||
1005 | if (!count) | 1009 | if (!count) |
1006 | return -EINVAL; | 1010 | return -EINVAL; |
@@ -1009,7 +1013,10 @@ static ssize_t pcmcia_store_allow_func_id_match(struct device *dev, | |||
1009 | p_dev->allow_func_id_match = 1; | 1013 | p_dev->allow_func_id_match = 1; |
1010 | mutex_unlock(&p_dev->socket->skt_mutex); | 1014 | mutex_unlock(&p_dev->socket->skt_mutex); |
1011 | 1015 | ||
1012 | bus_rescan_devices(&pcmcia_bus_type); | 1016 | ret = bus_rescan_devices(&pcmcia_bus_type); |
1017 | if (ret) | ||
1018 | printk(KERN_INFO "pcmcia: bus_rescan_devices failed after " | ||
1019 | "allowing func_id matches\n"); | ||
1013 | 1020 | ||
1014 | return count; | 1021 | return count; |
1015 | } | 1022 | } |
@@ -1264,6 +1271,9 @@ static void pcmcia_bus_remove_socket(struct class_device *class_dev, | |||
1264 | socket->pcmcia_state.dead = 1; | 1271 | socket->pcmcia_state.dead = 1; |
1265 | pccard_register_pcmcia(socket, NULL); | 1272 | pccard_register_pcmcia(socket, NULL); |
1266 | 1273 | ||
1274 | /* unregister any unbound devices */ | ||
1275 | pcmcia_card_remove(socket, NULL); | ||
1276 | |||
1267 | pcmcia_put_socket(socket); | 1277 | pcmcia_put_socket(socket); |
1268 | 1278 | ||
1269 | return; | 1279 | return; |
@@ -1292,10 +1302,22 @@ struct bus_type pcmcia_bus_type = { | |||
1292 | 1302 | ||
1293 | static int __init init_pcmcia_bus(void) | 1303 | static int __init init_pcmcia_bus(void) |
1294 | { | 1304 | { |
1305 | int ret; | ||
1306 | |||
1295 | spin_lock_init(&pcmcia_dev_list_lock); | 1307 | spin_lock_init(&pcmcia_dev_list_lock); |
1296 | 1308 | ||
1297 | bus_register(&pcmcia_bus_type); | 1309 | ret = bus_register(&pcmcia_bus_type); |
1298 | class_interface_register(&pcmcia_bus_interface); | 1310 | if (ret < 0) { |
1311 | printk(KERN_WARNING "pcmcia: bus_register error: %d\n", ret); | ||
1312 | return ret; | ||
1313 | } | ||
1314 | ret = class_interface_register(&pcmcia_bus_interface); | ||
1315 | if (ret < 0) { | ||
1316 | printk(KERN_WARNING | ||
1317 | "pcmcia: class_interface_register error: %d\n", ret); | ||
1318 | bus_unregister(&pcmcia_bus_type); | ||
1319 | return ret; | ||
1320 | } | ||
1299 | 1321 | ||
1300 | pcmcia_setup_ioctl(); | 1322 | pcmcia_setup_ioctl(); |
1301 | 1323 | ||
diff --git a/drivers/pcmcia/i82092.c b/drivers/pcmcia/i82092.c index 82715f448957..c2ea07aa7a12 100644 --- a/drivers/pcmcia/i82092.c +++ b/drivers/pcmcia/i82092.c | |||
@@ -41,6 +41,7 @@ static struct pci_device_id i82092aa_pci_ids[] = { | |||
41 | }; | 41 | }; |
42 | MODULE_DEVICE_TABLE(pci, i82092aa_pci_ids); | 42 | MODULE_DEVICE_TABLE(pci, i82092aa_pci_ids); |
43 | 43 | ||
44 | #ifdef CONFIG_PM | ||
44 | static int i82092aa_socket_suspend (struct pci_dev *dev, pm_message_t state) | 45 | static int i82092aa_socket_suspend (struct pci_dev *dev, pm_message_t state) |
45 | { | 46 | { |
46 | return pcmcia_socket_dev_suspend(&dev->dev, state); | 47 | return pcmcia_socket_dev_suspend(&dev->dev, state); |
@@ -50,14 +51,17 @@ static int i82092aa_socket_resume (struct pci_dev *dev) | |||
50 | { | 51 | { |
51 | return pcmcia_socket_dev_resume(&dev->dev); | 52 | return pcmcia_socket_dev_resume(&dev->dev); |
52 | } | 53 | } |
54 | #endif | ||
53 | 55 | ||
54 | static struct pci_driver i82092aa_pci_drv = { | 56 | static struct pci_driver i82092aa_pci_drv = { |
55 | .name = "i82092aa", | 57 | .name = "i82092aa", |
56 | .id_table = i82092aa_pci_ids, | 58 | .id_table = i82092aa_pci_ids, |
57 | .probe = i82092aa_pci_probe, | 59 | .probe = i82092aa_pci_probe, |
58 | .remove = __devexit_p(i82092aa_pci_remove), | 60 | .remove = __devexit_p(i82092aa_pci_remove), |
61 | #ifdef CONFIG_PM | ||
59 | .suspend = i82092aa_socket_suspend, | 62 | .suspend = i82092aa_socket_suspend, |
60 | .resume = i82092aa_socket_resume, | 63 | .resume = i82092aa_socket_resume, |
64 | #endif | ||
61 | }; | 65 | }; |
62 | 66 | ||
63 | 67 | ||
@@ -705,10 +709,7 @@ static int i82092aa_set_mem_map(struct pcmcia_socket *socket, struct pccard_mem_ | |||
705 | 709 | ||
706 | static int i82092aa_module_init(void) | 710 | static int i82092aa_module_init(void) |
707 | { | 711 | { |
708 | enter("i82092aa_module_init"); | 712 | return pci_register_driver(&i82092aa_pci_drv); |
709 | pci_register_driver(&i82092aa_pci_drv); | ||
710 | leave("i82092aa_module_init"); | ||
711 | return 0; | ||
712 | } | 713 | } |
713 | 714 | ||
714 | static void i82092aa_module_exit(void) | 715 | static void i82092aa_module_exit(void) |
diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c index e070a2896769..3b72be880401 100644 --- a/drivers/pcmcia/m8xx_pcmcia.c +++ b/drivers/pcmcia/m8xx_pcmcia.c | |||
@@ -427,7 +427,7 @@ static int voltage_set(int slot, int vcc, int vpp) | |||
427 | reg |= BCSR1_PCCVCC1; | 427 | reg |= BCSR1_PCCVCC1; |
428 | break; | 428 | break; |
429 | default: | 429 | default: |
430 | return 1; | 430 | goto out_unmap; |
431 | } | 431 | } |
432 | 432 | ||
433 | switch(vpp) { | 433 | switch(vpp) { |
@@ -438,15 +438,15 @@ static int voltage_set(int slot, int vcc, int vpp) | |||
438 | if(vcc == vpp) | 438 | if(vcc == vpp) |
439 | reg |= BCSR1_PCCVPP1; | 439 | reg |= BCSR1_PCCVPP1; |
440 | else | 440 | else |
441 | return 1; | 441 | goto out_unmap; |
442 | break; | 442 | break; |
443 | case 120: | 443 | case 120: |
444 | if ((vcc == 33) || (vcc == 50)) | 444 | if ((vcc == 33) || (vcc == 50)) |
445 | reg |= BCSR1_PCCVPP0; | 445 | reg |= BCSR1_PCCVPP0; |
446 | else | 446 | else |
447 | return 1; | 447 | goto out_unmap; |
448 | default: | 448 | default: |
449 | return 1; | 449 | goto out_unmap; |
450 | } | 450 | } |
451 | 451 | ||
452 | /* first, turn off all power */ | 452 | /* first, turn off all power */ |
@@ -457,6 +457,10 @@ static int voltage_set(int slot, int vcc, int vpp) | |||
457 | 457 | ||
458 | iounmap(bcsr_io); | 458 | iounmap(bcsr_io); |
459 | return 0; | 459 | return 0; |
460 | |||
461 | out_unmap: | ||
462 | iounmap(bcsr_io); | ||
463 | return 1; | ||
460 | } | 464 | } |
461 | 465 | ||
462 | #define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V | 466 | #define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V |
diff --git a/drivers/pcmcia/omap_cf.c b/drivers/pcmcia/omap_cf.c index c8e838c69766..06bf7f48836e 100644 --- a/drivers/pcmcia/omap_cf.c +++ b/drivers/pcmcia/omap_cf.c | |||
@@ -309,9 +309,10 @@ static int __devinit omap_cf_probe(struct device *dev) | |||
309 | return 0; | 309 | return 0; |
310 | 310 | ||
311 | fail2: | 311 | fail2: |
312 | iounmap((void __iomem *) cf->socket.io_offset); | ||
313 | release_mem_region(cf->phys_cf, SZ_8K); | 312 | release_mem_region(cf->phys_cf, SZ_8K); |
314 | fail1: | 313 | fail1: |
314 | if (cf->socket.io_offset) | ||
315 | iounmap((void __iomem *) cf->socket.io_offset); | ||
315 | free_irq(irq, cf); | 316 | free_irq(irq, cf); |
316 | fail0: | 317 | fail0: |
317 | kfree(cf); | 318 | kfree(cf); |
diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c index 9ad18e62658d..310ede575caa 100644 --- a/drivers/pcmcia/pcmcia_ioctl.c +++ b/drivers/pcmcia/pcmcia_ioctl.c | |||
@@ -128,9 +128,12 @@ static int proc_read_drivers(char *buf, char **start, off_t pos, | |||
128 | int count, int *eof, void *data) | 128 | int count, int *eof, void *data) |
129 | { | 129 | { |
130 | char *p = buf; | 130 | char *p = buf; |
131 | int rc; | ||
131 | 132 | ||
132 | bus_for_each_drv(&pcmcia_bus_type, NULL, | 133 | rc = bus_for_each_drv(&pcmcia_bus_type, NULL, |
133 | (void *) &p, proc_read_drivers_callback); | 134 | (void *) &p, proc_read_drivers_callback); |
135 | if (rc < 0) | ||
136 | return rc; | ||
134 | 137 | ||
135 | return (p - buf); | 138 | return (p - buf); |
136 | } | 139 | } |
@@ -269,8 +272,10 @@ rescan: | |||
269 | * Prevent this racing with a card insertion. | 272 | * Prevent this racing with a card insertion. |
270 | */ | 273 | */ |
271 | mutex_lock(&s->skt_mutex); | 274 | mutex_lock(&s->skt_mutex); |
272 | bus_rescan_devices(&pcmcia_bus_type); | 275 | ret = bus_rescan_devices(&pcmcia_bus_type); |
273 | mutex_unlock(&s->skt_mutex); | 276 | mutex_unlock(&s->skt_mutex); |
277 | if (ret) | ||
278 | goto err_put_module; | ||
274 | 279 | ||
275 | /* check whether the driver indeed matched. I don't care if this | 280 | /* check whether the driver indeed matched. I don't care if this |
276 | * is racy or not, because it can only happen on cardmgr access | 281 | * is racy or not, because it can only happen on cardmgr access |
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c index 74cebd424032..b9201c2ec38b 100644 --- a/drivers/pcmcia/pcmcia_resource.c +++ b/drivers/pcmcia/pcmcia_resource.c | |||
@@ -95,7 +95,7 @@ static int alloc_io_space(struct pcmcia_socket *s, u_int attr, ioaddr_t *base, | |||
95 | * potential conflicts, just the most obvious ones. | 95 | * potential conflicts, just the most obvious ones. |
96 | */ | 96 | */ |
97 | for (i = 0; i < MAX_IO_WIN; i++) | 97 | for (i = 0; i < MAX_IO_WIN; i++) |
98 | if ((s->io[i].res) && | 98 | if ((s->io[i].res) && *base && |
99 | ((s->io[i].res->start & (align-1)) == *base)) | 99 | ((s->io[i].res->start & (align-1)) == *base)) |
100 | return 1; | 100 | return 1; |
101 | for (i = 0; i < MAX_IO_WIN; i++) { | 101 | for (i = 0; i < MAX_IO_WIN; i++) { |
diff --git a/drivers/pcmcia/pd6729.c b/drivers/pcmcia/pd6729.c index c83a0a6b158f..a70f97fdbbdd 100644 --- a/drivers/pcmcia/pd6729.c +++ b/drivers/pcmcia/pd6729.c | |||
@@ -755,6 +755,7 @@ static void __devexit pd6729_pci_remove(struct pci_dev *dev) | |||
755 | kfree(socket); | 755 | kfree(socket); |
756 | } | 756 | } |
757 | 757 | ||
758 | #ifdef CONFIG_PM | ||
758 | static int pd6729_socket_suspend(struct pci_dev *dev, pm_message_t state) | 759 | static int pd6729_socket_suspend(struct pci_dev *dev, pm_message_t state) |
759 | { | 760 | { |
760 | return pcmcia_socket_dev_suspend(&dev->dev, state); | 761 | return pcmcia_socket_dev_suspend(&dev->dev, state); |
@@ -764,6 +765,7 @@ static int pd6729_socket_resume(struct pci_dev *dev) | |||
764 | { | 765 | { |
765 | return pcmcia_socket_dev_resume(&dev->dev); | 766 | return pcmcia_socket_dev_resume(&dev->dev); |
766 | } | 767 | } |
768 | #endif | ||
767 | 769 | ||
768 | static struct pci_device_id pd6729_pci_ids[] = { | 770 | static struct pci_device_id pd6729_pci_ids[] = { |
769 | { | 771 | { |
@@ -781,8 +783,10 @@ static struct pci_driver pd6729_pci_drv = { | |||
781 | .id_table = pd6729_pci_ids, | 783 | .id_table = pd6729_pci_ids, |
782 | .probe = pd6729_pci_probe, | 784 | .probe = pd6729_pci_probe, |
783 | .remove = __devexit_p(pd6729_pci_remove), | 785 | .remove = __devexit_p(pd6729_pci_remove), |
786 | #ifdef CONFIG_PM | ||
784 | .suspend = pd6729_socket_suspend, | 787 | .suspend = pd6729_socket_suspend, |
785 | .resume = pd6729_socket_resume, | 788 | .resume = pd6729_socket_resume, |
789 | #endif | ||
786 | }; | 790 | }; |
787 | 791 | ||
788 | static int pd6729_module_init(void) | 792 | static int pd6729_module_init(void) |
diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c index b3518131ea0d..dca9f8549b32 100644 --- a/drivers/pcmcia/pxa2xx_base.c +++ b/drivers/pcmcia/pxa2xx_base.c | |||
@@ -166,7 +166,7 @@ pxa2xx_pcmcia_frequency_change(struct soc_pcmcia_socket *skt, | |||
166 | } | 166 | } |
167 | #endif | 167 | #endif |
168 | 168 | ||
169 | int pxa2xx_drv_pcmcia_probe(struct device *dev) | 169 | int __pxa2xx_drv_pcmcia_probe(struct device *dev) |
170 | { | 170 | { |
171 | int ret; | 171 | int ret; |
172 | struct pcmcia_low_level *ops; | 172 | struct pcmcia_low_level *ops; |
@@ -203,35 +203,52 @@ int pxa2xx_drv_pcmcia_probe(struct device *dev) | |||
203 | 203 | ||
204 | return ret; | 204 | return ret; |
205 | } | 205 | } |
206 | EXPORT_SYMBOL(pxa2xx_drv_pcmcia_probe); | 206 | EXPORT_SYMBOL(__pxa2xx_drv_pcmcia_probe); |
207 | 207 | ||
208 | static int pxa2xx_drv_pcmcia_resume(struct device *dev) | 208 | |
209 | static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev) | ||
210 | { | ||
211 | return __pxa2xx_drv_pcmcia_probe(&dev->dev); | ||
212 | } | ||
213 | |||
214 | static int pxa2xx_drv_pcmcia_remove(struct platform_device *dev) | ||
215 | { | ||
216 | return soc_common_drv_pcmcia_remove(&dev->dev); | ||
217 | } | ||
218 | |||
219 | static int pxa2xx_drv_pcmcia_suspend(struct platform_device *dev, pm_message_t state) | ||
220 | { | ||
221 | return pcmcia_socket_dev_suspend(&dev->dev, state); | ||
222 | } | ||
223 | |||
224 | static int pxa2xx_drv_pcmcia_resume(struct platform_device *dev) | ||
209 | { | 225 | { |
210 | struct pcmcia_low_level *ops = dev->platform_data; | 226 | struct pcmcia_low_level *ops = dev->dev.platform_data; |
211 | int nr = ops ? ops->nr : 0; | 227 | int nr = ops ? ops->nr : 0; |
212 | 228 | ||
213 | MECR = nr > 1 ? MECR_CIT | MECR_NOS : (nr > 0 ? MECR_CIT : 0); | 229 | MECR = nr > 1 ? MECR_CIT | MECR_NOS : (nr > 0 ? MECR_CIT : 0); |
214 | 230 | ||
215 | return pcmcia_socket_dev_resume(dev); | 231 | return pcmcia_socket_dev_resume(&dev->dev); |
216 | } | 232 | } |
217 | 233 | ||
218 | static struct device_driver pxa2xx_pcmcia_driver = { | 234 | static struct platform_driver pxa2xx_pcmcia_driver = { |
219 | .probe = pxa2xx_drv_pcmcia_probe, | 235 | .probe = pxa2xx_drv_pcmcia_probe, |
220 | .remove = soc_common_drv_pcmcia_remove, | 236 | .remove = pxa2xx_drv_pcmcia_remove, |
221 | .suspend = pcmcia_socket_dev_suspend, | 237 | .suspend = pxa2xx_drv_pcmcia_suspend, |
222 | .resume = pxa2xx_drv_pcmcia_resume, | 238 | .resume = pxa2xx_drv_pcmcia_resume, |
223 | .name = "pxa2xx-pcmcia", | 239 | .driver = { |
224 | .bus = &platform_bus_type, | 240 | .name = "pxa2xx-pcmcia", |
241 | }, | ||
225 | }; | 242 | }; |
226 | 243 | ||
227 | static int __init pxa2xx_pcmcia_init(void) | 244 | static int __init pxa2xx_pcmcia_init(void) |
228 | { | 245 | { |
229 | return driver_register(&pxa2xx_pcmcia_driver); | 246 | return platform_driver_register(&pxa2xx_pcmcia_driver); |
230 | } | 247 | } |
231 | 248 | ||
232 | static void __exit pxa2xx_pcmcia_exit(void) | 249 | static void __exit pxa2xx_pcmcia_exit(void) |
233 | { | 250 | { |
234 | driver_unregister(&pxa2xx_pcmcia_driver); | 251 | platform_driver_unregister(&pxa2xx_pcmcia_driver); |
235 | } | 252 | } |
236 | 253 | ||
237 | fs_initcall(pxa2xx_pcmcia_init); | 254 | fs_initcall(pxa2xx_pcmcia_init); |
diff --git a/drivers/pcmcia/pxa2xx_base.h b/drivers/pcmcia/pxa2xx_base.h index e46cff345d47..235d681652c3 100644 --- a/drivers/pcmcia/pxa2xx_base.h +++ b/drivers/pcmcia/pxa2xx_base.h | |||
@@ -1,3 +1,3 @@ | |||
1 | /* temporary measure */ | 1 | /* temporary measure */ |
2 | extern int pxa2xx_drv_pcmcia_probe(struct device *); | 2 | extern int __pxa2xx_drv_pcmcia_probe(struct device *); |
3 | 3 | ||
diff --git a/drivers/pcmcia/pxa2xx_lubbock.c b/drivers/pcmcia/pxa2xx_lubbock.c index fd1f691c7c2c..a92f11143c43 100644 --- a/drivers/pcmcia/pxa2xx_lubbock.c +++ b/drivers/pcmcia/pxa2xx_lubbock.c | |||
@@ -260,7 +260,7 @@ int __init pcmcia_lubbock_init(struct sa1111_dev *sadev) | |||
260 | lubbock_set_misc_wr((1 << 15) | (1 << 14), 0); | 260 | lubbock_set_misc_wr((1 << 15) | (1 << 14), 0); |
261 | 261 | ||
262 | sadev->dev.platform_data = &lubbock_pcmcia_ops; | 262 | sadev->dev.platform_data = &lubbock_pcmcia_ops; |
263 | ret = pxa2xx_drv_pcmcia_probe(&sadev->dev); | 263 | ret = __pxa2xx_drv_pcmcia_probe(&sadev->dev); |
264 | } | 264 | } |
265 | 265 | ||
266 | return ret; | 266 | return ret; |
diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c index 3627e52e0c27..e433704e026a 100644 --- a/drivers/pcmcia/soc_common.c +++ b/drivers/pcmcia/soc_common.c | |||
@@ -824,3 +824,4 @@ int soc_common_drv_pcmcia_remove(struct device *dev) | |||
824 | 824 | ||
825 | return 0; | 825 | return 0; |
826 | } | 826 | } |
827 | EXPORT_SYMBOL(soc_common_drv_pcmcia_remove); | ||
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c index 26229d9da762..da471bddc972 100644 --- a/drivers/pcmcia/yenta_socket.c +++ b/drivers/pcmcia/yenta_socket.c | |||
@@ -1197,8 +1197,12 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i | |||
1197 | ret = pcmcia_register_socket(&socket->socket); | 1197 | ret = pcmcia_register_socket(&socket->socket); |
1198 | if (ret == 0) { | 1198 | if (ret == 0) { |
1199 | /* Add the yenta register attributes */ | 1199 | /* Add the yenta register attributes */ |
1200 | device_create_file(&dev->dev, &dev_attr_yenta_registers); | 1200 | ret = device_create_file(&dev->dev, &dev_attr_yenta_registers); |
1201 | goto out; | 1201 | if (ret == 0) |
1202 | goto out; | ||
1203 | |||
1204 | /* error path... */ | ||
1205 | pcmcia_unregister_socket(&socket->socket); | ||
1202 | } | 1206 | } |
1203 | 1207 | ||
1204 | unmap: | 1208 | unmap: |
@@ -1213,7 +1217,7 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i | |||
1213 | return ret; | 1217 | return ret; |
1214 | } | 1218 | } |
1215 | 1219 | ||
1216 | 1220 | #ifdef CONFIG_PM | |
1217 | static int yenta_dev_suspend (struct pci_dev *dev, pm_message_t state) | 1221 | static int yenta_dev_suspend (struct pci_dev *dev, pm_message_t state) |
1218 | { | 1222 | { |
1219 | struct yenta_socket *socket = pci_get_drvdata(dev); | 1223 | struct yenta_socket *socket = pci_get_drvdata(dev); |
@@ -1248,12 +1252,18 @@ static int yenta_dev_resume (struct pci_dev *dev) | |||
1248 | struct yenta_socket *socket = pci_get_drvdata(dev); | 1252 | struct yenta_socket *socket = pci_get_drvdata(dev); |
1249 | 1253 | ||
1250 | if (socket) { | 1254 | if (socket) { |
1255 | int rc; | ||
1256 | |||
1251 | pci_set_power_state(dev, 0); | 1257 | pci_set_power_state(dev, 0); |
1252 | /* FIXME: pci_restore_state needs to have a better interface */ | 1258 | /* FIXME: pci_restore_state needs to have a better interface */ |
1253 | pci_restore_state(dev); | 1259 | pci_restore_state(dev); |
1254 | pci_write_config_dword(dev, 16*4, socket->saved_state[0]); | 1260 | pci_write_config_dword(dev, 16*4, socket->saved_state[0]); |
1255 | pci_write_config_dword(dev, 17*4, socket->saved_state[1]); | 1261 | pci_write_config_dword(dev, 17*4, socket->saved_state[1]); |
1256 | pci_enable_device(dev); | 1262 | |
1263 | rc = pci_enable_device(dev); | ||
1264 | if (rc) | ||
1265 | return rc; | ||
1266 | |||
1257 | pci_set_master(dev); | 1267 | pci_set_master(dev); |
1258 | 1268 | ||
1259 | if (socket->type && socket->type->restore_state) | 1269 | if (socket->type && socket->type->restore_state) |
@@ -1262,7 +1272,7 @@ static int yenta_dev_resume (struct pci_dev *dev) | |||
1262 | 1272 | ||
1263 | return pcmcia_socket_dev_resume(&dev->dev); | 1273 | return pcmcia_socket_dev_resume(&dev->dev); |
1264 | } | 1274 | } |
1265 | 1275 | #endif | |
1266 | 1276 | ||
1267 | #define CB_ID(vend,dev,type) \ | 1277 | #define CB_ID(vend,dev,type) \ |
1268 | { \ | 1278 | { \ |
@@ -1359,8 +1369,10 @@ static struct pci_driver yenta_cardbus_driver = { | |||
1359 | .id_table = yenta_table, | 1369 | .id_table = yenta_table, |
1360 | .probe = yenta_probe, | 1370 | .probe = yenta_probe, |
1361 | .remove = __devexit_p(yenta_close), | 1371 | .remove = __devexit_p(yenta_close), |
1372 | #ifdef CONFIG_PM | ||
1362 | .suspend = yenta_dev_suspend, | 1373 | .suspend = yenta_dev_suspend, |
1363 | .resume = yenta_dev_resume, | 1374 | .resume = yenta_dev_resume, |
1375 | #endif | ||
1364 | }; | 1376 | }; |
1365 | 1377 | ||
1366 | 1378 | ||
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index dc79b0a0059f..379048fdf05d 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c | |||
@@ -776,21 +776,32 @@ static void pnpacpi_encode_dma(struct acpi_resource *resource, | |||
776 | struct resource *p) | 776 | struct resource *p) |
777 | { | 777 | { |
778 | /* Note: pnp_assign_dma will copy pnp_dma->flags into p->flags */ | 778 | /* Note: pnp_assign_dma will copy pnp_dma->flags into p->flags */ |
779 | if (p->flags & IORESOURCE_DMA_COMPATIBLE) | 779 | switch (p->flags & IORESOURCE_DMA_SPEED_MASK) { |
780 | resource->data.dma.type = ACPI_COMPATIBILITY; | 780 | case IORESOURCE_DMA_TYPEA: |
781 | else if (p->flags & IORESOURCE_DMA_TYPEA) | 781 | resource->data.dma.type = ACPI_TYPE_A; |
782 | resource->data.dma.type = ACPI_TYPE_A; | 782 | break; |
783 | else if (p->flags & IORESOURCE_DMA_TYPEB) | 783 | case IORESOURCE_DMA_TYPEB: |
784 | resource->data.dma.type = ACPI_TYPE_B; | 784 | resource->data.dma.type = ACPI_TYPE_B; |
785 | else if (p->flags & IORESOURCE_DMA_TYPEF) | 785 | break; |
786 | resource->data.dma.type = ACPI_TYPE_F; | 786 | case IORESOURCE_DMA_TYPEF: |
787 | if (p->flags & IORESOURCE_DMA_8BIT) | 787 | resource->data.dma.type = ACPI_TYPE_F; |
788 | resource->data.dma.transfer = ACPI_TRANSFER_8; | 788 | break; |
789 | else if (p->flags & IORESOURCE_DMA_8AND16BIT) | 789 | default: |
790 | resource->data.dma.transfer = ACPI_TRANSFER_8_16; | 790 | resource->data.dma.type = ACPI_COMPATIBILITY; |
791 | else if (p->flags & IORESOURCE_DMA_16BIT) | 791 | } |
792 | resource->data.dma.transfer = ACPI_TRANSFER_16; | 792 | |
793 | resource->data.dma.bus_master = p->flags & IORESOURCE_DMA_MASTER; | 793 | switch (p->flags & IORESOURCE_DMA_TYPE_MASK) { |
794 | case IORESOURCE_DMA_8BIT: | ||
795 | resource->data.dma.transfer = ACPI_TRANSFER_8; | ||
796 | break; | ||
797 | case IORESOURCE_DMA_8AND16BIT: | ||
798 | resource->data.dma.transfer = ACPI_TRANSFER_8_16; | ||
799 | break; | ||
800 | default: | ||
801 | resource->data.dma.transfer = ACPI_TRANSFER_16; | ||
802 | } | ||
803 | |||
804 | resource->data.dma.bus_master = !!(p->flags & IORESOURCE_DMA_MASTER); | ||
794 | resource->data.dma.channel_count = 1; | 805 | resource->data.dma.channel_count = 1; |
795 | resource->data.dma.channels[0] = p->start; | 806 | resource->data.dma.channels[0] = p->start; |
796 | } | 807 | } |
diff --git a/drivers/rtc/rtc-max6902.c b/drivers/rtc/rtc-max6902.c index 0b20dfacbf59..d94170728075 100644 --- a/drivers/rtc/rtc-max6902.c +++ b/drivers/rtc/rtc-max6902.c | |||
@@ -136,7 +136,7 @@ static int max6902_get_datetime(struct device *dev, struct rtc_time *dt) | |||
136 | dt->tm_min = BCD2BIN(chip->buf[2]); | 136 | dt->tm_min = BCD2BIN(chip->buf[2]); |
137 | dt->tm_hour = BCD2BIN(chip->buf[3]); | 137 | dt->tm_hour = BCD2BIN(chip->buf[3]); |
138 | dt->tm_mday = BCD2BIN(chip->buf[4]); | 138 | dt->tm_mday = BCD2BIN(chip->buf[4]); |
139 | dt->tm_mon = BCD2BIN(chip->buf[5] - 1); | 139 | dt->tm_mon = BCD2BIN(chip->buf[5]) - 1; |
140 | dt->tm_wday = BCD2BIN(chip->buf[6]); | 140 | dt->tm_wday = BCD2BIN(chip->buf[6]); |
141 | dt->tm_year = BCD2BIN(chip->buf[7]); | 141 | dt->tm_year = BCD2BIN(chip->buf[7]); |
142 | 142 | ||
diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c index 8b6efcc05058..143302a8e79c 100644 --- a/drivers/rtc/rtc-sh.c +++ b/drivers/rtc/rtc-sh.c | |||
@@ -160,7 +160,7 @@ static int sh_rtc_open(struct device *dev) | |||
160 | tmp |= RCR1_CIE; | 160 | tmp |= RCR1_CIE; |
161 | writeb(tmp, rtc->regbase + RCR1); | 161 | writeb(tmp, rtc->regbase + RCR1); |
162 | 162 | ||
163 | ret = request_irq(rtc->periodic_irq, sh_rtc_periodic, SA_INTERRUPT, | 163 | ret = request_irq(rtc->periodic_irq, sh_rtc_periodic, IRQF_DISABLED, |
164 | "sh-rtc period", dev); | 164 | "sh-rtc period", dev); |
165 | if (unlikely(ret)) { | 165 | if (unlikely(ret)) { |
166 | dev_err(dev, "request period IRQ failed with %d, IRQ %d\n", | 166 | dev_err(dev, "request period IRQ failed with %d, IRQ %d\n", |
@@ -168,7 +168,7 @@ static int sh_rtc_open(struct device *dev) | |||
168 | return ret; | 168 | return ret; |
169 | } | 169 | } |
170 | 170 | ||
171 | ret = request_irq(rtc->carry_irq, sh_rtc_interrupt, SA_INTERRUPT, | 171 | ret = request_irq(rtc->carry_irq, sh_rtc_interrupt, IRQF_DISABLED, |
172 | "sh-rtc carry", dev); | 172 | "sh-rtc carry", dev); |
173 | if (unlikely(ret)) { | 173 | if (unlikely(ret)) { |
174 | dev_err(dev, "request carry IRQ failed with %d, IRQ %d\n", | 174 | dev_err(dev, "request carry IRQ failed with %d, IRQ %d\n", |
@@ -177,7 +177,7 @@ static int sh_rtc_open(struct device *dev) | |||
177 | goto err_bad_carry; | 177 | goto err_bad_carry; |
178 | } | 178 | } |
179 | 179 | ||
180 | ret = request_irq(rtc->alarm_irq, sh_rtc_interrupt, SA_INTERRUPT, | 180 | ret = request_irq(rtc->alarm_irq, sh_rtc_interrupt, IRQF_DISABLED, |
181 | "sh-rtc alarm", dev); | 181 | "sh-rtc alarm", dev); |
182 | if (unlikely(ret)) { | 182 | if (unlikely(ret)) { |
183 | dev_err(dev, "request alarm IRQ failed with %d, IRQ %d\n", | 183 | dev_err(dev, "request alarm IRQ failed with %d, IRQ %d\n", |
diff --git a/drivers/rtc/rtc-v3020.c b/drivers/rtc/rtc-v3020.c index 09b714f1cdc3..3b58d3d5d38a 100644 --- a/drivers/rtc/rtc-v3020.c +++ b/drivers/rtc/rtc-v3020.c | |||
@@ -195,9 +195,9 @@ static int rtc_probe(struct platform_device *pdev) | |||
195 | * are all disabled */ | 195 | * are all disabled */ |
196 | v3020_set_reg(chip, V3020_STATUS_0, 0x0); | 196 | v3020_set_reg(chip, V3020_STATUS_0, 0x0); |
197 | 197 | ||
198 | dev_info(&pdev->dev, "Chip available at physical address 0x%p," | 198 | dev_info(&pdev->dev, "Chip available at physical address 0x%llx," |
199 | "data connected to D%d\n", | 199 | "data connected to D%d\n", |
200 | (void*)pdev->resource[0].start, | 200 | (unsigned long long)pdev->resource[0].start, |
201 | chip->leftshift); | 201 | chip->leftshift); |
202 | 202 | ||
203 | platform_set_drvdata(pdev, chip); | 203 | platform_set_drvdata(pdev, chip); |
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index d0647d116eaa..79ffef6bfaf8 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c | |||
@@ -203,6 +203,7 @@ dasd_state_basic_to_known(struct dasd_device * device) | |||
203 | rc = dasd_flush_ccw_queue(device, 1); | 203 | rc = dasd_flush_ccw_queue(device, 1); |
204 | if (rc) | 204 | if (rc) |
205 | return rc; | 205 | return rc; |
206 | dasd_clear_timer(device); | ||
206 | 207 | ||
207 | DBF_DEV_EVENT(DBF_EMERG, device, "%p debug area deleted", device); | 208 | DBF_DEV_EVENT(DBF_EMERG, device, "%p debug area deleted", device); |
208 | if (device->debug_area != NULL) { | 209 | if (device->debug_area != NULL) { |
diff --git a/drivers/s390/char/monwriter.c b/drivers/s390/char/monwriter.c index 4362ff260244..b9b0fc3f812b 100644 --- a/drivers/s390/char/monwriter.c +++ b/drivers/s390/char/monwriter.c | |||
@@ -73,12 +73,15 @@ static inline struct mon_buf *monwrite_find_hdr(struct mon_private *monpriv, | |||
73 | struct mon_buf *entry, *next; | 73 | struct mon_buf *entry, *next; |
74 | 74 | ||
75 | list_for_each_entry_safe(entry, next, &monpriv->list, list) | 75 | list_for_each_entry_safe(entry, next, &monpriv->list, list) |
76 | if (entry->hdr.applid == monhdr->applid && | 76 | if ((entry->hdr.mon_function == monhdr->mon_function || |
77 | monhdr->mon_function == MONWRITE_STOP_INTERVAL) && | ||
78 | entry->hdr.applid == monhdr->applid && | ||
77 | entry->hdr.record_num == monhdr->record_num && | 79 | entry->hdr.record_num == monhdr->record_num && |
78 | entry->hdr.version == monhdr->version && | 80 | entry->hdr.version == monhdr->version && |
79 | entry->hdr.release == monhdr->release && | 81 | entry->hdr.release == monhdr->release && |
80 | entry->hdr.mod_level == monhdr->mod_level) | 82 | entry->hdr.mod_level == monhdr->mod_level) |
81 | return entry; | 83 | return entry; |
84 | |||
82 | return NULL; | 85 | return NULL; |
83 | } | 86 | } |
84 | 87 | ||
@@ -92,7 +95,9 @@ static int monwrite_new_hdr(struct mon_private *monpriv) | |||
92 | monhdr->mon_function > MONWRITE_START_CONFIG || | 95 | monhdr->mon_function > MONWRITE_START_CONFIG || |
93 | monhdr->hdrlen != sizeof(struct monwrite_hdr)) | 96 | monhdr->hdrlen != sizeof(struct monwrite_hdr)) |
94 | return -EINVAL; | 97 | return -EINVAL; |
95 | monbuf = monwrite_find_hdr(monpriv, monhdr); | 98 | monbuf = NULL; |
99 | if (monhdr->mon_function != MONWRITE_GEN_EVENT) | ||
100 | monbuf = monwrite_find_hdr(monpriv, monhdr); | ||
96 | if (monbuf) { | 101 | if (monbuf) { |
97 | if (monhdr->mon_function == MONWRITE_STOP_INTERVAL) { | 102 | if (monhdr->mon_function == MONWRITE_STOP_INTERVAL) { |
98 | monhdr->datalen = monbuf->hdr.datalen; | 103 | monhdr->datalen = monbuf->hdr.datalen; |
@@ -104,13 +109,13 @@ static int monwrite_new_hdr(struct mon_private *monpriv) | |||
104 | kfree(monbuf); | 109 | kfree(monbuf); |
105 | monbuf = NULL; | 110 | monbuf = NULL; |
106 | } | 111 | } |
107 | } else { | 112 | } else if (monhdr->mon_function != MONWRITE_STOP_INTERVAL) { |
108 | if (mon_buf_count >= mon_max_bufs) | 113 | if (mon_buf_count >= mon_max_bufs) |
109 | return -ENOSPC; | 114 | return -ENOSPC; |
110 | monbuf = kzalloc(sizeof(struct mon_buf), GFP_KERNEL); | 115 | monbuf = kzalloc(sizeof(struct mon_buf), GFP_KERNEL); |
111 | if (!monbuf) | 116 | if (!monbuf) |
112 | return -ENOMEM; | 117 | return -ENOMEM; |
113 | monbuf->data = kzalloc(monbuf->hdr.datalen, | 118 | monbuf->data = kzalloc(monhdr->datalen, |
114 | GFP_KERNEL | GFP_DMA); | 119 | GFP_KERNEL | GFP_DMA); |
115 | if (!monbuf->data) { | 120 | if (!monbuf->data) { |
116 | kfree(monbuf); | 121 | kfree(monbuf); |
@@ -118,7 +123,8 @@ static int monwrite_new_hdr(struct mon_private *monpriv) | |||
118 | } | 123 | } |
119 | monbuf->hdr = *monhdr; | 124 | monbuf->hdr = *monhdr; |
120 | list_add_tail(&monbuf->list, &monpriv->list); | 125 | list_add_tail(&monbuf->list, &monpriv->list); |
121 | mon_buf_count++; | 126 | if (monhdr->mon_function != MONWRITE_GEN_EVENT) |
127 | mon_buf_count++; | ||
122 | } | 128 | } |
123 | monpriv->current_buf = monbuf; | 129 | monpriv->current_buf = monbuf; |
124 | return 0; | 130 | return 0; |
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c index 07c7f19339d2..2d78f0f4a40f 100644 --- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c | |||
@@ -370,7 +370,7 @@ __s390_process_res_acc(struct subchannel_id schid, void *data) | |||
370 | struct res_acc_data *res_data; | 370 | struct res_acc_data *res_data; |
371 | struct subchannel *sch; | 371 | struct subchannel *sch; |
372 | 372 | ||
373 | res_data = (struct res_acc_data *)data; | 373 | res_data = data; |
374 | sch = get_subchannel_by_schid(schid); | 374 | sch = get_subchannel_by_schid(schid); |
375 | if (!sch) | 375 | if (!sch) |
376 | /* Check if a subchannel is newly available. */ | 376 | /* Check if a subchannel is newly available. */ |
@@ -444,7 +444,7 @@ __get_chpid_from_lir(void *data) | |||
444 | u32 isinfo[28]; | 444 | u32 isinfo[28]; |
445 | } *lir; | 445 | } *lir; |
446 | 446 | ||
447 | lir = (struct lir*) data; | 447 | lir = data; |
448 | if (!(lir->iq&0x80)) | 448 | if (!(lir->iq&0x80)) |
449 | /* NULL link incident record */ | 449 | /* NULL link incident record */ |
450 | return -EINVAL; | 450 | return -EINVAL; |
@@ -628,7 +628,7 @@ __chp_add(struct subchannel_id schid, void *data) | |||
628 | struct channel_path *chp; | 628 | struct channel_path *chp; |
629 | struct subchannel *sch; | 629 | struct subchannel *sch; |
630 | 630 | ||
631 | chp = (struct channel_path *)data; | 631 | chp = data; |
632 | sch = get_subchannel_by_schid(schid); | 632 | sch = get_subchannel_by_schid(schid); |
633 | if (!sch) | 633 | if (!sch) |
634 | /* Check if the subchannel is now available. */ | 634 | /* Check if the subchannel is now available. */ |
@@ -707,8 +707,7 @@ chp_process_crw(int chpid, int on) | |||
707 | return chp_add(chpid); | 707 | return chp_add(chpid); |
708 | } | 708 | } |
709 | 709 | ||
710 | static inline int | 710 | static inline int check_for_io_on_path(struct subchannel *sch, int index) |
711 | __check_for_io_and_kill(struct subchannel *sch, int index) | ||
712 | { | 711 | { |
713 | int cc; | 712 | int cc; |
714 | 713 | ||
@@ -718,10 +717,8 @@ __check_for_io_and_kill(struct subchannel *sch, int index) | |||
718 | cc = stsch(sch->schid, &sch->schib); | 717 | cc = stsch(sch->schid, &sch->schib); |
719 | if (cc) | 718 | if (cc) |
720 | return 0; | 719 | return 0; |
721 | if (sch->schib.scsw.actl && sch->schib.pmcw.lpum == (0x80 >> index)) { | 720 | if (sch->schib.scsw.actl && sch->schib.pmcw.lpum == (0x80 >> index)) |
722 | device_set_waiting(sch); | ||
723 | return 1; | 721 | return 1; |
724 | } | ||
725 | return 0; | 722 | return 0; |
726 | } | 723 | } |
727 | 724 | ||
@@ -750,12 +747,10 @@ __s390_subchannel_vary_chpid(struct subchannel *sch, __u8 chpid, int on) | |||
750 | } else { | 747 | } else { |
751 | sch->opm &= ~(0x80 >> chp); | 748 | sch->opm &= ~(0x80 >> chp); |
752 | sch->lpm &= ~(0x80 >> chp); | 749 | sch->lpm &= ~(0x80 >> chp); |
753 | /* | 750 | if (check_for_io_on_path(sch, chp)) |
754 | * Give running I/O a grace period in which it | 751 | /* Path verification is done after killing. */ |
755 | * can successfully terminate, even using the | 752 | device_kill_io(sch); |
756 | * just varied off path. Then kill it. | 753 | else if (!sch->lpm) { |
757 | */ | ||
758 | if (!__check_for_io_and_kill(sch, chp) && !sch->lpm) { | ||
759 | if (css_enqueue_subchannel_slow(sch->schid)) { | 754 | if (css_enqueue_subchannel_slow(sch->schid)) { |
760 | css_clear_subchannel_slow_list(); | 755 | css_clear_subchannel_slow_list(); |
761 | need_rescan = 1; | 756 | need_rescan = 1; |
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index f18b1623cad7..8936e460a807 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c | |||
@@ -609,8 +609,8 @@ do_IRQ (struct pt_regs *regs) | |||
609 | struct irb *irb; | 609 | struct irb *irb; |
610 | struct pt_regs *old_regs; | 610 | struct pt_regs *old_regs; |
611 | 611 | ||
612 | irq_enter (); | ||
613 | old_regs = set_irq_regs(regs); | 612 | old_regs = set_irq_regs(regs); |
613 | irq_enter(); | ||
614 | asm volatile ("mc 0,0"); | 614 | asm volatile ("mc 0,0"); |
615 | if (S390_lowcore.int_clock >= S390_lowcore.jiffy_timer) | 615 | if (S390_lowcore.int_clock >= S390_lowcore.jiffy_timer) |
616 | /** | 616 | /** |
@@ -655,8 +655,8 @@ do_IRQ (struct pt_regs *regs) | |||
655 | * out of the sie which costs more cycles than it saves. | 655 | * out of the sie which costs more cycles than it saves. |
656 | */ | 656 | */ |
657 | } while (!MACHINE_IS_VM && tpi (NULL) != 0); | 657 | } while (!MACHINE_IS_VM && tpi (NULL) != 0); |
658 | irq_exit(); | ||
658 | set_irq_regs(old_regs); | 659 | set_irq_regs(old_regs); |
659 | irq_exit (); | ||
660 | } | 660 | } |
661 | 661 | ||
662 | #ifdef CONFIG_CCW_CONSOLE | 662 | #ifdef CONFIG_CCW_CONSOLE |
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index 7086a74e9871..ad7f7e1c0163 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c | |||
@@ -177,7 +177,7 @@ get_subchannel_by_schid(struct subchannel_id schid) | |||
177 | struct device *dev; | 177 | struct device *dev; |
178 | 178 | ||
179 | dev = bus_find_device(&css_bus_type, NULL, | 179 | dev = bus_find_device(&css_bus_type, NULL, |
180 | (void *)&schid, check_subchannel); | 180 | &schid, check_subchannel); |
181 | 181 | ||
182 | return dev ? to_subchannel(dev) : NULL; | 182 | return dev ? to_subchannel(dev) : NULL; |
183 | } | 183 | } |
@@ -271,10 +271,6 @@ static int css_evaluate_known_subchannel(struct subchannel *sch, int slow) | |||
271 | /* Reset intparm to zeroes. */ | 271 | /* Reset intparm to zeroes. */ |
272 | sch->schib.pmcw.intparm = 0; | 272 | sch->schib.pmcw.intparm = 0; |
273 | cio_modify(sch); | 273 | cio_modify(sch); |
274 | |||
275 | /* Probe if necessary. */ | ||
276 | if (action == UNREGISTER_PROBE) | ||
277 | ret = css_probe_device(sch->schid); | ||
278 | break; | 274 | break; |
279 | case REPROBE: | 275 | case REPROBE: |
280 | device_trigger_reprobe(sch); | 276 | device_trigger_reprobe(sch); |
@@ -283,6 +279,9 @@ static int css_evaluate_known_subchannel(struct subchannel *sch, int slow) | |||
283 | break; | 279 | break; |
284 | } | 280 | } |
285 | spin_unlock_irqrestore(&sch->lock, flags); | 281 | spin_unlock_irqrestore(&sch->lock, flags); |
282 | /* Probe if necessary. */ | ||
283 | if (action == UNREGISTER_PROBE) | ||
284 | ret = css_probe_device(sch->schid); | ||
286 | 285 | ||
287 | return ret; | 286 | return ret; |
288 | } | 287 | } |
diff --git a/drivers/s390/cio/css.h b/drivers/s390/cio/css.h index 8aabb4adeb5f..4c2ff8336288 100644 --- a/drivers/s390/cio/css.h +++ b/drivers/s390/cio/css.h | |||
@@ -76,9 +76,8 @@ struct ccw_device_private { | |||
76 | int state; /* device state */ | 76 | int state; /* device state */ |
77 | atomic_t onoff; | 77 | atomic_t onoff; |
78 | unsigned long registered; | 78 | unsigned long registered; |
79 | __u16 devno; /* device number */ | 79 | struct ccw_dev_id dev_id; /* device id */ |
80 | __u16 sch_no; /* subchannel number */ | 80 | struct subchannel_id schid; /* subchannel number */ |
81 | __u8 ssid; /* subchannel set id */ | ||
82 | __u8 imask; /* lpm mask for SNID/SID/SPGID */ | 81 | __u8 imask; /* lpm mask for SNID/SID/SPGID */ |
83 | int iretry; /* retry counter SNID/SID/SPGID */ | 82 | int iretry; /* retry counter SNID/SID/SPGID */ |
84 | struct { | 83 | struct { |
@@ -171,7 +170,7 @@ void device_trigger_reprobe(struct subchannel *); | |||
171 | 170 | ||
172 | /* Helper functions for vary on/off. */ | 171 | /* Helper functions for vary on/off. */ |
173 | int device_is_online(struct subchannel *); | 172 | int device_is_online(struct subchannel *); |
174 | void device_set_waiting(struct subchannel *); | 173 | void device_kill_io(struct subchannel *); |
175 | 174 | ||
176 | /* Machine check helper function. */ | 175 | /* Machine check helper function. */ |
177 | void device_kill_pending_timer(struct subchannel *); | 176 | void device_kill_pending_timer(struct subchannel *); |
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index 688945662c15..39c98f940507 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c | |||
@@ -532,8 +532,7 @@ device_remove_files(struct device *dev) | |||
532 | 532 | ||
533 | /* this is a simple abstraction for device_register that sets the | 533 | /* this is a simple abstraction for device_register that sets the |
534 | * correct bus type and adds the bus specific files */ | 534 | * correct bus type and adds the bus specific files */ |
535 | int | 535 | static int ccw_device_register(struct ccw_device *cdev) |
536 | ccw_device_register(struct ccw_device *cdev) | ||
537 | { | 536 | { |
538 | struct device *dev = &cdev->dev; | 537 | struct device *dev = &cdev->dev; |
539 | int ret; | 538 | int ret; |
@@ -552,21 +551,19 @@ ccw_device_register(struct ccw_device *cdev) | |||
552 | } | 551 | } |
553 | 552 | ||
554 | struct match_data { | 553 | struct match_data { |
555 | unsigned int devno; | 554 | struct ccw_dev_id dev_id; |
556 | unsigned int ssid; | ||
557 | struct ccw_device * sibling; | 555 | struct ccw_device * sibling; |
558 | }; | 556 | }; |
559 | 557 | ||
560 | static int | 558 | static int |
561 | match_devno(struct device * dev, void * data) | 559 | match_devno(struct device * dev, void * data) |
562 | { | 560 | { |
563 | struct match_data * d = (struct match_data *)data; | 561 | struct match_data * d = data; |
564 | struct ccw_device * cdev; | 562 | struct ccw_device * cdev; |
565 | 563 | ||
566 | cdev = to_ccwdev(dev); | 564 | cdev = to_ccwdev(dev); |
567 | if ((cdev->private->state == DEV_STATE_DISCONNECTED) && | 565 | if ((cdev->private->state == DEV_STATE_DISCONNECTED) && |
568 | (cdev->private->devno == d->devno) && | 566 | ccw_dev_id_is_equal(&cdev->private->dev_id, &d->dev_id) && |
569 | (cdev->private->ssid == d->ssid) && | ||
570 | (cdev != d->sibling)) { | 567 | (cdev != d->sibling)) { |
571 | cdev->private->state = DEV_STATE_NOT_OPER; | 568 | cdev->private->state = DEV_STATE_NOT_OPER; |
572 | return 1; | 569 | return 1; |
@@ -574,15 +571,13 @@ match_devno(struct device * dev, void * data) | |||
574 | return 0; | 571 | return 0; |
575 | } | 572 | } |
576 | 573 | ||
577 | static struct ccw_device * | 574 | static struct ccw_device * get_disc_ccwdev_by_dev_id(struct ccw_dev_id *dev_id, |
578 | get_disc_ccwdev_by_devno(unsigned int devno, unsigned int ssid, | 575 | struct ccw_device *sibling) |
579 | struct ccw_device *sibling) | ||
580 | { | 576 | { |
581 | struct device *dev; | 577 | struct device *dev; |
582 | struct match_data data; | 578 | struct match_data data; |
583 | 579 | ||
584 | data.devno = devno; | 580 | data.dev_id = *dev_id; |
585 | data.ssid = ssid; | ||
586 | data.sibling = sibling; | 581 | data.sibling = sibling; |
587 | dev = bus_find_device(&ccw_bus_type, NULL, &data, match_devno); | 582 | dev = bus_find_device(&ccw_bus_type, NULL, &data, match_devno); |
588 | 583 | ||
@@ -595,7 +590,7 @@ ccw_device_add_changed(void *data) | |||
595 | 590 | ||
596 | struct ccw_device *cdev; | 591 | struct ccw_device *cdev; |
597 | 592 | ||
598 | cdev = (struct ccw_device *)data; | 593 | cdev = data; |
599 | if (device_add(&cdev->dev)) { | 594 | if (device_add(&cdev->dev)) { |
600 | put_device(&cdev->dev); | 595 | put_device(&cdev->dev); |
601 | return; | 596 | return; |
@@ -616,9 +611,9 @@ ccw_device_do_unreg_rereg(void *data) | |||
616 | struct subchannel *sch; | 611 | struct subchannel *sch; |
617 | int need_rename; | 612 | int need_rename; |
618 | 613 | ||
619 | cdev = (struct ccw_device *)data; | 614 | cdev = data; |
620 | sch = to_subchannel(cdev->dev.parent); | 615 | sch = to_subchannel(cdev->dev.parent); |
621 | if (cdev->private->devno != sch->schib.pmcw.dev) { | 616 | if (cdev->private->dev_id.devno != sch->schib.pmcw.dev) { |
622 | /* | 617 | /* |
623 | * The device number has changed. This is usually only when | 618 | * The device number has changed. This is usually only when |
624 | * a device has been detached under VM and then re-appeared | 619 | * a device has been detached under VM and then re-appeared |
@@ -633,10 +628,12 @@ ccw_device_do_unreg_rereg(void *data) | |||
633 | * get possibly sick... | 628 | * get possibly sick... |
634 | */ | 629 | */ |
635 | struct ccw_device *other_cdev; | 630 | struct ccw_device *other_cdev; |
631 | struct ccw_dev_id dev_id; | ||
636 | 632 | ||
637 | need_rename = 1; | 633 | need_rename = 1; |
638 | other_cdev = get_disc_ccwdev_by_devno(sch->schib.pmcw.dev, | 634 | dev_id.devno = sch->schib.pmcw.dev; |
639 | sch->schid.ssid, cdev); | 635 | dev_id.ssid = sch->schid.ssid; |
636 | other_cdev = get_disc_ccwdev_by_dev_id(&dev_id, cdev); | ||
640 | if (other_cdev) { | 637 | if (other_cdev) { |
641 | struct subchannel *other_sch; | 638 | struct subchannel *other_sch; |
642 | 639 | ||
@@ -652,7 +649,7 @@ ccw_device_do_unreg_rereg(void *data) | |||
652 | } | 649 | } |
653 | /* Update ssd info here. */ | 650 | /* Update ssd info here. */ |
654 | css_get_ssd_info(sch); | 651 | css_get_ssd_info(sch); |
655 | cdev->private->devno = sch->schib.pmcw.dev; | 652 | cdev->private->dev_id.devno = sch->schib.pmcw.dev; |
656 | } else | 653 | } else |
657 | need_rename = 0; | 654 | need_rename = 0; |
658 | device_remove_files(&cdev->dev); | 655 | device_remove_files(&cdev->dev); |
@@ -662,7 +659,7 @@ ccw_device_do_unreg_rereg(void *data) | |||
662 | snprintf (cdev->dev.bus_id, BUS_ID_SIZE, "0.%x.%04x", | 659 | snprintf (cdev->dev.bus_id, BUS_ID_SIZE, "0.%x.%04x", |
663 | sch->schid.ssid, sch->schib.pmcw.dev); | 660 | sch->schid.ssid, sch->schib.pmcw.dev); |
664 | PREPARE_WORK(&cdev->private->kick_work, | 661 | PREPARE_WORK(&cdev->private->kick_work, |
665 | ccw_device_add_changed, (void *)cdev); | 662 | ccw_device_add_changed, cdev); |
666 | queue_work(ccw_device_work, &cdev->private->kick_work); | 663 | queue_work(ccw_device_work, &cdev->private->kick_work); |
667 | } | 664 | } |
668 | 665 | ||
@@ -687,7 +684,7 @@ io_subchannel_register(void *data) | |||
687 | int ret; | 684 | int ret; |
688 | unsigned long flags; | 685 | unsigned long flags; |
689 | 686 | ||
690 | cdev = (struct ccw_device *) data; | 687 | cdev = data; |
691 | sch = to_subchannel(cdev->dev.parent); | 688 | sch = to_subchannel(cdev->dev.parent); |
692 | 689 | ||
693 | if (klist_node_attached(&cdev->dev.knode_parent)) { | 690 | if (klist_node_attached(&cdev->dev.knode_parent)) { |
@@ -759,7 +756,7 @@ io_subchannel_recog_done(struct ccw_device *cdev) | |||
759 | break; | 756 | break; |
760 | sch = to_subchannel(cdev->dev.parent); | 757 | sch = to_subchannel(cdev->dev.parent); |
761 | PREPARE_WORK(&cdev->private->kick_work, | 758 | PREPARE_WORK(&cdev->private->kick_work, |
762 | ccw_device_call_sch_unregister, (void *) cdev); | 759 | ccw_device_call_sch_unregister, cdev); |
763 | queue_work(slow_path_wq, &cdev->private->kick_work); | 760 | queue_work(slow_path_wq, &cdev->private->kick_work); |
764 | if (atomic_dec_and_test(&ccw_device_init_count)) | 761 | if (atomic_dec_and_test(&ccw_device_init_count)) |
765 | wake_up(&ccw_device_init_wq); | 762 | wake_up(&ccw_device_init_wq); |
@@ -774,7 +771,7 @@ io_subchannel_recog_done(struct ccw_device *cdev) | |||
774 | if (!get_device(&cdev->dev)) | 771 | if (!get_device(&cdev->dev)) |
775 | break; | 772 | break; |
776 | PREPARE_WORK(&cdev->private->kick_work, | 773 | PREPARE_WORK(&cdev->private->kick_work, |
777 | io_subchannel_register, (void *) cdev); | 774 | io_subchannel_register, cdev); |
778 | queue_work(slow_path_wq, &cdev->private->kick_work); | 775 | queue_work(slow_path_wq, &cdev->private->kick_work); |
779 | break; | 776 | break; |
780 | } | 777 | } |
@@ -792,9 +789,9 @@ io_subchannel_recog(struct ccw_device *cdev, struct subchannel *sch) | |||
792 | 789 | ||
793 | /* Init private data. */ | 790 | /* Init private data. */ |
794 | priv = cdev->private; | 791 | priv = cdev->private; |
795 | priv->devno = sch->schib.pmcw.dev; | 792 | priv->dev_id.devno = sch->schib.pmcw.dev; |
796 | priv->ssid = sch->schid.ssid; | 793 | priv->dev_id.ssid = sch->schid.ssid; |
797 | priv->sch_no = sch->schid.sch_no; | 794 | priv->schid = sch->schid; |
798 | priv->state = DEV_STATE_NOT_OPER; | 795 | priv->state = DEV_STATE_NOT_OPER; |
799 | INIT_LIST_HEAD(&priv->cmb_list); | 796 | INIT_LIST_HEAD(&priv->cmb_list); |
800 | init_waitqueue_head(&priv->wait_q); | 797 | init_waitqueue_head(&priv->wait_q); |
@@ -912,7 +909,7 @@ io_subchannel_remove (struct subchannel *sch) | |||
912 | */ | 909 | */ |
913 | if (get_device(&cdev->dev)) { | 910 | if (get_device(&cdev->dev)) { |
914 | PREPARE_WORK(&cdev->private->kick_work, | 911 | PREPARE_WORK(&cdev->private->kick_work, |
915 | ccw_device_unregister, (void *) cdev); | 912 | ccw_device_unregister, cdev); |
916 | queue_work(ccw_device_work, &cdev->private->kick_work); | 913 | queue_work(ccw_device_work, &cdev->private->kick_work); |
917 | } | 914 | } |
918 | return 0; | 915 | return 0; |
@@ -1055,7 +1052,7 @@ __ccwdev_check_busid(struct device *dev, void *id) | |||
1055 | { | 1052 | { |
1056 | char *bus_id; | 1053 | char *bus_id; |
1057 | 1054 | ||
1058 | bus_id = (char *)id; | 1055 | bus_id = id; |
1059 | 1056 | ||
1060 | return (strncmp(bus_id, dev->bus_id, BUS_ID_SIZE) == 0); | 1057 | return (strncmp(bus_id, dev->bus_id, BUS_ID_SIZE) == 0); |
1061 | } | 1058 | } |
diff --git a/drivers/s390/cio/device.h b/drivers/s390/cio/device.h index 00be9a5b4acd..9233b5c0bcc8 100644 --- a/drivers/s390/cio/device.h +++ b/drivers/s390/cio/device.h | |||
@@ -21,7 +21,6 @@ enum dev_state { | |||
21 | /* states to wait for i/o completion before doing something */ | 21 | /* states to wait for i/o completion before doing something */ |
22 | DEV_STATE_CLEAR_VERIFY, | 22 | DEV_STATE_CLEAR_VERIFY, |
23 | DEV_STATE_TIMEOUT_KILL, | 23 | DEV_STATE_TIMEOUT_KILL, |
24 | DEV_STATE_WAIT4IO, | ||
25 | DEV_STATE_QUIESCE, | 24 | DEV_STATE_QUIESCE, |
26 | /* special states for devices gone not operational */ | 25 | /* special states for devices gone not operational */ |
27 | DEV_STATE_DISCONNECTED, | 26 | DEV_STATE_DISCONNECTED, |
@@ -79,7 +78,6 @@ void io_subchannel_recog_done(struct ccw_device *cdev); | |||
79 | 78 | ||
80 | int ccw_device_cancel_halt_clear(struct ccw_device *); | 79 | int ccw_device_cancel_halt_clear(struct ccw_device *); |
81 | 80 | ||
82 | int ccw_device_register(struct ccw_device *); | ||
83 | void ccw_device_do_unreg_rereg(void *); | 81 | void ccw_device_do_unreg_rereg(void *); |
84 | void ccw_device_call_sch_unregister(void *); | 82 | void ccw_device_call_sch_unregister(void *); |
85 | 83 | ||
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c index b67620208f36..de3d0857db9f 100644 --- a/drivers/s390/cio/device_fsm.c +++ b/drivers/s390/cio/device_fsm.c | |||
@@ -59,18 +59,6 @@ device_set_disconnected(struct subchannel *sch) | |||
59 | cdev->private->state = DEV_STATE_DISCONNECTED; | 59 | cdev->private->state = DEV_STATE_DISCONNECTED; |
60 | } | 60 | } |
61 | 61 | ||
62 | void | ||
63 | device_set_waiting(struct subchannel *sch) | ||
64 | { | ||
65 | struct ccw_device *cdev; | ||
66 | |||
67 | if (!sch->dev.driver_data) | ||
68 | return; | ||
69 | cdev = sch->dev.driver_data; | ||
70 | ccw_device_set_timeout(cdev, 10*HZ); | ||
71 | cdev->private->state = DEV_STATE_WAIT4IO; | ||
72 | } | ||
73 | |||
74 | /* | 62 | /* |
75 | * Timeout function. It just triggers a DEV_EVENT_TIMEOUT. | 63 | * Timeout function. It just triggers a DEV_EVENT_TIMEOUT. |
76 | */ | 64 | */ |
@@ -183,9 +171,9 @@ ccw_device_handle_oper(struct ccw_device *cdev) | |||
183 | cdev->id.cu_model != cdev->private->senseid.cu_model || | 171 | cdev->id.cu_model != cdev->private->senseid.cu_model || |
184 | cdev->id.dev_type != cdev->private->senseid.dev_type || | 172 | cdev->id.dev_type != cdev->private->senseid.dev_type || |
185 | cdev->id.dev_model != cdev->private->senseid.dev_model || | 173 | cdev->id.dev_model != cdev->private->senseid.dev_model || |
186 | cdev->private->devno != sch->schib.pmcw.dev) { | 174 | cdev->private->dev_id.devno != sch->schib.pmcw.dev) { |
187 | PREPARE_WORK(&cdev->private->kick_work, | 175 | PREPARE_WORK(&cdev->private->kick_work, |
188 | ccw_device_do_unreg_rereg, (void *)cdev); | 176 | ccw_device_do_unreg_rereg, cdev); |
189 | queue_work(ccw_device_work, &cdev->private->kick_work); | 177 | queue_work(ccw_device_work, &cdev->private->kick_work); |
190 | return 0; | 178 | return 0; |
191 | } | 179 | } |
@@ -255,7 +243,7 @@ ccw_device_recog_done(struct ccw_device *cdev, int state) | |||
255 | case DEV_STATE_NOT_OPER: | 243 | case DEV_STATE_NOT_OPER: |
256 | CIO_DEBUG(KERN_WARNING, 2, | 244 | CIO_DEBUG(KERN_WARNING, 2, |
257 | "SenseID : unknown device %04x on subchannel " | 245 | "SenseID : unknown device %04x on subchannel " |
258 | "0.%x.%04x\n", cdev->private->devno, | 246 | "0.%x.%04x\n", cdev->private->dev_id.devno, |
259 | sch->schid.ssid, sch->schid.sch_no); | 247 | sch->schid.ssid, sch->schid.sch_no); |
260 | break; | 248 | break; |
261 | case DEV_STATE_OFFLINE: | 249 | case DEV_STATE_OFFLINE: |
@@ -282,14 +270,15 @@ ccw_device_recog_done(struct ccw_device *cdev, int state) | |||
282 | CIO_DEBUG(KERN_INFO, 2, "SenseID : device 0.%x.%04x reports: " | 270 | CIO_DEBUG(KERN_INFO, 2, "SenseID : device 0.%x.%04x reports: " |
283 | "CU Type/Mod = %04X/%02X, Dev Type/Mod = " | 271 | "CU Type/Mod = %04X/%02X, Dev Type/Mod = " |
284 | "%04X/%02X\n", | 272 | "%04X/%02X\n", |
285 | cdev->private->ssid, cdev->private->devno, | 273 | cdev->private->dev_id.ssid, |
274 | cdev->private->dev_id.devno, | ||
286 | cdev->id.cu_type, cdev->id.cu_model, | 275 | cdev->id.cu_type, cdev->id.cu_model, |
287 | cdev->id.dev_type, cdev->id.dev_model); | 276 | cdev->id.dev_type, cdev->id.dev_model); |
288 | break; | 277 | break; |
289 | case DEV_STATE_BOXED: | 278 | case DEV_STATE_BOXED: |
290 | CIO_DEBUG(KERN_WARNING, 2, | 279 | CIO_DEBUG(KERN_WARNING, 2, |
291 | "SenseID : boxed device %04x on subchannel " | 280 | "SenseID : boxed device %04x on subchannel " |
292 | "0.%x.%04x\n", cdev->private->devno, | 281 | "0.%x.%04x\n", cdev->private->dev_id.devno, |
293 | sch->schid.ssid, sch->schid.sch_no); | 282 | sch->schid.ssid, sch->schid.sch_no); |
294 | break; | 283 | break; |
295 | } | 284 | } |
@@ -325,13 +314,13 @@ ccw_device_oper_notify(void *data) | |||
325 | struct subchannel *sch; | 314 | struct subchannel *sch; |
326 | int ret; | 315 | int ret; |
327 | 316 | ||
328 | cdev = (struct ccw_device *)data; | 317 | cdev = data; |
329 | sch = to_subchannel(cdev->dev.parent); | 318 | sch = to_subchannel(cdev->dev.parent); |
330 | ret = (sch->driver && sch->driver->notify) ? | 319 | ret = (sch->driver && sch->driver->notify) ? |
331 | sch->driver->notify(&sch->dev, CIO_OPER) : 0; | 320 | sch->driver->notify(&sch->dev, CIO_OPER) : 0; |
332 | if (!ret) | 321 | if (!ret) |
333 | /* Driver doesn't want device back. */ | 322 | /* Driver doesn't want device back. */ |
334 | ccw_device_do_unreg_rereg((void *)cdev); | 323 | ccw_device_do_unreg_rereg(cdev); |
335 | else { | 324 | else { |
336 | /* Reenable channel measurements, if needed. */ | 325 | /* Reenable channel measurements, if needed. */ |
337 | cmf_reenable(cdev); | 326 | cmf_reenable(cdev); |
@@ -363,12 +352,12 @@ ccw_device_done(struct ccw_device *cdev, int state) | |||
363 | if (state == DEV_STATE_BOXED) | 352 | if (state == DEV_STATE_BOXED) |
364 | CIO_DEBUG(KERN_WARNING, 2, | 353 | CIO_DEBUG(KERN_WARNING, 2, |
365 | "Boxed device %04x on subchannel %04x\n", | 354 | "Boxed device %04x on subchannel %04x\n", |
366 | cdev->private->devno, sch->schid.sch_no); | 355 | cdev->private->dev_id.devno, sch->schid.sch_no); |
367 | 356 | ||
368 | if (cdev->private->flags.donotify) { | 357 | if (cdev->private->flags.donotify) { |
369 | cdev->private->flags.donotify = 0; | 358 | cdev->private->flags.donotify = 0; |
370 | PREPARE_WORK(&cdev->private->kick_work, ccw_device_oper_notify, | 359 | PREPARE_WORK(&cdev->private->kick_work, ccw_device_oper_notify, |
371 | (void *)cdev); | 360 | cdev); |
372 | queue_work(ccw_device_notify_work, &cdev->private->kick_work); | 361 | queue_work(ccw_device_notify_work, &cdev->private->kick_work); |
373 | } | 362 | } |
374 | wake_up(&cdev->private->wait_q); | 363 | wake_up(&cdev->private->wait_q); |
@@ -412,7 +401,8 @@ static void __ccw_device_get_common_pgid(struct ccw_device *cdev) | |||
412 | /* PGID mismatch, can't pathgroup. */ | 401 | /* PGID mismatch, can't pathgroup. */ |
413 | CIO_MSG_EVENT(0, "SNID - pgid mismatch for device " | 402 | CIO_MSG_EVENT(0, "SNID - pgid mismatch for device " |
414 | "0.%x.%04x, can't pathgroup\n", | 403 | "0.%x.%04x, can't pathgroup\n", |
415 | cdev->private->ssid, cdev->private->devno); | 404 | cdev->private->dev_id.ssid, |
405 | cdev->private->dev_id.devno); | ||
416 | cdev->private->options.pgroup = 0; | 406 | cdev->private->options.pgroup = 0; |
417 | return; | 407 | return; |
418 | } | 408 | } |
@@ -523,7 +513,7 @@ ccw_device_nopath_notify(void *data) | |||
523 | struct subchannel *sch; | 513 | struct subchannel *sch; |
524 | int ret; | 514 | int ret; |
525 | 515 | ||
526 | cdev = (struct ccw_device *)data; | 516 | cdev = data; |
527 | sch = to_subchannel(cdev->dev.parent); | 517 | sch = to_subchannel(cdev->dev.parent); |
528 | /* Extra sanity. */ | 518 | /* Extra sanity. */ |
529 | if (sch->lpm) | 519 | if (sch->lpm) |
@@ -537,7 +527,7 @@ ccw_device_nopath_notify(void *data) | |||
537 | if (get_device(&cdev->dev)) { | 527 | if (get_device(&cdev->dev)) { |
538 | PREPARE_WORK(&cdev->private->kick_work, | 528 | PREPARE_WORK(&cdev->private->kick_work, |
539 | ccw_device_call_sch_unregister, | 529 | ccw_device_call_sch_unregister, |
540 | (void *)cdev); | 530 | cdev); |
541 | queue_work(ccw_device_work, | 531 | queue_work(ccw_device_work, |
542 | &cdev->private->kick_work); | 532 | &cdev->private->kick_work); |
543 | } else | 533 | } else |
@@ -588,11 +578,15 @@ ccw_device_verify_done(struct ccw_device *cdev, int err) | |||
588 | } | 578 | } |
589 | break; | 579 | break; |
590 | case -ETIME: | 580 | case -ETIME: |
581 | /* Reset oper notify indication after verify error. */ | ||
582 | cdev->private->flags.donotify = 0; | ||
591 | ccw_device_done(cdev, DEV_STATE_BOXED); | 583 | ccw_device_done(cdev, DEV_STATE_BOXED); |
592 | break; | 584 | break; |
593 | default: | 585 | default: |
586 | /* Reset oper notify indication after verify error. */ | ||
587 | cdev->private->flags.donotify = 0; | ||
594 | PREPARE_WORK(&cdev->private->kick_work, | 588 | PREPARE_WORK(&cdev->private->kick_work, |
595 | ccw_device_nopath_notify, (void *)cdev); | 589 | ccw_device_nopath_notify, cdev); |
596 | queue_work(ccw_device_notify_work, &cdev->private->kick_work); | 590 | queue_work(ccw_device_notify_work, &cdev->private->kick_work); |
597 | ccw_device_done(cdev, DEV_STATE_NOT_OPER); | 591 | ccw_device_done(cdev, DEV_STATE_NOT_OPER); |
598 | break; | 592 | break; |
@@ -723,7 +717,7 @@ ccw_device_offline_notoper(struct ccw_device *cdev, enum dev_event dev_event) | |||
723 | sch = to_subchannel(cdev->dev.parent); | 717 | sch = to_subchannel(cdev->dev.parent); |
724 | if (get_device(&cdev->dev)) { | 718 | if (get_device(&cdev->dev)) { |
725 | PREPARE_WORK(&cdev->private->kick_work, | 719 | PREPARE_WORK(&cdev->private->kick_work, |
726 | ccw_device_call_sch_unregister, (void *)cdev); | 720 | ccw_device_call_sch_unregister, cdev); |
727 | queue_work(ccw_device_work, &cdev->private->kick_work); | 721 | queue_work(ccw_device_work, &cdev->private->kick_work); |
728 | } | 722 | } |
729 | wake_up(&cdev->private->wait_q); | 723 | wake_up(&cdev->private->wait_q); |
@@ -754,7 +748,7 @@ ccw_device_online_notoper(struct ccw_device *cdev, enum dev_event dev_event) | |||
754 | } | 748 | } |
755 | if (get_device(&cdev->dev)) { | 749 | if (get_device(&cdev->dev)) { |
756 | PREPARE_WORK(&cdev->private->kick_work, | 750 | PREPARE_WORK(&cdev->private->kick_work, |
757 | ccw_device_call_sch_unregister, (void *)cdev); | 751 | ccw_device_call_sch_unregister, cdev); |
758 | queue_work(ccw_device_work, &cdev->private->kick_work); | 752 | queue_work(ccw_device_work, &cdev->private->kick_work); |
759 | } | 753 | } |
760 | wake_up(&cdev->private->wait_q); | 754 | wake_up(&cdev->private->wait_q); |
@@ -859,7 +853,7 @@ ccw_device_online_timeout(struct ccw_device *cdev, enum dev_event dev_event) | |||
859 | sch = to_subchannel(cdev->dev.parent); | 853 | sch = to_subchannel(cdev->dev.parent); |
860 | if (!sch->lpm) { | 854 | if (!sch->lpm) { |
861 | PREPARE_WORK(&cdev->private->kick_work, | 855 | PREPARE_WORK(&cdev->private->kick_work, |
862 | ccw_device_nopath_notify, (void *)cdev); | 856 | ccw_device_nopath_notify, cdev); |
863 | queue_work(ccw_device_notify_work, | 857 | queue_work(ccw_device_notify_work, |
864 | &cdev->private->kick_work); | 858 | &cdev->private->kick_work); |
865 | } else | 859 | } else |
@@ -885,7 +879,8 @@ ccw_device_w4sense(struct ccw_device *cdev, enum dev_event dev_event) | |||
885 | /* Basic sense hasn't started. Try again. */ | 879 | /* Basic sense hasn't started. Try again. */ |
886 | ccw_device_do_sense(cdev, irb); | 880 | ccw_device_do_sense(cdev, irb); |
887 | else { | 881 | else { |
888 | printk("Huh? %s(%s): unsolicited interrupt...\n", | 882 | printk(KERN_INFO "Huh? %s(%s): unsolicited " |
883 | "interrupt...\n", | ||
889 | __FUNCTION__, cdev->dev.bus_id); | 884 | __FUNCTION__, cdev->dev.bus_id); |
890 | if (cdev->handler) | 885 | if (cdev->handler) |
891 | cdev->handler (cdev, 0, irb); | 886 | cdev->handler (cdev, 0, irb); |
@@ -944,10 +939,10 @@ ccw_device_killing_irq(struct ccw_device *cdev, enum dev_event dev_event) | |||
944 | cdev->private->state = DEV_STATE_ONLINE; | 939 | cdev->private->state = DEV_STATE_ONLINE; |
945 | if (cdev->handler) | 940 | if (cdev->handler) |
946 | cdev->handler(cdev, cdev->private->intparm, | 941 | cdev->handler(cdev, cdev->private->intparm, |
947 | ERR_PTR(-ETIMEDOUT)); | 942 | ERR_PTR(-EIO)); |
948 | if (!sch->lpm) { | 943 | if (!sch->lpm) { |
949 | PREPARE_WORK(&cdev->private->kick_work, | 944 | PREPARE_WORK(&cdev->private->kick_work, |
950 | ccw_device_nopath_notify, (void *)cdev); | 945 | ccw_device_nopath_notify, cdev); |
951 | queue_work(ccw_device_notify_work, &cdev->private->kick_work); | 946 | queue_work(ccw_device_notify_work, &cdev->private->kick_work); |
952 | } else if (cdev->private->flags.doverify) | 947 | } else if (cdev->private->flags.doverify) |
953 | /* Start delayed path verification. */ | 948 | /* Start delayed path verification. */ |
@@ -970,7 +965,7 @@ ccw_device_killing_timeout(struct ccw_device *cdev, enum dev_event dev_event) | |||
970 | sch = to_subchannel(cdev->dev.parent); | 965 | sch = to_subchannel(cdev->dev.parent); |
971 | if (!sch->lpm) { | 966 | if (!sch->lpm) { |
972 | PREPARE_WORK(&cdev->private->kick_work, | 967 | PREPARE_WORK(&cdev->private->kick_work, |
973 | ccw_device_nopath_notify, (void *)cdev); | 968 | ccw_device_nopath_notify, cdev); |
974 | queue_work(ccw_device_notify_work, | 969 | queue_work(ccw_device_notify_work, |
975 | &cdev->private->kick_work); | 970 | &cdev->private->kick_work); |
976 | } else | 971 | } else |
@@ -981,51 +976,15 @@ ccw_device_killing_timeout(struct ccw_device *cdev, enum dev_event dev_event) | |||
981 | cdev->private->state = DEV_STATE_ONLINE; | 976 | cdev->private->state = DEV_STATE_ONLINE; |
982 | if (cdev->handler) | 977 | if (cdev->handler) |
983 | cdev->handler(cdev, cdev->private->intparm, | 978 | cdev->handler(cdev, cdev->private->intparm, |
984 | ERR_PTR(-ETIMEDOUT)); | 979 | ERR_PTR(-EIO)); |
985 | } | ||
986 | |||
987 | static void | ||
988 | ccw_device_wait4io_irq(struct ccw_device *cdev, enum dev_event dev_event) | ||
989 | { | ||
990 | struct irb *irb; | ||
991 | struct subchannel *sch; | ||
992 | |||
993 | irb = (struct irb *) __LC_IRB; | ||
994 | /* | ||
995 | * Accumulate status and find out if a basic sense is needed. | ||
996 | * This is fine since we have already adapted the lpm. | ||
997 | */ | ||
998 | ccw_device_accumulate_irb(cdev, irb); | ||
999 | if (cdev->private->flags.dosense) { | ||
1000 | if (ccw_device_do_sense(cdev, irb) == 0) { | ||
1001 | cdev->private->state = DEV_STATE_W4SENSE; | ||
1002 | } | ||
1003 | return; | ||
1004 | } | ||
1005 | |||
1006 | /* Iff device is idle, reset timeout. */ | ||
1007 | sch = to_subchannel(cdev->dev.parent); | ||
1008 | if (!stsch(sch->schid, &sch->schib)) | ||
1009 | if (sch->schib.scsw.actl == 0) | ||
1010 | ccw_device_set_timeout(cdev, 0); | ||
1011 | /* Call the handler. */ | ||
1012 | ccw_device_call_handler(cdev); | ||
1013 | if (!sch->lpm) { | ||
1014 | PREPARE_WORK(&cdev->private->kick_work, | ||
1015 | ccw_device_nopath_notify, (void *)cdev); | ||
1016 | queue_work(ccw_device_notify_work, &cdev->private->kick_work); | ||
1017 | } else if (cdev->private->flags.doverify) | ||
1018 | ccw_device_online_verify(cdev, 0); | ||
1019 | } | 980 | } |
1020 | 981 | ||
1021 | static void | 982 | void device_kill_io(struct subchannel *sch) |
1022 | ccw_device_wait4io_timeout(struct ccw_device *cdev, enum dev_event dev_event) | ||
1023 | { | 983 | { |
1024 | int ret; | 984 | int ret; |
1025 | struct subchannel *sch; | 985 | struct ccw_device *cdev; |
1026 | 986 | ||
1027 | sch = to_subchannel(cdev->dev.parent); | 987 | cdev = sch->dev.driver_data; |
1028 | ccw_device_set_timeout(cdev, 0); | ||
1029 | ret = ccw_device_cancel_halt_clear(cdev); | 988 | ret = ccw_device_cancel_halt_clear(cdev); |
1030 | if (ret == -EBUSY) { | 989 | if (ret == -EBUSY) { |
1031 | ccw_device_set_timeout(cdev, 3*HZ); | 990 | ccw_device_set_timeout(cdev, 3*HZ); |
@@ -1035,7 +994,7 @@ ccw_device_wait4io_timeout(struct ccw_device *cdev, enum dev_event dev_event) | |||
1035 | if (ret == -ENODEV) { | 994 | if (ret == -ENODEV) { |
1036 | if (!sch->lpm) { | 995 | if (!sch->lpm) { |
1037 | PREPARE_WORK(&cdev->private->kick_work, | 996 | PREPARE_WORK(&cdev->private->kick_work, |
1038 | ccw_device_nopath_notify, (void *)cdev); | 997 | ccw_device_nopath_notify, cdev); |
1039 | queue_work(ccw_device_notify_work, | 998 | queue_work(ccw_device_notify_work, |
1040 | &cdev->private->kick_work); | 999 | &cdev->private->kick_work); |
1041 | } else | 1000 | } else |
@@ -1044,12 +1003,12 @@ ccw_device_wait4io_timeout(struct ccw_device *cdev, enum dev_event dev_event) | |||
1044 | } | 1003 | } |
1045 | if (cdev->handler) | 1004 | if (cdev->handler) |
1046 | cdev->handler(cdev, cdev->private->intparm, | 1005 | cdev->handler(cdev, cdev->private->intparm, |
1047 | ERR_PTR(-ETIMEDOUT)); | 1006 | ERR_PTR(-EIO)); |
1048 | if (!sch->lpm) { | 1007 | if (!sch->lpm) { |
1049 | PREPARE_WORK(&cdev->private->kick_work, | 1008 | PREPARE_WORK(&cdev->private->kick_work, |
1050 | ccw_device_nopath_notify, (void *)cdev); | 1009 | ccw_device_nopath_notify, cdev); |
1051 | queue_work(ccw_device_notify_work, &cdev->private->kick_work); | 1010 | queue_work(ccw_device_notify_work, &cdev->private->kick_work); |
1052 | } else if (cdev->private->flags.doverify) | 1011 | } else |
1053 | /* Start delayed path verification. */ | 1012 | /* Start delayed path verification. */ |
1054 | ccw_device_online_verify(cdev, 0); | 1013 | ccw_device_online_verify(cdev, 0); |
1055 | } | 1014 | } |
@@ -1286,12 +1245,6 @@ fsm_func_t *dev_jumptable[NR_DEV_STATES][NR_DEV_EVENTS] = { | |||
1286 | [DEV_EVENT_TIMEOUT] = ccw_device_killing_timeout, | 1245 | [DEV_EVENT_TIMEOUT] = ccw_device_killing_timeout, |
1287 | [DEV_EVENT_VERIFY] = ccw_device_nop, //FIXME | 1246 | [DEV_EVENT_VERIFY] = ccw_device_nop, //FIXME |
1288 | }, | 1247 | }, |
1289 | [DEV_STATE_WAIT4IO] = { | ||
1290 | [DEV_EVENT_NOTOPER] = ccw_device_online_notoper, | ||
1291 | [DEV_EVENT_INTERRUPT] = ccw_device_wait4io_irq, | ||
1292 | [DEV_EVENT_TIMEOUT] = ccw_device_wait4io_timeout, | ||
1293 | [DEV_EVENT_VERIFY] = ccw_device_delay_verify, | ||
1294 | }, | ||
1295 | [DEV_STATE_QUIESCE] = { | 1248 | [DEV_STATE_QUIESCE] = { |
1296 | [DEV_EVENT_NOTOPER] = ccw_device_quiesce_done, | 1249 | [DEV_EVENT_NOTOPER] = ccw_device_quiesce_done, |
1297 | [DEV_EVENT_INTERRUPT] = ccw_device_quiesce_done, | 1250 | [DEV_EVENT_INTERRUPT] = ccw_device_quiesce_done, |
diff --git a/drivers/s390/cio/device_id.c b/drivers/s390/cio/device_id.c index 1398367b5f68..a74785b9e4eb 100644 --- a/drivers/s390/cio/device_id.c +++ b/drivers/s390/cio/device_id.c | |||
@@ -251,7 +251,7 @@ ccw_device_check_sense_id(struct ccw_device *cdev) | |||
251 | */ | 251 | */ |
252 | CIO_MSG_EVENT(2, "SenseID : device %04x on Subchannel " | 252 | CIO_MSG_EVENT(2, "SenseID : device %04x on Subchannel " |
253 | "0.%x.%04x reports cmd reject\n", | 253 | "0.%x.%04x reports cmd reject\n", |
254 | cdev->private->devno, sch->schid.ssid, | 254 | cdev->private->dev_id.devno, sch->schid.ssid, |
255 | sch->schid.sch_no); | 255 | sch->schid.sch_no); |
256 | return -EOPNOTSUPP; | 256 | return -EOPNOTSUPP; |
257 | } | 257 | } |
@@ -259,7 +259,8 @@ ccw_device_check_sense_id(struct ccw_device *cdev) | |||
259 | CIO_MSG_EVENT(2, "SenseID : UC on dev 0.%x.%04x, " | 259 | CIO_MSG_EVENT(2, "SenseID : UC on dev 0.%x.%04x, " |
260 | "lpum %02X, cnt %02d, sns :" | 260 | "lpum %02X, cnt %02d, sns :" |
261 | " %02X%02X%02X%02X %02X%02X%02X%02X ...\n", | 261 | " %02X%02X%02X%02X %02X%02X%02X%02X ...\n", |
262 | cdev->private->ssid, cdev->private->devno, | 262 | cdev->private->dev_id.ssid, |
263 | cdev->private->dev_id.devno, | ||
263 | irb->esw.esw0.sublog.lpum, | 264 | irb->esw.esw0.sublog.lpum, |
264 | irb->esw.esw0.erw.scnt, | 265 | irb->esw.esw0.erw.scnt, |
265 | irb->ecw[0], irb->ecw[1], | 266 | irb->ecw[0], irb->ecw[1], |
@@ -274,14 +275,15 @@ ccw_device_check_sense_id(struct ccw_device *cdev) | |||
274 | CIO_MSG_EVENT(2, "SenseID : path %02X for device %04x " | 275 | CIO_MSG_EVENT(2, "SenseID : path %02X for device %04x " |
275 | "on subchannel 0.%x.%04x is " | 276 | "on subchannel 0.%x.%04x is " |
276 | "'not operational'\n", sch->orb.lpm, | 277 | "'not operational'\n", sch->orb.lpm, |
277 | cdev->private->devno, sch->schid.ssid, | 278 | cdev->private->dev_id.devno, |
278 | sch->schid.sch_no); | 279 | sch->schid.ssid, sch->schid.sch_no); |
279 | return -EACCES; | 280 | return -EACCES; |
280 | } | 281 | } |
281 | /* Hmm, whatever happened, try again. */ | 282 | /* Hmm, whatever happened, try again. */ |
282 | CIO_MSG_EVENT(2, "SenseID : start_IO() for device %04x on " | 283 | CIO_MSG_EVENT(2, "SenseID : start_IO() for device %04x on " |
283 | "subchannel 0.%x.%04x returns status %02X%02X\n", | 284 | "subchannel 0.%x.%04x returns status %02X%02X\n", |
284 | cdev->private->devno, sch->schid.ssid, sch->schid.sch_no, | 285 | cdev->private->dev_id.devno, sch->schid.ssid, |
286 | sch->schid.sch_no, | ||
285 | irb->scsw.dstat, irb->scsw.cstat); | 287 | irb->scsw.dstat, irb->scsw.cstat); |
286 | return -EAGAIN; | 288 | return -EAGAIN; |
287 | } | 289 | } |
@@ -330,7 +332,7 @@ ccw_device_sense_id_irq(struct ccw_device *cdev, enum dev_event dev_event) | |||
330 | /* fall through. */ | 332 | /* fall through. */ |
331 | default: /* Sense ID failed. Try asking VM. */ | 333 | default: /* Sense ID failed. Try asking VM. */ |
332 | if (MACHINE_IS_VM) { | 334 | if (MACHINE_IS_VM) { |
333 | VM_virtual_device_info (cdev->private->devno, | 335 | VM_virtual_device_info (cdev->private->dev_id.devno, |
334 | &cdev->private->senseid); | 336 | &cdev->private->senseid); |
335 | if (cdev->private->senseid.cu_type != 0xFFFF) { | 337 | if (cdev->private->senseid.cu_type != 0xFFFF) { |
336 | /* Got the device information from VM. */ | 338 | /* Got the device information from VM. */ |
diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c index 84b9b18eabc2..b39c1fa48acd 100644 --- a/drivers/s390/cio/device_ops.c +++ b/drivers/s390/cio/device_ops.c | |||
@@ -50,7 +50,6 @@ ccw_device_clear(struct ccw_device *cdev, unsigned long intparm) | |||
50 | if (cdev->private->state == DEV_STATE_NOT_OPER) | 50 | if (cdev->private->state == DEV_STATE_NOT_OPER) |
51 | return -ENODEV; | 51 | return -ENODEV; |
52 | if (cdev->private->state != DEV_STATE_ONLINE && | 52 | if (cdev->private->state != DEV_STATE_ONLINE && |
53 | cdev->private->state != DEV_STATE_WAIT4IO && | ||
54 | cdev->private->state != DEV_STATE_W4SENSE) | 53 | cdev->private->state != DEV_STATE_W4SENSE) |
55 | return -EINVAL; | 54 | return -EINVAL; |
56 | sch = to_subchannel(cdev->dev.parent); | 55 | sch = to_subchannel(cdev->dev.parent); |
@@ -155,7 +154,6 @@ ccw_device_halt(struct ccw_device *cdev, unsigned long intparm) | |||
155 | if (cdev->private->state == DEV_STATE_NOT_OPER) | 154 | if (cdev->private->state == DEV_STATE_NOT_OPER) |
156 | return -ENODEV; | 155 | return -ENODEV; |
157 | if (cdev->private->state != DEV_STATE_ONLINE && | 156 | if (cdev->private->state != DEV_STATE_ONLINE && |
158 | cdev->private->state != DEV_STATE_WAIT4IO && | ||
159 | cdev->private->state != DEV_STATE_W4SENSE) | 157 | cdev->private->state != DEV_STATE_W4SENSE) |
160 | return -EINVAL; | 158 | return -EINVAL; |
161 | sch = to_subchannel(cdev->dev.parent); | 159 | sch = to_subchannel(cdev->dev.parent); |
@@ -592,13 +590,13 @@ ccw_device_get_chp_desc(struct ccw_device *cdev, int chp_no) | |||
592 | int | 590 | int |
593 | _ccw_device_get_subchannel_number(struct ccw_device *cdev) | 591 | _ccw_device_get_subchannel_number(struct ccw_device *cdev) |
594 | { | 592 | { |
595 | return cdev->private->sch_no; | 593 | return cdev->private->schid.sch_no; |
596 | } | 594 | } |
597 | 595 | ||
598 | int | 596 | int |
599 | _ccw_device_get_device_number(struct ccw_device *cdev) | 597 | _ccw_device_get_device_number(struct ccw_device *cdev) |
600 | { | 598 | { |
601 | return cdev->private->devno; | 599 | return cdev->private->dev_id.devno; |
602 | } | 600 | } |
603 | 601 | ||
604 | 602 | ||
diff --git a/drivers/s390/cio/device_pgid.c b/drivers/s390/cio/device_pgid.c index 84917b39de45..2975ce888c19 100644 --- a/drivers/s390/cio/device_pgid.c +++ b/drivers/s390/cio/device_pgid.c | |||
@@ -79,7 +79,8 @@ __ccw_device_sense_pgid_start(struct ccw_device *cdev) | |||
79 | CIO_MSG_EVENT(2, "SNID - Device %04x on Subchannel " | 79 | CIO_MSG_EVENT(2, "SNID - Device %04x on Subchannel " |
80 | "0.%x.%04x, lpm %02X, became 'not " | 80 | "0.%x.%04x, lpm %02X, became 'not " |
81 | "operational'\n", | 81 | "operational'\n", |
82 | cdev->private->devno, sch->schid.ssid, | 82 | cdev->private->dev_id.devno, |
83 | sch->schid.ssid, | ||
83 | sch->schid.sch_no, cdev->private->imask); | 84 | sch->schid.sch_no, cdev->private->imask); |
84 | 85 | ||
85 | } | 86 | } |
@@ -135,7 +136,8 @@ __ccw_device_check_sense_pgid(struct ccw_device *cdev) | |||
135 | CIO_MSG_EVENT(2, "SNID - device 0.%x.%04x, unit check, " | 136 | CIO_MSG_EVENT(2, "SNID - device 0.%x.%04x, unit check, " |
136 | "lpum %02X, cnt %02d, sns : " | 137 | "lpum %02X, cnt %02d, sns : " |
137 | "%02X%02X%02X%02X %02X%02X%02X%02X ...\n", | 138 | "%02X%02X%02X%02X %02X%02X%02X%02X ...\n", |
138 | cdev->private->ssid, cdev->private->devno, | 139 | cdev->private->dev_id.ssid, |
140 | cdev->private->dev_id.devno, | ||
139 | irb->esw.esw0.sublog.lpum, | 141 | irb->esw.esw0.sublog.lpum, |
140 | irb->esw.esw0.erw.scnt, | 142 | irb->esw.esw0.erw.scnt, |
141 | irb->ecw[0], irb->ecw[1], | 143 | irb->ecw[0], irb->ecw[1], |
@@ -147,7 +149,7 @@ __ccw_device_check_sense_pgid(struct ccw_device *cdev) | |||
147 | if (irb->scsw.cc == 3) { | 149 | if (irb->scsw.cc == 3) { |
148 | CIO_MSG_EVENT(2, "SNID - Device %04x on Subchannel 0.%x.%04x," | 150 | CIO_MSG_EVENT(2, "SNID - Device %04x on Subchannel 0.%x.%04x," |
149 | " lpm %02X, became 'not operational'\n", | 151 | " lpm %02X, became 'not operational'\n", |
150 | cdev->private->devno, sch->schid.ssid, | 152 | cdev->private->dev_id.devno, sch->schid.ssid, |
151 | sch->schid.sch_no, sch->orb.lpm); | 153 | sch->schid.sch_no, sch->orb.lpm); |
152 | return -EACCES; | 154 | return -EACCES; |
153 | } | 155 | } |
@@ -155,7 +157,7 @@ __ccw_device_check_sense_pgid(struct ccw_device *cdev) | |||
155 | if (cdev->private->pgid[i].inf.ps.state2 == SNID_STATE2_RESVD_ELSE) { | 157 | if (cdev->private->pgid[i].inf.ps.state2 == SNID_STATE2_RESVD_ELSE) { |
156 | CIO_MSG_EVENT(2, "SNID - Device %04x on Subchannel 0.%x.%04x " | 158 | CIO_MSG_EVENT(2, "SNID - Device %04x on Subchannel 0.%x.%04x " |
157 | "is reserved by someone else\n", | 159 | "is reserved by someone else\n", |
158 | cdev->private->devno, sch->schid.ssid, | 160 | cdev->private->dev_id.devno, sch->schid.ssid, |
159 | sch->schid.sch_no); | 161 | sch->schid.sch_no); |
160 | return -EUSERS; | 162 | return -EUSERS; |
161 | } | 163 | } |
@@ -261,7 +263,7 @@ __ccw_device_do_pgid(struct ccw_device *cdev, __u8 func) | |||
261 | /* PGID command failed on this path. */ | 263 | /* PGID command failed on this path. */ |
262 | CIO_MSG_EVENT(2, "SPID - Device %04x on Subchannel " | 264 | CIO_MSG_EVENT(2, "SPID - Device %04x on Subchannel " |
263 | "0.%x.%04x, lpm %02X, became 'not operational'\n", | 265 | "0.%x.%04x, lpm %02X, became 'not operational'\n", |
264 | cdev->private->devno, sch->schid.ssid, | 266 | cdev->private->dev_id.devno, sch->schid.ssid, |
265 | sch->schid.sch_no, cdev->private->imask); | 267 | sch->schid.sch_no, cdev->private->imask); |
266 | return ret; | 268 | return ret; |
267 | } | 269 | } |
@@ -301,7 +303,7 @@ static int __ccw_device_do_nop(struct ccw_device *cdev) | |||
301 | /* nop command failed on this path. */ | 303 | /* nop command failed on this path. */ |
302 | CIO_MSG_EVENT(2, "NOP - Device %04x on Subchannel " | 304 | CIO_MSG_EVENT(2, "NOP - Device %04x on Subchannel " |
303 | "0.%x.%04x, lpm %02X, became 'not operational'\n", | 305 | "0.%x.%04x, lpm %02X, became 'not operational'\n", |
304 | cdev->private->devno, sch->schid.ssid, | 306 | cdev->private->dev_id.devno, sch->schid.ssid, |
305 | sch->schid.sch_no, cdev->private->imask); | 307 | sch->schid.sch_no, cdev->private->imask); |
306 | return ret; | 308 | return ret; |
307 | } | 309 | } |
@@ -328,8 +330,9 @@ __ccw_device_check_pgid(struct ccw_device *cdev) | |||
328 | CIO_MSG_EVENT(2, "SPID - device 0.%x.%04x, unit check, " | 330 | CIO_MSG_EVENT(2, "SPID - device 0.%x.%04x, unit check, " |
329 | "cnt %02d, " | 331 | "cnt %02d, " |
330 | "sns : %02X%02X%02X%02X %02X%02X%02X%02X ...\n", | 332 | "sns : %02X%02X%02X%02X %02X%02X%02X%02X ...\n", |
331 | cdev->private->ssid, | 333 | cdev->private->dev_id.ssid, |
332 | cdev->private->devno, irb->esw.esw0.erw.scnt, | 334 | cdev->private->dev_id.devno, |
335 | irb->esw.esw0.erw.scnt, | ||
333 | irb->ecw[0], irb->ecw[1], | 336 | irb->ecw[0], irb->ecw[1], |
334 | irb->ecw[2], irb->ecw[3], | 337 | irb->ecw[2], irb->ecw[3], |
335 | irb->ecw[4], irb->ecw[5], | 338 | irb->ecw[4], irb->ecw[5], |
@@ -339,7 +342,7 @@ __ccw_device_check_pgid(struct ccw_device *cdev) | |||
339 | if (irb->scsw.cc == 3) { | 342 | if (irb->scsw.cc == 3) { |
340 | CIO_MSG_EVENT(2, "SPID - Device %04x on Subchannel 0.%x.%04x," | 343 | CIO_MSG_EVENT(2, "SPID - Device %04x on Subchannel 0.%x.%04x," |
341 | " lpm %02X, became 'not operational'\n", | 344 | " lpm %02X, became 'not operational'\n", |
342 | cdev->private->devno, sch->schid.ssid, | 345 | cdev->private->dev_id.devno, sch->schid.ssid, |
343 | sch->schid.sch_no, cdev->private->imask); | 346 | sch->schid.sch_no, cdev->private->imask); |
344 | return -EACCES; | 347 | return -EACCES; |
345 | } | 348 | } |
@@ -362,7 +365,7 @@ static int __ccw_device_check_nop(struct ccw_device *cdev) | |||
362 | if (irb->scsw.cc == 3) { | 365 | if (irb->scsw.cc == 3) { |
363 | CIO_MSG_EVENT(2, "NOP - Device %04x on Subchannel 0.%x.%04x," | 366 | CIO_MSG_EVENT(2, "NOP - Device %04x on Subchannel 0.%x.%04x," |
364 | " lpm %02X, became 'not operational'\n", | 367 | " lpm %02X, became 'not operational'\n", |
365 | cdev->private->devno, sch->schid.ssid, | 368 | cdev->private->dev_id.devno, sch->schid.ssid, |
366 | sch->schid.sch_no, cdev->private->imask); | 369 | sch->schid.sch_no, cdev->private->imask); |
367 | return -EACCES; | 370 | return -EACCES; |
368 | } | 371 | } |
diff --git a/drivers/s390/cio/device_status.c b/drivers/s390/cio/device_status.c index caf148d5caad..3f7cbce4cd87 100644 --- a/drivers/s390/cio/device_status.c +++ b/drivers/s390/cio/device_status.c | |||
@@ -32,19 +32,18 @@ ccw_device_msg_control_check(struct ccw_device *cdev, struct irb *irb) | |||
32 | SCHN_STAT_CHN_CTRL_CHK | | 32 | SCHN_STAT_CHN_CTRL_CHK | |
33 | SCHN_STAT_INTF_CTRL_CHK))) | 33 | SCHN_STAT_INTF_CTRL_CHK))) |
34 | return; | 34 | return; |
35 | |||
36 | CIO_MSG_EVENT(0, "Channel-Check or Interface-Control-Check " | 35 | CIO_MSG_EVENT(0, "Channel-Check or Interface-Control-Check " |
37 | "received" | 36 | "received" |
38 | " ... device %04x on subchannel 0.%x.%04x, dev_stat " | 37 | " ... device %04x on subchannel 0.%x.%04x, dev_stat " |
39 | ": %02X sch_stat : %02X\n", | 38 | ": %02X sch_stat : %02X\n", |
40 | cdev->private->devno, cdev->private->ssid, | 39 | cdev->private->dev_id.devno, cdev->private->schid.ssid, |
41 | cdev->private->sch_no, | 40 | cdev->private->schid.sch_no, |
42 | irb->scsw.dstat, irb->scsw.cstat); | 41 | irb->scsw.dstat, irb->scsw.cstat); |
43 | 42 | ||
44 | if (irb->scsw.cc != 3) { | 43 | if (irb->scsw.cc != 3) { |
45 | char dbf_text[15]; | 44 | char dbf_text[15]; |
46 | 45 | ||
47 | sprintf(dbf_text, "chk%x", cdev->private->sch_no); | 46 | sprintf(dbf_text, "chk%x", cdev->private->schid.sch_no); |
48 | CIO_TRACE_EVENT(0, dbf_text); | 47 | CIO_TRACE_EVENT(0, dbf_text); |
49 | CIO_HEX_EVENT(0, irb, sizeof (struct irb)); | 48 | CIO_HEX_EVENT(0, irb, sizeof (struct irb)); |
50 | } | 49 | } |
diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c index cde822d8b5c8..476aa1da5cbc 100644 --- a/drivers/s390/cio/qdio.c +++ b/drivers/s390/cio/qdio.c | |||
@@ -1741,7 +1741,7 @@ qdio_fill_qs(struct qdio_irq *irq_ptr, struct ccw_device *cdev, | |||
1741 | void *ptr; | 1741 | void *ptr; |
1742 | int available; | 1742 | int available; |
1743 | 1743 | ||
1744 | sprintf(dbf_text,"qfqs%4x",cdev->private->sch_no); | 1744 | sprintf(dbf_text,"qfqs%4x",cdev->private->schid.sch_no); |
1745 | QDIO_DBF_TEXT0(0,setup,dbf_text); | 1745 | QDIO_DBF_TEXT0(0,setup,dbf_text); |
1746 | for (i=0;i<no_input_qs;i++) { | 1746 | for (i=0;i<no_input_qs;i++) { |
1747 | q=irq_ptr->input_qs[i]; | 1747 | q=irq_ptr->input_qs[i]; |
@@ -2924,7 +2924,7 @@ qdio_establish_handle_irq(struct ccw_device *cdev, int cstat, int dstat) | |||
2924 | 2924 | ||
2925 | irq_ptr = cdev->private->qdio_data; | 2925 | irq_ptr = cdev->private->qdio_data; |
2926 | 2926 | ||
2927 | sprintf(dbf_text,"qehi%4x",cdev->private->sch_no); | 2927 | sprintf(dbf_text,"qehi%4x",cdev->private->schid.sch_no); |
2928 | QDIO_DBF_TEXT0(0,setup,dbf_text); | 2928 | QDIO_DBF_TEXT0(0,setup,dbf_text); |
2929 | QDIO_DBF_TEXT0(0,trace,dbf_text); | 2929 | QDIO_DBF_TEXT0(0,trace,dbf_text); |
2930 | 2930 | ||
@@ -2943,7 +2943,7 @@ qdio_initialize(struct qdio_initialize *init_data) | |||
2943 | int rc; | 2943 | int rc; |
2944 | char dbf_text[15]; | 2944 | char dbf_text[15]; |
2945 | 2945 | ||
2946 | sprintf(dbf_text,"qini%4x",init_data->cdev->private->sch_no); | 2946 | sprintf(dbf_text,"qini%4x",init_data->cdev->private->schid.sch_no); |
2947 | QDIO_DBF_TEXT0(0,setup,dbf_text); | 2947 | QDIO_DBF_TEXT0(0,setup,dbf_text); |
2948 | QDIO_DBF_TEXT0(0,trace,dbf_text); | 2948 | QDIO_DBF_TEXT0(0,trace,dbf_text); |
2949 | 2949 | ||
@@ -2964,7 +2964,7 @@ qdio_allocate(struct qdio_initialize *init_data) | |||
2964 | struct qdio_irq *irq_ptr; | 2964 | struct qdio_irq *irq_ptr; |
2965 | char dbf_text[15]; | 2965 | char dbf_text[15]; |
2966 | 2966 | ||
2967 | sprintf(dbf_text,"qalc%4x",init_data->cdev->private->sch_no); | 2967 | sprintf(dbf_text,"qalc%4x",init_data->cdev->private->schid.sch_no); |
2968 | QDIO_DBF_TEXT0(0,setup,dbf_text); | 2968 | QDIO_DBF_TEXT0(0,setup,dbf_text); |
2969 | QDIO_DBF_TEXT0(0,trace,dbf_text); | 2969 | QDIO_DBF_TEXT0(0,trace,dbf_text); |
2970 | if ( (init_data->no_input_qs>QDIO_MAX_QUEUES_PER_IRQ) || | 2970 | if ( (init_data->no_input_qs>QDIO_MAX_QUEUES_PER_IRQ) || |
@@ -3187,7 +3187,7 @@ qdio_establish(struct qdio_initialize *init_data) | |||
3187 | tiqdio_set_delay_target(irq_ptr,TIQDIO_DELAY_TARGET); | 3187 | tiqdio_set_delay_target(irq_ptr,TIQDIO_DELAY_TARGET); |
3188 | } | 3188 | } |
3189 | 3189 | ||
3190 | sprintf(dbf_text,"qest%4x",cdev->private->sch_no); | 3190 | sprintf(dbf_text,"qest%4x",cdev->private->schid.sch_no); |
3191 | QDIO_DBF_TEXT0(0,setup,dbf_text); | 3191 | QDIO_DBF_TEXT0(0,setup,dbf_text); |
3192 | QDIO_DBF_TEXT0(0,trace,dbf_text); | 3192 | QDIO_DBF_TEXT0(0,trace,dbf_text); |
3193 | 3193 | ||
@@ -3529,7 +3529,7 @@ do_QDIO(struct ccw_device *cdev,unsigned int callflags, | |||
3529 | #ifdef CONFIG_QDIO_DEBUG | 3529 | #ifdef CONFIG_QDIO_DEBUG |
3530 | char dbf_text[20]; | 3530 | char dbf_text[20]; |
3531 | 3531 | ||
3532 | sprintf(dbf_text,"doQD%04x",cdev->private->sch_no); | 3532 | sprintf(dbf_text,"doQD%04x",cdev->private->schid.sch_no); |
3533 | QDIO_DBF_TEXT3(0,trace,dbf_text); | 3533 | QDIO_DBF_TEXT3(0,trace,dbf_text); |
3534 | #endif /* CONFIG_QDIO_DEBUG */ | 3534 | #endif /* CONFIG_QDIO_DEBUG */ |
3535 | 3535 | ||
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index c5ccd20b110c..79d89c368919 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c | |||
@@ -739,11 +739,16 @@ static void ap_scan_bus(void *data) | |||
739 | dev = bus_find_device(&ap_bus_type, NULL, | 739 | dev = bus_find_device(&ap_bus_type, NULL, |
740 | (void *)(unsigned long)qid, | 740 | (void *)(unsigned long)qid, |
741 | __ap_scan_bus); | 741 | __ap_scan_bus); |
742 | rc = ap_query_queue(qid, &queue_depth, &device_type); | ||
743 | if (dev && rc) { | ||
744 | put_device(dev); | ||
745 | device_unregister(dev); | ||
746 | continue; | ||
747 | } | ||
742 | if (dev) { | 748 | if (dev) { |
743 | put_device(dev); | 749 | put_device(dev); |
744 | continue; | 750 | continue; |
745 | } | 751 | } |
746 | rc = ap_query_queue(qid, &queue_depth, &device_type); | ||
747 | if (rc) | 752 | if (rc) |
748 | continue; | 753 | continue; |
749 | rc = ap_init_queue(qid); | 754 | rc = ap_init_queue(qid); |
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index 8f882690994d..74c0eac083e4 100644 --- a/drivers/s390/scsi/zfcp_def.h +++ b/drivers/s390/scsi/zfcp_def.h | |||
@@ -107,6 +107,10 @@ zfcp_address_to_sg(void *address, struct scatterlist *list) | |||
107 | (ZFCP_MAX_SBALS_PER_REQ * ZFCP_MAX_SBALES_PER_SBAL - 2) | 107 | (ZFCP_MAX_SBALS_PER_REQ * ZFCP_MAX_SBALES_PER_SBAL - 2) |
108 | /* request ID + QTCB in SBALE 0 + 1 of first SBAL in chain */ | 108 | /* request ID + QTCB in SBALE 0 + 1 of first SBAL in chain */ |
109 | 109 | ||
110 | #define ZFCP_MAX_SECTORS (ZFCP_MAX_SBALES_PER_REQ * 8) | ||
111 | /* max. number of (data buffer) SBALEs in largest SBAL chain | ||
112 | multiplied with number of sectors per 4k block */ | ||
113 | |||
110 | /* FIXME(tune): free space should be one max. SBAL chain plus what? */ | 114 | /* FIXME(tune): free space should be one max. SBAL chain plus what? */ |
111 | #define ZFCP_QDIO_PCI_INTERVAL (QDIO_MAX_BUFFERS_PER_Q \ | 115 | #define ZFCP_QDIO_PCI_INTERVAL (QDIO_MAX_BUFFERS_PER_Q \ |
112 | - (ZFCP_MAX_SBALS_PER_REQ + 4)) | 116 | - (ZFCP_MAX_SBALS_PER_REQ + 4)) |
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index 4d2bc7981324..452d96f92a14 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c | |||
@@ -58,6 +58,7 @@ struct zfcp_data zfcp_data = { | |||
58 | .cmd_per_lun = 1, | 58 | .cmd_per_lun = 1, |
59 | .use_clustering = 1, | 59 | .use_clustering = 1, |
60 | .sdev_attrs = zfcp_sysfs_sdev_attrs, | 60 | .sdev_attrs = zfcp_sysfs_sdev_attrs, |
61 | .max_sectors = ZFCP_MAX_SECTORS, | ||
61 | }, | 62 | }, |
62 | .driver_version = ZFCP_VERSION, | 63 | .driver_version = ZFCP_VERSION, |
63 | }; | 64 | }; |
diff --git a/drivers/sbus/char/bbc_envctrl.c b/drivers/sbus/char/bbc_envctrl.c index d27e4f6d7045..a54e4140683a 100644 --- a/drivers/sbus/char/bbc_envctrl.c +++ b/drivers/sbus/char/bbc_envctrl.c | |||
@@ -4,11 +4,9 @@ | |||
4 | * Copyright (C) 2001 David S. Miller (davem@redhat.com) | 4 | * Copyright (C) 2001 David S. Miller (davem@redhat.com) |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include <linux/kernel.h> | ||
8 | #include <linux/kthread.h> | 7 | #include <linux/kthread.h> |
9 | #include <linux/sched.h> | ||
10 | #include <linux/slab.h> | ||
11 | #include <linux/delay.h> | 8 | #include <linux/delay.h> |
9 | #include <linux/kmod.h> | ||
12 | #include <asm/oplib.h> | 10 | #include <asm/oplib.h> |
13 | #include <asm/ebus.h> | 11 | #include <asm/ebus.h> |
14 | 12 | ||
@@ -197,7 +195,7 @@ static void do_envctrl_shutdown(struct bbc_cpu_temperature *tp) | |||
197 | printk(KERN_CRIT "kenvctrld: Shutting down the system now.\n"); | 195 | printk(KERN_CRIT "kenvctrld: Shutting down the system now.\n"); |
198 | 196 | ||
199 | shutting_down = 1; | 197 | shutting_down = 1; |
200 | if (kernel_execve("/sbin/shutdown", argv, envp) < 0) | 198 | if (call_usermodehelper("/sbin/shutdown", argv, envp, 0) < 0) |
201 | printk(KERN_CRIT "envctrl: shutdown execution failed\n"); | 199 | printk(KERN_CRIT "envctrl: shutdown execution failed\n"); |
202 | } | 200 | } |
203 | 201 | ||
diff --git a/drivers/sbus/char/envctrl.c b/drivers/sbus/char/envctrl.c index 728a133d0fc5..fff4660cdf96 100644 --- a/drivers/sbus/char/envctrl.c +++ b/drivers/sbus/char/envctrl.c | |||
@@ -20,16 +20,12 @@ | |||
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/sched.h> | 23 | #include <linux/init.h> |
24 | #include <linux/kthread.h> | 24 | #include <linux/kthread.h> |
25 | #include <linux/errno.h> | ||
26 | #include <linux/delay.h> | 25 | #include <linux/delay.h> |
27 | #include <linux/ioport.h> | 26 | #include <linux/ioport.h> |
28 | #include <linux/init.h> | ||
29 | #include <linux/miscdevice.h> | 27 | #include <linux/miscdevice.h> |
30 | #include <linux/mm.h> | 28 | #include <linux/kmod.h> |
31 | #include <linux/slab.h> | ||
32 | #include <linux/kernel.h> | ||
33 | 29 | ||
34 | #include <asm/ebus.h> | 30 | #include <asm/ebus.h> |
35 | #include <asm/uaccess.h> | 31 | #include <asm/uaccess.h> |
@@ -980,7 +976,7 @@ static void envctrl_do_shutdown(void) | |||
980 | 976 | ||
981 | inprog = 1; | 977 | inprog = 1; |
982 | printk(KERN_CRIT "kenvctrld: WARNING: Shutting down the system now.\n"); | 978 | printk(KERN_CRIT "kenvctrld: WARNING: Shutting down the system now.\n"); |
983 | ret = kernel_execve("/sbin/shutdown", argv, envp); | 979 | ret = call_usermodehelper("/sbin/shutdown", argv, envp, 0); |
984 | if (ret < 0) { | 980 | if (ret < 0) { |
985 | printk(KERN_CRIT "kenvctrld: WARNING: system shutdown failed!\n"); | 981 | printk(KERN_CRIT "kenvctrld: WARNING: system shutdown failed!\n"); |
986 | inprog = 0; /* unlikely to succeed, but we could try again */ | 982 | inprog = 0; /* unlikely to succeed, but we could try again */ |
diff --git a/drivers/sbus/sbus.c b/drivers/sbus/sbus.c index 935952ef88f1..98fcbb3d5560 100644 --- a/drivers/sbus/sbus.c +++ b/drivers/sbus/sbus.c | |||
@@ -61,11 +61,11 @@ static void __init fill_sbus_device(struct device_node *dp, struct sbus_dev *sde | |||
61 | else | 61 | else |
62 | sdev->ofdev.dev.parent = &sdev->bus->ofdev.dev; | 62 | sdev->ofdev.dev.parent = &sdev->bus->ofdev.dev; |
63 | sdev->ofdev.dev.bus = &sbus_bus_type; | 63 | sdev->ofdev.dev.bus = &sbus_bus_type; |
64 | strcpy(sdev->ofdev.dev.bus_id, dp->path_component_name); | 64 | sprintf(sdev->ofdev.dev.bus_id, "sbus[%08x]", dp->node); |
65 | 65 | ||
66 | if (of_device_register(&sdev->ofdev) != 0) | 66 | if (of_device_register(&sdev->ofdev) != 0) |
67 | printk(KERN_DEBUG "sbus: device registration error for %s!\n", | 67 | printk(KERN_DEBUG "sbus: device registration error for %s!\n", |
68 | sdev->ofdev.dev.bus_id); | 68 | dp->path_component_name); |
69 | } | 69 | } |
70 | 70 | ||
71 | static void __init sbus_bus_ranges_init(struct device_node *dp, struct sbus_bus *sbus) | 71 | static void __init sbus_bus_ranges_init(struct device_node *dp, struct sbus_bus *sbus) |
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c index 5f8c26cd66ca..b091a0fc4eb0 100644 --- a/drivers/scsi/3w-9xxx.c +++ b/drivers/scsi/3w-9xxx.c | |||
@@ -66,6 +66,9 @@ | |||
66 | 2.26.02.006 - Fix 9550SX pchip reset timeout. | 66 | 2.26.02.006 - Fix 9550SX pchip reset timeout. |
67 | Add big endian support. | 67 | Add big endian support. |
68 | 2.26.02.007 - Disable local interrupts during kmap/unmap_atomic(). | 68 | 2.26.02.007 - Disable local interrupts during kmap/unmap_atomic(). |
69 | 2.26.02.008 - Free irq handler in __twa_shutdown(). | ||
70 | Serialize reset code. | ||
71 | Add support for 9650SE controllers. | ||
69 | */ | 72 | */ |
70 | 73 | ||
71 | #include <linux/module.h> | 74 | #include <linux/module.h> |
@@ -89,7 +92,7 @@ | |||
89 | #include "3w-9xxx.h" | 92 | #include "3w-9xxx.h" |
90 | 93 | ||
91 | /* Globals */ | 94 | /* Globals */ |
92 | #define TW_DRIVER_VERSION "2.26.02.007" | 95 | #define TW_DRIVER_VERSION "2.26.02.008" |
93 | static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT]; | 96 | static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT]; |
94 | static unsigned int twa_device_extension_count; | 97 | static unsigned int twa_device_extension_count; |
95 | static int twa_major = -1; | 98 | static int twa_major = -1; |
@@ -566,9 +569,9 @@ static int twa_check_srl(TW_Device_Extension *tw_dev, int *flashed) | |||
566 | goto out; | 569 | goto out; |
567 | } | 570 | } |
568 | 571 | ||
569 | tw_dev->working_srl = fw_on_ctlr_srl; | 572 | tw_dev->tw_compat_info.working_srl = fw_on_ctlr_srl; |
570 | tw_dev->working_branch = fw_on_ctlr_branch; | 573 | tw_dev->tw_compat_info.working_branch = fw_on_ctlr_branch; |
571 | tw_dev->working_build = fw_on_ctlr_build; | 574 | tw_dev->tw_compat_info.working_build = fw_on_ctlr_build; |
572 | 575 | ||
573 | /* Try base mode compatibility */ | 576 | /* Try base mode compatibility */ |
574 | if (!(init_connect_result & TW_CTLR_FW_COMPATIBLE)) { | 577 | if (!(init_connect_result & TW_CTLR_FW_COMPATIBLE)) { |
@@ -590,10 +593,23 @@ static int twa_check_srl(TW_Device_Extension *tw_dev, int *flashed) | |||
590 | } | 593 | } |
591 | goto out; | 594 | goto out; |
592 | } | 595 | } |
593 | tw_dev->working_srl = TW_BASE_FW_SRL; | 596 | tw_dev->tw_compat_info.working_srl = TW_BASE_FW_SRL; |
594 | tw_dev->working_branch = TW_BASE_FW_BRANCH; | 597 | tw_dev->tw_compat_info.working_branch = TW_BASE_FW_BRANCH; |
595 | tw_dev->working_build = TW_BASE_FW_BUILD; | 598 | tw_dev->tw_compat_info.working_build = TW_BASE_FW_BUILD; |
596 | } | 599 | } |
600 | |||
601 | /* Load rest of compatibility struct */ | ||
602 | strncpy(tw_dev->tw_compat_info.driver_version, TW_DRIVER_VERSION, strlen(TW_DRIVER_VERSION)); | ||
603 | tw_dev->tw_compat_info.driver_srl_high = TW_CURRENT_DRIVER_SRL; | ||
604 | tw_dev->tw_compat_info.driver_branch_high = TW_CURRENT_DRIVER_BRANCH; | ||
605 | tw_dev->tw_compat_info.driver_build_high = TW_CURRENT_DRIVER_BUILD; | ||
606 | tw_dev->tw_compat_info.driver_srl_low = TW_BASE_FW_SRL; | ||
607 | tw_dev->tw_compat_info.driver_branch_low = TW_BASE_FW_BRANCH; | ||
608 | tw_dev->tw_compat_info.driver_build_low = TW_BASE_FW_BUILD; | ||
609 | tw_dev->tw_compat_info.fw_on_ctlr_srl = fw_on_ctlr_srl; | ||
610 | tw_dev->tw_compat_info.fw_on_ctlr_branch = fw_on_ctlr_branch; | ||
611 | tw_dev->tw_compat_info.fw_on_ctlr_build = fw_on_ctlr_build; | ||
612 | |||
597 | retval = 0; | 613 | retval = 0; |
598 | out: | 614 | out: |
599 | return retval; | 615 | return retval; |
@@ -631,7 +647,7 @@ static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int | |||
631 | goto out2; | 647 | goto out2; |
632 | 648 | ||
633 | /* Check data buffer size */ | 649 | /* Check data buffer size */ |
634 | if (driver_command.buffer_length > TW_MAX_SECTORS * 512) { | 650 | if (driver_command.buffer_length > TW_MAX_SECTORS * 2048) { |
635 | retval = TW_IOCTL_ERROR_OS_EINVAL; | 651 | retval = TW_IOCTL_ERROR_OS_EINVAL; |
636 | goto out2; | 652 | goto out2; |
637 | } | 653 | } |
@@ -680,13 +696,6 @@ static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int | |||
680 | /* Now wait for command to complete */ | 696 | /* Now wait for command to complete */ |
681 | timeout = wait_event_timeout(tw_dev->ioctl_wqueue, tw_dev->chrdev_request_id == TW_IOCTL_CHRDEV_FREE, timeout); | 697 | timeout = wait_event_timeout(tw_dev->ioctl_wqueue, tw_dev->chrdev_request_id == TW_IOCTL_CHRDEV_FREE, timeout); |
682 | 698 | ||
683 | /* See if we reset while waiting for the ioctl to complete */ | ||
684 | if (test_bit(TW_IN_RESET, &tw_dev->flags)) { | ||
685 | clear_bit(TW_IN_RESET, &tw_dev->flags); | ||
686 | retval = TW_IOCTL_ERROR_OS_ERESTARTSYS; | ||
687 | goto out3; | ||
688 | } | ||
689 | |||
690 | /* We timed out, and didn't get an interrupt */ | 699 | /* We timed out, and didn't get an interrupt */ |
691 | if (tw_dev->chrdev_request_id != TW_IOCTL_CHRDEV_FREE) { | 700 | if (tw_dev->chrdev_request_id != TW_IOCTL_CHRDEV_FREE) { |
692 | /* Now we need to reset the board */ | 701 | /* Now we need to reset the board */ |
@@ -694,11 +703,6 @@ static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int | |||
694 | tw_dev->host->host_no, TW_DRIVER, 0xc, | 703 | tw_dev->host->host_no, TW_DRIVER, 0xc, |
695 | cmd); | 704 | cmd); |
696 | retval = TW_IOCTL_ERROR_OS_EIO; | 705 | retval = TW_IOCTL_ERROR_OS_EIO; |
697 | spin_lock_irqsave(tw_dev->host->host_lock, flags); | ||
698 | tw_dev->state[request_id] = TW_S_COMPLETED; | ||
699 | twa_free_request_id(tw_dev, request_id); | ||
700 | tw_dev->posted_request_count--; | ||
701 | spin_unlock_irqrestore(tw_dev->host->host_lock, flags); | ||
702 | twa_reset_device_extension(tw_dev, 1); | 706 | twa_reset_device_extension(tw_dev, 1); |
703 | goto out3; | 707 | goto out3; |
704 | } | 708 | } |
@@ -717,16 +721,7 @@ static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int | |||
717 | tw_ioctl->driver_command.status = 0; | 721 | tw_ioctl->driver_command.status = 0; |
718 | /* Copy compatiblity struct into ioctl data buffer */ | 722 | /* Copy compatiblity struct into ioctl data buffer */ |
719 | tw_compat_info = (TW_Compatibility_Info *)tw_ioctl->data_buffer; | 723 | tw_compat_info = (TW_Compatibility_Info *)tw_ioctl->data_buffer; |
720 | strncpy(tw_compat_info->driver_version, TW_DRIVER_VERSION, strlen(TW_DRIVER_VERSION)); | 724 | memcpy(tw_compat_info, &tw_dev->tw_compat_info, sizeof(TW_Compatibility_Info)); |
721 | tw_compat_info->working_srl = tw_dev->working_srl; | ||
722 | tw_compat_info->working_branch = tw_dev->working_branch; | ||
723 | tw_compat_info->working_build = tw_dev->working_build; | ||
724 | tw_compat_info->driver_srl_high = TW_CURRENT_DRIVER_SRL; | ||
725 | tw_compat_info->driver_branch_high = TW_CURRENT_DRIVER_BRANCH; | ||
726 | tw_compat_info->driver_build_high = TW_CURRENT_DRIVER_BUILD; | ||
727 | tw_compat_info->driver_srl_low = TW_BASE_FW_SRL; | ||
728 | tw_compat_info->driver_branch_low = TW_BASE_FW_BRANCH; | ||
729 | tw_compat_info->driver_build_low = TW_BASE_FW_BUILD; | ||
730 | break; | 725 | break; |
731 | case TW_IOCTL_GET_LAST_EVENT: | 726 | case TW_IOCTL_GET_LAST_EVENT: |
732 | if (tw_dev->event_queue_wrapped) { | 727 | if (tw_dev->event_queue_wrapped) { |
@@ -895,7 +890,8 @@ static int twa_decode_bits(TW_Device_Extension *tw_dev, u32 status_reg_value) | |||
895 | } | 890 | } |
896 | 891 | ||
897 | if (status_reg_value & TW_STATUS_QUEUE_ERROR) { | 892 | if (status_reg_value & TW_STATUS_QUEUE_ERROR) { |
898 | TW_PRINTK(tw_dev->host, TW_DRIVER, 0xe, "Controller Queue Error: clearing"); | 893 | if ((tw_dev->tw_pci_dev->device != PCI_DEVICE_ID_3WARE_9650SE) || (!test_bit(TW_IN_RESET, &tw_dev->flags))) |
894 | TW_PRINTK(tw_dev->host, TW_DRIVER, 0xe, "Controller Queue Error: clearing"); | ||
899 | writel(TW_CONTROL_CLEAR_QUEUE_ERROR, TW_CONTROL_REG_ADDR(tw_dev)); | 895 | writel(TW_CONTROL_CLEAR_QUEUE_ERROR, TW_CONTROL_REG_ADDR(tw_dev)); |
900 | } | 896 | } |
901 | 897 | ||
@@ -939,10 +935,12 @@ static int twa_empty_response_queue_large(TW_Device_Extension *tw_dev) | |||
939 | unsigned long before; | 935 | unsigned long before; |
940 | int retval = 1; | 936 | int retval = 1; |
941 | 937 | ||
942 | if (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9550SX) { | 938 | if ((tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9550SX) || |
939 | (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9650SE)) { | ||
943 | before = jiffies; | 940 | before = jiffies; |
944 | while ((response_que_value & TW_9550SX_DRAIN_COMPLETED) != TW_9550SX_DRAIN_COMPLETED) { | 941 | while ((response_que_value & TW_9550SX_DRAIN_COMPLETED) != TW_9550SX_DRAIN_COMPLETED) { |
945 | response_que_value = readl(TW_RESPONSE_QUEUE_REG_ADDR_LARGE(tw_dev)); | 942 | response_que_value = readl(TW_RESPONSE_QUEUE_REG_ADDR_LARGE(tw_dev)); |
943 | msleep(1); | ||
946 | if (time_after(jiffies, before + HZ * 30)) | 944 | if (time_after(jiffies, before + HZ * 30)) |
947 | goto out; | 945 | goto out; |
948 | } | 946 | } |
@@ -1214,6 +1212,10 @@ static irqreturn_t twa_interrupt(int irq, void *dev_instance) | |||
1214 | 1212 | ||
1215 | handled = 1; | 1213 | handled = 1; |
1216 | 1214 | ||
1215 | /* If we are resetting, bail */ | ||
1216 | if (test_bit(TW_IN_RESET, &tw_dev->flags)) | ||
1217 | goto twa_interrupt_bail; | ||
1218 | |||
1217 | /* Check controller for errors */ | 1219 | /* Check controller for errors */ |
1218 | if (twa_check_bits(status_reg_value)) { | 1220 | if (twa_check_bits(status_reg_value)) { |
1219 | if (twa_decode_bits(tw_dev, status_reg_value)) { | 1221 | if (twa_decode_bits(tw_dev, status_reg_value)) { |
@@ -1355,8 +1357,8 @@ static void twa_load_sgl(TW_Command_Full *full_command_packet, int request_id, d | |||
1355 | 1357 | ||
1356 | if (TW_OP_OUT(full_command_packet->command.newcommand.opcode__reserved) == TW_OP_EXECUTE_SCSI) { | 1358 | if (TW_OP_OUT(full_command_packet->command.newcommand.opcode__reserved) == TW_OP_EXECUTE_SCSI) { |
1357 | newcommand = &full_command_packet->command.newcommand; | 1359 | newcommand = &full_command_packet->command.newcommand; |
1358 | newcommand->request_id__lunl = | 1360 | newcommand->request_id__lunl = |
1359 | TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->request_id__lunl), request_id); | 1361 | cpu_to_le16(TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->request_id__lunl), request_id)); |
1360 | newcommand->sg_list[0].address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1); | 1362 | newcommand->sg_list[0].address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1); |
1361 | newcommand->sg_list[0].length = cpu_to_le32(length); | 1363 | newcommand->sg_list[0].length = cpu_to_le32(length); |
1362 | newcommand->sgl_entries__lunh = | 1364 | newcommand->sgl_entries__lunh = |
@@ -1531,6 +1533,13 @@ static int twa_post_command_packet(TW_Device_Extension *tw_dev, int request_id, | |||
1531 | int retval = 1; | 1533 | int retval = 1; |
1532 | 1534 | ||
1533 | command_que_value = tw_dev->command_packet_phys[request_id]; | 1535 | command_que_value = tw_dev->command_packet_phys[request_id]; |
1536 | |||
1537 | /* For 9650SE write low 4 bytes first */ | ||
1538 | if (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9650SE) { | ||
1539 | command_que_value += TW_COMMAND_OFFSET; | ||
1540 | writel((u32)command_que_value, TW_COMMAND_QUEUE_REG_ADDR_LARGE(tw_dev)); | ||
1541 | } | ||
1542 | |||
1534 | status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev)); | 1543 | status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev)); |
1535 | 1544 | ||
1536 | if (twa_check_bits(status_reg_value)) | 1545 | if (twa_check_bits(status_reg_value)) |
@@ -1557,13 +1566,17 @@ static int twa_post_command_packet(TW_Device_Extension *tw_dev, int request_id, | |||
1557 | TW_UNMASK_COMMAND_INTERRUPT(tw_dev); | 1566 | TW_UNMASK_COMMAND_INTERRUPT(tw_dev); |
1558 | goto out; | 1567 | goto out; |
1559 | } else { | 1568 | } else { |
1560 | /* We successfully posted the command packet */ | 1569 | if (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9650SE) { |
1561 | if (sizeof(dma_addr_t) > 4) { | 1570 | /* Now write upper 4 bytes */ |
1562 | command_que_value += TW_COMMAND_OFFSET; | 1571 | writel((u32)((u64)command_que_value >> 32), TW_COMMAND_QUEUE_REG_ADDR_LARGE(tw_dev) + 0x4); |
1563 | writel((u32)command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev)); | ||
1564 | writel((u32)((u64)command_que_value >> 32), TW_COMMAND_QUEUE_REG_ADDR(tw_dev) + 0x4); | ||
1565 | } else { | 1572 | } else { |
1566 | writel(TW_COMMAND_OFFSET + command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev)); | 1573 | if (sizeof(dma_addr_t) > 4) { |
1574 | command_que_value += TW_COMMAND_OFFSET; | ||
1575 | writel((u32)command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev)); | ||
1576 | writel((u32)((u64)command_que_value >> 32), TW_COMMAND_QUEUE_REG_ADDR(tw_dev) + 0x4); | ||
1577 | } else { | ||
1578 | writel(TW_COMMAND_OFFSET + command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev)); | ||
1579 | } | ||
1567 | } | 1580 | } |
1568 | tw_dev->state[request_id] = TW_S_POSTED; | 1581 | tw_dev->state[request_id] = TW_S_POSTED; |
1569 | tw_dev->posted_request_count++; | 1582 | tw_dev->posted_request_count++; |
@@ -1620,14 +1633,9 @@ static int twa_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_res | |||
1620 | goto out; | 1633 | goto out; |
1621 | 1634 | ||
1622 | TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev); | 1635 | TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev); |
1636 | clear_bit(TW_IN_RESET, &tw_dev->flags); | ||
1637 | tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE; | ||
1623 | 1638 | ||
1624 | /* Wake up any ioctl that was pending before the reset */ | ||
1625 | if ((tw_dev->chrdev_request_id == TW_IOCTL_CHRDEV_FREE) || (ioctl_reset)) { | ||
1626 | clear_bit(TW_IN_RESET, &tw_dev->flags); | ||
1627 | } else { | ||
1628 | tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE; | ||
1629 | wake_up(&tw_dev->ioctl_wqueue); | ||
1630 | } | ||
1631 | retval = 0; | 1639 | retval = 0; |
1632 | out: | 1640 | out: |
1633 | return retval; | 1641 | return retval; |
@@ -1736,6 +1744,9 @@ static int twa_scsi_eh_reset(struct scsi_cmnd *SCpnt) | |||
1736 | "WARNING: (0x%02X:0x%04X): Command (0x%x) timed out, resetting card.\n", | 1744 | "WARNING: (0x%02X:0x%04X): Command (0x%x) timed out, resetting card.\n", |
1737 | TW_DRIVER, 0x2c, SCpnt->cmnd[0]); | 1745 | TW_DRIVER, 0x2c, SCpnt->cmnd[0]); |
1738 | 1746 | ||
1747 | /* Make sure we are not issuing an ioctl or resetting from ioctl */ | ||
1748 | mutex_lock(&tw_dev->ioctl_lock); | ||
1749 | |||
1739 | /* Now reset the card and some of the device extension data */ | 1750 | /* Now reset the card and some of the device extension data */ |
1740 | if (twa_reset_device_extension(tw_dev, 0)) { | 1751 | if (twa_reset_device_extension(tw_dev, 0)) { |
1741 | TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2b, "Controller reset failed during scsi host reset"); | 1752 | TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2b, "Controller reset failed during scsi host reset"); |
@@ -1744,6 +1755,7 @@ static int twa_scsi_eh_reset(struct scsi_cmnd *SCpnt) | |||
1744 | 1755 | ||
1745 | retval = SUCCESS; | 1756 | retval = SUCCESS; |
1746 | out: | 1757 | out: |
1758 | mutex_unlock(&tw_dev->ioctl_lock); | ||
1747 | return retval; | 1759 | return retval; |
1748 | } /* End twa_scsi_eh_reset() */ | 1760 | } /* End twa_scsi_eh_reset() */ |
1749 | 1761 | ||
@@ -1753,8 +1765,14 @@ static int twa_scsi_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd | |||
1753 | int request_id, retval; | 1765 | int request_id, retval; |
1754 | TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata; | 1766 | TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata; |
1755 | 1767 | ||
1768 | /* If we are resetting due to timed out ioctl, report as busy */ | ||
1769 | if (test_bit(TW_IN_RESET, &tw_dev->flags)) { | ||
1770 | retval = SCSI_MLQUEUE_HOST_BUSY; | ||
1771 | goto out; | ||
1772 | } | ||
1773 | |||
1756 | /* Check if this FW supports luns */ | 1774 | /* Check if this FW supports luns */ |
1757 | if ((SCpnt->device->lun != 0) && (tw_dev->working_srl < TW_FW_SRL_LUNS_SUPPORTED)) { | 1775 | if ((SCpnt->device->lun != 0) && (tw_dev->tw_compat_info.working_srl < TW_FW_SRL_LUNS_SUPPORTED)) { |
1758 | SCpnt->result = (DID_BAD_TARGET << 16); | 1776 | SCpnt->result = (DID_BAD_TARGET << 16); |
1759 | done(SCpnt); | 1777 | done(SCpnt); |
1760 | retval = 0; | 1778 | retval = 0; |
@@ -1960,6 +1978,9 @@ static void __twa_shutdown(TW_Device_Extension *tw_dev) | |||
1960 | /* Disable interrupts */ | 1978 | /* Disable interrupts */ |
1961 | TW_DISABLE_INTERRUPTS(tw_dev); | 1979 | TW_DISABLE_INTERRUPTS(tw_dev); |
1962 | 1980 | ||
1981 | /* Free up the IRQ */ | ||
1982 | free_irq(tw_dev->tw_pci_dev->irq, tw_dev); | ||
1983 | |||
1963 | printk(KERN_WARNING "3w-9xxx: Shutting down host %d.\n", tw_dev->host->host_no); | 1984 | printk(KERN_WARNING "3w-9xxx: Shutting down host %d.\n", tw_dev->host->host_no); |
1964 | 1985 | ||
1965 | /* Tell the card we are shutting down */ | 1986 | /* Tell the card we are shutting down */ |
@@ -2091,21 +2112,25 @@ static int __devinit twa_probe(struct pci_dev *pdev, const struct pci_device_id | |||
2091 | 2112 | ||
2092 | /* Initialize the card */ | 2113 | /* Initialize the card */ |
2093 | if (twa_reset_sequence(tw_dev, 0)) | 2114 | if (twa_reset_sequence(tw_dev, 0)) |
2094 | goto out_release_mem_region; | 2115 | goto out_iounmap; |
2095 | 2116 | ||
2096 | /* Set host specific parameters */ | 2117 | /* Set host specific parameters */ |
2097 | host->max_id = TW_MAX_UNITS; | 2118 | if (pdev->device == PCI_DEVICE_ID_3WARE_9650SE) |
2119 | host->max_id = TW_MAX_UNITS_9650SE; | ||
2120 | else | ||
2121 | host->max_id = TW_MAX_UNITS; | ||
2122 | |||
2098 | host->max_cmd_len = TW_MAX_CDB_LEN; | 2123 | host->max_cmd_len = TW_MAX_CDB_LEN; |
2099 | 2124 | ||
2100 | /* Channels aren't supported by adapter */ | 2125 | /* Channels aren't supported by adapter */ |
2101 | host->max_lun = TW_MAX_LUNS(tw_dev->working_srl); | 2126 | host->max_lun = TW_MAX_LUNS(tw_dev->tw_compat_info.working_srl); |
2102 | host->max_channel = 0; | 2127 | host->max_channel = 0; |
2103 | 2128 | ||
2104 | /* Register the card with the kernel SCSI layer */ | 2129 | /* Register the card with the kernel SCSI layer */ |
2105 | retval = scsi_add_host(host, &pdev->dev); | 2130 | retval = scsi_add_host(host, &pdev->dev); |
2106 | if (retval) { | 2131 | if (retval) { |
2107 | TW_PRINTK(tw_dev->host, TW_DRIVER, 0x27, "scsi add host failed"); | 2132 | TW_PRINTK(tw_dev->host, TW_DRIVER, 0x27, "scsi add host failed"); |
2108 | goto out_release_mem_region; | 2133 | goto out_iounmap; |
2109 | } | 2134 | } |
2110 | 2135 | ||
2111 | pci_set_drvdata(pdev, host); | 2136 | pci_set_drvdata(pdev, host); |
@@ -2145,6 +2170,8 @@ static int __devinit twa_probe(struct pci_dev *pdev, const struct pci_device_id | |||
2145 | 2170 | ||
2146 | out_remove_host: | 2171 | out_remove_host: |
2147 | scsi_remove_host(host); | 2172 | scsi_remove_host(host); |
2173 | out_iounmap: | ||
2174 | iounmap(tw_dev->base_addr); | ||
2148 | out_release_mem_region: | 2175 | out_release_mem_region: |
2149 | pci_release_regions(pdev); | 2176 | pci_release_regions(pdev); |
2150 | out_free_device_extension: | 2177 | out_free_device_extension: |
@@ -2170,12 +2197,12 @@ static void twa_remove(struct pci_dev *pdev) | |||
2170 | twa_major = -1; | 2197 | twa_major = -1; |
2171 | } | 2198 | } |
2172 | 2199 | ||
2173 | /* Free up the IRQ */ | ||
2174 | free_irq(tw_dev->tw_pci_dev->irq, tw_dev); | ||
2175 | |||
2176 | /* Shutdown the card */ | 2200 | /* Shutdown the card */ |
2177 | __twa_shutdown(tw_dev); | 2201 | __twa_shutdown(tw_dev); |
2178 | 2202 | ||
2203 | /* Free IO remapping */ | ||
2204 | iounmap(tw_dev->base_addr); | ||
2205 | |||
2179 | /* Free up the mem region */ | 2206 | /* Free up the mem region */ |
2180 | pci_release_regions(pdev); | 2207 | pci_release_regions(pdev); |
2181 | 2208 | ||
@@ -2193,6 +2220,8 @@ static struct pci_device_id twa_pci_tbl[] __devinitdata = { | |||
2193 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 2220 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
2194 | { PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_9550SX, | 2221 | { PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_9550SX, |
2195 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 2222 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
2223 | { PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_9650SE, | ||
2224 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | ||
2196 | { } | 2225 | { } |
2197 | }; | 2226 | }; |
2198 | MODULE_DEVICE_TABLE(pci, twa_pci_tbl); | 2227 | MODULE_DEVICE_TABLE(pci, twa_pci_tbl); |
diff --git a/drivers/scsi/3w-9xxx.h b/drivers/scsi/3w-9xxx.h index e5685be96f45..7901517d4513 100644 --- a/drivers/scsi/3w-9xxx.h +++ b/drivers/scsi/3w-9xxx.h | |||
@@ -289,7 +289,6 @@ static twa_message_type twa_error_table[] = { | |||
289 | #define TW_STATUS_VALID_INTERRUPT 0x00DF0000 | 289 | #define TW_STATUS_VALID_INTERRUPT 0x00DF0000 |
290 | 290 | ||
291 | /* PCI related defines */ | 291 | /* PCI related defines */ |
292 | #define TW_NUMDEVICES 1 | ||
293 | #define TW_PCI_CLEAR_PARITY_ERRORS 0xc100 | 292 | #define TW_PCI_CLEAR_PARITY_ERRORS 0xc100 |
294 | #define TW_PCI_CLEAR_PCI_ABORT 0x2000 | 293 | #define TW_PCI_CLEAR_PCI_ABORT 0x2000 |
295 | 294 | ||
@@ -335,6 +334,7 @@ static twa_message_type twa_error_table[] = { | |||
335 | #define TW_ALIGNMENT_9000 4 /* 4 bytes */ | 334 | #define TW_ALIGNMENT_9000 4 /* 4 bytes */ |
336 | #define TW_ALIGNMENT_9000_SGL 0x3 | 335 | #define TW_ALIGNMENT_9000_SGL 0x3 |
337 | #define TW_MAX_UNITS 16 | 336 | #define TW_MAX_UNITS 16 |
337 | #define TW_MAX_UNITS_9650SE 32 | ||
338 | #define TW_INIT_MESSAGE_CREDITS 0x100 | 338 | #define TW_INIT_MESSAGE_CREDITS 0x100 |
339 | #define TW_INIT_COMMAND_PACKET_SIZE 0x3 | 339 | #define TW_INIT_COMMAND_PACKET_SIZE 0x3 |
340 | #define TW_INIT_COMMAND_PACKET_SIZE_EXTENDED 0x6 | 340 | #define TW_INIT_COMMAND_PACKET_SIZE_EXTENDED 0x6 |
@@ -354,7 +354,6 @@ static twa_message_type twa_error_table[] = { | |||
354 | #define TW_MAX_RESPONSE_DRAIN 256 | 354 | #define TW_MAX_RESPONSE_DRAIN 256 |
355 | #define TW_MAX_AEN_DRAIN 40 | 355 | #define TW_MAX_AEN_DRAIN 40 |
356 | #define TW_IN_RESET 2 | 356 | #define TW_IN_RESET 2 |
357 | #define TW_IN_CHRDEV_IOCTL 3 | ||
358 | #define TW_IN_ATTENTION_LOOP 4 | 357 | #define TW_IN_ATTENTION_LOOP 4 |
359 | #define TW_MAX_SECTORS 256 | 358 | #define TW_MAX_SECTORS 256 |
360 | #define TW_AEN_WAIT_TIME 1000 | 359 | #define TW_AEN_WAIT_TIME 1000 |
@@ -417,6 +416,9 @@ static twa_message_type twa_error_table[] = { | |||
417 | #ifndef PCI_DEVICE_ID_3WARE_9550SX | 416 | #ifndef PCI_DEVICE_ID_3WARE_9550SX |
418 | #define PCI_DEVICE_ID_3WARE_9550SX 0x1003 | 417 | #define PCI_DEVICE_ID_3WARE_9550SX 0x1003 |
419 | #endif | 418 | #endif |
419 | #ifndef PCI_DEVICE_ID_3WARE_9650SE | ||
420 | #define PCI_DEVICE_ID_3WARE_9650SE 0x1004 | ||
421 | #endif | ||
420 | 422 | ||
421 | /* Bitmask macros to eliminate bitfields */ | 423 | /* Bitmask macros to eliminate bitfields */ |
422 | 424 | ||
@@ -442,6 +444,7 @@ static twa_message_type twa_error_table[] = { | |||
442 | #define TW_CONTROL_REG_ADDR(x) (x->base_addr) | 444 | #define TW_CONTROL_REG_ADDR(x) (x->base_addr) |
443 | #define TW_STATUS_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + 0x4) | 445 | #define TW_STATUS_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + 0x4) |
444 | #define TW_COMMAND_QUEUE_REG_ADDR(x) (sizeof(dma_addr_t) > 4 ? ((unsigned char __iomem *)x->base_addr + 0x20) : ((unsigned char __iomem *)x->base_addr + 0x8)) | 446 | #define TW_COMMAND_QUEUE_REG_ADDR(x) (sizeof(dma_addr_t) > 4 ? ((unsigned char __iomem *)x->base_addr + 0x20) : ((unsigned char __iomem *)x->base_addr + 0x8)) |
447 | #define TW_COMMAND_QUEUE_REG_ADDR_LARGE(x) ((unsigned char __iomem *)x->base_addr + 0x20) | ||
445 | #define TW_RESPONSE_QUEUE_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + 0xC) | 448 | #define TW_RESPONSE_QUEUE_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + 0xC) |
446 | #define TW_RESPONSE_QUEUE_REG_ADDR_LARGE(x) ((unsigned char __iomem *)x->base_addr + 0x30) | 449 | #define TW_RESPONSE_QUEUE_REG_ADDR_LARGE(x) ((unsigned char __iomem *)x->base_addr + 0x30) |
447 | #define TW_CLEAR_ALL_INTERRUPTS(x) (writel(TW_STATUS_VALID_INTERRUPT, TW_CONTROL_REG_ADDR(x))) | 450 | #define TW_CLEAR_ALL_INTERRUPTS(x) (writel(TW_STATUS_VALID_INTERRUPT, TW_CONTROL_REG_ADDR(x))) |
@@ -626,6 +629,9 @@ typedef struct TAG_TW_Compatibility_Info | |||
626 | unsigned short driver_srl_low; | 629 | unsigned short driver_srl_low; |
627 | unsigned short driver_branch_low; | 630 | unsigned short driver_branch_low; |
628 | unsigned short driver_build_low; | 631 | unsigned short driver_build_low; |
632 | unsigned short fw_on_ctlr_srl; | ||
633 | unsigned short fw_on_ctlr_branch; | ||
634 | unsigned short fw_on_ctlr_build; | ||
629 | } TW_Compatibility_Info; | 635 | } TW_Compatibility_Info; |
630 | 636 | ||
631 | #pragma pack() | 637 | #pragma pack() |
@@ -668,9 +674,7 @@ typedef struct TAG_TW_Device_Extension { | |||
668 | wait_queue_head_t ioctl_wqueue; | 674 | wait_queue_head_t ioctl_wqueue; |
669 | struct mutex ioctl_lock; | 675 | struct mutex ioctl_lock; |
670 | char aen_clobber; | 676 | char aen_clobber; |
671 | unsigned short working_srl; | 677 | TW_Compatibility_Info tw_compat_info; |
672 | unsigned short working_branch; | ||
673 | unsigned short working_build; | ||
674 | } TW_Device_Extension; | 678 | } TW_Device_Extension; |
675 | 679 | ||
676 | #endif /* _3W_9XXX_H */ | 680 | #endif /* _3W_9XXX_H */ |
diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c index 689dc4cc789c..3075204915c8 100644 --- a/drivers/scsi/BusLogic.c +++ b/drivers/scsi/BusLogic.c | |||
@@ -3600,5 +3600,16 @@ static void __exit BusLogic_exit(void) | |||
3600 | 3600 | ||
3601 | __setup("BusLogic=", BusLogic_Setup); | 3601 | __setup("BusLogic=", BusLogic_Setup); |
3602 | 3602 | ||
3603 | static struct pci_device_id BusLogic_pci_tbl[] __devinitdata = { | ||
3604 | { PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER, | ||
3605 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | ||
3606 | { PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC, | ||
3607 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | ||
3608 | { PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT, | ||
3609 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | ||
3610 | { } | ||
3611 | }; | ||
3612 | MODULE_DEVICE_TABLE(pci, BusLogic_pci_tbl); | ||
3613 | |||
3603 | module_init(BusLogic_init); | 3614 | module_init(BusLogic_init); |
3604 | module_exit(BusLogic_exit); | 3615 | module_exit(BusLogic_exit); |
diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c index a0d1cee0be77..306f46b85a55 100644 --- a/drivers/scsi/aha152x.c +++ b/drivers/scsi/aha152x.c | |||
@@ -238,7 +238,7 @@ | |||
238 | #include <linux/module.h> | 238 | #include <linux/module.h> |
239 | #include <linux/sched.h> | 239 | #include <linux/sched.h> |
240 | #include <asm/irq.h> | 240 | #include <asm/irq.h> |
241 | #include <asm/io.h> | 241 | #include <linux/io.h> |
242 | #include <linux/blkdev.h> | 242 | #include <linux/blkdev.h> |
243 | #include <asm/system.h> | 243 | #include <asm/system.h> |
244 | #include <linux/errno.h> | 244 | #include <linux/errno.h> |
diff --git a/drivers/scsi/aic7xxx/aic79xx.h b/drivers/scsi/aic7xxx/aic79xx.h index df3346b5caf8..170a4344cbb2 100644 --- a/drivers/scsi/aic7xxx/aic79xx.h +++ b/drivers/scsi/aic7xxx/aic79xx.h | |||
@@ -53,14 +53,6 @@ struct ahd_platform_data; | |||
53 | struct scb_platform_data; | 53 | struct scb_platform_data; |
54 | 54 | ||
55 | /****************************** Useful Macros *********************************/ | 55 | /****************************** Useful Macros *********************************/ |
56 | #ifndef MAX | ||
57 | #define MAX(a,b) (((a) > (b)) ? (a) : (b)) | ||
58 | #endif | ||
59 | |||
60 | #ifndef MIN | ||
61 | #define MIN(a,b) (((a) < (b)) ? (a) : (b)) | ||
62 | #endif | ||
63 | |||
64 | #ifndef TRUE | 56 | #ifndef TRUE |
65 | #define TRUE 1 | 57 | #define TRUE 1 |
66 | #endif | 58 | #endif |
@@ -972,8 +964,6 @@ int ahd_read_seeprom(struct ahd_softc *ahd, uint16_t *buf, | |||
972 | 964 | ||
973 | int ahd_write_seeprom(struct ahd_softc *ahd, uint16_t *buf, | 965 | int ahd_write_seeprom(struct ahd_softc *ahd, uint16_t *buf, |
974 | u_int start_addr, u_int count); | 966 | u_int start_addr, u_int count); |
975 | int ahd_wait_seeprom(struct ahd_softc *ahd); | ||
976 | int ahd_verify_vpd_cksum(struct vpd_config *vpd); | ||
977 | int ahd_verify_cksum(struct seeprom_config *sc); | 967 | int ahd_verify_cksum(struct seeprom_config *sc); |
978 | int ahd_acquire_seeprom(struct ahd_softc *ahd); | 968 | int ahd_acquire_seeprom(struct ahd_softc *ahd); |
979 | void ahd_release_seeprom(struct ahd_softc *ahd); | 969 | void ahd_release_seeprom(struct ahd_softc *ahd); |
@@ -1320,8 +1310,6 @@ struct ahd_pci_identity { | |||
1320 | char *name; | 1310 | char *name; |
1321 | ahd_device_setup_t *setup; | 1311 | ahd_device_setup_t *setup; |
1322 | }; | 1312 | }; |
1323 | extern struct ahd_pci_identity ahd_pci_ident_table []; | ||
1324 | extern const u_int ahd_num_pci_devs; | ||
1325 | 1313 | ||
1326 | /***************************** VL/EISA Declarations ***************************/ | 1314 | /***************************** VL/EISA Declarations ***************************/ |
1327 | struct aic7770_identity { | 1315 | struct aic7770_identity { |
@@ -1339,15 +1327,6 @@ extern const int ahd_num_aic7770_devs; | |||
1339 | /*************************** Function Declarations ****************************/ | 1327 | /*************************** Function Declarations ****************************/ |
1340 | /******************************************************************************/ | 1328 | /******************************************************************************/ |
1341 | void ahd_reset_cmds_pending(struct ahd_softc *ahd); | 1329 | void ahd_reset_cmds_pending(struct ahd_softc *ahd); |
1342 | u_int ahd_find_busy_tcl(struct ahd_softc *ahd, u_int tcl); | ||
1343 | void ahd_busy_tcl(struct ahd_softc *ahd, | ||
1344 | u_int tcl, u_int busyid); | ||
1345 | static __inline void ahd_unbusy_tcl(struct ahd_softc *ahd, u_int tcl); | ||
1346 | static __inline void | ||
1347 | ahd_unbusy_tcl(struct ahd_softc *ahd, u_int tcl) | ||
1348 | { | ||
1349 | ahd_busy_tcl(ahd, tcl, SCB_LIST_NULL); | ||
1350 | } | ||
1351 | 1330 | ||
1352 | /***************************** PCI Front End *********************************/ | 1331 | /***************************** PCI Front End *********************************/ |
1353 | struct ahd_pci_identity *ahd_find_pci_device(ahd_dev_softc_t); | 1332 | struct ahd_pci_identity *ahd_find_pci_device(ahd_dev_softc_t); |
@@ -1356,7 +1335,6 @@ int ahd_pci_config(struct ahd_softc *, | |||
1356 | int ahd_pci_test_register_access(struct ahd_softc *); | 1335 | int ahd_pci_test_register_access(struct ahd_softc *); |
1357 | 1336 | ||
1358 | /************************** SCB and SCB queue management **********************/ | 1337 | /************************** SCB and SCB queue management **********************/ |
1359 | int ahd_probe_scbs(struct ahd_softc *); | ||
1360 | void ahd_qinfifo_requeue_tail(struct ahd_softc *ahd, | 1338 | void ahd_qinfifo_requeue_tail(struct ahd_softc *ahd, |
1361 | struct scb *scb); | 1339 | struct scb *scb); |
1362 | int ahd_match_scb(struct ahd_softc *ahd, struct scb *scb, | 1340 | int ahd_match_scb(struct ahd_softc *ahd, struct scb *scb, |
@@ -1374,33 +1352,20 @@ int ahd_parse_vpddata(struct ahd_softc *ahd, | |||
1374 | int ahd_parse_cfgdata(struct ahd_softc *ahd, | 1352 | int ahd_parse_cfgdata(struct ahd_softc *ahd, |
1375 | struct seeprom_config *sc); | 1353 | struct seeprom_config *sc); |
1376 | void ahd_intr_enable(struct ahd_softc *ahd, int enable); | 1354 | void ahd_intr_enable(struct ahd_softc *ahd, int enable); |
1377 | void ahd_update_coalescing_values(struct ahd_softc *ahd, | ||
1378 | u_int timer, | ||
1379 | u_int maxcmds, | ||
1380 | u_int mincmds); | ||
1381 | void ahd_enable_coalescing(struct ahd_softc *ahd, | ||
1382 | int enable); | ||
1383 | void ahd_pause_and_flushwork(struct ahd_softc *ahd); | 1355 | void ahd_pause_and_flushwork(struct ahd_softc *ahd); |
1384 | int ahd_suspend(struct ahd_softc *ahd); | 1356 | int ahd_suspend(struct ahd_softc *ahd); |
1385 | int ahd_resume(struct ahd_softc *ahd); | ||
1386 | void ahd_set_unit(struct ahd_softc *, int); | 1357 | void ahd_set_unit(struct ahd_softc *, int); |
1387 | void ahd_set_name(struct ahd_softc *, char *); | 1358 | void ahd_set_name(struct ahd_softc *, char *); |
1388 | struct scb *ahd_get_scb(struct ahd_softc *ahd, u_int col_idx); | 1359 | struct scb *ahd_get_scb(struct ahd_softc *ahd, u_int col_idx); |
1389 | void ahd_free_scb(struct ahd_softc *ahd, struct scb *scb); | 1360 | void ahd_free_scb(struct ahd_softc *ahd, struct scb *scb); |
1390 | void ahd_alloc_scbs(struct ahd_softc *ahd); | ||
1391 | void ahd_free(struct ahd_softc *ahd); | 1361 | void ahd_free(struct ahd_softc *ahd); |
1392 | int ahd_reset(struct ahd_softc *ahd, int reinit); | 1362 | int ahd_reset(struct ahd_softc *ahd, int reinit); |
1393 | void ahd_shutdown(void *arg); | ||
1394 | int ahd_write_flexport(struct ahd_softc *ahd, | 1363 | int ahd_write_flexport(struct ahd_softc *ahd, |
1395 | u_int addr, u_int value); | 1364 | u_int addr, u_int value); |
1396 | int ahd_read_flexport(struct ahd_softc *ahd, u_int addr, | 1365 | int ahd_read_flexport(struct ahd_softc *ahd, u_int addr, |
1397 | uint8_t *value); | 1366 | uint8_t *value); |
1398 | int ahd_wait_flexport(struct ahd_softc *ahd); | ||
1399 | 1367 | ||
1400 | /*************************** Interrupt Services *******************************/ | 1368 | /*************************** Interrupt Services *******************************/ |
1401 | void ahd_pci_intr(struct ahd_softc *ahd); | ||
1402 | void ahd_clear_intstat(struct ahd_softc *ahd); | ||
1403 | void ahd_flush_qoutfifo(struct ahd_softc *ahd); | ||
1404 | void ahd_run_qoutfifo(struct ahd_softc *ahd); | 1369 | void ahd_run_qoutfifo(struct ahd_softc *ahd); |
1405 | #ifdef AHD_TARGET_MODE | 1370 | #ifdef AHD_TARGET_MODE |
1406 | void ahd_run_tqinfifo(struct ahd_softc *ahd, int paused); | 1371 | void ahd_run_tqinfifo(struct ahd_softc *ahd, int paused); |
@@ -1409,7 +1374,6 @@ void ahd_handle_hwerrint(struct ahd_softc *ahd); | |||
1409 | void ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat); | 1374 | void ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat); |
1410 | void ahd_handle_scsiint(struct ahd_softc *ahd, | 1375 | void ahd_handle_scsiint(struct ahd_softc *ahd, |
1411 | u_int intstat); | 1376 | u_int intstat); |
1412 | void ahd_clear_critical_section(struct ahd_softc *ahd); | ||
1413 | 1377 | ||
1414 | /***************************** Error Recovery *********************************/ | 1378 | /***************************** Error Recovery *********************************/ |
1415 | typedef enum { | 1379 | typedef enum { |
@@ -1426,23 +1390,9 @@ int ahd_search_disc_list(struct ahd_softc *ahd, int target, | |||
1426 | char channel, int lun, u_int tag, | 1390 | char channel, int lun, u_int tag, |
1427 | int stop_on_first, int remove, | 1391 | int stop_on_first, int remove, |
1428 | int save_state); | 1392 | int save_state); |
1429 | void ahd_freeze_devq(struct ahd_softc *ahd, struct scb *scb); | ||
1430 | int ahd_reset_channel(struct ahd_softc *ahd, char channel, | 1393 | int ahd_reset_channel(struct ahd_softc *ahd, char channel, |
1431 | int initiate_reset); | 1394 | int initiate_reset); |
1432 | int ahd_abort_scbs(struct ahd_softc *ahd, int target, | ||
1433 | char channel, int lun, u_int tag, | ||
1434 | role_t role, uint32_t status); | ||
1435 | void ahd_restart(struct ahd_softc *ahd); | ||
1436 | void ahd_clear_fifo(struct ahd_softc *ahd, u_int fifo); | ||
1437 | void ahd_handle_scb_status(struct ahd_softc *ahd, | ||
1438 | struct scb *scb); | ||
1439 | void ahd_handle_scsi_status(struct ahd_softc *ahd, | ||
1440 | struct scb *scb); | ||
1441 | void ahd_calc_residual(struct ahd_softc *ahd, | ||
1442 | struct scb *scb); | ||
1443 | /*************************** Utility Functions ********************************/ | 1395 | /*************************** Utility Functions ********************************/ |
1444 | struct ahd_phase_table_entry* | ||
1445 | ahd_lookup_phase_entry(int phase); | ||
1446 | void ahd_compile_devinfo(struct ahd_devinfo *devinfo, | 1396 | void ahd_compile_devinfo(struct ahd_devinfo *devinfo, |
1447 | u_int our_id, u_int target, | 1397 | u_int our_id, u_int target, |
1448 | u_int lun, char channel, | 1398 | u_int lun, char channel, |
@@ -1450,14 +1400,6 @@ void ahd_compile_devinfo(struct ahd_devinfo *devinfo, | |||
1450 | /************************** Transfer Negotiation ******************************/ | 1400 | /************************** Transfer Negotiation ******************************/ |
1451 | void ahd_find_syncrate(struct ahd_softc *ahd, u_int *period, | 1401 | void ahd_find_syncrate(struct ahd_softc *ahd, u_int *period, |
1452 | u_int *ppr_options, u_int maxsync); | 1402 | u_int *ppr_options, u_int maxsync); |
1453 | void ahd_validate_offset(struct ahd_softc *ahd, | ||
1454 | struct ahd_initiator_tinfo *tinfo, | ||
1455 | u_int period, u_int *offset, | ||
1456 | int wide, role_t role); | ||
1457 | void ahd_validate_width(struct ahd_softc *ahd, | ||
1458 | struct ahd_initiator_tinfo *tinfo, | ||
1459 | u_int *bus_width, | ||
1460 | role_t role); | ||
1461 | /* | 1403 | /* |
1462 | * Negotiation types. These are used to qualify if we should renegotiate | 1404 | * Negotiation types. These are used to qualify if we should renegotiate |
1463 | * even if our goal and current transport parameters are identical. | 1405 | * even if our goal and current transport parameters are identical. |
@@ -1486,11 +1428,6 @@ typedef enum { | |||
1486 | AHD_QUEUE_TAGGED | 1428 | AHD_QUEUE_TAGGED |
1487 | } ahd_queue_alg; | 1429 | } ahd_queue_alg; |
1488 | 1430 | ||
1489 | void ahd_set_tags(struct ahd_softc *ahd, | ||
1490 | struct scsi_cmnd *cmd, | ||
1491 | struct ahd_devinfo *devinfo, | ||
1492 | ahd_queue_alg alg); | ||
1493 | |||
1494 | /**************************** Target Mode *************************************/ | 1431 | /**************************** Target Mode *************************************/ |
1495 | #ifdef AHD_TARGET_MODE | 1432 | #ifdef AHD_TARGET_MODE |
1496 | void ahd_send_lstate_events(struct ahd_softc *, | 1433 | void ahd_send_lstate_events(struct ahd_softc *, |
@@ -1528,10 +1465,8 @@ extern uint32_t ahd_debug; | |||
1528 | #define AHD_SHOW_INT_COALESCING 0x10000 | 1465 | #define AHD_SHOW_INT_COALESCING 0x10000 |
1529 | #define AHD_DEBUG_SEQUENCER 0x20000 | 1466 | #define AHD_DEBUG_SEQUENCER 0x20000 |
1530 | #endif | 1467 | #endif |
1531 | void ahd_print_scb(struct scb *scb); | ||
1532 | void ahd_print_devinfo(struct ahd_softc *ahd, | 1468 | void ahd_print_devinfo(struct ahd_softc *ahd, |
1533 | struct ahd_devinfo *devinfo); | 1469 | struct ahd_devinfo *devinfo); |
1534 | void ahd_dump_sglist(struct scb *scb); | ||
1535 | void ahd_dump_card_state(struct ahd_softc *ahd); | 1470 | void ahd_dump_card_state(struct ahd_softc *ahd); |
1536 | int ahd_print_register(ahd_reg_parse_entry_t *table, | 1471 | int ahd_print_register(ahd_reg_parse_entry_t *table, |
1537 | u_int num_entries, | 1472 | u_int num_entries, |
@@ -1540,5 +1475,4 @@ int ahd_print_register(ahd_reg_parse_entry_t *table, | |||
1540 | u_int value, | 1475 | u_int value, |
1541 | u_int *cur_column, | 1476 | u_int *cur_column, |
1542 | u_int wrap_point); | 1477 | u_int wrap_point); |
1543 | void ahd_dump_scbs(struct ahd_softc *ahd); | ||
1544 | #endif /* _AIC79XX_H_ */ | 1478 | #endif /* _AIC79XX_H_ */ |
diff --git a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c index 653818d2f802..07a86a30f676 100644 --- a/drivers/scsi/aic7xxx/aic79xx_core.c +++ b/drivers/scsi/aic7xxx/aic79xx_core.c | |||
@@ -52,7 +52,7 @@ | |||
52 | 52 | ||
53 | 53 | ||
54 | /***************************** Lookup Tables **********************************/ | 54 | /***************************** Lookup Tables **********************************/ |
55 | char *ahd_chip_names[] = | 55 | static char *ahd_chip_names[] = |
56 | { | 56 | { |
57 | "NONE", | 57 | "NONE", |
58 | "aic7901", | 58 | "aic7901", |
@@ -237,10 +237,33 @@ static int ahd_handle_target_cmd(struct ahd_softc *ahd, | |||
237 | struct target_cmd *cmd); | 237 | struct target_cmd *cmd); |
238 | #endif | 238 | #endif |
239 | 239 | ||
240 | static int ahd_abort_scbs(struct ahd_softc *ahd, int target, | ||
241 | char channel, int lun, u_int tag, | ||
242 | role_t role, uint32_t status); | ||
243 | static void ahd_alloc_scbs(struct ahd_softc *ahd); | ||
244 | static void ahd_busy_tcl(struct ahd_softc *ahd, u_int tcl, | ||
245 | u_int scbid); | ||
246 | static void ahd_calc_residual(struct ahd_softc *ahd, | ||
247 | struct scb *scb); | ||
248 | static void ahd_clear_critical_section(struct ahd_softc *ahd); | ||
249 | static void ahd_clear_intstat(struct ahd_softc *ahd); | ||
250 | static void ahd_enable_coalescing(struct ahd_softc *ahd, | ||
251 | int enable); | ||
252 | static u_int ahd_find_busy_tcl(struct ahd_softc *ahd, u_int tcl); | ||
253 | static void ahd_freeze_devq(struct ahd_softc *ahd, | ||
254 | struct scb *scb); | ||
255 | static void ahd_handle_scb_status(struct ahd_softc *ahd, | ||
256 | struct scb *scb); | ||
257 | static struct ahd_phase_table_entry* ahd_lookup_phase_entry(int phase); | ||
258 | static void ahd_shutdown(void *arg); | ||
259 | static void ahd_update_coalescing_values(struct ahd_softc *ahd, | ||
260 | u_int timer, | ||
261 | u_int maxcmds, | ||
262 | u_int mincmds); | ||
263 | static int ahd_verify_vpd_cksum(struct vpd_config *vpd); | ||
264 | static int ahd_wait_seeprom(struct ahd_softc *ahd); | ||
265 | |||
240 | /******************************** Private Inlines *****************************/ | 266 | /******************************** Private Inlines *****************************/ |
241 | static __inline void ahd_assert_atn(struct ahd_softc *ahd); | ||
242 | static __inline int ahd_currently_packetized(struct ahd_softc *ahd); | ||
243 | static __inline int ahd_set_active_fifo(struct ahd_softc *ahd); | ||
244 | 267 | ||
245 | static __inline void | 268 | static __inline void |
246 | ahd_assert_atn(struct ahd_softc *ahd) | 269 | ahd_assert_atn(struct ahd_softc *ahd) |
@@ -294,11 +317,44 @@ ahd_set_active_fifo(struct ahd_softc *ahd) | |||
294 | } | 317 | } |
295 | } | 318 | } |
296 | 319 | ||
320 | static __inline void | ||
321 | ahd_unbusy_tcl(struct ahd_softc *ahd, u_int tcl) | ||
322 | { | ||
323 | ahd_busy_tcl(ahd, tcl, SCB_LIST_NULL); | ||
324 | } | ||
325 | |||
326 | /* | ||
327 | * Determine whether the sequencer reported a residual | ||
328 | * for this SCB/transaction. | ||
329 | */ | ||
330 | static __inline void | ||
331 | ahd_update_residual(struct ahd_softc *ahd, struct scb *scb) | ||
332 | { | ||
333 | uint32_t sgptr; | ||
334 | |||
335 | sgptr = ahd_le32toh(scb->hscb->sgptr); | ||
336 | if ((sgptr & SG_STATUS_VALID) != 0) | ||
337 | ahd_calc_residual(ahd, scb); | ||
338 | } | ||
339 | |||
340 | static __inline void | ||
341 | ahd_complete_scb(struct ahd_softc *ahd, struct scb *scb) | ||
342 | { | ||
343 | uint32_t sgptr; | ||
344 | |||
345 | sgptr = ahd_le32toh(scb->hscb->sgptr); | ||
346 | if ((sgptr & SG_STATUS_VALID) != 0) | ||
347 | ahd_handle_scb_status(ahd, scb); | ||
348 | else | ||
349 | ahd_done(ahd, scb); | ||
350 | } | ||
351 | |||
352 | |||
297 | /************************* Sequencer Execution Control ************************/ | 353 | /************************* Sequencer Execution Control ************************/ |
298 | /* | 354 | /* |
299 | * Restart the sequencer program from address zero | 355 | * Restart the sequencer program from address zero |
300 | */ | 356 | */ |
301 | void | 357 | static void |
302 | ahd_restart(struct ahd_softc *ahd) | 358 | ahd_restart(struct ahd_softc *ahd) |
303 | { | 359 | { |
304 | 360 | ||
@@ -342,7 +398,7 @@ ahd_restart(struct ahd_softc *ahd) | |||
342 | ahd_unpause(ahd); | 398 | ahd_unpause(ahd); |
343 | } | 399 | } |
344 | 400 | ||
345 | void | 401 | static void |
346 | ahd_clear_fifo(struct ahd_softc *ahd, u_int fifo) | 402 | ahd_clear_fifo(struct ahd_softc *ahd, u_int fifo) |
347 | { | 403 | { |
348 | ahd_mode_state saved_modes; | 404 | ahd_mode_state saved_modes; |
@@ -366,7 +422,7 @@ ahd_clear_fifo(struct ahd_softc *ahd, u_int fifo) | |||
366 | * Flush and completed commands that are sitting in the command | 422 | * Flush and completed commands that are sitting in the command |
367 | * complete queues down on the chip but have yet to be dma'ed back up. | 423 | * complete queues down on the chip but have yet to be dma'ed back up. |
368 | */ | 424 | */ |
369 | void | 425 | static void |
370 | ahd_flush_qoutfifo(struct ahd_softc *ahd) | 426 | ahd_flush_qoutfifo(struct ahd_softc *ahd) |
371 | { | 427 | { |
372 | struct scb *scb; | 428 | struct scb *scb; |
@@ -905,6 +961,51 @@ ahd_handle_hwerrint(struct ahd_softc *ahd) | |||
905 | ahd_free(ahd); | 961 | ahd_free(ahd); |
906 | } | 962 | } |
907 | 963 | ||
964 | #ifdef AHD_DEBUG | ||
965 | static void | ||
966 | ahd_dump_sglist(struct scb *scb) | ||
967 | { | ||
968 | int i; | ||
969 | |||
970 | if (scb->sg_count > 0) { | ||
971 | if ((scb->ahd_softc->flags & AHD_64BIT_ADDRESSING) != 0) { | ||
972 | struct ahd_dma64_seg *sg_list; | ||
973 | |||
974 | sg_list = (struct ahd_dma64_seg*)scb->sg_list; | ||
975 | for (i = 0; i < scb->sg_count; i++) { | ||
976 | uint64_t addr; | ||
977 | uint32_t len; | ||
978 | |||
979 | addr = ahd_le64toh(sg_list[i].addr); | ||
980 | len = ahd_le32toh(sg_list[i].len); | ||
981 | printf("sg[%d] - Addr 0x%x%x : Length %d%s\n", | ||
982 | i, | ||
983 | (uint32_t)((addr >> 32) & 0xFFFFFFFF), | ||
984 | (uint32_t)(addr & 0xFFFFFFFF), | ||
985 | sg_list[i].len & AHD_SG_LEN_MASK, | ||
986 | (sg_list[i].len & AHD_DMA_LAST_SEG) | ||
987 | ? " Last" : ""); | ||
988 | } | ||
989 | } else { | ||
990 | struct ahd_dma_seg *sg_list; | ||
991 | |||
992 | sg_list = (struct ahd_dma_seg*)scb->sg_list; | ||
993 | for (i = 0; i < scb->sg_count; i++) { | ||
994 | uint32_t len; | ||
995 | |||
996 | len = ahd_le32toh(sg_list[i].len); | ||
997 | printf("sg[%d] - Addr 0x%x%x : Length %d%s\n", | ||
998 | i, | ||
999 | (len & AHD_SG_HIGH_ADDR_MASK) >> 24, | ||
1000 | ahd_le32toh(sg_list[i].addr), | ||
1001 | len & AHD_SG_LEN_MASK, | ||
1002 | len & AHD_DMA_LAST_SEG ? " Last" : ""); | ||
1003 | } | ||
1004 | } | ||
1005 | } | ||
1006 | } | ||
1007 | #endif /* AHD_DEBUG */ | ||
1008 | |||
908 | void | 1009 | void |
909 | ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat) | 1010 | ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat) |
910 | { | 1011 | { |
@@ -1053,10 +1154,12 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat) | |||
1053 | * If a target takes us into the command phase | 1154 | * If a target takes us into the command phase |
1054 | * assume that it has been externally reset and | 1155 | * assume that it has been externally reset and |
1055 | * has thus lost our previous packetized negotiation | 1156 | * has thus lost our previous packetized negotiation |
1056 | * agreement. | 1157 | * agreement. Since we have not sent an identify |
1057 | * Revert to async/narrow transfers until we | 1158 | * message and may not have fully qualified the |
1058 | * can renegotiate with the device and notify | 1159 | * connection, we change our command to TUR, assert |
1059 | * the OSM about the reset. | 1160 | * ATN and ABORT the task when we go to message in |
1161 | * phase. The OSM will see the REQUEUE_REQUEST | ||
1162 | * status and retry the command. | ||
1060 | */ | 1163 | */ |
1061 | scbid = ahd_get_scbptr(ahd); | 1164 | scbid = ahd_get_scbptr(ahd); |
1062 | scb = ahd_lookup_scb(ahd, scbid); | 1165 | scb = ahd_lookup_scb(ahd, scbid); |
@@ -1083,7 +1186,28 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat) | |||
1083 | ahd_set_syncrate(ahd, &devinfo, /*period*/0, | 1186 | ahd_set_syncrate(ahd, &devinfo, /*period*/0, |
1084 | /*offset*/0, /*ppr_options*/0, | 1187 | /*offset*/0, /*ppr_options*/0, |
1085 | AHD_TRANS_ACTIVE, /*paused*/TRUE); | 1188 | AHD_TRANS_ACTIVE, /*paused*/TRUE); |
1086 | scb->flags |= SCB_EXTERNAL_RESET; | 1189 | /* Hand-craft TUR command */ |
1190 | ahd_outb(ahd, SCB_CDB_STORE, 0); | ||
1191 | ahd_outb(ahd, SCB_CDB_STORE+1, 0); | ||
1192 | ahd_outb(ahd, SCB_CDB_STORE+2, 0); | ||
1193 | ahd_outb(ahd, SCB_CDB_STORE+3, 0); | ||
1194 | ahd_outb(ahd, SCB_CDB_STORE+4, 0); | ||
1195 | ahd_outb(ahd, SCB_CDB_STORE+5, 0); | ||
1196 | ahd_outb(ahd, SCB_CDB_LEN, 6); | ||
1197 | scb->hscb->control &= ~(TAG_ENB|SCB_TAG_TYPE); | ||
1198 | scb->hscb->control |= MK_MESSAGE; | ||
1199 | ahd_outb(ahd, SCB_CONTROL, scb->hscb->control); | ||
1200 | ahd_outb(ahd, MSG_OUT, HOST_MSG); | ||
1201 | ahd_outb(ahd, SAVED_SCSIID, scb->hscb->scsiid); | ||
1202 | /* | ||
1203 | * The lun is 0, regardless of the SCB's lun | ||
1204 | * as we have not sent an identify message. | ||
1205 | */ | ||
1206 | ahd_outb(ahd, SAVED_LUN, 0); | ||
1207 | ahd_outb(ahd, SEQ_FLAGS, 0); | ||
1208 | ahd_assert_atn(ahd); | ||
1209 | scb->flags &= ~SCB_PACKETIZED; | ||
1210 | scb->flags |= SCB_ABORT|SCB_EXTERNAL_RESET; | ||
1087 | ahd_freeze_devq(ahd, scb); | 1211 | ahd_freeze_devq(ahd, scb); |
1088 | ahd_set_transaction_status(scb, CAM_REQUEUE_REQ); | 1212 | ahd_set_transaction_status(scb, CAM_REQUEUE_REQ); |
1089 | ahd_freeze_scb(scb); | 1213 | ahd_freeze_scb(scb); |
@@ -1519,8 +1643,10 @@ ahd_handle_scsiint(struct ahd_softc *ahd, u_int intstat) | |||
1519 | /* | 1643 | /* |
1520 | * Ignore external resets after a bus reset. | 1644 | * Ignore external resets after a bus reset. |
1521 | */ | 1645 | */ |
1522 | if (((status & SCSIRSTI) != 0) && (ahd->flags & AHD_BUS_RESET_ACTIVE)) | 1646 | if (((status & SCSIRSTI) != 0) && (ahd->flags & AHD_BUS_RESET_ACTIVE)) { |
1647 | ahd_outb(ahd, CLRSINT1, CLRSCSIRSTI); | ||
1523 | return; | 1648 | return; |
1649 | } | ||
1524 | 1650 | ||
1525 | /* | 1651 | /* |
1526 | * Clear bus reset flag | 1652 | * Clear bus reset flag |
@@ -2200,6 +2326,22 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd) | |||
2200 | if (sent_msg == MSG_ABORT_TAG) | 2326 | if (sent_msg == MSG_ABORT_TAG) |
2201 | tag = SCB_GET_TAG(scb); | 2327 | tag = SCB_GET_TAG(scb); |
2202 | 2328 | ||
2329 | if ((scb->flags & SCB_EXTERNAL_RESET) != 0) { | ||
2330 | /* | ||
2331 | * This abort is in response to an | ||
2332 | * unexpected switch to command phase | ||
2333 | * for a packetized connection. Since | ||
2334 | * the identify message was never sent, | ||
2335 | * "saved lun" is 0. We really want to | ||
2336 | * abort only the SCB that encountered | ||
2337 | * this error, which could have a different | ||
2338 | * lun. The SCB will be retried so the OS | ||
2339 | * will see the UA after renegotiating to | ||
2340 | * packetized. | ||
2341 | */ | ||
2342 | tag = SCB_GET_TAG(scb); | ||
2343 | saved_lun = scb->hscb->lun; | ||
2344 | } | ||
2203 | found = ahd_abort_scbs(ahd, target, 'A', saved_lun, | 2345 | found = ahd_abort_scbs(ahd, target, 'A', saved_lun, |
2204 | tag, ROLE_INITIATOR, | 2346 | tag, ROLE_INITIATOR, |
2205 | CAM_REQ_ABORTED); | 2347 | CAM_REQ_ABORTED); |
@@ -2523,7 +2665,7 @@ ahd_force_renegotiation(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) | |||
2523 | } | 2665 | } |
2524 | 2666 | ||
2525 | #define AHD_MAX_STEPS 2000 | 2667 | #define AHD_MAX_STEPS 2000 |
2526 | void | 2668 | static void |
2527 | ahd_clear_critical_section(struct ahd_softc *ahd) | 2669 | ahd_clear_critical_section(struct ahd_softc *ahd) |
2528 | { | 2670 | { |
2529 | ahd_mode_state saved_modes; | 2671 | ahd_mode_state saved_modes; |
@@ -2646,7 +2788,7 @@ ahd_clear_critical_section(struct ahd_softc *ahd) | |||
2646 | /* | 2788 | /* |
2647 | * Clear any pending interrupt status. | 2789 | * Clear any pending interrupt status. |
2648 | */ | 2790 | */ |
2649 | void | 2791 | static void |
2650 | ahd_clear_intstat(struct ahd_softc *ahd) | 2792 | ahd_clear_intstat(struct ahd_softc *ahd) |
2651 | { | 2793 | { |
2652 | AHD_ASSERT_MODES(ahd, ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK), | 2794 | AHD_ASSERT_MODES(ahd, ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK), |
@@ -2677,6 +2819,8 @@ ahd_clear_intstat(struct ahd_softc *ahd) | |||
2677 | #ifdef AHD_DEBUG | 2819 | #ifdef AHD_DEBUG |
2678 | uint32_t ahd_debug = AHD_DEBUG_OPTS; | 2820 | uint32_t ahd_debug = AHD_DEBUG_OPTS; |
2679 | #endif | 2821 | #endif |
2822 | |||
2823 | #if 0 | ||
2680 | void | 2824 | void |
2681 | ahd_print_scb(struct scb *scb) | 2825 | ahd_print_scb(struct scb *scb) |
2682 | { | 2826 | { |
@@ -2701,49 +2845,7 @@ ahd_print_scb(struct scb *scb) | |||
2701 | SCB_GET_TAG(scb)); | 2845 | SCB_GET_TAG(scb)); |
2702 | ahd_dump_sglist(scb); | 2846 | ahd_dump_sglist(scb); |
2703 | } | 2847 | } |
2704 | 2848 | #endif /* 0 */ | |
2705 | void | ||
2706 | ahd_dump_sglist(struct scb *scb) | ||
2707 | { | ||
2708 | int i; | ||
2709 | |||
2710 | if (scb->sg_count > 0) { | ||
2711 | if ((scb->ahd_softc->flags & AHD_64BIT_ADDRESSING) != 0) { | ||
2712 | struct ahd_dma64_seg *sg_list; | ||
2713 | |||
2714 | sg_list = (struct ahd_dma64_seg*)scb->sg_list; | ||
2715 | for (i = 0; i < scb->sg_count; i++) { | ||
2716 | uint64_t addr; | ||
2717 | uint32_t len; | ||
2718 | |||
2719 | addr = ahd_le64toh(sg_list[i].addr); | ||
2720 | len = ahd_le32toh(sg_list[i].len); | ||
2721 | printf("sg[%d] - Addr 0x%x%x : Length %d%s\n", | ||
2722 | i, | ||
2723 | (uint32_t)((addr >> 32) & 0xFFFFFFFF), | ||
2724 | (uint32_t)(addr & 0xFFFFFFFF), | ||
2725 | sg_list[i].len & AHD_SG_LEN_MASK, | ||
2726 | (sg_list[i].len & AHD_DMA_LAST_SEG) | ||
2727 | ? " Last" : ""); | ||
2728 | } | ||
2729 | } else { | ||
2730 | struct ahd_dma_seg *sg_list; | ||
2731 | |||
2732 | sg_list = (struct ahd_dma_seg*)scb->sg_list; | ||
2733 | for (i = 0; i < scb->sg_count; i++) { | ||
2734 | uint32_t len; | ||
2735 | |||
2736 | len = ahd_le32toh(sg_list[i].len); | ||
2737 | printf("sg[%d] - Addr 0x%x%x : Length %d%s\n", | ||
2738 | i, | ||
2739 | (len & AHD_SG_HIGH_ADDR_MASK) >> 24, | ||
2740 | ahd_le32toh(sg_list[i].addr), | ||
2741 | len & AHD_SG_LEN_MASK, | ||
2742 | len & AHD_DMA_LAST_SEG ? " Last" : ""); | ||
2743 | } | ||
2744 | } | ||
2745 | } | ||
2746 | } | ||
2747 | 2849 | ||
2748 | /************************* Transfer Negotiation *******************************/ | 2850 | /************************* Transfer Negotiation *******************************/ |
2749 | /* | 2851 | /* |
@@ -2850,14 +2952,14 @@ ahd_devlimited_syncrate(struct ahd_softc *ahd, | |||
2850 | transinfo = &tinfo->goal; | 2952 | transinfo = &tinfo->goal; |
2851 | *ppr_options &= (transinfo->ppr_options|MSG_EXT_PPR_PCOMP_EN); | 2953 | *ppr_options &= (transinfo->ppr_options|MSG_EXT_PPR_PCOMP_EN); |
2852 | if (transinfo->width == MSG_EXT_WDTR_BUS_8_BIT) { | 2954 | if (transinfo->width == MSG_EXT_WDTR_BUS_8_BIT) { |
2853 | maxsync = MAX(maxsync, AHD_SYNCRATE_ULTRA2); | 2955 | maxsync = max(maxsync, (u_int)AHD_SYNCRATE_ULTRA2); |
2854 | *ppr_options &= ~MSG_EXT_PPR_DT_REQ; | 2956 | *ppr_options &= ~MSG_EXT_PPR_DT_REQ; |
2855 | } | 2957 | } |
2856 | if (transinfo->period == 0) { | 2958 | if (transinfo->period == 0) { |
2857 | *period = 0; | 2959 | *period = 0; |
2858 | *ppr_options = 0; | 2960 | *ppr_options = 0; |
2859 | } else { | 2961 | } else { |
2860 | *period = MAX(*period, transinfo->period); | 2962 | *period = max(*period, (u_int)transinfo->period); |
2861 | ahd_find_syncrate(ahd, period, ppr_options, maxsync); | 2963 | ahd_find_syncrate(ahd, period, ppr_options, maxsync); |
2862 | } | 2964 | } |
2863 | } | 2965 | } |
@@ -2906,7 +3008,7 @@ ahd_find_syncrate(struct ahd_softc *ahd, u_int *period, | |||
2906 | * Truncate the given synchronous offset to a value the | 3008 | * Truncate the given synchronous offset to a value the |
2907 | * current adapter type and syncrate are capable of. | 3009 | * current adapter type and syncrate are capable of. |
2908 | */ | 3010 | */ |
2909 | void | 3011 | static void |
2910 | ahd_validate_offset(struct ahd_softc *ahd, | 3012 | ahd_validate_offset(struct ahd_softc *ahd, |
2911 | struct ahd_initiator_tinfo *tinfo, | 3013 | struct ahd_initiator_tinfo *tinfo, |
2912 | u_int period, u_int *offset, int wide, | 3014 | u_int period, u_int *offset, int wide, |
@@ -2924,12 +3026,12 @@ ahd_validate_offset(struct ahd_softc *ahd, | |||
2924 | maxoffset = MAX_OFFSET_PACED; | 3026 | maxoffset = MAX_OFFSET_PACED; |
2925 | } else | 3027 | } else |
2926 | maxoffset = MAX_OFFSET_NON_PACED; | 3028 | maxoffset = MAX_OFFSET_NON_PACED; |
2927 | *offset = MIN(*offset, maxoffset); | 3029 | *offset = min(*offset, maxoffset); |
2928 | if (tinfo != NULL) { | 3030 | if (tinfo != NULL) { |
2929 | if (role == ROLE_TARGET) | 3031 | if (role == ROLE_TARGET) |
2930 | *offset = MIN(*offset, tinfo->user.offset); | 3032 | *offset = min(*offset, (u_int)tinfo->user.offset); |
2931 | else | 3033 | else |
2932 | *offset = MIN(*offset, tinfo->goal.offset); | 3034 | *offset = min(*offset, (u_int)tinfo->goal.offset); |
2933 | } | 3035 | } |
2934 | } | 3036 | } |
2935 | 3037 | ||
@@ -2937,7 +3039,7 @@ ahd_validate_offset(struct ahd_softc *ahd, | |||
2937 | * Truncate the given transfer width parameter to a value the | 3039 | * Truncate the given transfer width parameter to a value the |
2938 | * current adapter type is capable of. | 3040 | * current adapter type is capable of. |
2939 | */ | 3041 | */ |
2940 | void | 3042 | static void |
2941 | ahd_validate_width(struct ahd_softc *ahd, struct ahd_initiator_tinfo *tinfo, | 3043 | ahd_validate_width(struct ahd_softc *ahd, struct ahd_initiator_tinfo *tinfo, |
2942 | u_int *bus_width, role_t role) | 3044 | u_int *bus_width, role_t role) |
2943 | { | 3045 | { |
@@ -2955,9 +3057,9 @@ ahd_validate_width(struct ahd_softc *ahd, struct ahd_initiator_tinfo *tinfo, | |||
2955 | } | 3057 | } |
2956 | if (tinfo != NULL) { | 3058 | if (tinfo != NULL) { |
2957 | if (role == ROLE_TARGET) | 3059 | if (role == ROLE_TARGET) |
2958 | *bus_width = MIN(tinfo->user.width, *bus_width); | 3060 | *bus_width = min((u_int)tinfo->user.width, *bus_width); |
2959 | else | 3061 | else |
2960 | *bus_width = MIN(tinfo->goal.width, *bus_width); | 3062 | *bus_width = min((u_int)tinfo->goal.width, *bus_width); |
2961 | } | 3063 | } |
2962 | } | 3064 | } |
2963 | 3065 | ||
@@ -3210,7 +3312,7 @@ ahd_set_width(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, | |||
3210 | /* | 3312 | /* |
3211 | * Update the current state of tagged queuing for a given target. | 3313 | * Update the current state of tagged queuing for a given target. |
3212 | */ | 3314 | */ |
3213 | void | 3315 | static void |
3214 | ahd_set_tags(struct ahd_softc *ahd, struct scsi_cmnd *cmd, | 3316 | ahd_set_tags(struct ahd_softc *ahd, struct scsi_cmnd *cmd, |
3215 | struct ahd_devinfo *devinfo, ahd_queue_alg alg) | 3317 | struct ahd_devinfo *devinfo, ahd_queue_alg alg) |
3216 | { | 3318 | { |
@@ -3466,7 +3568,7 @@ ahd_print_devinfo(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) | |||
3466 | devinfo->target, devinfo->lun); | 3568 | devinfo->target, devinfo->lun); |
3467 | } | 3569 | } |
3468 | 3570 | ||
3469 | struct ahd_phase_table_entry* | 3571 | static struct ahd_phase_table_entry* |
3470 | ahd_lookup_phase_entry(int phase) | 3572 | ahd_lookup_phase_entry(int phase) |
3471 | { | 3573 | { |
3472 | struct ahd_phase_table_entry *entry; | 3574 | struct ahd_phase_table_entry *entry; |
@@ -5351,7 +5453,7 @@ ahd_free(struct ahd_softc *ahd) | |||
5351 | return; | 5453 | return; |
5352 | } | 5454 | } |
5353 | 5455 | ||
5354 | void | 5456 | static void |
5355 | ahd_shutdown(void *arg) | 5457 | ahd_shutdown(void *arg) |
5356 | { | 5458 | { |
5357 | struct ahd_softc *ahd; | 5459 | struct ahd_softc *ahd; |
@@ -5480,7 +5582,7 @@ ahd_reset(struct ahd_softc *ahd, int reinit) | |||
5480 | /* | 5582 | /* |
5481 | * Determine the number of SCBs available on the controller | 5583 | * Determine the number of SCBs available on the controller |
5482 | */ | 5584 | */ |
5483 | int | 5585 | static int |
5484 | ahd_probe_scbs(struct ahd_softc *ahd) { | 5586 | ahd_probe_scbs(struct ahd_softc *ahd) { |
5485 | int i; | 5587 | int i; |
5486 | 5588 | ||
@@ -5929,7 +6031,7 @@ ahd_free_scb(struct ahd_softc *ahd, struct scb *scb) | |||
5929 | ahd_platform_scb_free(ahd, scb); | 6031 | ahd_platform_scb_free(ahd, scb); |
5930 | } | 6032 | } |
5931 | 6033 | ||
5932 | void | 6034 | static void |
5933 | ahd_alloc_scbs(struct ahd_softc *ahd) | 6035 | ahd_alloc_scbs(struct ahd_softc *ahd) |
5934 | { | 6036 | { |
5935 | struct scb_data *scb_data; | 6037 | struct scb_data *scb_data; |
@@ -6057,9 +6159,9 @@ ahd_alloc_scbs(struct ahd_softc *ahd) | |||
6057 | #endif | 6159 | #endif |
6058 | } | 6160 | } |
6059 | 6161 | ||
6060 | newcount = MIN(scb_data->sense_left, scb_data->scbs_left); | 6162 | newcount = min(scb_data->sense_left, scb_data->scbs_left); |
6061 | newcount = MIN(newcount, scb_data->sgs_left); | 6163 | newcount = min(newcount, scb_data->sgs_left); |
6062 | newcount = MIN(newcount, (AHD_SCB_MAX_ALLOC - scb_data->numscbs)); | 6164 | newcount = min(newcount, (AHD_SCB_MAX_ALLOC - scb_data->numscbs)); |
6063 | for (i = 0; i < newcount; i++) { | 6165 | for (i = 0; i < newcount; i++) { |
6064 | struct scb_platform_data *pdata; | 6166 | struct scb_platform_data *pdata; |
6065 | u_int col_tag; | 6167 | u_int col_tag; |
@@ -6982,7 +7084,7 @@ ahd_intr_enable(struct ahd_softc *ahd, int enable) | |||
6982 | ahd_outb(ahd, HCNTRL, hcntrl); | 7084 | ahd_outb(ahd, HCNTRL, hcntrl); |
6983 | } | 7085 | } |
6984 | 7086 | ||
6985 | void | 7087 | static void |
6986 | ahd_update_coalescing_values(struct ahd_softc *ahd, u_int timer, u_int maxcmds, | 7088 | ahd_update_coalescing_values(struct ahd_softc *ahd, u_int timer, u_int maxcmds, |
6987 | u_int mincmds) | 7089 | u_int mincmds) |
6988 | { | 7090 | { |
@@ -7000,7 +7102,7 @@ ahd_update_coalescing_values(struct ahd_softc *ahd, u_int timer, u_int maxcmds, | |||
7000 | ahd_outb(ahd, INT_COALESCING_MINCMDS, -mincmds); | 7102 | ahd_outb(ahd, INT_COALESCING_MINCMDS, -mincmds); |
7001 | } | 7103 | } |
7002 | 7104 | ||
7003 | void | 7105 | static void |
7004 | ahd_enable_coalescing(struct ahd_softc *ahd, int enable) | 7106 | ahd_enable_coalescing(struct ahd_softc *ahd, int enable) |
7005 | { | 7107 | { |
7006 | 7108 | ||
@@ -7070,6 +7172,7 @@ ahd_pause_and_flushwork(struct ahd_softc *ahd) | |||
7070 | ahd->flags &= ~AHD_ALL_INTERRUPTS; | 7172 | ahd->flags &= ~AHD_ALL_INTERRUPTS; |
7071 | } | 7173 | } |
7072 | 7174 | ||
7175 | #if 0 | ||
7073 | int | 7176 | int |
7074 | ahd_suspend(struct ahd_softc *ahd) | 7177 | ahd_suspend(struct ahd_softc *ahd) |
7075 | { | 7178 | { |
@@ -7083,7 +7186,9 @@ ahd_suspend(struct ahd_softc *ahd) | |||
7083 | ahd_shutdown(ahd); | 7186 | ahd_shutdown(ahd); |
7084 | return (0); | 7187 | return (0); |
7085 | } | 7188 | } |
7189 | #endif /* 0 */ | ||
7086 | 7190 | ||
7191 | #if 0 | ||
7087 | int | 7192 | int |
7088 | ahd_resume(struct ahd_softc *ahd) | 7193 | ahd_resume(struct ahd_softc *ahd) |
7089 | { | 7194 | { |
@@ -7093,6 +7198,7 @@ ahd_resume(struct ahd_softc *ahd) | |||
7093 | ahd_restart(ahd); | 7198 | ahd_restart(ahd); |
7094 | return (0); | 7199 | return (0); |
7095 | } | 7200 | } |
7201 | #endif /* 0 */ | ||
7096 | 7202 | ||
7097 | /************************** Busy Target Table *********************************/ | 7203 | /************************** Busy Target Table *********************************/ |
7098 | /* | 7204 | /* |
@@ -7125,7 +7231,7 @@ ahd_index_busy_tcl(struct ahd_softc *ahd, u_int *saved_scbid, u_int tcl) | |||
7125 | /* | 7231 | /* |
7126 | * Return the untagged transaction id for a given target/channel lun. | 7232 | * Return the untagged transaction id for a given target/channel lun. |
7127 | */ | 7233 | */ |
7128 | u_int | 7234 | static u_int |
7129 | ahd_find_busy_tcl(struct ahd_softc *ahd, u_int tcl) | 7235 | ahd_find_busy_tcl(struct ahd_softc *ahd, u_int tcl) |
7130 | { | 7236 | { |
7131 | u_int scbid; | 7237 | u_int scbid; |
@@ -7138,7 +7244,7 @@ ahd_find_busy_tcl(struct ahd_softc *ahd, u_int tcl) | |||
7138 | return (scbid); | 7244 | return (scbid); |
7139 | } | 7245 | } |
7140 | 7246 | ||
7141 | void | 7247 | static void |
7142 | ahd_busy_tcl(struct ahd_softc *ahd, u_int tcl, u_int scbid) | 7248 | ahd_busy_tcl(struct ahd_softc *ahd, u_int tcl, u_int scbid) |
7143 | { | 7249 | { |
7144 | u_int scb_offset; | 7250 | u_int scb_offset; |
@@ -7186,7 +7292,7 @@ ahd_match_scb(struct ahd_softc *ahd, struct scb *scb, int target, | |||
7186 | return match; | 7292 | return match; |
7187 | } | 7293 | } |
7188 | 7294 | ||
7189 | void | 7295 | static void |
7190 | ahd_freeze_devq(struct ahd_softc *ahd, struct scb *scb) | 7296 | ahd_freeze_devq(struct ahd_softc *ahd, struct scb *scb) |
7191 | { | 7297 | { |
7192 | int target; | 7298 | int target; |
@@ -7690,7 +7796,7 @@ ahd_add_scb_to_free_list(struct ahd_softc *ahd, u_int scbid) | |||
7690 | * been modified from CAM_REQ_INPROG. This routine assumes that the sequencer | 7796 | * been modified from CAM_REQ_INPROG. This routine assumes that the sequencer |
7691 | * is paused before it is called. | 7797 | * is paused before it is called. |
7692 | */ | 7798 | */ |
7693 | int | 7799 | static int |
7694 | ahd_abort_scbs(struct ahd_softc *ahd, int target, char channel, | 7800 | ahd_abort_scbs(struct ahd_softc *ahd, int target, char channel, |
7695 | int lun, u_int tag, role_t role, uint32_t status) | 7801 | int lun, u_int tag, role_t role, uint32_t status) |
7696 | { | 7802 | { |
@@ -7920,6 +8026,11 @@ ahd_reset_channel(struct ahd_softc *ahd, char channel, int initiate_reset) | |||
7920 | ahd_clear_fifo(ahd, 1); | 8026 | ahd_clear_fifo(ahd, 1); |
7921 | 8027 | ||
7922 | /* | 8028 | /* |
8029 | * Clear SCSI interrupt status | ||
8030 | */ | ||
8031 | ahd_outb(ahd, CLRSINT1, CLRSCSIRSTI); | ||
8032 | |||
8033 | /* | ||
7923 | * Reenable selections | 8034 | * Reenable selections |
7924 | */ | 8035 | */ |
7925 | ahd_outb(ahd, SIMODE1, ahd_inb(ahd, SIMODE1) | ENSCSIRST); | 8036 | ahd_outb(ahd, SIMODE1, ahd_inb(ahd, SIMODE1) | ENSCSIRST); |
@@ -7952,10 +8063,6 @@ ahd_reset_channel(struct ahd_softc *ahd, char channel, int initiate_reset) | |||
7952 | } | 8063 | } |
7953 | } | 8064 | } |
7954 | #endif | 8065 | #endif |
7955 | /* Notify the XPT that a bus reset occurred */ | ||
7956 | ahd_send_async(ahd, devinfo.channel, CAM_TARGET_WILDCARD, | ||
7957 | CAM_LUN_WILDCARD, AC_BUS_RESET); | ||
7958 | |||
7959 | /* | 8066 | /* |
7960 | * Revert to async/narrow transfers until we renegotiate. | 8067 | * Revert to async/narrow transfers until we renegotiate. |
7961 | */ | 8068 | */ |
@@ -7977,6 +8084,10 @@ ahd_reset_channel(struct ahd_softc *ahd, char channel, int initiate_reset) | |||
7977 | } | 8084 | } |
7978 | } | 8085 | } |
7979 | 8086 | ||
8087 | /* Notify the XPT that a bus reset occurred */ | ||
8088 | ahd_send_async(ahd, devinfo.channel, CAM_TARGET_WILDCARD, | ||
8089 | CAM_LUN_WILDCARD, AC_BUS_RESET); | ||
8090 | |||
7980 | ahd_restart(ahd); | 8091 | ahd_restart(ahd); |
7981 | 8092 | ||
7982 | return (found); | 8093 | return (found); |
@@ -8019,18 +8130,8 @@ ahd_stat_timer(void *arg) | |||
8019 | } | 8130 | } |
8020 | 8131 | ||
8021 | /****************************** Status Processing *****************************/ | 8132 | /****************************** Status Processing *****************************/ |
8022 | void | ||
8023 | ahd_handle_scb_status(struct ahd_softc *ahd, struct scb *scb) | ||
8024 | { | ||
8025 | if (scb->hscb->shared_data.istatus.scsi_status != 0) { | ||
8026 | ahd_handle_scsi_status(ahd, scb); | ||
8027 | } else { | ||
8028 | ahd_calc_residual(ahd, scb); | ||
8029 | ahd_done(ahd, scb); | ||
8030 | } | ||
8031 | } | ||
8032 | 8133 | ||
8033 | void | 8134 | static void |
8034 | ahd_handle_scsi_status(struct ahd_softc *ahd, struct scb *scb) | 8135 | ahd_handle_scsi_status(struct ahd_softc *ahd, struct scb *scb) |
8035 | { | 8136 | { |
8036 | struct hardware_scb *hscb; | 8137 | struct hardware_scb *hscb; |
@@ -8238,10 +8339,21 @@ ahd_handle_scsi_status(struct ahd_softc *ahd, struct scb *scb) | |||
8238 | } | 8339 | } |
8239 | } | 8340 | } |
8240 | 8341 | ||
8342 | static void | ||
8343 | ahd_handle_scb_status(struct ahd_softc *ahd, struct scb *scb) | ||
8344 | { | ||
8345 | if (scb->hscb->shared_data.istatus.scsi_status != 0) { | ||
8346 | ahd_handle_scsi_status(ahd, scb); | ||
8347 | } else { | ||
8348 | ahd_calc_residual(ahd, scb); | ||
8349 | ahd_done(ahd, scb); | ||
8350 | } | ||
8351 | } | ||
8352 | |||
8241 | /* | 8353 | /* |
8242 | * Calculate the residual for a just completed SCB. | 8354 | * Calculate the residual for a just completed SCB. |
8243 | */ | 8355 | */ |
8244 | void | 8356 | static void |
8245 | ahd_calc_residual(struct ahd_softc *ahd, struct scb *scb) | 8357 | ahd_calc_residual(struct ahd_softc *ahd, struct scb *scb) |
8246 | { | 8358 | { |
8247 | struct hardware_scb *hscb; | 8359 | struct hardware_scb *hscb; |
@@ -8668,7 +8780,7 @@ ahd_resolve_seqaddr(struct ahd_softc *ahd, u_int address) | |||
8668 | if (skip_addr > i) { | 8780 | if (skip_addr > i) { |
8669 | int end_addr; | 8781 | int end_addr; |
8670 | 8782 | ||
8671 | end_addr = MIN(address, skip_addr); | 8783 | end_addr = min(address, skip_addr); |
8672 | address_offset += end_addr - i; | 8784 | address_offset += end_addr - i; |
8673 | i = skip_addr; | 8785 | i = skip_addr; |
8674 | } else { | 8786 | } else { |
@@ -9092,6 +9204,7 @@ ahd_dump_card_state(struct ahd_softc *ahd) | |||
9092 | ahd_unpause(ahd); | 9204 | ahd_unpause(ahd); |
9093 | } | 9205 | } |
9094 | 9206 | ||
9207 | #if 0 | ||
9095 | void | 9208 | void |
9096 | ahd_dump_scbs(struct ahd_softc *ahd) | 9209 | ahd_dump_scbs(struct ahd_softc *ahd) |
9097 | { | 9210 | { |
@@ -9117,6 +9230,7 @@ ahd_dump_scbs(struct ahd_softc *ahd) | |||
9117 | ahd_set_scbptr(ahd, saved_scb_index); | 9230 | ahd_set_scbptr(ahd, saved_scb_index); |
9118 | ahd_restore_modes(ahd, saved_modes); | 9231 | ahd_restore_modes(ahd, saved_modes); |
9119 | } | 9232 | } |
9233 | #endif /* 0 */ | ||
9120 | 9234 | ||
9121 | /**************************** Flexport Logic **********************************/ | 9235 | /**************************** Flexport Logic **********************************/ |
9122 | /* | 9236 | /* |
@@ -9219,7 +9333,7 @@ ahd_write_seeprom(struct ahd_softc *ahd, uint16_t *buf, | |||
9219 | /* | 9333 | /* |
9220 | * Wait ~100us for the serial eeprom to satisfy our request. | 9334 | * Wait ~100us for the serial eeprom to satisfy our request. |
9221 | */ | 9335 | */ |
9222 | int | 9336 | static int |
9223 | ahd_wait_seeprom(struct ahd_softc *ahd) | 9337 | ahd_wait_seeprom(struct ahd_softc *ahd) |
9224 | { | 9338 | { |
9225 | int cnt; | 9339 | int cnt; |
@@ -9237,7 +9351,7 @@ ahd_wait_seeprom(struct ahd_softc *ahd) | |||
9237 | * Validate the two checksums in the per_channel | 9351 | * Validate the two checksums in the per_channel |
9238 | * vital product data struct. | 9352 | * vital product data struct. |
9239 | */ | 9353 | */ |
9240 | int | 9354 | static int |
9241 | ahd_verify_vpd_cksum(struct vpd_config *vpd) | 9355 | ahd_verify_vpd_cksum(struct vpd_config *vpd) |
9242 | { | 9356 | { |
9243 | int i; | 9357 | int i; |
@@ -9316,6 +9430,24 @@ ahd_release_seeprom(struct ahd_softc *ahd) | |||
9316 | /* Currently a no-op */ | 9430 | /* Currently a no-op */ |
9317 | } | 9431 | } |
9318 | 9432 | ||
9433 | /* | ||
9434 | * Wait at most 2 seconds for flexport arbitration to succeed. | ||
9435 | */ | ||
9436 | static int | ||
9437 | ahd_wait_flexport(struct ahd_softc *ahd) | ||
9438 | { | ||
9439 | int cnt; | ||
9440 | |||
9441 | AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK); | ||
9442 | cnt = 1000000 * 2 / 5; | ||
9443 | while ((ahd_inb(ahd, BRDCTL) & FLXARBACK) == 0 && --cnt) | ||
9444 | ahd_delay(5); | ||
9445 | |||
9446 | if (cnt == 0) | ||
9447 | return (ETIMEDOUT); | ||
9448 | return (0); | ||
9449 | } | ||
9450 | |||
9319 | int | 9451 | int |
9320 | ahd_write_flexport(struct ahd_softc *ahd, u_int addr, u_int value) | 9452 | ahd_write_flexport(struct ahd_softc *ahd, u_int addr, u_int value) |
9321 | { | 9453 | { |
@@ -9357,24 +9489,6 @@ ahd_read_flexport(struct ahd_softc *ahd, u_int addr, uint8_t *value) | |||
9357 | return (0); | 9489 | return (0); |
9358 | } | 9490 | } |
9359 | 9491 | ||
9360 | /* | ||
9361 | * Wait at most 2 seconds for flexport arbitration to succeed. | ||
9362 | */ | ||
9363 | int | ||
9364 | ahd_wait_flexport(struct ahd_softc *ahd) | ||
9365 | { | ||
9366 | int cnt; | ||
9367 | |||
9368 | AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK); | ||
9369 | cnt = 1000000 * 2 / 5; | ||
9370 | while ((ahd_inb(ahd, BRDCTL) & FLXARBACK) == 0 && --cnt) | ||
9371 | ahd_delay(5); | ||
9372 | |||
9373 | if (cnt == 0) | ||
9374 | return (ETIMEDOUT); | ||
9375 | return (0); | ||
9376 | } | ||
9377 | |||
9378 | /************************* Target Mode ****************************************/ | 9492 | /************************* Target Mode ****************************************/ |
9379 | #ifdef AHD_TARGET_MODE | 9493 | #ifdef AHD_TARGET_MODE |
9380 | cam_status | 9494 | cam_status |
diff --git a/drivers/scsi/aic7xxx/aic79xx_inline.h b/drivers/scsi/aic7xxx/aic79xx_inline.h index a3266e066c00..2ceb67f4af2a 100644 --- a/drivers/scsi/aic7xxx/aic79xx_inline.h +++ b/drivers/scsi/aic7xxx/aic79xx_inline.h | |||
@@ -418,10 +418,6 @@ ahd_targetcmd_offset(struct ahd_softc *ahd, u_int index) | |||
418 | } | 418 | } |
419 | 419 | ||
420 | /*********************** Miscelaneous Support Functions ***********************/ | 420 | /*********************** Miscelaneous Support Functions ***********************/ |
421 | static __inline void ahd_complete_scb(struct ahd_softc *ahd, | ||
422 | struct scb *scb); | ||
423 | static __inline void ahd_update_residual(struct ahd_softc *ahd, | ||
424 | struct scb *scb); | ||
425 | static __inline struct ahd_initiator_tinfo * | 421 | static __inline struct ahd_initiator_tinfo * |
426 | ahd_fetch_transinfo(struct ahd_softc *ahd, | 422 | ahd_fetch_transinfo(struct ahd_softc *ahd, |
427 | char channel, u_int our_id, | 423 | char channel, u_int our_id, |
@@ -467,32 +463,6 @@ static __inline uint32_t | |||
467 | ahd_get_sense_bufaddr(struct ahd_softc *ahd, | 463 | ahd_get_sense_bufaddr(struct ahd_softc *ahd, |
468 | struct scb *scb); | 464 | struct scb *scb); |
469 | 465 | ||
470 | static __inline void | ||
471 | ahd_complete_scb(struct ahd_softc *ahd, struct scb *scb) | ||
472 | { | ||
473 | uint32_t sgptr; | ||
474 | |||
475 | sgptr = ahd_le32toh(scb->hscb->sgptr); | ||
476 | if ((sgptr & SG_STATUS_VALID) != 0) | ||
477 | ahd_handle_scb_status(ahd, scb); | ||
478 | else | ||
479 | ahd_done(ahd, scb); | ||
480 | } | ||
481 | |||
482 | /* | ||
483 | * Determine whether the sequencer reported a residual | ||
484 | * for this SCB/transaction. | ||
485 | */ | ||
486 | static __inline void | ||
487 | ahd_update_residual(struct ahd_softc *ahd, struct scb *scb) | ||
488 | { | ||
489 | uint32_t sgptr; | ||
490 | |||
491 | sgptr = ahd_le32toh(scb->hscb->sgptr); | ||
492 | if ((sgptr & SG_STATUS_VALID) != 0) | ||
493 | ahd_calc_residual(ahd, scb); | ||
494 | } | ||
495 | |||
496 | /* | 466 | /* |
497 | * Return pointers to the transfer negotiation information | 467 | * Return pointers to the transfer negotiation information |
498 | * for the specified our_id/remote_id pair. | 468 | * for the specified our_id/remote_id pair. |
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c index f8e60486167d..9bfcca5ede08 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm.c | |||
@@ -293,7 +293,7 @@ static uint32_t aic79xx_seltime; | |||
293 | * force all outstanding transactions to be serviced prior to a new | 293 | * force all outstanding transactions to be serviced prior to a new |
294 | * transaction. | 294 | * transaction. |
295 | */ | 295 | */ |
296 | uint32_t aic79xx_periodic_otag; | 296 | static uint32_t aic79xx_periodic_otag; |
297 | 297 | ||
298 | /* Some storage boxes are using an LSI chip which has a bug making it | 298 | /* Some storage boxes are using an LSI chip which has a bug making it |
299 | * impossible to use aic79xx Rev B chip in 320 speeds. The following | 299 | * impossible to use aic79xx Rev B chip in 320 speeds. The following |
@@ -773,6 +773,7 @@ struct scsi_host_template aic79xx_driver_template = { | |||
773 | #endif | 773 | #endif |
774 | .can_queue = AHD_MAX_QUEUE, | 774 | .can_queue = AHD_MAX_QUEUE, |
775 | .this_id = -1, | 775 | .this_id = -1, |
776 | .max_sectors = 8192, | ||
776 | .cmd_per_lun = 2, | 777 | .cmd_per_lun = 2, |
777 | .use_clustering = ENABLE_CLUSTERING, | 778 | .use_clustering = ENABLE_CLUSTERING, |
778 | .slave_alloc = ahd_linux_slave_alloc, | 779 | .slave_alloc = ahd_linux_slave_alloc, |
@@ -1813,9 +1814,9 @@ ahd_linux_handle_scsi_status(struct ahd_softc *ahd, | |||
1813 | u_int sense_offset; | 1814 | u_int sense_offset; |
1814 | 1815 | ||
1815 | if (scb->flags & SCB_SENSE) { | 1816 | if (scb->flags & SCB_SENSE) { |
1816 | sense_size = MIN(sizeof(struct scsi_sense_data) | 1817 | sense_size = min(sizeof(struct scsi_sense_data) |
1817 | - ahd_get_sense_residual(scb), | 1818 | - ahd_get_sense_residual(scb), |
1818 | sizeof(cmd->sense_buffer)); | 1819 | (u_long)sizeof(cmd->sense_buffer)); |
1819 | sense_offset = 0; | 1820 | sense_offset = 0; |
1820 | } else { | 1821 | } else { |
1821 | /* | 1822 | /* |
@@ -1824,7 +1825,8 @@ ahd_linux_handle_scsi_status(struct ahd_softc *ahd, | |||
1824 | */ | 1825 | */ |
1825 | siu = (struct scsi_status_iu_header *) | 1826 | siu = (struct scsi_status_iu_header *) |
1826 | scb->sense_data; | 1827 | scb->sense_data; |
1827 | sense_size = MIN(scsi_4btoul(siu->sense_length), | 1828 | sense_size = min_t(size_t, |
1829 | scsi_4btoul(siu->sense_length), | ||
1828 | sizeof(cmd->sense_buffer)); | 1830 | sizeof(cmd->sense_buffer)); |
1829 | sense_offset = SIU_SENSE_OFFSET(siu); | 1831 | sense_offset = SIU_SENSE_OFFSET(siu); |
1830 | } | 1832 | } |
@@ -2634,8 +2636,22 @@ static void ahd_linux_set_pcomp_en(struct scsi_target *starget, int pcomp) | |||
2634 | pcomp ? "Enable" : "Disable"); | 2636 | pcomp ? "Enable" : "Disable"); |
2635 | #endif | 2637 | #endif |
2636 | 2638 | ||
2637 | if (pcomp) | 2639 | if (pcomp) { |
2640 | uint8_t precomp; | ||
2641 | |||
2642 | if (ahd->unit < ARRAY_SIZE(aic79xx_iocell_info)) { | ||
2643 | struct ahd_linux_iocell_opts *iocell_opts; | ||
2644 | |||
2645 | iocell_opts = &aic79xx_iocell_info[ahd->unit]; | ||
2646 | precomp = iocell_opts->precomp; | ||
2647 | } else { | ||
2648 | precomp = AIC79XX_DEFAULT_PRECOMP; | ||
2649 | } | ||
2638 | ppr_options |= MSG_EXT_PPR_PCOMP_EN; | 2650 | ppr_options |= MSG_EXT_PPR_PCOMP_EN; |
2651 | AHD_SET_PRECOMP(ahd, precomp); | ||
2652 | } else { | ||
2653 | AHD_SET_PRECOMP(ahd, 0); | ||
2654 | } | ||
2639 | 2655 | ||
2640 | ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0, | 2656 | ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0, |
2641 | starget->channel + 'A', ROLE_INITIATOR); | 2657 | starget->channel + 'A', ROLE_INITIATOR); |
@@ -2678,7 +2694,25 @@ static void ahd_linux_set_hold_mcs(struct scsi_target *starget, int hold) | |||
2678 | ahd_unlock(ahd, &flags); | 2694 | ahd_unlock(ahd, &flags); |
2679 | } | 2695 | } |
2680 | 2696 | ||
2697 | static void ahd_linux_get_signalling(struct Scsi_Host *shost) | ||
2698 | { | ||
2699 | struct ahd_softc *ahd = *(struct ahd_softc **)shost->hostdata; | ||
2700 | unsigned long flags; | ||
2701 | u8 mode; | ||
2702 | |||
2703 | ahd_lock(ahd, &flags); | ||
2704 | ahd_pause(ahd); | ||
2705 | mode = ahd_inb(ahd, SBLKCTL); | ||
2706 | ahd_unpause(ahd); | ||
2707 | ahd_unlock(ahd, &flags); | ||
2681 | 2708 | ||
2709 | if (mode & ENAB40) | ||
2710 | spi_signalling(shost) = SPI_SIGNAL_LVD; | ||
2711 | else if (mode & ENAB20) | ||
2712 | spi_signalling(shost) = SPI_SIGNAL_SE; | ||
2713 | else | ||
2714 | spi_signalling(shost) = SPI_SIGNAL_UNKNOWN; | ||
2715 | } | ||
2682 | 2716 | ||
2683 | static struct spi_function_template ahd_linux_transport_functions = { | 2717 | static struct spi_function_template ahd_linux_transport_functions = { |
2684 | .set_offset = ahd_linux_set_offset, | 2718 | .set_offset = ahd_linux_set_offset, |
@@ -2703,6 +2737,7 @@ static struct spi_function_template ahd_linux_transport_functions = { | |||
2703 | .show_pcomp_en = 1, | 2737 | .show_pcomp_en = 1, |
2704 | .set_hold_mcs = ahd_linux_set_hold_mcs, | 2738 | .set_hold_mcs = ahd_linux_set_hold_mcs, |
2705 | .show_hold_mcs = 1, | 2739 | .show_hold_mcs = 1, |
2740 | .get_signalling = ahd_linux_get_signalling, | ||
2706 | }; | 2741 | }; |
2707 | 2742 | ||
2708 | static int __init | 2743 | static int __init |
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.h b/drivers/scsi/aic7xxx/aic79xx_osm.h index fb3d4dd54413..3a67fc578d78 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.h +++ b/drivers/scsi/aic7xxx/aic79xx_osm.h | |||
@@ -506,9 +506,6 @@ struct info_str { | |||
506 | int pos; | 506 | int pos; |
507 | }; | 507 | }; |
508 | 508 | ||
509 | void ahd_format_transinfo(struct info_str *info, | ||
510 | struct ahd_transinfo *tinfo); | ||
511 | |||
512 | /******************************** Locking *************************************/ | 509 | /******************************** Locking *************************************/ |
513 | static __inline void | 510 | static __inline void |
514 | ahd_lockinit(struct ahd_softc *ahd) | 511 | ahd_lockinit(struct ahd_softc *ahd) |
@@ -582,8 +579,6 @@ ahd_unlock(struct ahd_softc *ahd, unsigned long *flags) | |||
582 | #define PCIXM_STATUS_MAXCRDS 0x1C00 /* Maximum Cumulative Read Size */ | 579 | #define PCIXM_STATUS_MAXCRDS 0x1C00 /* Maximum Cumulative Read Size */ |
583 | #define PCIXM_STATUS_RCVDSCEM 0x2000 /* Received a Split Comp w/Error msg */ | 580 | #define PCIXM_STATUS_RCVDSCEM 0x2000 /* Received a Split Comp w/Error msg */ |
584 | 581 | ||
585 | extern struct pci_driver aic79xx_pci_driver; | ||
586 | |||
587 | typedef enum | 582 | typedef enum |
588 | { | 583 | { |
589 | AHD_POWER_STATE_D0, | 584 | AHD_POWER_STATE_D0, |
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c index 4b5354201807..2001fe890e71 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c | |||
@@ -82,7 +82,7 @@ static struct pci_device_id ahd_linux_pci_id_table[] = { | |||
82 | 82 | ||
83 | MODULE_DEVICE_TABLE(pci, ahd_linux_pci_id_table); | 83 | MODULE_DEVICE_TABLE(pci, ahd_linux_pci_id_table); |
84 | 84 | ||
85 | struct pci_driver aic79xx_pci_driver = { | 85 | static struct pci_driver aic79xx_pci_driver = { |
86 | .name = "aic79xx", | 86 | .name = "aic79xx", |
87 | .probe = ahd_linux_pci_dev_probe, | 87 | .probe = ahd_linux_pci_dev_probe, |
88 | .remove = ahd_linux_pci_dev_remove, | 88 | .remove = ahd_linux_pci_dev_remove, |
diff --git a/drivers/scsi/aic7xxx/aic79xx_pci.c b/drivers/scsi/aic7xxx/aic79xx_pci.c index 14850f31aafa..c07735819cd1 100644 --- a/drivers/scsi/aic7xxx/aic79xx_pci.c +++ b/drivers/scsi/aic7xxx/aic79xx_pci.c | |||
@@ -97,7 +97,7 @@ static ahd_device_setup_t ahd_aic7901A_setup; | |||
97 | static ahd_device_setup_t ahd_aic7902_setup; | 97 | static ahd_device_setup_t ahd_aic7902_setup; |
98 | static ahd_device_setup_t ahd_aic790X_setup; | 98 | static ahd_device_setup_t ahd_aic790X_setup; |
99 | 99 | ||
100 | struct ahd_pci_identity ahd_pci_ident_table [] = | 100 | static struct ahd_pci_identity ahd_pci_ident_table [] = |
101 | { | 101 | { |
102 | /* aic7901 based controllers */ | 102 | /* aic7901 based controllers */ |
103 | { | 103 | { |
@@ -201,7 +201,7 @@ struct ahd_pci_identity ahd_pci_ident_table [] = | |||
201 | } | 201 | } |
202 | }; | 202 | }; |
203 | 203 | ||
204 | const u_int ahd_num_pci_devs = ARRAY_SIZE(ahd_pci_ident_table); | 204 | static const u_int ahd_num_pci_devs = ARRAY_SIZE(ahd_pci_ident_table); |
205 | 205 | ||
206 | #define DEVCONFIG 0x40 | 206 | #define DEVCONFIG 0x40 |
207 | #define PCIXINITPAT 0x0000E000ul | 207 | #define PCIXINITPAT 0x0000E000ul |
@@ -245,6 +245,7 @@ static int ahd_check_extport(struct ahd_softc *ahd); | |||
245 | static void ahd_configure_termination(struct ahd_softc *ahd, | 245 | static void ahd_configure_termination(struct ahd_softc *ahd, |
246 | u_int adapter_control); | 246 | u_int adapter_control); |
247 | static void ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat); | 247 | static void ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat); |
248 | static void ahd_pci_intr(struct ahd_softc *ahd); | ||
248 | 249 | ||
249 | struct ahd_pci_identity * | 250 | struct ahd_pci_identity * |
250 | ahd_find_pci_device(ahd_dev_softc_t pci) | 251 | ahd_find_pci_device(ahd_dev_softc_t pci) |
@@ -757,7 +758,7 @@ static const char *pci_status_strings[] = | |||
757 | "%s: Address or Write Phase Parity Error Detected in %s.\n" | 758 | "%s: Address or Write Phase Parity Error Detected in %s.\n" |
758 | }; | 759 | }; |
759 | 760 | ||
760 | void | 761 | static void |
761 | ahd_pci_intr(struct ahd_softc *ahd) | 762 | ahd_pci_intr(struct ahd_softc *ahd) |
762 | { | 763 | { |
763 | uint8_t pci_status[8]; | 764 | uint8_t pci_status[8]; |
diff --git a/drivers/scsi/aic7xxx/aic79xx_proc.c b/drivers/scsi/aic7xxx/aic79xx_proc.c index c5f0ee591509..6b28bebcbca0 100644 --- a/drivers/scsi/aic7xxx/aic79xx_proc.c +++ b/drivers/scsi/aic7xxx/aic79xx_proc.c | |||
@@ -136,7 +136,7 @@ copy_info(struct info_str *info, char *fmt, ...) | |||
136 | return (len); | 136 | return (len); |
137 | } | 137 | } |
138 | 138 | ||
139 | void | 139 | static void |
140 | ahd_format_transinfo(struct info_str *info, struct ahd_transinfo *tinfo) | 140 | ahd_format_transinfo(struct info_str *info, struct ahd_transinfo *tinfo) |
141 | { | 141 | { |
142 | u_int speed; | 142 | u_int speed; |
diff --git a/drivers/scsi/aic7xxx/aic7xxx.h b/drivers/scsi/aic7xxx/aic7xxx.h index 62ff8c3dc2bb..954c7c24501d 100644 --- a/drivers/scsi/aic7xxx/aic7xxx.h +++ b/drivers/scsi/aic7xxx/aic7xxx.h | |||
@@ -54,14 +54,6 @@ struct scb_platform_data; | |||
54 | struct seeprom_descriptor; | 54 | struct seeprom_descriptor; |
55 | 55 | ||
56 | /****************************** Useful Macros *********************************/ | 56 | /****************************** Useful Macros *********************************/ |
57 | #ifndef MAX | ||
58 | #define MAX(a,b) (((a) > (b)) ? (a) : (b)) | ||
59 | #endif | ||
60 | |||
61 | #ifndef MIN | ||
62 | #define MIN(a,b) (((a) < (b)) ? (a) : (b)) | ||
63 | #endif | ||
64 | |||
65 | #ifndef TRUE | 57 | #ifndef TRUE |
66 | #define TRUE 1 | 58 | #define TRUE 1 |
67 | #endif | 59 | #endif |
@@ -1135,8 +1127,6 @@ struct ahc_pci_identity { | |||
1135 | char *name; | 1127 | char *name; |
1136 | ahc_device_setup_t *setup; | 1128 | ahc_device_setup_t *setup; |
1137 | }; | 1129 | }; |
1138 | extern struct ahc_pci_identity ahc_pci_ident_table[]; | ||
1139 | extern const u_int ahc_num_pci_devs; | ||
1140 | 1130 | ||
1141 | /***************************** VL/EISA Declarations ***************************/ | 1131 | /***************************** VL/EISA Declarations ***************************/ |
1142 | struct aic7770_identity { | 1132 | struct aic7770_identity { |
@@ -1289,6 +1279,7 @@ typedef enum { | |||
1289 | } ahc_queue_alg; | 1279 | } ahc_queue_alg; |
1290 | 1280 | ||
1291 | void ahc_set_tags(struct ahc_softc *ahc, | 1281 | void ahc_set_tags(struct ahc_softc *ahc, |
1282 | struct scsi_cmnd *cmd, | ||
1292 | struct ahc_devinfo *devinfo, | 1283 | struct ahc_devinfo *devinfo, |
1293 | ahc_queue_alg alg); | 1284 | ahc_queue_alg alg); |
1294 | 1285 | ||
diff --git a/drivers/scsi/aic7xxx/aic7xxx_core.c b/drivers/scsi/aic7xxx/aic7xxx_core.c index 93e4e40944b6..50ef785224de 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_core.c +++ b/drivers/scsi/aic7xxx/aic7xxx_core.c | |||
@@ -1671,7 +1671,7 @@ ahc_devlimited_syncrate(struct ahc_softc *ahc, | |||
1671 | transinfo = &tinfo->goal; | 1671 | transinfo = &tinfo->goal; |
1672 | *ppr_options &= transinfo->ppr_options; | 1672 | *ppr_options &= transinfo->ppr_options; |
1673 | if (transinfo->width == MSG_EXT_WDTR_BUS_8_BIT) { | 1673 | if (transinfo->width == MSG_EXT_WDTR_BUS_8_BIT) { |
1674 | maxsync = MAX(maxsync, AHC_SYNCRATE_ULTRA2); | 1674 | maxsync = max(maxsync, (u_int)AHC_SYNCRATE_ULTRA2); |
1675 | *ppr_options &= ~MSG_EXT_PPR_DT_REQ; | 1675 | *ppr_options &= ~MSG_EXT_PPR_DT_REQ; |
1676 | } | 1676 | } |
1677 | if (transinfo->period == 0) { | 1677 | if (transinfo->period == 0) { |
@@ -1679,7 +1679,7 @@ ahc_devlimited_syncrate(struct ahc_softc *ahc, | |||
1679 | *ppr_options = 0; | 1679 | *ppr_options = 0; |
1680 | return (NULL); | 1680 | return (NULL); |
1681 | } | 1681 | } |
1682 | *period = MAX(*period, transinfo->period); | 1682 | *period = max(*period, (u_int)transinfo->period); |
1683 | return (ahc_find_syncrate(ahc, period, ppr_options, maxsync)); | 1683 | return (ahc_find_syncrate(ahc, period, ppr_options, maxsync)); |
1684 | } | 1684 | } |
1685 | 1685 | ||
@@ -1804,12 +1804,12 @@ ahc_validate_offset(struct ahc_softc *ahc, | |||
1804 | else | 1804 | else |
1805 | maxoffset = MAX_OFFSET_8BIT; | 1805 | maxoffset = MAX_OFFSET_8BIT; |
1806 | } | 1806 | } |
1807 | *offset = MIN(*offset, maxoffset); | 1807 | *offset = min(*offset, maxoffset); |
1808 | if (tinfo != NULL) { | 1808 | if (tinfo != NULL) { |
1809 | if (role == ROLE_TARGET) | 1809 | if (role == ROLE_TARGET) |
1810 | *offset = MIN(*offset, tinfo->user.offset); | 1810 | *offset = min(*offset, (u_int)tinfo->user.offset); |
1811 | else | 1811 | else |
1812 | *offset = MIN(*offset, tinfo->goal.offset); | 1812 | *offset = min(*offset, (u_int)tinfo->goal.offset); |
1813 | } | 1813 | } |
1814 | } | 1814 | } |
1815 | 1815 | ||
@@ -1835,9 +1835,9 @@ ahc_validate_width(struct ahc_softc *ahc, struct ahc_initiator_tinfo *tinfo, | |||
1835 | } | 1835 | } |
1836 | if (tinfo != NULL) { | 1836 | if (tinfo != NULL) { |
1837 | if (role == ROLE_TARGET) | 1837 | if (role == ROLE_TARGET) |
1838 | *bus_width = MIN(tinfo->user.width, *bus_width); | 1838 | *bus_width = min((u_int)tinfo->user.width, *bus_width); |
1839 | else | 1839 | else |
1840 | *bus_width = MIN(tinfo->goal.width, *bus_width); | 1840 | *bus_width = min((u_int)tinfo->goal.width, *bus_width); |
1841 | } | 1841 | } |
1842 | } | 1842 | } |
1843 | 1843 | ||
@@ -1986,7 +1986,7 @@ ahc_set_syncrate(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, | |||
1986 | tinfo->curr.ppr_options = ppr_options; | 1986 | tinfo->curr.ppr_options = ppr_options; |
1987 | 1987 | ||
1988 | ahc_send_async(ahc, devinfo->channel, devinfo->target, | 1988 | ahc_send_async(ahc, devinfo->channel, devinfo->target, |
1989 | CAM_LUN_WILDCARD, AC_TRANSFER_NEG, NULL); | 1989 | CAM_LUN_WILDCARD, AC_TRANSFER_NEG); |
1990 | if (bootverbose) { | 1990 | if (bootverbose) { |
1991 | if (offset != 0) { | 1991 | if (offset != 0) { |
1992 | printf("%s: target %d synchronous at %sMHz%s, " | 1992 | printf("%s: target %d synchronous at %sMHz%s, " |
@@ -2056,7 +2056,7 @@ ahc_set_width(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, | |||
2056 | tinfo->curr.width = width; | 2056 | tinfo->curr.width = width; |
2057 | 2057 | ||
2058 | ahc_send_async(ahc, devinfo->channel, devinfo->target, | 2058 | ahc_send_async(ahc, devinfo->channel, devinfo->target, |
2059 | CAM_LUN_WILDCARD, AC_TRANSFER_NEG, NULL); | 2059 | CAM_LUN_WILDCARD, AC_TRANSFER_NEG); |
2060 | if (bootverbose) { | 2060 | if (bootverbose) { |
2061 | printf("%s: target %d using %dbit transfers\n", | 2061 | printf("%s: target %d using %dbit transfers\n", |
2062 | ahc_name(ahc), devinfo->target, | 2062 | ahc_name(ahc), devinfo->target, |
@@ -2074,12 +2074,14 @@ ahc_set_width(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, | |||
2074 | * Update the current state of tagged queuing for a given target. | 2074 | * Update the current state of tagged queuing for a given target. |
2075 | */ | 2075 | */ |
2076 | void | 2076 | void |
2077 | ahc_set_tags(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, | 2077 | ahc_set_tags(struct ahc_softc *ahc, struct scsi_cmnd *cmd, |
2078 | ahc_queue_alg alg) | 2078 | struct ahc_devinfo *devinfo, ahc_queue_alg alg) |
2079 | { | 2079 | { |
2080 | ahc_platform_set_tags(ahc, devinfo, alg); | 2080 | struct scsi_device *sdev = cmd->device; |
2081 | |||
2082 | ahc_platform_set_tags(ahc, sdev, devinfo, alg); | ||
2081 | ahc_send_async(ahc, devinfo->channel, devinfo->target, | 2083 | ahc_send_async(ahc, devinfo->channel, devinfo->target, |
2082 | devinfo->lun, AC_TRANSFER_NEG, &alg); | 2084 | devinfo->lun, AC_TRANSFER_NEG); |
2083 | } | 2085 | } |
2084 | 2086 | ||
2085 | /* | 2087 | /* |
@@ -3489,7 +3491,7 @@ ahc_handle_msg_reject(struct ahc_softc *ahc, struct ahc_devinfo *devinfo) | |||
3489 | printf("(%s:%c:%d:%d): refuses tagged commands. " | 3491 | printf("(%s:%c:%d:%d): refuses tagged commands. " |
3490 | "Performing non-tagged I/O\n", ahc_name(ahc), | 3492 | "Performing non-tagged I/O\n", ahc_name(ahc), |
3491 | devinfo->channel, devinfo->target, devinfo->lun); | 3493 | devinfo->channel, devinfo->target, devinfo->lun); |
3492 | ahc_set_tags(ahc, devinfo, AHC_QUEUE_NONE); | 3494 | ahc_set_tags(ahc, scb->io_ctx, devinfo, AHC_QUEUE_NONE); |
3493 | mask = ~0x23; | 3495 | mask = ~0x23; |
3494 | } else { | 3496 | } else { |
3495 | printf("(%s:%c:%d:%d): refuses %s tagged commands. " | 3497 | printf("(%s:%c:%d:%d): refuses %s tagged commands. " |
@@ -3497,7 +3499,7 @@ ahc_handle_msg_reject(struct ahc_softc *ahc, struct ahc_devinfo *devinfo) | |||
3497 | ahc_name(ahc), devinfo->channel, devinfo->target, | 3499 | ahc_name(ahc), devinfo->channel, devinfo->target, |
3498 | devinfo->lun, tag_type == MSG_ORDERED_TASK | 3500 | devinfo->lun, tag_type == MSG_ORDERED_TASK |
3499 | ? "ordered" : "head of queue"); | 3501 | ? "ordered" : "head of queue"); |
3500 | ahc_set_tags(ahc, devinfo, AHC_QUEUE_BASIC); | 3502 | ahc_set_tags(ahc, scb->io_ctx, devinfo, AHC_QUEUE_BASIC); |
3501 | mask = ~0x03; | 3503 | mask = ~0x03; |
3502 | } | 3504 | } |
3503 | 3505 | ||
@@ -3763,7 +3765,7 @@ ahc_handle_devreset(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, | |||
3763 | 3765 | ||
3764 | if (status != CAM_SEL_TIMEOUT) | 3766 | if (status != CAM_SEL_TIMEOUT) |
3765 | ahc_send_async(ahc, devinfo->channel, devinfo->target, | 3767 | ahc_send_async(ahc, devinfo->channel, devinfo->target, |
3766 | CAM_LUN_WILDCARD, AC_SENT_BDR, NULL); | 3768 | CAM_LUN_WILDCARD, AC_SENT_BDR); |
3767 | 3769 | ||
3768 | if (message != NULL | 3770 | if (message != NULL |
3769 | && (verbose_level <= bootverbose)) | 3771 | && (verbose_level <= bootverbose)) |
@@ -4406,7 +4408,7 @@ ahc_alloc_scbs(struct ahc_softc *ahc) | |||
4406 | physaddr = sg_map->sg_physaddr; | 4408 | physaddr = sg_map->sg_physaddr; |
4407 | 4409 | ||
4408 | newcount = (PAGE_SIZE / (AHC_NSEG * sizeof(struct ahc_dma_seg))); | 4410 | newcount = (PAGE_SIZE / (AHC_NSEG * sizeof(struct ahc_dma_seg))); |
4409 | newcount = MIN(newcount, (AHC_SCB_MAX_ALLOC - scb_data->numscbs)); | 4411 | newcount = min(newcount, (AHC_SCB_MAX_ALLOC - scb_data->numscbs)); |
4410 | for (i = 0; i < newcount; i++) { | 4412 | for (i = 0; i < newcount; i++) { |
4411 | struct scb_platform_data *pdata; | 4413 | struct scb_platform_data *pdata; |
4412 | #ifndef __linux__ | 4414 | #ifndef __linux__ |
@@ -6018,7 +6020,7 @@ ahc_reset_channel(struct ahc_softc *ahc, char channel, int initiate_reset) | |||
6018 | #endif | 6020 | #endif |
6019 | /* Notify the XPT that a bus reset occurred */ | 6021 | /* Notify the XPT that a bus reset occurred */ |
6020 | ahc_send_async(ahc, devinfo.channel, CAM_TARGET_WILDCARD, | 6022 | ahc_send_async(ahc, devinfo.channel, CAM_TARGET_WILDCARD, |
6021 | CAM_LUN_WILDCARD, AC_BUS_RESET, NULL); | 6023 | CAM_LUN_WILDCARD, AC_BUS_RESET); |
6022 | 6024 | ||
6023 | /* | 6025 | /* |
6024 | * Revert to async/narrow transfers until we renegotiate. | 6026 | * Revert to async/narrow transfers until we renegotiate. |
@@ -6442,7 +6444,7 @@ ahc_download_instr(struct ahc_softc *ahc, u_int instrptr, uint8_t *dconsts) | |||
6442 | if (skip_addr > i) { | 6444 | if (skip_addr > i) { |
6443 | int end_addr; | 6445 | int end_addr; |
6444 | 6446 | ||
6445 | end_addr = MIN(address, skip_addr); | 6447 | end_addr = min(address, skip_addr); |
6446 | address_offset += end_addr - i; | 6448 | address_offset += end_addr - i; |
6447 | i = skip_addr; | 6449 | i = skip_addr; |
6448 | } else { | 6450 | } else { |
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c index 43ab753d2739..660f26e23a38 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c | |||
@@ -328,7 +328,7 @@ static uint32_t aic7xxx_seltime; | |||
328 | * force all outstanding transactions to be serviced prior to a new | 328 | * force all outstanding transactions to be serviced prior to a new |
329 | * transaction. | 329 | * transaction. |
330 | */ | 330 | */ |
331 | uint32_t aic7xxx_periodic_otag; | 331 | static uint32_t aic7xxx_periodic_otag; |
332 | 332 | ||
333 | /* | 333 | /* |
334 | * Module information and settable options. | 334 | * Module information and settable options. |
@@ -512,7 +512,6 @@ ahc_linux_target_alloc(struct scsi_target *starget) | |||
512 | struct seeprom_config *sc = ahc->seep_config; | 512 | struct seeprom_config *sc = ahc->seep_config; |
513 | unsigned long flags; | 513 | unsigned long flags; |
514 | struct scsi_target **ahc_targp = ahc_linux_target_in_softc(starget); | 514 | struct scsi_target **ahc_targp = ahc_linux_target_in_softc(starget); |
515 | struct ahc_linux_target *targ = scsi_transport_target_data(starget); | ||
516 | unsigned short scsirate; | 515 | unsigned short scsirate; |
517 | struct ahc_devinfo devinfo; | 516 | struct ahc_devinfo devinfo; |
518 | struct ahc_initiator_tinfo *tinfo; | 517 | struct ahc_initiator_tinfo *tinfo; |
@@ -533,7 +532,6 @@ ahc_linux_target_alloc(struct scsi_target *starget) | |||
533 | BUG_ON(*ahc_targp != NULL); | 532 | BUG_ON(*ahc_targp != NULL); |
534 | 533 | ||
535 | *ahc_targp = starget; | 534 | *ahc_targp = starget; |
536 | memset(targ, 0, sizeof(*targ)); | ||
537 | 535 | ||
538 | if (sc) { | 536 | if (sc) { |
539 | int maxsync = AHC_SYNCRATE_DT; | 537 | int maxsync = AHC_SYNCRATE_DT; |
@@ -594,14 +592,11 @@ ahc_linux_slave_alloc(struct scsi_device *sdev) | |||
594 | struct ahc_softc *ahc = | 592 | struct ahc_softc *ahc = |
595 | *((struct ahc_softc **)sdev->host->hostdata); | 593 | *((struct ahc_softc **)sdev->host->hostdata); |
596 | struct scsi_target *starget = sdev->sdev_target; | 594 | struct scsi_target *starget = sdev->sdev_target; |
597 | struct ahc_linux_target *targ = scsi_transport_target_data(starget); | ||
598 | struct ahc_linux_device *dev; | 595 | struct ahc_linux_device *dev; |
599 | 596 | ||
600 | if (bootverbose) | 597 | if (bootverbose) |
601 | printf("%s: Slave Alloc %d\n", ahc_name(ahc), sdev->id); | 598 | printf("%s: Slave Alloc %d\n", ahc_name(ahc), sdev->id); |
602 | 599 | ||
603 | BUG_ON(targ->sdev[sdev->lun] != NULL); | ||
604 | |||
605 | dev = scsi_transport_device_data(sdev); | 600 | dev = scsi_transport_device_data(sdev); |
606 | memset(dev, 0, sizeof(*dev)); | 601 | memset(dev, 0, sizeof(*dev)); |
607 | 602 | ||
@@ -618,8 +613,6 @@ ahc_linux_slave_alloc(struct scsi_device *sdev) | |||
618 | */ | 613 | */ |
619 | dev->maxtags = 0; | 614 | dev->maxtags = 0; |
620 | 615 | ||
621 | targ->sdev[sdev->lun] = sdev; | ||
622 | |||
623 | spi_period(starget) = 0; | 616 | spi_period(starget) = 0; |
624 | 617 | ||
625 | return 0; | 618 | return 0; |
@@ -644,22 +637,6 @@ ahc_linux_slave_configure(struct scsi_device *sdev) | |||
644 | return 0; | 637 | return 0; |
645 | } | 638 | } |
646 | 639 | ||
647 | static void | ||
648 | ahc_linux_slave_destroy(struct scsi_device *sdev) | ||
649 | { | ||
650 | struct ahc_softc *ahc; | ||
651 | struct ahc_linux_device *dev = scsi_transport_device_data(sdev); | ||
652 | struct ahc_linux_target *targ = scsi_transport_target_data(sdev->sdev_target); | ||
653 | |||
654 | ahc = *((struct ahc_softc **)sdev->host->hostdata); | ||
655 | if (bootverbose) | ||
656 | printf("%s: Slave Destroy %d\n", ahc_name(ahc), sdev->id); | ||
657 | |||
658 | BUG_ON(dev->active); | ||
659 | |||
660 | targ->sdev[sdev->lun] = NULL; | ||
661 | } | ||
662 | |||
663 | #if defined(__i386__) | 640 | #if defined(__i386__) |
664 | /* | 641 | /* |
665 | * Return the disk geometry for the given SCSI device. | 642 | * Return the disk geometry for the given SCSI device. |
@@ -777,11 +754,11 @@ struct scsi_host_template aic7xxx_driver_template = { | |||
777 | #endif | 754 | #endif |
778 | .can_queue = AHC_MAX_QUEUE, | 755 | .can_queue = AHC_MAX_QUEUE, |
779 | .this_id = -1, | 756 | .this_id = -1, |
757 | .max_sectors = 8192, | ||
780 | .cmd_per_lun = 2, | 758 | .cmd_per_lun = 2, |
781 | .use_clustering = ENABLE_CLUSTERING, | 759 | .use_clustering = ENABLE_CLUSTERING, |
782 | .slave_alloc = ahc_linux_slave_alloc, | 760 | .slave_alloc = ahc_linux_slave_alloc, |
783 | .slave_configure = ahc_linux_slave_configure, | 761 | .slave_configure = ahc_linux_slave_configure, |
784 | .slave_destroy = ahc_linux_slave_destroy, | ||
785 | .target_alloc = ahc_linux_target_alloc, | 762 | .target_alloc = ahc_linux_target_alloc, |
786 | .target_destroy = ahc_linux_target_destroy, | 763 | .target_destroy = ahc_linux_target_destroy, |
787 | }; | 764 | }; |
@@ -1203,21 +1180,13 @@ void | |||
1203 | ahc_platform_free(struct ahc_softc *ahc) | 1180 | ahc_platform_free(struct ahc_softc *ahc) |
1204 | { | 1181 | { |
1205 | struct scsi_target *starget; | 1182 | struct scsi_target *starget; |
1206 | int i, j; | 1183 | int i; |
1207 | 1184 | ||
1208 | if (ahc->platform_data != NULL) { | 1185 | if (ahc->platform_data != NULL) { |
1209 | /* destroy all of the device and target objects */ | 1186 | /* destroy all of the device and target objects */ |
1210 | for (i = 0; i < AHC_NUM_TARGETS; i++) { | 1187 | for (i = 0; i < AHC_NUM_TARGETS; i++) { |
1211 | starget = ahc->platform_data->starget[i]; | 1188 | starget = ahc->platform_data->starget[i]; |
1212 | if (starget != NULL) { | 1189 | if (starget != NULL) { |
1213 | for (j = 0; j < AHC_NUM_LUNS; j++) { | ||
1214 | struct ahc_linux_target *targ = | ||
1215 | scsi_transport_target_data(starget); | ||
1216 | |||
1217 | if (targ->sdev[j] == NULL) | ||
1218 | continue; | ||
1219 | targ->sdev[j] = NULL; | ||
1220 | } | ||
1221 | ahc->platform_data->starget[i] = NULL; | 1190 | ahc->platform_data->starget[i] = NULL; |
1222 | } | 1191 | } |
1223 | } | 1192 | } |
@@ -1251,24 +1220,13 @@ ahc_platform_freeze_devq(struct ahc_softc *ahc, struct scb *scb) | |||
1251 | } | 1220 | } |
1252 | 1221 | ||
1253 | void | 1222 | void |
1254 | ahc_platform_set_tags(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, | 1223 | ahc_platform_set_tags(struct ahc_softc *ahc, struct scsi_device *sdev, |
1255 | ahc_queue_alg alg) | 1224 | struct ahc_devinfo *devinfo, ahc_queue_alg alg) |
1256 | { | 1225 | { |
1257 | struct scsi_target *starget; | ||
1258 | struct ahc_linux_target *targ; | ||
1259 | struct ahc_linux_device *dev; | 1226 | struct ahc_linux_device *dev; |
1260 | struct scsi_device *sdev; | ||
1261 | u_int target_offset; | ||
1262 | int was_queuing; | 1227 | int was_queuing; |
1263 | int now_queuing; | 1228 | int now_queuing; |
1264 | 1229 | ||
1265 | target_offset = devinfo->target; | ||
1266 | if (devinfo->channel != 'A') | ||
1267 | target_offset += 8; | ||
1268 | starget = ahc->platform_data->starget[target_offset]; | ||
1269 | targ = scsi_transport_target_data(starget); | ||
1270 | BUG_ON(targ == NULL); | ||
1271 | sdev = targ->sdev[devinfo->lun]; | ||
1272 | if (sdev == NULL) | 1230 | if (sdev == NULL) |
1273 | return; | 1231 | return; |
1274 | dev = scsi_transport_device_data(sdev); | 1232 | dev = scsi_transport_device_data(sdev); |
@@ -1401,11 +1359,15 @@ ahc_linux_device_queue_depth(struct scsi_device *sdev) | |||
1401 | tags = ahc_linux_user_tagdepth(ahc, &devinfo); | 1359 | tags = ahc_linux_user_tagdepth(ahc, &devinfo); |
1402 | if (tags != 0 && sdev->tagged_supported != 0) { | 1360 | if (tags != 0 && sdev->tagged_supported != 0) { |
1403 | 1361 | ||
1404 | ahc_set_tags(ahc, &devinfo, AHC_QUEUE_TAGGED); | 1362 | ahc_platform_set_tags(ahc, sdev, &devinfo, AHC_QUEUE_TAGGED); |
1363 | ahc_send_async(ahc, devinfo.channel, devinfo.target, | ||
1364 | devinfo.lun, AC_TRANSFER_NEG); | ||
1405 | ahc_print_devinfo(ahc, &devinfo); | 1365 | ahc_print_devinfo(ahc, &devinfo); |
1406 | printf("Tagged Queuing enabled. Depth %d\n", tags); | 1366 | printf("Tagged Queuing enabled. Depth %d\n", tags); |
1407 | } else { | 1367 | } else { |
1408 | ahc_set_tags(ahc, &devinfo, AHC_QUEUE_NONE); | 1368 | ahc_platform_set_tags(ahc, sdev, &devinfo, AHC_QUEUE_NONE); |
1369 | ahc_send_async(ahc, devinfo.channel, devinfo.target, | ||
1370 | devinfo.lun, AC_TRANSFER_NEG); | ||
1409 | } | 1371 | } |
1410 | } | 1372 | } |
1411 | 1373 | ||
@@ -1629,7 +1591,7 @@ ahc_platform_flushwork(struct ahc_softc *ahc) | |||
1629 | 1591 | ||
1630 | void | 1592 | void |
1631 | ahc_send_async(struct ahc_softc *ahc, char channel, | 1593 | ahc_send_async(struct ahc_softc *ahc, char channel, |
1632 | u_int target, u_int lun, ac_code code, void *arg) | 1594 | u_int target, u_int lun, ac_code code) |
1633 | { | 1595 | { |
1634 | switch (code) { | 1596 | switch (code) { |
1635 | case AC_TRANSFER_NEG: | 1597 | case AC_TRANSFER_NEG: |
@@ -1875,9 +1837,9 @@ ahc_linux_handle_scsi_status(struct ahc_softc *ahc, | |||
1875 | if (scb->flags & SCB_SENSE) { | 1837 | if (scb->flags & SCB_SENSE) { |
1876 | u_int sense_size; | 1838 | u_int sense_size; |
1877 | 1839 | ||
1878 | sense_size = MIN(sizeof(struct scsi_sense_data) | 1840 | sense_size = min(sizeof(struct scsi_sense_data) |
1879 | - ahc_get_sense_residual(scb), | 1841 | - ahc_get_sense_residual(scb), |
1880 | sizeof(cmd->sense_buffer)); | 1842 | (u_long)sizeof(cmd->sense_buffer)); |
1881 | memcpy(cmd->sense_buffer, | 1843 | memcpy(cmd->sense_buffer, |
1882 | ahc_get_sense_buf(ahc, scb), sense_size); | 1844 | ahc_get_sense_buf(ahc, scb), sense_size); |
1883 | if (sense_size < sizeof(cmd->sense_buffer)) | 1845 | if (sense_size < sizeof(cmd->sense_buffer)) |
@@ -1946,7 +1908,7 @@ ahc_linux_handle_scsi_status(struct ahc_softc *ahc, | |||
1946 | } | 1908 | } |
1947 | ahc_set_transaction_status(scb, CAM_REQUEUE_REQ); | 1909 | ahc_set_transaction_status(scb, CAM_REQUEUE_REQ); |
1948 | ahc_set_scsi_status(scb, SCSI_STATUS_OK); | 1910 | ahc_set_scsi_status(scb, SCSI_STATUS_OK); |
1949 | ahc_platform_set_tags(ahc, &devinfo, | 1911 | ahc_platform_set_tags(ahc, sdev, &devinfo, |
1950 | (dev->flags & AHC_DEV_Q_BASIC) | 1912 | (dev->flags & AHC_DEV_Q_BASIC) |
1951 | ? AHC_QUEUE_BASIC : AHC_QUEUE_TAGGED); | 1913 | ? AHC_QUEUE_BASIC : AHC_QUEUE_TAGGED); |
1952 | break; | 1914 | break; |
@@ -1957,7 +1919,7 @@ ahc_linux_handle_scsi_status(struct ahc_softc *ahc, | |||
1957 | */ | 1919 | */ |
1958 | dev->openings = 1; | 1920 | dev->openings = 1; |
1959 | ahc_set_scsi_status(scb, SCSI_STATUS_BUSY); | 1921 | ahc_set_scsi_status(scb, SCSI_STATUS_BUSY); |
1960 | ahc_platform_set_tags(ahc, &devinfo, | 1922 | ahc_platform_set_tags(ahc, sdev, &devinfo, |
1961 | (dev->flags & AHC_DEV_Q_BASIC) | 1923 | (dev->flags & AHC_DEV_Q_BASIC) |
1962 | ? AHC_QUEUE_BASIC : AHC_QUEUE_TAGGED); | 1924 | ? AHC_QUEUE_BASIC : AHC_QUEUE_TAGGED); |
1963 | break; | 1925 | break; |
@@ -2599,8 +2561,6 @@ ahc_linux_init(void) | |||
2599 | if (!ahc_linux_transport_template) | 2561 | if (!ahc_linux_transport_template) |
2600 | return -ENODEV; | 2562 | return -ENODEV; |
2601 | 2563 | ||
2602 | scsi_transport_reserve_target(ahc_linux_transport_template, | ||
2603 | sizeof(struct ahc_linux_target)); | ||
2604 | scsi_transport_reserve_device(ahc_linux_transport_template, | 2564 | scsi_transport_reserve_device(ahc_linux_transport_template, |
2605 | sizeof(struct ahc_linux_device)); | 2565 | sizeof(struct ahc_linux_device)); |
2606 | 2566 | ||
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h index a87a4ce090df..85ae5d836fa4 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.h +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h | |||
@@ -256,7 +256,6 @@ typedef enum { | |||
256 | AHC_DEV_PERIODIC_OTAG = 0x40, /* Send OTAG to prevent starvation */ | 256 | AHC_DEV_PERIODIC_OTAG = 0x40, /* Send OTAG to prevent starvation */ |
257 | } ahc_linux_dev_flags; | 257 | } ahc_linux_dev_flags; |
258 | 258 | ||
259 | struct ahc_linux_target; | ||
260 | struct ahc_linux_device { | 259 | struct ahc_linux_device { |
261 | /* | 260 | /* |
262 | * The number of transactions currently | 261 | * The number of transactions currently |
@@ -329,12 +328,6 @@ struct ahc_linux_device { | |||
329 | #define AHC_OTAG_THRESH 500 | 328 | #define AHC_OTAG_THRESH 500 |
330 | }; | 329 | }; |
331 | 330 | ||
332 | struct ahc_linux_target { | ||
333 | struct scsi_device *sdev[AHC_NUM_LUNS]; | ||
334 | struct ahc_transinfo last_tinfo; | ||
335 | struct ahc_softc *ahc; | ||
336 | }; | ||
337 | |||
338 | /********************* Definitions Required by the Core ***********************/ | 331 | /********************* Definitions Required by the Core ***********************/ |
339 | /* | 332 | /* |
340 | * Number of SG segments we require. So long as the S/G segments for | 333 | * Number of SG segments we require. So long as the S/G segments for |
@@ -533,8 +526,6 @@ ahc_unlock(struct ahc_softc *ahc, unsigned long *flags) | |||
533 | #define PCIR_SUBVEND_0 0x2c | 526 | #define PCIR_SUBVEND_0 0x2c |
534 | #define PCIR_SUBDEV_0 0x2e | 527 | #define PCIR_SUBDEV_0 0x2e |
535 | 528 | ||
536 | extern struct pci_driver aic7xxx_pci_driver; | ||
537 | |||
538 | typedef enum | 529 | typedef enum |
539 | { | 530 | { |
540 | AHC_POWER_STATE_D0, | 531 | AHC_POWER_STATE_D0, |
@@ -824,7 +815,7 @@ ahc_freeze_scb(struct scb *scb) | |||
824 | } | 815 | } |
825 | } | 816 | } |
826 | 817 | ||
827 | void ahc_platform_set_tags(struct ahc_softc *ahc, | 818 | void ahc_platform_set_tags(struct ahc_softc *ahc, struct scsi_device *sdev, |
828 | struct ahc_devinfo *devinfo, ahc_queue_alg); | 819 | struct ahc_devinfo *devinfo, ahc_queue_alg); |
829 | int ahc_platform_abort_scbs(struct ahc_softc *ahc, int target, | 820 | int ahc_platform_abort_scbs(struct ahc_softc *ahc, int target, |
830 | char channel, int lun, u_int tag, | 821 | char channel, int lun, u_int tag, |
@@ -834,7 +825,7 @@ irqreturn_t | |||
834 | void ahc_platform_flushwork(struct ahc_softc *ahc); | 825 | void ahc_platform_flushwork(struct ahc_softc *ahc); |
835 | void ahc_done(struct ahc_softc*, struct scb*); | 826 | void ahc_done(struct ahc_softc*, struct scb*); |
836 | void ahc_send_async(struct ahc_softc *, char channel, | 827 | void ahc_send_async(struct ahc_softc *, char channel, |
837 | u_int target, u_int lun, ac_code, void *); | 828 | u_int target, u_int lun, ac_code); |
838 | void ahc_print_path(struct ahc_softc *, struct scb *); | 829 | void ahc_print_path(struct ahc_softc *, struct scb *); |
839 | void ahc_platform_dump_card_state(struct ahc_softc *ahc); | 830 | void ahc_platform_dump_card_state(struct ahc_softc *ahc); |
840 | 831 | ||
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c index d20ca514e9f3..ea5687df732d 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c | |||
@@ -130,7 +130,7 @@ static struct pci_device_id ahc_linux_pci_id_table[] = { | |||
130 | 130 | ||
131 | MODULE_DEVICE_TABLE(pci, ahc_linux_pci_id_table); | 131 | MODULE_DEVICE_TABLE(pci, ahc_linux_pci_id_table); |
132 | 132 | ||
133 | struct pci_driver aic7xxx_pci_driver = { | 133 | static struct pci_driver aic7xxx_pci_driver = { |
134 | .name = "aic7xxx", | 134 | .name = "aic7xxx", |
135 | .probe = ahc_linux_pci_dev_probe, | 135 | .probe = ahc_linux_pci_dev_probe, |
136 | .remove = ahc_linux_pci_dev_remove, | 136 | .remove = ahc_linux_pci_dev_remove, |
diff --git a/drivers/scsi/aic7xxx/aic7xxx_pci.c b/drivers/scsi/aic7xxx/aic7xxx_pci.c index 63cab2d74552..09c8172c9e5e 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_pci.c +++ b/drivers/scsi/aic7xxx/aic7xxx_pci.c | |||
@@ -168,7 +168,7 @@ static ahc_device_setup_t ahc_aha394XX_setup; | |||
168 | static ahc_device_setup_t ahc_aha494XX_setup; | 168 | static ahc_device_setup_t ahc_aha494XX_setup; |
169 | static ahc_device_setup_t ahc_aha398XX_setup; | 169 | static ahc_device_setup_t ahc_aha398XX_setup; |
170 | 170 | ||
171 | struct ahc_pci_identity ahc_pci_ident_table [] = | 171 | static struct ahc_pci_identity ahc_pci_ident_table [] = |
172 | { | 172 | { |
173 | /* aic7850 based controllers */ | 173 | /* aic7850 based controllers */ |
174 | { | 174 | { |
@@ -559,7 +559,7 @@ struct ahc_pci_identity ahc_pci_ident_table [] = | |||
559 | } | 559 | } |
560 | }; | 560 | }; |
561 | 561 | ||
562 | const u_int ahc_num_pci_devs = ARRAY_SIZE(ahc_pci_ident_table); | 562 | static const u_int ahc_num_pci_devs = ARRAY_SIZE(ahc_pci_ident_table); |
563 | 563 | ||
564 | #define AHC_394X_SLOT_CHANNEL_A 4 | 564 | #define AHC_394X_SLOT_CHANNEL_A 4 |
565 | #define AHC_394X_SLOT_CHANNEL_B 5 | 565 | #define AHC_394X_SLOT_CHANNEL_B 5 |
diff --git a/drivers/scsi/aic7xxx/aic7xxx_proc.c b/drivers/scsi/aic7xxx/aic7xxx_proc.c index 5914b4aa4a8f..99e5443e7535 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_proc.c +++ b/drivers/scsi/aic7xxx/aic7xxx_proc.c | |||
@@ -182,7 +182,6 @@ ahc_dump_target_state(struct ahc_softc *ahc, struct info_str *info, | |||
182 | u_int our_id, char channel, u_int target_id, | 182 | u_int our_id, char channel, u_int target_id, |
183 | u_int target_offset) | 183 | u_int target_offset) |
184 | { | 184 | { |
185 | struct ahc_linux_target *targ; | ||
186 | struct scsi_target *starget; | 185 | struct scsi_target *starget; |
187 | struct ahc_initiator_tinfo *tinfo; | 186 | struct ahc_initiator_tinfo *tinfo; |
188 | struct ahc_tmode_tstate *tstate; | 187 | struct ahc_tmode_tstate *tstate; |
@@ -198,7 +197,6 @@ ahc_dump_target_state(struct ahc_softc *ahc, struct info_str *info, | |||
198 | starget = ahc->platform_data->starget[target_offset]; | 197 | starget = ahc->platform_data->starget[target_offset]; |
199 | if (!starget) | 198 | if (!starget) |
200 | return; | 199 | return; |
201 | targ = scsi_transport_target_data(starget); | ||
202 | 200 | ||
203 | copy_info(info, "\tGoal: "); | 201 | copy_info(info, "\tGoal: "); |
204 | ahc_format_transinfo(info, &tinfo->goal); | 202 | ahc_format_transinfo(info, &tinfo->goal); |
@@ -208,7 +206,7 @@ ahc_dump_target_state(struct ahc_softc *ahc, struct info_str *info, | |||
208 | for (lun = 0; lun < AHC_NUM_LUNS; lun++) { | 206 | for (lun = 0; lun < AHC_NUM_LUNS; lun++) { |
209 | struct scsi_device *sdev; | 207 | struct scsi_device *sdev; |
210 | 208 | ||
211 | sdev = targ->sdev[lun]; | 209 | sdev = scsi_device_lookup_by_target(starget, lun); |
212 | 210 | ||
213 | if (sdev == NULL) | 211 | if (sdev == NULL) |
214 | continue; | 212 | continue; |
@@ -383,11 +381,11 @@ ahc_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start, | |||
383 | } | 381 | } |
384 | copy_info(&info, "\n"); | 382 | copy_info(&info, "\n"); |
385 | 383 | ||
386 | max_targ = 15; | 384 | max_targ = 16; |
387 | if ((ahc->features & (AHC_WIDE|AHC_TWIN)) == 0) | 385 | if ((ahc->features & (AHC_WIDE|AHC_TWIN)) == 0) |
388 | max_targ = 7; | 386 | max_targ = 8; |
389 | 387 | ||
390 | for (i = 0; i <= max_targ; i++) { | 388 | for (i = 0; i < max_targ; i++) { |
391 | u_int our_id; | 389 | u_int our_id; |
392 | u_int target_id; | 390 | u_int target_id; |
393 | char channel; | 391 | char channel; |
diff --git a/drivers/scsi/aic7xxx_old.c b/drivers/scsi/aic7xxx_old.c index bcd7fffab907..46eed10b25d9 100644 --- a/drivers/scsi/aic7xxx_old.c +++ b/drivers/scsi/aic7xxx_old.c | |||
@@ -2646,7 +2646,7 @@ static void aic7xxx_done_cmds_complete(struct aic7xxx_host *p) | |||
2646 | 2646 | ||
2647 | while (p->completeq.head != NULL) { | 2647 | while (p->completeq.head != NULL) { |
2648 | cmd = p->completeq.head; | 2648 | cmd = p->completeq.head; |
2649 | p->completeq.head = (struct scsi_Cmnd *) cmd->host_scribble; | 2649 | p->completeq.head = (struct scsi_cmnd *) cmd->host_scribble; |
2650 | cmd->host_scribble = NULL; | 2650 | cmd->host_scribble = NULL; |
2651 | cmd->scsi_done(cmd); | 2651 | cmd->scsi_done(cmd); |
2652 | } | 2652 | } |
diff --git a/drivers/scsi/aic94xx/aic94xx_hwi.c b/drivers/scsi/aic94xx/aic94xx_hwi.c index 3c2d7a379931..af7e01134364 100644 --- a/drivers/scsi/aic94xx/aic94xx_hwi.c +++ b/drivers/scsi/aic94xx/aic94xx_hwi.c | |||
@@ -112,6 +112,21 @@ static int asd_init_phy(struct asd_phy *phy) | |||
112 | return 0; | 112 | return 0; |
113 | } | 113 | } |
114 | 114 | ||
115 | static void asd_init_ports(struct asd_ha_struct *asd_ha) | ||
116 | { | ||
117 | int i; | ||
118 | |||
119 | spin_lock_init(&asd_ha->asd_ports_lock); | ||
120 | for (i = 0; i < ASD_MAX_PHYS; i++) { | ||
121 | struct asd_port *asd_port = &asd_ha->asd_ports[i]; | ||
122 | |||
123 | memset(asd_port->sas_addr, 0, SAS_ADDR_SIZE); | ||
124 | memset(asd_port->attached_sas_addr, 0, SAS_ADDR_SIZE); | ||
125 | asd_port->phy_mask = 0; | ||
126 | asd_port->num_phys = 0; | ||
127 | } | ||
128 | } | ||
129 | |||
115 | static int asd_init_phys(struct asd_ha_struct *asd_ha) | 130 | static int asd_init_phys(struct asd_ha_struct *asd_ha) |
116 | { | 131 | { |
117 | u8 i; | 132 | u8 i; |
@@ -121,6 +136,7 @@ static int asd_init_phys(struct asd_ha_struct *asd_ha) | |||
121 | struct asd_phy *phy = &asd_ha->phys[i]; | 136 | struct asd_phy *phy = &asd_ha->phys[i]; |
122 | 137 | ||
123 | phy->phy_desc = &asd_ha->hw_prof.phy_desc[i]; | 138 | phy->phy_desc = &asd_ha->hw_prof.phy_desc[i]; |
139 | phy->asd_port = NULL; | ||
124 | 140 | ||
125 | phy->sas_phy.enabled = 0; | 141 | phy->sas_phy.enabled = 0; |
126 | phy->sas_phy.id = i; | 142 | phy->sas_phy.id = i; |
@@ -658,6 +674,8 @@ int asd_init_hw(struct asd_ha_struct *asd_ha) | |||
658 | goto Out; | 674 | goto Out; |
659 | } | 675 | } |
660 | 676 | ||
677 | asd_init_ports(asd_ha); | ||
678 | |||
661 | err = asd_init_scbs(asd_ha); | 679 | err = asd_init_scbs(asd_ha); |
662 | if (err) { | 680 | if (err) { |
663 | asd_printk("couldn't initialize scbs for %s\n", | 681 | asd_printk("couldn't initialize scbs for %s\n", |
diff --git a/drivers/scsi/aic94xx/aic94xx_hwi.h b/drivers/scsi/aic94xx/aic94xx_hwi.h index 14319d1d6804..c6c3d18222fa 100644 --- a/drivers/scsi/aic94xx/aic94xx_hwi.h +++ b/drivers/scsi/aic94xx/aic94xx_hwi.h | |||
@@ -46,6 +46,7 @@ | |||
46 | #define PCI_DEVICE_ID_ADAPTEC2_RAZOR10 0x410 | 46 | #define PCI_DEVICE_ID_ADAPTEC2_RAZOR10 0x410 |
47 | #define PCI_DEVICE_ID_ADAPTEC2_RAZOR12 0x412 | 47 | #define PCI_DEVICE_ID_ADAPTEC2_RAZOR12 0x412 |
48 | #define PCI_DEVICE_ID_ADAPTEC2_RAZOR1E 0x41E | 48 | #define PCI_DEVICE_ID_ADAPTEC2_RAZOR1E 0x41E |
49 | #define PCI_DEVICE_ID_ADAPTEC2_RAZOR1F 0x41F | ||
49 | #define PCI_DEVICE_ID_ADAPTEC2_RAZOR30 0x430 | 50 | #define PCI_DEVICE_ID_ADAPTEC2_RAZOR30 0x430 |
50 | #define PCI_DEVICE_ID_ADAPTEC2_RAZOR32 0x432 | 51 | #define PCI_DEVICE_ID_ADAPTEC2_RAZOR32 0x432 |
51 | #define PCI_DEVICE_ID_ADAPTEC2_RAZOR3E 0x43E | 52 | #define PCI_DEVICE_ID_ADAPTEC2_RAZOR3E 0x43E |
@@ -192,6 +193,16 @@ struct asd_seq_data { | |||
192 | struct asd_ascb **escb_arr; /* array of pointers to escbs */ | 193 | struct asd_ascb **escb_arr; /* array of pointers to escbs */ |
193 | }; | 194 | }; |
194 | 195 | ||
196 | /* This is an internal port structure. These are used to get accurate | ||
197 | * phy_mask for updating DDB 0. | ||
198 | */ | ||
199 | struct asd_port { | ||
200 | u8 sas_addr[SAS_ADDR_SIZE]; | ||
201 | u8 attached_sas_addr[SAS_ADDR_SIZE]; | ||
202 | u32 phy_mask; | ||
203 | int num_phys; | ||
204 | }; | ||
205 | |||
195 | /* This is the Host Adapter structure. It describes the hardware | 206 | /* This is the Host Adapter structure. It describes the hardware |
196 | * SAS adapter. | 207 | * SAS adapter. |
197 | */ | 208 | */ |
@@ -210,6 +221,8 @@ struct asd_ha_struct { | |||
210 | struct hw_profile hw_prof; | 221 | struct hw_profile hw_prof; |
211 | 222 | ||
212 | struct asd_phy phys[ASD_MAX_PHYS]; | 223 | struct asd_phy phys[ASD_MAX_PHYS]; |
224 | spinlock_t asd_ports_lock; | ||
225 | struct asd_port asd_ports[ASD_MAX_PHYS]; | ||
213 | struct asd_sas_port ports[ASD_MAX_PHYS]; | 226 | struct asd_sas_port ports[ASD_MAX_PHYS]; |
214 | 227 | ||
215 | struct dma_pool *scb_pool; | 228 | struct dma_pool *scb_pool; |
diff --git a/drivers/scsi/aic94xx/aic94xx_init.c b/drivers/scsi/aic94xx/aic94xx_init.c index 3a5bbba3976e..42302ef05ee5 100644 --- a/drivers/scsi/aic94xx/aic94xx_init.c +++ b/drivers/scsi/aic94xx/aic94xx_init.c | |||
@@ -795,8 +795,6 @@ static void asd_remove_driver_attrs(struct device_driver *driver) | |||
795 | } | 795 | } |
796 | 796 | ||
797 | static struct sas_domain_function_template aic94xx_transport_functions = { | 797 | static struct sas_domain_function_template aic94xx_transport_functions = { |
798 | .lldd_port_formed = asd_update_port_links, | ||
799 | |||
800 | .lldd_dev_found = asd_dev_found, | 798 | .lldd_dev_found = asd_dev_found, |
801 | .lldd_dev_gone = asd_dev_gone, | 799 | .lldd_dev_gone = asd_dev_gone, |
802 | 800 | ||
@@ -823,6 +821,8 @@ static const struct pci_device_id aic94xx_pci_table[] __devinitdata = { | |||
823 | 0, 0, 1}, | 821 | 0, 0, 1}, |
824 | {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR1E), | 822 | {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR1E), |
825 | 0, 0, 1}, | 823 | 0, 0, 1}, |
824 | {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR1F), | ||
825 | 0, 0, 1}, | ||
826 | {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR30), | 826 | {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR30), |
827 | 0, 0, 2}, | 827 | 0, 0, 2}, |
828 | {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR32), | 828 | {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR32), |
diff --git a/drivers/scsi/aic94xx/aic94xx_sas.h b/drivers/scsi/aic94xx/aic94xx_sas.h index 64d231712345..9050e93bfd5e 100644 --- a/drivers/scsi/aic94xx/aic94xx_sas.h +++ b/drivers/scsi/aic94xx/aic94xx_sas.h | |||
@@ -733,6 +733,7 @@ struct asd_phy { | |||
733 | 733 | ||
734 | struct sas_identify_frame *identify_frame; | 734 | struct sas_identify_frame *identify_frame; |
735 | struct asd_dma_tok *id_frm_tok; | 735 | struct asd_dma_tok *id_frm_tok; |
736 | struct asd_port *asd_port; | ||
736 | 737 | ||
737 | u8 frame_rcvd[ASD_EDB_SIZE]; | 738 | u8 frame_rcvd[ASD_EDB_SIZE]; |
738 | }; | 739 | }; |
diff --git a/drivers/scsi/aic94xx/aic94xx_scb.c b/drivers/scsi/aic94xx/aic94xx_scb.c index 52c6ea4fbf71..14d5d8c2ee13 100644 --- a/drivers/scsi/aic94xx/aic94xx_scb.c +++ b/drivers/scsi/aic94xx/aic94xx_scb.c | |||
@@ -169,6 +169,70 @@ static inline void asd_get_attached_sas_addr(struct asd_phy *phy, u8 *sas_addr) | |||
169 | } | 169 | } |
170 | } | 170 | } |
171 | 171 | ||
172 | static void asd_form_port(struct asd_ha_struct *asd_ha, struct asd_phy *phy) | ||
173 | { | ||
174 | int i; | ||
175 | struct asd_port *free_port = NULL; | ||
176 | struct asd_port *port; | ||
177 | struct asd_sas_phy *sas_phy = &phy->sas_phy; | ||
178 | unsigned long flags; | ||
179 | |||
180 | spin_lock_irqsave(&asd_ha->asd_ports_lock, flags); | ||
181 | if (!phy->asd_port) { | ||
182 | for (i = 0; i < ASD_MAX_PHYS; i++) { | ||
183 | port = &asd_ha->asd_ports[i]; | ||
184 | |||
185 | /* Check for wide port */ | ||
186 | if (port->num_phys > 0 && | ||
187 | memcmp(port->sas_addr, sas_phy->sas_addr, | ||
188 | SAS_ADDR_SIZE) == 0 && | ||
189 | memcmp(port->attached_sas_addr, | ||
190 | sas_phy->attached_sas_addr, | ||
191 | SAS_ADDR_SIZE) == 0) { | ||
192 | break; | ||
193 | } | ||
194 | |||
195 | /* Find a free port */ | ||
196 | if (port->num_phys == 0 && free_port == NULL) { | ||
197 | free_port = port; | ||
198 | } | ||
199 | } | ||
200 | |||
201 | /* Use a free port if this doesn't form a wide port */ | ||
202 | if (i >= ASD_MAX_PHYS) { | ||
203 | port = free_port; | ||
204 | BUG_ON(!port); | ||
205 | memcpy(port->sas_addr, sas_phy->sas_addr, | ||
206 | SAS_ADDR_SIZE); | ||
207 | memcpy(port->attached_sas_addr, | ||
208 | sas_phy->attached_sas_addr, | ||
209 | SAS_ADDR_SIZE); | ||
210 | } | ||
211 | port->num_phys++; | ||
212 | port->phy_mask |= (1U << sas_phy->id); | ||
213 | phy->asd_port = port; | ||
214 | } | ||
215 | ASD_DPRINTK("%s: updating phy_mask 0x%x for phy%d\n", | ||
216 | __FUNCTION__, phy->asd_port->phy_mask, sas_phy->id); | ||
217 | asd_update_port_links(asd_ha, phy); | ||
218 | spin_unlock_irqrestore(&asd_ha->asd_ports_lock, flags); | ||
219 | } | ||
220 | |||
221 | static void asd_deform_port(struct asd_ha_struct *asd_ha, struct asd_phy *phy) | ||
222 | { | ||
223 | struct asd_port *port = phy->asd_port; | ||
224 | struct asd_sas_phy *sas_phy = &phy->sas_phy; | ||
225 | unsigned long flags; | ||
226 | |||
227 | spin_lock_irqsave(&asd_ha->asd_ports_lock, flags); | ||
228 | if (port) { | ||
229 | port->num_phys--; | ||
230 | port->phy_mask &= ~(1U << sas_phy->id); | ||
231 | phy->asd_port = NULL; | ||
232 | } | ||
233 | spin_unlock_irqrestore(&asd_ha->asd_ports_lock, flags); | ||
234 | } | ||
235 | |||
172 | static inline void asd_bytes_dmaed_tasklet(struct asd_ascb *ascb, | 236 | static inline void asd_bytes_dmaed_tasklet(struct asd_ascb *ascb, |
173 | struct done_list_struct *dl, | 237 | struct done_list_struct *dl, |
174 | int edb_id, int phy_id) | 238 | int edb_id, int phy_id) |
@@ -188,6 +252,7 @@ static inline void asd_bytes_dmaed_tasklet(struct asd_ascb *ascb, | |||
188 | asd_get_attached_sas_addr(phy, phy->sas_phy.attached_sas_addr); | 252 | asd_get_attached_sas_addr(phy, phy->sas_phy.attached_sas_addr); |
189 | spin_unlock_irqrestore(&phy->sas_phy.frame_rcvd_lock, flags); | 253 | spin_unlock_irqrestore(&phy->sas_phy.frame_rcvd_lock, flags); |
190 | asd_dump_frame_rcvd(phy, dl); | 254 | asd_dump_frame_rcvd(phy, dl); |
255 | asd_form_port(ascb->ha, phy); | ||
191 | sas_ha->notify_port_event(&phy->sas_phy, PORTE_BYTES_DMAED); | 256 | sas_ha->notify_port_event(&phy->sas_phy, PORTE_BYTES_DMAED); |
192 | } | 257 | } |
193 | 258 | ||
@@ -198,6 +263,7 @@ static inline void asd_link_reset_err_tasklet(struct asd_ascb *ascb, | |||
198 | struct asd_ha_struct *asd_ha = ascb->ha; | 263 | struct asd_ha_struct *asd_ha = ascb->ha; |
199 | struct sas_ha_struct *sas_ha = &asd_ha->sas_ha; | 264 | struct sas_ha_struct *sas_ha = &asd_ha->sas_ha; |
200 | struct asd_sas_phy *sas_phy = sas_ha->sas_phy[phy_id]; | 265 | struct asd_sas_phy *sas_phy = sas_ha->sas_phy[phy_id]; |
266 | struct asd_phy *phy = &asd_ha->phys[phy_id]; | ||
201 | u8 lr_error = dl->status_block[1]; | 267 | u8 lr_error = dl->status_block[1]; |
202 | u8 retries_left = dl->status_block[2]; | 268 | u8 retries_left = dl->status_block[2]; |
203 | 269 | ||
@@ -222,6 +288,7 @@ static inline void asd_link_reset_err_tasklet(struct asd_ascb *ascb, | |||
222 | 288 | ||
223 | asd_turn_led(asd_ha, phy_id, 0); | 289 | asd_turn_led(asd_ha, phy_id, 0); |
224 | sas_phy_disconnected(sas_phy); | 290 | sas_phy_disconnected(sas_phy); |
291 | asd_deform_port(asd_ha, phy); | ||
225 | sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); | 292 | sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); |
226 | 293 | ||
227 | if (retries_left == 0) { | 294 | if (retries_left == 0) { |
@@ -249,6 +316,8 @@ static inline void asd_primitive_rcvd_tasklet(struct asd_ascb *ascb, | |||
249 | unsigned long flags; | 316 | unsigned long flags; |
250 | struct sas_ha_struct *sas_ha = &ascb->ha->sas_ha; | 317 | struct sas_ha_struct *sas_ha = &ascb->ha->sas_ha; |
251 | struct asd_sas_phy *sas_phy = sas_ha->sas_phy[phy_id]; | 318 | struct asd_sas_phy *sas_phy = sas_ha->sas_phy[phy_id]; |
319 | struct asd_ha_struct *asd_ha = ascb->ha; | ||
320 | struct asd_phy *phy = &asd_ha->phys[phy_id]; | ||
252 | u8 reg = dl->status_block[1]; | 321 | u8 reg = dl->status_block[1]; |
253 | u32 cont = dl->status_block[2] << ((reg & 3)*8); | 322 | u32 cont = dl->status_block[2] << ((reg & 3)*8); |
254 | 323 | ||
@@ -285,6 +354,7 @@ static inline void asd_primitive_rcvd_tasklet(struct asd_ascb *ascb, | |||
285 | phy_id); | 354 | phy_id); |
286 | /* The sequencer disables all phys on that port. | 355 | /* The sequencer disables all phys on that port. |
287 | * We have to re-enable the phys ourselves. */ | 356 | * We have to re-enable the phys ourselves. */ |
357 | asd_deform_port(asd_ha, phy); | ||
288 | sas_ha->notify_port_event(sas_phy, PORTE_HARD_RESET); | 358 | sas_ha->notify_port_event(sas_phy, PORTE_HARD_RESET); |
289 | break; | 359 | break; |
290 | 360 | ||
@@ -385,6 +455,7 @@ static void escb_tasklet_complete(struct asd_ascb *ascb, | |||
385 | u8 sb_opcode = dl->status_block[0]; | 455 | u8 sb_opcode = dl->status_block[0]; |
386 | int phy_id = sb_opcode & DL_PHY_MASK; | 456 | int phy_id = sb_opcode & DL_PHY_MASK; |
387 | struct asd_sas_phy *sas_phy = sas_ha->sas_phy[phy_id]; | 457 | struct asd_sas_phy *sas_phy = sas_ha->sas_phy[phy_id]; |
458 | struct asd_phy *phy = &asd_ha->phys[phy_id]; | ||
388 | 459 | ||
389 | if (edb > 6 || edb < 0) { | 460 | if (edb > 6 || edb < 0) { |
390 | ASD_DPRINTK("edb is 0x%x! dl->opcode is 0x%x\n", | 461 | ASD_DPRINTK("edb is 0x%x! dl->opcode is 0x%x\n", |
@@ -497,6 +568,7 @@ static void escb_tasklet_complete(struct asd_ascb *ascb, | |||
497 | asd_turn_led(asd_ha, phy_id, 0); | 568 | asd_turn_led(asd_ha, phy_id, 0); |
498 | /* the device is gone */ | 569 | /* the device is gone */ |
499 | sas_phy_disconnected(sas_phy); | 570 | sas_phy_disconnected(sas_phy); |
571 | asd_deform_port(asd_ha, phy); | ||
500 | sas_ha->notify_port_event(sas_phy, PORTE_TIMER_EVENT); | 572 | sas_ha->notify_port_event(sas_phy, PORTE_TIMER_EVENT); |
501 | break; | 573 | break; |
502 | default: | 574 | default: |
diff --git a/drivers/scsi/aic94xx/aic94xx_sds.c b/drivers/scsi/aic94xx/aic94xx_sds.c index 83574b5b4e69..de7c04d4254d 100644 --- a/drivers/scsi/aic94xx/aic94xx_sds.c +++ b/drivers/scsi/aic94xx/aic94xx_sds.c | |||
@@ -630,10 +630,6 @@ static int asd_flash_getid(struct asd_ha_struct *asd_ha) | |||
630 | 630 | ||
631 | reg = asd_read_reg_dword(asd_ha, EXSICNFGR); | 631 | reg = asd_read_reg_dword(asd_ha, EXSICNFGR); |
632 | 632 | ||
633 | if (!(reg & FLASHEX)) { | ||
634 | ASD_DPRINTK("flash doesn't exist\n"); | ||
635 | return -ENOENT; | ||
636 | } | ||
637 | if (pci_read_config_dword(asd_ha->pcidev, PCI_CONF_FLSH_BAR, | 633 | if (pci_read_config_dword(asd_ha->pcidev, PCI_CONF_FLSH_BAR, |
638 | &asd_ha->hw_prof.flash.bar)) { | 634 | &asd_ha->hw_prof.flash.bar)) { |
639 | asd_printk("couldn't read PCI_CONF_FLSH_BAR of %s\n", | 635 | asd_printk("couldn't read PCI_CONF_FLSH_BAR of %s\n", |
diff --git a/drivers/scsi/aic94xx/aic94xx_seq.c b/drivers/scsi/aic94xx/aic94xx_seq.c index 56e4b3ba6a08..845112539d05 100644 --- a/drivers/scsi/aic94xx/aic94xx_seq.c +++ b/drivers/scsi/aic94xx/aic94xx_seq.c | |||
@@ -1369,10 +1369,9 @@ int asd_start_seqs(struct asd_ha_struct *asd_ha) | |||
1369 | * port_map_by_links is also used as the conn_mask byte in the | 1369 | * port_map_by_links is also used as the conn_mask byte in the |
1370 | * initiator/target port DDB. | 1370 | * initiator/target port DDB. |
1371 | */ | 1371 | */ |
1372 | void asd_update_port_links(struct asd_sas_phy *sas_phy) | 1372 | void asd_update_port_links(struct asd_ha_struct *asd_ha, struct asd_phy *phy) |
1373 | { | 1373 | { |
1374 | struct asd_ha_struct *asd_ha = sas_phy->ha->lldd_ha; | 1374 | const u8 phy_mask = (u8) phy->asd_port->phy_mask; |
1375 | const u8 phy_mask = (u8) sas_phy->port->phy_mask; | ||
1376 | u8 phy_is_up; | 1375 | u8 phy_is_up; |
1377 | u8 mask; | 1376 | u8 mask; |
1378 | int i, err; | 1377 | int i, err; |
diff --git a/drivers/scsi/aic94xx/aic94xx_seq.h b/drivers/scsi/aic94xx/aic94xx_seq.h index 42281c36153b..9e715e5496af 100644 --- a/drivers/scsi/aic94xx/aic94xx_seq.h +++ b/drivers/scsi/aic94xx/aic94xx_seq.h | |||
@@ -64,7 +64,7 @@ int asd_unpause_lseq(struct asd_ha_struct *asd_ha, u8 lseq_mask); | |||
64 | int asd_init_seqs(struct asd_ha_struct *asd_ha); | 64 | int asd_init_seqs(struct asd_ha_struct *asd_ha); |
65 | int asd_start_seqs(struct asd_ha_struct *asd_ha); | 65 | int asd_start_seqs(struct asd_ha_struct *asd_ha); |
66 | 66 | ||
67 | void asd_update_port_links(struct asd_sas_phy *phy); | 67 | void asd_update_port_links(struct asd_ha_struct *asd_ha, struct asd_phy *phy); |
68 | #endif | 68 | #endif |
69 | 69 | ||
70 | #endif | 70 | #endif |
diff --git a/drivers/scsi/dpt/dpti_i2o.h b/drivers/scsi/dpt/dpti_i2o.h index b3fa7ed71faf..5a49216fe4cf 100644 --- a/drivers/scsi/dpt/dpti_i2o.h +++ b/drivers/scsi/dpt/dpti_i2o.h | |||
@@ -49,7 +49,7 @@ | |||
49 | 49 | ||
50 | #include <linux/wait.h> | 50 | #include <linux/wait.h> |
51 | typedef wait_queue_head_t adpt_wait_queue_head_t; | 51 | typedef wait_queue_head_t adpt_wait_queue_head_t; |
52 | #define ADPT_DECLARE_WAIT_QUEUE_HEAD(wait) DECLARE_WAIT_QUEUE_HEAD(wait) | 52 | #define ADPT_DECLARE_WAIT_QUEUE_HEAD(wait) DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wait) |
53 | typedef wait_queue_t adpt_wait_queue_t; | 53 | typedef wait_queue_t adpt_wait_queue_t; |
54 | 54 | ||
55 | /* | 55 | /* |
diff --git a/drivers/scsi/dtc.c b/drivers/scsi/dtc.c index 0d5713dfa204..54756722dd5f 100644 --- a/drivers/scsi/dtc.c +++ b/drivers/scsi/dtc.c | |||
@@ -82,7 +82,7 @@ | |||
82 | #include <linux/string.h> | 82 | #include <linux/string.h> |
83 | #include <linux/init.h> | 83 | #include <linux/init.h> |
84 | #include <linux/interrupt.h> | 84 | #include <linux/interrupt.h> |
85 | #include <asm/io.h> | 85 | #include <linux/io.h> |
86 | #include "scsi.h" | 86 | #include "scsi.h" |
87 | #include <scsi/scsi_host.h> | 87 | #include <scsi/scsi_host.h> |
88 | #include "dtc.h" | 88 | #include "dtc.h" |
diff --git a/drivers/scsi/eata_pio.c b/drivers/scsi/eata_pio.c index 811d8840707e..2dbb66d2f0a7 100644 --- a/drivers/scsi/eata_pio.c +++ b/drivers/scsi/eata_pio.c | |||
@@ -203,7 +203,7 @@ static irqreturn_t do_eata_pio_int_handler(int irq, void *dev_id) | |||
203 | irqreturn_t ret; | 203 | irqreturn_t ret; |
204 | 204 | ||
205 | spin_lock_irqsave(dev->host_lock, flags); | 205 | spin_lock_irqsave(dev->host_lock, flags); |
206 | ret = eata_pio_int_handler(irq, dev_id, regs); | 206 | ret = eata_pio_int_handler(irq, dev_id); |
207 | spin_unlock_irqrestore(dev->host_lock, flags); | 207 | spin_unlock_irqrestore(dev->host_lock, flags); |
208 | return ret; | 208 | return ret; |
209 | } | 209 | } |
diff --git a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c index 41b05fc45380..5d4ea6f77953 100644 --- a/drivers/scsi/fdomain.c +++ b/drivers/scsi/fdomain.c | |||
@@ -278,9 +278,9 @@ | |||
278 | #include <linux/pci.h> | 278 | #include <linux/pci.h> |
279 | #include <linux/stat.h> | 279 | #include <linux/stat.h> |
280 | #include <linux/delay.h> | 280 | #include <linux/delay.h> |
281 | #include <linux/io.h> | ||
281 | #include <scsi/scsicam.h> | 282 | #include <scsi/scsicam.h> |
282 | 283 | ||
283 | #include <asm/io.h> | ||
284 | #include <asm/system.h> | 284 | #include <asm/system.h> |
285 | 285 | ||
286 | #include <scsi/scsi.h> | 286 | #include <scsi/scsi.h> |
@@ -387,6 +387,7 @@ static void __iomem * bios_mem; | |||
387 | static int bios_major; | 387 | static int bios_major; |
388 | static int bios_minor; | 388 | static int bios_minor; |
389 | static int PCI_bus; | 389 | static int PCI_bus; |
390 | static struct pci_dev *PCI_dev; | ||
390 | static int Quantum; /* Quantum board variant */ | 391 | static int Quantum; /* Quantum board variant */ |
391 | static int interrupt_level; | 392 | static int interrupt_level; |
392 | static volatile int in_command; | 393 | static volatile int in_command; |
@@ -812,9 +813,10 @@ static int fdomain_pci_bios_detect( int *irq, int *iobase, struct pci_dev **ret_ | |||
812 | PCI_DEVICE_ID_FD_36C70 ); | 813 | PCI_DEVICE_ID_FD_36C70 ); |
813 | #endif | 814 | #endif |
814 | 815 | ||
815 | if ((pdev = pci_find_device(PCI_VENDOR_ID_FD, PCI_DEVICE_ID_FD_36C70, pdev)) == NULL) | 816 | if ((pdev = pci_get_device(PCI_VENDOR_ID_FD, PCI_DEVICE_ID_FD_36C70, pdev)) == NULL) |
816 | return 0; | 817 | return 0; |
817 | if (pci_enable_device(pdev)) return 0; | 818 | if (pci_enable_device(pdev)) |
819 | goto fail; | ||
818 | 820 | ||
819 | #if DEBUG_DETECT | 821 | #if DEBUG_DETECT |
820 | printk( "scsi: <fdomain> TMC-3260 detect:" | 822 | printk( "scsi: <fdomain> TMC-3260 detect:" |
@@ -831,7 +833,7 @@ static int fdomain_pci_bios_detect( int *irq, int *iobase, struct pci_dev **ret_ | |||
831 | pci_irq = pdev->irq; | 833 | pci_irq = pdev->irq; |
832 | 834 | ||
833 | if (!request_region( pci_base, 0x10, "fdomain" )) | 835 | if (!request_region( pci_base, 0x10, "fdomain" )) |
834 | return 0; | 836 | goto fail; |
835 | 837 | ||
836 | /* Now we have the I/O base address and interrupt from the PCI | 838 | /* Now we have the I/O base address and interrupt from the PCI |
837 | configuration registers. */ | 839 | configuration registers. */ |
@@ -848,17 +850,22 @@ static int fdomain_pci_bios_detect( int *irq, int *iobase, struct pci_dev **ret_ | |||
848 | if (!fdomain_is_valid_port(pci_base)) { | 850 | if (!fdomain_is_valid_port(pci_base)) { |
849 | printk(KERN_ERR "scsi: <fdomain> PCI card detected, but driver not loaded (invalid port)\n" ); | 851 | printk(KERN_ERR "scsi: <fdomain> PCI card detected, but driver not loaded (invalid port)\n" ); |
850 | release_region(pci_base, 0x10); | 852 | release_region(pci_base, 0x10); |
851 | return 0; | 853 | goto fail; |
852 | } | 854 | } |
853 | 855 | ||
854 | /* Fill in a few global variables. Ugh. */ | 856 | /* Fill in a few global variables. Ugh. */ |
855 | bios_major = bios_minor = -1; | 857 | bios_major = bios_minor = -1; |
856 | PCI_bus = 1; | 858 | PCI_bus = 1; |
859 | PCI_dev = pdev; | ||
857 | Quantum = 0; | 860 | Quantum = 0; |
858 | bios_base = 0; | 861 | bios_base = 0; |
859 | 862 | ||
860 | return 1; | 863 | return 1; |
864 | fail: | ||
865 | pci_dev_put(pdev); | ||
866 | return 0; | ||
861 | } | 867 | } |
868 | |||
862 | #endif | 869 | #endif |
863 | 870 | ||
864 | struct Scsi_Host *__fdomain_16x0_detect(struct scsi_host_template *tpnt ) | 871 | struct Scsi_Host *__fdomain_16x0_detect(struct scsi_host_template *tpnt ) |
@@ -909,8 +916,7 @@ struct Scsi_Host *__fdomain_16x0_detect(struct scsi_host_template *tpnt ) | |||
909 | if (setup_called) { | 916 | if (setup_called) { |
910 | printk(KERN_ERR "scsi: <fdomain> Bad LILO/INSMOD parameters?\n"); | 917 | printk(KERN_ERR "scsi: <fdomain> Bad LILO/INSMOD parameters?\n"); |
911 | } | 918 | } |
912 | release_region(port_base, 0x10); | 919 | goto fail; |
913 | return NULL; | ||
914 | } | 920 | } |
915 | 921 | ||
916 | if (this_id) { | 922 | if (this_id) { |
@@ -942,8 +948,7 @@ struct Scsi_Host *__fdomain_16x0_detect(struct scsi_host_template *tpnt ) | |||
942 | /* Log IRQ with kernel */ | 948 | /* Log IRQ with kernel */ |
943 | if (!interrupt_level) { | 949 | if (!interrupt_level) { |
944 | printk(KERN_ERR "scsi: <fdomain> Card Detected, but driver not loaded (no IRQ)\n" ); | 950 | printk(KERN_ERR "scsi: <fdomain> Card Detected, but driver not loaded (no IRQ)\n" ); |
945 | release_region(port_base, 0x10); | 951 | goto fail; |
946 | return NULL; | ||
947 | } else { | 952 | } else { |
948 | /* Register the IRQ with the kernel */ | 953 | /* Register the IRQ with the kernel */ |
949 | 954 | ||
@@ -964,11 +969,14 @@ struct Scsi_Host *__fdomain_16x0_detect(struct scsi_host_template *tpnt ) | |||
964 | printk(KERN_ERR " Send mail to faith@acm.org\n" ); | 969 | printk(KERN_ERR " Send mail to faith@acm.org\n" ); |
965 | } | 970 | } |
966 | printk(KERN_ERR "scsi: <fdomain> Detected, but driver not loaded (IRQ)\n" ); | 971 | printk(KERN_ERR "scsi: <fdomain> Detected, but driver not loaded (IRQ)\n" ); |
967 | release_region(port_base, 0x10); | 972 | goto fail; |
968 | return NULL; | ||
969 | } | 973 | } |
970 | } | 974 | } |
971 | return shpnt; | 975 | return shpnt; |
976 | fail: | ||
977 | pci_dev_put(pdev); | ||
978 | release_region(port_base, 0x10); | ||
979 | return NULL; | ||
972 | } | 980 | } |
973 | 981 | ||
974 | static int fdomain_16x0_detect(struct scsi_host_template *tpnt) | 982 | static int fdomain_16x0_detect(struct scsi_host_template *tpnt) |
@@ -1714,6 +1722,8 @@ static int fdomain_16x0_release(struct Scsi_Host *shpnt) | |||
1714 | free_irq(shpnt->irq, shpnt); | 1722 | free_irq(shpnt->irq, shpnt); |
1715 | if (shpnt->io_port && shpnt->n_io_port) | 1723 | if (shpnt->io_port && shpnt->n_io_port) |
1716 | release_region(shpnt->io_port, shpnt->n_io_port); | 1724 | release_region(shpnt->io_port, shpnt->n_io_port); |
1725 | if (PCI_bus) | ||
1726 | pci_dev_put(PCI_dev); | ||
1717 | return 0; | 1727 | return 0; |
1718 | } | 1728 | } |
1719 | 1729 | ||
@@ -1736,6 +1746,15 @@ struct scsi_host_template fdomain_driver_template = { | |||
1736 | }; | 1746 | }; |
1737 | 1747 | ||
1738 | #ifndef PCMCIA | 1748 | #ifndef PCMCIA |
1749 | |||
1750 | static struct pci_device_id fdomain_pci_tbl[] __devinitdata = { | ||
1751 | { PCI_VENDOR_ID_FD, PCI_DEVICE_ID_FD_36C70, | ||
1752 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | ||
1753 | { } | ||
1754 | }; | ||
1755 | MODULE_DEVICE_TABLE(pci, fdomain_pci_tbl); | ||
1756 | |||
1739 | #define driver_template fdomain_driver_template | 1757 | #define driver_template fdomain_driver_template |
1740 | #include "scsi_module.c" | 1758 | #include "scsi_module.c" |
1759 | |||
1741 | #endif | 1760 | #endif |
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index 4bc14ad92e22..4c698a71f66f 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c | |||
@@ -3531,7 +3531,7 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id) | |||
3531 | IStatus &= ~0x80; | 3531 | IStatus &= ~0x80; |
3532 | #ifdef INT_COAL | 3532 | #ifdef INT_COAL |
3533 | if (coalesced) | 3533 | if (coalesced) |
3534 | ha->status = pcs->ext_status && 0xffff; | 3534 | ha->status = pcs->ext_status & 0xffff; |
3535 | else | 3535 | else |
3536 | #endif | 3536 | #endif |
3537 | ha->status = gdth_readw(&dp6m_ptr->i960r.status); | 3537 | ha->status = gdth_readw(&dp6m_ptr->i960r.status); |
@@ -3543,7 +3543,7 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id) | |||
3543 | if (coalesced) { | 3543 | if (coalesced) { |
3544 | ha->info = pcs->info0; | 3544 | ha->info = pcs->info0; |
3545 | ha->info2 = pcs->info1; | 3545 | ha->info2 = pcs->info1; |
3546 | ha->service = (pcs->ext_status >> 16) && 0xffff; | 3546 | ha->service = (pcs->ext_status >> 16) & 0xffff; |
3547 | } else | 3547 | } else |
3548 | #endif | 3548 | #endif |
3549 | { | 3549 | { |
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index 669ea4fff166..fbc1d5c3b0a7 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c | |||
@@ -1213,7 +1213,7 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq, | |||
1213 | "ibmvscsi: Re-enabling adapter!\n"); | 1213 | "ibmvscsi: Re-enabling adapter!\n"); |
1214 | purge_requests(hostdata, DID_REQUEUE); | 1214 | purge_requests(hostdata, DID_REQUEUE); |
1215 | if ((ibmvscsi_reenable_crq_queue(&hostdata->queue, | 1215 | if ((ibmvscsi_reenable_crq_queue(&hostdata->queue, |
1216 | hostdata) == 0) || | 1216 | hostdata)) || |
1217 | (ibmvscsi_send_crq(hostdata, | 1217 | (ibmvscsi_send_crq(hostdata, |
1218 | 0xC001000000000000LL, 0))) { | 1218 | 0xC001000000000000LL, 0))) { |
1219 | atomic_set(&hostdata->request_limit, | 1219 | atomic_set(&hostdata->request_limit, |
diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c index 2d95ac9c32c1..e31f6122106f 100644 --- a/drivers/scsi/imm.c +++ b/drivers/scsi/imm.c | |||
@@ -1153,7 +1153,7 @@ static int __imm_attach(struct parport *pb) | |||
1153 | { | 1153 | { |
1154 | struct Scsi_Host *host; | 1154 | struct Scsi_Host *host; |
1155 | imm_struct *dev; | 1155 | imm_struct *dev; |
1156 | DECLARE_WAIT_QUEUE_HEAD(waiting); | 1156 | DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waiting); |
1157 | DEFINE_WAIT(wait); | 1157 | DEFINE_WAIT(wait); |
1158 | int ports; | 1158 | int ports; |
1159 | int modes, ppb; | 1159 | int modes, ppb; |
diff --git a/drivers/scsi/initio.c b/drivers/scsi/initio.c index 911f2ff4a1f2..afed293dd7b9 100644 --- a/drivers/scsi/initio.c +++ b/drivers/scsi/initio.c | |||
@@ -142,8 +142,6 @@ | |||
142 | #define i91u_MAXQUEUE 2 | 142 | #define i91u_MAXQUEUE 2 |
143 | #define i91u_REVID "Initio INI-9X00U/UW SCSI device driver; Revision: 1.04a" | 143 | #define i91u_REVID "Initio INI-9X00U/UW SCSI device driver; Revision: 1.04a" |
144 | 144 | ||
145 | #define INI_VENDOR_ID 0x1101 /* Initio's PCI vendor ID */ | ||
146 | #define DMX_VENDOR_ID 0x134a /* Domex's PCI vendor ID */ | ||
147 | #define I950_DEVICE_ID 0x9500 /* Initio's inic-950 product ID */ | 145 | #define I950_DEVICE_ID 0x9500 /* Initio's inic-950 product ID */ |
148 | #define I940_DEVICE_ID 0x9400 /* Initio's inic-940 product ID */ | 146 | #define I940_DEVICE_ID 0x9400 /* Initio's inic-940 product ID */ |
149 | #define I935_DEVICE_ID 0x9401 /* Initio's inic-935 product ID */ | 147 | #define I935_DEVICE_ID 0x9401 /* Initio's inic-935 product ID */ |
@@ -171,13 +169,16 @@ static int setup_debug = 0; | |||
171 | 169 | ||
172 | static void i91uSCBPost(BYTE * pHcb, BYTE * pScb); | 170 | static void i91uSCBPost(BYTE * pHcb, BYTE * pScb); |
173 | 171 | ||
174 | static const PCI_ID i91u_pci_devices[] = { | 172 | /* PCI Devices supported by this driver */ |
175 | { INI_VENDOR_ID, I950_DEVICE_ID }, | 173 | static struct pci_device_id i91u_pci_devices[] __devinitdata = { |
176 | { INI_VENDOR_ID, I940_DEVICE_ID }, | 174 | { PCI_VENDOR_ID_INIT, I950_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
177 | { INI_VENDOR_ID, I935_DEVICE_ID }, | 175 | { PCI_VENDOR_ID_INIT, I940_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
178 | { INI_VENDOR_ID, I920_DEVICE_ID }, | 176 | { PCI_VENDOR_ID_INIT, I935_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
179 | { DMX_VENDOR_ID, I920_DEVICE_ID }, | 177 | { PCI_VENDOR_ID_INIT, I920_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
178 | { PCI_VENDOR_ID_DOMEX, I920_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | ||
179 | { } | ||
180 | }; | 180 | }; |
181 | MODULE_DEVICE_TABLE(pci, i91u_pci_devices); | ||
181 | 182 | ||
182 | #define DEBUG_INTERRUPT 0 | 183 | #define DEBUG_INTERRUPT 0 |
183 | #define DEBUG_QUEUE 0 | 184 | #define DEBUG_QUEUE 0 |
@@ -2771,7 +2772,7 @@ static int tul_NewReturnNumberOfAdapters(void) | |||
2771 | 2772 | ||
2772 | for (i = 0; i < ARRAY_SIZE(i91u_pci_devices); i++) | 2773 | for (i = 0; i < ARRAY_SIZE(i91u_pci_devices); i++) |
2773 | { | 2774 | { |
2774 | while ((pDev = pci_find_device(i91u_pci_devices[i].vendor_id, i91u_pci_devices[i].device_id, pDev)) != NULL) { | 2775 | while ((pDev = pci_find_device(i91u_pci_devices[i].vendor, i91u_pci_devices[i].device, pDev)) != NULL) { |
2775 | if (pci_enable_device(pDev)) | 2776 | if (pci_enable_device(pDev)) |
2776 | continue; | 2777 | continue; |
2777 | pci_read_config_dword(pDev, 0x44, (u32 *) & dRegValue); | 2778 | pci_read_config_dword(pDev, 0x44, (u32 *) & dRegValue); |
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 0a9dbc59663f..d0b139cccbbc 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c | |||
@@ -415,8 +415,8 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | |||
415 | iscsi_solicit_data_init(conn, ctask, r2t); | 415 | iscsi_solicit_data_init(conn, ctask, r2t); |
416 | 416 | ||
417 | tcp_ctask->exp_r2tsn = r2tsn + 1; | 417 | tcp_ctask->exp_r2tsn = r2tsn + 1; |
418 | tcp_ctask->xmstate |= XMSTATE_SOL_HDR; | ||
419 | __kfifo_put(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*)); | 418 | __kfifo_put(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*)); |
419 | tcp_ctask->xmstate |= XMSTATE_SOL_HDR; | ||
420 | list_move_tail(&ctask->running, &conn->xmitqueue); | 420 | list_move_tail(&ctask->running, &conn->xmitqueue); |
421 | 421 | ||
422 | scsi_queue_work(session->host, &conn->xmitwork); | 422 | scsi_queue_work(session->host, &conn->xmitwork); |
@@ -1627,9 +1627,12 @@ static int iscsi_send_sol_pdu(struct iscsi_conn *conn, | |||
1627 | if (tcp_ctask->xmstate & XMSTATE_SOL_HDR) { | 1627 | if (tcp_ctask->xmstate & XMSTATE_SOL_HDR) { |
1628 | tcp_ctask->xmstate &= ~XMSTATE_SOL_HDR; | 1628 | tcp_ctask->xmstate &= ~XMSTATE_SOL_HDR; |
1629 | tcp_ctask->xmstate |= XMSTATE_SOL_DATA; | 1629 | tcp_ctask->xmstate |= XMSTATE_SOL_DATA; |
1630 | if (!tcp_ctask->r2t) | 1630 | if (!tcp_ctask->r2t) { |
1631 | spin_lock_bh(&session->lock); | ||
1631 | __kfifo_get(tcp_ctask->r2tqueue, (void*)&tcp_ctask->r2t, | 1632 | __kfifo_get(tcp_ctask->r2tqueue, (void*)&tcp_ctask->r2t, |
1632 | sizeof(void*)); | 1633 | sizeof(void*)); |
1634 | spin_unlock_bh(&session->lock); | ||
1635 | } | ||
1633 | send_hdr: | 1636 | send_hdr: |
1634 | r2t = tcp_ctask->r2t; | 1637 | r2t = tcp_ctask->r2t; |
1635 | dtask = &r2t->dtask; | 1638 | dtask = &r2t->dtask; |
@@ -1816,21 +1819,14 @@ iscsi_tcp_conn_destroy(struct iscsi_cls_conn *cls_conn) | |||
1816 | { | 1819 | { |
1817 | struct iscsi_conn *conn = cls_conn->dd_data; | 1820 | struct iscsi_conn *conn = cls_conn->dd_data; |
1818 | struct iscsi_tcp_conn *tcp_conn = conn->dd_data; | 1821 | struct iscsi_tcp_conn *tcp_conn = conn->dd_data; |
1819 | int digest = 0; | ||
1820 | |||
1821 | if (conn->hdrdgst_en || conn->datadgst_en) | ||
1822 | digest = 1; | ||
1823 | 1822 | ||
1824 | iscsi_tcp_release_conn(conn); | 1823 | iscsi_tcp_release_conn(conn); |
1825 | iscsi_conn_teardown(cls_conn); | 1824 | iscsi_conn_teardown(cls_conn); |
1826 | 1825 | ||
1827 | /* now free tcp_conn */ | 1826 | if (tcp_conn->tx_hash.tfm) |
1828 | if (digest) { | 1827 | crypto_free_hash(tcp_conn->tx_hash.tfm); |
1829 | if (tcp_conn->tx_hash.tfm) | 1828 | if (tcp_conn->rx_hash.tfm) |
1830 | crypto_free_hash(tcp_conn->tx_hash.tfm); | 1829 | crypto_free_hash(tcp_conn->rx_hash.tfm); |
1831 | if (tcp_conn->rx_hash.tfm) | ||
1832 | crypto_free_hash(tcp_conn->rx_hash.tfm); | ||
1833 | } | ||
1834 | 1830 | ||
1835 | kfree(tcp_conn); | 1831 | kfree(tcp_conn); |
1836 | } | 1832 | } |
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index c542d0e95e68..5d8862189485 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c | |||
@@ -481,8 +481,8 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, | |||
481 | break; | 481 | break; |
482 | case ISCSI_OP_ASYNC_EVENT: | 482 | case ISCSI_OP_ASYNC_EVENT: |
483 | conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1; | 483 | conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1; |
484 | /* we need sth like iscsi_async_event_rsp() */ | 484 | if (iscsi_recv_pdu(conn->cls_conn, hdr, data, datalen)) |
485 | rc = ISCSI_ERR_BAD_OPCODE; | 485 | rc = ISCSI_ERR_CONN_FAILED; |
486 | break; | 486 | break; |
487 | default: | 487 | default: |
488 | rc = ISCSI_ERR_BAD_OPCODE; | 488 | rc = ISCSI_ERR_BAD_OPCODE; |
@@ -578,6 +578,27 @@ void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err) | |||
578 | } | 578 | } |
579 | EXPORT_SYMBOL_GPL(iscsi_conn_failure); | 579 | EXPORT_SYMBOL_GPL(iscsi_conn_failure); |
580 | 580 | ||
581 | static int iscsi_xmit_imm_task(struct iscsi_conn *conn) | ||
582 | { | ||
583 | struct iscsi_hdr *hdr = conn->mtask->hdr; | ||
584 | int rc, was_logout = 0; | ||
585 | |||
586 | if ((hdr->opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGOUT) { | ||
587 | conn->session->state = ISCSI_STATE_IN_RECOVERY; | ||
588 | iscsi_block_session(session_to_cls(conn->session)); | ||
589 | was_logout = 1; | ||
590 | } | ||
591 | rc = conn->session->tt->xmit_mgmt_task(conn, conn->mtask); | ||
592 | if (rc) | ||
593 | return rc; | ||
594 | |||
595 | if (was_logout) { | ||
596 | set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); | ||
597 | return -ENODATA; | ||
598 | } | ||
599 | return 0; | ||
600 | } | ||
601 | |||
581 | /** | 602 | /** |
582 | * iscsi_data_xmit - xmit any command into the scheduled connection | 603 | * iscsi_data_xmit - xmit any command into the scheduled connection |
583 | * @conn: iscsi connection | 604 | * @conn: iscsi connection |
@@ -623,7 +644,7 @@ static int iscsi_data_xmit(struct iscsi_conn *conn) | |||
623 | conn->ctask = NULL; | 644 | conn->ctask = NULL; |
624 | } | 645 | } |
625 | if (conn->mtask) { | 646 | if (conn->mtask) { |
626 | rc = tt->xmit_mgmt_task(conn, conn->mtask); | 647 | rc = iscsi_xmit_imm_task(conn); |
627 | if (rc) | 648 | if (rc) |
628 | goto again; | 649 | goto again; |
629 | /* done with this in-progress mtask */ | 650 | /* done with this in-progress mtask */ |
@@ -638,7 +659,7 @@ static int iscsi_data_xmit(struct iscsi_conn *conn) | |||
638 | list_add_tail(&conn->mtask->running, | 659 | list_add_tail(&conn->mtask->running, |
639 | &conn->mgmt_run_list); | 660 | &conn->mgmt_run_list); |
640 | spin_unlock_bh(&conn->session->lock); | 661 | spin_unlock_bh(&conn->session->lock); |
641 | rc = tt->xmit_mgmt_task(conn, conn->mtask); | 662 | rc = iscsi_xmit_imm_task(conn); |
642 | if (rc) | 663 | if (rc) |
643 | goto again; | 664 | goto again; |
644 | } | 665 | } |
@@ -661,8 +682,6 @@ static int iscsi_data_xmit(struct iscsi_conn *conn) | |||
661 | spin_unlock_bh(&conn->session->lock); | 682 | spin_unlock_bh(&conn->session->lock); |
662 | 683 | ||
663 | rc = tt->xmit_cmd_task(conn, conn->ctask); | 684 | rc = tt->xmit_cmd_task(conn, conn->ctask); |
664 | if (rc) | ||
665 | goto again; | ||
666 | 685 | ||
667 | spin_lock_bh(&conn->session->lock); | 686 | spin_lock_bh(&conn->session->lock); |
668 | __iscsi_put_ctask(conn->ctask); | 687 | __iscsi_put_ctask(conn->ctask); |
@@ -778,6 +797,10 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) | |||
778 | } | 797 | } |
779 | 798 | ||
780 | conn = session->leadconn; | 799 | conn = session->leadconn; |
800 | if (!conn) { | ||
801 | reason = FAILURE_SESSION_FREED; | ||
802 | goto fault; | ||
803 | } | ||
781 | 804 | ||
782 | if (!__kfifo_get(session->cmdpool.queue, (void*)&ctask, | 805 | if (!__kfifo_get(session->cmdpool.queue, (void*)&ctask, |
783 | sizeof(void*))) { | 806 | sizeof(void*))) { |
@@ -952,13 +975,13 @@ int iscsi_eh_host_reset(struct scsi_cmnd *sc) | |||
952 | if (session->state == ISCSI_STATE_TERMINATE) { | 975 | if (session->state == ISCSI_STATE_TERMINATE) { |
953 | failed: | 976 | failed: |
954 | debug_scsi("failing host reset: session terminated " | 977 | debug_scsi("failing host reset: session terminated " |
955 | "[CID %d age %d]", conn->id, session->age); | 978 | "[CID %d age %d]\n", conn->id, session->age); |
956 | spin_unlock_bh(&session->lock); | 979 | spin_unlock_bh(&session->lock); |
957 | return FAILED; | 980 | return FAILED; |
958 | } | 981 | } |
959 | 982 | ||
960 | if (sc->SCp.phase == session->age) { | 983 | if (sc->SCp.phase == session->age) { |
961 | debug_scsi("failing connection CID %d due to SCSI host reset", | 984 | debug_scsi("failing connection CID %d due to SCSI host reset\n", |
962 | conn->id); | 985 | conn->id); |
963 | fail_session = 1; | 986 | fail_session = 1; |
964 | } | 987 | } |
@@ -1031,7 +1054,8 @@ static int iscsi_exec_abort_task(struct scsi_cmnd *sc, | |||
1031 | NULL, 0); | 1054 | NULL, 0); |
1032 | if (rc) { | 1055 | if (rc) { |
1033 | iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); | 1056 | iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); |
1034 | debug_scsi("abort sent failure [itt 0x%x] %d", ctask->itt, rc); | 1057 | debug_scsi("abort sent failure [itt 0x%x] %d\n", ctask->itt, |
1058 | rc); | ||
1035 | return rc; | 1059 | return rc; |
1036 | } | 1060 | } |
1037 | 1061 | ||
@@ -1048,7 +1072,7 @@ static int iscsi_exec_abort_task(struct scsi_cmnd *sc, | |||
1048 | conn->tmabort_timer.function = iscsi_tmabort_timedout; | 1072 | conn->tmabort_timer.function = iscsi_tmabort_timedout; |
1049 | conn->tmabort_timer.data = (unsigned long)ctask; | 1073 | conn->tmabort_timer.data = (unsigned long)ctask; |
1050 | add_timer(&conn->tmabort_timer); | 1074 | add_timer(&conn->tmabort_timer); |
1051 | debug_scsi("abort set timeout [itt 0x%x]", ctask->itt); | 1075 | debug_scsi("abort set timeout [itt 0x%x]\n", ctask->itt); |
1052 | } | 1076 | } |
1053 | spin_unlock_bh(&session->lock); | 1077 | spin_unlock_bh(&session->lock); |
1054 | mutex_unlock(&conn->xmitmutex); | 1078 | mutex_unlock(&conn->xmitmutex); |
@@ -1377,7 +1401,6 @@ iscsi_session_setup(struct iscsi_transport *iscsit, | |||
1377 | } | 1401 | } |
1378 | 1402 | ||
1379 | spin_lock_init(&session->lock); | 1403 | spin_lock_init(&session->lock); |
1380 | INIT_LIST_HEAD(&session->connections); | ||
1381 | 1404 | ||
1382 | /* initialize immediate command pool */ | 1405 | /* initialize immediate command pool */ |
1383 | if (iscsi_pool_init(&session->mgmtpool, session->mgmtpool_max, | 1406 | if (iscsi_pool_init(&session->mgmtpool, session->mgmtpool_max, |
@@ -1580,16 +1603,11 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn) | |||
1580 | kfree(conn->persistent_address); | 1603 | kfree(conn->persistent_address); |
1581 | __kfifo_put(session->mgmtpool.queue, (void*)&conn->login_mtask, | 1604 | __kfifo_put(session->mgmtpool.queue, (void*)&conn->login_mtask, |
1582 | sizeof(void*)); | 1605 | sizeof(void*)); |
1583 | list_del(&conn->item); | 1606 | if (session->leadconn == conn) { |
1584 | if (list_empty(&session->connections)) | ||
1585 | session->leadconn = NULL; | 1607 | session->leadconn = NULL; |
1586 | if (session->leadconn && session->leadconn == conn) | ||
1587 | session->leadconn = container_of(session->connections.next, | ||
1588 | struct iscsi_conn, item); | ||
1589 | |||
1590 | if (session->leadconn == NULL) | ||
1591 | /* no connections exits.. reset sequencing */ | 1608 | /* no connections exits.. reset sequencing */ |
1592 | session->cmdsn = session->max_cmdsn = session->exp_cmdsn = 1; | 1609 | session->cmdsn = session->max_cmdsn = session->exp_cmdsn = 1; |
1610 | } | ||
1593 | spin_unlock_bh(&session->lock); | 1611 | spin_unlock_bh(&session->lock); |
1594 | 1612 | ||
1595 | kfifo_free(conn->immqueue); | 1613 | kfifo_free(conn->immqueue); |
@@ -1777,32 +1795,12 @@ int iscsi_conn_bind(struct iscsi_cls_session *cls_session, | |||
1777 | struct iscsi_cls_conn *cls_conn, int is_leading) | 1795 | struct iscsi_cls_conn *cls_conn, int is_leading) |
1778 | { | 1796 | { |
1779 | struct iscsi_session *session = class_to_transport_session(cls_session); | 1797 | struct iscsi_session *session = class_to_transport_session(cls_session); |
1780 | struct iscsi_conn *tmp = ERR_PTR(-EEXIST), *conn = cls_conn->dd_data; | 1798 | struct iscsi_conn *conn = cls_conn->dd_data; |
1781 | 1799 | ||
1782 | /* lookup for existing connection */ | ||
1783 | spin_lock_bh(&session->lock); | 1800 | spin_lock_bh(&session->lock); |
1784 | list_for_each_entry(tmp, &session->connections, item) { | ||
1785 | if (tmp == conn) { | ||
1786 | if (conn->c_stage != ISCSI_CONN_STOPPED || | ||
1787 | conn->stop_stage == STOP_CONN_TERM) { | ||
1788 | printk(KERN_ERR "iscsi: can't bind " | ||
1789 | "non-stopped connection (%d:%d)\n", | ||
1790 | conn->c_stage, conn->stop_stage); | ||
1791 | spin_unlock_bh(&session->lock); | ||
1792 | return -EIO; | ||
1793 | } | ||
1794 | break; | ||
1795 | } | ||
1796 | } | ||
1797 | if (tmp != conn) { | ||
1798 | /* bind new iSCSI connection to session */ | ||
1799 | conn->session = session; | ||
1800 | list_add(&conn->item, &session->connections); | ||
1801 | } | ||
1802 | spin_unlock_bh(&session->lock); | ||
1803 | |||
1804 | if (is_leading) | 1801 | if (is_leading) |
1805 | session->leadconn = conn; | 1802 | session->leadconn = conn; |
1803 | spin_unlock_bh(&session->lock); | ||
1806 | 1804 | ||
1807 | /* | 1805 | /* |
1808 | * Unblock xmitworker(), Login Phase will pass through. | 1806 | * Unblock xmitworker(), Login Phase will pass through. |
diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index 30b8014bcc7a..e34a93435497 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c | |||
@@ -71,55 +71,65 @@ static void smp_task_done(struct sas_task *task) | |||
71 | static int smp_execute_task(struct domain_device *dev, void *req, int req_size, | 71 | static int smp_execute_task(struct domain_device *dev, void *req, int req_size, |
72 | void *resp, int resp_size) | 72 | void *resp, int resp_size) |
73 | { | 73 | { |
74 | int res; | 74 | int res, retry; |
75 | struct sas_task *task = sas_alloc_task(GFP_KERNEL); | 75 | struct sas_task *task = NULL; |
76 | struct sas_internal *i = | 76 | struct sas_internal *i = |
77 | to_sas_internal(dev->port->ha->core.shost->transportt); | 77 | to_sas_internal(dev->port->ha->core.shost->transportt); |
78 | 78 | ||
79 | if (!task) | 79 | for (retry = 0; retry < 3; retry++) { |
80 | return -ENOMEM; | 80 | task = sas_alloc_task(GFP_KERNEL); |
81 | 81 | if (!task) | |
82 | task->dev = dev; | 82 | return -ENOMEM; |
83 | task->task_proto = dev->tproto; | ||
84 | sg_init_one(&task->smp_task.smp_req, req, req_size); | ||
85 | sg_init_one(&task->smp_task.smp_resp, resp, resp_size); | ||
86 | 83 | ||
87 | task->task_done = smp_task_done; | 84 | task->dev = dev; |
85 | task->task_proto = dev->tproto; | ||
86 | sg_init_one(&task->smp_task.smp_req, req, req_size); | ||
87 | sg_init_one(&task->smp_task.smp_resp, resp, resp_size); | ||
88 | 88 | ||
89 | task->timer.data = (unsigned long) task; | 89 | task->task_done = smp_task_done; |
90 | task->timer.function = smp_task_timedout; | ||
91 | task->timer.expires = jiffies + SMP_TIMEOUT*HZ; | ||
92 | add_timer(&task->timer); | ||
93 | 90 | ||
94 | res = i->dft->lldd_execute_task(task, 1, GFP_KERNEL); | 91 | task->timer.data = (unsigned long) task; |
92 | task->timer.function = smp_task_timedout; | ||
93 | task->timer.expires = jiffies + SMP_TIMEOUT*HZ; | ||
94 | add_timer(&task->timer); | ||
95 | 95 | ||
96 | if (res) { | 96 | res = i->dft->lldd_execute_task(task, 1, GFP_KERNEL); |
97 | del_timer(&task->timer); | ||
98 | SAS_DPRINTK("executing SMP task failed:%d\n", res); | ||
99 | goto ex_err; | ||
100 | } | ||
101 | 97 | ||
102 | wait_for_completion(&task->completion); | 98 | if (res) { |
103 | res = -ETASK; | 99 | del_timer(&task->timer); |
104 | if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) { | 100 | SAS_DPRINTK("executing SMP task failed:%d\n", res); |
105 | SAS_DPRINTK("smp task timed out or aborted\n"); | ||
106 | i->dft->lldd_abort_task(task); | ||
107 | if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) { | ||
108 | SAS_DPRINTK("SMP task aborted and not done\n"); | ||
109 | goto ex_err; | 101 | goto ex_err; |
110 | } | 102 | } |
103 | |||
104 | wait_for_completion(&task->completion); | ||
105 | res = -ETASK; | ||
106 | if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) { | ||
107 | SAS_DPRINTK("smp task timed out or aborted\n"); | ||
108 | i->dft->lldd_abort_task(task); | ||
109 | if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) { | ||
110 | SAS_DPRINTK("SMP task aborted and not done\n"); | ||
111 | goto ex_err; | ||
112 | } | ||
113 | } | ||
114 | if (task->task_status.resp == SAS_TASK_COMPLETE && | ||
115 | task->task_status.stat == SAM_GOOD) { | ||
116 | res = 0; | ||
117 | break; | ||
118 | } else { | ||
119 | SAS_DPRINTK("%s: task to dev %016llx response: 0x%x " | ||
120 | "status 0x%x\n", __FUNCTION__, | ||
121 | SAS_ADDR(dev->sas_addr), | ||
122 | task->task_status.resp, | ||
123 | task->task_status.stat); | ||
124 | sas_free_task(task); | ||
125 | task = NULL; | ||
126 | } | ||
111 | } | 127 | } |
112 | if (task->task_status.resp == SAS_TASK_COMPLETE && | ||
113 | task->task_status.stat == SAM_GOOD) | ||
114 | res = 0; | ||
115 | else | ||
116 | SAS_DPRINTK("%s: task to dev %016llx response: 0x%x " | ||
117 | "status 0x%x\n", __FUNCTION__, | ||
118 | SAS_ADDR(dev->sas_addr), | ||
119 | task->task_status.resp, | ||
120 | task->task_status.stat); | ||
121 | ex_err: | 128 | ex_err: |
122 | sas_free_task(task); | 129 | BUG_ON(retry == 3 && task != NULL); |
130 | if (task != NULL) { | ||
131 | sas_free_task(task); | ||
132 | } | ||
123 | return res; | 133 | return res; |
124 | } | 134 | } |
125 | 135 | ||
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 9496e87c135e..2a4e02e7a392 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c | |||
@@ -594,7 +594,8 @@ lpfc_soft_wwpn_show(struct class_device *cdev, char *buf) | |||
594 | { | 594 | { |
595 | struct Scsi_Host *host = class_to_shost(cdev); | 595 | struct Scsi_Host *host = class_to_shost(cdev); |
596 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; | 596 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; |
597 | return snprintf(buf, PAGE_SIZE, "0x%llx\n", phba->cfg_soft_wwpn); | 597 | return snprintf(buf, PAGE_SIZE, "0x%llx\n", |
598 | (unsigned long long)phba->cfg_soft_wwpn); | ||
598 | } | 599 | } |
599 | 600 | ||
600 | 601 | ||
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index 1b53afb1cb57..3add7c237859 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c | |||
@@ -188,7 +188,8 @@ lpfc_alloc_ct_rsp(struct lpfc_hba * phba, int cmdcode, struct ulp_bde64 * bpl, | |||
188 | 188 | ||
189 | if (!mp->virt) { | 189 | if (!mp->virt) { |
190 | kfree(mp); | 190 | kfree(mp); |
191 | lpfc_free_ct_rsp(phba, mlist); | 191 | if (mlist) |
192 | lpfc_free_ct_rsp(phba, mlist); | ||
192 | return NULL; | 193 | return NULL; |
193 | } | 194 | } |
194 | 195 | ||
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index d586c3d3b0d0..19c79a0549a7 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
@@ -305,7 +305,7 @@ lpfc_do_work(void *p) | |||
305 | { | 305 | { |
306 | struct lpfc_hba *phba = p; | 306 | struct lpfc_hba *phba = p; |
307 | int rc; | 307 | int rc; |
308 | DECLARE_WAIT_QUEUE_HEAD(work_waitq); | 308 | DECLARE_WAIT_QUEUE_HEAD_ONSTACK(work_waitq); |
309 | 309 | ||
310 | set_user_nice(current, -20); | 310 | set_user_nice(current, -20); |
311 | phba->work_wait = &work_waitq; | 311 | phba->work_wait = &work_waitq; |
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 24a1779b9af4..582f5ea4e84e 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -2983,7 +2983,7 @@ lpfc_sli_issue_iocb_wait(struct lpfc_hba * phba, | |||
2983 | struct lpfc_iocbq * prspiocbq, | 2983 | struct lpfc_iocbq * prspiocbq, |
2984 | uint32_t timeout) | 2984 | uint32_t timeout) |
2985 | { | 2985 | { |
2986 | DECLARE_WAIT_QUEUE_HEAD(done_q); | 2986 | DECLARE_WAIT_QUEUE_HEAD_ONSTACK(done_q); |
2987 | long timeleft, timeout_req = 0; | 2987 | long timeleft, timeout_req = 0; |
2988 | int retval = IOCB_SUCCESS; | 2988 | int retval = IOCB_SUCCESS; |
2989 | uint32_t creg_val; | 2989 | uint32_t creg_val; |
@@ -3061,7 +3061,7 @@ int | |||
3061 | lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq, | 3061 | lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq, |
3062 | uint32_t timeout) | 3062 | uint32_t timeout) |
3063 | { | 3063 | { |
3064 | DECLARE_WAIT_QUEUE_HEAD(done_q); | 3064 | DECLARE_WAIT_QUEUE_HEAD_ONSTACK(done_q); |
3065 | DECLARE_WAITQUEUE(wq_entry, current); | 3065 | DECLARE_WAITQUEUE(wq_entry, current); |
3066 | uint32_t timeleft = 0; | 3066 | uint32_t timeleft = 0; |
3067 | int retval; | 3067 | int retval; |
diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c index c0edb662d863..7bac86dda88f 100644 --- a/drivers/scsi/megaraid/megaraid_mbox.c +++ b/drivers/scsi/megaraid/megaraid_mbox.c | |||
@@ -884,7 +884,7 @@ megaraid_init_mbox(adapter_t *adapter) | |||
884 | 884 | ||
885 | if (((magic64 == HBA_SIGNATURE_64_BIT) && | 885 | if (((magic64 == HBA_SIGNATURE_64_BIT) && |
886 | ((adapter->pdev->subsystem_device != | 886 | ((adapter->pdev->subsystem_device != |
887 | PCI_SUBSYS_ID_MEGARAID_SATA_150_6) || | 887 | PCI_SUBSYS_ID_MEGARAID_SATA_150_6) && |
888 | (adapter->pdev->subsystem_device != | 888 | (adapter->pdev->subsystem_device != |
889 | PCI_SUBSYS_ID_MEGARAID_SATA_150_4))) || | 889 | PCI_SUBSYS_ID_MEGARAID_SATA_150_4))) || |
890 | (adapter->pdev->vendor == PCI_VENDOR_ID_LSI_LOGIC && | 890 | (adapter->pdev->vendor == PCI_VENDOR_ID_LSI_LOGIC && |
diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c index b1d346049525..f2d79c3f0b8e 100644 --- a/drivers/scsi/pcmcia/nsp_cs.c +++ b/drivers/scsi/pcmcia/nsp_cs.c | |||
@@ -183,7 +183,7 @@ static void nsp_cs_dmessage(const char *func, int line, int mask, char *fmt, ... | |||
183 | * Clenaup parameters and call done() functions. | 183 | * Clenaup parameters and call done() functions. |
184 | * You must be set SCpnt->result before call this function. | 184 | * You must be set SCpnt->result before call this function. |
185 | */ | 185 | */ |
186 | static void nsp_scsi_done(Scsi_Cmnd *SCpnt) | 186 | static void nsp_scsi_done(struct scsi_cmnd *SCpnt) |
187 | { | 187 | { |
188 | nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; | 188 | nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; |
189 | 189 | ||
@@ -192,7 +192,8 @@ static void nsp_scsi_done(Scsi_Cmnd *SCpnt) | |||
192 | SCpnt->scsi_done(SCpnt); | 192 | SCpnt->scsi_done(SCpnt); |
193 | } | 193 | } |
194 | 194 | ||
195 | static int nsp_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) | 195 | static int nsp_queuecommand(struct scsi_cmnd *SCpnt, |
196 | void (*done)(struct scsi_cmnd *)) | ||
196 | { | 197 | { |
197 | #ifdef NSP_DEBUG | 198 | #ifdef NSP_DEBUG |
198 | /*unsigned int host_id = SCpnt->device->host->this_id;*/ | 199 | /*unsigned int host_id = SCpnt->device->host->this_id;*/ |
@@ -365,7 +366,7 @@ static int nsphw_init(nsp_hw_data *data) | |||
365 | /* | 366 | /* |
366 | * Start selection phase | 367 | * Start selection phase |
367 | */ | 368 | */ |
368 | static int nsphw_start_selection(Scsi_Cmnd *SCpnt) | 369 | static int nsphw_start_selection(struct scsi_cmnd *SCpnt) |
369 | { | 370 | { |
370 | unsigned int host_id = SCpnt->device->host->this_id; | 371 | unsigned int host_id = SCpnt->device->host->this_id; |
371 | unsigned int base = SCpnt->device->host->io_port; | 372 | unsigned int base = SCpnt->device->host->io_port; |
@@ -446,7 +447,7 @@ static struct nsp_sync_table nsp_sync_table_20M[] = { | |||
446 | /* | 447 | /* |
447 | * setup synchronous data transfer mode | 448 | * setup synchronous data transfer mode |
448 | */ | 449 | */ |
449 | static int nsp_analyze_sdtr(Scsi_Cmnd *SCpnt) | 450 | static int nsp_analyze_sdtr(struct scsi_cmnd *SCpnt) |
450 | { | 451 | { |
451 | unsigned char target = scmd_id(SCpnt); | 452 | unsigned char target = scmd_id(SCpnt); |
452 | // unsigned char lun = SCpnt->device->lun; | 453 | // unsigned char lun = SCpnt->device->lun; |
@@ -504,7 +505,7 @@ static int nsp_analyze_sdtr(Scsi_Cmnd *SCpnt) | |||
504 | /* | 505 | /* |
505 | * start ninja hardware timer | 506 | * start ninja hardware timer |
506 | */ | 507 | */ |
507 | static void nsp_start_timer(Scsi_Cmnd *SCpnt, int time) | 508 | static void nsp_start_timer(struct scsi_cmnd *SCpnt, int time) |
508 | { | 509 | { |
509 | unsigned int base = SCpnt->device->host->io_port; | 510 | unsigned int base = SCpnt->device->host->io_port; |
510 | nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; | 511 | nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; |
@@ -517,7 +518,8 @@ static void nsp_start_timer(Scsi_Cmnd *SCpnt, int time) | |||
517 | /* | 518 | /* |
518 | * wait for bus phase change | 519 | * wait for bus phase change |
519 | */ | 520 | */ |
520 | static int nsp_negate_signal(Scsi_Cmnd *SCpnt, unsigned char mask, char *str) | 521 | static int nsp_negate_signal(struct scsi_cmnd *SCpnt, unsigned char mask, |
522 | char *str) | ||
521 | { | 523 | { |
522 | unsigned int base = SCpnt->device->host->io_port; | 524 | unsigned int base = SCpnt->device->host->io_port; |
523 | unsigned char reg; | 525 | unsigned char reg; |
@@ -544,9 +546,9 @@ static int nsp_negate_signal(Scsi_Cmnd *SCpnt, unsigned char mask, char *str) | |||
544 | /* | 546 | /* |
545 | * expect Ninja Irq | 547 | * expect Ninja Irq |
546 | */ | 548 | */ |
547 | static int nsp_expect_signal(Scsi_Cmnd *SCpnt, | 549 | static int nsp_expect_signal(struct scsi_cmnd *SCpnt, |
548 | unsigned char current_phase, | 550 | unsigned char current_phase, |
549 | unsigned char mask) | 551 | unsigned char mask) |
550 | { | 552 | { |
551 | unsigned int base = SCpnt->device->host->io_port; | 553 | unsigned int base = SCpnt->device->host->io_port; |
552 | int time_out; | 554 | int time_out; |
@@ -579,7 +581,7 @@ static int nsp_expect_signal(Scsi_Cmnd *SCpnt, | |||
579 | /* | 581 | /* |
580 | * transfer SCSI message | 582 | * transfer SCSI message |
581 | */ | 583 | */ |
582 | static int nsp_xfer(Scsi_Cmnd *SCpnt, int phase) | 584 | static int nsp_xfer(struct scsi_cmnd *SCpnt, int phase) |
583 | { | 585 | { |
584 | unsigned int base = SCpnt->device->host->io_port; | 586 | unsigned int base = SCpnt->device->host->io_port; |
585 | nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; | 587 | nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; |
@@ -619,7 +621,7 @@ static int nsp_xfer(Scsi_Cmnd *SCpnt, int phase) | |||
619 | /* | 621 | /* |
620 | * get extra SCSI data from fifo | 622 | * get extra SCSI data from fifo |
621 | */ | 623 | */ |
622 | static int nsp_dataphase_bypass(Scsi_Cmnd *SCpnt) | 624 | static int nsp_dataphase_bypass(struct scsi_cmnd *SCpnt) |
623 | { | 625 | { |
624 | nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; | 626 | nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; |
625 | unsigned int count; | 627 | unsigned int count; |
@@ -651,7 +653,7 @@ static int nsp_dataphase_bypass(Scsi_Cmnd *SCpnt) | |||
651 | /* | 653 | /* |
652 | * accept reselection | 654 | * accept reselection |
653 | */ | 655 | */ |
654 | static int nsp_reselected(Scsi_Cmnd *SCpnt) | 656 | static int nsp_reselected(struct scsi_cmnd *SCpnt) |
655 | { | 657 | { |
656 | unsigned int base = SCpnt->device->host->io_port; | 658 | unsigned int base = SCpnt->device->host->io_port; |
657 | unsigned int host_id = SCpnt->device->host->this_id; | 659 | unsigned int host_id = SCpnt->device->host->this_id; |
@@ -690,7 +692,7 @@ static int nsp_reselected(Scsi_Cmnd *SCpnt) | |||
690 | /* | 692 | /* |
691 | * count how many data transferd | 693 | * count how many data transferd |
692 | */ | 694 | */ |
693 | static int nsp_fifo_count(Scsi_Cmnd *SCpnt) | 695 | static int nsp_fifo_count(struct scsi_cmnd *SCpnt) |
694 | { | 696 | { |
695 | unsigned int base = SCpnt->device->host->io_port; | 697 | unsigned int base = SCpnt->device->host->io_port; |
696 | unsigned int count; | 698 | unsigned int count; |
@@ -717,7 +719,7 @@ static int nsp_fifo_count(Scsi_Cmnd *SCpnt) | |||
717 | /* | 719 | /* |
718 | * read data in DATA IN phase | 720 | * read data in DATA IN phase |
719 | */ | 721 | */ |
720 | static void nsp_pio_read(Scsi_Cmnd *SCpnt) | 722 | static void nsp_pio_read(struct scsi_cmnd *SCpnt) |
721 | { | 723 | { |
722 | unsigned int base = SCpnt->device->host->io_port; | 724 | unsigned int base = SCpnt->device->host->io_port; |
723 | unsigned long mmio_base = SCpnt->device->host->base; | 725 | unsigned long mmio_base = SCpnt->device->host->base; |
@@ -812,7 +814,7 @@ static void nsp_pio_read(Scsi_Cmnd *SCpnt) | |||
812 | /* | 814 | /* |
813 | * write data in DATA OUT phase | 815 | * write data in DATA OUT phase |
814 | */ | 816 | */ |
815 | static void nsp_pio_write(Scsi_Cmnd *SCpnt) | 817 | static void nsp_pio_write(struct scsi_cmnd *SCpnt) |
816 | { | 818 | { |
817 | unsigned int base = SCpnt->device->host->io_port; | 819 | unsigned int base = SCpnt->device->host->io_port; |
818 | unsigned long mmio_base = SCpnt->device->host->base; | 820 | unsigned long mmio_base = SCpnt->device->host->base; |
@@ -905,7 +907,7 @@ static void nsp_pio_write(Scsi_Cmnd *SCpnt) | |||
905 | /* | 907 | /* |
906 | * setup synchronous/asynchronous data transfer mode | 908 | * setup synchronous/asynchronous data transfer mode |
907 | */ | 909 | */ |
908 | static int nsp_nexus(Scsi_Cmnd *SCpnt) | 910 | static int nsp_nexus(struct scsi_cmnd *SCpnt) |
909 | { | 911 | { |
910 | unsigned int base = SCpnt->device->host->io_port; | 912 | unsigned int base = SCpnt->device->host->io_port; |
911 | unsigned char target = scmd_id(SCpnt); | 913 | unsigned char target = scmd_id(SCpnt); |
@@ -952,7 +954,7 @@ static irqreturn_t nspintr(int irq, void *dev_id) | |||
952 | { | 954 | { |
953 | unsigned int base; | 955 | unsigned int base; |
954 | unsigned char irq_status, irq_phase, phase; | 956 | unsigned char irq_status, irq_phase, phase; |
955 | Scsi_Cmnd *tmpSC; | 957 | struct scsi_cmnd *tmpSC; |
956 | unsigned char target, lun; | 958 | unsigned char target, lun; |
957 | unsigned int *sync_neg; | 959 | unsigned int *sync_neg; |
958 | int i, tmp; | 960 | int i, tmp; |
@@ -1530,7 +1532,7 @@ nsp_proc_info( | |||
1530 | /*---------------------------------------------------------------*/ | 1532 | /*---------------------------------------------------------------*/ |
1531 | 1533 | ||
1532 | /* | 1534 | /* |
1533 | static int nsp_eh_abort(Scsi_Cmnd *SCpnt) | 1535 | static int nsp_eh_abort(struct scsi_cmnd *SCpnt) |
1534 | { | 1536 | { |
1535 | nsp_dbg(NSP_DEBUG_BUSRESET, "SCpnt=0x%p", SCpnt); | 1537 | nsp_dbg(NSP_DEBUG_BUSRESET, "SCpnt=0x%p", SCpnt); |
1536 | 1538 | ||
@@ -1558,7 +1560,7 @@ static int nsp_bus_reset(nsp_hw_data *data) | |||
1558 | return SUCCESS; | 1560 | return SUCCESS; |
1559 | } | 1561 | } |
1560 | 1562 | ||
1561 | static int nsp_eh_bus_reset(Scsi_Cmnd *SCpnt) | 1563 | static int nsp_eh_bus_reset(struct scsi_cmnd *SCpnt) |
1562 | { | 1564 | { |
1563 | nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; | 1565 | nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; |
1564 | 1566 | ||
@@ -1567,7 +1569,7 @@ static int nsp_eh_bus_reset(Scsi_Cmnd *SCpnt) | |||
1567 | return nsp_bus_reset(data); | 1569 | return nsp_bus_reset(data); |
1568 | } | 1570 | } |
1569 | 1571 | ||
1570 | static int nsp_eh_host_reset(Scsi_Cmnd *SCpnt) | 1572 | static int nsp_eh_host_reset(struct scsi_cmnd *SCpnt) |
1571 | { | 1573 | { |
1572 | nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; | 1574 | nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; |
1573 | 1575 | ||
diff --git a/drivers/scsi/pcmcia/nsp_cs.h b/drivers/scsi/pcmcia/nsp_cs.h index a88714f4c05b..625ca97da52d 100644 --- a/drivers/scsi/pcmcia/nsp_cs.h +++ b/drivers/scsi/pcmcia/nsp_cs.h | |||
@@ -266,7 +266,7 @@ typedef struct _nsp_hw_data { | |||
266 | 266 | ||
267 | int TimerCount; | 267 | int TimerCount; |
268 | int SelectionTimeOut; | 268 | int SelectionTimeOut; |
269 | Scsi_Cmnd *CurrentSC; | 269 | struct scsi_cmnd *CurrentSC; |
270 | //int CurrnetTarget; | 270 | //int CurrnetTarget; |
271 | 271 | ||
272 | int FifoCount; | 272 | int FifoCount; |
@@ -319,30 +319,34 @@ static int nsp_proc_info ( | |||
319 | int hostno, | 319 | int hostno, |
320 | #endif | 320 | #endif |
321 | int inout); | 321 | int inout); |
322 | static int nsp_queuecommand(Scsi_Cmnd *SCpnt, void (* done)(Scsi_Cmnd *SCpnt)); | 322 | static int nsp_queuecommand(struct scsi_cmnd *SCpnt, |
323 | void (* done)(struct scsi_cmnd *SCpnt)); | ||
323 | 324 | ||
324 | /* Error handler */ | 325 | /* Error handler */ |
325 | /*static int nsp_eh_abort (Scsi_Cmnd *SCpnt);*/ | 326 | /*static int nsp_eh_abort (struct scsi_cmnd *SCpnt);*/ |
326 | /*static int nsp_eh_device_reset(Scsi_Cmnd *SCpnt);*/ | 327 | /*static int nsp_eh_device_reset(struct scsi_cmnd *SCpnt);*/ |
327 | static int nsp_eh_bus_reset (Scsi_Cmnd *SCpnt); | 328 | static int nsp_eh_bus_reset (struct scsi_cmnd *SCpnt); |
328 | static int nsp_eh_host_reset (Scsi_Cmnd *SCpnt); | 329 | static int nsp_eh_host_reset (struct scsi_cmnd *SCpnt); |
329 | static int nsp_bus_reset (nsp_hw_data *data); | 330 | static int nsp_bus_reset (nsp_hw_data *data); |
330 | 331 | ||
331 | /* */ | 332 | /* */ |
332 | static int nsphw_init (nsp_hw_data *data); | 333 | static int nsphw_init (nsp_hw_data *data); |
333 | static int nsphw_start_selection(Scsi_Cmnd *SCpnt); | 334 | static int nsphw_start_selection(struct scsi_cmnd *SCpnt); |
334 | static void nsp_start_timer (Scsi_Cmnd *SCpnt, int time); | 335 | static void nsp_start_timer (struct scsi_cmnd *SCpnt, int time); |
335 | static int nsp_fifo_count (Scsi_Cmnd *SCpnt); | 336 | static int nsp_fifo_count (struct scsi_cmnd *SCpnt); |
336 | static void nsp_pio_read (Scsi_Cmnd *SCpnt); | 337 | static void nsp_pio_read (struct scsi_cmnd *SCpnt); |
337 | static void nsp_pio_write (Scsi_Cmnd *SCpnt); | 338 | static void nsp_pio_write (struct scsi_cmnd *SCpnt); |
338 | static int nsp_nexus (Scsi_Cmnd *SCpnt); | 339 | static int nsp_nexus (struct scsi_cmnd *SCpnt); |
339 | static void nsp_scsi_done (Scsi_Cmnd *SCpnt); | 340 | static void nsp_scsi_done (struct scsi_cmnd *SCpnt); |
340 | static int nsp_analyze_sdtr (Scsi_Cmnd *SCpnt); | 341 | static int nsp_analyze_sdtr (struct scsi_cmnd *SCpnt); |
341 | static int nsp_negate_signal (Scsi_Cmnd *SCpnt, unsigned char mask, char *str); | 342 | static int nsp_negate_signal (struct scsi_cmnd *SCpnt, |
342 | static int nsp_expect_signal (Scsi_Cmnd *SCpnt, unsigned char current_phase, unsigned char mask); | 343 | unsigned char mask, char *str); |
343 | static int nsp_xfer (Scsi_Cmnd *SCpnt, int phase); | 344 | static int nsp_expect_signal (struct scsi_cmnd *SCpnt, |
344 | static int nsp_dataphase_bypass (Scsi_Cmnd *SCpnt); | 345 | unsigned char current_phase, |
345 | static int nsp_reselected (Scsi_Cmnd *SCpnt); | 346 | unsigned char mask); |
347 | static int nsp_xfer (struct scsi_cmnd *SCpnt, int phase); | ||
348 | static int nsp_dataphase_bypass (struct scsi_cmnd *SCpnt); | ||
349 | static int nsp_reselected (struct scsi_cmnd *SCpnt); | ||
346 | static struct Scsi_Host *nsp_detect(struct scsi_host_template *sht); | 350 | static struct Scsi_Host *nsp_detect(struct scsi_host_template *sht); |
347 | 351 | ||
348 | /* Interrupt handler */ | 352 | /* Interrupt handler */ |
@@ -355,8 +359,8 @@ static void __exit nsp_cs_exit(void); | |||
355 | 359 | ||
356 | /* Debug */ | 360 | /* Debug */ |
357 | #ifdef NSP_DEBUG | 361 | #ifdef NSP_DEBUG |
358 | static void show_command (Scsi_Cmnd *SCpnt); | 362 | static void show_command (struct scsi_cmnd *SCpnt); |
359 | static void show_phase (Scsi_Cmnd *SCpnt); | 363 | static void show_phase (struct scsi_cmnd *SCpnt); |
360 | static void show_busphase(unsigned char stat); | 364 | static void show_busphase(unsigned char stat); |
361 | static void show_message (nsp_hw_data *data); | 365 | static void show_message (nsp_hw_data *data); |
362 | #else | 366 | #else |
diff --git a/drivers/scsi/pcmcia/nsp_debug.c b/drivers/scsi/pcmcia/nsp_debug.c index 62e5c60067fd..2f75fe6e35a7 100644 --- a/drivers/scsi/pcmcia/nsp_debug.c +++ b/drivers/scsi/pcmcia/nsp_debug.c | |||
@@ -138,12 +138,12 @@ static void print_commandk (unsigned char *command) | |||
138 | printk("\n"); | 138 | printk("\n"); |
139 | } | 139 | } |
140 | 140 | ||
141 | static void show_command(Scsi_Cmnd *SCpnt) | 141 | static void show_command(struct scsi_cmnd *SCpnt) |
142 | { | 142 | { |
143 | print_commandk(SCpnt->cmnd); | 143 | print_commandk(SCpnt->cmnd); |
144 | } | 144 | } |
145 | 145 | ||
146 | static void show_phase(Scsi_Cmnd *SCpnt) | 146 | static void show_phase(struct scsi_cmnd *SCpnt) |
147 | { | 147 | { |
148 | int i = SCpnt->SCp.phase; | 148 | int i = SCpnt->SCp.phase; |
149 | 149 | ||
diff --git a/drivers/scsi/pcmcia/nsp_message.c b/drivers/scsi/pcmcia/nsp_message.c index d7057737ff34..ef593b70d0f0 100644 --- a/drivers/scsi/pcmcia/nsp_message.c +++ b/drivers/scsi/pcmcia/nsp_message.c | |||
@@ -8,7 +8,7 @@ | |||
8 | 8 | ||
9 | /* $Id: nsp_message.c,v 1.6 2003/07/26 14:21:09 elca Exp $ */ | 9 | /* $Id: nsp_message.c,v 1.6 2003/07/26 14:21:09 elca Exp $ */ |
10 | 10 | ||
11 | static void nsp_message_in(Scsi_Cmnd *SCpnt) | 11 | static void nsp_message_in(struct scsi_cmnd *SCpnt) |
12 | { | 12 | { |
13 | unsigned int base = SCpnt->device->host->io_port; | 13 | unsigned int base = SCpnt->device->host->io_port; |
14 | nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; | 14 | nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; |
@@ -50,7 +50,7 @@ static void nsp_message_in(Scsi_Cmnd *SCpnt) | |||
50 | 50 | ||
51 | } | 51 | } |
52 | 52 | ||
53 | static void nsp_message_out(Scsi_Cmnd *SCpnt) | 53 | static void nsp_message_out(struct scsi_cmnd *SCpnt) |
54 | { | 54 | { |
55 | nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; | 55 | nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata; |
56 | int ret = 1; | 56 | int ret = 1; |
diff --git a/drivers/scsi/ppa.c b/drivers/scsi/ppa.c index b0eba39f208a..89a2a9f11e41 100644 --- a/drivers/scsi/ppa.c +++ b/drivers/scsi/ppa.c | |||
@@ -1012,7 +1012,7 @@ static LIST_HEAD(ppa_hosts); | |||
1012 | static int __ppa_attach(struct parport *pb) | 1012 | static int __ppa_attach(struct parport *pb) |
1013 | { | 1013 | { |
1014 | struct Scsi_Host *host; | 1014 | struct Scsi_Host *host; |
1015 | DECLARE_WAIT_QUEUE_HEAD(waiting); | 1015 | DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waiting); |
1016 | DEFINE_WAIT(wait); | 1016 | DEFINE_WAIT(wait); |
1017 | ppa_struct *dev; | 1017 | ppa_struct *dev; |
1018 | int ports; | 1018 | int ports; |
diff --git a/drivers/scsi/psi240i.c b/drivers/scsi/psi240i.c index a720c9265e66..899e89d6fe67 100644 --- a/drivers/scsi/psi240i.c +++ b/drivers/scsi/psi240i.c | |||
@@ -87,11 +87,11 @@ typedef struct | |||
87 | { | 87 | { |
88 | USHORT ports[13]; | 88 | USHORT ports[13]; |
89 | OUR_DEVICE device[8]; | 89 | OUR_DEVICE device[8]; |
90 | Scsi_Cmnd *pSCmnd; | 90 | struct scsi_cmnd *pSCmnd; |
91 | IDE_STRUCT ide; | 91 | IDE_STRUCT ide; |
92 | ULONG startSector; | 92 | ULONG startSector; |
93 | USHORT sectorCount; | 93 | USHORT sectorCount; |
94 | Scsi_Cmnd *SCpnt; | 94 | struct scsi_cmnd *SCpnt; |
95 | VOID *buffer; | 95 | VOID *buffer; |
96 | USHORT expectingIRQ; | 96 | USHORT expectingIRQ; |
97 | } ADAPTER240I, *PADAPTER240I; | 97 | } ADAPTER240I, *PADAPTER240I; |
@@ -253,12 +253,12 @@ static ULONG DecodeError (struct Scsi_Host *pshost, UCHAR status) | |||
253 | ****************************************************************/ | 253 | ****************************************************************/ |
254 | static void Irq_Handler (int irq, void *dev_id) | 254 | static void Irq_Handler (int irq, void *dev_id) |
255 | { | 255 | { |
256 | struct Scsi_Host *shost; // Pointer to host data block | 256 | struct Scsi_Host *shost; // Pointer to host data block |
257 | PADAPTER240I padapter; // Pointer to adapter control structure | 257 | PADAPTER240I padapter; // Pointer to adapter control structure |
258 | USHORT *pports; // I/O port array | 258 | USHORT *pports; // I/O port array |
259 | Scsi_Cmnd *SCpnt; | 259 | struct scsi_cmnd *SCpnt; |
260 | UCHAR status; | 260 | UCHAR status; |
261 | int z; | 261 | int z; |
262 | 262 | ||
263 | DEB(printk ("\npsi240i received interrupt\n")); | 263 | DEB(printk ("\npsi240i received interrupt\n")); |
264 | 264 | ||
@@ -328,7 +328,7 @@ static void Irq_Handler (int irq, void *dev_id) | |||
328 | pinquiryData->AdditionalLength = 35 - 4; | 328 | pinquiryData->AdditionalLength = 35 - 4; |
329 | 329 | ||
330 | // Fill in vendor identification fields. | 330 | // Fill in vendor identification fields. |
331 | for ( z = 0; z < 20; z += 2 ) | 331 | for ( z = 0; z < 8; z += 2 ) |
332 | { | 332 | { |
333 | pinquiryData->VendorId[z] = ((UCHAR *)identifyData.ModelNumber)[z + 1]; | 333 | pinquiryData->VendorId[z] = ((UCHAR *)identifyData.ModelNumber)[z + 1]; |
334 | pinquiryData->VendorId[z + 1] = ((UCHAR *)identifyData.ModelNumber)[z]; | 334 | pinquiryData->VendorId[z + 1] = ((UCHAR *)identifyData.ModelNumber)[z]; |
@@ -389,12 +389,17 @@ static irqreturn_t do_Irq_Handler (int irq, void *dev_id) | |||
389 | * Returns: Status code. | 389 | * Returns: Status code. |
390 | * | 390 | * |
391 | ****************************************************************/ | 391 | ****************************************************************/ |
392 | static int Psi240i_QueueCommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) | 392 | static int Psi240i_QueueCommand(struct scsi_cmnd *SCpnt, |
393 | void (*done)(struct scsi_cmnd *)) | ||
393 | { | 394 | { |
394 | UCHAR *cdb = (UCHAR *)SCpnt->cmnd; // Pointer to SCSI CDB | 395 | UCHAR *cdb = (UCHAR *)SCpnt->cmnd; |
395 | PADAPTER240I padapter = HOSTDATA (SCpnt->device->host); // Pointer to adapter control structure | 396 | // Pointer to SCSI CDB |
396 | POUR_DEVICE pdev = &padapter->device [SCpnt->device->id];// Pointer to device information | 397 | PADAPTER240I padapter = HOSTDATA (SCpnt->device->host); |
397 | UCHAR rc; // command return code | 398 | // Pointer to adapter control structure |
399 | POUR_DEVICE pdev = &padapter->device [SCpnt->device->id]; | ||
400 | // Pointer to device information | ||
401 | UCHAR rc; | ||
402 | // command return code | ||
398 | 403 | ||
399 | SCpnt->scsi_done = done; | 404 | SCpnt->scsi_done = done; |
400 | padapter->ide.ide.ides.spigot = pdev->spigot; | 405 | padapter->ide.ide.ides.spigot = pdev->spigot; |
diff --git a/drivers/scsi/psi240i.h b/drivers/scsi/psi240i.h index 6a598766df51..21ebb9214004 100644 --- a/drivers/scsi/psi240i.h +++ b/drivers/scsi/psi240i.h | |||
@@ -309,7 +309,7 @@ typedef struct _IDENTIFY_DATA2 { | |||
309 | #endif // PSI_EIDE_SCSIOP | 309 | #endif // PSI_EIDE_SCSIOP |
310 | 310 | ||
311 | // function prototypes | 311 | // function prototypes |
312 | int Psi240i_Command (Scsi_Cmnd *SCpnt); | 312 | int Psi240i_Command(struct scsi_cmnd *SCpnt); |
313 | int Psi240i_Abort (Scsi_Cmnd *SCpnt); | 313 | int Psi240i_Abort(struct scsi_cmnd *SCpnt); |
314 | int Psi240i_Reset (Scsi_Cmnd *SCpnt, unsigned int flags); | 314 | int Psi240i_Reset(struct scsi_cmnd *SCpnt, unsigned int flags); |
315 | #endif | 315 | #endif |
diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c index 2521d548dd59..16af5b79e587 100644 --- a/drivers/scsi/qla1280.c +++ b/drivers/scsi/qla1280.c | |||
@@ -931,11 +931,10 @@ qla1280_error_action(struct scsi_cmnd *cmd, enum action action) | |||
931 | 931 | ||
932 | case BUS_RESET: | 932 | case BUS_RESET: |
933 | if (qla1280_verbose) | 933 | if (qla1280_verbose) |
934 | printk(KERN_INFO "qla1280(%ld:%d): Issuing BUS " | 934 | printk(KERN_INFO "qla1280(%ld:%d): Issued bus " |
935 | "DEVICE RESET\n", ha->host_no, bus); | 935 | "reset.\n", ha->host_no, bus); |
936 | if (qla1280_bus_reset(ha, bus == 0)) | 936 | if (qla1280_bus_reset(ha, bus) == 0) |
937 | result = SUCCESS; | 937 | result = SUCCESS; |
938 | |||
939 | break; | 938 | break; |
940 | 939 | ||
941 | case ADAPTER_RESET: | 940 | case ADAPTER_RESET: |
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index ee75a71f3c66..285c8e8ff1a0 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c | |||
@@ -379,21 +379,37 @@ static struct bin_attribute sysfs_sfp_attr = { | |||
379 | .read = qla2x00_sysfs_read_sfp, | 379 | .read = qla2x00_sysfs_read_sfp, |
380 | }; | 380 | }; |
381 | 381 | ||
382 | static struct sysfs_entry { | ||
383 | char *name; | ||
384 | struct bin_attribute *attr; | ||
385 | int is4GBp_only; | ||
386 | } bin_file_entries[] = { | ||
387 | { "fw_dump", &sysfs_fw_dump_attr, }, | ||
388 | { "nvram", &sysfs_nvram_attr, }, | ||
389 | { "optrom", &sysfs_optrom_attr, }, | ||
390 | { "optrom_ctl", &sysfs_optrom_ctl_attr, }, | ||
391 | { "vpd", &sysfs_vpd_attr, 1 }, | ||
392 | { "sfp", &sysfs_sfp_attr, 1 }, | ||
393 | { 0 }, | ||
394 | }; | ||
395 | |||
382 | void | 396 | void |
383 | qla2x00_alloc_sysfs_attr(scsi_qla_host_t *ha) | 397 | qla2x00_alloc_sysfs_attr(scsi_qla_host_t *ha) |
384 | { | 398 | { |
385 | struct Scsi_Host *host = ha->host; | 399 | struct Scsi_Host *host = ha->host; |
400 | struct sysfs_entry *iter; | ||
401 | int ret; | ||
386 | 402 | ||
387 | sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_fw_dump_attr); | 403 | for (iter = bin_file_entries; iter->name; iter++) { |
388 | sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_nvram_attr); | 404 | if (iter->is4GBp_only && (!IS_QLA24XX(ha) && !IS_QLA54XX(ha))) |
389 | sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_optrom_attr); | 405 | continue; |
390 | sysfs_create_bin_file(&host->shost_gendev.kobj, | 406 | |
391 | &sysfs_optrom_ctl_attr); | 407 | ret = sysfs_create_bin_file(&host->shost_gendev.kobj, |
392 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { | 408 | iter->attr); |
393 | sysfs_create_bin_file(&host->shost_gendev.kobj, | 409 | if (ret) |
394 | &sysfs_vpd_attr); | 410 | qla_printk(KERN_INFO, ha, |
395 | sysfs_create_bin_file(&host->shost_gendev.kobj, | 411 | "Unable to create sysfs %s binary attribute " |
396 | &sysfs_sfp_attr); | 412 | "(%d).\n", iter->name, ret); |
397 | } | 413 | } |
398 | } | 414 | } |
399 | 415 | ||
@@ -401,17 +417,14 @@ void | |||
401 | qla2x00_free_sysfs_attr(scsi_qla_host_t *ha) | 417 | qla2x00_free_sysfs_attr(scsi_qla_host_t *ha) |
402 | { | 418 | { |
403 | struct Scsi_Host *host = ha->host; | 419 | struct Scsi_Host *host = ha->host; |
420 | struct sysfs_entry *iter; | ||
421 | |||
422 | for (iter = bin_file_entries; iter->name; iter++) { | ||
423 | if (iter->is4GBp_only && (!IS_QLA24XX(ha) && !IS_QLA54XX(ha))) | ||
424 | continue; | ||
404 | 425 | ||
405 | sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_fw_dump_attr); | ||
406 | sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_nvram_attr); | ||
407 | sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_optrom_attr); | ||
408 | sysfs_remove_bin_file(&host->shost_gendev.kobj, | ||
409 | &sysfs_optrom_ctl_attr); | ||
410 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { | ||
411 | sysfs_remove_bin_file(&host->shost_gendev.kobj, | ||
412 | &sysfs_vpd_attr); | ||
413 | sysfs_remove_bin_file(&host->shost_gendev.kobj, | 426 | sysfs_remove_bin_file(&host->shost_gendev.kobj, |
414 | &sysfs_sfp_attr); | 427 | iter->attr); |
415 | } | 428 | } |
416 | 429 | ||
417 | if (ha->beacon_blink_led == 1) | 430 | if (ha->beacon_blink_led == 1) |
diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h index 90dad7e88985..5b12278968e0 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.h +++ b/drivers/scsi/qla2xxx/qla_dbg.h | |||
@@ -38,7 +38,7 @@ | |||
38 | * Macros use for debugging the driver. | 38 | * Macros use for debugging the driver. |
39 | */ | 39 | */ |
40 | 40 | ||
41 | #define DEBUG(x) do { if (qla2_extended_error_logging) { x; } } while (0) | 41 | #define DEBUG(x) do { if (ql2xextended_error_logging) { x; } } while (0) |
42 | 42 | ||
43 | #if defined(QL_DEBUG_LEVEL_1) | 43 | #if defined(QL_DEBUG_LEVEL_1) |
44 | #define DEBUG1(x) do {x;} while (0) | 44 | #define DEBUG1(x) do {x;} while (0) |
@@ -46,12 +46,12 @@ | |||
46 | #define DEBUG1(x) do {} while (0) | 46 | #define DEBUG1(x) do {} while (0) |
47 | #endif | 47 | #endif |
48 | 48 | ||
49 | #define DEBUG2(x) do { if (qla2_extended_error_logging) { x; } } while (0) | 49 | #define DEBUG2(x) do { if (ql2xextended_error_logging) { x; } } while (0) |
50 | #define DEBUG2_3(x) do { if (qla2_extended_error_logging) { x; } } while (0) | 50 | #define DEBUG2_3(x) do { if (ql2xextended_error_logging) { x; } } while (0) |
51 | #define DEBUG2_3_11(x) do { if (qla2_extended_error_logging) { x; } } while (0) | 51 | #define DEBUG2_3_11(x) do { if (ql2xextended_error_logging) { x; } } while (0) |
52 | #define DEBUG2_9_10(x) do { if (qla2_extended_error_logging) { x; } } while (0) | 52 | #define DEBUG2_9_10(x) do { if (ql2xextended_error_logging) { x; } } while (0) |
53 | #define DEBUG2_11(x) do { if (qla2_extended_error_logging) { x; } } while (0) | 53 | #define DEBUG2_11(x) do { if (ql2xextended_error_logging) { x; } } while (0) |
54 | #define DEBUG2_13(x) do { if (qla2_extended_error_logging) { x; } } while (0) | 54 | #define DEBUG2_13(x) do { if (ql2xextended_error_logging) { x; } } while (0) |
55 | 55 | ||
56 | #if defined(QL_DEBUG_LEVEL_3) | 56 | #if defined(QL_DEBUG_LEVEL_3) |
57 | #define DEBUG3(x) do {x;} while (0) | 57 | #define DEBUG3(x) do {x;} while (0) |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index bab33f6d0bdb..c4fc40f8e8ca 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -1545,6 +1545,9 @@ typedef struct fc_port { | |||
1545 | spinlock_t rport_lock; | 1545 | spinlock_t rport_lock; |
1546 | struct fc_rport *rport, *drport; | 1546 | struct fc_rport *rport, *drport; |
1547 | u32 supported_classes; | 1547 | u32 supported_classes; |
1548 | |||
1549 | unsigned long last_queue_full; | ||
1550 | unsigned long last_ramp_up; | ||
1548 | } fc_port_t; | 1551 | } fc_port_t; |
1549 | 1552 | ||
1550 | /* | 1553 | /* |
@@ -2255,6 +2258,7 @@ typedef struct scsi_qla_host { | |||
2255 | uint16_t mgmt_svr_loop_id; | 2258 | uint16_t mgmt_svr_loop_id; |
2256 | 2259 | ||
2257 | uint32_t login_retry_count; | 2260 | uint32_t login_retry_count; |
2261 | int max_q_depth; | ||
2258 | 2262 | ||
2259 | /* Fibre Channel Device List. */ | 2263 | /* Fibre Channel Device List. */ |
2260 | struct list_head fcports; | 2264 | struct list_head fcports; |
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 7da69832d74c..32ebeec45ff0 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h | |||
@@ -48,6 +48,7 @@ extern void qla2x00_update_fcport(scsi_qla_host_t *, fc_port_t *); | |||
48 | extern void qla2x00_reg_remote_port(scsi_qla_host_t *, fc_port_t *); | 48 | extern void qla2x00_reg_remote_port(scsi_qla_host_t *, fc_port_t *); |
49 | 49 | ||
50 | extern void qla2x00_alloc_fw_dump(scsi_qla_host_t *); | 50 | extern void qla2x00_alloc_fw_dump(scsi_qla_host_t *); |
51 | extern void qla2x00_try_to_stop_firmware(scsi_qla_host_t *); | ||
51 | 52 | ||
52 | /* | 53 | /* |
53 | * Global Data in qla_os.c source file. | 54 | * Global Data in qla_os.c source file. |
@@ -60,7 +61,8 @@ extern int ql2xplogiabsentdevice; | |||
60 | extern int ql2xloginretrycount; | 61 | extern int ql2xloginretrycount; |
61 | extern int ql2xfdmienable; | 62 | extern int ql2xfdmienable; |
62 | extern int ql2xallocfwdump; | 63 | extern int ql2xallocfwdump; |
63 | extern int qla2_extended_error_logging; | 64 | extern int ql2xextended_error_logging; |
65 | extern int ql2xqfullrampup; | ||
64 | 66 | ||
65 | extern void qla2x00_sp_compl(scsi_qla_host_t *, srb_t *); | 67 | extern void qla2x00_sp_compl(scsi_qla_host_t *, srb_t *); |
66 | 68 | ||
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 833b93085fd3..08cb5e3fb553 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -1644,7 +1644,7 @@ qla2x00_nvram_config(scsi_qla_host_t *ha) | |||
1644 | * Set host adapter parameters. | 1644 | * Set host adapter parameters. |
1645 | */ | 1645 | */ |
1646 | if (nv->host_p[0] & BIT_7) | 1646 | if (nv->host_p[0] & BIT_7) |
1647 | qla2_extended_error_logging = 1; | 1647 | ql2xextended_error_logging = 1; |
1648 | ha->flags.disable_risc_code_load = ((nv->host_p[0] & BIT_4) ? 1 : 0); | 1648 | ha->flags.disable_risc_code_load = ((nv->host_p[0] & BIT_4) ? 1 : 0); |
1649 | /* Always load RISC code on non ISP2[12]00 chips. */ | 1649 | /* Always load RISC code on non ISP2[12]00 chips. */ |
1650 | if (!IS_QLA2100(ha) && !IS_QLA2200(ha)) | 1650 | if (!IS_QLA2100(ha) && !IS_QLA2200(ha)) |
@@ -3948,3 +3948,24 @@ qla24xx_load_risc(scsi_qla_host_t *ha, uint32_t *srisc_addr) | |||
3948 | fail_fw_integrity: | 3948 | fail_fw_integrity: |
3949 | return QLA_FUNCTION_FAILED; | 3949 | return QLA_FUNCTION_FAILED; |
3950 | } | 3950 | } |
3951 | |||
3952 | void | ||
3953 | qla2x00_try_to_stop_firmware(scsi_qla_host_t *ha) | ||
3954 | { | ||
3955 | int ret, retries; | ||
3956 | |||
3957 | if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)) | ||
3958 | return; | ||
3959 | |||
3960 | ret = qla2x00_stop_firmware(ha); | ||
3961 | for (retries = 5; ret != QLA_SUCCESS && retries ; retries--) { | ||
3962 | qla2x00_reset_chip(ha); | ||
3963 | if (qla2x00_chip_diag(ha) != QLA_SUCCESS) | ||
3964 | continue; | ||
3965 | if (qla2x00_setup_chip(ha) != QLA_SUCCESS) | ||
3966 | continue; | ||
3967 | qla_printk(KERN_INFO, ha, | ||
3968 | "Attempting retry of stop-firmware command...\n"); | ||
3969 | ret = qla2x00_stop_firmware(ha); | ||
3970 | } | ||
3971 | } | ||
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 626c7178a434..d3b6df4d55c8 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
@@ -6,6 +6,8 @@ | |||
6 | */ | 6 | */ |
7 | #include "qla_def.h" | 7 | #include "qla_def.h" |
8 | 8 | ||
9 | #include <scsi/scsi_tcq.h> | ||
10 | |||
9 | static void qla2x00_mbx_completion(scsi_qla_host_t *, uint16_t); | 11 | static void qla2x00_mbx_completion(scsi_qla_host_t *, uint16_t); |
10 | static void qla2x00_async_event(scsi_qla_host_t *, uint16_t *); | 12 | static void qla2x00_async_event(scsi_qla_host_t *, uint16_t *); |
11 | static void qla2x00_process_completed_request(struct scsi_qla_host *, uint32_t); | 13 | static void qla2x00_process_completed_request(struct scsi_qla_host *, uint32_t); |
@@ -593,6 +595,67 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
593 | } | 595 | } |
594 | } | 596 | } |
595 | 597 | ||
598 | static void | ||
599 | qla2x00_adjust_sdev_qdepth_up(struct scsi_device *sdev, void *data) | ||
600 | { | ||
601 | fc_port_t *fcport = data; | ||
602 | |||
603 | if (fcport->ha->max_q_depth <= sdev->queue_depth) | ||
604 | return; | ||
605 | |||
606 | if (sdev->ordered_tags) | ||
607 | scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, | ||
608 | sdev->queue_depth + 1); | ||
609 | else | ||
610 | scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, | ||
611 | sdev->queue_depth + 1); | ||
612 | |||
613 | fcport->last_ramp_up = jiffies; | ||
614 | |||
615 | DEBUG2(qla_printk(KERN_INFO, fcport->ha, | ||
616 | "scsi(%ld:%d:%d:%d): Queue depth adjusted-up to %d.\n", | ||
617 | fcport->ha->host_no, sdev->channel, sdev->id, sdev->lun, | ||
618 | sdev->queue_depth)); | ||
619 | } | ||
620 | |||
621 | static void | ||
622 | qla2x00_adjust_sdev_qdepth_down(struct scsi_device *sdev, void *data) | ||
623 | { | ||
624 | fc_port_t *fcport = data; | ||
625 | |||
626 | if (!scsi_track_queue_full(sdev, sdev->queue_depth - 1)) | ||
627 | return; | ||
628 | |||
629 | DEBUG2(qla_printk(KERN_INFO, fcport->ha, | ||
630 | "scsi(%ld:%d:%d:%d): Queue depth adjusted-down to %d.\n", | ||
631 | fcport->ha->host_no, sdev->channel, sdev->id, sdev->lun, | ||
632 | sdev->queue_depth)); | ||
633 | } | ||
634 | |||
635 | static inline void | ||
636 | qla2x00_ramp_up_queue_depth(scsi_qla_host_t *ha, srb_t *sp) | ||
637 | { | ||
638 | fc_port_t *fcport; | ||
639 | struct scsi_device *sdev; | ||
640 | |||
641 | sdev = sp->cmd->device; | ||
642 | if (sdev->queue_depth >= ha->max_q_depth) | ||
643 | return; | ||
644 | |||
645 | fcport = sp->fcport; | ||
646 | if (time_before(jiffies, | ||
647 | fcport->last_ramp_up + ql2xqfullrampup * HZ)) | ||
648 | return; | ||
649 | if (time_before(jiffies, | ||
650 | fcport->last_queue_full + ql2xqfullrampup * HZ)) | ||
651 | return; | ||
652 | |||
653 | spin_unlock_irq(&ha->hardware_lock); | ||
654 | starget_for_each_device(sdev->sdev_target, fcport, | ||
655 | qla2x00_adjust_sdev_qdepth_up); | ||
656 | spin_lock_irq(&ha->hardware_lock); | ||
657 | } | ||
658 | |||
596 | /** | 659 | /** |
597 | * qla2x00_process_completed_request() - Process a Fast Post response. | 660 | * qla2x00_process_completed_request() - Process a Fast Post response. |
598 | * @ha: SCSI driver HA context | 661 | * @ha: SCSI driver HA context |
@@ -624,6 +687,8 @@ qla2x00_process_completed_request(struct scsi_qla_host *ha, uint32_t index) | |||
624 | 687 | ||
625 | /* Save ISP completion status */ | 688 | /* Save ISP completion status */ |
626 | sp->cmd->result = DID_OK << 16; | 689 | sp->cmd->result = DID_OK << 16; |
690 | |||
691 | qla2x00_ramp_up_queue_depth(ha, sp); | ||
627 | qla2x00_sp_compl(ha, sp); | 692 | qla2x00_sp_compl(ha, sp); |
628 | } else { | 693 | } else { |
629 | DEBUG2(printk("scsi(%ld): Invalid ISP SCSI completion handle\n", | 694 | DEBUG2(printk("scsi(%ld): Invalid ISP SCSI completion handle\n", |
@@ -823,6 +888,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) | |||
823 | */ | 888 | */ |
824 | switch (comp_status) { | 889 | switch (comp_status) { |
825 | case CS_COMPLETE: | 890 | case CS_COMPLETE: |
891 | case CS_QUEUE_FULL: | ||
826 | if (scsi_status == 0) { | 892 | if (scsi_status == 0) { |
827 | cp->result = DID_OK << 16; | 893 | cp->result = DID_OK << 16; |
828 | break; | 894 | break; |
@@ -849,6 +915,20 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) | |||
849 | } | 915 | } |
850 | cp->result = DID_OK << 16 | lscsi_status; | 916 | cp->result = DID_OK << 16 | lscsi_status; |
851 | 917 | ||
918 | if (lscsi_status == SAM_STAT_TASK_SET_FULL) { | ||
919 | DEBUG2(printk(KERN_INFO | ||
920 | "scsi(%ld): QUEUE FULL status detected " | ||
921 | "0x%x-0x%x.\n", ha->host_no, comp_status, | ||
922 | scsi_status)); | ||
923 | |||
924 | /* Adjust queue depth for all luns on the port. */ | ||
925 | fcport->last_queue_full = jiffies; | ||
926 | spin_unlock_irq(&ha->hardware_lock); | ||
927 | starget_for_each_device(cp->device->sdev_target, | ||
928 | fcport, qla2x00_adjust_sdev_qdepth_down); | ||
929 | spin_lock_irq(&ha->hardware_lock); | ||
930 | break; | ||
931 | } | ||
852 | if (lscsi_status != SS_CHECK_CONDITION) | 932 | if (lscsi_status != SS_CHECK_CONDITION) |
853 | break; | 933 | break; |
854 | 934 | ||
@@ -1066,17 +1146,6 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) | |||
1066 | qla2x00_mark_device_lost(ha, fcport, 1, 1); | 1146 | qla2x00_mark_device_lost(ha, fcport, 1, 1); |
1067 | break; | 1147 | break; |
1068 | 1148 | ||
1069 | case CS_QUEUE_FULL: | ||
1070 | DEBUG2(printk(KERN_INFO | ||
1071 | "scsi(%ld): QUEUE FULL status detected 0x%x-0x%x.\n", | ||
1072 | ha->host_no, comp_status, scsi_status)); | ||
1073 | |||
1074 | /* SCSI Mid-Layer handles device queue full */ | ||
1075 | |||
1076 | cp->result = DID_OK << 16 | lscsi_status; | ||
1077 | |||
1078 | break; | ||
1079 | |||
1080 | default: | 1149 | default: |
1081 | DEBUG3(printk("scsi(%ld): Error detected (unknown status) " | 1150 | DEBUG3(printk("scsi(%ld): Error detected (unknown status) " |
1082 | "0x%x-0x%x.\n", ha->host_no, comp_status, scsi_status)); | 1151 | "0x%x-0x%x.\n", ha->host_no, comp_status, scsi_status)); |
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 5e70c49fdf84..3eb4cd2cbc78 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -61,9 +61,9 @@ MODULE_PARM_DESC(ql2xallocfwdump, | |||
61 | "during HBA initialization. Memory allocation requirements " | 61 | "during HBA initialization. Memory allocation requirements " |
62 | "vary by ISP type. Default is 1 - allocate memory."); | 62 | "vary by ISP type. Default is 1 - allocate memory."); |
63 | 63 | ||
64 | int qla2_extended_error_logging; | 64 | int ql2xextended_error_logging; |
65 | module_param(qla2_extended_error_logging, int, S_IRUGO|S_IRUSR); | 65 | module_param(ql2xextended_error_logging, int, S_IRUGO|S_IRUSR); |
66 | MODULE_PARM_DESC(qla2_extended_error_logging, | 66 | MODULE_PARM_DESC(ql2xextended_error_logging, |
67 | "Option to enable extended error logging, " | 67 | "Option to enable extended error logging, " |
68 | "Default is 0 - no logging. 1 - log errors."); | 68 | "Default is 0 - no logging. 1 - log errors."); |
69 | 69 | ||
@@ -77,6 +77,19 @@ MODULE_PARM_DESC(ql2xfdmienable, | |||
77 | "Enables FDMI registratons " | 77 | "Enables FDMI registratons " |
78 | "Default is 0 - no FDMI. 1 - perfom FDMI."); | 78 | "Default is 0 - no FDMI. 1 - perfom FDMI."); |
79 | 79 | ||
80 | #define MAX_Q_DEPTH 32 | ||
81 | static int ql2xmaxqdepth = MAX_Q_DEPTH; | ||
82 | module_param(ql2xmaxqdepth, int, S_IRUGO|S_IWUSR); | ||
83 | MODULE_PARM_DESC(ql2xmaxqdepth, | ||
84 | "Maximum queue depth to report for target devices."); | ||
85 | |||
86 | int ql2xqfullrampup = 120; | ||
87 | module_param(ql2xqfullrampup, int, S_IRUGO|S_IWUSR); | ||
88 | MODULE_PARM_DESC(ql2xqfullrampup, | ||
89 | "Number of seconds to wait to begin to ramp-up the queue " | ||
90 | "depth for a device after a queue-full condition has been " | ||
91 | "detected. Default is 120 seconds."); | ||
92 | |||
80 | /* | 93 | /* |
81 | * SCSI host template entry points | 94 | * SCSI host template entry points |
82 | */ | 95 | */ |
@@ -1104,9 +1117,9 @@ qla2xxx_slave_configure(struct scsi_device *sdev) | |||
1104 | struct fc_rport *rport = starget_to_rport(sdev->sdev_target); | 1117 | struct fc_rport *rport = starget_to_rport(sdev->sdev_target); |
1105 | 1118 | ||
1106 | if (sdev->tagged_supported) | 1119 | if (sdev->tagged_supported) |
1107 | scsi_activate_tcq(sdev, 32); | 1120 | scsi_activate_tcq(sdev, ha->max_q_depth); |
1108 | else | 1121 | else |
1109 | scsi_deactivate_tcq(sdev, 32); | 1122 | scsi_deactivate_tcq(sdev, ha->max_q_depth); |
1110 | 1123 | ||
1111 | rport->dev_loss_tmo = ha->port_down_retry_count + 5; | 1124 | rport->dev_loss_tmo = ha->port_down_retry_count + 5; |
1112 | 1125 | ||
@@ -1413,6 +1426,10 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1413 | ha->link_data_rate = PORT_SPEED_UNKNOWN; | 1426 | ha->link_data_rate = PORT_SPEED_UNKNOWN; |
1414 | ha->optrom_size = OPTROM_SIZE_2300; | 1427 | ha->optrom_size = OPTROM_SIZE_2300; |
1415 | 1428 | ||
1429 | ha->max_q_depth = MAX_Q_DEPTH; | ||
1430 | if (ql2xmaxqdepth != 0 && ql2xmaxqdepth <= 0xffffU) | ||
1431 | ha->max_q_depth = ql2xmaxqdepth; | ||
1432 | |||
1416 | /* Assign ISP specific operations. */ | 1433 | /* Assign ISP specific operations. */ |
1417 | ha->isp_ops.pci_config = qla2100_pci_config; | 1434 | ha->isp_ops.pci_config = qla2100_pci_config; |
1418 | ha->isp_ops.reset_chip = qla2x00_reset_chip; | 1435 | ha->isp_ops.reset_chip = qla2x00_reset_chip; |
@@ -1712,8 +1729,10 @@ qla2x00_free_device(scsi_qla_host_t *ha) | |||
1712 | if (ha->eft) | 1729 | if (ha->eft) |
1713 | qla2x00_trace_control(ha, TC_DISABLE, 0, 0); | 1730 | qla2x00_trace_control(ha, TC_DISABLE, 0, 0); |
1714 | 1731 | ||
1732 | ha->flags.online = 0; | ||
1733 | |||
1715 | /* Stop currently executing firmware. */ | 1734 | /* Stop currently executing firmware. */ |
1716 | qla2x00_stop_firmware(ha); | 1735 | qla2x00_try_to_stop_firmware(ha); |
1717 | 1736 | ||
1718 | /* turn-off interrupts on the card */ | 1737 | /* turn-off interrupts on the card */ |
1719 | if (ha->interrupts_on) | 1738 | if (ha->interrupts_on) |
@@ -1721,8 +1740,6 @@ qla2x00_free_device(scsi_qla_host_t *ha) | |||
1721 | 1740 | ||
1722 | qla2x00_mem_free(ha); | 1741 | qla2x00_mem_free(ha); |
1723 | 1742 | ||
1724 | ha->flags.online = 0; | ||
1725 | |||
1726 | /* Detach interrupts */ | 1743 | /* Detach interrupts */ |
1727 | if (ha->host->irq) | 1744 | if (ha->host->irq) |
1728 | free_irq(ha->host->irq, ha); | 1745 | free_irq(ha->host->irq, ha); |
@@ -2697,7 +2714,7 @@ qla2x00_module_init(void) | |||
2697 | 2714 | ||
2698 | /* Derive version string. */ | 2715 | /* Derive version string. */ |
2699 | strcpy(qla2x00_version_str, QLA2XXX_VERSION); | 2716 | strcpy(qla2x00_version_str, QLA2XXX_VERSION); |
2700 | if (qla2_extended_error_logging) | 2717 | if (ql2xextended_error_logging) |
2701 | strcat(qla2x00_version_str, "-debug"); | 2718 | strcat(qla2x00_version_str, "-debug"); |
2702 | 2719 | ||
2703 | qla2xxx_transport_template = | 2720 | qla2xxx_transport_template = |
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index e57bf45a3393..1fa0bce6b24e 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.01.07-k2" | 10 | #define QLA2XXX_VERSION "8.01.07-k3" |
11 | 11 | ||
12 | #define QLA_DRIVER_MAJOR_VER 8 | 12 | #define QLA_DRIVER_MAJOR_VER 8 |
13 | #define QLA_DRIVER_MINOR_VER 1 | 13 | #define QLA_DRIVER_MINOR_VER 1 |
diff --git a/drivers/scsi/qla4xxx/Kconfig b/drivers/scsi/qla4xxx/Kconfig index 08a07f0b8d94..69cbff3f57cf 100644 --- a/drivers/scsi/qla4xxx/Kconfig +++ b/drivers/scsi/qla4xxx/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config SCSI_QLA_ISCSI | 1 | config SCSI_QLA_ISCSI |
2 | tristate "QLogic ISP4XXX host adapter family support" | 2 | tristate "QLogic ISP4XXX host adapter family support" |
3 | depends on PCI && SCSI | 3 | depends on PCI && SCSI && NET |
4 | select SCSI_ISCSI_ATTRS | 4 | select SCSI_ISCSI_ATTRS |
5 | ---help--- | 5 | ---help--- |
6 | This driver supports the QLogic 40xx (ISP4XXX) iSCSI host | 6 | This driver supports the QLogic 40xx (ISP4XXX) iSCSI host |
diff --git a/drivers/scsi/qla4xxx/ql4_dbg.h b/drivers/scsi/qla4xxx/ql4_dbg.h index 3e99dcfd5a9f..d861c3b411c8 100644 --- a/drivers/scsi/qla4xxx/ql4_dbg.h +++ b/drivers/scsi/qla4xxx/ql4_dbg.h | |||
@@ -22,14 +22,14 @@ | |||
22 | #endif | 22 | #endif |
23 | 23 | ||
24 | #if defined(QL_DEBUG_LEVEL_2) | 24 | #if defined(QL_DEBUG_LEVEL_2) |
25 | #define DEBUG2(x) do {if(qla4_extended_error_logging == 2) x;} while (0); | 25 | #define DEBUG2(x) do {if(ql4xextended_error_logging == 2) x;} while (0); |
26 | #define DEBUG2_3(x) do {x;} while (0); | 26 | #define DEBUG2_3(x) do {x;} while (0); |
27 | #else /* */ | 27 | #else /* */ |
28 | #define DEBUG2(x) do {} while (0); | 28 | #define DEBUG2(x) do {} while (0); |
29 | #endif /* */ | 29 | #endif /* */ |
30 | 30 | ||
31 | #if defined(QL_DEBUG_LEVEL_3) | 31 | #if defined(QL_DEBUG_LEVEL_3) |
32 | #define DEBUG3(x) do {if(qla4_extended_error_logging == 3) x;} while (0); | 32 | #define DEBUG3(x) do {if(ql4xextended_error_logging == 3) x;} while (0); |
33 | #else /* */ | 33 | #else /* */ |
34 | #define DEBUG3(x) do {} while (0); | 34 | #define DEBUG3(x) do {} while (0); |
35 | #if !defined(QL_DEBUG_LEVEL_2) | 35 | #if !defined(QL_DEBUG_LEVEL_2) |
diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h b/drivers/scsi/qla4xxx/ql4_glbl.h index 2c803edf2de8..eeefdcb1edb5 100644 --- a/drivers/scsi/qla4xxx/ql4_glbl.h +++ b/drivers/scsi/qla4xxx/ql4_glbl.h | |||
@@ -8,6 +8,7 @@ | |||
8 | #ifndef __QLA4x_GBL_H | 8 | #ifndef __QLA4x_GBL_H |
9 | #define __QLA4x_GBL_H | 9 | #define __QLA4x_GBL_H |
10 | 10 | ||
11 | int ql4xxx_lock_drvr_wait(struct scsi_qla_host *a); | ||
11 | int qla4xxx_send_tgts(struct scsi_qla_host *ha, char *ip, uint16_t port); | 12 | int qla4xxx_send_tgts(struct scsi_qla_host *ha, char *ip, uint16_t port); |
12 | int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb * srb); | 13 | int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb * srb); |
13 | int qla4xxx_initialize_adapter(struct scsi_qla_host * ha, | 14 | int qla4xxx_initialize_adapter(struct scsi_qla_host * ha, |
@@ -72,7 +73,7 @@ int qla4xxx_reinitialize_ddb_list(struct scsi_qla_host * ha); | |||
72 | int qla4xxx_process_ddb_changed(struct scsi_qla_host * ha, | 73 | int qla4xxx_process_ddb_changed(struct scsi_qla_host * ha, |
73 | uint32_t fw_ddb_index, uint32_t state); | 74 | uint32_t fw_ddb_index, uint32_t state); |
74 | 75 | ||
75 | extern int qla4_extended_error_logging; | 76 | extern int ql4xextended_error_logging; |
76 | extern int ql4xdiscoverywait; | 77 | extern int ql4xdiscoverywait; |
77 | extern int ql4xdontresethba; | 78 | extern int ql4xdontresethba; |
78 | #endif /* _QLA4x_GBL_H */ | 79 | #endif /* _QLA4x_GBL_H */ |
diff --git a/drivers/scsi/qla4xxx/ql4_init.c b/drivers/scsi/qla4xxx/ql4_init.c index bb3a1c11f44c..9e81b810dc88 100644 --- a/drivers/scsi/qla4xxx/ql4_init.c +++ b/drivers/scsi/qla4xxx/ql4_init.c | |||
@@ -978,7 +978,7 @@ static int qla4xxx_start_firmware_from_flash(struct scsi_qla_host *ha) | |||
978 | return status; | 978 | return status; |
979 | } | 979 | } |
980 | 980 | ||
981 | static int ql4xxx_lock_drvr_wait(struct scsi_qla_host *a) | 981 | int ql4xxx_lock_drvr_wait(struct scsi_qla_host *a) |
982 | { | 982 | { |
983 | #define QL4_LOCK_DRVR_WAIT 300 | 983 | #define QL4_LOCK_DRVR_WAIT 300 |
984 | #define QL4_LOCK_DRVR_SLEEP 100 | 984 | #define QL4_LOCK_DRVR_SLEEP 100 |
diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c index ef82399c0858..b721dc5dd711 100644 --- a/drivers/scsi/qla4xxx/ql4_mbx.c +++ b/drivers/scsi/qla4xxx/ql4_mbx.c | |||
@@ -701,7 +701,7 @@ void qla4xxx_get_conn_event_log(struct scsi_qla_host * ha) | |||
701 | DEBUG3(printk("scsi%ld: Connection Event Log Dump (%d entries):\n", | 701 | DEBUG3(printk("scsi%ld: Connection Event Log Dump (%d entries):\n", |
702 | ha->host_no, num_valid_entries)); | 702 | ha->host_no, num_valid_entries)); |
703 | 703 | ||
704 | if (qla4_extended_error_logging == 3) { | 704 | if (ql4xextended_error_logging == 3) { |
705 | if (oldest_entry == 0) { | 705 | if (oldest_entry == 0) { |
706 | /* Circular Buffer has not wrapped around */ | 706 | /* Circular Buffer has not wrapped around */ |
707 | for (i=0; i < num_valid_entries; i++) { | 707 | for (i=0; i < num_valid_entries; i++) { |
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index 178fcddcfd81..bab434ee774b 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c | |||
@@ -34,9 +34,9 @@ MODULE_PARM_DESC(ql4xdontresethba, | |||
34 | " default it will reset hba :0" | 34 | " default it will reset hba :0" |
35 | " set to 1 to avoid resetting HBA"); | 35 | " set to 1 to avoid resetting HBA"); |
36 | 36 | ||
37 | int qla4_extended_error_logging = 0; /* 0 = off, 1 = log errors */ | 37 | int ql4xextended_error_logging = 0; /* 0 = off, 1 = log errors */ |
38 | module_param(qla4_extended_error_logging, int, S_IRUGO | S_IRUSR); | 38 | module_param(ql4xextended_error_logging, int, S_IRUGO | S_IRUSR); |
39 | MODULE_PARM_DESC(qla4_extended_error_logging, | 39 | MODULE_PARM_DESC(ql4xextended_error_logging, |
40 | "Option to enable extended error logging, " | 40 | "Option to enable extended error logging, " |
41 | "Default is 0 - no logging, 1 - debug logging"); | 41 | "Default is 0 - no logging, 1 - debug logging"); |
42 | 42 | ||
@@ -919,18 +919,11 @@ static int qla4xxx_recover_adapter(struct scsi_qla_host *ha, | |||
919 | if (status == QLA_SUCCESS) { | 919 | if (status == QLA_SUCCESS) { |
920 | DEBUG2(printk("scsi%ld: %s - Performing soft reset..\n", | 920 | DEBUG2(printk("scsi%ld: %s - Performing soft reset..\n", |
921 | ha->host_no, __func__)); | 921 | ha->host_no, __func__)); |
922 | status = qla4xxx_soft_reset(ha); | 922 | qla4xxx_flush_active_srbs(ha); |
923 | } | 923 | if (ql4xxx_lock_drvr_wait(ha) == QLA_SUCCESS) |
924 | /* FIXMEkaren: Do we want to keep interrupts enabled and process | 924 | status = qla4xxx_soft_reset(ha); |
925 | AENs after soft reset */ | 925 | else |
926 | 926 | status = QLA_ERROR; | |
927 | /* If firmware (SOFT) reset failed, or if all outstanding | ||
928 | * commands have not returned, then do a HARD reset. | ||
929 | */ | ||
930 | if (status == QLA_ERROR) { | ||
931 | DEBUG2(printk("scsi%ld: %s - Performing hard reset..\n", | ||
932 | ha->host_no, __func__)); | ||
933 | status = qla4xxx_hard_reset(ha); | ||
934 | } | 927 | } |
935 | 928 | ||
936 | /* Flush any pending ddb changed AENs */ | 929 | /* Flush any pending ddb changed AENs */ |
@@ -1016,13 +1009,9 @@ static void qla4xxx_do_dpc(void *data) | |||
1016 | struct scsi_qla_host *ha = (struct scsi_qla_host *) data; | 1009 | struct scsi_qla_host *ha = (struct scsi_qla_host *) data; |
1017 | struct ddb_entry *ddb_entry, *dtemp; | 1010 | struct ddb_entry *ddb_entry, *dtemp; |
1018 | 1011 | ||
1019 | DEBUG2(printk("scsi%ld: %s: DPC handler waking up.\n", | 1012 | DEBUG2(printk("scsi%ld: %s: DPC handler waking up." |
1020 | ha->host_no, __func__)); | 1013 | "flags = 0x%08lx, dpc_flags = 0x%08lx\n", |
1021 | 1014 | ha->host_no, __func__, ha->flags, ha->dpc_flags)); | |
1022 | DEBUG2(printk("scsi%ld: %s: ha->flags = 0x%08lx\n", | ||
1023 | ha->host_no, __func__, ha->flags)); | ||
1024 | DEBUG2(printk("scsi%ld: %s: ha->dpc_flags = 0x%08lx\n", | ||
1025 | ha->host_no, __func__, ha->dpc_flags)); | ||
1026 | 1015 | ||
1027 | /* Initialization not yet finished. Don't do anything yet. */ | 1016 | /* Initialization not yet finished. Don't do anything yet. */ |
1028 | if (!test_bit(AF_INIT_DONE, &ha->flags)) | 1017 | if (!test_bit(AF_INIT_DONE, &ha->flags)) |
@@ -1032,16 +1021,8 @@ static void qla4xxx_do_dpc(void *data) | |||
1032 | test_bit(DPC_RESET_HA, &ha->dpc_flags) || | 1021 | test_bit(DPC_RESET_HA, &ha->dpc_flags) || |
1033 | test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags) || | 1022 | test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags) || |
1034 | test_bit(DPC_RESET_HA_DESTROY_DDB_LIST, &ha->dpc_flags)) { | 1023 | test_bit(DPC_RESET_HA_DESTROY_DDB_LIST, &ha->dpc_flags)) { |
1035 | if (test_bit(DPC_RESET_HA_DESTROY_DDB_LIST, &ha->dpc_flags)) | 1024 | if (test_bit(DPC_RESET_HA_DESTROY_DDB_LIST, &ha->dpc_flags) || |
1036 | /* | 1025 | test_bit(DPC_RESET_HA, &ha->dpc_flags)) |
1037 | * dg 09/23 Never initialize ddb list | ||
1038 | * once we up and running | ||
1039 | * qla4xxx_recover_adapter(ha, | ||
1040 | * REBUILD_DDB_LIST); | ||
1041 | */ | ||
1042 | qla4xxx_recover_adapter(ha, PRESERVE_DDB_LIST); | ||
1043 | |||
1044 | if (test_bit(DPC_RESET_HA, &ha->dpc_flags)) | ||
1045 | qla4xxx_recover_adapter(ha, PRESERVE_DDB_LIST); | 1026 | qla4xxx_recover_adapter(ha, PRESERVE_DDB_LIST); |
1046 | 1027 | ||
1047 | if (test_and_clear_bit(DPC_RESET_HA_INTR, &ha->dpc_flags)) { | 1028 | if (test_and_clear_bit(DPC_RESET_HA_INTR, &ha->dpc_flags)) { |
@@ -1122,7 +1103,8 @@ static void qla4xxx_free_adapter(struct scsi_qla_host *ha) | |||
1122 | destroy_workqueue(ha->dpc_thread); | 1103 | destroy_workqueue(ha->dpc_thread); |
1123 | 1104 | ||
1124 | /* Issue Soft Reset to put firmware in unknown state */ | 1105 | /* Issue Soft Reset to put firmware in unknown state */ |
1125 | qla4xxx_soft_reset(ha); | 1106 | if (ql4xxx_lock_drvr_wait(ha) == QLA_SUCCESS) |
1107 | qla4xxx_soft_reset(ha); | ||
1126 | 1108 | ||
1127 | /* Remove timer thread, if present */ | 1109 | /* Remove timer thread, if present */ |
1128 | if (ha->timer_active) | 1110 | if (ha->timer_active) |
@@ -1714,7 +1696,7 @@ static int __init qla4xxx_module_init(void) | |||
1714 | 1696 | ||
1715 | /* Derive version string. */ | 1697 | /* Derive version string. */ |
1716 | strcpy(qla4xxx_version_str, QLA4XXX_DRIVER_VERSION); | 1698 | strcpy(qla4xxx_version_str, QLA4XXX_DRIVER_VERSION); |
1717 | if (qla4_extended_error_logging) | 1699 | if (ql4xextended_error_logging) |
1718 | strcat(qla4xxx_version_str, "-debug"); | 1700 | strcat(qla4xxx_version_str, "-debug"); |
1719 | 1701 | ||
1720 | qla4xxx_scsi_transport = | 1702 | qla4xxx_scsi_transport = |
@@ -1724,13 +1706,13 @@ static int __init qla4xxx_module_init(void) | |||
1724 | goto release_srb_cache; | 1706 | goto release_srb_cache; |
1725 | } | 1707 | } |
1726 | 1708 | ||
1727 | printk(KERN_INFO "QLogic iSCSI HBA Driver\n"); | ||
1728 | ret = pci_register_driver(&qla4xxx_pci_driver); | 1709 | ret = pci_register_driver(&qla4xxx_pci_driver); |
1729 | if (ret) | 1710 | if (ret) |
1730 | goto unregister_transport; | 1711 | goto unregister_transport; |
1731 | 1712 | ||
1732 | printk(KERN_INFO "QLogic iSCSI HBA Driver\n"); | 1713 | printk(KERN_INFO "QLogic iSCSI HBA Driver\n"); |
1733 | return 0; | 1714 | return 0; |
1715 | |||
1734 | unregister_transport: | 1716 | unregister_transport: |
1735 | iscsi_unregister_transport(&qla4xxx_iscsi_transport); | 1717 | iscsi_unregister_transport(&qla4xxx_iscsi_transport); |
1736 | release_srb_cache: | 1718 | release_srb_cache: |
diff --git a/drivers/scsi/qla4xxx/ql4_version.h b/drivers/scsi/qla4xxx/ql4_version.h index b3fe7e68988e..d05048b4e88a 100644 --- a/drivers/scsi/qla4xxx/ql4_version.h +++ b/drivers/scsi/qla4xxx/ql4_version.h | |||
@@ -5,9 +5,4 @@ | |||
5 | * See LICENSE.qla4xxx for copyright and licensing details. | 5 | * See LICENSE.qla4xxx for copyright and licensing details. |
6 | */ | 6 | */ |
7 | 7 | ||
8 | #define QLA4XXX_DRIVER_VERSION "5.00.05b9-k" | 8 | #define QLA4XXX_DRIVER_VERSION "5.00.06-k" |
9 | |||
10 | #define QL4_DRIVER_MAJOR_VER 5 | ||
11 | #define QL4_DRIVER_MINOR_VER 0 | ||
12 | #define QL4_DRIVER_PATCH_VER 5 | ||
13 | #define QL4_DRIVER_BETA_VER 9 | ||
diff --git a/drivers/scsi/qlogicfas408.c b/drivers/scsi/qlogicfas408.c index e0725353c99c..2e7db18f5aef 100644 --- a/drivers/scsi/qlogicfas408.c +++ b/drivers/scsi/qlogicfas408.c | |||
@@ -209,7 +209,7 @@ static int ql_wai(struct qlogicfas408_priv *priv) | |||
209 | * caller must hold host lock | 209 | * caller must hold host lock |
210 | */ | 210 | */ |
211 | 211 | ||
212 | static void ql_icmd(Scsi_Cmnd * cmd) | 212 | static void ql_icmd(struct scsi_cmnd *cmd) |
213 | { | 213 | { |
214 | struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd); | 214 | struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd); |
215 | int qbase = priv->qbase; | 215 | int qbase = priv->qbase; |
@@ -256,7 +256,7 @@ static void ql_icmd(Scsi_Cmnd * cmd) | |||
256 | * Process scsi command - usually after interrupt | 256 | * Process scsi command - usually after interrupt |
257 | */ | 257 | */ |
258 | 258 | ||
259 | static unsigned int ql_pcmd(Scsi_Cmnd * cmd) | 259 | static unsigned int ql_pcmd(struct scsi_cmnd *cmd) |
260 | { | 260 | { |
261 | unsigned int i, j; | 261 | unsigned int i, j; |
262 | unsigned long k; | 262 | unsigned long k; |
@@ -407,7 +407,7 @@ static unsigned int ql_pcmd(Scsi_Cmnd * cmd) | |||
407 | 407 | ||
408 | static void ql_ihandl(void *dev_id) | 408 | static void ql_ihandl(void *dev_id) |
409 | { | 409 | { |
410 | Scsi_Cmnd *icmd; | 410 | struct scsi_cmnd *icmd; |
411 | struct Scsi_Host *host = dev_id; | 411 | struct Scsi_Host *host = dev_id; |
412 | struct qlogicfas408_priv *priv = get_priv_by_host(host); | 412 | struct qlogicfas408_priv *priv = get_priv_by_host(host); |
413 | int qbase = priv->qbase; | 413 | int qbase = priv->qbase; |
@@ -447,7 +447,8 @@ irqreturn_t qlogicfas408_ihandl(int irq, void *dev_id) | |||
447 | * Queued command | 447 | * Queued command |
448 | */ | 448 | */ |
449 | 449 | ||
450 | int qlogicfas408_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)) | 450 | int qlogicfas408_queuecommand(struct scsi_cmnd *cmd, |
451 | void (*done) (struct scsi_cmnd *)) | ||
451 | { | 452 | { |
452 | struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd); | 453 | struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd); |
453 | if (scmd_id(cmd) == priv->qinitid) { | 454 | if (scmd_id(cmd) == priv->qinitid) { |
@@ -470,9 +471,8 @@ int qlogicfas408_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)) | |||
470 | * Return bios parameters | 471 | * Return bios parameters |
471 | */ | 472 | */ |
472 | 473 | ||
473 | int qlogicfas408_biosparam(struct scsi_device * disk, | 474 | int qlogicfas408_biosparam(struct scsi_device *disk, struct block_device *dev, |
474 | struct block_device *dev, | 475 | sector_t capacity, int ip[]) |
475 | sector_t capacity, int ip[]) | ||
476 | { | 476 | { |
477 | /* This should mimic the DOS Qlogic driver's behavior exactly */ | 477 | /* This should mimic the DOS Qlogic driver's behavior exactly */ |
478 | ip[0] = 0x40; | 478 | ip[0] = 0x40; |
@@ -494,7 +494,7 @@ int qlogicfas408_biosparam(struct scsi_device * disk, | |||
494 | * Abort a command in progress | 494 | * Abort a command in progress |
495 | */ | 495 | */ |
496 | 496 | ||
497 | int qlogicfas408_abort(Scsi_Cmnd * cmd) | 497 | int qlogicfas408_abort(struct scsi_cmnd *cmd) |
498 | { | 498 | { |
499 | struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd); | 499 | struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd); |
500 | priv->qabort = 1; | 500 | priv->qabort = 1; |
@@ -508,7 +508,7 @@ int qlogicfas408_abort(Scsi_Cmnd * cmd) | |||
508 | * the PCMCIA qlogic_stub code. This wants fixing | 508 | * the PCMCIA qlogic_stub code. This wants fixing |
509 | */ | 509 | */ |
510 | 510 | ||
511 | int qlogicfas408_bus_reset(Scsi_Cmnd * cmd) | 511 | int qlogicfas408_bus_reset(struct scsi_cmnd *cmd) |
512 | { | 512 | { |
513 | struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd); | 513 | struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd); |
514 | unsigned long flags; | 514 | unsigned long flags; |
diff --git a/drivers/scsi/qlogicfas408.h b/drivers/scsi/qlogicfas408.h index 8fd5555c75b1..260626427a32 100644 --- a/drivers/scsi/qlogicfas408.h +++ b/drivers/scsi/qlogicfas408.h | |||
@@ -75,15 +75,15 @@ | |||
75 | /*----------------------------------------------------------------*/ | 75 | /*----------------------------------------------------------------*/ |
76 | 76 | ||
77 | struct qlogicfas408_priv { | 77 | struct qlogicfas408_priv { |
78 | int qbase; /* Port */ | 78 | int qbase; /* Port */ |
79 | int qinitid; /* initiator ID */ | 79 | int qinitid; /* initiator ID */ |
80 | int qabort; /* Flag to cause an abort */ | 80 | int qabort; /* Flag to cause an abort */ |
81 | int qlirq; /* IRQ being used */ | 81 | int qlirq; /* IRQ being used */ |
82 | int int_type; /* type of irq, 2 for ISA board, 0 for PCMCIA */ | 82 | int int_type; /* type of irq, 2 for ISA board, 0 for PCMCIA */ |
83 | char qinfo[80]; /* description */ | 83 | char qinfo[80]; /* description */ |
84 | Scsi_Cmnd *qlcmd; /* current command being processed */ | 84 | struct scsi_cmnd *qlcmd; /* current command being processed */ |
85 | struct Scsi_Host *shost; /* pointer back to host */ | 85 | struct Scsi_Host *shost; /* pointer back to host */ |
86 | struct qlogicfas408_priv *next; /* next private struct */ | 86 | struct qlogicfas408_priv *next; /* next private struct */ |
87 | }; | 87 | }; |
88 | 88 | ||
89 | /* The qlogic card uses two register maps - These macros select which one */ | 89 | /* The qlogic card uses two register maps - These macros select which one */ |
@@ -103,12 +103,13 @@ struct qlogicfas408_priv { | |||
103 | #define get_priv_by_host(x) (struct qlogicfas408_priv *)&((x)->hostdata[0]) | 103 | #define get_priv_by_host(x) (struct qlogicfas408_priv *)&((x)->hostdata[0]) |
104 | 104 | ||
105 | irqreturn_t qlogicfas408_ihandl(int irq, void *dev_id); | 105 | irqreturn_t qlogicfas408_ihandl(int irq, void *dev_id); |
106 | int qlogicfas408_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)); | 106 | int qlogicfas408_queuecommand(struct scsi_cmnd * cmd, |
107 | void (*done) (struct scsi_cmnd *)); | ||
107 | int qlogicfas408_biosparam(struct scsi_device * disk, | 108 | int qlogicfas408_biosparam(struct scsi_device * disk, |
108 | struct block_device *dev, | 109 | struct block_device *dev, |
109 | sector_t capacity, int ip[]); | 110 | sector_t capacity, int ip[]); |
110 | int qlogicfas408_abort(Scsi_Cmnd * cmd); | 111 | int qlogicfas408_abort(struct scsi_cmnd * cmd); |
111 | int qlogicfas408_bus_reset(Scsi_Cmnd * cmd); | 112 | int qlogicfas408_bus_reset(struct scsi_cmnd * cmd); |
112 | const char *qlogicfas408_info(struct Scsi_Host *host); | 113 | const char *qlogicfas408_info(struct Scsi_Host *host); |
113 | int qlogicfas408_get_chip_type(int qbase, int int_type); | 114 | int qlogicfas408_get_chip_type(int qbase, int int_type); |
114 | void qlogicfas408_setup(int qbase, int id, int int_type); | 115 | void qlogicfas408_setup(int qbase, int id, int int_type); |
diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c index ed58bb489889..9b827ceec501 100644 --- a/drivers/scsi/qlogicpti.c +++ b/drivers/scsi/qlogicpti.c | |||
@@ -461,7 +461,7 @@ static int qlogicpti_reset_hardware(struct Scsi_Host *host) | |||
461 | 461 | ||
462 | #define PTI_RESET_LIMIT 400 | 462 | #define PTI_RESET_LIMIT 400 |
463 | 463 | ||
464 | static int __init qlogicpti_load_firmware(struct qlogicpti *qpti) | 464 | static int __devinit qlogicpti_load_firmware(struct qlogicpti *qpti) |
465 | { | 465 | { |
466 | struct Scsi_Host *host = qpti->qhost; | 466 | struct Scsi_Host *host = qpti->qhost; |
467 | unsigned short csum = 0; | 467 | unsigned short csum = 0; |
diff --git a/drivers/scsi/qlogicpti_asm.c b/drivers/scsi/qlogicpti_asm.c index 1545b30681b4..19aa84f46018 100644 --- a/drivers/scsi/qlogicpti_asm.c +++ b/drivers/scsi/qlogicpti_asm.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* Version 1.31.00 ISP1000 Initiator RISC firmware */ | 1 | /* Version 1.31.00 ISP1000 Initiator RISC firmware */ |
2 | unsigned short sbus_risc_code01[] __initdata = { | 2 | unsigned short sbus_risc_code01[] __devinitdata = { |
3 | 0x0078, 0x1030, 0x0000, 0x2419, 0x0000, 0x12ff, 0x2043, 0x4f50, | 3 | 0x0078, 0x1030, 0x0000, 0x2419, 0x0000, 0x12ff, 0x2043, 0x4f50, |
4 | 0x5952, 0x4947, 0x4854, 0x2031, 0x3939, 0x312c, 0x3139, 0x3932, | 4 | 0x5952, 0x4947, 0x4854, 0x2031, 0x3939, 0x312c, 0x3139, 0x3932, |
5 | 0x2c31, 0x3939, 0x332c, 0x3139, 0x3934, 0x2051, 0x4c4f, 0x4749, | 5 | 0x2c31, 0x3939, 0x332c, 0x3139, 0x3934, 0x2051, 0x4c4f, 0x4749, |
@@ -1157,4 +1157,4 @@ unsigned short sbus_risc_code01[] __initdata = { | |||
1157 | 0x003c, 0x0040, 0x3415, 0x2019, 0x2626, 0x7b22, 0x7b26, 0x007c, | 1157 | 0x003c, 0x0040, 0x3415, 0x2019, 0x2626, 0x7b22, 0x7b26, 0x007c, |
1158 | 0x92a7 | 1158 | 0x92a7 |
1159 | }; | 1159 | }; |
1160 | unsigned short sbus_risc_code_length01 = 0x2419; | 1160 | unsigned short __devinitdata sbus_risc_code_length01 = 0x2419; |
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 9c0f35820e3e..30ee3d72c021 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c | |||
@@ -52,7 +52,7 @@ | |||
52 | #include "scsi_debug.h" | 52 | #include "scsi_debug.h" |
53 | 53 | ||
54 | #define SCSI_DEBUG_VERSION "1.80" | 54 | #define SCSI_DEBUG_VERSION "1.80" |
55 | static const char * scsi_debug_version_date = "20060914"; | 55 | static const char * scsi_debug_version_date = "20061018"; |
56 | 56 | ||
57 | /* Additional Sense Code (ASC) used */ | 57 | /* Additional Sense Code (ASC) used */ |
58 | #define NO_ADDITIONAL_SENSE 0x0 | 58 | #define NO_ADDITIONAL_SENSE 0x0 |
@@ -254,6 +254,8 @@ static int resp_requests(struct scsi_cmnd * SCpnt, | |||
254 | struct sdebug_dev_info * devip); | 254 | struct sdebug_dev_info * devip); |
255 | static int resp_start_stop(struct scsi_cmnd * scp, | 255 | static int resp_start_stop(struct scsi_cmnd * scp, |
256 | struct sdebug_dev_info * devip); | 256 | struct sdebug_dev_info * devip); |
257 | static int resp_report_tgtpgs(struct scsi_cmnd * scp, | ||
258 | struct sdebug_dev_info * devip); | ||
257 | static int resp_readcap(struct scsi_cmnd * SCpnt, | 259 | static int resp_readcap(struct scsi_cmnd * SCpnt, |
258 | struct sdebug_dev_info * devip); | 260 | struct sdebug_dev_info * devip); |
259 | static int resp_readcap16(struct scsi_cmnd * SCpnt, | 261 | static int resp_readcap16(struct scsi_cmnd * SCpnt, |
@@ -287,9 +289,9 @@ static void __init sdebug_build_parts(unsigned char * ramp); | |||
287 | static void __init init_all_queued(void); | 289 | static void __init init_all_queued(void); |
288 | static void stop_all_queued(void); | 290 | static void stop_all_queued(void); |
289 | static int stop_queued_cmnd(struct scsi_cmnd * cmnd); | 291 | static int stop_queued_cmnd(struct scsi_cmnd * cmnd); |
290 | static int inquiry_evpd_83(unsigned char * arr, int target_dev_id, | 292 | static int inquiry_evpd_83(unsigned char * arr, int port_group_id, |
291 | int dev_id_num, const char * dev_id_str, | 293 | int target_dev_id, int dev_id_num, |
292 | int dev_id_str_len); | 294 | const char * dev_id_str, int dev_id_str_len); |
293 | static int inquiry_evpd_88(unsigned char * arr, int target_dev_id); | 295 | static int inquiry_evpd_88(unsigned char * arr, int target_dev_id); |
294 | static int do_create_driverfs_files(void); | 296 | static int do_create_driverfs_files(void); |
295 | static void do_remove_driverfs_files(void); | 297 | static void do_remove_driverfs_files(void); |
@@ -422,6 +424,15 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done) | |||
422 | } | 424 | } |
423 | errsts = resp_readcap16(SCpnt, devip); | 425 | errsts = resp_readcap16(SCpnt, devip); |
424 | break; | 426 | break; |
427 | case MAINTENANCE_IN: | ||
428 | if (MI_REPORT_TARGET_PGS != cmd[1]) { | ||
429 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
430 | INVALID_OPCODE, 0); | ||
431 | errsts = check_condition_result; | ||
432 | break; | ||
433 | } | ||
434 | errsts = resp_report_tgtpgs(SCpnt, devip); | ||
435 | break; | ||
425 | case READ_16: | 436 | case READ_16: |
426 | case READ_12: | 437 | case READ_12: |
427 | case READ_10: | 438 | case READ_10: |
@@ -665,8 +676,9 @@ static const char * inq_vendor_id = "Linux "; | |||
665 | static const char * inq_product_id = "scsi_debug "; | 676 | static const char * inq_product_id = "scsi_debug "; |
666 | static const char * inq_product_rev = "0004"; | 677 | static const char * inq_product_rev = "0004"; |
667 | 678 | ||
668 | static int inquiry_evpd_83(unsigned char * arr, int target_dev_id, | 679 | static int inquiry_evpd_83(unsigned char * arr, int port_group_id, |
669 | int dev_id_num, const char * dev_id_str, | 680 | int target_dev_id, int dev_id_num, |
681 | const char * dev_id_str, | ||
670 | int dev_id_str_len) | 682 | int dev_id_str_len) |
671 | { | 683 | { |
672 | int num, port_a; | 684 | int num, port_a; |
@@ -720,6 +732,15 @@ static int inquiry_evpd_83(unsigned char * arr, int target_dev_id, | |||
720 | arr[num++] = (port_a >> 16) & 0xff; | 732 | arr[num++] = (port_a >> 16) & 0xff; |
721 | arr[num++] = (port_a >> 8) & 0xff; | 733 | arr[num++] = (port_a >> 8) & 0xff; |
722 | arr[num++] = port_a & 0xff; | 734 | arr[num++] = port_a & 0xff; |
735 | /* NAA-5, Target port group identifier */ | ||
736 | arr[num++] = 0x61; /* proto=sas, binary */ | ||
737 | arr[num++] = 0x95; /* piv=1, target port group id */ | ||
738 | arr[num++] = 0x0; | ||
739 | arr[num++] = 0x4; | ||
740 | arr[num++] = 0; | ||
741 | arr[num++] = 0; | ||
742 | arr[num++] = (port_group_id >> 8) & 0xff; | ||
743 | arr[num++] = port_group_id & 0xff; | ||
723 | /* NAA-5, Target device identifier */ | 744 | /* NAA-5, Target device identifier */ |
724 | arr[num++] = 0x61; /* proto=sas, binary */ | 745 | arr[num++] = 0x61; /* proto=sas, binary */ |
725 | arr[num++] = 0xa3; /* piv=1, target device, naa */ | 746 | arr[num++] = 0xa3; /* piv=1, target device, naa */ |
@@ -928,12 +949,12 @@ static int resp_inquiry(struct scsi_cmnd * scp, int target, | |||
928 | struct sdebug_dev_info * devip) | 949 | struct sdebug_dev_info * devip) |
929 | { | 950 | { |
930 | unsigned char pq_pdt; | 951 | unsigned char pq_pdt; |
931 | unsigned char arr[SDEBUG_MAX_INQ_ARR_SZ]; | 952 | unsigned char * arr; |
932 | unsigned char *cmd = (unsigned char *)scp->cmnd; | 953 | unsigned char *cmd = (unsigned char *)scp->cmnd; |
933 | int alloc_len, n; | 954 | int alloc_len, n, ret; |
934 | 955 | ||
935 | alloc_len = (cmd[3] << 8) + cmd[4]; | 956 | alloc_len = (cmd[3] << 8) + cmd[4]; |
936 | memset(arr, 0, SDEBUG_MAX_INQ_ARR_SZ); | 957 | arr = kzalloc(SDEBUG_MAX_INQ_ARR_SZ, GFP_KERNEL); |
937 | if (devip->wlun) | 958 | if (devip->wlun) |
938 | pq_pdt = 0x1e; /* present, wlun */ | 959 | pq_pdt = 0x1e; /* present, wlun */ |
939 | else if (scsi_debug_no_lun_0 && (0 == devip->lun)) | 960 | else if (scsi_debug_no_lun_0 && (0 == devip->lun)) |
@@ -944,12 +965,15 @@ static int resp_inquiry(struct scsi_cmnd * scp, int target, | |||
944 | if (0x2 & cmd[1]) { /* CMDDT bit set */ | 965 | if (0x2 & cmd[1]) { /* CMDDT bit set */ |
945 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, | 966 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, |
946 | 0); | 967 | 0); |
968 | kfree(arr); | ||
947 | return check_condition_result; | 969 | return check_condition_result; |
948 | } else if (0x1 & cmd[1]) { /* EVPD bit set */ | 970 | } else if (0x1 & cmd[1]) { /* EVPD bit set */ |
949 | int lu_id_num, target_dev_id, len; | 971 | int lu_id_num, port_group_id, target_dev_id, len; |
950 | char lu_id_str[6]; | 972 | char lu_id_str[6]; |
951 | int host_no = devip->sdbg_host->shost->host_no; | 973 | int host_no = devip->sdbg_host->shost->host_no; |
952 | 974 | ||
975 | port_group_id = (((host_no + 1) & 0x7f) << 8) + | ||
976 | (devip->channel & 0x7f); | ||
953 | if (0 == scsi_debug_vpd_use_hostno) | 977 | if (0 == scsi_debug_vpd_use_hostno) |
954 | host_no = 0; | 978 | host_no = 0; |
955 | lu_id_num = devip->wlun ? -1 : (((host_no + 1) * 2000) + | 979 | lu_id_num = devip->wlun ? -1 : (((host_no + 1) * 2000) + |
@@ -977,8 +1001,9 @@ static int resp_inquiry(struct scsi_cmnd * scp, int target, | |||
977 | memcpy(&arr[4], lu_id_str, len); | 1001 | memcpy(&arr[4], lu_id_str, len); |
978 | } else if (0x83 == cmd[2]) { /* device identification */ | 1002 | } else if (0x83 == cmd[2]) { /* device identification */ |
979 | arr[1] = cmd[2]; /*sanity */ | 1003 | arr[1] = cmd[2]; /*sanity */ |
980 | arr[3] = inquiry_evpd_83(&arr[4], target_dev_id, | 1004 | arr[3] = inquiry_evpd_83(&arr[4], port_group_id, |
981 | lu_id_num, lu_id_str, len); | 1005 | target_dev_id, lu_id_num, |
1006 | lu_id_str, len); | ||
982 | } else if (0x84 == cmd[2]) { /* Software interface ident. */ | 1007 | } else if (0x84 == cmd[2]) { /* Software interface ident. */ |
983 | arr[1] = cmd[2]; /*sanity */ | 1008 | arr[1] = cmd[2]; /*sanity */ |
984 | arr[3] = inquiry_evpd_84(&arr[4]); | 1009 | arr[3] = inquiry_evpd_84(&arr[4]); |
@@ -1012,17 +1037,22 @@ static int resp_inquiry(struct scsi_cmnd * scp, int target, | |||
1012 | /* Illegal request, invalid field in cdb */ | 1037 | /* Illegal request, invalid field in cdb */ |
1013 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | 1038 | mk_sense_buffer(devip, ILLEGAL_REQUEST, |
1014 | INVALID_FIELD_IN_CDB, 0); | 1039 | INVALID_FIELD_IN_CDB, 0); |
1040 | kfree(arr); | ||
1015 | return check_condition_result; | 1041 | return check_condition_result; |
1016 | } | 1042 | } |
1017 | len = min(((arr[2] << 8) + arr[3]) + 4, alloc_len); | 1043 | len = min(((arr[2] << 8) + arr[3]) + 4, alloc_len); |
1018 | return fill_from_dev_buffer(scp, arr, | 1044 | ret = fill_from_dev_buffer(scp, arr, |
1019 | min(len, SDEBUG_MAX_INQ_ARR_SZ)); | 1045 | min(len, SDEBUG_MAX_INQ_ARR_SZ)); |
1046 | kfree(arr); | ||
1047 | return ret; | ||
1020 | } | 1048 | } |
1021 | /* drops through here for a standard inquiry */ | 1049 | /* drops through here for a standard inquiry */ |
1022 | arr[1] = DEV_REMOVEABLE(target) ? 0x80 : 0; /* Removable disk */ | 1050 | arr[1] = DEV_REMOVEABLE(target) ? 0x80 : 0; /* Removable disk */ |
1023 | arr[2] = scsi_debug_scsi_level; | 1051 | arr[2] = scsi_debug_scsi_level; |
1024 | arr[3] = 2; /* response_data_format==2 */ | 1052 | arr[3] = 2; /* response_data_format==2 */ |
1025 | arr[4] = SDEBUG_LONG_INQ_SZ - 5; | 1053 | arr[4] = SDEBUG_LONG_INQ_SZ - 5; |
1054 | if (0 == scsi_debug_vpd_use_hostno) | ||
1055 | arr[5] = 0x10; /* claim: implicit TGPS */ | ||
1026 | arr[6] = 0x10; /* claim: MultiP */ | 1056 | arr[6] = 0x10; /* claim: MultiP */ |
1027 | /* arr[6] |= 0x40; ... claim: EncServ (enclosure services) */ | 1057 | /* arr[6] |= 0x40; ... claim: EncServ (enclosure services) */ |
1028 | arr[7] = 0xa; /* claim: LINKED + CMDQUE */ | 1058 | arr[7] = 0xa; /* claim: LINKED + CMDQUE */ |
@@ -1039,8 +1069,10 @@ static int resp_inquiry(struct scsi_cmnd * scp, int target, | |||
1039 | arr[n++] = 0x3; arr[n++] = 0x60; /* SSC-2 no version */ | 1069 | arr[n++] = 0x3; arr[n++] = 0x60; /* SSC-2 no version */ |
1040 | } | 1070 | } |
1041 | arr[n++] = 0xc; arr[n++] = 0xf; /* SAS-1.1 rev 10 */ | 1071 | arr[n++] = 0xc; arr[n++] = 0xf; /* SAS-1.1 rev 10 */ |
1042 | return fill_from_dev_buffer(scp, arr, | 1072 | ret = fill_from_dev_buffer(scp, arr, |
1043 | min(alloc_len, SDEBUG_LONG_INQ_SZ)); | 1073 | min(alloc_len, SDEBUG_LONG_INQ_SZ)); |
1074 | kfree(arr); | ||
1075 | return ret; | ||
1044 | } | 1076 | } |
1045 | 1077 | ||
1046 | static int resp_requests(struct scsi_cmnd * scp, | 1078 | static int resp_requests(struct scsi_cmnd * scp, |
@@ -1171,6 +1203,87 @@ static int resp_readcap16(struct scsi_cmnd * scp, | |||
1171 | min(alloc_len, SDEBUG_READCAP16_ARR_SZ)); | 1203 | min(alloc_len, SDEBUG_READCAP16_ARR_SZ)); |
1172 | } | 1204 | } |
1173 | 1205 | ||
1206 | #define SDEBUG_MAX_TGTPGS_ARR_SZ 1412 | ||
1207 | |||
1208 | static int resp_report_tgtpgs(struct scsi_cmnd * scp, | ||
1209 | struct sdebug_dev_info * devip) | ||
1210 | { | ||
1211 | unsigned char *cmd = (unsigned char *)scp->cmnd; | ||
1212 | unsigned char * arr; | ||
1213 | int host_no = devip->sdbg_host->shost->host_no; | ||
1214 | int n, ret, alen, rlen; | ||
1215 | int port_group_a, port_group_b, port_a, port_b; | ||
1216 | |||
1217 | alen = ((cmd[6] << 24) + (cmd[7] << 16) + (cmd[8] << 8) | ||
1218 | + cmd[9]); | ||
1219 | |||
1220 | arr = kzalloc(SDEBUG_MAX_TGTPGS_ARR_SZ, GFP_KERNEL); | ||
1221 | /* | ||
1222 | * EVPD page 0x88 states we have two ports, one | ||
1223 | * real and a fake port with no device connected. | ||
1224 | * So we create two port groups with one port each | ||
1225 | * and set the group with port B to unavailable. | ||
1226 | */ | ||
1227 | port_a = 0x1; /* relative port A */ | ||
1228 | port_b = 0x2; /* relative port B */ | ||
1229 | port_group_a = (((host_no + 1) & 0x7f) << 8) + | ||
1230 | (devip->channel & 0x7f); | ||
1231 | port_group_b = (((host_no + 1) & 0x7f) << 8) + | ||
1232 | (devip->channel & 0x7f) + 0x80; | ||
1233 | |||
1234 | /* | ||
1235 | * The asymmetric access state is cycled according to the host_id. | ||
1236 | */ | ||
1237 | n = 4; | ||
1238 | if (0 == scsi_debug_vpd_use_hostno) { | ||
1239 | arr[n++] = host_no % 3; /* Asymm access state */ | ||
1240 | arr[n++] = 0x0F; /* claim: all states are supported */ | ||
1241 | } else { | ||
1242 | arr[n++] = 0x0; /* Active/Optimized path */ | ||
1243 | arr[n++] = 0x01; /* claim: only support active/optimized paths */ | ||
1244 | } | ||
1245 | arr[n++] = (port_group_a >> 8) & 0xff; | ||
1246 | arr[n++] = port_group_a & 0xff; | ||
1247 | arr[n++] = 0; /* Reserved */ | ||
1248 | arr[n++] = 0; /* Status code */ | ||
1249 | arr[n++] = 0; /* Vendor unique */ | ||
1250 | arr[n++] = 0x1; /* One port per group */ | ||
1251 | arr[n++] = 0; /* Reserved */ | ||
1252 | arr[n++] = 0; /* Reserved */ | ||
1253 | arr[n++] = (port_a >> 8) & 0xff; | ||
1254 | arr[n++] = port_a & 0xff; | ||
1255 | arr[n++] = 3; /* Port unavailable */ | ||
1256 | arr[n++] = 0x08; /* claim: only unavailalbe paths are supported */ | ||
1257 | arr[n++] = (port_group_b >> 8) & 0xff; | ||
1258 | arr[n++] = port_group_b & 0xff; | ||
1259 | arr[n++] = 0; /* Reserved */ | ||
1260 | arr[n++] = 0; /* Status code */ | ||
1261 | arr[n++] = 0; /* Vendor unique */ | ||
1262 | arr[n++] = 0x1; /* One port per group */ | ||
1263 | arr[n++] = 0; /* Reserved */ | ||
1264 | arr[n++] = 0; /* Reserved */ | ||
1265 | arr[n++] = (port_b >> 8) & 0xff; | ||
1266 | arr[n++] = port_b & 0xff; | ||
1267 | |||
1268 | rlen = n - 4; | ||
1269 | arr[0] = (rlen >> 24) & 0xff; | ||
1270 | arr[1] = (rlen >> 16) & 0xff; | ||
1271 | arr[2] = (rlen >> 8) & 0xff; | ||
1272 | arr[3] = rlen & 0xff; | ||
1273 | |||
1274 | /* | ||
1275 | * Return the smallest value of either | ||
1276 | * - The allocated length | ||
1277 | * - The constructed command length | ||
1278 | * - The maximum array size | ||
1279 | */ | ||
1280 | rlen = min(alen,n); | ||
1281 | ret = fill_from_dev_buffer(scp, arr, | ||
1282 | min(rlen, SDEBUG_MAX_TGTPGS_ARR_SZ)); | ||
1283 | kfree(arr); | ||
1284 | return ret; | ||
1285 | } | ||
1286 | |||
1174 | /* <<Following mode page info copied from ST318451LW>> */ | 1287 | /* <<Following mode page info copied from ST318451LW>> */ |
1175 | 1288 | ||
1176 | static int resp_err_recov_pg(unsigned char * p, int pcontrol, int target) | 1289 | static int resp_err_recov_pg(unsigned char * p, int pcontrol, int target) |
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index ee35a62bb7a2..2f12f9f12fcb 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -410,6 +410,7 @@ int scsi_execute_async(struct scsi_device *sdev, const unsigned char *cmd, | |||
410 | goto free_req; | 410 | goto free_req; |
411 | 411 | ||
412 | req->cmd_len = cmd_len; | 412 | req->cmd_len = cmd_len; |
413 | memset(req->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */ | ||
413 | memcpy(req->cmd, cmd, req->cmd_len); | 414 | memcpy(req->cmd, cmd, req->cmd_len); |
414 | req->sense = sioc->sense; | 415 | req->sense = sioc->sense; |
415 | req->sense_len = 0; | 416 | req->sense_len = 0; |
@@ -1119,7 +1120,7 @@ static int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req) | |||
1119 | req->buffer = NULL; | 1120 | req->buffer = NULL; |
1120 | } | 1121 | } |
1121 | 1122 | ||
1122 | BUG_ON(sizeof(req->cmd) > sizeof(cmd->cmnd)); | 1123 | BUILD_BUG_ON(sizeof(req->cmd) > sizeof(cmd->cmnd)); |
1123 | memcpy(cmd->cmnd, req->cmd, sizeof(cmd->cmnd)); | 1124 | memcpy(cmd->cmnd, req->cmd, sizeof(cmd->cmnd)); |
1124 | cmd->cmd_len = req->cmd_len; | 1125 | cmd->cmd_len = req->cmd_len; |
1125 | if (!req->data_len) | 1126 | if (!req->data_len) |
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 148e24cc3222..aa1b1e0e9d22 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c | |||
@@ -700,12 +700,22 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, | |||
700 | * scanning run at their own risk, or supply a user level program | 700 | * scanning run at their own risk, or supply a user level program |
701 | * that can correctly scan. | 701 | * that can correctly scan. |
702 | */ | 702 | */ |
703 | sdev->inquiry = kmalloc(sdev->inquiry_len, GFP_ATOMIC); | 703 | |
704 | if (sdev->inquiry == NULL) { | 704 | /* |
705 | * Copy at least 36 bytes of INQUIRY data, so that we don't | ||
706 | * dereference unallocated memory when accessing the Vendor, | ||
707 | * Product, and Revision strings. Badly behaved devices may set | ||
708 | * the INQUIRY Additional Length byte to a small value, indicating | ||
709 | * these strings are invalid, but often they contain plausible data | ||
710 | * nonetheless. It doesn't matter if the device sent < 36 bytes | ||
711 | * total, since scsi_probe_lun() initializes inq_result with 0s. | ||
712 | */ | ||
713 | sdev->inquiry = kmemdup(inq_result, | ||
714 | max_t(size_t, sdev->inquiry_len, 36), | ||
715 | GFP_ATOMIC); | ||
716 | if (sdev->inquiry == NULL) | ||
705 | return SCSI_SCAN_NO_RESPONSE; | 717 | return SCSI_SCAN_NO_RESPONSE; |
706 | } | ||
707 | 718 | ||
708 | memcpy(sdev->inquiry, inq_result, sdev->inquiry_len); | ||
709 | sdev->vendor = (char *) (sdev->inquiry + 8); | 719 | sdev->vendor = (char *) (sdev->inquiry + 8); |
710 | sdev->model = (char *) (sdev->inquiry + 16); | 720 | sdev->model = (char *) (sdev->inquiry + 16); |
711 | sdev->rev = (char *) (sdev->inquiry + 32); | 721 | sdev->rev = (char *) (sdev->inquiry + 32); |
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index e7fe565b96de..e1a91665d1c2 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c | |||
@@ -192,6 +192,7 @@ static CLASS_DEVICE_ATTR(state, S_IRUGO | S_IWUSR, show_shost_state, store_shost | |||
192 | shost_rd_attr(unique_id, "%u\n"); | 192 | shost_rd_attr(unique_id, "%u\n"); |
193 | shost_rd_attr(host_busy, "%hu\n"); | 193 | shost_rd_attr(host_busy, "%hu\n"); |
194 | shost_rd_attr(cmd_per_lun, "%hd\n"); | 194 | shost_rd_attr(cmd_per_lun, "%hd\n"); |
195 | shost_rd_attr(can_queue, "%hd\n"); | ||
195 | shost_rd_attr(sg_tablesize, "%hu\n"); | 196 | shost_rd_attr(sg_tablesize, "%hu\n"); |
196 | shost_rd_attr(unchecked_isa_dma, "%d\n"); | 197 | shost_rd_attr(unchecked_isa_dma, "%d\n"); |
197 | shost_rd_attr2(proc_name, hostt->proc_name, "%s\n"); | 198 | shost_rd_attr2(proc_name, hostt->proc_name, "%s\n"); |
@@ -200,6 +201,7 @@ static struct class_device_attribute *scsi_sysfs_shost_attrs[] = { | |||
200 | &class_device_attr_unique_id, | 201 | &class_device_attr_unique_id, |
201 | &class_device_attr_host_busy, | 202 | &class_device_attr_host_busy, |
202 | &class_device_attr_cmd_per_lun, | 203 | &class_device_attr_cmd_per_lun, |
204 | &class_device_attr_can_queue, | ||
203 | &class_device_attr_sg_tablesize, | 205 | &class_device_attr_sg_tablesize, |
204 | &class_device_attr_unchecked_isa_dma, | 206 | &class_device_attr_unchecked_isa_dma, |
205 | &class_device_attr_proc_name, | 207 | &class_device_attr_proc_name, |
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 7b0019cccce3..9b25124a989e 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c | |||
@@ -21,7 +21,6 @@ | |||
21 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | 21 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
22 | */ | 22 | */ |
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #include <linux/mempool.h> | ||
25 | #include <linux/mutex.h> | 24 | #include <linux/mutex.h> |
26 | #include <net/tcp.h> | 25 | #include <net/tcp.h> |
27 | #include <scsi/scsi.h> | 26 | #include <scsi/scsi.h> |
@@ -34,7 +33,7 @@ | |||
34 | #define ISCSI_SESSION_ATTRS 11 | 33 | #define ISCSI_SESSION_ATTRS 11 |
35 | #define ISCSI_CONN_ATTRS 11 | 34 | #define ISCSI_CONN_ATTRS 11 |
36 | #define ISCSI_HOST_ATTRS 0 | 35 | #define ISCSI_HOST_ATTRS 0 |
37 | #define ISCSI_TRANSPORT_VERSION "2.0-685" | 36 | #define ISCSI_TRANSPORT_VERSION "2.0-724" |
38 | 37 | ||
39 | struct iscsi_internal { | 38 | struct iscsi_internal { |
40 | int daemon_pid; | 39 | int daemon_pid; |
@@ -149,30 +148,6 @@ static DECLARE_TRANSPORT_CLASS(iscsi_connection_class, | |||
149 | static struct sock *nls; | 148 | static struct sock *nls; |
150 | static DEFINE_MUTEX(rx_queue_mutex); | 149 | static DEFINE_MUTEX(rx_queue_mutex); |
151 | 150 | ||
152 | struct mempool_zone { | ||
153 | mempool_t *pool; | ||
154 | atomic_t allocated; | ||
155 | int size; | ||
156 | int hiwat; | ||
157 | struct list_head freequeue; | ||
158 | spinlock_t freelock; | ||
159 | }; | ||
160 | |||
161 | static struct mempool_zone *z_reply; | ||
162 | |||
163 | /* | ||
164 | * Z_MAX_* - actual mempool size allocated at the mempool_zone_init() time | ||
165 | * Z_HIWAT_* - zone's high watermark when if_error bit will be set to -ENOMEM | ||
166 | * so daemon will notice OOM on NETLINK tranposrt level and will | ||
167 | * be able to predict or change operational behavior | ||
168 | */ | ||
169 | #define Z_MAX_REPLY 8 | ||
170 | #define Z_HIWAT_REPLY 6 | ||
171 | #define Z_MAX_PDU 8 | ||
172 | #define Z_HIWAT_PDU 6 | ||
173 | #define Z_MAX_ERROR 16 | ||
174 | #define Z_HIWAT_ERROR 12 | ||
175 | |||
176 | static LIST_HEAD(sesslist); | 151 | static LIST_HEAD(sesslist); |
177 | static DEFINE_SPINLOCK(sesslock); | 152 | static DEFINE_SPINLOCK(sesslock); |
178 | static LIST_HEAD(connlist); | 153 | static LIST_HEAD(connlist); |
@@ -414,59 +389,11 @@ int iscsi_destroy_session(struct iscsi_cls_session *session) | |||
414 | } | 389 | } |
415 | EXPORT_SYMBOL_GPL(iscsi_destroy_session); | 390 | EXPORT_SYMBOL_GPL(iscsi_destroy_session); |
416 | 391 | ||
417 | static void mempool_zone_destroy(struct mempool_zone *zp) | ||
418 | { | ||
419 | mempool_destroy(zp->pool); | ||
420 | kfree(zp); | ||
421 | } | ||
422 | |||
423 | static void* | ||
424 | mempool_zone_alloc_skb(gfp_t gfp_mask, void *pool_data) | ||
425 | { | ||
426 | struct mempool_zone *zone = pool_data; | ||
427 | |||
428 | return alloc_skb(zone->size, gfp_mask); | ||
429 | } | ||
430 | |||
431 | static void | ||
432 | mempool_zone_free_skb(void *element, void *pool_data) | ||
433 | { | ||
434 | kfree_skb(element); | ||
435 | } | ||
436 | |||
437 | static struct mempool_zone * | ||
438 | mempool_zone_init(unsigned max, unsigned size, unsigned hiwat) | ||
439 | { | ||
440 | struct mempool_zone *zp; | ||
441 | |||
442 | zp = kzalloc(sizeof(*zp), GFP_KERNEL); | ||
443 | if (!zp) | ||
444 | return NULL; | ||
445 | |||
446 | zp->size = size; | ||
447 | zp->hiwat = hiwat; | ||
448 | INIT_LIST_HEAD(&zp->freequeue); | ||
449 | spin_lock_init(&zp->freelock); | ||
450 | atomic_set(&zp->allocated, 0); | ||
451 | |||
452 | zp->pool = mempool_create(max, mempool_zone_alloc_skb, | ||
453 | mempool_zone_free_skb, zp); | ||
454 | if (!zp->pool) { | ||
455 | kfree(zp); | ||
456 | return NULL; | ||
457 | } | ||
458 | |||
459 | return zp; | ||
460 | } | ||
461 | |||
462 | static void iscsi_conn_release(struct device *dev) | 392 | static void iscsi_conn_release(struct device *dev) |
463 | { | 393 | { |
464 | struct iscsi_cls_conn *conn = iscsi_dev_to_conn(dev); | 394 | struct iscsi_cls_conn *conn = iscsi_dev_to_conn(dev); |
465 | struct device *parent = conn->dev.parent; | 395 | struct device *parent = conn->dev.parent; |
466 | 396 | ||
467 | mempool_zone_destroy(conn->z_pdu); | ||
468 | mempool_zone_destroy(conn->z_error); | ||
469 | |||
470 | kfree(conn); | 397 | kfree(conn); |
471 | put_device(parent); | 398 | put_device(parent); |
472 | } | 399 | } |
@@ -476,31 +403,6 @@ static int iscsi_is_conn_dev(const struct device *dev) | |||
476 | return dev->release == iscsi_conn_release; | 403 | return dev->release == iscsi_conn_release; |
477 | } | 404 | } |
478 | 405 | ||
479 | static int iscsi_create_event_pools(struct iscsi_cls_conn *conn) | ||
480 | { | ||
481 | conn->z_pdu = mempool_zone_init(Z_MAX_PDU, | ||
482 | NLMSG_SPACE(sizeof(struct iscsi_uevent) + | ||
483 | sizeof(struct iscsi_hdr) + | ||
484 | DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH), | ||
485 | Z_HIWAT_PDU); | ||
486 | if (!conn->z_pdu) { | ||
487 | dev_printk(KERN_ERR, &conn->dev, "iscsi: can not allocate " | ||
488 | "pdu zone for new conn\n"); | ||
489 | return -ENOMEM; | ||
490 | } | ||
491 | |||
492 | conn->z_error = mempool_zone_init(Z_MAX_ERROR, | ||
493 | NLMSG_SPACE(sizeof(struct iscsi_uevent)), | ||
494 | Z_HIWAT_ERROR); | ||
495 | if (!conn->z_error) { | ||
496 | dev_printk(KERN_ERR, &conn->dev, "iscsi: can not allocate " | ||
497 | "error zone for new conn\n"); | ||
498 | mempool_zone_destroy(conn->z_pdu); | ||
499 | return -ENOMEM; | ||
500 | } | ||
501 | return 0; | ||
502 | } | ||
503 | |||
504 | /** | 406 | /** |
505 | * iscsi_create_conn - create iscsi class connection | 407 | * iscsi_create_conn - create iscsi class connection |
506 | * @session: iscsi cls session | 408 | * @session: iscsi cls session |
@@ -533,12 +435,9 @@ iscsi_create_conn(struct iscsi_cls_session *session, uint32_t cid) | |||
533 | conn->transport = transport; | 435 | conn->transport = transport; |
534 | conn->cid = cid; | 436 | conn->cid = cid; |
535 | 437 | ||
536 | if (iscsi_create_event_pools(conn)) | ||
537 | goto free_conn; | ||
538 | |||
539 | /* this is released in the dev's release function */ | 438 | /* this is released in the dev's release function */ |
540 | if (!get_device(&session->dev)) | 439 | if (!get_device(&session->dev)) |
541 | goto free_conn_pools; | 440 | goto free_conn; |
542 | 441 | ||
543 | snprintf(conn->dev.bus_id, BUS_ID_SIZE, "connection%d:%u", | 442 | snprintf(conn->dev.bus_id, BUS_ID_SIZE, "connection%d:%u", |
544 | session->sid, cid); | 443 | session->sid, cid); |
@@ -555,8 +454,6 @@ iscsi_create_conn(struct iscsi_cls_session *session, uint32_t cid) | |||
555 | 454 | ||
556 | release_parent_ref: | 455 | release_parent_ref: |
557 | put_device(&session->dev); | 456 | put_device(&session->dev); |
558 | free_conn_pools: | ||
559 | |||
560 | free_conn: | 457 | free_conn: |
561 | kfree(conn); | 458 | kfree(conn); |
562 | return NULL; | 459 | return NULL; |
@@ -599,81 +496,31 @@ iscsi_if_transport_lookup(struct iscsi_transport *tt) | |||
599 | return NULL; | 496 | return NULL; |
600 | } | 497 | } |
601 | 498 | ||
602 | static inline struct list_head *skb_to_lh(struct sk_buff *skb) | ||
603 | { | ||
604 | return (struct list_head *)&skb->cb; | ||
605 | } | ||
606 | |||
607 | static void | ||
608 | mempool_zone_complete(struct mempool_zone *zone) | ||
609 | { | ||
610 | unsigned long flags; | ||
611 | struct list_head *lh, *n; | ||
612 | |||
613 | spin_lock_irqsave(&zone->freelock, flags); | ||
614 | list_for_each_safe(lh, n, &zone->freequeue) { | ||
615 | struct sk_buff *skb = (struct sk_buff *)((char *)lh - | ||
616 | offsetof(struct sk_buff, cb)); | ||
617 | if (!skb_shared(skb)) { | ||
618 | list_del(skb_to_lh(skb)); | ||
619 | mempool_free(skb, zone->pool); | ||
620 | atomic_dec(&zone->allocated); | ||
621 | } | ||
622 | } | ||
623 | spin_unlock_irqrestore(&zone->freelock, flags); | ||
624 | } | ||
625 | |||
626 | static struct sk_buff* | ||
627 | mempool_zone_get_skb(struct mempool_zone *zone) | ||
628 | { | ||
629 | struct sk_buff *skb; | ||
630 | |||
631 | skb = mempool_alloc(zone->pool, GFP_ATOMIC); | ||
632 | if (skb) | ||
633 | atomic_inc(&zone->allocated); | ||
634 | return skb; | ||
635 | } | ||
636 | |||
637 | static int | 499 | static int |
638 | iscsi_broadcast_skb(struct mempool_zone *zone, struct sk_buff *skb, gfp_t gfp) | 500 | iscsi_broadcast_skb(struct sk_buff *skb, gfp_t gfp) |
639 | { | 501 | { |
640 | unsigned long flags; | ||
641 | int rc; | 502 | int rc; |
642 | 503 | ||
643 | skb_get(skb); | ||
644 | rc = netlink_broadcast(nls, skb, 0, 1, gfp); | 504 | rc = netlink_broadcast(nls, skb, 0, 1, gfp); |
645 | if (rc < 0) { | 505 | if (rc < 0) { |
646 | mempool_free(skb, zone->pool); | ||
647 | printk(KERN_ERR "iscsi: can not broadcast skb (%d)\n", rc); | 506 | printk(KERN_ERR "iscsi: can not broadcast skb (%d)\n", rc); |
648 | return rc; | 507 | return rc; |
649 | } | 508 | } |
650 | 509 | ||
651 | spin_lock_irqsave(&zone->freelock, flags); | ||
652 | INIT_LIST_HEAD(skb_to_lh(skb)); | ||
653 | list_add(skb_to_lh(skb), &zone->freequeue); | ||
654 | spin_unlock_irqrestore(&zone->freelock, flags); | ||
655 | return 0; | 510 | return 0; |
656 | } | 511 | } |
657 | 512 | ||
658 | static int | 513 | static int |
659 | iscsi_unicast_skb(struct mempool_zone *zone, struct sk_buff *skb, int pid) | 514 | iscsi_unicast_skb(struct sk_buff *skb, int pid) |
660 | { | 515 | { |
661 | unsigned long flags; | ||
662 | int rc; | 516 | int rc; |
663 | 517 | ||
664 | skb_get(skb); | ||
665 | rc = netlink_unicast(nls, skb, pid, MSG_DONTWAIT); | 518 | rc = netlink_unicast(nls, skb, pid, MSG_DONTWAIT); |
666 | if (rc < 0) { | 519 | if (rc < 0) { |
667 | mempool_free(skb, zone->pool); | ||
668 | printk(KERN_ERR "iscsi: can not unicast skb (%d)\n", rc); | 520 | printk(KERN_ERR "iscsi: can not unicast skb (%d)\n", rc); |
669 | return rc; | 521 | return rc; |
670 | } | 522 | } |
671 | 523 | ||
672 | spin_lock_irqsave(&zone->freelock, flags); | ||
673 | INIT_LIST_HEAD(skb_to_lh(skb)); | ||
674 | list_add(skb_to_lh(skb), &zone->freequeue); | ||
675 | spin_unlock_irqrestore(&zone->freelock, flags); | ||
676 | |||
677 | return 0; | 524 | return 0; |
678 | } | 525 | } |
679 | 526 | ||
@@ -692,9 +539,7 @@ int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr, | |||
692 | if (!priv) | 539 | if (!priv) |
693 | return -EINVAL; | 540 | return -EINVAL; |
694 | 541 | ||
695 | mempool_zone_complete(conn->z_pdu); | 542 | skb = alloc_skb(len, GFP_ATOMIC); |
696 | |||
697 | skb = mempool_zone_get_skb(conn->z_pdu); | ||
698 | if (!skb) { | 543 | if (!skb) { |
699 | iscsi_conn_error(conn, ISCSI_ERR_CONN_FAILED); | 544 | iscsi_conn_error(conn, ISCSI_ERR_CONN_FAILED); |
700 | dev_printk(KERN_ERR, &conn->dev, "iscsi: can not deliver " | 545 | dev_printk(KERN_ERR, &conn->dev, "iscsi: can not deliver " |
@@ -707,15 +552,13 @@ int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr, | |||
707 | memset(ev, 0, sizeof(*ev)); | 552 | memset(ev, 0, sizeof(*ev)); |
708 | ev->transport_handle = iscsi_handle(conn->transport); | 553 | ev->transport_handle = iscsi_handle(conn->transport); |
709 | ev->type = ISCSI_KEVENT_RECV_PDU; | 554 | ev->type = ISCSI_KEVENT_RECV_PDU; |
710 | if (atomic_read(&conn->z_pdu->allocated) >= conn->z_pdu->hiwat) | ||
711 | ev->iferror = -ENOMEM; | ||
712 | ev->r.recv_req.cid = conn->cid; | 555 | ev->r.recv_req.cid = conn->cid; |
713 | ev->r.recv_req.sid = iscsi_conn_get_sid(conn); | 556 | ev->r.recv_req.sid = iscsi_conn_get_sid(conn); |
714 | pdu = (char*)ev + sizeof(*ev); | 557 | pdu = (char*)ev + sizeof(*ev); |
715 | memcpy(pdu, hdr, sizeof(struct iscsi_hdr)); | 558 | memcpy(pdu, hdr, sizeof(struct iscsi_hdr)); |
716 | memcpy(pdu + sizeof(struct iscsi_hdr), data, data_size); | 559 | memcpy(pdu + sizeof(struct iscsi_hdr), data, data_size); |
717 | 560 | ||
718 | return iscsi_unicast_skb(conn->z_pdu, skb, priv->daemon_pid); | 561 | return iscsi_unicast_skb(skb, priv->daemon_pid); |
719 | } | 562 | } |
720 | EXPORT_SYMBOL_GPL(iscsi_recv_pdu); | 563 | EXPORT_SYMBOL_GPL(iscsi_recv_pdu); |
721 | 564 | ||
@@ -731,9 +574,7 @@ void iscsi_conn_error(struct iscsi_cls_conn *conn, enum iscsi_err error) | |||
731 | if (!priv) | 574 | if (!priv) |
732 | return; | 575 | return; |
733 | 576 | ||
734 | mempool_zone_complete(conn->z_error); | 577 | skb = alloc_skb(len, GFP_ATOMIC); |
735 | |||
736 | skb = mempool_zone_get_skb(conn->z_error); | ||
737 | if (!skb) { | 578 | if (!skb) { |
738 | dev_printk(KERN_ERR, &conn->dev, "iscsi: gracefully ignored " | 579 | dev_printk(KERN_ERR, &conn->dev, "iscsi: gracefully ignored " |
739 | "conn error (%d)\n", error); | 580 | "conn error (%d)\n", error); |
@@ -744,13 +585,11 @@ void iscsi_conn_error(struct iscsi_cls_conn *conn, enum iscsi_err error) | |||
744 | ev = NLMSG_DATA(nlh); | 585 | ev = NLMSG_DATA(nlh); |
745 | ev->transport_handle = iscsi_handle(conn->transport); | 586 | ev->transport_handle = iscsi_handle(conn->transport); |
746 | ev->type = ISCSI_KEVENT_CONN_ERROR; | 587 | ev->type = ISCSI_KEVENT_CONN_ERROR; |
747 | if (atomic_read(&conn->z_error->allocated) >= conn->z_error->hiwat) | ||
748 | ev->iferror = -ENOMEM; | ||
749 | ev->r.connerror.error = error; | 588 | ev->r.connerror.error = error; |
750 | ev->r.connerror.cid = conn->cid; | 589 | ev->r.connerror.cid = conn->cid; |
751 | ev->r.connerror.sid = iscsi_conn_get_sid(conn); | 590 | ev->r.connerror.sid = iscsi_conn_get_sid(conn); |
752 | 591 | ||
753 | iscsi_broadcast_skb(conn->z_error, skb, GFP_ATOMIC); | 592 | iscsi_broadcast_skb(skb, GFP_ATOMIC); |
754 | 593 | ||
755 | dev_printk(KERN_INFO, &conn->dev, "iscsi: detected conn error (%d)\n", | 594 | dev_printk(KERN_INFO, &conn->dev, "iscsi: detected conn error (%d)\n", |
756 | error); | 595 | error); |
@@ -767,9 +606,7 @@ iscsi_if_send_reply(int pid, int seq, int type, int done, int multi, | |||
767 | int flags = multi ? NLM_F_MULTI : 0; | 606 | int flags = multi ? NLM_F_MULTI : 0; |
768 | int t = done ? NLMSG_DONE : type; | 607 | int t = done ? NLMSG_DONE : type; |
769 | 608 | ||
770 | mempool_zone_complete(z_reply); | 609 | skb = alloc_skb(len, GFP_ATOMIC); |
771 | |||
772 | skb = mempool_zone_get_skb(z_reply); | ||
773 | /* | 610 | /* |
774 | * FIXME: | 611 | * FIXME: |
775 | * user is supposed to react on iferror == -ENOMEM; | 612 | * user is supposed to react on iferror == -ENOMEM; |
@@ -780,7 +617,7 @@ iscsi_if_send_reply(int pid, int seq, int type, int done, int multi, | |||
780 | nlh = __nlmsg_put(skb, pid, seq, t, (len - sizeof(*nlh)), 0); | 617 | nlh = __nlmsg_put(skb, pid, seq, t, (len - sizeof(*nlh)), 0); |
781 | nlh->nlmsg_flags = flags; | 618 | nlh->nlmsg_flags = flags; |
782 | memcpy(NLMSG_DATA(nlh), payload, size); | 619 | memcpy(NLMSG_DATA(nlh), payload, size); |
783 | return iscsi_unicast_skb(z_reply, skb, pid); | 620 | return iscsi_unicast_skb(skb, pid); |
784 | } | 621 | } |
785 | 622 | ||
786 | static int | 623 | static int |
@@ -810,9 +647,7 @@ iscsi_if_get_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh) | |||
810 | do { | 647 | do { |
811 | int actual_size; | 648 | int actual_size; |
812 | 649 | ||
813 | mempool_zone_complete(conn->z_pdu); | 650 | skbstat = alloc_skb(len, GFP_ATOMIC); |
814 | |||
815 | skbstat = mempool_zone_get_skb(conn->z_pdu); | ||
816 | if (!skbstat) { | 651 | if (!skbstat) { |
817 | dev_printk(KERN_ERR, &conn->dev, "iscsi: can not " | 652 | dev_printk(KERN_ERR, &conn->dev, "iscsi: can not " |
818 | "deliver stats: OOM\n"); | 653 | "deliver stats: OOM\n"); |
@@ -825,8 +660,6 @@ iscsi_if_get_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh) | |||
825 | memset(evstat, 0, sizeof(*evstat)); | 660 | memset(evstat, 0, sizeof(*evstat)); |
826 | evstat->transport_handle = iscsi_handle(conn->transport); | 661 | evstat->transport_handle = iscsi_handle(conn->transport); |
827 | evstat->type = nlh->nlmsg_type; | 662 | evstat->type = nlh->nlmsg_type; |
828 | if (atomic_read(&conn->z_pdu->allocated) >= conn->z_pdu->hiwat) | ||
829 | evstat->iferror = -ENOMEM; | ||
830 | evstat->u.get_stats.cid = | 663 | evstat->u.get_stats.cid = |
831 | ev->u.get_stats.cid; | 664 | ev->u.get_stats.cid; |
832 | evstat->u.get_stats.sid = | 665 | evstat->u.get_stats.sid = |
@@ -845,7 +678,7 @@ iscsi_if_get_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh) | |||
845 | skb_trim(skbstat, NLMSG_ALIGN(actual_size)); | 678 | skb_trim(skbstat, NLMSG_ALIGN(actual_size)); |
846 | nlhstat->nlmsg_len = actual_size; | 679 | nlhstat->nlmsg_len = actual_size; |
847 | 680 | ||
848 | err = iscsi_unicast_skb(conn->z_pdu, skbstat, priv->daemon_pid); | 681 | err = iscsi_unicast_skb(skbstat, priv->daemon_pid); |
849 | } while (err < 0 && err != -ECONNREFUSED); | 682 | } while (err < 0 && err != -ECONNREFUSED); |
850 | 683 | ||
851 | return err; | 684 | return err; |
@@ -876,9 +709,7 @@ int iscsi_if_destroy_session_done(struct iscsi_cls_conn *conn) | |||
876 | session = iscsi_dev_to_session(conn->dev.parent); | 709 | session = iscsi_dev_to_session(conn->dev.parent); |
877 | shost = iscsi_session_to_shost(session); | 710 | shost = iscsi_session_to_shost(session); |
878 | 711 | ||
879 | mempool_zone_complete(conn->z_pdu); | 712 | skb = alloc_skb(len, GFP_KERNEL); |
880 | |||
881 | skb = mempool_zone_get_skb(conn->z_pdu); | ||
882 | if (!skb) { | 713 | if (!skb) { |
883 | dev_printk(KERN_ERR, &conn->dev, "Cannot notify userspace of " | 714 | dev_printk(KERN_ERR, &conn->dev, "Cannot notify userspace of " |
884 | "session creation event\n"); | 715 | "session creation event\n"); |
@@ -896,7 +727,7 @@ int iscsi_if_destroy_session_done(struct iscsi_cls_conn *conn) | |||
896 | * this will occur if the daemon is not up, so we just warn | 727 | * this will occur if the daemon is not up, so we just warn |
897 | * the user and when the daemon is restarted it will handle it | 728 | * the user and when the daemon is restarted it will handle it |
898 | */ | 729 | */ |
899 | rc = iscsi_broadcast_skb(conn->z_pdu, skb, GFP_KERNEL); | 730 | rc = iscsi_broadcast_skb(skb, GFP_KERNEL); |
900 | if (rc < 0) | 731 | if (rc < 0) |
901 | dev_printk(KERN_ERR, &conn->dev, "Cannot notify userspace of " | 732 | dev_printk(KERN_ERR, &conn->dev, "Cannot notify userspace of " |
902 | "session destruction event. Check iscsi daemon\n"); | 733 | "session destruction event. Check iscsi daemon\n"); |
@@ -939,9 +770,7 @@ int iscsi_if_create_session_done(struct iscsi_cls_conn *conn) | |||
939 | session = iscsi_dev_to_session(conn->dev.parent); | 770 | session = iscsi_dev_to_session(conn->dev.parent); |
940 | shost = iscsi_session_to_shost(session); | 771 | shost = iscsi_session_to_shost(session); |
941 | 772 | ||
942 | mempool_zone_complete(conn->z_pdu); | 773 | skb = alloc_skb(len, GFP_KERNEL); |
943 | |||
944 | skb = mempool_zone_get_skb(conn->z_pdu); | ||
945 | if (!skb) { | 774 | if (!skb) { |
946 | dev_printk(KERN_ERR, &conn->dev, "Cannot notify userspace of " | 775 | dev_printk(KERN_ERR, &conn->dev, "Cannot notify userspace of " |
947 | "session creation event\n"); | 776 | "session creation event\n"); |
@@ -959,7 +788,7 @@ int iscsi_if_create_session_done(struct iscsi_cls_conn *conn) | |||
959 | * this will occur if the daemon is not up, so we just warn | 788 | * this will occur if the daemon is not up, so we just warn |
960 | * the user and when the daemon is restarted it will handle it | 789 | * the user and when the daemon is restarted it will handle it |
961 | */ | 790 | */ |
962 | rc = iscsi_broadcast_skb(conn->z_pdu, skb, GFP_KERNEL); | 791 | rc = iscsi_broadcast_skb(skb, GFP_KERNEL); |
963 | if (rc < 0) | 792 | if (rc < 0) |
964 | dev_printk(KERN_ERR, &conn->dev, "Cannot notify userspace of " | 793 | dev_printk(KERN_ERR, &conn->dev, "Cannot notify userspace of " |
965 | "session creation event. Check iscsi daemon\n"); | 794 | "session creation event. Check iscsi daemon\n"); |
@@ -1278,9 +1107,6 @@ iscsi_if_rx(struct sock *sk, int len) | |||
1278 | err = iscsi_if_send_reply( | 1107 | err = iscsi_if_send_reply( |
1279 | NETLINK_CREDS(skb)->pid, nlh->nlmsg_seq, | 1108 | NETLINK_CREDS(skb)->pid, nlh->nlmsg_seq, |
1280 | nlh->nlmsg_type, 0, 0, ev, sizeof(*ev)); | 1109 | nlh->nlmsg_type, 0, 0, ev, sizeof(*ev)); |
1281 | if (atomic_read(&z_reply->allocated) >= | ||
1282 | z_reply->hiwat) | ||
1283 | ev->iferror = -ENOMEM; | ||
1284 | } while (err < 0 && err != -ECONNREFUSED); | 1110 | } while (err < 0 && err != -ECONNREFUSED); |
1285 | skb_pull(skb, rlen); | 1111 | skb_pull(skb, rlen); |
1286 | } | 1112 | } |
@@ -1584,32 +1410,6 @@ int iscsi_unregister_transport(struct iscsi_transport *tt) | |||
1584 | } | 1410 | } |
1585 | EXPORT_SYMBOL_GPL(iscsi_unregister_transport); | 1411 | EXPORT_SYMBOL_GPL(iscsi_unregister_transport); |
1586 | 1412 | ||
1587 | static int | ||
1588 | iscsi_rcv_nl_event(struct notifier_block *this, unsigned long event, void *ptr) | ||
1589 | { | ||
1590 | struct netlink_notify *n = ptr; | ||
1591 | |||
1592 | if (event == NETLINK_URELEASE && | ||
1593 | n->protocol == NETLINK_ISCSI && n->pid) { | ||
1594 | struct iscsi_cls_conn *conn; | ||
1595 | unsigned long flags; | ||
1596 | |||
1597 | mempool_zone_complete(z_reply); | ||
1598 | spin_lock_irqsave(&connlock, flags); | ||
1599 | list_for_each_entry(conn, &connlist, conn_list) { | ||
1600 | mempool_zone_complete(conn->z_error); | ||
1601 | mempool_zone_complete(conn->z_pdu); | ||
1602 | } | ||
1603 | spin_unlock_irqrestore(&connlock, flags); | ||
1604 | } | ||
1605 | |||
1606 | return NOTIFY_DONE; | ||
1607 | } | ||
1608 | |||
1609 | static struct notifier_block iscsi_nl_notifier = { | ||
1610 | .notifier_call = iscsi_rcv_nl_event, | ||
1611 | }; | ||
1612 | |||
1613 | static __init int iscsi_transport_init(void) | 1413 | static __init int iscsi_transport_init(void) |
1614 | { | 1414 | { |
1615 | int err; | 1415 | int err; |
@@ -1633,25 +1433,15 @@ static __init int iscsi_transport_init(void) | |||
1633 | if (err) | 1433 | if (err) |
1634 | goto unregister_conn_class; | 1434 | goto unregister_conn_class; |
1635 | 1435 | ||
1636 | err = netlink_register_notifier(&iscsi_nl_notifier); | ||
1637 | if (err) | ||
1638 | goto unregister_session_class; | ||
1639 | |||
1640 | nls = netlink_kernel_create(NETLINK_ISCSI, 1, iscsi_if_rx, | 1436 | nls = netlink_kernel_create(NETLINK_ISCSI, 1, iscsi_if_rx, |
1641 | THIS_MODULE); | 1437 | THIS_MODULE); |
1642 | if (!nls) { | 1438 | if (!nls) { |
1643 | err = -ENOBUFS; | 1439 | err = -ENOBUFS; |
1644 | goto unregister_notifier; | 1440 | goto unregister_session_class; |
1645 | } | 1441 | } |
1646 | 1442 | ||
1647 | z_reply = mempool_zone_init(Z_MAX_REPLY, | 1443 | return 0; |
1648 | NLMSG_SPACE(sizeof(struct iscsi_uevent)), Z_HIWAT_REPLY); | ||
1649 | if (z_reply) | ||
1650 | return 0; | ||
1651 | 1444 | ||
1652 | sock_release(nls->sk_socket); | ||
1653 | unregister_notifier: | ||
1654 | netlink_unregister_notifier(&iscsi_nl_notifier); | ||
1655 | unregister_session_class: | 1445 | unregister_session_class: |
1656 | transport_class_unregister(&iscsi_session_class); | 1446 | transport_class_unregister(&iscsi_session_class); |
1657 | unregister_conn_class: | 1447 | unregister_conn_class: |
@@ -1665,9 +1455,7 @@ unregister_transport_class: | |||
1665 | 1455 | ||
1666 | static void __exit iscsi_transport_exit(void) | 1456 | static void __exit iscsi_transport_exit(void) |
1667 | { | 1457 | { |
1668 | mempool_zone_destroy(z_reply); | ||
1669 | sock_release(nls->sk_socket); | 1458 | sock_release(nls->sk_socket); |
1670 | netlink_unregister_notifier(&iscsi_nl_notifier); | ||
1671 | transport_class_unregister(&iscsi_connection_class); | 1459 | transport_class_unregister(&iscsi_connection_class); |
1672 | transport_class_unregister(&iscsi_session_class); | 1460 | transport_class_unregister(&iscsi_session_class); |
1673 | transport_class_unregister(&iscsi_host_class); | 1461 | transport_class_unregister(&iscsi_host_class); |
diff --git a/drivers/scsi/seagate.c b/drivers/scsi/seagate.c index 8ff1f2866f7b..5ffec2721b28 100644 --- a/drivers/scsi/seagate.c +++ b/drivers/scsi/seagate.c | |||
@@ -97,8 +97,8 @@ | |||
97 | #include <linux/blkdev.h> | 97 | #include <linux/blkdev.h> |
98 | #include <linux/stat.h> | 98 | #include <linux/stat.h> |
99 | #include <linux/delay.h> | 99 | #include <linux/delay.h> |
100 | #include <linux/io.h> | ||
100 | 101 | ||
101 | #include <asm/io.h> | ||
102 | #include <asm/system.h> | 102 | #include <asm/system.h> |
103 | #include <asm/uaccess.h> | 103 | #include <asm/uaccess.h> |
104 | 104 | ||
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 3f8b93188567..81e3bc7b02a1 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c | |||
@@ -60,7 +60,7 @@ static int sg_version_num = 30534; /* 2 digits for each component */ | |||
60 | 60 | ||
61 | #ifdef CONFIG_SCSI_PROC_FS | 61 | #ifdef CONFIG_SCSI_PROC_FS |
62 | #include <linux/proc_fs.h> | 62 | #include <linux/proc_fs.h> |
63 | static char *sg_version_date = "20060920"; | 63 | static char *sg_version_date = "20061027"; |
64 | 64 | ||
65 | static int sg_proc_init(void); | 65 | static int sg_proc_init(void); |
66 | static void sg_proc_cleanup(void); | 66 | static void sg_proc_cleanup(void); |
@@ -710,12 +710,12 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp, | |||
710 | (int) cmnd[0], (int) hp->cmd_len)); | 710 | (int) cmnd[0], (int) hp->cmd_len)); |
711 | 711 | ||
712 | if ((k = sg_start_req(srp))) { | 712 | if ((k = sg_start_req(srp))) { |
713 | SCSI_LOG_TIMEOUT(1, printk("sg_write: start_req err=%d\n", k)); | 713 | SCSI_LOG_TIMEOUT(1, printk("sg_common_write: start_req err=%d\n", k)); |
714 | sg_finish_rem_req(srp); | 714 | sg_finish_rem_req(srp); |
715 | return k; /* probably out of space --> ENOMEM */ | 715 | return k; /* probably out of space --> ENOMEM */ |
716 | } | 716 | } |
717 | if ((k = sg_write_xfer(srp))) { | 717 | if ((k = sg_write_xfer(srp))) { |
718 | SCSI_LOG_TIMEOUT(1, printk("sg_write: write_xfer, bad address\n")); | 718 | SCSI_LOG_TIMEOUT(1, printk("sg_common_write: write_xfer, bad address\n")); |
719 | sg_finish_rem_req(srp); | 719 | sg_finish_rem_req(srp); |
720 | return k; | 720 | return k; |
721 | } | 721 | } |
@@ -746,7 +746,7 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp, | |||
746 | hp->dxfer_len, srp->data.k_use_sg, timeout, | 746 | hp->dxfer_len, srp->data.k_use_sg, timeout, |
747 | SG_DEFAULT_RETRIES, srp, sg_cmd_done, | 747 | SG_DEFAULT_RETRIES, srp, sg_cmd_done, |
748 | GFP_ATOMIC)) { | 748 | GFP_ATOMIC)) { |
749 | SCSI_LOG_TIMEOUT(1, printk("sg_write: scsi_execute_async failed\n")); | 749 | SCSI_LOG_TIMEOUT(1, printk("sg_common_write: scsi_execute_async failed\n")); |
750 | /* | 750 | /* |
751 | * most likely out of mem, but could also be a bad map | 751 | * most likely out of mem, but could also be a bad map |
752 | */ | 752 | */ |
@@ -1283,7 +1283,7 @@ sg_cmd_done(void *data, char *sense, int result, int resid) | |||
1283 | sg_finish_rem_req(srp); | 1283 | sg_finish_rem_req(srp); |
1284 | srp = NULL; | 1284 | srp = NULL; |
1285 | if (NULL == sfp->headrp) { | 1285 | if (NULL == sfp->headrp) { |
1286 | SCSI_LOG_TIMEOUT(1, printk("sg...bh: already closed, final cleanup\n")); | 1286 | SCSI_LOG_TIMEOUT(1, printk("sg_cmd_done: already closed, final cleanup\n")); |
1287 | if (0 == sg_remove_sfp(sdp, sfp)) { /* device still present */ | 1287 | if (0 == sg_remove_sfp(sdp, sfp)) { /* device still present */ |
1288 | scsi_device_put(sdp->device); | 1288 | scsi_device_put(sdp->device); |
1289 | } | 1289 | } |
@@ -1512,12 +1512,12 @@ sg_remove(struct class_device *cl_dev, struct class_interface *cl_intf) | |||
1512 | POLL_HUP); | 1512 | POLL_HUP); |
1513 | } | 1513 | } |
1514 | } | 1514 | } |
1515 | SCSI_LOG_TIMEOUT(3, printk("sg_detach: dev=%d, dirty\n", k)); | 1515 | SCSI_LOG_TIMEOUT(3, printk("sg_remove: dev=%d, dirty\n", k)); |
1516 | if (NULL == sdp->headfp) { | 1516 | if (NULL == sdp->headfp) { |
1517 | sg_dev_arr[k] = NULL; | 1517 | sg_dev_arr[k] = NULL; |
1518 | } | 1518 | } |
1519 | } else { /* nothing active, simple case */ | 1519 | } else { /* nothing active, simple case */ |
1520 | SCSI_LOG_TIMEOUT(3, printk("sg_detach: dev=%d\n", k)); | 1520 | SCSI_LOG_TIMEOUT(3, printk("sg_remove: dev=%d\n", k)); |
1521 | sg_dev_arr[k] = NULL; | 1521 | sg_dev_arr[k] = NULL; |
1522 | } | 1522 | } |
1523 | sg_nr_dev--; | 1523 | sg_nr_dev--; |
@@ -1876,14 +1876,15 @@ sg_build_indirect(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size) | |||
1876 | } | 1876 | } |
1877 | } | 1877 | } |
1878 | sg->page = p; | 1878 | sg->page = p; |
1879 | sg->length = ret_sz; | 1879 | sg->length = (ret_sz > num) ? num : ret_sz; |
1880 | 1880 | ||
1881 | SCSI_LOG_TIMEOUT(5, printk("sg_build_build: k=%d, a=0x%p, len=%d\n", | 1881 | SCSI_LOG_TIMEOUT(5, printk("sg_build_indirect: k=%d, num=%d, " |
1882 | k, p, ret_sz)); | 1882 | "ret_sz=%d\n", k, num, ret_sz)); |
1883 | } /* end of for loop */ | 1883 | } /* end of for loop */ |
1884 | 1884 | ||
1885 | schp->k_use_sg = k; | 1885 | schp->k_use_sg = k; |
1886 | SCSI_LOG_TIMEOUT(5, printk("sg_build_indirect: k_use_sg=%d, rem_sz=%d\n", k, rem_sz)); | 1886 | SCSI_LOG_TIMEOUT(5, printk("sg_build_indirect: k_use_sg=%d, " |
1887 | "rem_sz=%d\n", k, rem_sz)); | ||
1887 | 1888 | ||
1888 | schp->bufflen = blk_size; | 1889 | schp->bufflen = blk_size; |
1889 | if (rem_sz > 0) /* must have failed */ | 1890 | if (rem_sz > 0) /* must have failed */ |
@@ -2014,7 +2015,7 @@ sg_remove_scat(Sg_scatter_hold * schp) | |||
2014 | for (k = 0; (k < schp->k_use_sg) && sg->page; | 2015 | for (k = 0; (k < schp->k_use_sg) && sg->page; |
2015 | ++k, ++sg) { | 2016 | ++k, ++sg) { |
2016 | SCSI_LOG_TIMEOUT(5, printk( | 2017 | SCSI_LOG_TIMEOUT(5, printk( |
2017 | "sg_remove_scat: k=%d, a=0x%p, len=%d\n", | 2018 | "sg_remove_scat: k=%d, pg=0x%p, len=%d\n", |
2018 | k, sg->page, sg->length)); | 2019 | k, sg->page, sg->length)); |
2019 | sg_page_free(sg->page, sg->length); | 2020 | sg_page_free(sg->page, sg->length); |
2020 | } | 2021 | } |
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index febfac97ad38..587274dd7059 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c | |||
@@ -1177,7 +1177,10 @@ static int st_open(struct inode *inode, struct file *filp) | |||
1177 | goto err_out; | 1177 | goto err_out; |
1178 | if ((filp->f_flags & O_NONBLOCK) == 0 && | 1178 | if ((filp->f_flags & O_NONBLOCK) == 0 && |
1179 | retval != CHKRES_READY) { | 1179 | retval != CHKRES_READY) { |
1180 | retval = (-EIO); | 1180 | if (STp->ready == NO_TAPE) |
1181 | retval = (-ENOMEDIUM); | ||
1182 | else | ||
1183 | retval = (-EIO); | ||
1181 | goto err_out; | 1184 | goto err_out; |
1182 | } | 1185 | } |
1183 | return 0; | 1186 | return 0; |
diff --git a/drivers/scsi/sun3_NCR5380.c b/drivers/scsi/sun3_NCR5380.c index 5ec5af8e3379..3b3f3050a877 100644 --- a/drivers/scsi/sun3_NCR5380.c +++ b/drivers/scsi/sun3_NCR5380.c | |||
@@ -266,8 +266,8 @@ static struct scsi_host_template *the_template = NULL; | |||
266 | (struct NCR5380_hostdata *)(in)->hostdata | 266 | (struct NCR5380_hostdata *)(in)->hostdata |
267 | #define HOSTDATA(in) ((struct NCR5380_hostdata *)(in)->hostdata) | 267 | #define HOSTDATA(in) ((struct NCR5380_hostdata *)(in)->hostdata) |
268 | 268 | ||
269 | #define NEXT(cmd) ((Scsi_Cmnd *)((cmd)->host_scribble)) | 269 | #define NEXT(cmd) ((struct scsi_cmnd *)((cmd)->host_scribble)) |
270 | #define NEXTADDR(cmd) ((Scsi_Cmnd **)&((cmd)->host_scribble)) | 270 | #define NEXTADDR(cmd) ((struct scsi_cmnd **)&((cmd)->host_scribble)) |
271 | 271 | ||
272 | #define HOSTNO instance->host_no | 272 | #define HOSTNO instance->host_no |
273 | #define H_NO(cmd) (cmd)->device->host->host_no | 273 | #define H_NO(cmd) (cmd)->device->host->host_no |
@@ -360,7 +360,7 @@ static void __init init_tags( void ) | |||
360 | * conditions. | 360 | * conditions. |
361 | */ | 361 | */ |
362 | 362 | ||
363 | static int is_lun_busy( Scsi_Cmnd *cmd, int should_be_tagged ) | 363 | static int is_lun_busy(struct scsi_cmnd *cmd, int should_be_tagged) |
364 | { | 364 | { |
365 | SETUP_HOSTDATA(cmd->device->host); | 365 | SETUP_HOSTDATA(cmd->device->host); |
366 | 366 | ||
@@ -384,7 +384,7 @@ static int is_lun_busy( Scsi_Cmnd *cmd, int should_be_tagged ) | |||
384 | * untagged. | 384 | * untagged. |
385 | */ | 385 | */ |
386 | 386 | ||
387 | static void cmd_get_tag( Scsi_Cmnd *cmd, int should_be_tagged ) | 387 | static void cmd_get_tag(struct scsi_cmnd *cmd, int should_be_tagged) |
388 | { | 388 | { |
389 | SETUP_HOSTDATA(cmd->device->host); | 389 | SETUP_HOSTDATA(cmd->device->host); |
390 | 390 | ||
@@ -416,7 +416,7 @@ static void cmd_get_tag( Scsi_Cmnd *cmd, int should_be_tagged ) | |||
416 | * unlock the LUN. | 416 | * unlock the LUN. |
417 | */ | 417 | */ |
418 | 418 | ||
419 | static void cmd_free_tag( Scsi_Cmnd *cmd ) | 419 | static void cmd_free_tag(struct scsi_cmnd *cmd) |
420 | { | 420 | { |
421 | SETUP_HOSTDATA(cmd->device->host); | 421 | SETUP_HOSTDATA(cmd->device->host); |
422 | 422 | ||
@@ -460,18 +460,18 @@ static void free_all_tags( void ) | |||
460 | 460 | ||
461 | 461 | ||
462 | /* | 462 | /* |
463 | * Function: void merge_contiguous_buffers( Scsi_Cmnd *cmd ) | 463 | * Function: void merge_contiguous_buffers(struct scsi_cmnd *cmd) |
464 | * | 464 | * |
465 | * Purpose: Try to merge several scatter-gather requests into one DMA | 465 | * Purpose: Try to merge several scatter-gather requests into one DMA |
466 | * transfer. This is possible if the scatter buffers lie on | 466 | * transfer. This is possible if the scatter buffers lie on |
467 | * physical contiguous addresses. | 467 | * physical contiguous addresses. |
468 | * | 468 | * |
469 | * Parameters: Scsi_Cmnd *cmd | 469 | * Parameters: struct scsi_cmnd *cmd |
470 | * The command to work on. The first scatter buffer's data are | 470 | * The command to work on. The first scatter buffer's data are |
471 | * assumed to be already transfered into ptr/this_residual. | 471 | * assumed to be already transfered into ptr/this_residual. |
472 | */ | 472 | */ |
473 | 473 | ||
474 | static void merge_contiguous_buffers( Scsi_Cmnd *cmd ) | 474 | static void merge_contiguous_buffers(struct scsi_cmnd *cmd) |
475 | { | 475 | { |
476 | unsigned long endaddr; | 476 | unsigned long endaddr; |
477 | #if (NDEBUG & NDEBUG_MERGING) | 477 | #if (NDEBUG & NDEBUG_MERGING) |
@@ -501,15 +501,15 @@ static void merge_contiguous_buffers( Scsi_Cmnd *cmd ) | |||
501 | } | 501 | } |
502 | 502 | ||
503 | /* | 503 | /* |
504 | * Function : void initialize_SCp(Scsi_Cmnd *cmd) | 504 | * Function : void initialize_SCp(struct scsi_cmnd *cmd) |
505 | * | 505 | * |
506 | * Purpose : initialize the saved data pointers for cmd to point to the | 506 | * Purpose : initialize the saved data pointers for cmd to point to the |
507 | * start of the buffer. | 507 | * start of the buffer. |
508 | * | 508 | * |
509 | * Inputs : cmd - Scsi_Cmnd structure to have pointers reset. | 509 | * Inputs : cmd - struct scsi_cmnd structure to have pointers reset. |
510 | */ | 510 | */ |
511 | 511 | ||
512 | static __inline__ void initialize_SCp(Scsi_Cmnd *cmd) | 512 | static __inline__ void initialize_SCp(struct scsi_cmnd *cmd) |
513 | { | 513 | { |
514 | /* | 514 | /* |
515 | * Initialize the Scsi Pointer field so that all of the commands in the | 515 | * Initialize the Scsi Pointer field so that all of the commands in the |
@@ -753,14 +753,15 @@ static void NCR5380_print_status (struct Scsi_Host *instance) | |||
753 | do { if (pos + strlen(fmt) + 20 /* slop */ < buffer + length) \ | 753 | do { if (pos + strlen(fmt) + 20 /* slop */ < buffer + length) \ |
754 | pos += sprintf(pos, fmt , ## args); } while(0) | 754 | pos += sprintf(pos, fmt , ## args); } while(0) |
755 | static | 755 | static |
756 | char *lprint_Scsi_Cmnd (Scsi_Cmnd *cmd, char *pos, char *buffer, int length); | 756 | char *lprint_Scsi_Cmnd(struct scsi_cmnd *cmd, char *pos, char *buffer, |
757 | int length); | ||
757 | 758 | ||
758 | static int NCR5380_proc_info (struct Scsi_Host *instance, char *buffer, char **start, | 759 | static int NCR5380_proc_info(struct Scsi_Host *instance, char *buffer, |
759 | off_t offset, int length, int inout) | 760 | char **start, off_t offset, int length, int inout) |
760 | { | 761 | { |
761 | char *pos = buffer; | 762 | char *pos = buffer; |
762 | struct NCR5380_hostdata *hostdata; | 763 | struct NCR5380_hostdata *hostdata; |
763 | Scsi_Cmnd *ptr; | 764 | struct scsi_cmnd *ptr; |
764 | unsigned long flags; | 765 | unsigned long flags; |
765 | off_t begin = 0; | 766 | off_t begin = 0; |
766 | #define check_offset() \ | 767 | #define check_offset() \ |
@@ -784,18 +785,19 @@ static int NCR5380_proc_info (struct Scsi_Host *instance, char *buffer, char **s | |||
784 | if (!hostdata->connected) | 785 | if (!hostdata->connected) |
785 | SPRINTF("scsi%d: no currently connected command\n", HOSTNO); | 786 | SPRINTF("scsi%d: no currently connected command\n", HOSTNO); |
786 | else | 787 | else |
787 | pos = lprint_Scsi_Cmnd ((Scsi_Cmnd *) hostdata->connected, | 788 | pos = lprint_Scsi_Cmnd ((struct scsi_cmnd *) hostdata->connected, |
788 | pos, buffer, length); | 789 | pos, buffer, length); |
789 | SPRINTF("scsi%d: issue_queue\n", HOSTNO); | 790 | SPRINTF("scsi%d: issue_queue\n", HOSTNO); |
790 | check_offset(); | 791 | check_offset(); |
791 | for (ptr = (Scsi_Cmnd *) hostdata->issue_queue; ptr; ptr = NEXT(ptr)) { | 792 | for (ptr = (struct scsi_cmnd *) hostdata->issue_queue; ptr; ptr = NEXT(ptr)) |
793 | { | ||
792 | pos = lprint_Scsi_Cmnd (ptr, pos, buffer, length); | 794 | pos = lprint_Scsi_Cmnd (ptr, pos, buffer, length); |
793 | check_offset(); | 795 | check_offset(); |
794 | } | 796 | } |
795 | 797 | ||
796 | SPRINTF("scsi%d: disconnected_queue\n", HOSTNO); | 798 | SPRINTF("scsi%d: disconnected_queue\n", HOSTNO); |
797 | check_offset(); | 799 | check_offset(); |
798 | for (ptr = (Scsi_Cmnd *) hostdata->disconnected_queue; ptr; | 800 | for (ptr = (struct scsi_cmnd *) hostdata->disconnected_queue; ptr; |
799 | ptr = NEXT(ptr)) { | 801 | ptr = NEXT(ptr)) { |
800 | pos = lprint_Scsi_Cmnd (ptr, pos, buffer, length); | 802 | pos = lprint_Scsi_Cmnd (ptr, pos, buffer, length); |
801 | check_offset(); | 803 | check_offset(); |
@@ -810,8 +812,8 @@ static int NCR5380_proc_info (struct Scsi_Host *instance, char *buffer, char **s | |||
810 | return length; | 812 | return length; |
811 | } | 813 | } |
812 | 814 | ||
813 | static char * | 815 | static char *lprint_Scsi_Cmnd(struct scsi_cmnd *cmd, char *pos, char *buffer, |
814 | lprint_Scsi_Cmnd (Scsi_Cmnd *cmd, char *pos, char *buffer, int length) | 816 | int length) |
815 | { | 817 | { |
816 | int i, s; | 818 | int i, s; |
817 | unsigned char *command; | 819 | unsigned char *command; |
@@ -888,8 +890,8 @@ static int NCR5380_init (struct Scsi_Host *instance, int flags) | |||
888 | } | 890 | } |
889 | 891 | ||
890 | /* | 892 | /* |
891 | * Function : int NCR5380_queue_command (Scsi_Cmnd *cmd, | 893 | * Function : int NCR5380_queue_command (struct scsi_cmnd *cmd, |
892 | * void (*done)(Scsi_Cmnd *)) | 894 | * void (*done)(struct scsi_cmnd *)) |
893 | * | 895 | * |
894 | * Purpose : enqueues a SCSI command | 896 | * Purpose : enqueues a SCSI command |
895 | * | 897 | * |
@@ -906,10 +908,11 @@ static int NCR5380_init (struct Scsi_Host *instance, int flags) | |||
906 | */ | 908 | */ |
907 | 909 | ||
908 | /* Only make static if a wrapper function is used */ | 910 | /* Only make static if a wrapper function is used */ |
909 | static int NCR5380_queue_command (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *)) | 911 | static int NCR5380_queue_command(struct scsi_cmnd *cmd, |
912 | void (*done)(struct scsi_cmnd *)) | ||
910 | { | 913 | { |
911 | SETUP_HOSTDATA(cmd->device->host); | 914 | SETUP_HOSTDATA(cmd->device->host); |
912 | Scsi_Cmnd *tmp; | 915 | struct scsi_cmnd *tmp; |
913 | unsigned long flags; | 916 | unsigned long flags; |
914 | 917 | ||
915 | #if (NDEBUG & NDEBUG_NO_WRITE) | 918 | #if (NDEBUG & NDEBUG_NO_WRITE) |
@@ -990,7 +993,7 @@ static int NCR5380_queue_command (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *)) | |||
990 | NEXT(cmd) = hostdata->issue_queue; | 993 | NEXT(cmd) = hostdata->issue_queue; |
991 | hostdata->issue_queue = cmd; | 994 | hostdata->issue_queue = cmd; |
992 | } else { | 995 | } else { |
993 | for (tmp = (Scsi_Cmnd *)hostdata->issue_queue; | 996 | for (tmp = (struct scsi_cmnd *)hostdata->issue_queue; |
994 | NEXT(tmp); tmp = NEXT(tmp)) | 997 | NEXT(tmp); tmp = NEXT(tmp)) |
995 | ; | 998 | ; |
996 | LIST(cmd, tmp); | 999 | LIST(cmd, tmp); |
@@ -1030,7 +1033,7 @@ static int NCR5380_queue_command (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *)) | |||
1030 | 1033 | ||
1031 | static void NCR5380_main (void *bl) | 1034 | static void NCR5380_main (void *bl) |
1032 | { | 1035 | { |
1033 | Scsi_Cmnd *tmp, *prev; | 1036 | struct scsi_cmnd *tmp, *prev; |
1034 | struct Scsi_Host *instance = first_instance; | 1037 | struct Scsi_Host *instance = first_instance; |
1035 | struct NCR5380_hostdata *hostdata = HOSTDATA(instance); | 1038 | struct NCR5380_hostdata *hostdata = HOSTDATA(instance); |
1036 | int done; | 1039 | int done; |
@@ -1073,12 +1076,12 @@ static void NCR5380_main (void *bl) | |||
1073 | * for a target that's not busy. | 1076 | * for a target that's not busy. |
1074 | */ | 1077 | */ |
1075 | #if (NDEBUG & NDEBUG_LISTS) | 1078 | #if (NDEBUG & NDEBUG_LISTS) |
1076 | for (tmp = (Scsi_Cmnd *) hostdata->issue_queue, prev = NULL; | 1079 | for (tmp = (struct scsi_cmnd *) hostdata->issue_queue, prev = NULL; |
1077 | tmp && (tmp != prev); prev = tmp, tmp = NEXT(tmp)) | 1080 | tmp && (tmp != prev); prev = tmp, tmp = NEXT(tmp)) |
1078 | ; | 1081 | ; |
1079 | if ((tmp == prev) && tmp) printk(" LOOP\n");/* else printk("\n");*/ | 1082 | if ((tmp == prev) && tmp) printk(" LOOP\n");/* else printk("\n");*/ |
1080 | #endif | 1083 | #endif |
1081 | for (tmp = (Scsi_Cmnd *) hostdata->issue_queue, | 1084 | for (tmp = (struct scsi_cmnd *) hostdata->issue_queue, |
1082 | prev = NULL; tmp; prev = tmp, tmp = NEXT(tmp) ) { | 1085 | prev = NULL; tmp; prev = tmp, tmp = NEXT(tmp) ) { |
1083 | 1086 | ||
1084 | #if (NDEBUG & NDEBUG_LISTS) | 1087 | #if (NDEBUG & NDEBUG_LISTS) |
@@ -1339,7 +1342,8 @@ static irqreturn_t NCR5380_intr (int irq, void *dev_id) | |||
1339 | } | 1342 | } |
1340 | 1343 | ||
1341 | #ifdef NCR5380_STATS | 1344 | #ifdef NCR5380_STATS |
1342 | static void collect_stats(struct NCR5380_hostdata* hostdata, Scsi_Cmnd* cmd) | 1345 | static void collect_stats(struct NCR5380_hostdata *hostdata, |
1346 | struct scsi_cmnd *cmd) | ||
1343 | { | 1347 | { |
1344 | # ifdef NCR5380_STAT_LIMIT | 1348 | # ifdef NCR5380_STAT_LIMIT |
1345 | if (cmd->request_bufflen > NCR5380_STAT_LIMIT) | 1349 | if (cmd->request_bufflen > NCR5380_STAT_LIMIT) |
@@ -1365,8 +1369,8 @@ static void collect_stats(struct NCR5380_hostdata* hostdata, Scsi_Cmnd* cmd) | |||
1365 | #endif | 1369 | #endif |
1366 | 1370 | ||
1367 | /* | 1371 | /* |
1368 | * Function : int NCR5380_select (struct Scsi_Host *instance, Scsi_Cmnd *cmd, | 1372 | * Function : int NCR5380_select(struct Scsi_Host *instance, |
1369 | * int tag); | 1373 | * struct scsi_cmnd *cmd, int tag); |
1370 | * | 1374 | * |
1371 | * Purpose : establishes I_T_L or I_T_L_Q nexus for new or existing command, | 1375 | * Purpose : establishes I_T_L or I_T_L_Q nexus for new or existing command, |
1372 | * including ARBITRATION, SELECTION, and initial message out for | 1376 | * including ARBITRATION, SELECTION, and initial message out for |
@@ -1395,7 +1399,8 @@ static void collect_stats(struct NCR5380_hostdata* hostdata, Scsi_Cmnd* cmd) | |||
1395 | * cmd->result host byte set to DID_BAD_TARGET. | 1399 | * cmd->result host byte set to DID_BAD_TARGET. |
1396 | */ | 1400 | */ |
1397 | 1401 | ||
1398 | static int NCR5380_select (struct Scsi_Host *instance, Scsi_Cmnd *cmd, int tag) | 1402 | static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd, |
1403 | int tag) | ||
1399 | { | 1404 | { |
1400 | SETUP_HOSTDATA(instance); | 1405 | SETUP_HOSTDATA(instance); |
1401 | unsigned char tmp[3], phase; | 1406 | unsigned char tmp[3], phase; |
@@ -1985,7 +1990,7 @@ static void NCR5380_information_transfer (struct Scsi_Host *instance) | |||
1985 | #endif | 1990 | #endif |
1986 | unsigned char *data; | 1991 | unsigned char *data; |
1987 | unsigned char phase, tmp, extended_msg[10], old_phase=0xff; | 1992 | unsigned char phase, tmp, extended_msg[10], old_phase=0xff; |
1988 | Scsi_Cmnd *cmd = (Scsi_Cmnd *) hostdata->connected; | 1993 | struct scsi_cmnd *cmd = (struct scsi_cmnd *) hostdata->connected; |
1989 | 1994 | ||
1990 | #ifdef SUN3_SCSI_VME | 1995 | #ifdef SUN3_SCSI_VME |
1991 | dregs->csr |= CSR_INTR; | 1996 | dregs->csr |= CSR_INTR; |
@@ -2272,7 +2277,7 @@ static void NCR5380_information_transfer (struct Scsi_Host *instance) | |||
2272 | local_irq_save(flags); | 2277 | local_irq_save(flags); |
2273 | LIST(cmd,hostdata->issue_queue); | 2278 | LIST(cmd,hostdata->issue_queue); |
2274 | NEXT(cmd) = hostdata->issue_queue; | 2279 | NEXT(cmd) = hostdata->issue_queue; |
2275 | hostdata->issue_queue = (Scsi_Cmnd *) cmd; | 2280 | hostdata->issue_queue = (struct scsi_cmnd *) cmd; |
2276 | local_irq_restore(flags); | 2281 | local_irq_restore(flags); |
2277 | QU_PRINTK("scsi%d: REQUEST SENSE added to head of " | 2282 | QU_PRINTK("scsi%d: REQUEST SENSE added to head of " |
2278 | "issue queue\n", H_NO(cmd)); | 2283 | "issue queue\n", H_NO(cmd)); |
@@ -2502,7 +2507,7 @@ static void NCR5380_information_transfer (struct Scsi_Host *instance) | |||
2502 | * Function : void NCR5380_reselect (struct Scsi_Host *instance) | 2507 | * Function : void NCR5380_reselect (struct Scsi_Host *instance) |
2503 | * | 2508 | * |
2504 | * Purpose : does reselection, initializing the instance->connected | 2509 | * Purpose : does reselection, initializing the instance->connected |
2505 | * field to point to the Scsi_Cmnd for which the I_T_L or I_T_L_Q | 2510 | * field to point to the struct scsi_cmnd for which the I_T_L or I_T_L_Q |
2506 | * nexus has been reestablished, | 2511 | * nexus has been reestablished, |
2507 | * | 2512 | * |
2508 | * Inputs : instance - this instance of the NCR5380. | 2513 | * Inputs : instance - this instance of the NCR5380. |
@@ -2521,7 +2526,7 @@ static void NCR5380_reselect (struct Scsi_Host *instance) | |||
2521 | unsigned char tag; | 2526 | unsigned char tag; |
2522 | #endif | 2527 | #endif |
2523 | unsigned char msg[3]; | 2528 | unsigned char msg[3]; |
2524 | Scsi_Cmnd *tmp = NULL, *prev; | 2529 | struct scsi_cmnd *tmp = NULL, *prev; |
2525 | /* unsigned long flags; */ | 2530 | /* unsigned long flags; */ |
2526 | 2531 | ||
2527 | /* | 2532 | /* |
@@ -2577,7 +2582,7 @@ static void NCR5380_reselect (struct Scsi_Host *instance) | |||
2577 | * just reestablished, and remove it from the disconnected queue. | 2582 | * just reestablished, and remove it from the disconnected queue. |
2578 | */ | 2583 | */ |
2579 | 2584 | ||
2580 | for (tmp = (Scsi_Cmnd *) hostdata->disconnected_queue, prev = NULL; | 2585 | for (tmp = (struct scsi_cmnd *) hostdata->disconnected_queue, prev = NULL; |
2581 | tmp; prev = tmp, tmp = NEXT(tmp) ) { | 2586 | tmp; prev = tmp, tmp = NEXT(tmp) ) { |
2582 | if ((target_mask == (1 << tmp->device->id)) && (lun == tmp->device->lun) | 2587 | if ((target_mask == (1 << tmp->device->id)) && (lun == tmp->device->lun) |
2583 | #ifdef SUPPORT_TAGS | 2588 | #ifdef SUPPORT_TAGS |
@@ -2668,11 +2673,11 @@ static void NCR5380_reselect (struct Scsi_Host *instance) | |||
2668 | 2673 | ||
2669 | 2674 | ||
2670 | /* | 2675 | /* |
2671 | * Function : int NCR5380_abort (Scsi_Cmnd *cmd) | 2676 | * Function : int NCR5380_abort(struct scsi_cmnd *cmd) |
2672 | * | 2677 | * |
2673 | * Purpose : abort a command | 2678 | * Purpose : abort a command |
2674 | * | 2679 | * |
2675 | * Inputs : cmd - the Scsi_Cmnd to abort, code - code to set the | 2680 | * Inputs : cmd - the struct scsi_cmnd to abort, code - code to set the |
2676 | * host byte of the result field to, if zero DID_ABORTED is | 2681 | * host byte of the result field to, if zero DID_ABORTED is |
2677 | * used. | 2682 | * used. |
2678 | * | 2683 | * |
@@ -2684,11 +2689,11 @@ static void NCR5380_reselect (struct Scsi_Host *instance) | |||
2684 | * called where the loop started in NCR5380_main(). | 2689 | * called where the loop started in NCR5380_main(). |
2685 | */ | 2690 | */ |
2686 | 2691 | ||
2687 | static int NCR5380_abort (Scsi_Cmnd *cmd) | 2692 | static int NCR5380_abort(struct scsi_cmnd *cmd) |
2688 | { | 2693 | { |
2689 | struct Scsi_Host *instance = cmd->device->host; | 2694 | struct Scsi_Host *instance = cmd->device->host; |
2690 | SETUP_HOSTDATA(instance); | 2695 | SETUP_HOSTDATA(instance); |
2691 | Scsi_Cmnd *tmp, **prev; | 2696 | struct scsi_cmnd *tmp, **prev; |
2692 | unsigned long flags; | 2697 | unsigned long flags; |
2693 | 2698 | ||
2694 | printk(KERN_NOTICE "scsi%d: aborting command\n", HOSTNO); | 2699 | printk(KERN_NOTICE "scsi%d: aborting command\n", HOSTNO); |
@@ -2753,9 +2758,9 @@ static int NCR5380_abort (Scsi_Cmnd *cmd) | |||
2753 | * Case 2 : If the command hasn't been issued yet, we simply remove it | 2758 | * Case 2 : If the command hasn't been issued yet, we simply remove it |
2754 | * from the issue queue. | 2759 | * from the issue queue. |
2755 | */ | 2760 | */ |
2756 | for (prev = (Scsi_Cmnd **) &(hostdata->issue_queue), | 2761 | for (prev = (struct scsi_cmnd **) &(hostdata->issue_queue), |
2757 | tmp = (Scsi_Cmnd *) hostdata->issue_queue; | 2762 | tmp = (struct scsi_cmnd *) hostdata->issue_queue; |
2758 | tmp; prev = NEXTADDR(tmp), tmp = NEXT(tmp) ) | 2763 | tmp; prev = NEXTADDR(tmp), tmp = NEXT(tmp)) |
2759 | if (cmd == tmp) { | 2764 | if (cmd == tmp) { |
2760 | REMOVE(5, *prev, tmp, NEXT(tmp)); | 2765 | REMOVE(5, *prev, tmp, NEXT(tmp)); |
2761 | (*prev) = NEXT(tmp); | 2766 | (*prev) = NEXT(tmp); |
@@ -2812,7 +2817,7 @@ static int NCR5380_abort (Scsi_Cmnd *cmd) | |||
2812 | * it from the disconnected queue. | 2817 | * it from the disconnected queue. |
2813 | */ | 2818 | */ |
2814 | 2819 | ||
2815 | for (tmp = (Scsi_Cmnd *) hostdata->disconnected_queue; tmp; | 2820 | for (tmp = (struct scsi_cmnd *) hostdata->disconnected_queue; tmp; |
2816 | tmp = NEXT(tmp)) | 2821 | tmp = NEXT(tmp)) |
2817 | if (cmd == tmp) { | 2822 | if (cmd == tmp) { |
2818 | local_irq_restore(flags); | 2823 | local_irq_restore(flags); |
@@ -2826,8 +2831,8 @@ static int NCR5380_abort (Scsi_Cmnd *cmd) | |||
2826 | do_abort (instance); | 2831 | do_abort (instance); |
2827 | 2832 | ||
2828 | local_irq_save(flags); | 2833 | local_irq_save(flags); |
2829 | for (prev = (Scsi_Cmnd **) &(hostdata->disconnected_queue), | 2834 | for (prev = (struct scsi_cmnd **) &(hostdata->disconnected_queue), |
2830 | tmp = (Scsi_Cmnd *) hostdata->disconnected_queue; | 2835 | tmp = (struct scsi_cmnd *) hostdata->disconnected_queue; |
2831 | tmp; prev = NEXTADDR(tmp), tmp = NEXT(tmp) ) | 2836 | tmp; prev = NEXTADDR(tmp), tmp = NEXT(tmp) ) |
2832 | if (cmd == tmp) { | 2837 | if (cmd == tmp) { |
2833 | REMOVE(5, *prev, tmp, NEXT(tmp)); | 2838 | REMOVE(5, *prev, tmp, NEXT(tmp)); |
@@ -2868,7 +2873,7 @@ static int NCR5380_abort (Scsi_Cmnd *cmd) | |||
2868 | 2873 | ||
2869 | 2874 | ||
2870 | /* | 2875 | /* |
2871 | * Function : int NCR5380_bus_reset (Scsi_Cmnd *cmd) | 2876 | * Function : int NCR5380_bus_reset(struct scsi_cmnd *cmd) |
2872 | * | 2877 | * |
2873 | * Purpose : reset the SCSI bus. | 2878 | * Purpose : reset the SCSI bus. |
2874 | * | 2879 | * |
@@ -2876,13 +2881,13 @@ static int NCR5380_abort (Scsi_Cmnd *cmd) | |||
2876 | * | 2881 | * |
2877 | */ | 2882 | */ |
2878 | 2883 | ||
2879 | static int NCR5380_bus_reset( Scsi_Cmnd *cmd) | 2884 | static int NCR5380_bus_reset(struct scsi_cmnd *cmd) |
2880 | { | 2885 | { |
2881 | SETUP_HOSTDATA(cmd->device->host); | 2886 | SETUP_HOSTDATA(cmd->device->host); |
2882 | int i; | 2887 | int i; |
2883 | unsigned long flags; | 2888 | unsigned long flags; |
2884 | #if 1 | 2889 | #if 1 |
2885 | Scsi_Cmnd *connected, *disconnected_queue; | 2890 | struct scsi_cmnd *connected, *disconnected_queue; |
2886 | #endif | 2891 | #endif |
2887 | 2892 | ||
2888 | 2893 | ||
@@ -2914,9 +2919,9 @@ static int NCR5380_bus_reset( Scsi_Cmnd *cmd) | |||
2914 | * remembered in local variables first. | 2919 | * remembered in local variables first. |
2915 | */ | 2920 | */ |
2916 | local_irq_save(flags); | 2921 | local_irq_save(flags); |
2917 | connected = (Scsi_Cmnd *)hostdata->connected; | 2922 | connected = (struct scsi_cmnd *)hostdata->connected; |
2918 | hostdata->connected = NULL; | 2923 | hostdata->connected = NULL; |
2919 | disconnected_queue = (Scsi_Cmnd *)hostdata->disconnected_queue; | 2924 | disconnected_queue = (struct scsi_cmnd *)hostdata->disconnected_queue; |
2920 | hostdata->disconnected_queue = NULL; | 2925 | hostdata->disconnected_queue = NULL; |
2921 | #ifdef SUPPORT_TAGS | 2926 | #ifdef SUPPORT_TAGS |
2922 | free_all_tags(); | 2927 | free_all_tags(); |
diff --git a/drivers/scsi/sun3_scsi.c b/drivers/scsi/sun3_scsi.c index e625b4c5833a..d56d85dd9ba0 100644 --- a/drivers/scsi/sun3_scsi.c +++ b/drivers/scsi/sun3_scsi.c | |||
@@ -119,7 +119,7 @@ module_param(setup_use_tagged_queuing, int, 0); | |||
119 | static int setup_hostid = -1; | 119 | static int setup_hostid = -1; |
120 | module_param(setup_hostid, int, 0); | 120 | module_param(setup_hostid, int, 0); |
121 | 121 | ||
122 | static Scsi_Cmnd *sun3_dma_setup_done = NULL; | 122 | static struct scsi_cmnd *sun3_dma_setup_done = NULL; |
123 | 123 | ||
124 | #define AFTER_RESET_DELAY (HZ/2) | 124 | #define AFTER_RESET_DELAY (HZ/2) |
125 | 125 | ||
@@ -521,8 +521,9 @@ static inline unsigned long sun3scsi_dma_residual(struct Scsi_Host *instance) | |||
521 | return last_residual; | 521 | return last_residual; |
522 | } | 522 | } |
523 | 523 | ||
524 | static inline unsigned long sun3scsi_dma_xfer_len(unsigned long wanted, Scsi_Cmnd *cmd, | 524 | static inline unsigned long sun3scsi_dma_xfer_len(unsigned long wanted, |
525 | int write_flag) | 525 | struct scsi_cmnd *cmd, |
526 | int write_flag) | ||
526 | { | 527 | { |
527 | if(blk_fs_request(cmd->request)) | 528 | if(blk_fs_request(cmd->request)) |
528 | return wanted; | 529 | return wanted; |
diff --git a/drivers/scsi/sun3_scsi.h b/drivers/scsi/sun3_scsi.h index 834dab428019..a1103b3e2034 100644 --- a/drivers/scsi/sun3_scsi.h +++ b/drivers/scsi/sun3_scsi.h | |||
@@ -47,11 +47,12 @@ | |||
47 | 47 | ||
48 | #define IOBASE_SUN3_VMESCSI 0xff200000 | 48 | #define IOBASE_SUN3_VMESCSI 0xff200000 |
49 | 49 | ||
50 | static int sun3scsi_abort (Scsi_Cmnd *); | 50 | static int sun3scsi_abort(struct scsi_cmnd *); |
51 | static int sun3scsi_detect (struct scsi_host_template *); | 51 | static int sun3scsi_detect (struct scsi_host_template *); |
52 | static const char *sun3scsi_info (struct Scsi_Host *); | 52 | static const char *sun3scsi_info (struct Scsi_Host *); |
53 | static int sun3scsi_bus_reset(Scsi_Cmnd *); | 53 | static int sun3scsi_bus_reset(struct scsi_cmnd *); |
54 | static int sun3scsi_queue_command (Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); | 54 | static int sun3scsi_queue_command(struct scsi_cmnd *, |
55 | void (*done)(struct scsi_cmnd *)); | ||
55 | static int sun3scsi_release (struct Scsi_Host *); | 56 | static int sun3scsi_release (struct Scsi_Host *); |
56 | 57 | ||
57 | #ifndef CMD_PER_LUN | 58 | #ifndef CMD_PER_LUN |
diff --git a/drivers/scsi/sun3_scsi_vme.c b/drivers/scsi/sun3_scsi_vme.c index e8faab16567b..92def310a84c 100644 --- a/drivers/scsi/sun3_scsi_vme.c +++ b/drivers/scsi/sun3_scsi_vme.c | |||
@@ -84,7 +84,7 @@ module_param(setup_use_tagged_queuing, int, 0); | |||
84 | static int setup_hostid = -1; | 84 | static int setup_hostid = -1; |
85 | module_param(setup_hostid, int, 0); | 85 | module_param(setup_hostid, int, 0); |
86 | 86 | ||
87 | static Scsi_Cmnd *sun3_dma_setup_done = NULL; | 87 | static struct scsi_cmnd *sun3_dma_setup_done = NULL; |
88 | 88 | ||
89 | #define AFTER_RESET_DELAY (HZ/2) | 89 | #define AFTER_RESET_DELAY (HZ/2) |
90 | 90 | ||
@@ -455,8 +455,9 @@ static inline unsigned long sun3scsi_dma_residual(struct Scsi_Host *instance) | |||
455 | return last_residual; | 455 | return last_residual; |
456 | } | 456 | } |
457 | 457 | ||
458 | static inline unsigned long sun3scsi_dma_xfer_len(unsigned long wanted, Scsi_Cmnd *cmd, | 458 | static inline unsigned long sun3scsi_dma_xfer_len(unsigned long wanted, |
459 | int write_flag) | 459 | struct scsi_cmnd *cmd, |
460 | int write_flag) | ||
460 | { | 461 | { |
461 | if(blk_fs_request(cmd->request)) | 462 | if(blk_fs_request(cmd->request)) |
462 | return wanted; | 463 | return wanted; |
diff --git a/drivers/scsi/t128.c b/drivers/scsi/t128.c index 2df6747cb76f..0b7a70f61e0d 100644 --- a/drivers/scsi/t128.c +++ b/drivers/scsi/t128.c | |||
@@ -109,7 +109,7 @@ | |||
109 | #include <asm/system.h> | 109 | #include <asm/system.h> |
110 | #include <linux/signal.h> | 110 | #include <linux/signal.h> |
111 | #include <linux/sched.h> | 111 | #include <linux/sched.h> |
112 | #include <asm/io.h> | 112 | #include <linux/io.h> |
113 | #include <linux/blkdev.h> | 113 | #include <linux/blkdev.h> |
114 | #include <linux/interrupt.h> | 114 | #include <linux/interrupt.h> |
115 | #include <linux/stat.h> | 115 | #include <linux/stat.h> |
diff --git a/drivers/scsi/tmscsim.c b/drivers/scsi/tmscsim.c index d03aa6ce8fe8..fa5382e354be 100644 --- a/drivers/scsi/tmscsim.c +++ b/drivers/scsi/tmscsim.c | |||
@@ -2304,6 +2304,7 @@ static struct scsi_host_template driver_template = { | |||
2304 | .sg_tablesize = SG_ALL, | 2304 | .sg_tablesize = SG_ALL, |
2305 | .cmd_per_lun = 1, | 2305 | .cmd_per_lun = 1, |
2306 | .use_clustering = ENABLE_CLUSTERING, | 2306 | .use_clustering = ENABLE_CLUSTERING, |
2307 | .max_sectors = 0x4000, /* 8MiB = 16 * 1024 * 512 */ | ||
2307 | }; | 2308 | }; |
2308 | 2309 | ||
2309 | /*********************************************************************** | 2310 | /*********************************************************************** |
diff --git a/drivers/scsi/wd7000.c b/drivers/scsi/wd7000.c index 331e1cf159b0..30be76514c43 100644 --- a/drivers/scsi/wd7000.c +++ b/drivers/scsi/wd7000.c | |||
@@ -178,10 +178,10 @@ | |||
178 | #include <linux/blkdev.h> | 178 | #include <linux/blkdev.h> |
179 | #include <linux/init.h> | 179 | #include <linux/init.h> |
180 | #include <linux/stat.h> | 180 | #include <linux/stat.h> |
181 | #include <linux/io.h> | ||
181 | 182 | ||
182 | #include <asm/system.h> | 183 | #include <asm/system.h> |
183 | #include <asm/dma.h> | 184 | #include <asm/dma.h> |
184 | #include <asm/io.h> | ||
185 | 185 | ||
186 | #include <scsi/scsi.h> | 186 | #include <scsi/scsi.h> |
187 | #include <scsi/scsi_cmnd.h> | 187 | #include <scsi/scsi_cmnd.h> |
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index b0d502622d94..0b71e7d18903 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig | |||
@@ -767,37 +767,37 @@ config SERIAL_CPM_SCC1 | |||
767 | bool "Support for SCC1 serial port" | 767 | bool "Support for SCC1 serial port" |
768 | depends on SERIAL_CPM=y | 768 | depends on SERIAL_CPM=y |
769 | help | 769 | help |
770 | Select the is option to use SCC1 as a serial port | 770 | Select this option to use SCC1 as a serial port |
771 | 771 | ||
772 | config SERIAL_CPM_SCC2 | 772 | config SERIAL_CPM_SCC2 |
773 | bool "Support for SCC2 serial port" | 773 | bool "Support for SCC2 serial port" |
774 | depends on SERIAL_CPM=y | 774 | depends on SERIAL_CPM=y |
775 | help | 775 | help |
776 | Select the is option to use SCC2 as a serial port | 776 | Select this option to use SCC2 as a serial port |
777 | 777 | ||
778 | config SERIAL_CPM_SCC3 | 778 | config SERIAL_CPM_SCC3 |
779 | bool "Support for SCC3 serial port" | 779 | bool "Support for SCC3 serial port" |
780 | depends on SERIAL_CPM=y | 780 | depends on SERIAL_CPM=y |
781 | help | 781 | help |
782 | Select the is option to use SCC3 as a serial port | 782 | Select this option to use SCC3 as a serial port |
783 | 783 | ||
784 | config SERIAL_CPM_SCC4 | 784 | config SERIAL_CPM_SCC4 |
785 | bool "Support for SCC4 serial port" | 785 | bool "Support for SCC4 serial port" |
786 | depends on SERIAL_CPM=y | 786 | depends on SERIAL_CPM=y |
787 | help | 787 | help |
788 | Select the is option to use SCC4 as a serial port | 788 | Select this option to use SCC4 as a serial port |
789 | 789 | ||
790 | config SERIAL_CPM_SMC1 | 790 | config SERIAL_CPM_SMC1 |
791 | bool "Support for SMC1 serial port" | 791 | bool "Support for SMC1 serial port" |
792 | depends on SERIAL_CPM=y | 792 | depends on SERIAL_CPM=y |
793 | help | 793 | help |
794 | Select the is option to use SMC1 as a serial port | 794 | Select this option to use SMC1 as a serial port |
795 | 795 | ||
796 | config SERIAL_CPM_SMC2 | 796 | config SERIAL_CPM_SMC2 |
797 | bool "Support for SMC2 serial port" | 797 | bool "Support for SMC2 serial port" |
798 | depends on SERIAL_CPM=y | 798 | depends on SERIAL_CPM=y |
799 | help | 799 | help |
800 | Select the is option to use SMC2 as a serial port | 800 | Select this option to use SMC2 as a serial port |
801 | 801 | ||
802 | config SERIAL_SGI_L1_CONSOLE | 802 | config SERIAL_SGI_L1_CONSOLE |
803 | bool "SGI Altix L1 serial console support" | 803 | bool "SGI Altix L1 serial console support" |
diff --git a/drivers/serial/cpm_uart/cpm_uart.h b/drivers/serial/cpm_uart/cpm_uart.h index a8f894c78194..69715e556506 100644 --- a/drivers/serial/cpm_uart/cpm_uart.h +++ b/drivers/serial/cpm_uart/cpm_uart.h | |||
@@ -88,7 +88,7 @@ extern struct uart_cpm_port cpm_uart_ports[UART_NR]; | |||
88 | 88 | ||
89 | /* these are located in their respective files */ | 89 | /* these are located in their respective files */ |
90 | void cpm_line_cr_cmd(int line, int cmd); | 90 | void cpm_line_cr_cmd(int line, int cmd); |
91 | int cpm_uart_init_portdesc(void); | 91 | int __init cpm_uart_init_portdesc(void); |
92 | int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con); | 92 | int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con); |
93 | void cpm_uart_freebuf(struct uart_cpm_port *pinfo); | 93 | void cpm_uart_freebuf(struct uart_cpm_port *pinfo); |
94 | 94 | ||
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c index 0abb544ae63d..7a3b97fdf8d1 100644 --- a/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/serial/cpm_uart/cpm_uart_core.c | |||
@@ -195,10 +195,8 @@ static void cpm_uart_start_tx(struct uart_port *port) | |||
195 | if (cpm_uart_tx_pump(port) != 0) { | 195 | if (cpm_uart_tx_pump(port) != 0) { |
196 | if (IS_SMC(pinfo)) { | 196 | if (IS_SMC(pinfo)) { |
197 | smcp->smc_smcm |= SMCM_TX; | 197 | smcp->smc_smcm |= SMCM_TX; |
198 | smcp->smc_smcmr |= SMCMR_TEN; | ||
199 | } else { | 198 | } else { |
200 | sccp->scc_sccm |= UART_SCCM_TX; | 199 | sccp->scc_sccm |= UART_SCCM_TX; |
201 | pinfo->sccp->scc_gsmrl |= SCC_GSMRL_ENT; | ||
202 | } | 200 | } |
203 | } | 201 | } |
204 | } | 202 | } |
@@ -421,9 +419,10 @@ static int cpm_uart_startup(struct uart_port *port) | |||
421 | /* Startup rx-int */ | 419 | /* Startup rx-int */ |
422 | if (IS_SMC(pinfo)) { | 420 | if (IS_SMC(pinfo)) { |
423 | pinfo->smcp->smc_smcm |= SMCM_RX; | 421 | pinfo->smcp->smc_smcm |= SMCM_RX; |
424 | pinfo->smcp->smc_smcmr |= SMCMR_REN; | 422 | pinfo->smcp->smc_smcmr |= (SMCMR_REN | SMCMR_TEN); |
425 | } else { | 423 | } else { |
426 | pinfo->sccp->scc_sccm |= UART_SCCM_RX; | 424 | pinfo->sccp->scc_sccm |= UART_SCCM_RX; |
425 | pinfo->sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT); | ||
427 | } | 426 | } |
428 | 427 | ||
429 | if (!(pinfo->flags & FLAG_CONSOLE)) | 428 | if (!(pinfo->flags & FLAG_CONSOLE)) |
@@ -1350,11 +1349,10 @@ static int cpm_uart_init(void) { | |||
1350 | pr_info("cpm_uart: WARNING: no UART devices found on platform bus!\n"); | 1349 | pr_info("cpm_uart: WARNING: no UART devices found on platform bus!\n"); |
1351 | pr_info( | 1350 | pr_info( |
1352 | "cpm_uart: the driver will guess configuration, but this mode is no longer supported.\n"); | 1351 | "cpm_uart: the driver will guess configuration, but this mode is no longer supported.\n"); |
1353 | #ifndef CONFIG_SERIAL_CPM_CONSOLE | 1352 | |
1354 | ret = cpm_uart_init_portdesc(); | 1353 | /* Don't run this again, if the console driver did it already */ |
1355 | if (ret) | 1354 | if (cpm_uart_nr == 0) |
1356 | return ret; | 1355 | cpm_uart_init_portdesc(); |
1357 | #endif | ||
1358 | 1356 | ||
1359 | cpm_reg.nr = cpm_uart_nr; | 1357 | cpm_reg.nr = cpm_uart_nr; |
1360 | ret = uart_register_driver(&cpm_reg); | 1358 | ret = uart_register_driver(&cpm_reg); |
@@ -1366,6 +1364,8 @@ static int cpm_uart_init(void) { | |||
1366 | int con = cpm_uart_port_map[i]; | 1364 | int con = cpm_uart_port_map[i]; |
1367 | cpm_uart_ports[con].port.line = i; | 1365 | cpm_uart_ports[con].port.line = i; |
1368 | cpm_uart_ports[con].port.flags = UPF_BOOT_AUTOCONF; | 1366 | cpm_uart_ports[con].port.flags = UPF_BOOT_AUTOCONF; |
1367 | if (cpm_uart_ports[con].set_lineif) | ||
1368 | cpm_uart_ports[con].set_lineif(&cpm_uart_ports[con]); | ||
1369 | uart_add_one_port(&cpm_reg, &cpm_uart_ports[con].port); | 1369 | uart_add_one_port(&cpm_reg, &cpm_uart_ports[con].port); |
1370 | } | 1370 | } |
1371 | 1371 | ||
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.c b/drivers/serial/cpm_uart/cpm_uart_cpm1.c index 95afc37297a8..08e55fdc882a 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm1.c +++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.c | |||
@@ -184,7 +184,7 @@ void cpm_uart_freebuf(struct uart_cpm_port *pinfo) | |||
184 | } | 184 | } |
185 | 185 | ||
186 | /* Setup any dynamic params in the uart desc */ | 186 | /* Setup any dynamic params in the uart desc */ |
187 | int cpm_uart_init_portdesc(void) | 187 | int __init cpm_uart_init_portdesc(void) |
188 | { | 188 | { |
189 | pr_debug("CPM uart[-]:init portdesc\n"); | 189 | pr_debug("CPM uart[-]:init portdesc\n"); |
190 | 190 | ||
diff --git a/drivers/serial/ioc4_serial.c b/drivers/serial/ioc4_serial.c index 98ce88d80207..711bd1511439 100644 --- a/drivers/serial/ioc4_serial.c +++ b/drivers/serial/ioc4_serial.c | |||
@@ -921,7 +921,7 @@ static void handle_dma_error_intr(void *arg, uint32_t other_ir) | |||
921 | { | 921 | { |
922 | struct ioc4_port *port = (struct ioc4_port *)arg; | 922 | struct ioc4_port *port = (struct ioc4_port *)arg; |
923 | struct hooks *hooks = port->ip_hooks; | 923 | struct hooks *hooks = port->ip_hooks; |
924 | unsigned int flags; | 924 | unsigned long flags; |
925 | 925 | ||
926 | spin_lock_irqsave(&port->ip_lock, flags); | 926 | spin_lock_irqsave(&port->ip_lock, flags); |
927 | 927 | ||
@@ -1834,7 +1834,7 @@ static void handle_intr(void *arg, uint32_t sio_ir) | |||
1834 | struct ioc4_port *port = (struct ioc4_port *)arg; | 1834 | struct ioc4_port *port = (struct ioc4_port *)arg; |
1835 | struct hooks *hooks = port->ip_hooks; | 1835 | struct hooks *hooks = port->ip_hooks; |
1836 | unsigned int rx_high_rd_aborted = 0; | 1836 | unsigned int rx_high_rd_aborted = 0; |
1837 | unsigned int flags; | 1837 | unsigned long flags; |
1838 | struct uart_port *the_port; | 1838 | struct uart_port *the_port; |
1839 | int loop_counter; | 1839 | int loop_counter; |
1840 | 1840 | ||
@@ -2935,7 +2935,7 @@ static void __devexit ioc4_serial_exit(void) | |||
2935 | uart_unregister_driver(&ioc4_uart_rs422); | 2935 | uart_unregister_driver(&ioc4_uart_rs422); |
2936 | } | 2936 | } |
2937 | 2937 | ||
2938 | module_init(ioc4_serial_init); | 2938 | late_initcall(ioc4_serial_init); /* Call only after tty init is done */ |
2939 | module_exit(ioc4_serial_exit); | 2939 | module_exit(ioc4_serial_exit); |
2940 | 2940 | ||
2941 | MODULE_AUTHOR("Pat Gefre - Silicon Graphics Inc. (SGI) <pfg@sgi.com>"); | 2941 | MODULE_AUTHOR("Pat Gefre - Silicon Graphics Inc. (SGI) <pfg@sgi.com>"); |
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 266aa325569e..cfcc3caf49d8 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c | |||
@@ -808,7 +808,7 @@ static int sci_request_irq(struct sci_port *port) | |||
808 | } | 808 | } |
809 | 809 | ||
810 | if (request_irq(port->irqs[0], sci_mpxed_interrupt, | 810 | if (request_irq(port->irqs[0], sci_mpxed_interrupt, |
811 | SA_INTERRUPT, "sci", port)) { | 811 | IRQF_DISABLED, "sci", port)) { |
812 | printk(KERN_ERR "sci: Cannot allocate irq.\n"); | 812 | printk(KERN_ERR "sci: Cannot allocate irq.\n"); |
813 | return -ENODEV; | 813 | return -ENODEV; |
814 | } | 814 | } |
@@ -817,7 +817,7 @@ static int sci_request_irq(struct sci_port *port) | |||
817 | if (!port->irqs[i]) | 817 | if (!port->irqs[i]) |
818 | continue; | 818 | continue; |
819 | if (request_irq(port->irqs[i], handlers[i], | 819 | if (request_irq(port->irqs[i], handlers[i], |
820 | SA_INTERRUPT, desc[i], port)) { | 820 | IRQF_DISABLED, desc[i], port)) { |
821 | printk(KERN_ERR "sci: Cannot allocate irq.\n"); | 821 | printk(KERN_ERR "sci: Cannot allocate irq.\n"); |
822 | return -ENODEV; | 822 | return -ENODEV; |
823 | } | 823 | } |
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c index 73dd2eedaaad..b2cc703b2b9e 100644 --- a/drivers/serial/sunzilog.c +++ b/drivers/serial/sunzilog.c | |||
@@ -1182,7 +1182,7 @@ static int __init sunzilog_console_setup(struct console *con, char *options) | |||
1182 | return 0; | 1182 | return 0; |
1183 | } | 1183 | } |
1184 | 1184 | ||
1185 | static struct console sunzilog_console = { | 1185 | static struct console sunzilog_console_ops = { |
1186 | .name = "ttyS", | 1186 | .name = "ttyS", |
1187 | .write = sunzilog_console_write, | 1187 | .write = sunzilog_console_write, |
1188 | .device = uart_console_device, | 1188 | .device = uart_console_device, |
@@ -1208,10 +1208,10 @@ static inline struct console *SUNZILOG_CONSOLE(void) | |||
1208 | if (i == NUM_CHANNELS) | 1208 | if (i == NUM_CHANNELS) |
1209 | return NULL; | 1209 | return NULL; |
1210 | 1210 | ||
1211 | sunzilog_console.index = i; | 1211 | sunzilog_console_ops.index = i; |
1212 | sunzilog_port_table[i].flags |= SUNZILOG_FLAG_IS_CONS; | 1212 | sunzilog_port_table[i].flags |= SUNZILOG_FLAG_IS_CONS; |
1213 | 1213 | ||
1214 | return &sunzilog_console; | 1214 | return &sunzilog_console_ops; |
1215 | } | 1215 | } |
1216 | 1216 | ||
1217 | #else | 1217 | #else |
diff --git a/drivers/sn/Kconfig b/drivers/sn/Kconfig index a34731625877..c66ba9ad833d 100644 --- a/drivers/sn/Kconfig +++ b/drivers/sn/Kconfig | |||
@@ -5,19 +5,6 @@ | |||
5 | menu "SN Devices" | 5 | menu "SN Devices" |
6 | depends on SGI_SN | 6 | depends on SGI_SN |
7 | 7 | ||
8 | config SGI_IOC4 | ||
9 | tristate "SGI IOC4 Base IO support" | ||
10 | depends on MMTIMER | ||
11 | default m | ||
12 | ---help--- | ||
13 | This option enables basic support for the SGI IOC4-based Base IO | ||
14 | controller card. This option does not enable any specific | ||
15 | functions on such a card, but provides necessary infrastructure | ||
16 | for other drivers to utilize. | ||
17 | |||
18 | If you have an SGI Altix with an IOC4-based | ||
19 | I/O controller say Y. Otherwise say N. | ||
20 | |||
21 | config SGI_IOC3 | 8 | config SGI_IOC3 |
22 | tristate "SGI IOC3 Base IO support" | 9 | tristate "SGI IOC3 Base IO support" |
23 | default m | 10 | default m |
diff --git a/drivers/sn/Makefile b/drivers/sn/Makefile index 2cda011597c0..693db8bb8d9c 100644 --- a/drivers/sn/Makefile +++ b/drivers/sn/Makefile | |||
@@ -3,5 +3,4 @@ | |||
3 | # | 3 | # |
4 | # | 4 | # |
5 | 5 | ||
6 | obj-$(CONFIG_SGI_IOC4) += ioc4.o | ||
7 | obj-$(CONFIG_SGI_IOC3) += ioc3.o | 6 | obj-$(CONFIG_SGI_IOC3) += ioc3.o |
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 146298ad7371..c3c0626f550b 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c | |||
@@ -281,7 +281,6 @@ spi_register_board_info(struct spi_board_info const *info, unsigned n) | |||
281 | up(&board_lock); | 281 | up(&board_lock); |
282 | return 0; | 282 | return 0; |
283 | } | 283 | } |
284 | EXPORT_SYMBOL_GPL(spi_register_board_info); | ||
285 | 284 | ||
286 | /* FIXME someone should add support for a __setup("spi", ...) that | 285 | /* FIXME someone should add support for a __setup("spi", ...) that |
287 | * creates board info from kernel command lines | 286 | * creates board info from kernel command lines |
diff --git a/drivers/telephony/ixj.c b/drivers/telephony/ixj.c index f6b2948ab288..1b601b6cf2a2 100644 --- a/drivers/telephony/ixj.c +++ b/drivers/telephony/ixj.c | |||
@@ -284,6 +284,14 @@ static int samplerate = 100; | |||
284 | 284 | ||
285 | module_param(ixjdebug, int, 0); | 285 | module_param(ixjdebug, int, 0); |
286 | 286 | ||
287 | static struct pci_device_id ixj_pci_tbl[] __devinitdata = { | ||
288 | { PCI_VENDOR_ID_QUICKNET, PCI_DEVICE_ID_QUICKNET_XJ, | ||
289 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | ||
290 | { } | ||
291 | }; | ||
292 | |||
293 | MODULE_DEVICE_TABLE(pci, ixj_pci_tbl); | ||
294 | |||
287 | /************************************************************************ | 295 | /************************************************************************ |
288 | * | 296 | * |
289 | * ixjdebug meanings are now bit mapped instead of level based | 297 | * ixjdebug meanings are now bit mapped instead of level based |
@@ -7683,7 +7691,8 @@ static int __init ixj_probe_pci(int *cnt) | |||
7683 | IXJ *j = NULL; | 7691 | IXJ *j = NULL; |
7684 | 7692 | ||
7685 | for (i = 0; i < IXJMAX - *cnt; i++) { | 7693 | for (i = 0; i < IXJMAX - *cnt; i++) { |
7686 | pci = pci_find_device(0x15E2, 0x0500, pci); | 7694 | pci = pci_find_device(PCI_VENDOR_ID_QUICKNET, |
7695 | PCI_DEVICE_ID_QUICKNET_XJ, pci); | ||
7687 | if (!pci) | 7696 | if (!pci) |
7688 | break; | 7697 | break; |
7689 | 7698 | ||
diff --git a/drivers/telephony/ixj.h b/drivers/telephony/ixj.h index fbea4541c234..8d69bcdc29c9 100644 --- a/drivers/telephony/ixj.h +++ b/drivers/telephony/ixj.h | |||
@@ -1295,7 +1295,7 @@ typedef struct { | |||
1295 | Proc_Info_Type Info_write; | 1295 | Proc_Info_Type Info_write; |
1296 | unsigned short frame_count; | 1296 | unsigned short frame_count; |
1297 | unsigned int filter_hist[4]; | 1297 | unsigned int filter_hist[4]; |
1298 | unsigned char filter_en[4]; | 1298 | unsigned char filter_en[6]; |
1299 | unsigned short proc_load; | 1299 | unsigned short proc_load; |
1300 | unsigned long framesread; | 1300 | unsigned long framesread; |
1301 | unsigned long frameswritten; | 1301 | unsigned long frameswritten; |
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index 97d57cfc343b..825bf884537a 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile | |||
@@ -33,7 +33,6 @@ obj-$(CONFIG_USB_KBTAB) += input/ | |||
33 | obj-$(CONFIG_USB_MOUSE) += input/ | 33 | obj-$(CONFIG_USB_MOUSE) += input/ |
34 | obj-$(CONFIG_USB_MTOUCH) += input/ | 34 | obj-$(CONFIG_USB_MTOUCH) += input/ |
35 | obj-$(CONFIG_USB_POWERMATE) += input/ | 35 | obj-$(CONFIG_USB_POWERMATE) += input/ |
36 | obj-$(CONFIG_USB_TRANCEVIBRATOR)+= input/ | ||
37 | obj-$(CONFIG_USB_WACOM) += input/ | 36 | obj-$(CONFIG_USB_WACOM) += input/ |
38 | obj-$(CONFIG_USB_XPAD) += input/ | 37 | obj-$(CONFIG_USB_XPAD) += input/ |
39 | 38 | ||
@@ -66,6 +65,7 @@ obj-$(CONFIG_USB_PHIDGETSERVO) += misc/ | |||
66 | obj-$(CONFIG_USB_RIO500) += misc/ | 65 | obj-$(CONFIG_USB_RIO500) += misc/ |
67 | obj-$(CONFIG_USB_SISUSBVGA) += misc/ | 66 | obj-$(CONFIG_USB_SISUSBVGA) += misc/ |
68 | obj-$(CONFIG_USB_TEST) += misc/ | 67 | obj-$(CONFIG_USB_TEST) += misc/ |
68 | obj-$(CONFIG_USB_TRANCEVIBRATOR)+= misc/ | ||
69 | obj-$(CONFIG_USB_USS720) += misc/ | 69 | obj-$(CONFIG_USB_USS720) += misc/ |
70 | 70 | ||
71 | obj-$(CONFIG_USB_ATM) += atm/ | 71 | obj-$(CONFIG_USB_ATM) += atm/ |
diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c index 3892a9e9aee3..e6565633ba0f 100644 --- a/drivers/usb/atm/cxacru.c +++ b/drivers/usb/atm/cxacru.c | |||
@@ -793,6 +793,9 @@ static const struct usb_device_id cxacru_usb_ids[] = { | |||
793 | { /* V = Conexant P = ADSL modem */ | 793 | { /* V = Conexant P = ADSL modem */ |
794 | USB_DEVICE(0x0572, 0xcb06), .driver_info = (unsigned long) &cxacru_cb00 | 794 | USB_DEVICE(0x0572, 0xcb06), .driver_info = (unsigned long) &cxacru_cb00 |
795 | }, | 795 | }, |
796 | { /* V = Conexant P = ADSL modem (ZTE ZXDSL 852) */ | ||
797 | USB_DEVICE(0x0572, 0xcb07), .driver_info = (unsigned long) &cxacru_cb00 | ||
798 | }, | ||
796 | { /* V = Olitec P = ADSL modem version 2 */ | 799 | { /* V = Olitec P = ADSL modem version 2 */ |
797 | USB_DEVICE(0x08e3, 0x0100), .driver_info = (unsigned long) &cxacru_cafe | 800 | USB_DEVICE(0x08e3, 0x0100), .driver_info = (unsigned long) &cxacru_cafe |
798 | }, | 801 | }, |
diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c index 7c7b507af29d..c870c804470f 100644 --- a/drivers/usb/atm/speedtch.c +++ b/drivers/usb/atm/speedtch.c | |||
@@ -55,7 +55,6 @@ static const char speedtch_driver_name[] = "speedtch"; | |||
55 | #define OFFSET_d 9 /* size 4 */ | 55 | #define OFFSET_d 9 /* size 4 */ |
56 | #define OFFSET_e 13 /* size 1 */ | 56 | #define OFFSET_e 13 /* size 1 */ |
57 | #define OFFSET_f 14 /* size 1 */ | 57 | #define OFFSET_f 14 /* size 1 */ |
58 | #define TOTAL 15 | ||
59 | 58 | ||
60 | #define SIZE_7 1 | 59 | #define SIZE_7 1 |
61 | #define SIZE_b 8 | 60 | #define SIZE_b 8 |
@@ -79,6 +78,18 @@ static int dl_512_first = DEFAULT_DL_512_FIRST; | |||
79 | static int enable_isoc = DEFAULT_ENABLE_ISOC; | 78 | static int enable_isoc = DEFAULT_ENABLE_ISOC; |
80 | static int sw_buffering = DEFAULT_SW_BUFFERING; | 79 | static int sw_buffering = DEFAULT_SW_BUFFERING; |
81 | 80 | ||
81 | #define DEFAULT_B_MAX_DSL 8128 | ||
82 | #define DEFAULT_MODEM_MODE 11 | ||
83 | #define MODEM_OPTION_LENGTH 16 | ||
84 | static const unsigned char DEFAULT_MODEM_OPTION[MODEM_OPTION_LENGTH] = { | ||
85 | 0x10, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | ||
86 | }; | ||
87 | |||
88 | static unsigned int BMaxDSL = DEFAULT_B_MAX_DSL; | ||
89 | static unsigned char ModemMode = DEFAULT_MODEM_MODE; | ||
90 | static unsigned char ModemOption[MODEM_OPTION_LENGTH]; | ||
91 | static int num_ModemOption; | ||
92 | |||
82 | module_param(altsetting, uint, S_IRUGO | S_IWUSR); | 93 | module_param(altsetting, uint, S_IRUGO | S_IWUSR); |
83 | MODULE_PARM_DESC(altsetting, | 94 | MODULE_PARM_DESC(altsetting, |
84 | "Alternative setting for data interface (bulk_default: " | 95 | "Alternative setting for data interface (bulk_default: " |
@@ -100,6 +111,17 @@ MODULE_PARM_DESC(sw_buffering, | |||
100 | "Enable software buffering (default: " | 111 | "Enable software buffering (default: " |
101 | __MODULE_STRING(DEFAULT_SW_BUFFERING) ")"); | 112 | __MODULE_STRING(DEFAULT_SW_BUFFERING) ")"); |
102 | 113 | ||
114 | module_param(BMaxDSL, uint, S_IRUGO | S_IWUSR); | ||
115 | MODULE_PARM_DESC(BMaxDSL, | ||
116 | "default: " __MODULE_STRING(DEFAULT_B_MAX_DSL)); | ||
117 | |||
118 | module_param(ModemMode, byte, S_IRUGO | S_IWUSR); | ||
119 | MODULE_PARM_DESC(ModemMode, | ||
120 | "default: " __MODULE_STRING(DEFAULT_MODEM_MODE)); | ||
121 | |||
122 | module_param_array(ModemOption, byte, &num_ModemOption, S_IRUGO); | ||
123 | MODULE_PARM_DESC(ModemOption, "default: 0x10,0x00,0x00,0x00,0x20"); | ||
124 | |||
103 | #define INTERFACE_DATA 1 | 125 | #define INTERFACE_DATA 1 |
104 | #define ENDPOINT_INT 0x81 | 126 | #define ENDPOINT_INT 0x81 |
105 | #define ENDPOINT_BULK_DATA 0x07 | 127 | #define ENDPOINT_BULK_DATA 0x07 |
@@ -108,10 +130,17 @@ MODULE_PARM_DESC(sw_buffering, | |||
108 | 130 | ||
109 | #define hex2int(c) ( (c >= '0') && (c <= '9') ? (c - '0') : ((c & 0xf) + 9) ) | 131 | #define hex2int(c) ( (c >= '0') && (c <= '9') ? (c - '0') : ((c & 0xf) + 9) ) |
110 | 132 | ||
133 | struct speedtch_params { | ||
134 | unsigned int altsetting; | ||
135 | unsigned int BMaxDSL; | ||
136 | unsigned char ModemMode; | ||
137 | unsigned char ModemOption[MODEM_OPTION_LENGTH]; | ||
138 | }; | ||
139 | |||
111 | struct speedtch_instance_data { | 140 | struct speedtch_instance_data { |
112 | struct usbatm_data *usbatm; | 141 | struct usbatm_data *usbatm; |
113 | 142 | ||
114 | unsigned int altsetting; | 143 | struct speedtch_params params; /* set in probe, constant afterwards */ |
115 | 144 | ||
116 | struct work_struct status_checker; | 145 | struct work_struct status_checker; |
117 | 146 | ||
@@ -123,7 +152,7 @@ struct speedtch_instance_data { | |||
123 | struct urb *int_urb; | 152 | struct urb *int_urb; |
124 | unsigned char int_data[16]; | 153 | unsigned char int_data[16]; |
125 | 154 | ||
126 | unsigned char scratch_buffer[TOTAL]; | 155 | unsigned char scratch_buffer[16]; |
127 | }; | 156 | }; |
128 | 157 | ||
129 | /*************** | 158 | /*************** |
@@ -186,6 +215,34 @@ static void speedtch_test_sequence(struct speedtch_instance_data *instance) | |||
186 | 0x01, 0x40, 0x04, 0x00, buf, 3, CTRL_TIMEOUT); | 215 | 0x01, 0x40, 0x04, 0x00, buf, 3, CTRL_TIMEOUT); |
187 | if (ret < 0) | 216 | if (ret < 0) |
188 | usb_warn(usbatm, "%s failed on URB150: %d\n", __func__, ret); | 217 | usb_warn(usbatm, "%s failed on URB150: %d\n", __func__, ret); |
218 | |||
219 | /* Extra initialisation in recent drivers - gives higher speeds */ | ||
220 | |||
221 | /* URBext1 */ | ||
222 | buf[0] = instance->params.ModemMode; | ||
223 | ret = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), | ||
224 | 0x01, 0x40, 0x11, 0x00, buf, 1, CTRL_TIMEOUT); | ||
225 | if (ret < 0) | ||
226 | usb_warn(usbatm, "%s failed on URBext1: %d\n", __func__, ret); | ||
227 | |||
228 | /* URBext2 */ | ||
229 | /* This seems to be the one which actually triggers the higher sync | ||
230 | rate -- it does require the new firmware too, although it works OK | ||
231 | with older firmware */ | ||
232 | ret = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), | ||
233 | 0x01, 0x40, 0x14, 0x00, | ||
234 | instance->params.ModemOption, | ||
235 | MODEM_OPTION_LENGTH, CTRL_TIMEOUT); | ||
236 | if (ret < 0) | ||
237 | usb_warn(usbatm, "%s failed on URBext2: %d\n", __func__, ret); | ||
238 | |||
239 | /* URBext3 */ | ||
240 | buf[0] = instance->params.BMaxDSL & 0xff; | ||
241 | buf[1] = instance->params.BMaxDSL >> 8; | ||
242 | ret = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), | ||
243 | 0x01, 0x40, 0x12, 0x00, buf, 2, CTRL_TIMEOUT); | ||
244 | if (ret < 0) | ||
245 | usb_warn(usbatm, "%s failed on URBext3: %d\n", __func__, ret); | ||
189 | } | 246 | } |
190 | 247 | ||
191 | static int speedtch_upload_firmware(struct speedtch_instance_data *instance, | 248 | static int speedtch_upload_firmware(struct speedtch_instance_data *instance, |
@@ -285,8 +342,8 @@ static int speedtch_upload_firmware(struct speedtch_instance_data *instance, | |||
285 | because we're in our own kernel thread anyway. */ | 342 | because we're in our own kernel thread anyway. */ |
286 | msleep_interruptible(1000); | 343 | msleep_interruptible(1000); |
287 | 344 | ||
288 | if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, instance->altsetting)) < 0) { | 345 | if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, instance->params.altsetting)) < 0) { |
289 | usb_err(usbatm, "%s: setting interface to %d failed (%d)!\n", __func__, instance->altsetting, ret); | 346 | usb_err(usbatm, "%s: setting interface to %d failed (%d)!\n", __func__, instance->params.altsetting, ret); |
290 | goto out_free; | 347 | goto out_free; |
291 | } | 348 | } |
292 | 349 | ||
@@ -372,7 +429,7 @@ static int speedtch_read_status(struct speedtch_instance_data *instance) | |||
372 | unsigned char *buf = instance->scratch_buffer; | 429 | unsigned char *buf = instance->scratch_buffer; |
373 | int ret; | 430 | int ret; |
374 | 431 | ||
375 | memset(buf, 0, TOTAL); | 432 | memset(buf, 0, 16); |
376 | 433 | ||
377 | ret = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), | 434 | ret = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), |
378 | 0x12, 0xc0, 0x07, 0x00, buf + OFFSET_7, SIZE_7, | 435 | 0x12, 0xc0, 0x07, 0x00, buf + OFFSET_7, SIZE_7, |
@@ -746,17 +803,21 @@ static int speedtch_bind(struct usbatm_data *usbatm, | |||
746 | 803 | ||
747 | instance->usbatm = usbatm; | 804 | instance->usbatm = usbatm; |
748 | 805 | ||
749 | /* altsetting and enable_isoc may change at any moment, so take a snapshot */ | 806 | /* module parameters may change at any moment, so take a snapshot */ |
750 | instance->altsetting = altsetting; | 807 | instance->params.altsetting = altsetting; |
808 | instance->params.BMaxDSL = BMaxDSL; | ||
809 | instance->params.ModemMode = ModemMode; | ||
810 | memcpy(instance->params.ModemOption, DEFAULT_MODEM_OPTION, MODEM_OPTION_LENGTH); | ||
811 | memcpy(instance->params.ModemOption, ModemOption, num_ModemOption); | ||
751 | use_isoc = enable_isoc; | 812 | use_isoc = enable_isoc; |
752 | 813 | ||
753 | if (instance->altsetting) | 814 | if (instance->params.altsetting) |
754 | if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, instance->altsetting)) < 0) { | 815 | if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, instance->params.altsetting)) < 0) { |
755 | usb_err(usbatm, "%s: setting interface to %2d failed (%d)!\n", __func__, instance->altsetting, ret); | 816 | usb_err(usbatm, "%s: setting interface to %2d failed (%d)!\n", __func__, instance->params.altsetting, ret); |
756 | instance->altsetting = 0; /* fall back to default */ | 817 | instance->params.altsetting = 0; /* fall back to default */ |
757 | } | 818 | } |
758 | 819 | ||
759 | if (!instance->altsetting && use_isoc) | 820 | if (!instance->params.altsetting && use_isoc) |
760 | if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, DEFAULT_ISOC_ALTSETTING)) < 0) { | 821 | if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, DEFAULT_ISOC_ALTSETTING)) < 0) { |
761 | usb_dbg(usbatm, "%s: setting interface to %2d failed (%d)!\n", __func__, DEFAULT_ISOC_ALTSETTING, ret); | 822 | usb_dbg(usbatm, "%s: setting interface to %2d failed (%d)!\n", __func__, DEFAULT_ISOC_ALTSETTING, ret); |
762 | use_isoc = 0; /* fall back to bulk */ | 823 | use_isoc = 0; /* fall back to bulk */ |
@@ -783,14 +844,14 @@ static int speedtch_bind(struct usbatm_data *usbatm, | |||
783 | usb_info(usbatm, "isochronous transfer not supported - using bulk\n"); | 844 | usb_info(usbatm, "isochronous transfer not supported - using bulk\n"); |
784 | } | 845 | } |
785 | 846 | ||
786 | if (!use_isoc && !instance->altsetting) | 847 | if (!use_isoc && !instance->params.altsetting) |
787 | if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, DEFAULT_BULK_ALTSETTING)) < 0) { | 848 | if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, DEFAULT_BULK_ALTSETTING)) < 0) { |
788 | usb_err(usbatm, "%s: setting interface to %2d failed (%d)!\n", __func__, DEFAULT_BULK_ALTSETTING, ret); | 849 | usb_err(usbatm, "%s: setting interface to %2d failed (%d)!\n", __func__, DEFAULT_BULK_ALTSETTING, ret); |
789 | goto fail_free; | 850 | goto fail_free; |
790 | } | 851 | } |
791 | 852 | ||
792 | if (!instance->altsetting) | 853 | if (!instance->params.altsetting) |
793 | instance->altsetting = use_isoc ? DEFAULT_ISOC_ALTSETTING : DEFAULT_BULK_ALTSETTING; | 854 | instance->params.altsetting = use_isoc ? DEFAULT_ISOC_ALTSETTING : DEFAULT_BULK_ALTSETTING; |
794 | 855 | ||
795 | usbatm->flags |= (use_isoc ? UDSL_USE_ISOC : 0); | 856 | usbatm->flags |= (use_isoc ? UDSL_USE_ISOC : 0); |
796 | 857 | ||
diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c index f5434b1cbb1e..f6b9f7e1f716 100644 --- a/drivers/usb/atm/ueagle-atm.c +++ b/drivers/usb/atm/ueagle-atm.c | |||
@@ -68,7 +68,7 @@ | |||
68 | 68 | ||
69 | #include "usbatm.h" | 69 | #include "usbatm.h" |
70 | 70 | ||
71 | #define EAGLEUSBVERSION "ueagle 1.3" | 71 | #define EAGLEUSBVERSION "ueagle 1.4" |
72 | 72 | ||
73 | 73 | ||
74 | /* | 74 | /* |
@@ -80,14 +80,14 @@ | |||
80 | dev_dbg(&(usb_dev)->dev, \ | 80 | dev_dbg(&(usb_dev)->dev, \ |
81 | "[ueagle-atm dbg] %s: " format, \ | 81 | "[ueagle-atm dbg] %s: " format, \ |
82 | __FUNCTION__, ##args); \ | 82 | __FUNCTION__, ##args); \ |
83 | } while (0) | 83 | } while (0) |
84 | 84 | ||
85 | #define uea_vdbg(usb_dev, format, args...) \ | 85 | #define uea_vdbg(usb_dev, format, args...) \ |
86 | do { \ | 86 | do { \ |
87 | if (debug >= 2) \ | 87 | if (debug >= 2) \ |
88 | dev_dbg(&(usb_dev)->dev, \ | 88 | dev_dbg(&(usb_dev)->dev, \ |
89 | "[ueagle-atm vdbg] " format, ##args); \ | 89 | "[ueagle-atm vdbg] " format, ##args); \ |
90 | } while (0) | 90 | } while (0) |
91 | 91 | ||
92 | #define uea_enters(usb_dev) \ | 92 | #define uea_enters(usb_dev) \ |
93 | uea_vdbg(usb_dev, "entering %s\n", __FUNCTION__) | 93 | uea_vdbg(usb_dev, "entering %s\n", __FUNCTION__) |
@@ -218,8 +218,8 @@ enum { | |||
218 | #define UEA_CHIP_VERSION(x) \ | 218 | #define UEA_CHIP_VERSION(x) \ |
219 | ((x)->driver_info & 0xf) | 219 | ((x)->driver_info & 0xf) |
220 | 220 | ||
221 | #define IS_ISDN(sc) \ | 221 | #define IS_ISDN(usb_dev) \ |
222 | (le16_to_cpu(sc->usb_dev->descriptor.bcdDevice) & 0x80) | 222 | (le16_to_cpu((usb_dev)->descriptor.bcdDevice) & 0x80) |
223 | 223 | ||
224 | #define INS_TO_USBDEV(ins) ins->usb_dev | 224 | #define INS_TO_USBDEV(ins) ins->usb_dev |
225 | 225 | ||
@@ -625,12 +625,12 @@ static int request_dsp(struct uea_softc *sc) | |||
625 | char *dsp_name; | 625 | char *dsp_name; |
626 | 626 | ||
627 | if (UEA_CHIP_VERSION(sc) == ADI930) { | 627 | if (UEA_CHIP_VERSION(sc) == ADI930) { |
628 | if (IS_ISDN(sc)) | 628 | if (IS_ISDN(sc->usb_dev)) |
629 | dsp_name = FW_DIR "DSP9i.bin"; | 629 | dsp_name = FW_DIR "DSP9i.bin"; |
630 | else | 630 | else |
631 | dsp_name = FW_DIR "DSP9p.bin"; | 631 | dsp_name = FW_DIR "DSP9p.bin"; |
632 | } else { | 632 | } else { |
633 | if (IS_ISDN(sc)) | 633 | if (IS_ISDN(sc->usb_dev)) |
634 | dsp_name = FW_DIR "DSPei.bin"; | 634 | dsp_name = FW_DIR "DSPei.bin"; |
635 | else | 635 | else |
636 | dsp_name = FW_DIR "DSPep.bin"; | 636 | dsp_name = FW_DIR "DSPep.bin"; |
@@ -744,7 +744,7 @@ static inline void wake_up_cmv_ack(struct uea_softc *sc) | |||
744 | 744 | ||
745 | static inline int wait_cmv_ack(struct uea_softc *sc) | 745 | static inline int wait_cmv_ack(struct uea_softc *sc) |
746 | { | 746 | { |
747 | int ret = wait_event_timeout(sc->cmv_ack_wait, | 747 | int ret = wait_event_interruptible_timeout(sc->cmv_ack_wait, |
748 | sc->cmv_ack, ACK_TIMEOUT); | 748 | sc->cmv_ack, ACK_TIMEOUT); |
749 | sc->cmv_ack = 0; | 749 | sc->cmv_ack = 0; |
750 | 750 | ||
@@ -885,7 +885,8 @@ static int uea_stat(struct uea_softc *sc) | |||
885 | break; | 885 | break; |
886 | 886 | ||
887 | case 3: /* fail ... */ | 887 | case 3: /* fail ... */ |
888 | uea_info(INS_TO_USBDEV(sc), "modem synchronization failed\n"); | 888 | uea_info(INS_TO_USBDEV(sc), "modem synchronization failed" |
889 | " (may be try other cmv/dsp)\n"); | ||
889 | return -EAGAIN; | 890 | return -EAGAIN; |
890 | 891 | ||
891 | case 4 ... 6: /* test state */ | 892 | case 4 ... 6: /* test state */ |
@@ -913,12 +914,6 @@ static int uea_stat(struct uea_softc *sc) | |||
913 | release_firmware(sc->dsp_firm); | 914 | release_firmware(sc->dsp_firm); |
914 | sc->dsp_firm = NULL; | 915 | sc->dsp_firm = NULL; |
915 | } | 916 | } |
916 | |||
917 | ret = uea_read_cmv(sc, SA_INFO, 10, &sc->stats.phy.firmid); | ||
918 | if (ret < 0) | ||
919 | return ret; | ||
920 | uea_info(INS_TO_USBDEV(sc), "ATU-R firmware version : %x\n", | ||
921 | sc->stats.phy.firmid); | ||
922 | } | 917 | } |
923 | 918 | ||
924 | /* always update it as atm layer could not be init when we switch to | 919 | /* always update it as atm layer could not be init when we switch to |
@@ -1033,9 +1028,9 @@ static int request_cmvs(struct uea_softc *sc, | |||
1033 | 1028 | ||
1034 | if (cmv_file[sc->modem_index] == NULL) { | 1029 | if (cmv_file[sc->modem_index] == NULL) { |
1035 | if (UEA_CHIP_VERSION(sc) == ADI930) | 1030 | if (UEA_CHIP_VERSION(sc) == ADI930) |
1036 | file = (IS_ISDN(sc)) ? "CMV9i.bin" : "CMV9p.bin"; | 1031 | file = (IS_ISDN(sc->usb_dev)) ? "CMV9i.bin" : "CMV9p.bin"; |
1037 | else | 1032 | else |
1038 | file = (IS_ISDN(sc)) ? "CMVei.bin" : "CMVep.bin"; | 1033 | file = (IS_ISDN(sc->usb_dev)) ? "CMVei.bin" : "CMVep.bin"; |
1039 | } else | 1034 | } else |
1040 | file = cmv_file[sc->modem_index]; | 1035 | file = cmv_file[sc->modem_index]; |
1041 | 1036 | ||
@@ -1131,6 +1126,13 @@ static int uea_start_reset(struct uea_softc *sc) | |||
1131 | if (ret < 0) | 1126 | if (ret < 0) |
1132 | return ret; | 1127 | return ret; |
1133 | 1128 | ||
1129 | /* Dump firmware version */ | ||
1130 | ret = uea_read_cmv(sc, SA_INFO, 10, &sc->stats.phy.firmid); | ||
1131 | if (ret < 0) | ||
1132 | return ret; | ||
1133 | uea_info(INS_TO_USBDEV(sc), "ATU-R firmware version : %x\n", | ||
1134 | sc->stats.phy.firmid); | ||
1135 | |||
1134 | /* get options */ | 1136 | /* get options */ |
1135 | ret = len = request_cmvs(sc, &cmvs, &cmvs_fw); | 1137 | ret = len = request_cmvs(sc, &cmvs, &cmvs_fw); |
1136 | if (ret < 0) | 1138 | if (ret < 0) |
@@ -1147,6 +1149,8 @@ static int uea_start_reset(struct uea_softc *sc) | |||
1147 | /* Enter in R-ACT-REQ */ | 1149 | /* Enter in R-ACT-REQ */ |
1148 | ret = uea_write_cmv(sc, SA_CNTL, 0, 2); | 1150 | ret = uea_write_cmv(sc, SA_CNTL, 0, 2); |
1149 | uea_vdbg(INS_TO_USBDEV(sc), "Entering in R-ACT-REQ state\n"); | 1151 | uea_vdbg(INS_TO_USBDEV(sc), "Entering in R-ACT-REQ state\n"); |
1152 | uea_info(INS_TO_USBDEV(sc), "Modem started, " | ||
1153 | "waiting synchronization\n"); | ||
1150 | out: | 1154 | out: |
1151 | release_firmware(cmvs_fw); | 1155 | release_firmware(cmvs_fw); |
1152 | sc->reset = 0; | 1156 | sc->reset = 0; |
@@ -1172,7 +1176,10 @@ static int uea_kthread(void *data) | |||
1172 | if (!ret) | 1176 | if (!ret) |
1173 | ret = uea_stat(sc); | 1177 | ret = uea_stat(sc); |
1174 | if (ret != -EAGAIN) | 1178 | if (ret != -EAGAIN) |
1175 | msleep(1000); | 1179 | msleep_interruptible(1000); |
1180 | if (try_to_freeze()) | ||
1181 | uea_err(INS_TO_USBDEV(sc), "suspend/resume not supported, " | ||
1182 | "please unplug/replug your modem\n"); | ||
1176 | } | 1183 | } |
1177 | uea_leaves(INS_TO_USBDEV(sc)); | 1184 | uea_leaves(INS_TO_USBDEV(sc)); |
1178 | return ret; | 1185 | return ret; |
@@ -1566,6 +1573,7 @@ UEA_ATTR(uscorr, 0); | |||
1566 | UEA_ATTR(dscorr, 0); | 1573 | UEA_ATTR(dscorr, 0); |
1567 | UEA_ATTR(usunc, 0); | 1574 | UEA_ATTR(usunc, 0); |
1568 | UEA_ATTR(dsunc, 0); | 1575 | UEA_ATTR(dsunc, 0); |
1576 | UEA_ATTR(firmid, 0); | ||
1569 | 1577 | ||
1570 | /* Retrieve the device End System Identifier (MAC) */ | 1578 | /* Retrieve the device End System Identifier (MAC) */ |
1571 | 1579 | ||
@@ -1597,7 +1605,7 @@ static int uea_heavy(struct usbatm_data *usbatm, struct usb_interface *intf) | |||
1597 | { | 1605 | { |
1598 | struct uea_softc *sc = usbatm->driver_data; | 1606 | struct uea_softc *sc = usbatm->driver_data; |
1599 | 1607 | ||
1600 | wait_event(sc->sync_q, IS_OPERATIONAL(sc)); | 1608 | wait_event_interruptible(sc->sync_q, IS_OPERATIONAL(sc)); |
1601 | 1609 | ||
1602 | return 0; | 1610 | return 0; |
1603 | 1611 | ||
@@ -1639,16 +1647,13 @@ static struct attribute *attrs[] = { | |||
1639 | &dev_attr_stat_dscorr.attr, | 1647 | &dev_attr_stat_dscorr.attr, |
1640 | &dev_attr_stat_usunc.attr, | 1648 | &dev_attr_stat_usunc.attr, |
1641 | &dev_attr_stat_dsunc.attr, | 1649 | &dev_attr_stat_dsunc.attr, |
1650 | &dev_attr_stat_firmid.attr, | ||
1651 | NULL, | ||
1642 | }; | 1652 | }; |
1643 | static struct attribute_group attr_grp = { | 1653 | static struct attribute_group attr_grp = { |
1644 | .attrs = attrs, | 1654 | .attrs = attrs, |
1645 | }; | 1655 | }; |
1646 | 1656 | ||
1647 | static int create_fs_entries(struct usb_interface *intf) | ||
1648 | { | ||
1649 | return sysfs_create_group(&intf->dev.kobj, &attr_grp); | ||
1650 | } | ||
1651 | |||
1652 | static int uea_bind(struct usbatm_data *usbatm, struct usb_interface *intf, | 1657 | static int uea_bind(struct usbatm_data *usbatm, struct usb_interface *intf, |
1653 | const struct usb_device_id *id) | 1658 | const struct usb_device_id *id) |
1654 | { | 1659 | { |
@@ -1708,31 +1713,25 @@ static int uea_bind(struct usbatm_data *usbatm, struct usb_interface *intf, | |||
1708 | } | 1713 | } |
1709 | } | 1714 | } |
1710 | 1715 | ||
1716 | ret = sysfs_create_group(&intf->dev.kobj, &attr_grp); | ||
1717 | if (ret < 0) | ||
1718 | goto error; | ||
1719 | |||
1711 | ret = uea_boot(sc); | 1720 | ret = uea_boot(sc); |
1712 | if (ret < 0) { | 1721 | if (ret < 0) |
1713 | kfree(sc); | 1722 | goto error; |
1714 | return ret; | ||
1715 | } | ||
1716 | 1723 | ||
1717 | ret = create_fs_entries(intf); | ||
1718 | if (ret) { | ||
1719 | uea_stop(sc); | ||
1720 | kfree(sc); | ||
1721 | return ret; | ||
1722 | } | ||
1723 | return 0; | 1724 | return 0; |
1724 | } | 1725 | error: |
1725 | 1726 | kfree(sc); | |
1726 | static void destroy_fs_entries(struct usb_interface *intf) | 1727 | return ret; |
1727 | { | ||
1728 | sysfs_remove_group(&intf->dev.kobj, &attr_grp); | ||
1729 | } | 1728 | } |
1730 | 1729 | ||
1731 | static void uea_unbind(struct usbatm_data *usbatm, struct usb_interface *intf) | 1730 | static void uea_unbind(struct usbatm_data *usbatm, struct usb_interface *intf) |
1732 | { | 1731 | { |
1733 | struct uea_softc *sc = usbatm->driver_data; | 1732 | struct uea_softc *sc = usbatm->driver_data; |
1734 | 1733 | ||
1735 | destroy_fs_entries(intf); | 1734 | sysfs_remove_group(&intf->dev.kobj, &attr_grp); |
1736 | uea_stop(sc); | 1735 | uea_stop(sc); |
1737 | kfree(sc); | 1736 | kfree(sc); |
1738 | } | 1737 | } |
@@ -1753,10 +1752,10 @@ static int uea_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
1753 | struct usb_device *usb = interface_to_usbdev(intf); | 1752 | struct usb_device *usb = interface_to_usbdev(intf); |
1754 | 1753 | ||
1755 | uea_enters(usb); | 1754 | uea_enters(usb); |
1756 | uea_info(usb, "ADSL device founded vid (%#X) pid (%#X) : %s\n", | 1755 | uea_info(usb, "ADSL device founded vid (%#X) pid (%#X) : %s %s\n", |
1757 | le16_to_cpu(usb->descriptor.idVendor), | 1756 | le16_to_cpu(usb->descriptor.idVendor), |
1758 | le16_to_cpu(usb->descriptor.idProduct), | 1757 | le16_to_cpu(usb->descriptor.idProduct), |
1759 | chip_name[UEA_CHIP_VERSION(id)]); | 1758 | chip_name[UEA_CHIP_VERSION(id)], IS_ISDN(usb)?"isdn":"pots"); |
1760 | 1759 | ||
1761 | usb_reset_device(usb); | 1760 | usb_reset_device(usb); |
1762 | 1761 | ||
diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c index 309073f6433a..ec63b0ee0743 100644 --- a/drivers/usb/atm/usbatm.c +++ b/drivers/usb/atm/usbatm.c | |||
@@ -1001,6 +1001,7 @@ static int usbatm_do_heavy_init(void *arg) | |||
1001 | 1001 | ||
1002 | daemonize(instance->driver->driver_name); | 1002 | daemonize(instance->driver->driver_name); |
1003 | allow_signal(SIGTERM); | 1003 | allow_signal(SIGTERM); |
1004 | instance->thread_pid = current->pid; | ||
1004 | 1005 | ||
1005 | complete(&instance->thread_started); | 1006 | complete(&instance->thread_started); |
1006 | 1007 | ||
@@ -1025,10 +1026,6 @@ static int usbatm_heavy_init(struct usbatm_data *instance) | |||
1025 | return ret; | 1026 | return ret; |
1026 | } | 1027 | } |
1027 | 1028 | ||
1028 | mutex_lock(&instance->serialize); | ||
1029 | instance->thread_pid = ret; | ||
1030 | mutex_unlock(&instance->serialize); | ||
1031 | |||
1032 | wait_for_completion(&instance->thread_started); | 1029 | wait_for_completion(&instance->thread_started); |
1033 | 1030 | ||
1034 | return 0; | 1031 | return 0; |
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index ec4d1d756725..9a9012fd284b 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
@@ -325,7 +325,7 @@ static void acm_rx_tasklet(unsigned long _acm) | |||
325 | struct acm_rb *buf; | 325 | struct acm_rb *buf; |
326 | struct tty_struct *tty = acm->tty; | 326 | struct tty_struct *tty = acm->tty; |
327 | struct acm_ru *rcv; | 327 | struct acm_ru *rcv; |
328 | //unsigned long flags; | 328 | unsigned long flags; |
329 | int i = 0; | 329 | int i = 0; |
330 | dbg("Entering acm_rx_tasklet"); | 330 | dbg("Entering acm_rx_tasklet"); |
331 | 331 | ||
@@ -333,15 +333,15 @@ static void acm_rx_tasklet(unsigned long _acm) | |||
333 | return; | 333 | return; |
334 | 334 | ||
335 | next_buffer: | 335 | next_buffer: |
336 | spin_lock(&acm->read_lock); | 336 | spin_lock_irqsave(&acm->read_lock, flags); |
337 | if (list_empty(&acm->filled_read_bufs)) { | 337 | if (list_empty(&acm->filled_read_bufs)) { |
338 | spin_unlock(&acm->read_lock); | 338 | spin_unlock_irqrestore(&acm->read_lock, flags); |
339 | goto urbs; | 339 | goto urbs; |
340 | } | 340 | } |
341 | buf = list_entry(acm->filled_read_bufs.next, | 341 | buf = list_entry(acm->filled_read_bufs.next, |
342 | struct acm_rb, list); | 342 | struct acm_rb, list); |
343 | list_del(&buf->list); | 343 | list_del(&buf->list); |
344 | spin_unlock(&acm->read_lock); | 344 | spin_unlock_irqrestore(&acm->read_lock, flags); |
345 | 345 | ||
346 | dbg("acm_rx_tasklet: procesing buf 0x%p, size = %d", buf, buf->size); | 346 | dbg("acm_rx_tasklet: procesing buf 0x%p, size = %d", buf, buf->size); |
347 | 347 | ||
@@ -356,29 +356,29 @@ next_buffer: | |||
356 | memmove(buf->base, buf->base + i, buf->size - i); | 356 | memmove(buf->base, buf->base + i, buf->size - i); |
357 | buf->size -= i; | 357 | buf->size -= i; |
358 | spin_unlock(&acm->throttle_lock); | 358 | spin_unlock(&acm->throttle_lock); |
359 | spin_lock(&acm->read_lock); | 359 | spin_lock_irqsave(&acm->read_lock, flags); |
360 | list_add(&buf->list, &acm->filled_read_bufs); | 360 | list_add(&buf->list, &acm->filled_read_bufs); |
361 | spin_unlock(&acm->read_lock); | 361 | spin_unlock_irqrestore(&acm->read_lock, flags); |
362 | return; | 362 | return; |
363 | } | 363 | } |
364 | spin_unlock(&acm->throttle_lock); | 364 | spin_unlock(&acm->throttle_lock); |
365 | 365 | ||
366 | spin_lock(&acm->read_lock); | 366 | spin_lock_irqsave(&acm->read_lock, flags); |
367 | list_add(&buf->list, &acm->spare_read_bufs); | 367 | list_add(&buf->list, &acm->spare_read_bufs); |
368 | spin_unlock(&acm->read_lock); | 368 | spin_unlock_irqrestore(&acm->read_lock, flags); |
369 | goto next_buffer; | 369 | goto next_buffer; |
370 | 370 | ||
371 | urbs: | 371 | urbs: |
372 | while (!list_empty(&acm->spare_read_bufs)) { | 372 | while (!list_empty(&acm->spare_read_bufs)) { |
373 | spin_lock(&acm->read_lock); | 373 | spin_lock_irqsave(&acm->read_lock, flags); |
374 | if (list_empty(&acm->spare_read_urbs)) { | 374 | if (list_empty(&acm->spare_read_urbs)) { |
375 | spin_unlock(&acm->read_lock); | 375 | spin_unlock_irqrestore(&acm->read_lock, flags); |
376 | return; | 376 | return; |
377 | } | 377 | } |
378 | rcv = list_entry(acm->spare_read_urbs.next, | 378 | rcv = list_entry(acm->spare_read_urbs.next, |
379 | struct acm_ru, list); | 379 | struct acm_ru, list); |
380 | list_del(&rcv->list); | 380 | list_del(&rcv->list); |
381 | spin_unlock(&acm->read_lock); | 381 | spin_unlock_irqrestore(&acm->read_lock, flags); |
382 | 382 | ||
383 | buf = list_entry(acm->spare_read_bufs.next, | 383 | buf = list_entry(acm->spare_read_bufs.next, |
384 | struct acm_rb, list); | 384 | struct acm_rb, list); |
@@ -400,9 +400,9 @@ urbs: | |||
400 | free-urbs-pool and resubmited ASAP */ | 400 | free-urbs-pool and resubmited ASAP */ |
401 | if (usb_submit_urb(rcv->urb, GFP_ATOMIC) < 0) { | 401 | if (usb_submit_urb(rcv->urb, GFP_ATOMIC) < 0) { |
402 | list_add(&buf->list, &acm->spare_read_bufs); | 402 | list_add(&buf->list, &acm->spare_read_bufs); |
403 | spin_lock(&acm->read_lock); | 403 | spin_lock_irqsave(&acm->read_lock, flags); |
404 | list_add(&rcv->list, &acm->spare_read_urbs); | 404 | list_add(&rcv->list, &acm->spare_read_urbs); |
405 | spin_unlock(&acm->read_lock); | 405 | spin_unlock_irqrestore(&acm->read_lock, flags); |
406 | return; | 406 | return; |
407 | } | 407 | } |
408 | } | 408 | } |
@@ -1083,6 +1083,9 @@ static struct usb_device_id acm_ids[] = { | |||
1083 | { USB_DEVICE(0x0482, 0x0203), /* KYOCERA AH-K3001V */ | 1083 | { USB_DEVICE(0x0482, 0x0203), /* KYOCERA AH-K3001V */ |
1084 | .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ | 1084 | .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ |
1085 | }, | 1085 | }, |
1086 | { USB_DEVICE(0x079b, 0x000f), /* BT On-Air USB MODEM */ | ||
1087 | .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ | ||
1088 | }, | ||
1086 | { USB_DEVICE(0x0ace, 0x1608), /* ZyDAS 56K USB MODEM */ | 1089 | { USB_DEVICE(0x0ace, 0x1608), /* ZyDAS 56K USB MODEM */ |
1087 | .driver_info = SINGLE_RX_URB, /* firmware bug */ | 1090 | .driver_info = SINGLE_RX_URB, /* firmware bug */ |
1088 | }, | 1091 | }, |
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c index a161d70e1e42..6303970e93c1 100644 --- a/drivers/usb/class/usblp.c +++ b/drivers/usb/class/usblp.c | |||
@@ -154,6 +154,7 @@ struct usblp { | |||
154 | unsigned char used; /* True if open */ | 154 | unsigned char used; /* True if open */ |
155 | unsigned char present; /* True if not disconnected */ | 155 | unsigned char present; /* True if not disconnected */ |
156 | unsigned char bidir; /* interface is bidirectional */ | 156 | unsigned char bidir; /* interface is bidirectional */ |
157 | unsigned char sleeping; /* interface is suspended */ | ||
157 | unsigned char *device_id_string; /* IEEE 1284 DEVICE ID string (ptr) */ | 158 | unsigned char *device_id_string; /* IEEE 1284 DEVICE ID string (ptr) */ |
158 | /* first 2 bytes are (big-endian) length */ | 159 | /* first 2 bytes are (big-endian) length */ |
159 | }; | 160 | }; |
@@ -183,6 +184,7 @@ static void usblp_dump(struct usblp *usblp) { | |||
183 | dbg("quirks=%d", usblp->quirks); | 184 | dbg("quirks=%d", usblp->quirks); |
184 | dbg("used=%d", usblp->used); | 185 | dbg("used=%d", usblp->used); |
185 | dbg("bidir=%d", usblp->bidir); | 186 | dbg("bidir=%d", usblp->bidir); |
187 | dbg("sleeping=%d", usblp->sleeping); | ||
186 | dbg("device_id_string=\"%s\"", | 188 | dbg("device_id_string=\"%s\"", |
187 | usblp->device_id_string ? | 189 | usblp->device_id_string ? |
188 | usblp->device_id_string + 2 : | 190 | usblp->device_id_string + 2 : |
@@ -338,6 +340,20 @@ static int usblp_check_status(struct usblp *usblp, int err) | |||
338 | return newerr; | 340 | return newerr; |
339 | } | 341 | } |
340 | 342 | ||
343 | static int handle_bidir (struct usblp *usblp) | ||
344 | { | ||
345 | if (usblp->bidir && usblp->used && !usblp->sleeping) { | ||
346 | usblp->readcount = 0; | ||
347 | usblp->readurb->dev = usblp->dev; | ||
348 | if (usb_submit_urb(usblp->readurb, GFP_KERNEL) < 0) { | ||
349 | usblp->used = 0; | ||
350 | return -EIO; | ||
351 | } | ||
352 | } | ||
353 | |||
354 | return 0; | ||
355 | } | ||
356 | |||
341 | /* | 357 | /* |
342 | * File op functions. | 358 | * File op functions. |
343 | */ | 359 | */ |
@@ -390,14 +406,9 @@ static int usblp_open(struct inode *inode, struct file *file) | |||
390 | usblp->writeurb->status = 0; | 406 | usblp->writeurb->status = 0; |
391 | usblp->readurb->status = 0; | 407 | usblp->readurb->status = 0; |
392 | 408 | ||
393 | if (usblp->bidir) { | 409 | if (handle_bidir(usblp) < 0) { |
394 | usblp->readcount = 0; | 410 | file->private_data = NULL; |
395 | usblp->readurb->dev = usblp->dev; | 411 | retval = -EIO; |
396 | if (usb_submit_urb(usblp->readurb, GFP_KERNEL) < 0) { | ||
397 | retval = -EIO; | ||
398 | usblp->used = 0; | ||
399 | file->private_data = NULL; | ||
400 | } | ||
401 | } | 412 | } |
402 | out: | 413 | out: |
403 | mutex_unlock (&usblp_mutex); | 414 | mutex_unlock (&usblp_mutex); |
@@ -460,6 +471,11 @@ static long usblp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
460 | goto done; | 471 | goto done; |
461 | } | 472 | } |
462 | 473 | ||
474 | if (usblp->sleeping) { | ||
475 | retval = -ENODEV; | ||
476 | goto done; | ||
477 | } | ||
478 | |||
463 | dbg("usblp_ioctl: cmd=0x%x (%c nr=%d len=%d dir=%d)", cmd, _IOC_TYPE(cmd), | 479 | dbg("usblp_ioctl: cmd=0x%x (%c nr=%d len=%d dir=%d)", cmd, _IOC_TYPE(cmd), |
464 | _IOC_NR(cmd), _IOC_SIZE(cmd), _IOC_DIR(cmd) ); | 480 | _IOC_NR(cmd), _IOC_SIZE(cmd), _IOC_DIR(cmd) ); |
465 | 481 | ||
@@ -658,6 +674,11 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t | |||
658 | return -ENODEV; | 674 | return -ENODEV; |
659 | } | 675 | } |
660 | 676 | ||
677 | if (usblp->sleeping) { | ||
678 | up (&usblp->sem); | ||
679 | return writecount ? writecount : -ENODEV; | ||
680 | } | ||
681 | |||
661 | if (usblp->writeurb->status != 0) { | 682 | if (usblp->writeurb->status != 0) { |
662 | if (usblp->quirks & USBLP_QUIRK_BIDIR) { | 683 | if (usblp->quirks & USBLP_QUIRK_BIDIR) { |
663 | if (!usblp->wcomplete) | 684 | if (!usblp->wcomplete) |
@@ -701,6 +722,7 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t | |||
701 | usblp->wcomplete = 0; | 722 | usblp->wcomplete = 0; |
702 | err = usb_submit_urb(usblp->writeurb, GFP_KERNEL); | 723 | err = usb_submit_urb(usblp->writeurb, GFP_KERNEL); |
703 | if (err) { | 724 | if (err) { |
725 | usblp->wcomplete = 1; | ||
704 | if (err != -ENOMEM) | 726 | if (err != -ENOMEM) |
705 | count = -EIO; | 727 | count = -EIO; |
706 | else | 728 | else |
@@ -749,6 +771,11 @@ static ssize_t usblp_read(struct file *file, char __user *buffer, size_t count, | |||
749 | goto done; | 771 | goto done; |
750 | } | 772 | } |
751 | 773 | ||
774 | if (usblp->sleeping) { | ||
775 | count = -ENODEV; | ||
776 | goto done; | ||
777 | } | ||
778 | |||
752 | if (usblp->readurb->status) { | 779 | if (usblp->readurb->status) { |
753 | err("usblp%d: error %d reading from printer", | 780 | err("usblp%d: error %d reading from printer", |
754 | usblp->minor, usblp->readurb->status); | 781 | usblp->minor, usblp->readurb->status); |
@@ -1167,6 +1194,39 @@ static void usblp_disconnect(struct usb_interface *intf) | |||
1167 | mutex_unlock (&usblp_mutex); | 1194 | mutex_unlock (&usblp_mutex); |
1168 | } | 1195 | } |
1169 | 1196 | ||
1197 | static int usblp_suspend (struct usb_interface *intf, pm_message_t message) | ||
1198 | { | ||
1199 | struct usblp *usblp = usb_get_intfdata (intf); | ||
1200 | |||
1201 | /* this races against normal access and open */ | ||
1202 | mutex_lock (&usblp_mutex); | ||
1203 | down (&usblp->sem); | ||
1204 | /* we take no more IO */ | ||
1205 | usblp->sleeping = 1; | ||
1206 | usblp_unlink_urbs(usblp); | ||
1207 | up (&usblp->sem); | ||
1208 | mutex_unlock (&usblp_mutex); | ||
1209 | |||
1210 | return 0; | ||
1211 | } | ||
1212 | |||
1213 | static int usblp_resume (struct usb_interface *intf) | ||
1214 | { | ||
1215 | struct usblp *usblp = usb_get_intfdata (intf); | ||
1216 | int r; | ||
1217 | |||
1218 | mutex_lock (&usblp_mutex); | ||
1219 | down (&usblp->sem); | ||
1220 | |||
1221 | usblp->sleeping = 0; | ||
1222 | r = handle_bidir (usblp); | ||
1223 | |||
1224 | up (&usblp->sem); | ||
1225 | mutex_unlock (&usblp_mutex); | ||
1226 | |||
1227 | return r; | ||
1228 | } | ||
1229 | |||
1170 | static struct usb_device_id usblp_ids [] = { | 1230 | static struct usb_device_id usblp_ids [] = { |
1171 | { USB_DEVICE_INFO(7, 1, 1) }, | 1231 | { USB_DEVICE_INFO(7, 1, 1) }, |
1172 | { USB_DEVICE_INFO(7, 1, 2) }, | 1232 | { USB_DEVICE_INFO(7, 1, 2) }, |
@@ -1183,6 +1243,8 @@ static struct usb_driver usblp_driver = { | |||
1183 | .name = "usblp", | 1243 | .name = "usblp", |
1184 | .probe = usblp_probe, | 1244 | .probe = usblp_probe, |
1185 | .disconnect = usblp_disconnect, | 1245 | .disconnect = usblp_disconnect, |
1246 | .suspend = usblp_suspend, | ||
1247 | .resume = usblp_resume, | ||
1186 | .id_table = usblp_ids, | 1248 | .id_table = usblp_ids, |
1187 | }; | 1249 | }; |
1188 | 1250 | ||
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 724822cac2b1..fed92be63b5e 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c | |||
@@ -1588,15 +1588,18 @@ const struct file_operations usbfs_device_file_operations = { | |||
1588 | .release = usbdev_release, | 1588 | .release = usbdev_release, |
1589 | }; | 1589 | }; |
1590 | 1590 | ||
1591 | static void usbdev_add(struct usb_device *dev) | 1591 | static int usbdev_add(struct usb_device *dev) |
1592 | { | 1592 | { |
1593 | int minor = ((dev->bus->busnum-1) * 128) + (dev->devnum-1); | 1593 | int minor = ((dev->bus->busnum-1) * 128) + (dev->devnum-1); |
1594 | 1594 | ||
1595 | dev->class_dev = class_device_create(usb_device_class, NULL, | 1595 | dev->class_dev = class_device_create(usb_device_class, NULL, |
1596 | MKDEV(USB_DEVICE_MAJOR, minor), &dev->dev, | 1596 | MKDEV(USB_DEVICE_MAJOR, minor), &dev->dev, |
1597 | "usbdev%d.%d", dev->bus->busnum, dev->devnum); | 1597 | "usbdev%d.%d", dev->bus->busnum, dev->devnum); |
1598 | if (IS_ERR(dev->class_dev)) | ||
1599 | return PTR_ERR(dev->class_dev); | ||
1598 | 1600 | ||
1599 | dev->class_dev->class_data = dev; | 1601 | dev->class_dev->class_data = dev; |
1602 | return 0; | ||
1600 | } | 1603 | } |
1601 | 1604 | ||
1602 | static void usbdev_remove(struct usb_device *dev) | 1605 | static void usbdev_remove(struct usb_device *dev) |
@@ -1609,7 +1612,8 @@ static int usbdev_notify(struct notifier_block *self, unsigned long action, | |||
1609 | { | 1612 | { |
1610 | switch (action) { | 1613 | switch (action) { |
1611 | case USB_DEVICE_ADD: | 1614 | case USB_DEVICE_ADD: |
1612 | usbdev_add(dev); | 1615 | if (usbdev_add(dev)) |
1616 | return NOTIFY_BAD; | ||
1613 | break; | 1617 | break; |
1614 | case USB_DEVICE_REMOVE: | 1618 | case USB_DEVICE_REMOVE: |
1615 | usbdev_remove(dev); | 1619 | usbdev_remove(dev); |
diff --git a/drivers/usb/core/endpoint.c b/drivers/usb/core/endpoint.c index 3ebb90149e93..3b2d137912be 100644 --- a/drivers/usb/core/endpoint.c +++ b/drivers/usb/core/endpoint.c | |||
@@ -223,7 +223,7 @@ int usb_create_ep_files(struct device *parent, | |||
223 | ep_dev = kzalloc(sizeof(*ep_dev), GFP_KERNEL); | 223 | ep_dev = kzalloc(sizeof(*ep_dev), GFP_KERNEL); |
224 | if (!ep_dev) { | 224 | if (!ep_dev) { |
225 | retval = -ENOMEM; | 225 | retval = -ENOMEM; |
226 | goto exit; | 226 | goto error_alloc; |
227 | } | 227 | } |
228 | 228 | ||
229 | /* fun calculation to determine the minor of this endpoint */ | 229 | /* fun calculation to determine the minor of this endpoint */ |
@@ -241,33 +241,31 @@ int usb_create_ep_files(struct device *parent, | |||
241 | 241 | ||
242 | retval = device_register(&ep_dev->dev); | 242 | retval = device_register(&ep_dev->dev); |
243 | if (retval) | 243 | if (retval) |
244 | goto error; | 244 | goto error_register; |
245 | retval = sysfs_create_group(&ep_dev->dev.kobj, &ep_dev_attr_grp); | 245 | retval = sysfs_create_group(&ep_dev->dev.kobj, &ep_dev_attr_grp); |
246 | if (retval) | 246 | if (retval) |
247 | goto error_group; | 247 | goto error_group; |
248 | 248 | ||
249 | endpoint->ep_dev = ep_dev; | ||
250 | |||
251 | /* create the symlink to the old-style "ep_XX" directory */ | 249 | /* create the symlink to the old-style "ep_XX" directory */ |
252 | sprintf(name, "ep_%02x", endpoint->desc.bEndpointAddress); | 250 | sprintf(name, "ep_%02x", endpoint->desc.bEndpointAddress); |
253 | retval = sysfs_create_link(&parent->kobj, | 251 | retval = sysfs_create_link(&parent->kobj, &ep_dev->dev.kobj, name); |
254 | &endpoint->ep_dev->dev.kobj, name); | ||
255 | if (retval) | 252 | if (retval) |
256 | goto error_link; | 253 | goto error_link; |
257 | exit: | 254 | endpoint->ep_dev = ep_dev; |
258 | return retval; | 255 | return retval; |
259 | 256 | ||
260 | error_link: | 257 | error_link: |
261 | sysfs_remove_group(&ep_dev->dev.kobj, &ep_dev_attr_grp); | 258 | sysfs_remove_group(&ep_dev->dev.kobj, &ep_dev_attr_grp); |
262 | |||
263 | error_group: | 259 | error_group: |
264 | device_unregister(&ep_dev->dev); | 260 | device_unregister(&ep_dev->dev); |
265 | endpoint->ep_dev = NULL; | ||
266 | destroy_endpoint_class(); | 261 | destroy_endpoint_class(); |
267 | return retval; | 262 | return retval; |
268 | error: | 263 | |
264 | error_register: | ||
269 | kfree(ep_dev); | 265 | kfree(ep_dev); |
266 | error_alloc: | ||
270 | destroy_endpoint_class(); | 267 | destroy_endpoint_class(); |
268 | exit: | ||
271 | return retval; | 269 | return retval; |
272 | } | 270 | } |
273 | 271 | ||
@@ -282,8 +280,6 @@ void usb_remove_ep_files(struct usb_host_endpoint *endpoint) | |||
282 | sysfs_remove_group(&endpoint->ep_dev->dev.kobj, &ep_dev_attr_grp); | 280 | sysfs_remove_group(&endpoint->ep_dev->dev.kobj, &ep_dev_attr_grp); |
283 | device_unregister(&endpoint->ep_dev->dev); | 281 | device_unregister(&endpoint->ep_dev->dev); |
284 | endpoint->ep_dev = NULL; | 282 | endpoint->ep_dev = NULL; |
283 | destroy_endpoint_class(); | ||
285 | } | 284 | } |
286 | destroy_endpoint_class(); | ||
287 | } | 285 | } |
288 | |||
289 | |||
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 66bff184a30c..ba165aff9ea4 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -1188,6 +1188,7 @@ static inline void show_string(struct usb_device *udev, char *id, char *string) | |||
1188 | 1188 | ||
1189 | #ifdef CONFIG_USB_OTG | 1189 | #ifdef CONFIG_USB_OTG |
1190 | #include "otg_whitelist.h" | 1190 | #include "otg_whitelist.h" |
1191 | static int __usb_port_suspend(struct usb_device *, int port1); | ||
1191 | #endif | 1192 | #endif |
1192 | 1193 | ||
1193 | /** | 1194 | /** |
@@ -1289,8 +1290,6 @@ int usb_new_device(struct usb_device *udev) | |||
1289 | * (Includes HNP test device.) | 1290 | * (Includes HNP test device.) |
1290 | */ | 1291 | */ |
1291 | if (udev->bus->b_hnp_enable || udev->bus->is_b_host) { | 1292 | if (udev->bus->b_hnp_enable || udev->bus->is_b_host) { |
1292 | static int __usb_port_suspend(struct usb_device *, | ||
1293 | int port1); | ||
1294 | err = __usb_port_suspend(udev, udev->bus->otg_port); | 1293 | err = __usb_port_suspend(udev, udev->bus->otg_port); |
1295 | if (err < 0) | 1294 | if (err < 0) |
1296 | dev_dbg(&udev->dev, "HNP fail, %d\n", err); | 1295 | dev_dbg(&udev->dev, "HNP fail, %d\n", err); |
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index fccd1952bad3..7729c0744886 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -828,10 +828,7 @@ char *usb_cache_string(struct usb_device *udev, int index) | |||
828 | * Context: !in_interrupt () | 828 | * Context: !in_interrupt () |
829 | * | 829 | * |
830 | * Updates the copy of the device descriptor stored in the device structure, | 830 | * Updates the copy of the device descriptor stored in the device structure, |
831 | * which dedicates space for this purpose. Note that several fields are | 831 | * which dedicates space for this purpose. |
832 | * converted to the host CPU's byte order: the USB version (bcdUSB), and | ||
833 | * vendors product and version fields (idVendor, idProduct, and bcdDevice). | ||
834 | * That lets device drivers compare against non-byteswapped constants. | ||
835 | * | 832 | * |
836 | * Not exported, only for use by the core. If drivers really want to read | 833 | * Not exported, only for use by the core. If drivers really want to read |
837 | * the device descriptor directly, they can call usb_get_descriptor() with | 834 | * the device descriptor directly, they can call usb_get_descriptor() with |
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index d954daa8e9e0..3acc896a5d4c 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c | |||
@@ -1774,8 +1774,8 @@ static DEVICE_ATTR (queues, S_IRUGO, show_queues, NULL); | |||
1774 | 1774 | ||
1775 | #else | 1775 | #else |
1776 | 1776 | ||
1777 | #define device_create_file(a,b) do {} while (0) | 1777 | #define device_create_file(a,b) (0) |
1778 | #define device_remove_file device_create_file | 1778 | #define device_remove_file(a,b) do { } while (0) |
1779 | 1779 | ||
1780 | #endif | 1780 | #endif |
1781 | 1781 | ||
@@ -2044,8 +2044,10 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver) | |||
2044 | return retval; | 2044 | return retval; |
2045 | } | 2045 | } |
2046 | 2046 | ||
2047 | device_create_file (&dev->pdev->dev, &dev_attr_function); | 2047 | retval = device_create_file (&dev->pdev->dev, &dev_attr_function); |
2048 | device_create_file (&dev->pdev->dev, &dev_attr_queues); | 2048 | if (retval) goto err_unbind; |
2049 | retval = device_create_file (&dev->pdev->dev, &dev_attr_queues); | ||
2050 | if (retval) goto err_func; | ||
2049 | 2051 | ||
2050 | /* ... then enable host detection and ep0; and we're ready | 2052 | /* ... then enable host detection and ep0; and we're ready |
2051 | * for set_configuration as well as eventual disconnect. | 2053 | * for set_configuration as well as eventual disconnect. |
@@ -2060,6 +2062,14 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver) | |||
2060 | 2062 | ||
2061 | /* pci writes may still be posted */ | 2063 | /* pci writes may still be posted */ |
2062 | return 0; | 2064 | return 0; |
2065 | |||
2066 | err_func: | ||
2067 | device_remove_file (&dev->pdev->dev, &dev_attr_function); | ||
2068 | err_unbind: | ||
2069 | driver->unbind (&dev->gadget); | ||
2070 | dev->gadget.dev.driver = NULL; | ||
2071 | dev->driver = NULL; | ||
2072 | return retval; | ||
2063 | } | 2073 | } |
2064 | EXPORT_SYMBOL (usb_gadget_register_driver); | 2074 | EXPORT_SYMBOL (usb_gadget_register_driver); |
2065 | 2075 | ||
@@ -2974,8 +2984,10 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id) | |||
2974 | : "disabled"); | 2984 | : "disabled"); |
2975 | the_controller = dev; | 2985 | the_controller = dev; |
2976 | 2986 | ||
2977 | device_register (&dev->gadget.dev); | 2987 | retval = device_register (&dev->gadget.dev); |
2978 | device_create_file (&pdev->dev, &dev_attr_registers); | 2988 | if (retval) goto done; |
2989 | retval = device_create_file (&pdev->dev, &dev_attr_registers); | ||
2990 | if (retval) goto done; | ||
2979 | 2991 | ||
2980 | return 0; | 2992 | return 0; |
2981 | 2993 | ||
diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c index f42c00ef0bca..671c24bc6d75 100644 --- a/drivers/usb/gadget/pxa2xx_udc.c +++ b/drivers/usb/gadget/pxa2xx_udc.c | |||
@@ -43,11 +43,11 @@ | |||
43 | #include <linux/mm.h> | 43 | #include <linux/mm.h> |
44 | #include <linux/platform_device.h> | 44 | #include <linux/platform_device.h> |
45 | #include <linux/dma-mapping.h> | 45 | #include <linux/dma-mapping.h> |
46 | #include <linux/irq.h> | ||
46 | 47 | ||
47 | #include <asm/byteorder.h> | 48 | #include <asm/byteorder.h> |
48 | #include <asm/dma.h> | 49 | #include <asm/dma.h> |
49 | #include <asm/io.h> | 50 | #include <asm/io.h> |
50 | #include <asm/irq.h> | ||
51 | #include <asm/system.h> | 51 | #include <asm/system.h> |
52 | #include <asm/mach-types.h> | 52 | #include <asm/mach-types.h> |
53 | #include <asm/unaligned.h> | 53 | #include <asm/unaligned.h> |
diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c index 23b95b2bfe15..34b7a31cd85b 100644 --- a/drivers/usb/host/ehci-dbg.c +++ b/drivers/usb/host/ehci-dbg.c | |||
@@ -754,7 +754,9 @@ show_registers (struct class_device *class_dev, char *buf) | |||
754 | } | 754 | } |
755 | 755 | ||
756 | if (ehci->reclaim) { | 756 | if (ehci->reclaim) { |
757 | temp = scnprintf (next, size, "reclaim qh %p\n", ehci->reclaim); | 757 | temp = scnprintf (next, size, "reclaim qh %p%s\n", |
758 | ehci->reclaim, | ||
759 | ehci->reclaim_ready ? " ready" : ""); | ||
758 | size -= temp; | 760 | size -= temp; |
759 | next += temp; | 761 | next += temp; |
760 | } | 762 | } |
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index aac6ec5dd7cf..9030994aba98 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c | |||
@@ -111,7 +111,7 @@ static const char hcd_name [] = "ehci_hcd"; | |||
111 | #define EHCI_TUNE_MULT_TT 1 | 111 | #define EHCI_TUNE_MULT_TT 1 |
112 | #define EHCI_TUNE_FLS 2 /* (small) 256 frame schedule */ | 112 | #define EHCI_TUNE_FLS 2 /* (small) 256 frame schedule */ |
113 | 113 | ||
114 | #define EHCI_IAA_MSECS 10 /* arbitrary */ | 114 | #define EHCI_IAA_JIFFIES (HZ/100) /* arbitrary; ~10 msec */ |
115 | #define EHCI_IO_JIFFIES (HZ/10) /* io watchdog > irq_thresh */ | 115 | #define EHCI_IO_JIFFIES (HZ/10) /* io watchdog > irq_thresh */ |
116 | #define EHCI_ASYNC_JIFFIES (HZ/20) /* async idle timeout */ | 116 | #define EHCI_ASYNC_JIFFIES (HZ/20) /* async idle timeout */ |
117 | #define EHCI_SHRINK_JIFFIES (HZ/200) /* async qh unlink delay */ | 117 | #define EHCI_SHRINK_JIFFIES (HZ/200) /* async qh unlink delay */ |
@@ -254,7 +254,6 @@ static void ehci_quiesce (struct ehci_hcd *ehci) | |||
254 | 254 | ||
255 | /*-------------------------------------------------------------------------*/ | 255 | /*-------------------------------------------------------------------------*/ |
256 | 256 | ||
257 | static void end_unlink_async (struct ehci_hcd *ehci); | ||
258 | static void ehci_work(struct ehci_hcd *ehci); | 257 | static void ehci_work(struct ehci_hcd *ehci); |
259 | 258 | ||
260 | #include "ehci-hub.c" | 259 | #include "ehci-hub.c" |
@@ -264,37 +263,25 @@ static void ehci_work(struct ehci_hcd *ehci); | |||
264 | 263 | ||
265 | /*-------------------------------------------------------------------------*/ | 264 | /*-------------------------------------------------------------------------*/ |
266 | 265 | ||
267 | static void ehci_iaa_watchdog (unsigned long param) | 266 | static void ehci_watchdog (unsigned long param) |
268 | { | 267 | { |
269 | struct ehci_hcd *ehci = (struct ehci_hcd *) param; | 268 | struct ehci_hcd *ehci = (struct ehci_hcd *) param; |
270 | unsigned long flags; | 269 | unsigned long flags; |
271 | u32 status; | ||
272 | 270 | ||
273 | spin_lock_irqsave (&ehci->lock, flags); | 271 | spin_lock_irqsave (&ehci->lock, flags); |
274 | WARN_ON(!ehci->reclaim); | ||
275 | 272 | ||
276 | /* lost IAA irqs wedge things badly; seen first with a vt8235 */ | 273 | /* lost IAA irqs wedge things badly; seen with a vt8235 */ |
277 | if (ehci->reclaim) { | 274 | if (ehci->reclaim) { |
278 | status = readl (&ehci->regs->status); | 275 | u32 status = readl (&ehci->regs->status); |
279 | if (status & STS_IAA) { | 276 | if (status & STS_IAA) { |
280 | ehci_vdbg (ehci, "lost IAA\n"); | 277 | ehci_vdbg (ehci, "lost IAA\n"); |
281 | COUNT (ehci->stats.lost_iaa); | 278 | COUNT (ehci->stats.lost_iaa); |
282 | writel (STS_IAA, &ehci->regs->status); | 279 | writel (STS_IAA, &ehci->regs->status); |
283 | end_unlink_async (ehci); | 280 | ehci->reclaim_ready = 1; |
284 | } | 281 | } |
285 | } | 282 | } |
286 | 283 | ||
287 | spin_unlock_irqrestore (&ehci->lock, flags); | 284 | /* stop async processing after it's idled a bit */ |
288 | } | ||
289 | |||
290 | static void ehci_watchdog (unsigned long param) | ||
291 | { | ||
292 | struct ehci_hcd *ehci = (struct ehci_hcd *) param; | ||
293 | unsigned long flags; | ||
294 | |||
295 | spin_lock_irqsave (&ehci->lock, flags); | ||
296 | |||
297 | /* stop async processing after it's idled a bit */ | ||
298 | if (test_bit (TIMER_ASYNC_OFF, &ehci->actions)) | 285 | if (test_bit (TIMER_ASYNC_OFF, &ehci->actions)) |
299 | start_unlink_async (ehci, ehci->async); | 286 | start_unlink_async (ehci, ehci->async); |
300 | 287 | ||
@@ -345,6 +332,8 @@ static void ehci_port_power (struct ehci_hcd *ehci, int is_on) | |||
345 | static void ehci_work (struct ehci_hcd *ehci) | 332 | static void ehci_work (struct ehci_hcd *ehci) |
346 | { | 333 | { |
347 | timer_action_done (ehci, TIMER_IO_WATCHDOG); | 334 | timer_action_done (ehci, TIMER_IO_WATCHDOG); |
335 | if (ehci->reclaim_ready) | ||
336 | end_unlink_async (ehci); | ||
348 | 337 | ||
349 | /* another CPU may drop ehci->lock during a schedule scan while | 338 | /* another CPU may drop ehci->lock during a schedule scan while |
350 | * it reports urb completions. this flag guards against bogus | 339 | * it reports urb completions. this flag guards against bogus |
@@ -379,7 +368,6 @@ static void ehci_stop (struct usb_hcd *hcd) | |||
379 | 368 | ||
380 | /* no more interrupts ... */ | 369 | /* no more interrupts ... */ |
381 | del_timer_sync (&ehci->watchdog); | 370 | del_timer_sync (&ehci->watchdog); |
382 | del_timer_sync (&ehci->iaa_watchdog); | ||
383 | 371 | ||
384 | spin_lock_irq(&ehci->lock); | 372 | spin_lock_irq(&ehci->lock); |
385 | if (HC_IS_RUNNING (hcd->state)) | 373 | if (HC_IS_RUNNING (hcd->state)) |
@@ -426,10 +414,6 @@ static int ehci_init(struct usb_hcd *hcd) | |||
426 | ehci->watchdog.function = ehci_watchdog; | 414 | ehci->watchdog.function = ehci_watchdog; |
427 | ehci->watchdog.data = (unsigned long) ehci; | 415 | ehci->watchdog.data = (unsigned long) ehci; |
428 | 416 | ||
429 | init_timer(&ehci->iaa_watchdog); | ||
430 | ehci->iaa_watchdog.function = ehci_iaa_watchdog; | ||
431 | ehci->iaa_watchdog.data = (unsigned long) ehci; | ||
432 | |||
433 | /* | 417 | /* |
434 | * hw default: 1K periodic list heads, one per frame. | 418 | * hw default: 1K periodic list heads, one per frame. |
435 | * periodic_size can shrink by USBCMD update if hcc_params allows. | 419 | * periodic_size can shrink by USBCMD update if hcc_params allows. |
@@ -446,6 +430,7 @@ static int ehci_init(struct usb_hcd *hcd) | |||
446 | ehci->i_thresh = 2 + HCC_ISOC_THRES(hcc_params); | 430 | ehci->i_thresh = 2 + HCC_ISOC_THRES(hcc_params); |
447 | 431 | ||
448 | ehci->reclaim = NULL; | 432 | ehci->reclaim = NULL; |
433 | ehci->reclaim_ready = 0; | ||
449 | ehci->next_uframe = -1; | 434 | ehci->next_uframe = -1; |
450 | 435 | ||
451 | /* | 436 | /* |
@@ -619,7 +604,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) | |||
619 | /* complete the unlinking of some qh [4.15.2.3] */ | 604 | /* complete the unlinking of some qh [4.15.2.3] */ |
620 | if (status & STS_IAA) { | 605 | if (status & STS_IAA) { |
621 | COUNT (ehci->stats.reclaim); | 606 | COUNT (ehci->stats.reclaim); |
622 | end_unlink_async (ehci); | 607 | ehci->reclaim_ready = 1; |
623 | bh = 1; | 608 | bh = 1; |
624 | } | 609 | } |
625 | 610 | ||
@@ -723,14 +708,10 @@ static int ehci_urb_enqueue ( | |||
723 | 708 | ||
724 | static void unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) | 709 | static void unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) |
725 | { | 710 | { |
726 | // BUG_ON(qh->qh_state != QH_STATE_LINKED); | 711 | /* if we need to use IAA and it's busy, defer */ |
727 | 712 | if (qh->qh_state == QH_STATE_LINKED | |
728 | /* failfast */ | 713 | && ehci->reclaim |
729 | if (!HC_IS_RUNNING (ehci_to_hcd(ehci)->state)) | 714 | && HC_IS_RUNNING (ehci_to_hcd(ehci)->state)) { |
730 | end_unlink_async (ehci); | ||
731 | |||
732 | /* defer till later if busy */ | ||
733 | else if (ehci->reclaim) { | ||
734 | struct ehci_qh *last; | 715 | struct ehci_qh *last; |
735 | 716 | ||
736 | for (last = ehci->reclaim; | 717 | for (last = ehci->reclaim; |
@@ -740,8 +721,12 @@ static void unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
740 | qh->qh_state = QH_STATE_UNLINK_WAIT; | 721 | qh->qh_state = QH_STATE_UNLINK_WAIT; |
741 | last->reclaim = qh; | 722 | last->reclaim = qh; |
742 | 723 | ||
743 | /* start IAA cycle */ | 724 | /* bypass IAA if the hc can't care */ |
744 | } else | 725 | } else if (!HC_IS_RUNNING (ehci_to_hcd(ehci)->state) && ehci->reclaim) |
726 | end_unlink_async (ehci); | ||
727 | |||
728 | /* something else might have unlinked the qh by now */ | ||
729 | if (qh->qh_state == QH_STATE_LINKED) | ||
745 | start_unlink_async (ehci, qh); | 730 | start_unlink_async (ehci, qh); |
746 | } | 731 | } |
747 | 732 | ||
@@ -763,19 +748,7 @@ static int ehci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb) | |||
763 | qh = (struct ehci_qh *) urb->hcpriv; | 748 | qh = (struct ehci_qh *) urb->hcpriv; |
764 | if (!qh) | 749 | if (!qh) |
765 | break; | 750 | break; |
766 | switch (qh->qh_state) { | 751 | unlink_async (ehci, qh); |
767 | case QH_STATE_LINKED: | ||
768 | case QH_STATE_COMPLETING: | ||
769 | unlink_async (ehci, qh); | ||
770 | break; | ||
771 | case QH_STATE_UNLINK: | ||
772 | case QH_STATE_UNLINK_WAIT: | ||
773 | /* already started */ | ||
774 | break; | ||
775 | case QH_STATE_IDLE: | ||
776 | WARN_ON(1); | ||
777 | break; | ||
778 | } | ||
779 | break; | 752 | break; |
780 | 753 | ||
781 | case PIPE_INTERRUPT: | 754 | case PIPE_INTERRUPT: |
@@ -867,7 +840,6 @@ rescan: | |||
867 | unlink_async (ehci, qh); | 840 | unlink_async (ehci, qh); |
868 | /* FALL THROUGH */ | 841 | /* FALL THROUGH */ |
869 | case QH_STATE_UNLINK: /* wait for hw to finish? */ | 842 | case QH_STATE_UNLINK: /* wait for hw to finish? */ |
870 | case QH_STATE_UNLINK_WAIT: | ||
871 | idle_timeout: | 843 | idle_timeout: |
872 | spin_unlock_irqrestore (&ehci->lock, flags); | 844 | spin_unlock_irqrestore (&ehci->lock, flags); |
873 | schedule_timeout_uninterruptible(1); | 845 | schedule_timeout_uninterruptible(1); |
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 2012213c0a25..1b20722c102b 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c | |||
@@ -48,7 +48,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) | |||
48 | } | 48 | } |
49 | ehci->command = readl (&ehci->regs->command); | 49 | ehci->command = readl (&ehci->regs->command); |
50 | if (ehci->reclaim) | 50 | if (ehci->reclaim) |
51 | end_unlink_async (ehci); | 51 | ehci->reclaim_ready = 1; |
52 | ehci_work(ehci); | 52 | ehci_work(ehci); |
53 | 53 | ||
54 | /* suspend any active/unsuspended ports, maybe allow wakeup */ | 54 | /* suspend any active/unsuspended ports, maybe allow wakeup */ |
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 35e3fab6fc4e..e51c1ed81ac4 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c | |||
@@ -303,7 +303,7 @@ restart: | |||
303 | /* emptying the schedule aborts any urbs */ | 303 | /* emptying the schedule aborts any urbs */ |
304 | spin_lock_irq(&ehci->lock); | 304 | spin_lock_irq(&ehci->lock); |
305 | if (ehci->reclaim) | 305 | if (ehci->reclaim) |
306 | end_unlink_async (ehci); | 306 | ehci->reclaim_ready = 1; |
307 | ehci_work(ehci); | 307 | ehci_work(ehci); |
308 | spin_unlock_irq(&ehci->lock); | 308 | spin_unlock_irq(&ehci->lock); |
309 | 309 | ||
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 46327272f614..62e46dc60e86 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c | |||
@@ -967,7 +967,7 @@ static void end_unlink_async (struct ehci_hcd *ehci) | |||
967 | struct ehci_qh *qh = ehci->reclaim; | 967 | struct ehci_qh *qh = ehci->reclaim; |
968 | struct ehci_qh *next; | 968 | struct ehci_qh *next; |
969 | 969 | ||
970 | iaa_watchdog_done (ehci); | 970 | timer_action_done (ehci, TIMER_IAA_WATCHDOG); |
971 | 971 | ||
972 | // qh->hw_next = cpu_to_le32 (qh->qh_dma); | 972 | // qh->hw_next = cpu_to_le32 (qh->qh_dma); |
973 | qh->qh_state = QH_STATE_IDLE; | 973 | qh->qh_state = QH_STATE_IDLE; |
@@ -977,6 +977,7 @@ static void end_unlink_async (struct ehci_hcd *ehci) | |||
977 | /* other unlink(s) may be pending (in QH_STATE_UNLINK_WAIT) */ | 977 | /* other unlink(s) may be pending (in QH_STATE_UNLINK_WAIT) */ |
978 | next = qh->reclaim; | 978 | next = qh->reclaim; |
979 | ehci->reclaim = next; | 979 | ehci->reclaim = next; |
980 | ehci->reclaim_ready = 0; | ||
980 | qh->reclaim = NULL; | 981 | qh->reclaim = NULL; |
981 | 982 | ||
982 | qh_completions (ehci, qh); | 983 | qh_completions (ehci, qh); |
@@ -1051,10 +1052,11 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
1051 | return; | 1052 | return; |
1052 | } | 1053 | } |
1053 | 1054 | ||
1055 | ehci->reclaim_ready = 0; | ||
1054 | cmd |= CMD_IAAD; | 1056 | cmd |= CMD_IAAD; |
1055 | writel (cmd, &ehci->regs->command); | 1057 | writel (cmd, &ehci->regs->command); |
1056 | (void) readl (&ehci->regs->command); | 1058 | (void) readl (&ehci->regs->command); |
1057 | iaa_watchdog_start (ehci); | 1059 | timer_action (ehci, TIMER_IAA_WATCHDOG); |
1058 | } | 1060 | } |
1059 | 1061 | ||
1060 | /*-------------------------------------------------------------------------*/ | 1062 | /*-------------------------------------------------------------------------*/ |
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 6aac39f50e07..bbc3082a73d7 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h | |||
@@ -58,6 +58,7 @@ struct ehci_hcd { /* one per controller */ | |||
58 | /* async schedule support */ | 58 | /* async schedule support */ |
59 | struct ehci_qh *async; | 59 | struct ehci_qh *async; |
60 | struct ehci_qh *reclaim; | 60 | struct ehci_qh *reclaim; |
61 | unsigned reclaim_ready : 1; | ||
61 | unsigned scanning : 1; | 62 | unsigned scanning : 1; |
62 | 63 | ||
63 | /* periodic schedule support */ | 64 | /* periodic schedule support */ |
@@ -80,7 +81,6 @@ struct ehci_hcd { /* one per controller */ | |||
80 | struct dma_pool *itd_pool; /* itd per iso urb */ | 81 | struct dma_pool *itd_pool; /* itd per iso urb */ |
81 | struct dma_pool *sitd_pool; /* sitd per split iso urb */ | 82 | struct dma_pool *sitd_pool; /* sitd per split iso urb */ |
82 | 83 | ||
83 | struct timer_list iaa_watchdog; | ||
84 | struct timer_list watchdog; | 84 | struct timer_list watchdog; |
85 | unsigned long actions; | 85 | unsigned long actions; |
86 | unsigned stamp; | 86 | unsigned stamp; |
@@ -114,21 +114,9 @@ static inline struct usb_hcd *ehci_to_hcd (struct ehci_hcd *ehci) | |||
114 | } | 114 | } |
115 | 115 | ||
116 | 116 | ||
117 | static inline void | ||
118 | iaa_watchdog_start (struct ehci_hcd *ehci) | ||
119 | { | ||
120 | WARN_ON(timer_pending(&ehci->iaa_watchdog)); | ||
121 | mod_timer (&ehci->iaa_watchdog, | ||
122 | jiffies + msecs_to_jiffies(EHCI_IAA_MSECS)); | ||
123 | } | ||
124 | |||
125 | static inline void iaa_watchdog_done (struct ehci_hcd *ehci) | ||
126 | { | ||
127 | del_timer (&ehci->iaa_watchdog); | ||
128 | } | ||
129 | |||
130 | enum ehci_timer_action { | 117 | enum ehci_timer_action { |
131 | TIMER_IO_WATCHDOG, | 118 | TIMER_IO_WATCHDOG, |
119 | TIMER_IAA_WATCHDOG, | ||
132 | TIMER_ASYNC_SHRINK, | 120 | TIMER_ASYNC_SHRINK, |
133 | TIMER_ASYNC_OFF, | 121 | TIMER_ASYNC_OFF, |
134 | }; | 122 | }; |
@@ -146,6 +134,9 @@ timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action) | |||
146 | unsigned long t; | 134 | unsigned long t; |
147 | 135 | ||
148 | switch (action) { | 136 | switch (action) { |
137 | case TIMER_IAA_WATCHDOG: | ||
138 | t = EHCI_IAA_JIFFIES; | ||
139 | break; | ||
149 | case TIMER_IO_WATCHDOG: | 140 | case TIMER_IO_WATCHDOG: |
150 | t = EHCI_IO_JIFFIES; | 141 | t = EHCI_IO_JIFFIES; |
151 | break; | 142 | break; |
@@ -162,7 +153,8 @@ timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action) | |||
162 | // async queue SHRINK often precedes IAA. while it's ready | 153 | // async queue SHRINK often precedes IAA. while it's ready |
163 | // to go OFF neither can matter, and afterwards the IO | 154 | // to go OFF neither can matter, and afterwards the IO |
164 | // watchdog stops unless there's still periodic traffic. | 155 | // watchdog stops unless there's still periodic traffic. |
165 | if (time_before_eq(t, ehci->watchdog.expires) | 156 | if (action != TIMER_IAA_WATCHDOG |
157 | && t > ehci->watchdog.expires | ||
166 | && timer_pending (&ehci->watchdog)) | 158 | && timer_pending (&ehci->watchdog)) |
167 | return; | 159 | return; |
168 | mod_timer (&ehci->watchdog, t); | 160 | mod_timer (&ehci->watchdog, t); |
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 9be6b303e784..ea4714e557e4 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c | |||
@@ -715,13 +715,6 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd) | |||
715 | return IRQ_NOTMINE; | 715 | return IRQ_NOTMINE; |
716 | } | 716 | } |
717 | 717 | ||
718 | if (ints & OHCI_INTR_RHSC) { | ||
719 | ohci_vdbg (ohci, "rhsc\n"); | ||
720 | ohci->next_statechange = jiffies + STATECHANGE_DELAY; | ||
721 | ohci_writel (ohci, OHCI_INTR_RHSC, ®s->intrstatus); | ||
722 | usb_hcd_poll_rh_status(hcd); | ||
723 | } | ||
724 | |||
725 | if (ints & OHCI_INTR_UE) { | 718 | if (ints & OHCI_INTR_UE) { |
726 | disable (ohci); | 719 | disable (ohci); |
727 | ohci_err (ohci, "OHCI Unrecoverable Error, disabled\n"); | 720 | ohci_err (ohci, "OHCI Unrecoverable Error, disabled\n"); |
@@ -731,9 +724,21 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd) | |||
731 | ohci_usb_reset (ohci); | 724 | ohci_usb_reset (ohci); |
732 | } | 725 | } |
733 | 726 | ||
734 | if (ints & OHCI_INTR_RD) { | 727 | if (ints & OHCI_INTR_RHSC) { |
735 | ohci_vdbg (ohci, "resume detect\n"); | 728 | ohci_vdbg(ohci, "rhsc\n"); |
736 | ohci_writel (ohci, OHCI_INTR_RD, ®s->intrstatus); | 729 | ohci->next_statechange = jiffies + STATECHANGE_DELAY; |
730 | ohci_writel(ohci, OHCI_INTR_RD | OHCI_INTR_RHSC, | ||
731 | ®s->intrstatus); | ||
732 | usb_hcd_poll_rh_status(hcd); | ||
733 | } | ||
734 | |||
735 | /* For connect and disconnect events, we expect the controller | ||
736 | * to turn on RHSC along with RD. But for remote wakeup events | ||
737 | * this might not happen. | ||
738 | */ | ||
739 | else if (ints & OHCI_INTR_RD) { | ||
740 | ohci_vdbg(ohci, "resume detect\n"); | ||
741 | ohci_writel(ohci, OHCI_INTR_RD, ®s->intrstatus); | ||
737 | hcd->poll_rh = 1; | 742 | hcd->poll_rh = 1; |
738 | if (ohci->autostop) { | 743 | if (ohci->autostop) { |
739 | spin_lock (&ohci->lock); | 744 | spin_lock (&ohci->lock); |
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index 6f113596af66..6995ea36f2e8 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c | |||
@@ -169,7 +169,8 @@ __acquires(ohci->lock) | |||
169 | break; | 169 | break; |
170 | case OHCI_USB_RESUME: | 170 | case OHCI_USB_RESUME: |
171 | /* HCFS changes sometime after INTR_RD */ | 171 | /* HCFS changes sometime after INTR_RD */ |
172 | ohci_info (ohci, "wakeup\n"); | 172 | ohci_info(ohci, "%swakeup\n", |
173 | autostopped ? "auto-" : ""); | ||
173 | break; | 174 | break; |
174 | case OHCI_USB_OPER: | 175 | case OHCI_USB_OPER: |
175 | /* this can happen after resuming a swsusp snapshot */ | 176 | /* this can happen after resuming a swsusp snapshot */ |
@@ -422,7 +423,8 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf) | |||
422 | ohci->autostop = 0; | 423 | ohci->autostop = 0; |
423 | ohci->next_statechange = jiffies + | 424 | ohci->next_statechange = jiffies + |
424 | STATECHANGE_DELAY; | 425 | STATECHANGE_DELAY; |
425 | } else if (time_after_eq (jiffies, | 426 | } else if (device_may_wakeup(&hcd->self.root_hub->dev) |
427 | && time_after_eq(jiffies, | ||
426 | ohci->next_statechange) | 428 | ohci->next_statechange) |
427 | && !ohci->ed_rm_list | 429 | && !ohci->ed_rm_list |
428 | && !(ohci->hc_control & | 430 | && !(ohci->hc_control & |
diff --git a/drivers/usb/host/ohci-pnx4008.c b/drivers/usb/host/ohci-pnx4008.c index 82cb22f002e7..2dbb77414905 100644 --- a/drivers/usb/host/ohci-pnx4008.c +++ b/drivers/usb/host/ohci-pnx4008.c | |||
@@ -262,6 +262,7 @@ static const struct hc_driver ohci_pnx4008_hc_driver = { | |||
262 | */ | 262 | */ |
263 | .start = ohci_pnx4008_start, | 263 | .start = ohci_pnx4008_start, |
264 | .stop = ohci_stop, | 264 | .stop = ohci_stop, |
265 | .shutdown = ohci_shutdown, | ||
265 | 266 | ||
266 | /* | 267 | /* |
267 | * managing i/o requests and associated device resources | 268 | * managing i/o requests and associated device resources |
@@ -280,7 +281,11 @@ static const struct hc_driver ohci_pnx4008_hc_driver = { | |||
280 | */ | 281 | */ |
281 | .hub_status_data = ohci_hub_status_data, | 282 | .hub_status_data = ohci_hub_status_data, |
282 | .hub_control = ohci_hub_control, | 283 | .hub_control = ohci_hub_control, |
283 | 284 | .hub_irq_enable = ohci_rhsc_enable, | |
285 | #ifdef CONFIG_PM | ||
286 | .bus_suspend = ohci_bus_suspend, | ||
287 | .bus_resume = ohci_bus_resume, | ||
288 | #endif | ||
284 | .start_port_reset = ohci_start_port_reset, | 289 | .start_port_reset = ohci_start_port_reset, |
285 | }; | 290 | }; |
286 | 291 | ||
@@ -410,8 +415,6 @@ static int __devinit usb_hcd_pnx4008_probe(struct platform_device *pdev) | |||
410 | goto out4; | 415 | goto out4; |
411 | } | 416 | } |
412 | 417 | ||
413 | hcd->self.hcpriv = (void *)hcd; | ||
414 | |||
415 | pnx4008_start_hc(); | 418 | pnx4008_start_hc(); |
416 | platform_set_drvdata(pdev, hcd); | 419 | platform_set_drvdata(pdev, hcd); |
417 | ohci = hcd_to_ohci(hcd); | 420 | ohci = hcd_to_ohci(hcd); |
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index 45ee6920a850..226bf3de8edd 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <linux/dma-mapping.h> | 40 | #include <linux/dma-mapping.h> |
41 | #include <linux/usb.h> | 41 | #include <linux/usb.h> |
42 | #include <linux/bitops.h> | 42 | #include <linux/bitops.h> |
43 | #include <linux/dmi.h> | ||
43 | 44 | ||
44 | #include <asm/uaccess.h> | 45 | #include <asm/uaccess.h> |
45 | #include <asm/io.h> | 46 | #include <asm/io.h> |
@@ -196,12 +197,42 @@ static int resume_detect_interrupts_are_broken(struct uhci_hcd *uhci) | |||
196 | return 0; | 197 | return 0; |
197 | } | 198 | } |
198 | 199 | ||
200 | static int remote_wakeup_is_broken(struct uhci_hcd *uhci) | ||
201 | { | ||
202 | static struct dmi_system_id broken_wakeup_table[] = { | ||
203 | { | ||
204 | .ident = "Asus A7V8X", | ||
205 | .matches = { | ||
206 | DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK"), | ||
207 | DMI_MATCH(DMI_BOARD_NAME, "A7V8X"), | ||
208 | DMI_MATCH(DMI_BOARD_VERSION, "REV 1.xx"), | ||
209 | } | ||
210 | }, | ||
211 | { } | ||
212 | }; | ||
213 | int port; | ||
214 | |||
215 | /* One of Asus's motherboards has a bug which causes it to | ||
216 | * wake up immediately from suspend-to-RAM if any of the ports | ||
217 | * are connected. In such cases we will not set EGSM. | ||
218 | */ | ||
219 | if (dmi_check_system(broken_wakeup_table)) { | ||
220 | for (port = 0; port < uhci->rh_numports; ++port) { | ||
221 | if (inw(uhci->io_addr + USBPORTSC1 + port * 2) & | ||
222 | USBPORTSC_CCS) | ||
223 | return 1; | ||
224 | } | ||
225 | } | ||
226 | |||
227 | return 0; | ||
228 | } | ||
229 | |||
199 | static void suspend_rh(struct uhci_hcd *uhci, enum uhci_rh_state new_state) | 230 | static void suspend_rh(struct uhci_hcd *uhci, enum uhci_rh_state new_state) |
200 | __releases(uhci->lock) | 231 | __releases(uhci->lock) |
201 | __acquires(uhci->lock) | 232 | __acquires(uhci->lock) |
202 | { | 233 | { |
203 | int auto_stop; | 234 | int auto_stop; |
204 | int int_enable; | 235 | int int_enable, egsm_enable; |
205 | 236 | ||
206 | auto_stop = (new_state == UHCI_RH_AUTO_STOPPED); | 237 | auto_stop = (new_state == UHCI_RH_AUTO_STOPPED); |
207 | dev_dbg(&uhci_to_hcd(uhci)->self.root_hub->dev, | 238 | dev_dbg(&uhci_to_hcd(uhci)->self.root_hub->dev, |
@@ -217,15 +248,18 @@ __acquires(uhci->lock) | |||
217 | } | 248 | } |
218 | 249 | ||
219 | /* Enable resume-detect interrupts if they work. | 250 | /* Enable resume-detect interrupts if they work. |
220 | * Then enter Global Suspend mode, still configured. | 251 | * Then enter Global Suspend mode if _it_ works, still configured. |
221 | */ | 252 | */ |
253 | egsm_enable = USBCMD_EGSM; | ||
222 | uhci->working_RD = 1; | 254 | uhci->working_RD = 1; |
223 | int_enable = USBINTR_RESUME; | 255 | int_enable = USBINTR_RESUME; |
224 | if (resume_detect_interrupts_are_broken(uhci)) { | 256 | if (remote_wakeup_is_broken(uhci)) |
257 | egsm_enable = 0; | ||
258 | if (resume_detect_interrupts_are_broken(uhci) || !egsm_enable) | ||
225 | uhci->working_RD = int_enable = 0; | 259 | uhci->working_RD = int_enable = 0; |
226 | } | 260 | |
227 | outw(int_enable, uhci->io_addr + USBINTR); | 261 | outw(int_enable, uhci->io_addr + USBINTR); |
228 | outw(USBCMD_EGSM | USBCMD_CF, uhci->io_addr + USBCMD); | 262 | outw(egsm_enable | USBCMD_CF, uhci->io_addr + USBCMD); |
229 | mb(); | 263 | mb(); |
230 | udelay(5); | 264 | udelay(5); |
231 | 265 | ||
diff --git a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig index 21cd22640080..20db36448ab3 100644 --- a/drivers/usb/input/Kconfig +++ b/drivers/usb/input/Kconfig | |||
@@ -348,13 +348,3 @@ config USB_APPLETOUCH | |||
348 | 348 | ||
349 | To compile this driver as a module, choose M here: the | 349 | To compile this driver as a module, choose M here: the |
350 | module will be called appletouch. | 350 | module will be called appletouch. |
351 | |||
352 | config USB_TRANCEVIBRATOR | ||
353 | tristate "PlayStation 2 Trance Vibrator driver support" | ||
354 | depends on USB | ||
355 | help | ||
356 | Say Y here if you want to connect a PlayStation 2 Trance Vibrator | ||
357 | device to your computer's USB port. | ||
358 | |||
359 | To compile this driver as a module, choose M here: the | ||
360 | module will be called trancevibrator. | ||
diff --git a/drivers/usb/input/Makefile b/drivers/usb/input/Makefile index 295f459d1079..d946d5213b30 100644 --- a/drivers/usb/input/Makefile +++ b/drivers/usb/input/Makefile | |||
@@ -3,7 +3,7 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | # Multipart objects. | 5 | # Multipart objects. |
6 | wacom-objs := wacom_sys.o wacom_wac.o | 6 | wacom-objs := wacom_wac.o wacom_sys.o |
7 | usbhid-objs := hid-core.o | 7 | usbhid-objs := hid-core.o |
8 | 8 | ||
9 | # Optional parts of multipart objects. | 9 | # Optional parts of multipart objects. |
@@ -48,7 +48,6 @@ obj-$(CONFIG_USB_ACECAD) += acecad.o | |||
48 | obj-$(CONFIG_USB_YEALINK) += yealink.o | 48 | obj-$(CONFIG_USB_YEALINK) += yealink.o |
49 | obj-$(CONFIG_USB_XPAD) += xpad.o | 49 | obj-$(CONFIG_USB_XPAD) += xpad.o |
50 | obj-$(CONFIG_USB_APPLETOUCH) += appletouch.o | 50 | obj-$(CONFIG_USB_APPLETOUCH) += appletouch.o |
51 | obj-$(CONFIG_USB_TRANCEVIBRATOR) += trancevibrator.o | ||
52 | 51 | ||
53 | ifeq ($(CONFIG_USB_DEBUG),y) | 52 | ifeq ($(CONFIG_USB_DEBUG),y) |
54 | EXTRA_CFLAGS += -DDEBUG | 53 | EXTRA_CFLAGS += -DDEBUG |
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index a6738a83ff5b..6d08a3bcc952 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c | |||
@@ -270,7 +270,7 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign | |||
270 | * Read data value from item. | 270 | * Read data value from item. |
271 | */ | 271 | */ |
272 | 272 | ||
273 | static __inline__ __u32 item_udata(struct hid_item *item) | 273 | static u32 item_udata(struct hid_item *item) |
274 | { | 274 | { |
275 | switch (item->size) { | 275 | switch (item->size) { |
276 | case 1: return item->data.u8; | 276 | case 1: return item->data.u8; |
@@ -280,7 +280,7 @@ static __inline__ __u32 item_udata(struct hid_item *item) | |||
280 | return 0; | 280 | return 0; |
281 | } | 281 | } |
282 | 282 | ||
283 | static __inline__ __s32 item_sdata(struct hid_item *item) | 283 | static s32 item_sdata(struct hid_item *item) |
284 | { | 284 | { |
285 | switch (item->size) { | 285 | switch (item->size) { |
286 | case 1: return item->data.s8; | 286 | case 1: return item->data.s8; |
@@ -727,7 +727,7 @@ static struct hid_device *hid_parse_report(__u8 *start, unsigned size) | |||
727 | * done by hand. | 727 | * done by hand. |
728 | */ | 728 | */ |
729 | 729 | ||
730 | static __inline__ __s32 snto32(__u32 value, unsigned n) | 730 | static s32 snto32(__u32 value, unsigned n) |
731 | { | 731 | { |
732 | switch (n) { | 732 | switch (n) { |
733 | case 8: return ((__s8)value); | 733 | case 8: return ((__s8)value); |
@@ -741,30 +741,65 @@ static __inline__ __s32 snto32(__u32 value, unsigned n) | |||
741 | * Convert a signed 32-bit integer to a signed n-bit integer. | 741 | * Convert a signed 32-bit integer to a signed n-bit integer. |
742 | */ | 742 | */ |
743 | 743 | ||
744 | static __inline__ __u32 s32ton(__s32 value, unsigned n) | 744 | static u32 s32ton(__s32 value, unsigned n) |
745 | { | 745 | { |
746 | __s32 a = value >> (n - 1); | 746 | s32 a = value >> (n - 1); |
747 | if (a && a != -1) | 747 | if (a && a != -1) |
748 | return value < 0 ? 1 << (n - 1) : (1 << (n - 1)) - 1; | 748 | return value < 0 ? 1 << (n - 1) : (1 << (n - 1)) - 1; |
749 | return value & ((1 << n) - 1); | 749 | return value & ((1 << n) - 1); |
750 | } | 750 | } |
751 | 751 | ||
752 | /* | 752 | /* |
753 | * Extract/implement a data field from/to a report. | 753 | * Extract/implement a data field from/to a little endian report (bit array). |
754 | * | ||
755 | * Code sort-of follows HID spec: | ||
756 | * http://www.usb.org/developers/devclass_docs/HID1_11.pdf | ||
757 | * | ||
758 | * While the USB HID spec allows unlimited length bit fields in "report | ||
759 | * descriptors", most devices never use more than 16 bits. | ||
760 | * One model of UPS is claimed to report "LINEV" as a 32-bit field. | ||
761 | * Search linux-kernel and linux-usb-devel archives for "hid-core extract". | ||
754 | */ | 762 | */ |
755 | 763 | ||
756 | static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n) | 764 | static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n) |
757 | { | 765 | { |
758 | report += (offset >> 5) << 2; offset &= 31; | 766 | u64 x; |
759 | return (le64_to_cpu(get_unaligned((__le64*)report)) >> offset) & ((1ULL << n) - 1); | 767 | |
768 | WARN_ON(n > 32); | ||
769 | |||
770 | report += offset >> 3; /* adjust byte index */ | ||
771 | offset &= 7; /* now only need bit offset into one byte */ | ||
772 | x = get_unaligned((u64 *) report); | ||
773 | x = le64_to_cpu(x); | ||
774 | x = (x >> offset) & ((1ULL << n) - 1); /* extract bit field */ | ||
775 | return (u32) x; | ||
760 | } | 776 | } |
761 | 777 | ||
778 | /* | ||
779 | * "implement" : set bits in a little endian bit stream. | ||
780 | * Same concepts as "extract" (see comments above). | ||
781 | * The data mangled in the bit stream remains in little endian | ||
782 | * order the whole time. It make more sense to talk about | ||
783 | * endianness of register values by considering a register | ||
784 | * a "cached" copy of the little endiad bit stream. | ||
785 | */ | ||
762 | static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u32 value) | 786 | static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u32 value) |
763 | { | 787 | { |
764 | report += (offset >> 5) << 2; offset &= 31; | 788 | u64 x; |
765 | put_unaligned((get_unaligned((__le64*)report) | 789 | u64 m = (1ULL << n) - 1; |
766 | & cpu_to_le64(~((((__u64) 1 << n) - 1) << offset))) | 790 | |
767 | | cpu_to_le64((__u64)value << offset), (__le64*)report); | 791 | WARN_ON(n > 32); |
792 | |||
793 | WARN_ON(value > m); | ||
794 | value &= m; | ||
795 | |||
796 | report += offset >> 3; | ||
797 | offset &= 7; | ||
798 | |||
799 | x = get_unaligned((u64 *)report); | ||
800 | x &= cpu_to_le64(~(m << offset)); | ||
801 | x |= cpu_to_le64(((u64) value) << offset); | ||
802 | put_unaligned(x, (u64 *) report); | ||
768 | } | 803 | } |
769 | 804 | ||
770 | /* | 805 | /* |
@@ -1381,6 +1416,9 @@ void hid_close(struct hid_device *hid) | |||
1381 | 1416 | ||
1382 | #define USB_VENDOR_ID_PANJIT 0x134c | 1417 | #define USB_VENDOR_ID_PANJIT 0x134c |
1383 | 1418 | ||
1419 | #define USB_VENDOR_ID_TURBOX 0x062a | ||
1420 | #define USB_DEVICE_ID_TURBOX_KEYBOARD 0x0201 | ||
1421 | |||
1384 | /* | 1422 | /* |
1385 | * Initialize all reports | 1423 | * Initialize all reports |
1386 | */ | 1424 | */ |
@@ -1602,6 +1640,9 @@ void hid_init_reports(struct hid_device *hid) | |||
1602 | #define USB_VENDOR_ID_SUN 0x0430 | 1640 | #define USB_VENDOR_ID_SUN 0x0430 |
1603 | #define USB_DEVICE_ID_RARITAN_KVM_DONGLE 0xcdab | 1641 | #define USB_DEVICE_ID_RARITAN_KVM_DONGLE 0xcdab |
1604 | 1642 | ||
1643 | #define USB_VENDOR_ID_AIRCABLE 0x16CA | ||
1644 | #define USB_DEVICE_ID_AIRCABLE1 0x1502 | ||
1645 | |||
1605 | /* | 1646 | /* |
1606 | * Alphabetically sorted blacklist by quirk type. | 1647 | * Alphabetically sorted blacklist by quirk type. |
1607 | */ | 1648 | */ |
@@ -1619,6 +1660,7 @@ static const struct hid_blacklist { | |||
1619 | { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_22, HID_QUIRK_IGNORE }, | 1660 | { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_22, HID_QUIRK_IGNORE }, |
1620 | { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_23, HID_QUIRK_IGNORE }, | 1661 | { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_23, HID_QUIRK_IGNORE }, |
1621 | { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_24, HID_QUIRK_IGNORE }, | 1662 | { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_24, HID_QUIRK_IGNORE }, |
1663 | { USB_VENDOR_ID_AIRCABLE, USB_DEVICE_ID_AIRCABLE1, HID_QUIRK_IGNORE }, | ||
1622 | { USB_VENDOR_ID_ALCOR, USB_DEVICE_ID_ALCOR_USBRS232, HID_QUIRK_IGNORE }, | 1664 | { USB_VENDOR_ID_ALCOR, USB_DEVICE_ID_ALCOR_USBRS232, HID_QUIRK_IGNORE }, |
1623 | { USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD, HID_QUIRK_IGNORE }, | 1665 | { USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD, HID_QUIRK_IGNORE }, |
1624 | { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW40, HID_QUIRK_IGNORE }, | 1666 | { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW40, HID_QUIRK_IGNORE }, |
@@ -1755,11 +1797,12 @@ static const struct hid_blacklist { | |||
1755 | { USB_VENDOR_ID_APPLE, 0x020E, HID_QUIRK_POWERBOOK_HAS_FN }, | 1797 | { USB_VENDOR_ID_APPLE, 0x020E, HID_QUIRK_POWERBOOK_HAS_FN }, |
1756 | { USB_VENDOR_ID_APPLE, 0x020F, HID_QUIRK_POWERBOOK_HAS_FN }, | 1798 | { USB_VENDOR_ID_APPLE, 0x020F, HID_QUIRK_POWERBOOK_HAS_FN }, |
1757 | { USB_VENDOR_ID_APPLE, 0x0214, HID_QUIRK_POWERBOOK_HAS_FN }, | 1799 | { USB_VENDOR_ID_APPLE, 0x0214, HID_QUIRK_POWERBOOK_HAS_FN }, |
1758 | { USB_VENDOR_ID_APPLE, 0x0215, HID_QUIRK_POWERBOOK_HAS_FN }, | 1800 | { USB_VENDOR_ID_APPLE, 0x0215, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_POWERBOOK_ISO_KEYBOARD}, |
1759 | { USB_VENDOR_ID_APPLE, 0x0216, HID_QUIRK_POWERBOOK_HAS_FN }, | 1801 | { USB_VENDOR_ID_APPLE, 0x0216, HID_QUIRK_POWERBOOK_HAS_FN }, |
1760 | { USB_VENDOR_ID_APPLE, 0x0217, HID_QUIRK_POWERBOOK_HAS_FN }, | 1802 | { USB_VENDOR_ID_APPLE, 0x0217, HID_QUIRK_POWERBOOK_HAS_FN }, |
1761 | { USB_VENDOR_ID_APPLE, 0x0218, HID_QUIRK_POWERBOOK_HAS_FN }, | 1803 | { USB_VENDOR_ID_APPLE, 0x0218, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_POWERBOOK_ISO_KEYBOARD}, |
1762 | { USB_VENDOR_ID_APPLE, 0x0219, HID_QUIRK_POWERBOOK_HAS_FN }, | 1804 | { USB_VENDOR_ID_APPLE, 0x0219, HID_QUIRK_POWERBOOK_HAS_FN }, |
1805 | { USB_VENDOR_ID_APPLE, 0x021B, HID_QUIRK_POWERBOOK_HAS_FN }, | ||
1763 | { USB_VENDOR_ID_APPLE, 0x030A, HID_QUIRK_POWERBOOK_HAS_FN }, | 1806 | { USB_VENDOR_ID_APPLE, 0x030A, HID_QUIRK_POWERBOOK_HAS_FN }, |
1764 | { USB_VENDOR_ID_APPLE, 0x030B, HID_QUIRK_POWERBOOK_HAS_FN }, | 1807 | { USB_VENDOR_ID_APPLE, 0x030B, HID_QUIRK_POWERBOOK_HAS_FN }, |
1765 | 1808 | ||
@@ -1768,6 +1811,8 @@ static const struct hid_blacklist { | |||
1768 | { USB_VENDOR_ID_PANJIT, 0x0003, HID_QUIRK_IGNORE }, | 1811 | { USB_VENDOR_ID_PANJIT, 0x0003, HID_QUIRK_IGNORE }, |
1769 | { USB_VENDOR_ID_PANJIT, 0x0004, HID_QUIRK_IGNORE }, | 1812 | { USB_VENDOR_ID_PANJIT, 0x0004, HID_QUIRK_IGNORE }, |
1770 | 1813 | ||
1814 | { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET }, | ||
1815 | |||
1771 | { 0, 0 } | 1816 | { 0, 0 } |
1772 | }; | 1817 | }; |
1773 | 1818 | ||
diff --git a/drivers/usb/input/hid-input.c b/drivers/usb/input/hid-input.c index 9a808a3b4d37..68e7ebb978a9 100644 --- a/drivers/usb/input/hid-input.c +++ b/drivers/usb/input/hid-input.c | |||
@@ -121,6 +121,12 @@ static struct hidinput_key_translation powerbook_numlock_keys[] = { | |||
121 | { } | 121 | { } |
122 | }; | 122 | }; |
123 | 123 | ||
124 | static struct hidinput_key_translation powerbook_iso_keyboard[] = { | ||
125 | { KEY_GRAVE, KEY_102ND }, | ||
126 | { KEY_102ND, KEY_GRAVE }, | ||
127 | { } | ||
128 | }; | ||
129 | |||
124 | static int usbhid_pb_fnmode = 1; | 130 | static int usbhid_pb_fnmode = 1; |
125 | module_param_named(pb_fnmode, usbhid_pb_fnmode, int, 0644); | 131 | module_param_named(pb_fnmode, usbhid_pb_fnmode, int, 0644); |
126 | MODULE_PARM_DESC(pb_fnmode, | 132 | MODULE_PARM_DESC(pb_fnmode, |
@@ -195,6 +201,14 @@ static int hidinput_pb_event(struct hid_device *hid, struct input_dev *input, | |||
195 | } | 201 | } |
196 | } | 202 | } |
197 | 203 | ||
204 | if (hid->quirks & HID_QUIRK_POWERBOOK_ISO_KEYBOARD) { | ||
205 | trans = find_translation(powerbook_iso_keyboard, usage->code); | ||
206 | if (trans) { | ||
207 | input_event(input, usage->type, trans->to, value); | ||
208 | return 1; | ||
209 | } | ||
210 | } | ||
211 | |||
198 | return 0; | 212 | return 0; |
199 | } | 213 | } |
200 | 214 | ||
@@ -210,6 +224,9 @@ static void hidinput_pb_setup(struct input_dev *input) | |||
210 | 224 | ||
211 | for (trans = powerbook_numlock_keys; trans->from; trans++) | 225 | for (trans = powerbook_numlock_keys; trans->from; trans++) |
212 | set_bit(trans->to, input->keybit); | 226 | set_bit(trans->to, input->keybit); |
227 | |||
228 | for (trans = powerbook_iso_keyboard; trans->from; trans++) | ||
229 | set_bit(trans->to, input->keybit); | ||
213 | } | 230 | } |
214 | #else | 231 | #else |
215 | static inline int hidinput_pb_event(struct hid_device *hid, struct input_dev *input, | 232 | static inline int hidinput_pb_event(struct hid_device *hid, struct input_dev *input, |
diff --git a/drivers/usb/input/hid.h b/drivers/usb/input/hid.h index 9b50effef758..0e76e6dcac37 100644 --- a/drivers/usb/input/hid.h +++ b/drivers/usb/input/hid.h | |||
@@ -260,6 +260,7 @@ struct hid_item { | |||
260 | #define HID_QUIRK_POWERBOOK_HAS_FN 0x00001000 | 260 | #define HID_QUIRK_POWERBOOK_HAS_FN 0x00001000 |
261 | #define HID_QUIRK_POWERBOOK_FN_ON 0x00002000 | 261 | #define HID_QUIRK_POWERBOOK_FN_ON 0x00002000 |
262 | #define HID_QUIRK_INVERT_HWHEEL 0x00004000 | 262 | #define HID_QUIRK_INVERT_HWHEEL 0x00004000 |
263 | #define HID_QUIRK_POWERBOOK_ISO_KEYBOARD 0x00008000 | ||
263 | 264 | ||
264 | /* | 265 | /* |
265 | * This is the global environment of the parser. This information is | 266 | * This is the global environment of the parser. This information is |
diff --git a/drivers/usb/input/usbtouchscreen.c b/drivers/usb/input/usbtouchscreen.c index f26c1cd1129f..933ceddf3dee 100644 --- a/drivers/usb/input/usbtouchscreen.c +++ b/drivers/usb/input/usbtouchscreen.c | |||
@@ -256,10 +256,10 @@ static int itm_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *pr | |||
256 | { | 256 | { |
257 | *x = ((pkt[0] & 0x1F) << 7) | (pkt[3] & 0x7F); | 257 | *x = ((pkt[0] & 0x1F) << 7) | (pkt[3] & 0x7F); |
258 | *y = ((pkt[1] & 0x1F) << 7) | (pkt[4] & 0x7F); | 258 | *y = ((pkt[1] & 0x1F) << 7) | (pkt[4] & 0x7F); |
259 | *press = ((pkt[2] & 0x1F) << 7) | (pkt[5] & 0x7F); | 259 | *press = ((pkt[2] & 0x01) << 7) | (pkt[5] & 0x7F); |
260 | *touch = ~pkt[7] & 0x20; | 260 | *touch = ~pkt[7] & 0x20; |
261 | 261 | ||
262 | return 1; | 262 | return *touch; |
263 | } | 263 | } |
264 | #endif | 264 | #endif |
265 | 265 | ||
@@ -640,7 +640,7 @@ static int usbtouch_probe(struct usb_interface *intf, | |||
640 | type->max_press, 0, 0); | 640 | type->max_press, 0, 0); |
641 | 641 | ||
642 | usb_fill_int_urb(usbtouch->irq, usbtouch->udev, | 642 | usb_fill_int_urb(usbtouch->irq, usbtouch->udev, |
643 | usb_rcvintpipe(usbtouch->udev, 0x81), | 643 | usb_rcvintpipe(usbtouch->udev, endpoint->bEndpointAddress), |
644 | usbtouch->data, type->rept_size, | 644 | usbtouch->data, type->rept_size, |
645 | usbtouch_irq, usbtouch, endpoint->bInterval); | 645 | usbtouch_irq, usbtouch, endpoint->bInterval); |
646 | 646 | ||
diff --git a/drivers/usb/input/wacom.h b/drivers/usb/input/wacom.h index 7b3840e378a8..1cf08f02c50e 100644 --- a/drivers/usb/input/wacom.h +++ b/drivers/usb/input/wacom.h | |||
@@ -63,6 +63,7 @@ | |||
63 | * v1.46 (pc) - Split wacom.c into wacom_sys.c and wacom_wac.c, | 63 | * v1.46 (pc) - Split wacom.c into wacom_sys.c and wacom_wac.c, |
64 | * - where wacom_sys.c deals with system specific code, | 64 | * - where wacom_sys.c deals with system specific code, |
65 | * - and wacom_wac.c deals with Wacom specific code | 65 | * - and wacom_wac.c deals with Wacom specific code |
66 | * - Support Intuos3 4x6 | ||
66 | */ | 67 | */ |
67 | 68 | ||
68 | /* | 69 | /* |
@@ -118,6 +119,7 @@ extern void wacom_input_sync(void *wcombo); | |||
118 | extern void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | 119 | extern void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_wac); |
119 | extern void input_dev_g4(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | 120 | extern void input_dev_g4(struct input_dev *input_dev, struct wacom_wac *wacom_wac); |
120 | extern void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | 121 | extern void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac); |
122 | extern void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | ||
121 | extern void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | 123 | extern void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac); |
122 | extern void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | 124 | extern void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac); |
123 | extern void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | 125 | extern void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac); |
diff --git a/drivers/usb/input/wacom_sys.c b/drivers/usb/input/wacom_sys.c index d233c37bd533..3498b893b53b 100644 --- a/drivers/usb/input/wacom_sys.c +++ b/drivers/usb/input/wacom_sys.c | |||
@@ -110,7 +110,7 @@ __u16 wacom_be16_to_cpu(unsigned char *data) | |||
110 | __u16 wacom_le16_to_cpu(unsigned char *data) | 110 | __u16 wacom_le16_to_cpu(unsigned char *data) |
111 | { | 111 | { |
112 | __u16 value; | 112 | __u16 value; |
113 | value = be16_to_cpu(*(__be16 *) data); | 113 | value = le16_to_cpu(*(__le16 *) data); |
114 | return value; | 114 | return value; |
115 | } | 115 | } |
116 | 116 | ||
@@ -143,7 +143,7 @@ void input_dev_g4(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | |||
143 | input_dev->evbit[0] |= BIT(EV_MSC); | 143 | input_dev->evbit[0] |= BIT(EV_MSC); |
144 | input_dev->mscbit[0] |= BIT(MSC_SERIAL); | 144 | input_dev->mscbit[0] |= BIT(MSC_SERIAL); |
145 | input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); | 145 | input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); |
146 | input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3) | BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7); | 146 | input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_4); |
147 | } | 147 | } |
148 | 148 | ||
149 | void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | 149 | void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac) |
@@ -155,11 +155,16 @@ void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | |||
155 | input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0); | 155 | input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0); |
156 | } | 156 | } |
157 | 157 | ||
158 | void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | 158 | void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac) |
159 | { | 159 | { |
160 | input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); | 160 | input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); |
161 | input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3) | BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7); | 161 | input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3); |
162 | input_set_abs_params(input_dev, ABS_RX, 0, 4097, 0, 0); | 162 | input_set_abs_params(input_dev, ABS_RX, 0, 4097, 0, 0); |
163 | } | ||
164 | |||
165 | void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | ||
166 | { | ||
167 | input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7); | ||
163 | input_set_abs_params(input_dev, ABS_RY, 0, 4097, 0, 0); | 168 | input_set_abs_params(input_dev, ABS_RY, 0, 4097, 0, 0); |
164 | } | 169 | } |
165 | 170 | ||
@@ -218,8 +223,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
218 | strlcat(wacom->phys, "/input0", sizeof(wacom->phys)); | 223 | strlcat(wacom->phys, "/input0", sizeof(wacom->phys)); |
219 | 224 | ||
220 | wacom_wac->features = get_wacom_feature(id); | 225 | wacom_wac->features = get_wacom_feature(id); |
221 | if (wacom_wac->features->pktlen > 10) | 226 | BUG_ON(wacom_wac->features->pktlen > 10); |
222 | BUG(); | ||
223 | 227 | ||
224 | input_dev->name = wacom_wac->features->name; | 228 | input_dev->name = wacom_wac->features->name; |
225 | wacom->wacom_wac = wacom_wac; | 229 | wacom->wacom_wac = wacom_wac; |
@@ -244,7 +248,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
244 | usb_fill_int_urb(wacom->irq, dev, | 248 | usb_fill_int_urb(wacom->irq, dev, |
245 | usb_rcvintpipe(dev, endpoint->bEndpointAddress), | 249 | usb_rcvintpipe(dev, endpoint->bEndpointAddress), |
246 | wacom_wac->data, wacom_wac->features->pktlen, | 250 | wacom_wac->data, wacom_wac->features->pktlen, |
247 | wacom_wac->features->irq, wacom, endpoint->bInterval); | 251 | wacom_sys_irq, wacom, endpoint->bInterval); |
248 | wacom->irq->transfer_dma = wacom->data_dma; | 252 | wacom->irq->transfer_dma = wacom->data_dma; |
249 | wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | 253 | wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
250 | 254 | ||
@@ -278,8 +282,8 @@ static void wacom_disconnect(struct usb_interface *intf) | |||
278 | input_unregister_device(wacom->dev); | 282 | input_unregister_device(wacom->dev); |
279 | usb_free_urb(wacom->irq); | 283 | usb_free_urb(wacom->irq); |
280 | usb_buffer_free(interface_to_usbdev(intf), 10, wacom->wacom_wac->data, wacom->data_dma); | 284 | usb_buffer_free(interface_to_usbdev(intf), 10, wacom->wacom_wac->data, wacom->data_dma); |
281 | kfree(wacom); | ||
282 | kfree(wacom->wacom_wac); | 285 | kfree(wacom->wacom_wac); |
286 | kfree(wacom); | ||
283 | } | 287 | } |
284 | } | 288 | } |
285 | 289 | ||
diff --git a/drivers/usb/input/wacom_wac.c b/drivers/usb/input/wacom_wac.c index aa31d22d4f05..92726fe89379 100644 --- a/drivers/usb/input/wacom_wac.c +++ b/drivers/usb/input/wacom_wac.c | |||
@@ -191,9 +191,9 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) | |||
191 | wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01); | 191 | wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01); |
192 | wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02); | 192 | wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02); |
193 | if (wacom->features->type == WACOM_G4) | 193 | if (wacom->features->type == WACOM_G4) |
194 | wacom_report_abs(wcombo, ABS_DISTANCE, data[6]); | 194 | wacom_report_abs(wcombo, ABS_DISTANCE, data[6] & 0x3f); |
195 | else | 195 | else |
196 | wacom_report_abs(wcombo, ABS_DISTANCE, data[7]); | 196 | wacom_report_abs(wcombo, ABS_DISTANCE, data[7] & 0x3f); |
197 | break; | 197 | break; |
198 | } | 198 | } |
199 | } | 199 | } |
@@ -303,8 +303,9 @@ static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo) | |||
303 | wacom->tool[idx] = BTN_TOOL_PEN; | 303 | wacom->tool[idx] = BTN_TOOL_PEN; |
304 | } | 304 | } |
305 | /* only large I3 support Lens Cursor */ | 305 | /* only large I3 support Lens Cursor */ |
306 | if(!((wacom->tool[idx] == BTN_TOOL_LENS) && | 306 | if(!((wacom->tool[idx] == BTN_TOOL_LENS) |
307 | (wacom->features->type == INTUOS3))) { | 307 | && ((wacom->features->type == INTUOS3) |
308 | || (wacom->features->type == INTUOS3S)))) { | ||
308 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[idx]); /* report tool id */ | 309 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[idx]); /* report tool id */ |
309 | wacom_report_key(wcombo, wacom->tool[idx], 1); | 310 | wacom_report_key(wcombo, wacom->tool[idx], 1); |
310 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, wacom->serial[idx]); | 311 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, wacom->serial[idx]); |
@@ -315,10 +316,14 @@ static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo) | |||
315 | 316 | ||
316 | /* Exit report */ | 317 | /* Exit report */ |
317 | if ((data[1] & 0xfe) == 0x80) { | 318 | if ((data[1] & 0xfe) == 0x80) { |
318 | wacom_report_key(wcombo, wacom->tool[idx], 0); | 319 | if(!((wacom->tool[idx] == BTN_TOOL_LENS) |
319 | wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */ | 320 | && ((wacom->features->type == INTUOS3) |
320 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, wacom->serial[idx]); | 321 | || (wacom->features->type == INTUOS3S)))) { |
321 | return 2; | 322 | wacom_report_key(wcombo, wacom->tool[idx], 0); |
323 | wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */ | ||
324 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, wacom->serial[idx]); | ||
325 | return 2; | ||
326 | } | ||
322 | } | 327 | } |
323 | return 0; | 328 | return 0; |
324 | } | 329 | } |
@@ -382,7 +387,8 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) | |||
382 | wacom_report_abs(wcombo, ABS_RX, ((data[1] & 0x1f) << 8) | data[2]); | 387 | wacom_report_abs(wcombo, ABS_RX, ((data[1] & 0x1f) << 8) | data[2]); |
383 | wacom_report_abs(wcombo, ABS_RY, ((data[3] & 0x1f) << 8) | data[4]); | 388 | wacom_report_abs(wcombo, ABS_RY, ((data[3] & 0x1f) << 8) | data[4]); |
384 | 389 | ||
385 | if((data[5] & 0x0f) | (data[6] & 0x0f) | (data[1] & 0x1f) | data[2]) | 390 | if((data[5] & 0x0f) | (data[6] & 0x0f) | (data[1] & 0x1f) | |
391 | data[2] | (data[3] & 0x1f) | data[4]) | ||
386 | wacom_report_key(wcombo, wacom->tool[1], 1); | 392 | wacom_report_key(wcombo, wacom->tool[1], 1); |
387 | else | 393 | else |
388 | wacom_report_key(wcombo, wacom->tool[1], 0); | 394 | wacom_report_key(wcombo, wacom->tool[1], 0); |
@@ -432,7 +438,7 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) | |||
432 | ((t - 1) / 2) : -t / 2); | 438 | ((t - 1) / 2) : -t / 2); |
433 | } | 439 | } |
434 | 440 | ||
435 | } else if (!(data[1] & 0x10) && wacom->features->type < INTUOS3) { | 441 | } else if (!(data[1] & 0x10) && wacom->features->type < INTUOS3S) { |
436 | /* 4D mouse packet */ | 442 | /* 4D mouse packet */ |
437 | wacom_report_key(wcombo, BTN_LEFT, data[8] & 0x01); | 443 | wacom_report_key(wcombo, BTN_LEFT, data[8] & 0x01); |
438 | wacom_report_key(wcombo, BTN_MIDDLE, data[8] & 0x02); | 444 | wacom_report_key(wcombo, BTN_MIDDLE, data[8] & 0x02); |
@@ -452,12 +458,12 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) | |||
452 | - ((data[8] & 0x02) >> 1)); | 458 | - ((data[8] & 0x02) >> 1)); |
453 | 459 | ||
454 | /* I3 2D mouse side buttons */ | 460 | /* I3 2D mouse side buttons */ |
455 | if (wacom->features->type == INTUOS3) { | 461 | if (wacom->features->type >= INTUOS3S && wacom->features->type <= INTUOS3L) { |
456 | wacom_report_key(wcombo, BTN_SIDE, data[8] & 0x40); | 462 | wacom_report_key(wcombo, BTN_SIDE, data[8] & 0x40); |
457 | wacom_report_key(wcombo, BTN_EXTRA, data[8] & 0x20); | 463 | wacom_report_key(wcombo, BTN_EXTRA, data[8] & 0x20); |
458 | } | 464 | } |
459 | 465 | ||
460 | } else if (wacom->features->type < INTUOS3) { | 466 | } else if (wacom->features->type < INTUOS3S || wacom->features->type == INTUOS3L) { |
461 | /* Lens cursor packets */ | 467 | /* Lens cursor packets */ |
462 | wacom_report_key(wcombo, BTN_LEFT, data[8] & 0x01); | 468 | wacom_report_key(wcombo, BTN_LEFT, data[8] & 0x01); |
463 | wacom_report_key(wcombo, BTN_MIDDLE, data[8] & 0x02); | 469 | wacom_report_key(wcombo, BTN_MIDDLE, data[8] & 0x02); |
@@ -490,6 +496,7 @@ int wacom_wac_irq(struct wacom_wac *wacom_wac, void *wcombo) | |||
490 | return (wacom_ptu_irq(wacom_wac, wcombo)); | 496 | return (wacom_ptu_irq(wacom_wac, wcombo)); |
491 | break; | 497 | break; |
492 | case INTUOS: | 498 | case INTUOS: |
499 | case INTUOS3S: | ||
493 | case INTUOS3: | 500 | case INTUOS3: |
494 | case INTUOS3L: | 501 | case INTUOS3L: |
495 | case CINTIQ: | 502 | case CINTIQ: |
@@ -515,6 +522,8 @@ void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_w | |||
515 | case CINTIQ: | 522 | case CINTIQ: |
516 | input_dev_i3(input_dev, wacom_wac); | 523 | input_dev_i3(input_dev, wacom_wac); |
517 | /* fall through */ | 524 | /* fall through */ |
525 | case INTUOS3S: | ||
526 | input_dev_i3s(input_dev, wacom_wac); | ||
518 | case INTUOS: | 527 | case INTUOS: |
519 | input_dev_i(input_dev, wacom_wac); | 528 | input_dev_i(input_dev, wacom_wac); |
520 | break; | 529 | break; |
@@ -530,49 +539,50 @@ void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_w | |||
530 | } | 539 | } |
531 | 540 | ||
532 | static struct wacom_features wacom_features[] = { | 541 | static struct wacom_features wacom_features[] = { |
533 | { "Wacom Penpartner", 7, 5040, 3780, 255, 32, PENPARTNER, wacom_sys_irq }, | 542 | { "Wacom Penpartner", 7, 5040, 3780, 255, 0, PENPARTNER }, |
534 | { "Wacom Graphire", 8, 10206, 7422, 511, 32, GRAPHIRE, wacom_sys_irq }, | 543 | { "Wacom Graphire", 8, 10206, 7422, 511, 63, GRAPHIRE }, |
535 | { "Wacom Graphire2 4x5", 8, 10206, 7422, 511, 32, GRAPHIRE, wacom_sys_irq }, | 544 | { "Wacom Graphire2 4x5", 8, 10206, 7422, 511, 63, GRAPHIRE }, |
536 | { "Wacom Graphire2 5x7", 8, 13918, 10206, 511, 32, GRAPHIRE, wacom_sys_irq }, | 545 | { "Wacom Graphire2 5x7", 8, 13918, 10206, 511, 63, GRAPHIRE }, |
537 | { "Wacom Graphire3", 8, 10208, 7424, 511, 32, GRAPHIRE, wacom_sys_irq }, | 546 | { "Wacom Graphire3", 8, 10208, 7424, 511, 63, GRAPHIRE }, |
538 | { "Wacom Graphire3 6x8", 8, 16704, 12064, 511, 32, GRAPHIRE, wacom_sys_irq }, | 547 | { "Wacom Graphire3 6x8", 8, 16704, 12064, 511, 63, GRAPHIRE }, |
539 | { "Wacom Graphire4 4x5", 8, 10208, 7424, 511, 32, WACOM_G4, wacom_sys_irq }, | 548 | { "Wacom Graphire4 4x5", 8, 10208, 7424, 511, 63, WACOM_G4 }, |
540 | { "Wacom Graphire4 6x8", 8, 16704, 12064, 511, 32, WACOM_G4, wacom_sys_irq }, | 549 | { "Wacom Graphire4 6x8", 8, 16704, 12064, 511, 63, WACOM_G4 }, |
541 | { "Wacom Volito", 8, 5104, 3712, 511, 32, GRAPHIRE, wacom_sys_irq }, | 550 | { "Wacom Volito", 8, 5104, 3712, 511, 0, GRAPHIRE }, |
542 | { "Wacom PenStation2", 8, 3250, 2320, 255, 32, GRAPHIRE, wacom_sys_irq }, | 551 | { "Wacom PenStation2", 8, 3250, 2320, 255, 0, GRAPHIRE }, |
543 | { "Wacom Volito2 4x5", 8, 5104, 3712, 511, 32, GRAPHIRE, wacom_sys_irq }, | 552 | { "Wacom Volito2 4x5", 8, 5104, 3712, 511, 0, GRAPHIRE }, |
544 | { "Wacom Volito2 2x3", 8, 3248, 2320, 511, 32, GRAPHIRE, wacom_sys_irq }, | 553 | { "Wacom Volito2 2x3", 8, 3248, 2320, 511, 0, GRAPHIRE }, |
545 | { "Wacom PenPartner2", 8, 3250, 2320, 255, 32, GRAPHIRE, wacom_sys_irq }, | 554 | { "Wacom PenPartner2", 8, 3250, 2320, 255, 0, GRAPHIRE }, |
546 | { "Wacom Intuos 4x5", 10, 12700, 10600, 1023, 15, INTUOS, wacom_sys_irq}, | 555 | { "Wacom Intuos 4x5", 10, 12700, 10600, 1023, 63, INTUOS }, |
547 | { "Wacom Intuos 6x8", 10, 20320, 16240, 1023, 15, INTUOS, wacom_sys_irq }, | 556 | { "Wacom Intuos 6x8", 10, 20320, 16240, 1023, 63, INTUOS }, |
548 | { "Wacom Intuos 9x12", 10, 30480, 24060, 1023, 15, INTUOS, wacom_sys_irq }, | 557 | { "Wacom Intuos 9x12", 10, 30480, 24060, 1023, 63, INTUOS }, |
549 | { "Wacom Intuos 12x12", 10, 30480, 31680, 1023, 15, INTUOS, wacom_sys_irq }, | 558 | { "Wacom Intuos 12x12", 10, 30480, 31680, 1023, 63, INTUOS }, |
550 | { "Wacom Intuos 12x18", 10, 45720, 31680, 1023, 15, INTUOS, wacom_sys_irq}, | 559 | { "Wacom Intuos 12x18", 10, 45720, 31680, 1023, 63, INTUOS }, |
551 | { "Wacom PL400", 8, 5408, 4056, 255, 32, PL, wacom_sys_irq }, | 560 | { "Wacom PL400", 8, 5408, 4056, 255, 0, PL }, |
552 | { "Wacom PL500", 8, 6144, 4608, 255, 32, PL, wacom_sys_irq }, | 561 | { "Wacom PL500", 8, 6144, 4608, 255, 0, PL }, |
553 | { "Wacom PL600", 8, 6126, 4604, 255, 32, PL, wacom_sys_irq }, | 562 | { "Wacom PL600", 8, 6126, 4604, 255, 0, PL }, |
554 | { "Wacom PL600SX", 8, 6260, 5016, 255, 32, PL, wacom_sys_irq }, | 563 | { "Wacom PL600SX", 8, 6260, 5016, 255, 0, PL }, |
555 | { "Wacom PL550", 8, 6144, 4608, 511, 32, PL, wacom_sys_irq }, | 564 | { "Wacom PL550", 8, 6144, 4608, 511, 0, PL }, |
556 | { "Wacom PL800", 8, 7220, 5780, 511, 32, PL, wacom_sys_irq }, | 565 | { "Wacom PL800", 8, 7220, 5780, 511, 0, PL }, |
557 | { "Wacom PL700", 8, 6758, 5406, 511, 32, PL, wacom_sys_irq }, | 566 | { "Wacom PL700", 8, 6758, 5406, 511, 0, PL }, |
558 | { "Wacom PL510", 8, 6282, 4762, 511, 32, PL, wacom_sys_irq }, | 567 | { "Wacom PL510", 8, 6282, 4762, 511, 0, PL }, |
559 | { "Wacom DTU710", 8, 34080, 27660, 511, 32, PL, wacom_sys_irq }, | 568 | { "Wacom DTU710", 8, 34080, 27660, 511, 0, PL }, |
560 | { "Wacom DTF521", 8, 6282, 4762, 511, 32, PL, wacom_sys_irq }, | 569 | { "Wacom DTF521", 8, 6282, 4762, 511, 0, PL }, |
561 | { "Wacom DTF720", 8, 6858, 5506, 511, 32, PL, wacom_sys_irq }, | 570 | { "Wacom DTF720", 8, 6858, 5506, 511, 0, PL }, |
562 | { "Wacom Cintiq Partner",8, 20480, 15360, 511, 32, PTU, wacom_sys_irq }, | 571 | { "Wacom Cintiq Partner",8, 20480, 15360, 511, 0, PTU }, |
563 | { "Wacom Intuos2 4x5", 10, 12700, 10600, 1023, 15, INTUOS, wacom_sys_irq }, | 572 | { "Wacom Intuos2 4x5", 10, 12700, 10600, 1023, 63, INTUOS }, |
564 | { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 15, INTUOS, wacom_sys_irq }, | 573 | { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 63, INTUOS }, |
565 | { "Wacom Intuos2 9x12", 10, 30480, 24060, 1023, 15, INTUOS, wacom_sys_irq }, | 574 | { "Wacom Intuos2 9x12", 10, 30480, 24060, 1023, 63, INTUOS }, |
566 | { "Wacom Intuos2 12x12", 10, 30480, 31680, 1023, 15, INTUOS, wacom_sys_irq }, | 575 | { "Wacom Intuos2 12x12", 10, 30480, 31680, 1023, 63, INTUOS }, |
567 | { "Wacom Intuos2 12x18", 10, 45720, 31680, 1023, 15, INTUOS, wacom_sys_irq }, | 576 | { "Wacom Intuos2 12x18", 10, 45720, 31680, 1023, 63, INTUOS }, |
568 | { "Wacom Intuos3 4x5", 10, 25400, 20320, 1023, 15, INTUOS3, wacom_sys_irq }, | 577 | { "Wacom Intuos3 4x5", 10, 25400, 20320, 1023, 63, INTUOS3S }, |
569 | { "Wacom Intuos3 6x8", 10, 40640, 30480, 1023, 15, INTUOS3, wacom_sys_irq }, | 578 | { "Wacom Intuos3 6x8", 10, 40640, 30480, 1023, 63, INTUOS3 }, |
570 | { "Wacom Intuos3 9x12", 10, 60960, 45720, 1023, 15, INTUOS3, wacom_sys_irq }, | 579 | { "Wacom Intuos3 9x12", 10, 60960, 45720, 1023, 63, INTUOS3 }, |
571 | { "Wacom Intuos3 12x12", 10, 60960, 60960, 1023, 15, INTUOS3L, wacom_sys_irq }, | 580 | { "Wacom Intuos3 12x12", 10, 60960, 60960, 1023, 63, INTUOS3L }, |
572 | { "Wacom Intuos3 12x19", 10, 97536, 60960, 1023, 15, INTUOS3L, wacom_sys_irq }, | 581 | { "Wacom Intuos3 12x19", 10, 97536, 60960, 1023, 63, INTUOS3L }, |
573 | { "Wacom Intuos3 6x11", 10, 54204, 31750, 1023, 15, INTUOS3, wacom_sys_irq }, | 582 | { "Wacom Intuos3 6x11", 10, 54204, 31750, 1023, 63, INTUOS3 }, |
574 | { "Wacom Cintiq 21UX", 10, 87200, 65600, 1023, 15, CINTIQ, wacom_sys_irq }, | 583 | { "Wacom Intuos3 4x6", 10, 31496, 19685, 1023, 15, INTUOS3S }, |
575 | { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 15, INTUOS, wacom_sys_irq }, | 584 | { "Wacom Cintiq 21UX", 10, 87200, 65600, 1023, 63, CINTIQ }, |
585 | { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 63, INTUOS }, | ||
576 | { } | 586 | { } |
577 | }; | 587 | }; |
578 | 588 | ||
@@ -618,6 +628,7 @@ static struct usb_device_id wacom_ids[] = { | |||
618 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB3) }, | 628 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB3) }, |
619 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB4) }, | 629 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB4) }, |
620 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB5) }, | 630 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB5) }, |
631 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB7) }, | ||
621 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x3F) }, | 632 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x3F) }, |
622 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x47) }, | 633 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x47) }, |
623 | { } | 634 | { } |
diff --git a/drivers/usb/input/wacom_wac.h b/drivers/usb/input/wacom_wac.h index ceae7bf59d9f..a1d9ce007970 100644 --- a/drivers/usb/input/wacom_wac.h +++ b/drivers/usb/input/wacom_wac.h | |||
@@ -20,6 +20,7 @@ enum { | |||
20 | PTU, | 20 | PTU, |
21 | PL, | 21 | PL, |
22 | INTUOS, | 22 | INTUOS, |
23 | INTUOS3S, | ||
23 | INTUOS3, | 24 | INTUOS3, |
24 | INTUOS3L, | 25 | INTUOS3L, |
25 | CINTIQ, | 26 | CINTIQ, |
@@ -34,7 +35,6 @@ struct wacom_features { | |||
34 | int pressure_max; | 35 | int pressure_max; |
35 | int distance_max; | 36 | int distance_max; |
36 | int type; | 37 | int type; |
37 | usb_complete_t irq; | ||
38 | }; | 38 | }; |
39 | 39 | ||
40 | struct wacom_wac { | 40 | struct wacom_wac { |
diff --git a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c index cebb6c463bfb..df97e5c803f9 100644 --- a/drivers/usb/input/xpad.c +++ b/drivers/usb/input/xpad.c | |||
@@ -1,8 +1,13 @@ | |||
1 | /* | 1 | /* |
2 | * X-Box gamepad - v0.0.5 | 2 | * X-Box gamepad - v0.0.6 |
3 | * | 3 | * |
4 | * Copyright (c) 2002 Marko Friedemann <mfr@bmx-chemnitz.de> | 4 | * Copyright (c) 2002 Marko Friedemann <mfr@bmx-chemnitz.de> |
5 | * | 5 | * 2004 Oliver Schwartz <Oliver.Schwartz@gmx.de>, |
6 | * Steven Toth <steve@toth.demon.co.uk>, | ||
7 | * Franz Lehner <franz@caos.at>, | ||
8 | * Ivan Hawkes <blackhawk@ivanhawkes.com> | ||
9 | * 2005 Dominic Cerquetti <binary1230@yahoo.com> | ||
10 | * 2006 Adam Buchbinder <adam.buchbinder@gmail.com> | ||
6 | * | 11 | * |
7 | * This program is free software; you can redistribute it and/or | 12 | * This program is free software; you can redistribute it and/or |
8 | * modify it under the terms of the GNU General Public License as | 13 | * modify it under the terms of the GNU General Public License as |
@@ -28,11 +33,13 @@ | |||
28 | * - ITO Takayuki for providing essential xpad information on his website | 33 | * - ITO Takayuki for providing essential xpad information on his website |
29 | * - Vojtech Pavlik - iforce driver / input subsystem | 34 | * - Vojtech Pavlik - iforce driver / input subsystem |
30 | * - Greg Kroah-Hartman - usb-skeleton driver | 35 | * - Greg Kroah-Hartman - usb-skeleton driver |
36 | * - XBOX Linux project - extra USB id's | ||
31 | * | 37 | * |
32 | * TODO: | 38 | * TODO: |
33 | * - fine tune axes | 39 | * - fine tune axes (especially trigger axes) |
34 | * - fix "analog" buttons (reported as digital now) | 40 | * - fix "analog" buttons (reported as digital now) |
35 | * - get rumble working | 41 | * - get rumble working |
42 | * - need USB IDs for other dance pads | ||
36 | * | 43 | * |
37 | * History: | 44 | * History: |
38 | * | 45 | * |
@@ -52,30 +59,79 @@ | |||
52 | * - fixed d-pad to axes mapping | 59 | * - fixed d-pad to axes mapping |
53 | * | 60 | * |
54 | * 2002-07-17 - 0.0.5 : simplified d-pad handling | 61 | * 2002-07-17 - 0.0.5 : simplified d-pad handling |
62 | * | ||
63 | * 2004-10-02 - 0.0.6 : DDR pad support | ||
64 | * - borrowed from the XBOX linux kernel | ||
65 | * - USB id's for commonly used dance pads are present | ||
66 | * - dance pads will map D-PAD to buttons, not axes | ||
67 | * - pass the module paramater 'dpad_to_buttons' to force | ||
68 | * the D-PAD to map to buttons if your pad is not detected | ||
55 | */ | 69 | */ |
56 | 70 | ||
57 | #include <linux/kernel.h> | 71 | #include <linux/kernel.h> |
58 | #include <linux/init.h> | 72 | #include <linux/init.h> |
59 | #include <linux/slab.h> | 73 | #include <linux/slab.h> |
74 | #include <linux/stat.h> | ||
60 | #include <linux/module.h> | 75 | #include <linux/module.h> |
76 | #include <linux/moduleparam.h> | ||
61 | #include <linux/smp_lock.h> | 77 | #include <linux/smp_lock.h> |
62 | #include <linux/usb/input.h> | 78 | #include <linux/usb/input.h> |
63 | 79 | ||
64 | #define DRIVER_VERSION "v0.0.5" | 80 | #define DRIVER_VERSION "v0.0.6" |
65 | #define DRIVER_AUTHOR "Marko Friedemann <mfr@bmx-chemnitz.de>" | 81 | #define DRIVER_AUTHOR "Marko Friedemann <mfr@bmx-chemnitz.de>" |
66 | #define DRIVER_DESC "X-Box pad driver" | 82 | #define DRIVER_DESC "X-Box pad driver" |
67 | 83 | ||
68 | #define XPAD_PKT_LEN 32 | 84 | #define XPAD_PKT_LEN 32 |
69 | 85 | ||
86 | /* xbox d-pads should map to buttons, as is required for DDR pads | ||
87 | but we map them to axes when possible to simplify things */ | ||
88 | #define MAP_DPAD_TO_BUTTONS 0 | ||
89 | #define MAP_DPAD_TO_AXES 1 | ||
90 | #define MAP_DPAD_UNKNOWN -1 | ||
91 | |||
92 | static int dpad_to_buttons; | ||
93 | module_param(dpad_to_buttons, bool, S_IRUGO); | ||
94 | MODULE_PARM_DESC(dpad_to_buttons, "Map D-PAD to buttons rather than axes for unknown pads"); | ||
95 | |||
70 | static const struct xpad_device { | 96 | static const struct xpad_device { |
71 | u16 idVendor; | 97 | u16 idVendor; |
72 | u16 idProduct; | 98 | u16 idProduct; |
73 | char *name; | 99 | char *name; |
100 | u8 dpad_mapping; | ||
74 | } xpad_device[] = { | 101 | } xpad_device[] = { |
75 | { 0x045e, 0x0202, "Microsoft X-Box pad (US)" }, | 102 | { 0x045e, 0x0202, "Microsoft X-Box pad v1 (US)", MAP_DPAD_TO_AXES }, |
76 | { 0x045e, 0x0285, "Microsoft X-Box pad (Japan)" }, | 103 | { 0x045e, 0x0289, "Microsoft X-Box pad v2 (US)", MAP_DPAD_TO_AXES }, |
77 | { 0x05fd, 0x107a, "InterAct 'PowerPad Pro' X-Box pad (Germany)" }, | 104 | { 0x045e, 0x0285, "Microsoft X-Box pad (Japan)", MAP_DPAD_TO_AXES }, |
78 | { 0x0000, 0x0000, "X-Box pad" } | 105 | { 0x045e, 0x0287, "Microsoft Xbox Controller S", MAP_DPAD_TO_AXES }, |
106 | { 0x0c12, 0x8809, "RedOctane Xbox Dance Pad", MAP_DPAD_TO_BUTTONS }, | ||
107 | { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", MAP_DPAD_TO_AXES }, | ||
108 | { 0x046d, 0xca84, "Logitech Xbox Cordless Controller", MAP_DPAD_TO_AXES }, | ||
109 | { 0x046d, 0xca88, "Logitech Compact Controller for Xbox", MAP_DPAD_TO_AXES }, | ||
110 | { 0x05fd, 0x1007, "Mad Catz Controller (unverified)", MAP_DPAD_TO_AXES }, | ||
111 | { 0x05fd, 0x107a, "InterAct 'PowerPad Pro' X-Box pad (Germany)", MAP_DPAD_TO_AXES }, | ||
112 | { 0x0738, 0x4516, "Mad Catz Control Pad", MAP_DPAD_TO_AXES }, | ||
113 | { 0x0738, 0x4522, "Mad Catz LumiCON", MAP_DPAD_TO_AXES }, | ||
114 | { 0x0738, 0x4526, "Mad Catz Control Pad Pro", MAP_DPAD_TO_AXES }, | ||
115 | { 0x0738, 0x4536, "Mad Catz MicroCON", MAP_DPAD_TO_AXES }, | ||
116 | { 0x0738, 0x4540, "Mad Catz Beat Pad", MAP_DPAD_TO_BUTTONS }, | ||
117 | { 0x0738, 0x4556, "Mad Catz Lynx Wireless Controller", MAP_DPAD_TO_AXES }, | ||
118 | { 0x0738, 0x6040, "Mad Catz Beat Pad Pro", MAP_DPAD_TO_BUTTONS }, | ||
119 | { 0x0c12, 0x8802, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES }, | ||
120 | { 0x0c12, 0x8810, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES }, | ||
121 | { 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", MAP_DPAD_TO_AXES }, | ||
122 | { 0x0e4c, 0x1097, "Radica Gamester Controller", MAP_DPAD_TO_AXES }, | ||
123 | { 0x0e4c, 0x2390, "Radica Games Jtech Controller", MAP_DPAD_TO_AXES}, | ||
124 | { 0x0e6f, 0x0003, "Logic3 Freebird wireless Controller", MAP_DPAD_TO_AXES }, | ||
125 | { 0x0e6f, 0x0005, "Eclipse wireless Controller", MAP_DPAD_TO_AXES }, | ||
126 | { 0x0e6f, 0x0006, "Edge wireless Controller", MAP_DPAD_TO_AXES }, | ||
127 | { 0x0e8f, 0x0201, "SmartJoy Frag Xpad/PS2 adaptor", MAP_DPAD_TO_AXES }, | ||
128 | { 0x0f30, 0x0202, "Joytech Advanced Controller", MAP_DPAD_TO_AXES }, | ||
129 | { 0x0f30, 0x8888, "BigBen XBMiniPad Controller", MAP_DPAD_TO_AXES }, | ||
130 | { 0x102c, 0xff0c, "Joytech Wireless Advanced Controller", MAP_DPAD_TO_AXES }, | ||
131 | { 0x12ab, 0x8809, "Xbox DDR dancepad", MAP_DPAD_TO_BUTTONS }, | ||
132 | { 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS }, | ||
133 | { 0xffff, 0xffff, "Chinese-made Xbox Controller", MAP_DPAD_TO_AXES }, | ||
134 | { 0x0000, 0x0000, "Generic X-Box pad", MAP_DPAD_UNKNOWN } | ||
79 | }; | 135 | }; |
80 | 136 | ||
81 | static const signed short xpad_btn[] = { | 137 | static const signed short xpad_btn[] = { |
@@ -84,11 +140,23 @@ static const signed short xpad_btn[] = { | |||
84 | -1 /* terminating entry */ | 140 | -1 /* terminating entry */ |
85 | }; | 141 | }; |
86 | 142 | ||
143 | /* only used if MAP_DPAD_TO_BUTTONS */ | ||
144 | static const signed short xpad_btn_pad[] = { | ||
145 | BTN_LEFT, BTN_RIGHT, /* d-pad left, right */ | ||
146 | BTN_0, BTN_1, /* d-pad up, down (XXX names??) */ | ||
147 | -1 /* terminating entry */ | ||
148 | }; | ||
149 | |||
87 | static const signed short xpad_abs[] = { | 150 | static const signed short xpad_abs[] = { |
88 | ABS_X, ABS_Y, /* left stick */ | 151 | ABS_X, ABS_Y, /* left stick */ |
89 | ABS_RX, ABS_RY, /* right stick */ | 152 | ABS_RX, ABS_RY, /* right stick */ |
90 | ABS_Z, ABS_RZ, /* triggers left/right */ | 153 | ABS_Z, ABS_RZ, /* triggers left/right */ |
91 | ABS_HAT0X, ABS_HAT0Y, /* digital pad */ | 154 | -1 /* terminating entry */ |
155 | }; | ||
156 | |||
157 | /* only used if MAP_DPAD_TO_AXES */ | ||
158 | static const signed short xpad_abs_pad[] = { | ||
159 | ABS_HAT0X, ABS_HAT0Y, /* d-pad axes */ | ||
92 | -1 /* terminating entry */ | 160 | -1 /* terminating entry */ |
93 | }; | 161 | }; |
94 | 162 | ||
@@ -100,14 +168,16 @@ static struct usb_device_id xpad_table [] = { | |||
100 | MODULE_DEVICE_TABLE (usb, xpad_table); | 168 | MODULE_DEVICE_TABLE (usb, xpad_table); |
101 | 169 | ||
102 | struct usb_xpad { | 170 | struct usb_xpad { |
103 | struct input_dev *dev; /* input device interface */ | 171 | struct input_dev *dev; /* input device interface */ |
104 | struct usb_device *udev; /* usb device */ | 172 | struct usb_device *udev; /* usb device */ |
105 | 173 | ||
106 | struct urb *irq_in; /* urb for interrupt in report */ | 174 | struct urb *irq_in; /* urb for interrupt in report */ |
107 | unsigned char *idata; /* input data */ | 175 | unsigned char *idata; /* input data */ |
108 | dma_addr_t idata_dma; | 176 | dma_addr_t idata_dma; |
109 | 177 | ||
110 | char phys[65]; /* physical device path */ | 178 | char phys[65]; /* physical device path */ |
179 | |||
180 | int dpad_mapping; /* map d-pad to buttons or to axes */ | ||
111 | }; | 181 | }; |
112 | 182 | ||
113 | /* | 183 | /* |
@@ -137,14 +207,21 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d | |||
137 | input_report_abs(dev, ABS_RZ, data[11]); | 207 | input_report_abs(dev, ABS_RZ, data[11]); |
138 | 208 | ||
139 | /* digital pad */ | 209 | /* digital pad */ |
140 | input_report_abs(dev, ABS_HAT0X, !!(data[2] & 0x08) - !!(data[2] & 0x04)); | 210 | if (xpad->dpad_mapping == MAP_DPAD_TO_AXES) { |
141 | input_report_abs(dev, ABS_HAT0Y, !!(data[2] & 0x02) - !!(data[2] & 0x01)); | 211 | input_report_abs(dev, ABS_HAT0X, !!(data[2] & 0x08) - !!(data[2] & 0x04)); |
212 | input_report_abs(dev, ABS_HAT0Y, !!(data[2] & 0x02) - !!(data[2] & 0x01)); | ||
213 | } else /* xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS */ { | ||
214 | input_report_key(dev, BTN_LEFT, data[2] & 0x04); | ||
215 | input_report_key(dev, BTN_RIGHT, data[2] & 0x08); | ||
216 | input_report_key(dev, BTN_0, data[2] & 0x01); // up | ||
217 | input_report_key(dev, BTN_1, data[2] & 0x02); // down | ||
218 | } | ||
142 | 219 | ||
143 | /* start/back buttons and stick press left/right */ | 220 | /* start/back buttons and stick press left/right */ |
144 | input_report_key(dev, BTN_START, (data[2] & 0x10) >> 4); | 221 | input_report_key(dev, BTN_START, data[2] & 0x10); |
145 | input_report_key(dev, BTN_BACK, (data[2] & 0x20) >> 5); | 222 | input_report_key(dev, BTN_BACK, data[2] & 0x20); |
146 | input_report_key(dev, BTN_THUMBL, (data[2] & 0x40) >> 6); | 223 | input_report_key(dev, BTN_THUMBL, data[2] & 0x40); |
147 | input_report_key(dev, BTN_THUMBR, data[2] >> 7); | 224 | input_report_key(dev, BTN_THUMBR, data[2] & 0x80); |
148 | 225 | ||
149 | /* "analog" buttons A, B, X, Y */ | 226 | /* "analog" buttons A, B, X, Y */ |
150 | input_report_key(dev, BTN_A, data[4]); | 227 | input_report_key(dev, BTN_A, data[4]); |
@@ -206,6 +283,28 @@ static void xpad_close (struct input_dev *dev) | |||
206 | usb_kill_urb(xpad->irq_in); | 283 | usb_kill_urb(xpad->irq_in); |
207 | } | 284 | } |
208 | 285 | ||
286 | static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs) | ||
287 | { | ||
288 | set_bit(abs, input_dev->absbit); | ||
289 | |||
290 | switch (abs) { | ||
291 | case ABS_X: | ||
292 | case ABS_Y: | ||
293 | case ABS_RX: | ||
294 | case ABS_RY: /* the two sticks */ | ||
295 | input_set_abs_params(input_dev, abs, -32768, 32767, 16, 128); | ||
296 | break; | ||
297 | case ABS_Z: | ||
298 | case ABS_RZ: /* the triggers */ | ||
299 | input_set_abs_params(input_dev, abs, 0, 255, 0, 0); | ||
300 | break; | ||
301 | case ABS_HAT0X: | ||
302 | case ABS_HAT0Y: /* the d-pad (only if MAP_DPAD_TO_AXES) */ | ||
303 | input_set_abs_params(input_dev, abs, -1, 1, 0, 0); | ||
304 | break; | ||
305 | } | ||
306 | } | ||
307 | |||
209 | static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id) | 308 | static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id) |
210 | { | 309 | { |
211 | struct usb_device *udev = interface_to_usbdev (intf); | 310 | struct usb_device *udev = interface_to_usbdev (intf); |
@@ -235,6 +334,9 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
235 | goto fail2; | 334 | goto fail2; |
236 | 335 | ||
237 | xpad->udev = udev; | 336 | xpad->udev = udev; |
337 | xpad->dpad_mapping = xpad_device[i].dpad_mapping; | ||
338 | if (xpad->dpad_mapping == MAP_DPAD_UNKNOWN) | ||
339 | xpad->dpad_mapping = dpad_to_buttons; | ||
238 | xpad->dev = input_dev; | 340 | xpad->dev = input_dev; |
239 | usb_make_path(udev, xpad->phys, sizeof(xpad->phys)); | 341 | usb_make_path(udev, xpad->phys, sizeof(xpad->phys)); |
240 | strlcat(xpad->phys, "/input0", sizeof(xpad->phys)); | 342 | strlcat(xpad->phys, "/input0", sizeof(xpad->phys)); |
@@ -249,32 +351,19 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
249 | 351 | ||
250 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); | 352 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); |
251 | 353 | ||
354 | /* set up buttons */ | ||
252 | for (i = 0; xpad_btn[i] >= 0; i++) | 355 | for (i = 0; xpad_btn[i] >= 0; i++) |
253 | set_bit(xpad_btn[i], input_dev->keybit); | 356 | set_bit(xpad_btn[i], input_dev->keybit); |
357 | if (xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS) | ||
358 | for (i = 0; xpad_btn_pad[i] >= 0; i++) | ||
359 | set_bit(xpad_btn_pad[i], input_dev->keybit); | ||
254 | 360 | ||
255 | for (i = 0; xpad_abs[i] >= 0; i++) { | 361 | /* set up axes */ |
256 | 362 | for (i = 0; xpad_abs[i] >= 0; i++) | |
257 | signed short t = xpad_abs[i]; | 363 | xpad_set_up_abs(input_dev, xpad_abs[i]); |
258 | 364 | if (xpad->dpad_mapping == MAP_DPAD_TO_AXES) | |
259 | set_bit(t, input_dev->absbit); | 365 | for (i = 0; xpad_abs_pad[i] >= 0; i++) |
260 | 366 | xpad_set_up_abs(input_dev, xpad_abs_pad[i]); | |
261 | switch (t) { | ||
262 | case ABS_X: | ||
263 | case ABS_Y: | ||
264 | case ABS_RX: | ||
265 | case ABS_RY: /* the two sticks */ | ||
266 | input_set_abs_params(input_dev, t, -32768, 32767, 16, 128); | ||
267 | break; | ||
268 | case ABS_Z: | ||
269 | case ABS_RZ: /* the triggers */ | ||
270 | input_set_abs_params(input_dev, t, 0, 255, 0, 0); | ||
271 | break; | ||
272 | case ABS_HAT0X: | ||
273 | case ABS_HAT0Y: /* the d-pad */ | ||
274 | input_set_abs_params(input_dev, t, -1, 1, 0, 0); | ||
275 | break; | ||
276 | } | ||
277 | } | ||
278 | 367 | ||
279 | ep_irq_in = &intf->cur_altsetting->endpoint[0].desc; | 368 | ep_irq_in = &intf->cur_altsetting->endpoint[0].desc; |
280 | usb_fill_int_urb(xpad->irq_in, udev, | 369 | usb_fill_int_urb(xpad->irq_in, udev, |
@@ -305,7 +394,8 @@ static void xpad_disconnect(struct usb_interface *intf) | |||
305 | usb_kill_urb(xpad->irq_in); | 394 | usb_kill_urb(xpad->irq_in); |
306 | input_unregister_device(xpad->dev); | 395 | input_unregister_device(xpad->dev); |
307 | usb_free_urb(xpad->irq_in); | 396 | usb_free_urb(xpad->irq_in); |
308 | usb_buffer_free(interface_to_usbdev(intf), XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); | 397 | usb_buffer_free(interface_to_usbdev(intf), XPAD_PKT_LEN, |
398 | xpad->idata, xpad->idata_dma); | ||
309 | kfree(xpad); | 399 | kfree(xpad); |
310 | } | 400 | } |
311 | } | 401 | } |
diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig index c29658f69e2a..a74bf8617e7f 100644 --- a/drivers/usb/misc/Kconfig +++ b/drivers/usb/misc/Kconfig | |||
@@ -223,6 +223,16 @@ config USB_LD | |||
223 | To compile this driver as a module, choose M here: the | 223 | To compile this driver as a module, choose M here: the |
224 | module will be called ldusb. | 224 | module will be called ldusb. |
225 | 225 | ||
226 | config USB_TRANCEVIBRATOR | ||
227 | tristate "PlayStation 2 Trance Vibrator driver support" | ||
228 | depends on USB | ||
229 | help | ||
230 | Say Y here if you want to connect a PlayStation 2 Trance Vibrator | ||
231 | device to your computer's USB port. | ||
232 | |||
233 | To compile this driver as a module, choose M here: the | ||
234 | module will be called trancevibrator. | ||
235 | |||
226 | config USB_TEST | 236 | config USB_TEST |
227 | tristate "USB testing driver (DEVELOPMENT)" | 237 | tristate "USB testing driver (DEVELOPMENT)" |
228 | depends on USB && USB_DEVICEFS && EXPERIMENTAL | 238 | depends on USB && USB_DEVICEFS && EXPERIMENTAL |
diff --git a/drivers/usb/misc/Makefile b/drivers/usb/misc/Makefile index 2be70fa259bf..11dc59540cda 100644 --- a/drivers/usb/misc/Makefile +++ b/drivers/usb/misc/Makefile | |||
@@ -21,6 +21,7 @@ obj-$(CONFIG_USB_PHIDGETMOTORCONTROL) += phidgetmotorcontrol.o | |||
21 | obj-$(CONFIG_USB_PHIDGETSERVO) += phidgetservo.o | 21 | obj-$(CONFIG_USB_PHIDGETSERVO) += phidgetservo.o |
22 | obj-$(CONFIG_USB_RIO500) += rio500.o | 22 | obj-$(CONFIG_USB_RIO500) += rio500.o |
23 | obj-$(CONFIG_USB_TEST) += usbtest.o | 23 | obj-$(CONFIG_USB_TEST) += usbtest.o |
24 | obj-$(CONFIG_USB_TRANCEVIBRATOR) += trancevibrator.o | ||
24 | obj-$(CONFIG_USB_USS720) += uss720.o | 25 | obj-$(CONFIG_USB_USS720) += uss720.o |
25 | 26 | ||
26 | obj-$(CONFIG_USB_SISUSBVGA) += sisusbvga/ | 27 | obj-$(CONFIG_USB_SISUSBVGA) += sisusbvga/ |
diff --git a/drivers/usb/misc/adutux.c b/drivers/usb/misc/adutux.c index aecd633fe9f6..af2934e016a7 100644 --- a/drivers/usb/misc/adutux.c +++ b/drivers/usb/misc/adutux.c | |||
@@ -370,7 +370,8 @@ static int adu_release(struct inode *inode, struct file *file) | |||
370 | retval = adu_release_internal(dev); | 370 | retval = adu_release_internal(dev); |
371 | 371 | ||
372 | exit: | 372 | exit: |
373 | up(&dev->sem); | 373 | if (dev) |
374 | up(&dev->sem); | ||
374 | dbg(2," %s : leave, return value %d", __FUNCTION__, retval); | 375 | dbg(2," %s : leave, return value %d", __FUNCTION__, retval); |
375 | return retval; | 376 | return retval; |
376 | } | 377 | } |
diff --git a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c index 0be9d62d62ae..e4971d6aaafb 100644 --- a/drivers/usb/misc/auerswald.c +++ b/drivers/usb/misc/auerswald.c | |||
@@ -780,7 +780,7 @@ static int auerbuf_setup (pauerbufctl_t bcp, unsigned int numElements, unsigned | |||
780 | 780 | ||
781 | bl_fail:/* not enough memory. Free allocated elements */ | 781 | bl_fail:/* not enough memory. Free allocated elements */ |
782 | dbg ("auerbuf_setup: no more memory"); | 782 | dbg ("auerbuf_setup: no more memory"); |
783 | kfree(bep); | 783 | auerbuf_free(bep); |
784 | auerbuf_free_buffers (bcp); | 784 | auerbuf_free_buffers (bcp); |
785 | return -ENOMEM; | 785 | return -ENOMEM; |
786 | } | 786 | } |
diff --git a/drivers/usb/misc/ftdi-elan.c b/drivers/usb/misc/ftdi-elan.c index 0eb26a26115b..9b591b8b9369 100644 --- a/drivers/usb/misc/ftdi-elan.c +++ b/drivers/usb/misc/ftdi-elan.c | |||
@@ -513,8 +513,6 @@ static void ftdi_elan_respond_work(void *data) | |||
513 | ftdi->disconnected += 1; | 513 | ftdi->disconnected += 1; |
514 | } else if (retval == -ENODEV) { | 514 | } else if (retval == -ENODEV) { |
515 | ftdi->disconnected += 1; | 515 | ftdi->disconnected += 1; |
516 | } else if (retval == -ENODEV) { | ||
517 | ftdi->disconnected += 1; | ||
518 | } else if (retval == -EILSEQ) { | 516 | } else if (retval == -EILSEQ) { |
519 | ftdi->disconnected += 1; | 517 | ftdi->disconnected += 1; |
520 | } else { | 518 | } else { |
@@ -1186,11 +1184,8 @@ static ssize_t ftdi_elan_write(struct file *file, | |||
1186 | int retval = 0; | 1184 | int retval = 0; |
1187 | struct urb *urb; | 1185 | struct urb *urb; |
1188 | char *buf; | 1186 | char *buf; |
1189 | char data[30 *3 + 4]; | 1187 | struct usb_ftdi *ftdi = file->private_data; |
1190 | char *d = data; | 1188 | |
1191 | const char __user *s = user_buffer; | ||
1192 | int m = (sizeof(data) - 1) / 3; | ||
1193 | struct usb_ftdi *ftdi = (struct usb_ftdi *)file->private_data; | ||
1194 | if (ftdi->disconnected > 0) { | 1189 | if (ftdi->disconnected > 0) { |
1195 | return -ENODEV; | 1190 | return -ENODEV; |
1196 | } | 1191 | } |
@@ -1220,27 +1215,18 @@ static ssize_t ftdi_elan_write(struct file *file, | |||
1220 | if (retval) { | 1215 | if (retval) { |
1221 | dev_err(&ftdi->udev->dev, "failed submitting write urb, error %" | 1216 | dev_err(&ftdi->udev->dev, "failed submitting write urb, error %" |
1222 | "d\n", retval); | 1217 | "d\n", retval); |
1223 | goto error_4; | 1218 | goto error_3; |
1224 | } | 1219 | } |
1225 | usb_free_urb(urb); | 1220 | usb_free_urb(urb); |
1226 | exit:; | 1221 | |
1227 | if (count > m) { | 1222 | exit: |
1228 | int I = m - 1; | ||
1229 | while (I-- > 0) { | ||
1230 | d += sprintf(d, " %02X", 0x000000FF & *s++); | ||
1231 | } | ||
1232 | d += sprintf(d, " .."); | ||
1233 | } else { | ||
1234 | int I = count; | ||
1235 | while (I-- > 0) { | ||
1236 | d += sprintf(d, " %02X", 0x000000FF & *s++); | ||
1237 | } | ||
1238 | } | ||
1239 | return count; | 1223 | return count; |
1240 | error_4: error_3:usb_buffer_free(ftdi->udev, count, buf, | 1224 | error_3: |
1241 | urb->transfer_dma); | 1225 | usb_buffer_free(ftdi->udev, count, buf, urb->transfer_dma); |
1242 | error_2:usb_free_urb(urb); | 1226 | error_2: |
1243 | error_1:return retval; | 1227 | usb_free_urb(urb); |
1228 | error_1: | ||
1229 | return retval; | ||
1244 | } | 1230 | } |
1245 | 1231 | ||
1246 | static struct file_operations ftdi_elan_fops = { | 1232 | static struct file_operations ftdi_elan_fops = { |
diff --git a/drivers/usb/input/trancevibrator.c b/drivers/usb/misc/trancevibrator.c index 33cd91d11eca..33cd91d11eca 100644 --- a/drivers/usb/input/trancevibrator.c +++ b/drivers/usb/misc/trancevibrator.c | |||
diff --git a/drivers/usb/net/Kconfig b/drivers/usb/net/Kconfig index 054059632a21..e081836014ac 100644 --- a/drivers/usb/net/Kconfig +++ b/drivers/usb/net/Kconfig | |||
@@ -92,8 +92,13 @@ config USB_RTL8150 | |||
92 | To compile this driver as a module, choose M here: the | 92 | To compile this driver as a module, choose M here: the |
93 | module will be called rtl8150. | 93 | module will be called rtl8150. |
94 | 94 | ||
95 | config USB_USBNET_MII | ||
96 | tristate | ||
97 | default n | ||
98 | |||
95 | config USB_USBNET | 99 | config USB_USBNET |
96 | tristate "Multi-purpose USB Networking Framework" | 100 | tristate "Multi-purpose USB Networking Framework" |
101 | select MII if USBNET_MII != n | ||
97 | ---help--- | 102 | ---help--- |
98 | This driver supports several kinds of network links over USB, | 103 | This driver supports several kinds of network links over USB, |
99 | with "minidrivers" built around a common network driver core | 104 | with "minidrivers" built around a common network driver core |
@@ -129,7 +134,7 @@ config USB_NET_AX8817X | |||
129 | tristate "ASIX AX88xxx Based USB 2.0 Ethernet Adapters" | 134 | tristate "ASIX AX88xxx Based USB 2.0 Ethernet Adapters" |
130 | depends on USB_USBNET && NET_ETHERNET | 135 | depends on USB_USBNET && NET_ETHERNET |
131 | select CRC32 | 136 | select CRC32 |
132 | select MII | 137 | select USB_USBNET_MII |
133 | default y | 138 | default y |
134 | help | 139 | help |
135 | This option adds support for ASIX AX88xxx based USB 2.0 | 140 | This option adds support for ASIX AX88xxx based USB 2.0 |
@@ -207,6 +212,15 @@ config USB_NET_PLUSB | |||
207 | Choose this option if you're using a host-to-host cable | 212 | Choose this option if you're using a host-to-host cable |
208 | with one of these chips. | 213 | with one of these chips. |
209 | 214 | ||
215 | config USB_NET_MCS7830 | ||
216 | tristate "MosChip MCS7830 based Ethernet adapters" | ||
217 | depends on USB_USBNET | ||
218 | select USB_USBNET_MII | ||
219 | help | ||
220 | Choose this option if you're using a 10/100 Ethernet USB2 | ||
221 | adapter based on the MosChip 7830 controller. This includes | ||
222 | adapters marketed under the DeLOCK brand. | ||
223 | |||
210 | config USB_NET_RNDIS_HOST | 224 | config USB_NET_RNDIS_HOST |
211 | tristate "Host for RNDIS devices (EXPERIMENTAL)" | 225 | tristate "Host for RNDIS devices (EXPERIMENTAL)" |
212 | depends on USB_USBNET && EXPERIMENTAL | 226 | depends on USB_USBNET && EXPERIMENTAL |
diff --git a/drivers/usb/net/Makefile b/drivers/usb/net/Makefile index 160f19dbdf12..7b51964de171 100644 --- a/drivers/usb/net/Makefile +++ b/drivers/usb/net/Makefile | |||
@@ -14,6 +14,7 @@ obj-$(CONFIG_USB_NET_PLUSB) += plusb.o | |||
14 | obj-$(CONFIG_USB_NET_RNDIS_HOST) += rndis_host.o | 14 | obj-$(CONFIG_USB_NET_RNDIS_HOST) += rndis_host.o |
15 | obj-$(CONFIG_USB_NET_CDC_SUBSET) += cdc_subset.o | 15 | obj-$(CONFIG_USB_NET_CDC_SUBSET) += cdc_subset.o |
16 | obj-$(CONFIG_USB_NET_ZAURUS) += zaurus.o | 16 | obj-$(CONFIG_USB_NET_ZAURUS) += zaurus.o |
17 | obj-$(CONFIG_USB_NET_MCS7830) += mcs7830.o | ||
17 | obj-$(CONFIG_USB_USBNET) += usbnet.o | 18 | obj-$(CONFIG_USB_USBNET) += usbnet.o |
18 | 19 | ||
19 | ifeq ($(CONFIG_USB_DEBUG),y) | 20 | ifeq ($(CONFIG_USB_DEBUG),y) |
diff --git a/drivers/usb/net/asix.c b/drivers/usb/net/asix.c index c73dd224aa76..881841e600de 100644 --- a/drivers/usb/net/asix.c +++ b/drivers/usb/net/asix.c | |||
@@ -569,10 +569,12 @@ static int asix_mdio_read(struct net_device *netdev, int phy_id, int loc) | |||
569 | struct usbnet *dev = netdev_priv(netdev); | 569 | struct usbnet *dev = netdev_priv(netdev); |
570 | u16 res; | 570 | u16 res; |
571 | 571 | ||
572 | mutex_lock(&dev->phy_mutex); | ||
572 | asix_set_sw_mii(dev); | 573 | asix_set_sw_mii(dev); |
573 | asix_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id, | 574 | asix_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id, |
574 | (__u16)loc, 2, (u16 *)&res); | 575 | (__u16)loc, 2, (u16 *)&res); |
575 | asix_set_hw_mii(dev); | 576 | asix_set_hw_mii(dev); |
577 | mutex_unlock(&dev->phy_mutex); | ||
576 | 578 | ||
577 | devdbg(dev, "asix_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x", phy_id, loc, le16_to_cpu(res & 0xffff)); | 579 | devdbg(dev, "asix_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x", phy_id, loc, le16_to_cpu(res & 0xffff)); |
578 | 580 | ||
@@ -586,10 +588,12 @@ asix_mdio_write(struct net_device *netdev, int phy_id, int loc, int val) | |||
586 | u16 res = cpu_to_le16(val); | 588 | u16 res = cpu_to_le16(val); |
587 | 589 | ||
588 | devdbg(dev, "asix_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x", phy_id, loc, val); | 590 | devdbg(dev, "asix_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x", phy_id, loc, val); |
591 | mutex_lock(&dev->phy_mutex); | ||
589 | asix_set_sw_mii(dev); | 592 | asix_set_sw_mii(dev); |
590 | asix_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id, | 593 | asix_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id, |
591 | (__u16)loc, 2, (u16 *)&res); | 594 | (__u16)loc, 2, (u16 *)&res); |
592 | asix_set_hw_mii(dev); | 595 | asix_set_hw_mii(dev); |
596 | mutex_unlock(&dev->phy_mutex); | ||
593 | } | 597 | } |
594 | 598 | ||
595 | /* Get the PHY Identifier from the PHYSID1 & PHYSID2 MII registers */ | 599 | /* Get the PHY Identifier from the PHYSID1 & PHYSID2 MII registers */ |
@@ -700,32 +704,6 @@ static void asix_get_drvinfo (struct net_device *net, | |||
700 | info->eedump_len = data->eeprom_len; | 704 | info->eedump_len = data->eeprom_len; |
701 | } | 705 | } |
702 | 706 | ||
703 | static int asix_get_settings(struct net_device *net, struct ethtool_cmd *cmd) | ||
704 | { | ||
705 | struct usbnet *dev = netdev_priv(net); | ||
706 | |||
707 | return mii_ethtool_gset(&dev->mii,cmd); | ||
708 | } | ||
709 | |||
710 | static int asix_set_settings(struct net_device *net, struct ethtool_cmd *cmd) | ||
711 | { | ||
712 | struct usbnet *dev = netdev_priv(net); | ||
713 | int res = mii_ethtool_sset(&dev->mii,cmd); | ||
714 | |||
715 | /* link speed/duplex might have changed */ | ||
716 | if (dev->driver_info->link_reset) | ||
717 | dev->driver_info->link_reset(dev); | ||
718 | |||
719 | return res; | ||
720 | } | ||
721 | |||
722 | static int asix_nway_reset(struct net_device *net) | ||
723 | { | ||
724 | struct usbnet *dev = netdev_priv(net); | ||
725 | |||
726 | return mii_nway_restart(&dev->mii); | ||
727 | } | ||
728 | |||
729 | static u32 asix_get_link(struct net_device *net) | 707 | static u32 asix_get_link(struct net_device *net) |
730 | { | 708 | { |
731 | struct usbnet *dev = netdev_priv(net); | 709 | struct usbnet *dev = netdev_priv(net); |
@@ -746,15 +724,15 @@ static int asix_ioctl (struct net_device *net, struct ifreq *rq, int cmd) | |||
746 | static struct ethtool_ops ax88172_ethtool_ops = { | 724 | static struct ethtool_ops ax88172_ethtool_ops = { |
747 | .get_drvinfo = asix_get_drvinfo, | 725 | .get_drvinfo = asix_get_drvinfo, |
748 | .get_link = asix_get_link, | 726 | .get_link = asix_get_link, |
749 | .nway_reset = asix_nway_reset, | ||
750 | .get_msglevel = usbnet_get_msglevel, | 727 | .get_msglevel = usbnet_get_msglevel, |
751 | .set_msglevel = usbnet_set_msglevel, | 728 | .set_msglevel = usbnet_set_msglevel, |
752 | .get_wol = asix_get_wol, | 729 | .get_wol = asix_get_wol, |
753 | .set_wol = asix_set_wol, | 730 | .set_wol = asix_set_wol, |
754 | .get_eeprom_len = asix_get_eeprom_len, | 731 | .get_eeprom_len = asix_get_eeprom_len, |
755 | .get_eeprom = asix_get_eeprom, | 732 | .get_eeprom = asix_get_eeprom, |
756 | .get_settings = asix_get_settings, | 733 | .get_settings = usbnet_get_settings, |
757 | .set_settings = asix_set_settings, | 734 | .set_settings = usbnet_set_settings, |
735 | .nway_reset = usbnet_nway_reset, | ||
758 | }; | 736 | }; |
759 | 737 | ||
760 | static void ax88172_set_multicast(struct net_device *net) | 738 | static void ax88172_set_multicast(struct net_device *net) |
@@ -885,15 +863,15 @@ out1: | |||
885 | static struct ethtool_ops ax88772_ethtool_ops = { | 863 | static struct ethtool_ops ax88772_ethtool_ops = { |
886 | .get_drvinfo = asix_get_drvinfo, | 864 | .get_drvinfo = asix_get_drvinfo, |
887 | .get_link = asix_get_link, | 865 | .get_link = asix_get_link, |
888 | .nway_reset = asix_nway_reset, | ||
889 | .get_msglevel = usbnet_get_msglevel, | 866 | .get_msglevel = usbnet_get_msglevel, |
890 | .set_msglevel = usbnet_set_msglevel, | 867 | .set_msglevel = usbnet_set_msglevel, |
891 | .get_wol = asix_get_wol, | 868 | .get_wol = asix_get_wol, |
892 | .set_wol = asix_set_wol, | 869 | .set_wol = asix_set_wol, |
893 | .get_eeprom_len = asix_get_eeprom_len, | 870 | .get_eeprom_len = asix_get_eeprom_len, |
894 | .get_eeprom = asix_get_eeprom, | 871 | .get_eeprom = asix_get_eeprom, |
895 | .get_settings = asix_get_settings, | 872 | .get_settings = usbnet_get_settings, |
896 | .set_settings = asix_set_settings, | 873 | .set_settings = usbnet_set_settings, |
874 | .nway_reset = usbnet_nway_reset, | ||
897 | }; | 875 | }; |
898 | 876 | ||
899 | static int ax88772_link_reset(struct usbnet *dev) | 877 | static int ax88772_link_reset(struct usbnet *dev) |
@@ -1046,15 +1024,15 @@ out1: | |||
1046 | static struct ethtool_ops ax88178_ethtool_ops = { | 1024 | static struct ethtool_ops ax88178_ethtool_ops = { |
1047 | .get_drvinfo = asix_get_drvinfo, | 1025 | .get_drvinfo = asix_get_drvinfo, |
1048 | .get_link = asix_get_link, | 1026 | .get_link = asix_get_link, |
1049 | .nway_reset = asix_nway_reset, | ||
1050 | .get_msglevel = usbnet_get_msglevel, | 1027 | .get_msglevel = usbnet_get_msglevel, |
1051 | .set_msglevel = usbnet_set_msglevel, | 1028 | .set_msglevel = usbnet_set_msglevel, |
1052 | .get_wol = asix_get_wol, | 1029 | .get_wol = asix_get_wol, |
1053 | .set_wol = asix_set_wol, | 1030 | .set_wol = asix_set_wol, |
1054 | .get_eeprom_len = asix_get_eeprom_len, | 1031 | .get_eeprom_len = asix_get_eeprom_len, |
1055 | .get_eeprom = asix_get_eeprom, | 1032 | .get_eeprom = asix_get_eeprom, |
1056 | .get_settings = asix_get_settings, | 1033 | .get_settings = usbnet_get_settings, |
1057 | .set_settings = asix_set_settings, | 1034 | .set_settings = usbnet_set_settings, |
1035 | .nway_reset = usbnet_nway_reset, | ||
1058 | }; | 1036 | }; |
1059 | 1037 | ||
1060 | static int marvell_phy_init(struct usbnet *dev) | 1038 | static int marvell_phy_init(struct usbnet *dev) |
diff --git a/drivers/usb/net/cdc_ether.c b/drivers/usb/net/cdc_ether.c index 82ce0358d9a3..f6971b88349d 100644 --- a/drivers/usb/net/cdc_ether.c +++ b/drivers/usb/net/cdc_ether.c | |||
@@ -498,7 +498,7 @@ static struct usb_driver cdc_driver = { | |||
498 | 498 | ||
499 | static int __init cdc_init(void) | 499 | static int __init cdc_init(void) |
500 | { | 500 | { |
501 | BUG_ON((sizeof(((struct usbnet *)0)->data) | 501 | BUILD_BUG_ON((sizeof(((struct usbnet *)0)->data) |
502 | < sizeof(struct cdc_state))); | 502 | < sizeof(struct cdc_state))); |
503 | 503 | ||
504 | return usb_register(&cdc_driver); | 504 | return usb_register(&cdc_driver); |
diff --git a/drivers/usb/net/kaweth.c b/drivers/usb/net/kaweth.c index 957d4ad316f9..7c906a43e497 100644 --- a/drivers/usb/net/kaweth.c +++ b/drivers/usb/net/kaweth.c | |||
@@ -65,16 +65,6 @@ | |||
65 | 65 | ||
66 | #undef DEBUG | 66 | #undef DEBUG |
67 | 67 | ||
68 | #ifdef DEBUG | ||
69 | #define kaweth_dbg(format, arg...) printk(KERN_DEBUG __FILE__ ": " format "\n" ,##arg) | ||
70 | #else | ||
71 | #define kaweth_dbg(format, arg...) do {} while (0) | ||
72 | #endif | ||
73 | #define kaweth_err(format, arg...) printk(KERN_ERR __FILE__ ": " format "\n" ,##arg) | ||
74 | #define kaweth_info(format, arg...) printk(KERN_INFO __FILE__ ": " format "\n" , ##arg) | ||
75 | #define kaweth_warn(format, arg...) printk(KERN_WARNING __FILE__ ": " format "\n" , ##arg) | ||
76 | |||
77 | |||
78 | #include "kawethfw.h" | 68 | #include "kawethfw.h" |
79 | 69 | ||
80 | #define KAWETH_MTU 1514 | 70 | #define KAWETH_MTU 1514 |
@@ -86,6 +76,9 @@ | |||
86 | 76 | ||
87 | #define KAWETH_STATUS_BROKEN 0x0000001 | 77 | #define KAWETH_STATUS_BROKEN 0x0000001 |
88 | #define KAWETH_STATUS_CLOSING 0x0000002 | 78 | #define KAWETH_STATUS_CLOSING 0x0000002 |
79 | #define KAWETH_STATUS_SUSPENDING 0x0000004 | ||
80 | |||
81 | #define KAWETH_STATUS_BLOCKED (KAWETH_STATUS_CLOSING | KAWETH_STATUS_SUSPENDING) | ||
89 | 82 | ||
90 | #define KAWETH_PACKET_FILTER_PROMISCUOUS 0x01 | 83 | #define KAWETH_PACKET_FILTER_PROMISCUOUS 0x01 |
91 | #define KAWETH_PACKET_FILTER_ALL_MULTICAST 0x02 | 84 | #define KAWETH_PACKET_FILTER_ALL_MULTICAST 0x02 |
@@ -112,6 +105,8 @@ | |||
112 | #define STATE_MASK 0x40 | 105 | #define STATE_MASK 0x40 |
113 | #define STATE_SHIFT 5 | 106 | #define STATE_SHIFT 5 |
114 | 107 | ||
108 | #define IS_BLOCKED(s) (s & KAWETH_STATUS_BLOCKED) | ||
109 | |||
115 | 110 | ||
116 | MODULE_AUTHOR("Michael Zappe <zapman@interlan.net>, Stephane Alnet <stephane@u-picardie.fr>, Brad Hards <bhards@bigpond.net.au> and Oliver Neukum <oliver@neukum.org>"); | 111 | MODULE_AUTHOR("Michael Zappe <zapman@interlan.net>, Stephane Alnet <stephane@u-picardie.fr>, Brad Hards <bhards@bigpond.net.au> and Oliver Neukum <oliver@neukum.org>"); |
117 | MODULE_DESCRIPTION("KL5USB101 USB Ethernet driver"); | 112 | MODULE_DESCRIPTION("KL5USB101 USB Ethernet driver"); |
@@ -128,6 +123,8 @@ static int kaweth_internal_control_msg(struct usb_device *usb_dev, | |||
128 | unsigned int pipe, | 123 | unsigned int pipe, |
129 | struct usb_ctrlrequest *cmd, void *data, | 124 | struct usb_ctrlrequest *cmd, void *data, |
130 | int len, int timeout); | 125 | int len, int timeout); |
126 | static int kaweth_suspend(struct usb_interface *intf, pm_message_t message); | ||
127 | static int kaweth_resume(struct usb_interface *intf); | ||
131 | 128 | ||
132 | /**************************************************************** | 129 | /**************************************************************** |
133 | * usb_device_id | 130 | * usb_device_id |
@@ -179,6 +176,8 @@ static struct usb_driver kaweth_driver = { | |||
179 | .name = driver_name, | 176 | .name = driver_name, |
180 | .probe = kaweth_probe, | 177 | .probe = kaweth_probe, |
181 | .disconnect = kaweth_disconnect, | 178 | .disconnect = kaweth_disconnect, |
179 | .suspend = kaweth_suspend, | ||
180 | .resume = kaweth_resume, | ||
182 | .id_table = usb_klsi_table, | 181 | .id_table = usb_klsi_table, |
183 | }; | 182 | }; |
184 | 183 | ||
@@ -222,6 +221,7 @@ struct kaweth_device | |||
222 | int suspend_lowmem_rx; | 221 | int suspend_lowmem_rx; |
223 | int suspend_lowmem_ctrl; | 222 | int suspend_lowmem_ctrl; |
224 | int linkstate; | 223 | int linkstate; |
224 | int opened; | ||
225 | struct work_struct lowmem_work; | 225 | struct work_struct lowmem_work; |
226 | 226 | ||
227 | struct usb_device *dev; | 227 | struct usb_device *dev; |
@@ -265,17 +265,17 @@ static int kaweth_control(struct kaweth_device *kaweth, | |||
265 | { | 265 | { |
266 | struct usb_ctrlrequest *dr; | 266 | struct usb_ctrlrequest *dr; |
267 | 267 | ||
268 | kaweth_dbg("kaweth_control()"); | 268 | dbg("kaweth_control()"); |
269 | 269 | ||
270 | if(in_interrupt()) { | 270 | if(in_interrupt()) { |
271 | kaweth_dbg("in_interrupt()"); | 271 | dbg("in_interrupt()"); |
272 | return -EBUSY; | 272 | return -EBUSY; |
273 | } | 273 | } |
274 | 274 | ||
275 | dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC); | 275 | dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC); |
276 | 276 | ||
277 | if (!dr) { | 277 | if (!dr) { |
278 | kaweth_dbg("kmalloc() failed"); | 278 | dbg("kmalloc() failed"); |
279 | return -ENOMEM; | 279 | return -ENOMEM; |
280 | } | 280 | } |
281 | 281 | ||
@@ -300,7 +300,7 @@ static int kaweth_read_configuration(struct kaweth_device *kaweth) | |||
300 | { | 300 | { |
301 | int retval; | 301 | int retval; |
302 | 302 | ||
303 | kaweth_dbg("Reading kaweth configuration"); | 303 | dbg("Reading kaweth configuration"); |
304 | 304 | ||
305 | retval = kaweth_control(kaweth, | 305 | retval = kaweth_control(kaweth, |
306 | usb_rcvctrlpipe(kaweth->dev, 0), | 306 | usb_rcvctrlpipe(kaweth->dev, 0), |
@@ -322,7 +322,7 @@ static int kaweth_set_urb_size(struct kaweth_device *kaweth, __u16 urb_size) | |||
322 | { | 322 | { |
323 | int retval; | 323 | int retval; |
324 | 324 | ||
325 | kaweth_dbg("Setting URB size to %d", (unsigned)urb_size); | 325 | dbg("Setting URB size to %d", (unsigned)urb_size); |
326 | 326 | ||
327 | retval = kaweth_control(kaweth, | 327 | retval = kaweth_control(kaweth, |
328 | usb_sndctrlpipe(kaweth->dev, 0), | 328 | usb_sndctrlpipe(kaweth->dev, 0), |
@@ -344,7 +344,7 @@ static int kaweth_set_sofs_wait(struct kaweth_device *kaweth, __u16 sofs_wait) | |||
344 | { | 344 | { |
345 | int retval; | 345 | int retval; |
346 | 346 | ||
347 | kaweth_dbg("Set SOFS wait to %d", (unsigned)sofs_wait); | 347 | dbg("Set SOFS wait to %d", (unsigned)sofs_wait); |
348 | 348 | ||
349 | retval = kaweth_control(kaweth, | 349 | retval = kaweth_control(kaweth, |
350 | usb_sndctrlpipe(kaweth->dev, 0), | 350 | usb_sndctrlpipe(kaweth->dev, 0), |
@@ -367,7 +367,7 @@ static int kaweth_set_receive_filter(struct kaweth_device *kaweth, | |||
367 | { | 367 | { |
368 | int retval; | 368 | int retval; |
369 | 369 | ||
370 | kaweth_dbg("Set receive filter to %d", (unsigned)receive_filter); | 370 | dbg("Set receive filter to %d", (unsigned)receive_filter); |
371 | 371 | ||
372 | retval = kaweth_control(kaweth, | 372 | retval = kaweth_control(kaweth, |
373 | usb_sndctrlpipe(kaweth->dev, 0), | 373 | usb_sndctrlpipe(kaweth->dev, 0), |
@@ -392,7 +392,7 @@ static int kaweth_download_firmware(struct kaweth_device *kaweth, | |||
392 | __u8 type) | 392 | __u8 type) |
393 | { | 393 | { |
394 | if(data_len > KAWETH_FIRMWARE_BUF_SIZE) { | 394 | if(data_len > KAWETH_FIRMWARE_BUF_SIZE) { |
395 | kaweth_err("Firmware too big: %d", data_len); | 395 | err("Firmware too big: %d", data_len); |
396 | return -ENOSPC; | 396 | return -ENOSPC; |
397 | } | 397 | } |
398 | 398 | ||
@@ -403,13 +403,13 @@ static int kaweth_download_firmware(struct kaweth_device *kaweth, | |||
403 | kaweth->firmware_buf[4] = type; | 403 | kaweth->firmware_buf[4] = type; |
404 | kaweth->firmware_buf[5] = interrupt; | 404 | kaweth->firmware_buf[5] = interrupt; |
405 | 405 | ||
406 | kaweth_dbg("High: %i, Low:%i", kaweth->firmware_buf[3], | 406 | dbg("High: %i, Low:%i", kaweth->firmware_buf[3], |
407 | kaweth->firmware_buf[2]); | 407 | kaweth->firmware_buf[2]); |
408 | 408 | ||
409 | kaweth_dbg("Downloading firmware at %p to kaweth device at %p", | 409 | dbg("Downloading firmware at %p to kaweth device at %p", |
410 | data, | 410 | data, |
411 | kaweth); | 411 | kaweth); |
412 | kaweth_dbg("Firmware length: %d", data_len); | 412 | dbg("Firmware length: %d", data_len); |
413 | 413 | ||
414 | return kaweth_control(kaweth, | 414 | return kaweth_control(kaweth, |
415 | usb_sndctrlpipe(kaweth->dev, 0), | 415 | usb_sndctrlpipe(kaweth->dev, 0), |
@@ -437,7 +437,7 @@ static int kaweth_trigger_firmware(struct kaweth_device *kaweth, | |||
437 | kaweth->firmware_buf[6] = 0x00; | 437 | kaweth->firmware_buf[6] = 0x00; |
438 | kaweth->firmware_buf[7] = 0x00; | 438 | kaweth->firmware_buf[7] = 0x00; |
439 | 439 | ||
440 | kaweth_dbg("Triggering firmware"); | 440 | dbg("Triggering firmware"); |
441 | 441 | ||
442 | return kaweth_control(kaweth, | 442 | return kaweth_control(kaweth, |
443 | usb_sndctrlpipe(kaweth->dev, 0), | 443 | usb_sndctrlpipe(kaweth->dev, 0), |
@@ -457,7 +457,7 @@ static int kaweth_reset(struct kaweth_device *kaweth) | |||
457 | { | 457 | { |
458 | int result; | 458 | int result; |
459 | 459 | ||
460 | kaweth_dbg("kaweth_reset(%p)", kaweth); | 460 | dbg("kaweth_reset(%p)", kaweth); |
461 | result = kaweth_control(kaweth, | 461 | result = kaweth_control(kaweth, |
462 | usb_sndctrlpipe(kaweth->dev, 0), | 462 | usb_sndctrlpipe(kaweth->dev, 0), |
463 | USB_REQ_SET_CONFIGURATION, | 463 | USB_REQ_SET_CONFIGURATION, |
@@ -470,7 +470,7 @@ static int kaweth_reset(struct kaweth_device *kaweth) | |||
470 | 470 | ||
471 | mdelay(10); | 471 | mdelay(10); |
472 | 472 | ||
473 | kaweth_dbg("kaweth_reset() returns %d.",result); | 473 | dbg("kaweth_reset() returns %d.",result); |
474 | 474 | ||
475 | return result; | 475 | return result; |
476 | } | 476 | } |
@@ -534,7 +534,7 @@ static void kaweth_resubmit_tl(void *d) | |||
534 | { | 534 | { |
535 | struct kaweth_device *kaweth = (struct kaweth_device *)d; | 535 | struct kaweth_device *kaweth = (struct kaweth_device *)d; |
536 | 536 | ||
537 | if (kaweth->status | KAWETH_STATUS_CLOSING) | 537 | if (IS_BLOCKED(kaweth->status)) |
538 | return; | 538 | return; |
539 | 539 | ||
540 | if (kaweth->suspend_lowmem_rx) | 540 | if (kaweth->suspend_lowmem_rx) |
@@ -568,7 +568,7 @@ static int kaweth_resubmit_rx_urb(struct kaweth_device *kaweth, | |||
568 | kaweth->suspend_lowmem_rx = 1; | 568 | kaweth->suspend_lowmem_rx = 1; |
569 | schedule_delayed_work(&kaweth->lowmem_work, HZ/4); | 569 | schedule_delayed_work(&kaweth->lowmem_work, HZ/4); |
570 | } | 570 | } |
571 | kaweth_err("resubmitting rx_urb %d failed", result); | 571 | err("resubmitting rx_urb %d failed", result); |
572 | } else { | 572 | } else { |
573 | kaweth->suspend_lowmem_rx = 0; | 573 | kaweth->suspend_lowmem_rx = 0; |
574 | } | 574 | } |
@@ -601,11 +601,15 @@ static void kaweth_usb_receive(struct urb *urb) | |||
601 | return; | 601 | return; |
602 | } | 602 | } |
603 | 603 | ||
604 | if (kaweth->status & KAWETH_STATUS_CLOSING) | 604 | spin_lock(&kaweth->device_lock); |
605 | if (IS_BLOCKED(kaweth->status)) { | ||
606 | spin_unlock(&kaweth->device_lock); | ||
605 | return; | 607 | return; |
608 | } | ||
609 | spin_unlock(&kaweth->device_lock); | ||
606 | 610 | ||
607 | if(urb->status && urb->status != -EREMOTEIO && count != 1) { | 611 | if(urb->status && urb->status != -EREMOTEIO && count != 1) { |
608 | kaweth_err("%s RX status: %d count: %d packet_len: %d", | 612 | err("%s RX status: %d count: %d packet_len: %d", |
609 | net->name, | 613 | net->name, |
610 | urb->status, | 614 | urb->status, |
611 | count, | 615 | count, |
@@ -616,9 +620,9 @@ static void kaweth_usb_receive(struct urb *urb) | |||
616 | 620 | ||
617 | if(kaweth->net && (count > 2)) { | 621 | if(kaweth->net && (count > 2)) { |
618 | if(pkt_len > (count - 2)) { | 622 | if(pkt_len > (count - 2)) { |
619 | kaweth_err("Packet length too long for USB frame (pkt_len: %x, count: %x)",pkt_len, count); | 623 | err("Packet length too long for USB frame (pkt_len: %x, count: %x)",pkt_len, count); |
620 | kaweth_err("Packet len & 2047: %x", pkt_len & 2047); | 624 | err("Packet len & 2047: %x", pkt_len & 2047); |
621 | kaweth_err("Count 2: %x", count2); | 625 | err("Count 2: %x", count2); |
622 | kaweth_resubmit_rx_urb(kaweth, GFP_ATOMIC); | 626 | kaweth_resubmit_rx_urb(kaweth, GFP_ATOMIC); |
623 | return; | 627 | return; |
624 | } | 628 | } |
@@ -655,7 +659,7 @@ static int kaweth_open(struct net_device *net) | |||
655 | struct kaweth_device *kaweth = netdev_priv(net); | 659 | struct kaweth_device *kaweth = netdev_priv(net); |
656 | int res; | 660 | int res; |
657 | 661 | ||
658 | kaweth_dbg("Opening network device."); | 662 | dbg("Opening network device."); |
659 | 663 | ||
660 | res = kaweth_resubmit_rx_urb(kaweth, GFP_KERNEL); | 664 | res = kaweth_resubmit_rx_urb(kaweth, GFP_KERNEL); |
661 | if (res) | 665 | if (res) |
@@ -678,6 +682,7 @@ static int kaweth_open(struct net_device *net) | |||
678 | usb_kill_urb(kaweth->rx_urb); | 682 | usb_kill_urb(kaweth->rx_urb); |
679 | return -EIO; | 683 | return -EIO; |
680 | } | 684 | } |
685 | kaweth->opened = 1; | ||
681 | 686 | ||
682 | netif_start_queue(net); | 687 | netif_start_queue(net); |
683 | 688 | ||
@@ -688,14 +693,8 @@ static int kaweth_open(struct net_device *net) | |||
688 | /**************************************************************** | 693 | /**************************************************************** |
689 | * kaweth_close | 694 | * kaweth_close |
690 | ****************************************************************/ | 695 | ****************************************************************/ |
691 | static int kaweth_close(struct net_device *net) | 696 | static void kaweth_kill_urbs(struct kaweth_device *kaweth) |
692 | { | 697 | { |
693 | struct kaweth_device *kaweth = netdev_priv(net); | ||
694 | |||
695 | netif_stop_queue(net); | ||
696 | |||
697 | kaweth->status |= KAWETH_STATUS_CLOSING; | ||
698 | |||
699 | usb_kill_urb(kaweth->irq_urb); | 698 | usb_kill_urb(kaweth->irq_urb); |
700 | usb_kill_urb(kaweth->rx_urb); | 699 | usb_kill_urb(kaweth->rx_urb); |
701 | usb_kill_urb(kaweth->tx_urb); | 700 | usb_kill_urb(kaweth->tx_urb); |
@@ -706,6 +705,21 @@ static int kaweth_close(struct net_device *net) | |||
706 | we hit them again */ | 705 | we hit them again */ |
707 | usb_kill_urb(kaweth->irq_urb); | 706 | usb_kill_urb(kaweth->irq_urb); |
708 | usb_kill_urb(kaweth->rx_urb); | 707 | usb_kill_urb(kaweth->rx_urb); |
708 | } | ||
709 | |||
710 | /**************************************************************** | ||
711 | * kaweth_close | ||
712 | ****************************************************************/ | ||
713 | static int kaweth_close(struct net_device *net) | ||
714 | { | ||
715 | struct kaweth_device *kaweth = netdev_priv(net); | ||
716 | |||
717 | netif_stop_queue(net); | ||
718 | kaweth->opened = 0; | ||
719 | |||
720 | kaweth->status |= KAWETH_STATUS_CLOSING; | ||
721 | |||
722 | kaweth_kill_urbs(kaweth); | ||
709 | 723 | ||
710 | kaweth->status &= ~KAWETH_STATUS_CLOSING; | 724 | kaweth->status &= ~KAWETH_STATUS_CLOSING; |
711 | 725 | ||
@@ -732,7 +746,7 @@ static void kaweth_usb_transmit_complete(struct urb *urb) | |||
732 | 746 | ||
733 | if (unlikely(urb->status != 0)) | 747 | if (unlikely(urb->status != 0)) |
734 | if (urb->status != -ENOENT) | 748 | if (urb->status != -ENOENT) |
735 | kaweth_dbg("%s: TX status %d.", kaweth->net->name, urb->status); | 749 | dbg("%s: TX status %d.", kaweth->net->name, urb->status); |
736 | 750 | ||
737 | netif_wake_queue(kaweth->net); | 751 | netif_wake_queue(kaweth->net); |
738 | dev_kfree_skb_irq(skb); | 752 | dev_kfree_skb_irq(skb); |
@@ -752,6 +766,9 @@ static int kaweth_start_xmit(struct sk_buff *skb, struct net_device *net) | |||
752 | 766 | ||
753 | kaweth_async_set_rx_mode(kaweth); | 767 | kaweth_async_set_rx_mode(kaweth); |
754 | netif_stop_queue(net); | 768 | netif_stop_queue(net); |
769 | if (IS_BLOCKED(kaweth->status)) { | ||
770 | goto skip; | ||
771 | } | ||
755 | 772 | ||
756 | /* We now decide whether we can put our special header into the sk_buff */ | 773 | /* We now decide whether we can put our special header into the sk_buff */ |
757 | if (skb_cloned(skb) || skb_headroom(skb) < 2) { | 774 | if (skb_cloned(skb) || skb_headroom(skb) < 2) { |
@@ -783,7 +800,8 @@ static int kaweth_start_xmit(struct sk_buff *skb, struct net_device *net) | |||
783 | 800 | ||
784 | if((res = usb_submit_urb(kaweth->tx_urb, GFP_ATOMIC))) | 801 | if((res = usb_submit_urb(kaweth->tx_urb, GFP_ATOMIC))) |
785 | { | 802 | { |
786 | kaweth_warn("kaweth failed tx_urb %d", res); | 803 | warn("kaweth failed tx_urb %d", res); |
804 | skip: | ||
787 | kaweth->stats.tx_errors++; | 805 | kaweth->stats.tx_errors++; |
788 | 806 | ||
789 | netif_start_queue(net); | 807 | netif_start_queue(net); |
@@ -812,7 +830,7 @@ static void kaweth_set_rx_mode(struct net_device *net) | |||
812 | KAWETH_PACKET_FILTER_BROADCAST | | 830 | KAWETH_PACKET_FILTER_BROADCAST | |
813 | KAWETH_PACKET_FILTER_MULTICAST; | 831 | KAWETH_PACKET_FILTER_MULTICAST; |
814 | 832 | ||
815 | kaweth_dbg("Setting Rx mode to %d", packet_filter_bitmap); | 833 | dbg("Setting Rx mode to %d", packet_filter_bitmap); |
816 | 834 | ||
817 | netif_stop_queue(net); | 835 | netif_stop_queue(net); |
818 | 836 | ||
@@ -850,10 +868,10 @@ static void kaweth_async_set_rx_mode(struct kaweth_device *kaweth) | |||
850 | KAWETH_CONTROL_TIMEOUT); | 868 | KAWETH_CONTROL_TIMEOUT); |
851 | 869 | ||
852 | if(result < 0) { | 870 | if(result < 0) { |
853 | kaweth_err("Failed to set Rx mode: %d", result); | 871 | err("Failed to set Rx mode: %d", result); |
854 | } | 872 | } |
855 | else { | 873 | else { |
856 | kaweth_dbg("Set Rx mode to %d", packet_filter_bitmap); | 874 | dbg("Set Rx mode to %d", packet_filter_bitmap); |
857 | } | 875 | } |
858 | } | 876 | } |
859 | } | 877 | } |
@@ -874,7 +892,7 @@ static void kaweth_tx_timeout(struct net_device *net) | |||
874 | { | 892 | { |
875 | struct kaweth_device *kaweth = netdev_priv(net); | 893 | struct kaweth_device *kaweth = netdev_priv(net); |
876 | 894 | ||
877 | kaweth_warn("%s: Tx timed out. Resetting.", net->name); | 895 | warn("%s: Tx timed out. Resetting.", net->name); |
878 | kaweth->stats.tx_errors++; | 896 | kaweth->stats.tx_errors++; |
879 | net->trans_start = jiffies; | 897 | net->trans_start = jiffies; |
880 | 898 | ||
@@ -882,6 +900,42 @@ static void kaweth_tx_timeout(struct net_device *net) | |||
882 | } | 900 | } |
883 | 901 | ||
884 | /**************************************************************** | 902 | /**************************************************************** |
903 | * kaweth_suspend | ||
904 | ****************************************************************/ | ||
905 | static int kaweth_suspend(struct usb_interface *intf, pm_message_t message) | ||
906 | { | ||
907 | struct kaweth_device *kaweth = usb_get_intfdata(intf); | ||
908 | unsigned long flags; | ||
909 | |||
910 | spin_lock_irqsave(&kaweth->device_lock, flags); | ||
911 | kaweth->status |= KAWETH_STATUS_SUSPENDING; | ||
912 | spin_unlock_irqrestore(&kaweth->device_lock, flags); | ||
913 | |||
914 | kaweth_kill_urbs(kaweth); | ||
915 | return 0; | ||
916 | } | ||
917 | |||
918 | /**************************************************************** | ||
919 | * kaweth_resume | ||
920 | ****************************************************************/ | ||
921 | static int kaweth_resume(struct usb_interface *intf) | ||
922 | { | ||
923 | struct kaweth_device *kaweth = usb_get_intfdata(intf); | ||
924 | unsigned long flags; | ||
925 | |||
926 | spin_lock_irqsave(&kaweth->device_lock, flags); | ||
927 | kaweth->status &= ~KAWETH_STATUS_SUSPENDING; | ||
928 | spin_unlock_irqrestore(&kaweth->device_lock, flags); | ||
929 | |||
930 | if (!kaweth->opened) | ||
931 | return 0; | ||
932 | kaweth_resubmit_rx_urb(kaweth, GFP_NOIO); | ||
933 | kaweth_resubmit_int_urb(kaweth, GFP_NOIO); | ||
934 | |||
935 | return 0; | ||
936 | } | ||
937 | |||
938 | /**************************************************************** | ||
885 | * kaweth_probe | 939 | * kaweth_probe |
886 | ****************************************************************/ | 940 | ****************************************************************/ |
887 | static int kaweth_probe( | 941 | static int kaweth_probe( |
@@ -895,15 +949,15 @@ static int kaweth_probe( | |||
895 | const eth_addr_t bcast_addr = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; | 949 | const eth_addr_t bcast_addr = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; |
896 | int result = 0; | 950 | int result = 0; |
897 | 951 | ||
898 | kaweth_dbg("Kawasaki Device Probe (Device number:%d): 0x%4.4x:0x%4.4x:0x%4.4x", | 952 | dbg("Kawasaki Device Probe (Device number:%d): 0x%4.4x:0x%4.4x:0x%4.4x", |
899 | dev->devnum, | 953 | dev->devnum, |
900 | le16_to_cpu(dev->descriptor.idVendor), | 954 | le16_to_cpu(dev->descriptor.idVendor), |
901 | le16_to_cpu(dev->descriptor.idProduct), | 955 | le16_to_cpu(dev->descriptor.idProduct), |
902 | le16_to_cpu(dev->descriptor.bcdDevice)); | 956 | le16_to_cpu(dev->descriptor.bcdDevice)); |
903 | 957 | ||
904 | kaweth_dbg("Device at %p", dev); | 958 | dbg("Device at %p", dev); |
905 | 959 | ||
906 | kaweth_dbg("Descriptor length: %x type: %x", | 960 | dbg("Descriptor length: %x type: %x", |
907 | (int)dev->descriptor.bLength, | 961 | (int)dev->descriptor.bLength, |
908 | (int)dev->descriptor.bDescriptorType); | 962 | (int)dev->descriptor.bDescriptorType); |
909 | 963 | ||
@@ -918,7 +972,7 @@ static int kaweth_probe( | |||
918 | spin_lock_init(&kaweth->device_lock); | 972 | spin_lock_init(&kaweth->device_lock); |
919 | init_waitqueue_head(&kaweth->term_wait); | 973 | init_waitqueue_head(&kaweth->term_wait); |
920 | 974 | ||
921 | kaweth_dbg("Resetting."); | 975 | dbg("Resetting."); |
922 | 976 | ||
923 | kaweth_reset(kaweth); | 977 | kaweth_reset(kaweth); |
924 | 978 | ||
@@ -928,17 +982,17 @@ static int kaweth_probe( | |||
928 | */ | 982 | */ |
929 | 983 | ||
930 | if (le16_to_cpu(dev->descriptor.bcdDevice) >> 8) { | 984 | if (le16_to_cpu(dev->descriptor.bcdDevice) >> 8) { |
931 | kaweth_info("Firmware present in device."); | 985 | info("Firmware present in device."); |
932 | } else { | 986 | } else { |
933 | /* Download the firmware */ | 987 | /* Download the firmware */ |
934 | kaweth_info("Downloading firmware..."); | 988 | info("Downloading firmware..."); |
935 | kaweth->firmware_buf = (__u8 *)__get_free_page(GFP_KERNEL); | 989 | kaweth->firmware_buf = (__u8 *)__get_free_page(GFP_KERNEL); |
936 | if ((result = kaweth_download_firmware(kaweth, | 990 | if ((result = kaweth_download_firmware(kaweth, |
937 | kaweth_new_code, | 991 | kaweth_new_code, |
938 | len_kaweth_new_code, | 992 | len_kaweth_new_code, |
939 | 100, | 993 | 100, |
940 | 2)) < 0) { | 994 | 2)) < 0) { |
941 | kaweth_err("Error downloading firmware (%d)", result); | 995 | err("Error downloading firmware (%d)", result); |
942 | goto err_fw; | 996 | goto err_fw; |
943 | } | 997 | } |
944 | 998 | ||
@@ -947,7 +1001,7 @@ static int kaweth_probe( | |||
947 | len_kaweth_new_code_fix, | 1001 | len_kaweth_new_code_fix, |
948 | 100, | 1002 | 100, |
949 | 3)) < 0) { | 1003 | 3)) < 0) { |
950 | kaweth_err("Error downloading firmware fix (%d)", result); | 1004 | err("Error downloading firmware fix (%d)", result); |
951 | goto err_fw; | 1005 | goto err_fw; |
952 | } | 1006 | } |
953 | 1007 | ||
@@ -956,7 +1010,7 @@ static int kaweth_probe( | |||
956 | len_kaweth_trigger_code, | 1010 | len_kaweth_trigger_code, |
957 | 126, | 1011 | 126, |
958 | 2)) < 0) { | 1012 | 2)) < 0) { |
959 | kaweth_err("Error downloading trigger code (%d)", result); | 1013 | err("Error downloading trigger code (%d)", result); |
960 | goto err_fw; | 1014 | goto err_fw; |
961 | 1015 | ||
962 | } | 1016 | } |
@@ -966,18 +1020,18 @@ static int kaweth_probe( | |||
966 | len_kaweth_trigger_code_fix, | 1020 | len_kaweth_trigger_code_fix, |
967 | 126, | 1021 | 126, |
968 | 3)) < 0) { | 1022 | 3)) < 0) { |
969 | kaweth_err("Error downloading trigger code fix (%d)", result); | 1023 | err("Error downloading trigger code fix (%d)", result); |
970 | goto err_fw; | 1024 | goto err_fw; |
971 | } | 1025 | } |
972 | 1026 | ||
973 | 1027 | ||
974 | if ((result = kaweth_trigger_firmware(kaweth, 126)) < 0) { | 1028 | if ((result = kaweth_trigger_firmware(kaweth, 126)) < 0) { |
975 | kaweth_err("Error triggering firmware (%d)", result); | 1029 | err("Error triggering firmware (%d)", result); |
976 | goto err_fw; | 1030 | goto err_fw; |
977 | } | 1031 | } |
978 | 1032 | ||
979 | /* Device will now disappear for a moment... */ | 1033 | /* Device will now disappear for a moment... */ |
980 | kaweth_info("Firmware loaded. I'll be back..."); | 1034 | info("Firmware loaded. I'll be back..."); |
981 | err_fw: | 1035 | err_fw: |
982 | free_page((unsigned long)kaweth->firmware_buf); | 1036 | free_page((unsigned long)kaweth->firmware_buf); |
983 | free_netdev(netdev); | 1037 | free_netdev(netdev); |
@@ -987,14 +1041,14 @@ err_fw: | |||
987 | result = kaweth_read_configuration(kaweth); | 1041 | result = kaweth_read_configuration(kaweth); |
988 | 1042 | ||
989 | if(result < 0) { | 1043 | if(result < 0) { |
990 | kaweth_err("Error reading configuration (%d), no net device created", result); | 1044 | err("Error reading configuration (%d), no net device created", result); |
991 | goto err_free_netdev; | 1045 | goto err_free_netdev; |
992 | } | 1046 | } |
993 | 1047 | ||
994 | kaweth_info("Statistics collection: %x", kaweth->configuration.statistics_mask); | 1048 | info("Statistics collection: %x", kaweth->configuration.statistics_mask); |
995 | kaweth_info("Multicast filter limit: %x", kaweth->configuration.max_multicast_filters & ((1 << 15) - 1)); | 1049 | info("Multicast filter limit: %x", kaweth->configuration.max_multicast_filters & ((1 << 15) - 1)); |
996 | kaweth_info("MTU: %d", le16_to_cpu(kaweth->configuration.segment_size)); | 1050 | info("MTU: %d", le16_to_cpu(kaweth->configuration.segment_size)); |
997 | kaweth_info("Read MAC address %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x", | 1051 | info("Read MAC address %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x", |
998 | (int)kaweth->configuration.hw_addr[0], | 1052 | (int)kaweth->configuration.hw_addr[0], |
999 | (int)kaweth->configuration.hw_addr[1], | 1053 | (int)kaweth->configuration.hw_addr[1], |
1000 | (int)kaweth->configuration.hw_addr[2], | 1054 | (int)kaweth->configuration.hw_addr[2], |
@@ -1005,17 +1059,17 @@ err_fw: | |||
1005 | if(!memcmp(&kaweth->configuration.hw_addr, | 1059 | if(!memcmp(&kaweth->configuration.hw_addr, |
1006 | &bcast_addr, | 1060 | &bcast_addr, |
1007 | sizeof(bcast_addr))) { | 1061 | sizeof(bcast_addr))) { |
1008 | kaweth_err("Firmware not functioning properly, no net device created"); | 1062 | err("Firmware not functioning properly, no net device created"); |
1009 | goto err_free_netdev; | 1063 | goto err_free_netdev; |
1010 | } | 1064 | } |
1011 | 1065 | ||
1012 | if(kaweth_set_urb_size(kaweth, KAWETH_BUF_SIZE) < 0) { | 1066 | if(kaweth_set_urb_size(kaweth, KAWETH_BUF_SIZE) < 0) { |
1013 | kaweth_dbg("Error setting URB size"); | 1067 | dbg("Error setting URB size"); |
1014 | goto err_free_netdev; | 1068 | goto err_free_netdev; |
1015 | } | 1069 | } |
1016 | 1070 | ||
1017 | if(kaweth_set_sofs_wait(kaweth, KAWETH_SOFS_TO_WAIT) < 0) { | 1071 | if(kaweth_set_sofs_wait(kaweth, KAWETH_SOFS_TO_WAIT) < 0) { |
1018 | kaweth_err("Error setting SOFS wait"); | 1072 | err("Error setting SOFS wait"); |
1019 | goto err_free_netdev; | 1073 | goto err_free_netdev; |
1020 | } | 1074 | } |
1021 | 1075 | ||
@@ -1025,11 +1079,11 @@ err_fw: | |||
1025 | KAWETH_PACKET_FILTER_MULTICAST); | 1079 | KAWETH_PACKET_FILTER_MULTICAST); |
1026 | 1080 | ||
1027 | if(result < 0) { | 1081 | if(result < 0) { |
1028 | kaweth_err("Error setting receive filter"); | 1082 | err("Error setting receive filter"); |
1029 | goto err_free_netdev; | 1083 | goto err_free_netdev; |
1030 | } | 1084 | } |
1031 | 1085 | ||
1032 | kaweth_dbg("Initializing net device."); | 1086 | dbg("Initializing net device."); |
1033 | 1087 | ||
1034 | kaweth->tx_urb = usb_alloc_urb(0, GFP_KERNEL); | 1088 | kaweth->tx_urb = usb_alloc_urb(0, GFP_KERNEL); |
1035 | if (!kaweth->tx_urb) | 1089 | if (!kaweth->tx_urb) |
@@ -1086,13 +1140,13 @@ err_fw: | |||
1086 | 1140 | ||
1087 | SET_NETDEV_DEV(netdev, &intf->dev); | 1141 | SET_NETDEV_DEV(netdev, &intf->dev); |
1088 | if (register_netdev(netdev) != 0) { | 1142 | if (register_netdev(netdev) != 0) { |
1089 | kaweth_err("Error registering netdev."); | 1143 | err("Error registering netdev."); |
1090 | goto err_intfdata; | 1144 | goto err_intfdata; |
1091 | } | 1145 | } |
1092 | 1146 | ||
1093 | kaweth_info("kaweth interface created at %s", kaweth->net->name); | 1147 | info("kaweth interface created at %s", kaweth->net->name); |
1094 | 1148 | ||
1095 | kaweth_dbg("Kaweth probe returning."); | 1149 | dbg("Kaweth probe returning."); |
1096 | 1150 | ||
1097 | return 0; | 1151 | return 0; |
1098 | 1152 | ||
@@ -1121,16 +1175,16 @@ static void kaweth_disconnect(struct usb_interface *intf) | |||
1121 | struct kaweth_device *kaweth = usb_get_intfdata(intf); | 1175 | struct kaweth_device *kaweth = usb_get_intfdata(intf); |
1122 | struct net_device *netdev; | 1176 | struct net_device *netdev; |
1123 | 1177 | ||
1124 | kaweth_info("Unregistering"); | 1178 | info("Unregistering"); |
1125 | 1179 | ||
1126 | usb_set_intfdata(intf, NULL); | 1180 | usb_set_intfdata(intf, NULL); |
1127 | if (!kaweth) { | 1181 | if (!kaweth) { |
1128 | kaweth_warn("unregistering non-existant device"); | 1182 | warn("unregistering non-existant device"); |
1129 | return; | 1183 | return; |
1130 | } | 1184 | } |
1131 | netdev = kaweth->net; | 1185 | netdev = kaweth->net; |
1132 | 1186 | ||
1133 | kaweth_dbg("Unregistering net device"); | 1187 | dbg("Unregistering net device"); |
1134 | unregister_netdev(netdev); | 1188 | unregister_netdev(netdev); |
1135 | 1189 | ||
1136 | usb_free_urb(kaweth->rx_urb); | 1190 | usb_free_urb(kaweth->rx_urb); |
@@ -1185,7 +1239,7 @@ static int usb_start_wait_urb(struct urb *urb, int timeout, int* actual_length) | |||
1185 | 1239 | ||
1186 | if (!wait_event_timeout(awd.wqh, awd.done, timeout)) { | 1240 | if (!wait_event_timeout(awd.wqh, awd.done, timeout)) { |
1187 | // timeout | 1241 | // timeout |
1188 | kaweth_warn("usb_control/bulk_msg: timeout"); | 1242 | warn("usb_control/bulk_msg: timeout"); |
1189 | usb_kill_urb(urb); // remove urb safely | 1243 | usb_kill_urb(urb); // remove urb safely |
1190 | status = -ETIMEDOUT; | 1244 | status = -ETIMEDOUT; |
1191 | } | 1245 | } |
@@ -1234,7 +1288,7 @@ static int kaweth_internal_control_msg(struct usb_device *usb_dev, | |||
1234 | ****************************************************************/ | 1288 | ****************************************************************/ |
1235 | static int __init kaweth_init(void) | 1289 | static int __init kaweth_init(void) |
1236 | { | 1290 | { |
1237 | kaweth_dbg("Driver loading"); | 1291 | dbg("Driver loading"); |
1238 | return usb_register(&kaweth_driver); | 1292 | return usb_register(&kaweth_driver); |
1239 | } | 1293 | } |
1240 | 1294 | ||
diff --git a/drivers/usb/net/mcs7830.c b/drivers/usb/net/mcs7830.c new file mode 100644 index 000000000000..6240b978fe3d --- /dev/null +++ b/drivers/usb/net/mcs7830.c | |||
@@ -0,0 +1,534 @@ | |||
1 | /* | ||
2 | * MosChips MCS7830 based USB 2.0 Ethernet Devices | ||
3 | * | ||
4 | * based on usbnet.c, asix.c and the vendor provided mcs7830 driver | ||
5 | * | ||
6 | * Copyright (C) 2006 Arnd Bergmann <arnd@arndb.de> | ||
7 | * Copyright (C) 2003-2005 David Hollis <dhollis@davehollis.com> | ||
8 | * Copyright (C) 2005 Phil Chang <pchang23@sbcglobal.net> | ||
9 | * Copyright (c) 2002-2003 TiVo Inc. | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License as published by | ||
13 | * the Free Software Foundation; either version 2 of the License, or | ||
14 | * (at your option) any later version. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License | ||
22 | * along with this program; if not, write to the Free Software | ||
23 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
24 | */ | ||
25 | |||
26 | #include <linux/crc32.h> | ||
27 | #include <linux/etherdevice.h> | ||
28 | #include <linux/ethtool.h> | ||
29 | #include <linux/init.h> | ||
30 | #include <linux/mii.h> | ||
31 | #include <linux/module.h> | ||
32 | #include <linux/netdevice.h> | ||
33 | #include <linux/usb.h> | ||
34 | |||
35 | #include "usbnet.h" | ||
36 | |||
37 | /* requests */ | ||
38 | #define MCS7830_RD_BMREQ (USB_DIR_IN | USB_TYPE_VENDOR | \ | ||
39 | USB_RECIP_DEVICE) | ||
40 | #define MCS7830_WR_BMREQ (USB_DIR_OUT | USB_TYPE_VENDOR | \ | ||
41 | USB_RECIP_DEVICE) | ||
42 | #define MCS7830_RD_BREQ 0x0E | ||
43 | #define MCS7830_WR_BREQ 0x0D | ||
44 | |||
45 | #define MCS7830_CTRL_TIMEOUT 1000 | ||
46 | #define MCS7830_MAX_MCAST 64 | ||
47 | |||
48 | #define MCS7830_VENDOR_ID 0x9710 | ||
49 | #define MCS7830_PRODUCT_ID 0x7830 | ||
50 | |||
51 | #define MCS7830_MII_ADVERTISE (ADVERTISE_PAUSE_CAP | ADVERTISE_100FULL | \ | ||
52 | ADVERTISE_100HALF | ADVERTISE_10FULL | \ | ||
53 | ADVERTISE_10HALF | ADVERTISE_CSMA) | ||
54 | |||
55 | /* HIF_REG_XX coressponding index value */ | ||
56 | enum { | ||
57 | HIF_REG_MULTICAST_HASH = 0x00, | ||
58 | HIF_REG_PACKET_GAP1 = 0x08, | ||
59 | HIF_REG_PACKET_GAP2 = 0x09, | ||
60 | HIF_REG_PHY_DATA = 0x0a, | ||
61 | HIF_REG_PHY_CMD1 = 0x0c, | ||
62 | HIF_REG_PHY_CMD1_READ = 0x40, | ||
63 | HIF_REG_PHY_CMD1_WRITE = 0x20, | ||
64 | HIF_REG_PHY_CMD1_PHYADDR = 0x01, | ||
65 | HIF_REG_PHY_CMD2 = 0x0d, | ||
66 | HIF_REG_PHY_CMD2_PEND_FLAG_BIT = 0x80, | ||
67 | HIF_REG_PHY_CMD2_READY_FLAG_BIT = 0x40, | ||
68 | HIF_REG_CONFIG = 0x0e, | ||
69 | HIF_REG_CONFIG_CFG = 0x80, | ||
70 | HIF_REG_CONFIG_SPEED100 = 0x40, | ||
71 | HIF_REG_CONFIG_FULLDUPLEX_ENABLE = 0x20, | ||
72 | HIF_REG_CONFIG_RXENABLE = 0x10, | ||
73 | HIF_REG_CONFIG_TXENABLE = 0x08, | ||
74 | HIF_REG_CONFIG_SLEEPMODE = 0x04, | ||
75 | HIF_REG_CONFIG_ALLMULTICAST = 0x02, | ||
76 | HIF_REG_CONFIG_PROMISCIOUS = 0x01, | ||
77 | HIF_REG_ETHERNET_ADDR = 0x0f, | ||
78 | HIF_REG_22 = 0x15, | ||
79 | HIF_REG_PAUSE_THRESHOLD = 0x16, | ||
80 | HIF_REG_PAUSE_THRESHOLD_DEFAULT = 0, | ||
81 | }; | ||
82 | |||
83 | struct mcs7830_data { | ||
84 | u8 multi_filter[8]; | ||
85 | u8 config; | ||
86 | }; | ||
87 | |||
88 | static const char driver_name[] = "MOSCHIP usb-ethernet driver"; | ||
89 | |||
90 | static int mcs7830_get_reg(struct usbnet *dev, u16 index, u16 size, void *data) | ||
91 | { | ||
92 | struct usb_device *xdev = dev->udev; | ||
93 | int ret; | ||
94 | |||
95 | ret = usb_control_msg(xdev, usb_rcvctrlpipe(xdev, 0), MCS7830_RD_BREQ, | ||
96 | MCS7830_RD_BMREQ, 0x0000, index, data, | ||
97 | size, msecs_to_jiffies(MCS7830_CTRL_TIMEOUT)); | ||
98 | return ret; | ||
99 | } | ||
100 | |||
101 | static int mcs7830_set_reg(struct usbnet *dev, u16 index, u16 size, void *data) | ||
102 | { | ||
103 | struct usb_device *xdev = dev->udev; | ||
104 | int ret; | ||
105 | |||
106 | ret = usb_control_msg(xdev, usb_sndctrlpipe(xdev, 0), MCS7830_WR_BREQ, | ||
107 | MCS7830_WR_BMREQ, 0x0000, index, data, | ||
108 | size, msecs_to_jiffies(MCS7830_CTRL_TIMEOUT)); | ||
109 | return ret; | ||
110 | } | ||
111 | |||
112 | static void mcs7830_async_cmd_callback(struct urb *urb) | ||
113 | { | ||
114 | struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context; | ||
115 | |||
116 | if (urb->status < 0) | ||
117 | printk(KERN_DEBUG "mcs7830_async_cmd_callback() failed with %d", | ||
118 | urb->status); | ||
119 | |||
120 | kfree(req); | ||
121 | usb_free_urb(urb); | ||
122 | } | ||
123 | |||
124 | static void mcs7830_set_reg_async(struct usbnet *dev, u16 index, u16 size, void *data) | ||
125 | { | ||
126 | struct usb_ctrlrequest *req; | ||
127 | int ret; | ||
128 | struct urb *urb; | ||
129 | |||
130 | urb = usb_alloc_urb(0, GFP_ATOMIC); | ||
131 | if (!urb) { | ||
132 | dev_dbg(&dev->udev->dev, "Error allocating URB " | ||
133 | "in write_cmd_async!"); | ||
134 | return; | ||
135 | } | ||
136 | |||
137 | req = kmalloc(sizeof *req, GFP_ATOMIC); | ||
138 | if (!req) { | ||
139 | dev_err(&dev->udev->dev, "Failed to allocate memory for " | ||
140 | "control request"); | ||
141 | goto out; | ||
142 | } | ||
143 | req->bRequestType = MCS7830_WR_BMREQ; | ||
144 | req->bRequest = MCS7830_WR_BREQ; | ||
145 | req->wValue = 0; | ||
146 | req->wIndex = cpu_to_le16(index); | ||
147 | req->wLength = cpu_to_le16(size); | ||
148 | |||
149 | usb_fill_control_urb(urb, dev->udev, | ||
150 | usb_sndctrlpipe(dev->udev, 0), | ||
151 | (void *)req, data, size, | ||
152 | mcs7830_async_cmd_callback, req); | ||
153 | |||
154 | ret = usb_submit_urb(urb, GFP_ATOMIC); | ||
155 | if (ret < 0) { | ||
156 | dev_err(&dev->udev->dev, "Error submitting the control " | ||
157 | "message: ret=%d", ret); | ||
158 | goto out; | ||
159 | } | ||
160 | return; | ||
161 | out: | ||
162 | kfree(req); | ||
163 | usb_free_urb(urb); | ||
164 | } | ||
165 | |||
166 | static int mcs7830_get_address(struct usbnet *dev) | ||
167 | { | ||
168 | int ret; | ||
169 | ret = mcs7830_get_reg(dev, HIF_REG_ETHERNET_ADDR, ETH_ALEN, | ||
170 | dev->net->dev_addr); | ||
171 | if (ret < 0) | ||
172 | return ret; | ||
173 | return 0; | ||
174 | } | ||
175 | |||
176 | static int mcs7830_read_phy(struct usbnet *dev, u8 index) | ||
177 | { | ||
178 | int ret; | ||
179 | int i; | ||
180 | __le16 val; | ||
181 | |||
182 | u8 cmd[2] = { | ||
183 | HIF_REG_PHY_CMD1_READ | HIF_REG_PHY_CMD1_PHYADDR, | ||
184 | HIF_REG_PHY_CMD2_PEND_FLAG_BIT | index, | ||
185 | }; | ||
186 | |||
187 | mutex_lock(&dev->phy_mutex); | ||
188 | /* write the MII command */ | ||
189 | ret = mcs7830_set_reg(dev, HIF_REG_PHY_CMD1, 2, cmd); | ||
190 | if (ret < 0) | ||
191 | goto out; | ||
192 | |||
193 | /* wait for the data to become valid, should be within < 1ms */ | ||
194 | for (i = 0; i < 10; i++) { | ||
195 | ret = mcs7830_get_reg(dev, HIF_REG_PHY_CMD1, 2, cmd); | ||
196 | if ((ret < 0) || (cmd[1] & HIF_REG_PHY_CMD2_READY_FLAG_BIT)) | ||
197 | break; | ||
198 | ret = -EIO; | ||
199 | msleep(1); | ||
200 | } | ||
201 | if (ret < 0) | ||
202 | goto out; | ||
203 | |||
204 | /* read actual register contents */ | ||
205 | ret = mcs7830_get_reg(dev, HIF_REG_PHY_DATA, 2, &val); | ||
206 | if (ret < 0) | ||
207 | goto out; | ||
208 | ret = le16_to_cpu(val); | ||
209 | dev_dbg(&dev->udev->dev, "read PHY reg %02x: %04x (%d tries)\n", | ||
210 | index, val, i); | ||
211 | out: | ||
212 | mutex_unlock(&dev->phy_mutex); | ||
213 | return ret; | ||
214 | } | ||
215 | |||
216 | static int mcs7830_write_phy(struct usbnet *dev, u8 index, u16 val) | ||
217 | { | ||
218 | int ret; | ||
219 | int i; | ||
220 | __le16 le_val; | ||
221 | |||
222 | u8 cmd[2] = { | ||
223 | HIF_REG_PHY_CMD1_WRITE | HIF_REG_PHY_CMD1_PHYADDR, | ||
224 | HIF_REG_PHY_CMD2_PEND_FLAG_BIT | (index & 0x1F), | ||
225 | }; | ||
226 | |||
227 | mutex_lock(&dev->phy_mutex); | ||
228 | |||
229 | /* write the new register contents */ | ||
230 | le_val = cpu_to_le16(val); | ||
231 | ret = mcs7830_set_reg(dev, HIF_REG_PHY_DATA, 2, &le_val); | ||
232 | if (ret < 0) | ||
233 | goto out; | ||
234 | |||
235 | /* write the MII command */ | ||
236 | ret = mcs7830_set_reg(dev, HIF_REG_PHY_CMD1, 2, cmd); | ||
237 | if (ret < 0) | ||
238 | goto out; | ||
239 | |||
240 | /* wait for the command to be accepted by the PHY */ | ||
241 | for (i = 0; i < 10; i++) { | ||
242 | ret = mcs7830_get_reg(dev, HIF_REG_PHY_CMD1, 2, cmd); | ||
243 | if ((ret < 0) || (cmd[1] & HIF_REG_PHY_CMD2_READY_FLAG_BIT)) | ||
244 | break; | ||
245 | ret = -EIO; | ||
246 | msleep(1); | ||
247 | } | ||
248 | if (ret < 0) | ||
249 | goto out; | ||
250 | |||
251 | ret = 0; | ||
252 | dev_dbg(&dev->udev->dev, "write PHY reg %02x: %04x (%d tries)\n", | ||
253 | index, val, i); | ||
254 | out: | ||
255 | mutex_unlock(&dev->phy_mutex); | ||
256 | return ret; | ||
257 | } | ||
258 | |||
259 | /* | ||
260 | * This algorithm comes from the original mcs7830 version 1.4 driver, | ||
261 | * not sure if it is needed. | ||
262 | */ | ||
263 | static int mcs7830_set_autoneg(struct usbnet *dev, int ptrUserPhyMode) | ||
264 | { | ||
265 | int ret; | ||
266 | /* Enable all media types */ | ||
267 | ret = mcs7830_write_phy(dev, MII_ADVERTISE, MCS7830_MII_ADVERTISE); | ||
268 | |||
269 | /* First reset BMCR */ | ||
270 | if (!ret) | ||
271 | ret = mcs7830_write_phy(dev, MII_BMCR, 0x0000); | ||
272 | /* Enable Auto Neg */ | ||
273 | if (!ret) | ||
274 | ret = mcs7830_write_phy(dev, MII_BMCR, BMCR_ANENABLE); | ||
275 | /* Restart Auto Neg (Keep the Enable Auto Neg Bit Set) */ | ||
276 | if (!ret) | ||
277 | ret = mcs7830_write_phy(dev, MII_BMCR, | ||
278 | BMCR_ANENABLE | BMCR_ANRESTART ); | ||
279 | return ret < 0 ? : 0; | ||
280 | } | ||
281 | |||
282 | |||
283 | /* | ||
284 | * if we can read register 22, the chip revision is C or higher | ||
285 | */ | ||
286 | static int mcs7830_get_rev(struct usbnet *dev) | ||
287 | { | ||
288 | u8 dummy[2]; | ||
289 | int ret; | ||
290 | ret = mcs7830_get_reg(dev, HIF_REG_22, 2, dummy); | ||
291 | if (ret > 0) | ||
292 | return 2; /* Rev C or later */ | ||
293 | return 1; /* earlier revision */ | ||
294 | } | ||
295 | |||
296 | /* | ||
297 | * On rev. C we need to set the pause threshold | ||
298 | */ | ||
299 | static void mcs7830_rev_C_fixup(struct usbnet *dev) | ||
300 | { | ||
301 | u8 pause_threshold = HIF_REG_PAUSE_THRESHOLD_DEFAULT; | ||
302 | int retry; | ||
303 | |||
304 | for (retry = 0; retry < 2; retry++) { | ||
305 | if (mcs7830_get_rev(dev) == 2) { | ||
306 | dev_info(&dev->udev->dev, "applying rev.C fixup\n"); | ||
307 | mcs7830_set_reg(dev, HIF_REG_PAUSE_THRESHOLD, | ||
308 | 1, &pause_threshold); | ||
309 | } | ||
310 | msleep(1); | ||
311 | } | ||
312 | } | ||
313 | |||
314 | static int mcs7830_init_dev(struct usbnet *dev) | ||
315 | { | ||
316 | int ret; | ||
317 | int retry; | ||
318 | |||
319 | /* Read MAC address from EEPROM */ | ||
320 | ret = -EINVAL; | ||
321 | for (retry = 0; retry < 5 && ret; retry++) | ||
322 | ret = mcs7830_get_address(dev); | ||
323 | if (ret) { | ||
324 | dev_warn(&dev->udev->dev, "Cannot read MAC address\n"); | ||
325 | goto out; | ||
326 | } | ||
327 | |||
328 | /* Set up PHY */ | ||
329 | ret = mcs7830_set_autoneg(dev, 0); | ||
330 | if (ret) { | ||
331 | dev_info(&dev->udev->dev, "Cannot set autoneg\n"); | ||
332 | goto out; | ||
333 | } | ||
334 | |||
335 | mcs7830_rev_C_fixup(dev); | ||
336 | ret = 0; | ||
337 | out: | ||
338 | return ret; | ||
339 | } | ||
340 | |||
341 | static int mcs7830_mdio_read(struct net_device *netdev, int phy_id, | ||
342 | int location) | ||
343 | { | ||
344 | struct usbnet *dev = netdev->priv; | ||
345 | return mcs7830_read_phy(dev, location); | ||
346 | } | ||
347 | |||
348 | static void mcs7830_mdio_write(struct net_device *netdev, int phy_id, | ||
349 | int location, int val) | ||
350 | { | ||
351 | struct usbnet *dev = netdev->priv; | ||
352 | mcs7830_write_phy(dev, location, val); | ||
353 | } | ||
354 | |||
355 | static int mcs7830_ioctl(struct net_device *net, struct ifreq *rq, int cmd) | ||
356 | { | ||
357 | struct usbnet *dev = netdev_priv(net); | ||
358 | return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL); | ||
359 | } | ||
360 | |||
361 | /* credits go to asix_set_multicast */ | ||
362 | static void mcs7830_set_multicast(struct net_device *net) | ||
363 | { | ||
364 | struct usbnet *dev = netdev_priv(net); | ||
365 | struct mcs7830_data *data = (struct mcs7830_data *)&dev->data; | ||
366 | |||
367 | data->config = HIF_REG_CONFIG_TXENABLE; | ||
368 | |||
369 | /* this should not be needed, but it doesn't work otherwise */ | ||
370 | data->config |= HIF_REG_CONFIG_ALLMULTICAST; | ||
371 | |||
372 | if (net->flags & IFF_PROMISC) { | ||
373 | data->config |= HIF_REG_CONFIG_PROMISCIOUS; | ||
374 | } else if (net->flags & IFF_ALLMULTI | ||
375 | || net->mc_count > MCS7830_MAX_MCAST) { | ||
376 | data->config |= HIF_REG_CONFIG_ALLMULTICAST; | ||
377 | } else if (net->mc_count == 0) { | ||
378 | /* just broadcast and directed */ | ||
379 | } else { | ||
380 | /* We use the 20 byte dev->data | ||
381 | * for our 8 byte filter buffer | ||
382 | * to avoid allocating memory that | ||
383 | * is tricky to free later */ | ||
384 | struct dev_mc_list *mc_list = net->mc_list; | ||
385 | u32 crc_bits; | ||
386 | int i; | ||
387 | |||
388 | memset(data->multi_filter, 0, sizeof data->multi_filter); | ||
389 | |||
390 | /* Build the multicast hash filter. */ | ||
391 | for (i = 0; i < net->mc_count; i++) { | ||
392 | crc_bits = ether_crc(ETH_ALEN, mc_list->dmi_addr) >> 26; | ||
393 | data->multi_filter[crc_bits >> 3] |= 1 << (crc_bits & 7); | ||
394 | mc_list = mc_list->next; | ||
395 | } | ||
396 | |||
397 | mcs7830_set_reg_async(dev, HIF_REG_MULTICAST_HASH, | ||
398 | sizeof data->multi_filter, | ||
399 | data->multi_filter); | ||
400 | } | ||
401 | |||
402 | mcs7830_set_reg_async(dev, HIF_REG_CONFIG, 1, &data->config); | ||
403 | } | ||
404 | |||
405 | static int mcs7830_get_regs_len(struct net_device *net) | ||
406 | { | ||
407 | struct usbnet *dev = netdev_priv(net); | ||
408 | |||
409 | switch (mcs7830_get_rev(dev)) { | ||
410 | case 1: | ||
411 | return 21; | ||
412 | case 2: | ||
413 | return 32; | ||
414 | } | ||
415 | return 0; | ||
416 | } | ||
417 | |||
418 | static void mcs7830_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *drvinfo) | ||
419 | { | ||
420 | usbnet_get_drvinfo(net, drvinfo); | ||
421 | drvinfo->regdump_len = mcs7830_get_regs_len(net); | ||
422 | } | ||
423 | |||
424 | static void mcs7830_get_regs(struct net_device *net, struct ethtool_regs *regs, void *data) | ||
425 | { | ||
426 | struct usbnet *dev = netdev_priv(net); | ||
427 | |||
428 | regs->version = mcs7830_get_rev(dev); | ||
429 | mcs7830_get_reg(dev, 0, regs->len, data); | ||
430 | } | ||
431 | |||
432 | static struct ethtool_ops mcs7830_ethtool_ops = { | ||
433 | .get_drvinfo = mcs7830_get_drvinfo, | ||
434 | .get_regs_len = mcs7830_get_regs_len, | ||
435 | .get_regs = mcs7830_get_regs, | ||
436 | |||
437 | /* common usbnet calls */ | ||
438 | .get_link = usbnet_get_link, | ||
439 | .get_msglevel = usbnet_get_msglevel, | ||
440 | .set_msglevel = usbnet_set_msglevel, | ||
441 | .get_settings = usbnet_get_settings, | ||
442 | .set_settings = usbnet_set_settings, | ||
443 | .nway_reset = usbnet_nway_reset, | ||
444 | }; | ||
445 | |||
446 | static int mcs7830_bind(struct usbnet *dev, struct usb_interface *udev) | ||
447 | { | ||
448 | struct net_device *net = dev->net; | ||
449 | int ret; | ||
450 | |||
451 | ret = mcs7830_init_dev(dev); | ||
452 | if (ret) | ||
453 | goto out; | ||
454 | |||
455 | net->do_ioctl = mcs7830_ioctl; | ||
456 | net->ethtool_ops = &mcs7830_ethtool_ops; | ||
457 | net->set_multicast_list = mcs7830_set_multicast; | ||
458 | mcs7830_set_multicast(net); | ||
459 | |||
460 | /* reserve space for the status byte on rx */ | ||
461 | dev->rx_urb_size = ETH_FRAME_LEN + 1; | ||
462 | |||
463 | dev->mii.mdio_read = mcs7830_mdio_read; | ||
464 | dev->mii.mdio_write = mcs7830_mdio_write; | ||
465 | dev->mii.dev = net; | ||
466 | dev->mii.phy_id_mask = 0x3f; | ||
467 | dev->mii.reg_num_mask = 0x1f; | ||
468 | dev->mii.phy_id = *((u8 *) net->dev_addr + 1); | ||
469 | |||
470 | ret = usbnet_get_endpoints(dev, udev); | ||
471 | out: | ||
472 | return ret; | ||
473 | } | ||
474 | |||
475 | /* The chip always appends a status bytes that we need to strip */ | ||
476 | static int mcs7830_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | ||
477 | { | ||
478 | u8 status; | ||
479 | |||
480 | if (skb->len == 0) { | ||
481 | dev_err(&dev->udev->dev, "unexpected empty rx frame\n"); | ||
482 | return 0; | ||
483 | } | ||
484 | |||
485 | skb_trim(skb, skb->len - 1); | ||
486 | status = skb->data[skb->len]; | ||
487 | |||
488 | if (status != 0x20) | ||
489 | dev_dbg(&dev->udev->dev, "rx fixup status %x\n", status); | ||
490 | |||
491 | return skb->len > 0; | ||
492 | } | ||
493 | |||
494 | static const struct driver_info moschip_info = { | ||
495 | .description = "MOSCHIP 7830 usb-NET adapter", | ||
496 | .bind = mcs7830_bind, | ||
497 | .rx_fixup = mcs7830_rx_fixup, | ||
498 | .flags = FLAG_ETHER, | ||
499 | .in = 1, | ||
500 | .out = 2, | ||
501 | }; | ||
502 | |||
503 | static const struct usb_device_id products[] = { | ||
504 | { | ||
505 | USB_DEVICE(MCS7830_VENDOR_ID, MCS7830_PRODUCT_ID), | ||
506 | .driver_info = (unsigned long) &moschip_info, | ||
507 | }, | ||
508 | {}, | ||
509 | }; | ||
510 | MODULE_DEVICE_TABLE(usb, products); | ||
511 | |||
512 | static struct usb_driver mcs7830_driver = { | ||
513 | .name = driver_name, | ||
514 | .id_table = products, | ||
515 | .probe = usbnet_probe, | ||
516 | .disconnect = usbnet_disconnect, | ||
517 | .suspend = usbnet_suspend, | ||
518 | .resume = usbnet_resume, | ||
519 | }; | ||
520 | |||
521 | static int __init mcs7830_init(void) | ||
522 | { | ||
523 | return usb_register(&mcs7830_driver); | ||
524 | } | ||
525 | module_init(mcs7830_init); | ||
526 | |||
527 | static void __exit mcs7830_exit(void) | ||
528 | { | ||
529 | usb_deregister(&mcs7830_driver); | ||
530 | } | ||
531 | module_exit(mcs7830_exit); | ||
532 | |||
533 | MODULE_DESCRIPTION("USB to network adapter MCS7830)"); | ||
534 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c index 24bd3486ee63..760b5327b81b 100644 --- a/drivers/usb/net/usbnet.c +++ b/drivers/usb/net/usbnet.c | |||
@@ -554,7 +554,7 @@ static int usbnet_stop (struct net_device *net) | |||
554 | { | 554 | { |
555 | struct usbnet *dev = netdev_priv(net); | 555 | struct usbnet *dev = netdev_priv(net); |
556 | int temp; | 556 | int temp; |
557 | DECLARE_WAIT_QUEUE_HEAD (unlink_wakeup); | 557 | DECLARE_WAIT_QUEUE_HEAD_ONSTACK (unlink_wakeup); |
558 | DECLARE_WAITQUEUE (wait, current); | 558 | DECLARE_WAITQUEUE (wait, current); |
559 | 559 | ||
560 | netif_stop_queue (net); | 560 | netif_stop_queue (net); |
@@ -669,20 +669,40 @@ done: | |||
669 | * they'll probably want to use this base set. | 669 | * they'll probably want to use this base set. |
670 | */ | 670 | */ |
671 | 671 | ||
672 | void usbnet_get_drvinfo (struct net_device *net, struct ethtool_drvinfo *info) | 672 | #if defined(CONFIG_MII) || defined(CONFIG_MII_MODULE) |
673 | #define HAVE_MII | ||
674 | |||
675 | int usbnet_get_settings (struct net_device *net, struct ethtool_cmd *cmd) | ||
673 | { | 676 | { |
674 | struct usbnet *dev = netdev_priv(net); | 677 | struct usbnet *dev = netdev_priv(net); |
675 | 678 | ||
676 | /* REVISIT don't always return "usbnet" */ | 679 | if (!dev->mii.mdio_read) |
677 | strncpy (info->driver, driver_name, sizeof info->driver); | 680 | return -EOPNOTSUPP; |
678 | strncpy (info->version, DRIVER_VERSION, sizeof info->version); | 681 | |
679 | strncpy (info->fw_version, dev->driver_info->description, | 682 | return mii_ethtool_gset(&dev->mii, cmd); |
680 | sizeof info->fw_version); | ||
681 | usb_make_path (dev->udev, info->bus_info, sizeof info->bus_info); | ||
682 | } | 683 | } |
683 | EXPORT_SYMBOL_GPL(usbnet_get_drvinfo); | 684 | EXPORT_SYMBOL_GPL(usbnet_get_settings); |
685 | |||
686 | int usbnet_set_settings (struct net_device *net, struct ethtool_cmd *cmd) | ||
687 | { | ||
688 | struct usbnet *dev = netdev_priv(net); | ||
689 | int retval; | ||
690 | |||
691 | if (!dev->mii.mdio_write) | ||
692 | return -EOPNOTSUPP; | ||
684 | 693 | ||
685 | static u32 usbnet_get_link (struct net_device *net) | 694 | retval = mii_ethtool_sset(&dev->mii, cmd); |
695 | |||
696 | /* link speed/duplex might have changed */ | ||
697 | if (dev->driver_info->link_reset) | ||
698 | dev->driver_info->link_reset(dev); | ||
699 | |||
700 | return retval; | ||
701 | |||
702 | } | ||
703 | EXPORT_SYMBOL_GPL(usbnet_set_settings); | ||
704 | |||
705 | u32 usbnet_get_link (struct net_device *net) | ||
686 | { | 706 | { |
687 | struct usbnet *dev = netdev_priv(net); | 707 | struct usbnet *dev = netdev_priv(net); |
688 | 708 | ||
@@ -690,9 +710,40 @@ static u32 usbnet_get_link (struct net_device *net) | |||
690 | if (dev->driver_info->check_connect) | 710 | if (dev->driver_info->check_connect) |
691 | return dev->driver_info->check_connect (dev) == 0; | 711 | return dev->driver_info->check_connect (dev) == 0; |
692 | 712 | ||
713 | /* if the device has mii operations, use those */ | ||
714 | if (dev->mii.mdio_read) | ||
715 | return mii_link_ok(&dev->mii); | ||
716 | |||
693 | /* Otherwise, say we're up (to avoid breaking scripts) */ | 717 | /* Otherwise, say we're up (to avoid breaking scripts) */ |
694 | return 1; | 718 | return 1; |
695 | } | 719 | } |
720 | EXPORT_SYMBOL_GPL(usbnet_get_link); | ||
721 | |||
722 | int usbnet_nway_reset(struct net_device *net) | ||
723 | { | ||
724 | struct usbnet *dev = netdev_priv(net); | ||
725 | |||
726 | if (!dev->mii.mdio_write) | ||
727 | return -EOPNOTSUPP; | ||
728 | |||
729 | return mii_nway_restart(&dev->mii); | ||
730 | } | ||
731 | EXPORT_SYMBOL_GPL(usbnet_nway_reset); | ||
732 | |||
733 | #endif /* HAVE_MII */ | ||
734 | |||
735 | void usbnet_get_drvinfo (struct net_device *net, struct ethtool_drvinfo *info) | ||
736 | { | ||
737 | struct usbnet *dev = netdev_priv(net); | ||
738 | |||
739 | /* REVISIT don't always return "usbnet" */ | ||
740 | strncpy (info->driver, driver_name, sizeof info->driver); | ||
741 | strncpy (info->version, DRIVER_VERSION, sizeof info->version); | ||
742 | strncpy (info->fw_version, dev->driver_info->description, | ||
743 | sizeof info->fw_version); | ||
744 | usb_make_path (dev->udev, info->bus_info, sizeof info->bus_info); | ||
745 | } | ||
746 | EXPORT_SYMBOL_GPL(usbnet_get_drvinfo); | ||
696 | 747 | ||
697 | u32 usbnet_get_msglevel (struct net_device *net) | 748 | u32 usbnet_get_msglevel (struct net_device *net) |
698 | { | 749 | { |
@@ -712,8 +763,13 @@ EXPORT_SYMBOL_GPL(usbnet_set_msglevel); | |||
712 | 763 | ||
713 | /* drivers may override default ethtool_ops in their bind() routine */ | 764 | /* drivers may override default ethtool_ops in their bind() routine */ |
714 | static struct ethtool_ops usbnet_ethtool_ops = { | 765 | static struct ethtool_ops usbnet_ethtool_ops = { |
715 | .get_drvinfo = usbnet_get_drvinfo, | 766 | #ifdef HAVE_MII |
767 | .get_settings = usbnet_get_settings, | ||
768 | .set_settings = usbnet_set_settings, | ||
716 | .get_link = usbnet_get_link, | 769 | .get_link = usbnet_get_link, |
770 | .nway_reset = usbnet_nway_reset, | ||
771 | #endif | ||
772 | .get_drvinfo = usbnet_get_drvinfo, | ||
717 | .get_msglevel = usbnet_get_msglevel, | 773 | .get_msglevel = usbnet_get_msglevel, |
718 | .set_msglevel = usbnet_set_msglevel, | 774 | .set_msglevel = usbnet_set_msglevel, |
719 | }; | 775 | }; |
@@ -1094,6 +1150,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) | |||
1094 | dev->delay.function = usbnet_bh; | 1150 | dev->delay.function = usbnet_bh; |
1095 | dev->delay.data = (unsigned long) dev; | 1151 | dev->delay.data = (unsigned long) dev; |
1096 | init_timer (&dev->delay); | 1152 | init_timer (&dev->delay); |
1153 | mutex_init (&dev->phy_mutex); | ||
1097 | 1154 | ||
1098 | SET_MODULE_OWNER (net); | 1155 | SET_MODULE_OWNER (net); |
1099 | dev->net = net; | 1156 | dev->net = net; |
@@ -1225,7 +1282,7 @@ EXPORT_SYMBOL_GPL(usbnet_resume); | |||
1225 | static int __init usbnet_init(void) | 1282 | static int __init usbnet_init(void) |
1226 | { | 1283 | { |
1227 | /* compiler should optimize this out */ | 1284 | /* compiler should optimize this out */ |
1228 | BUG_ON (sizeof (((struct sk_buff *)0)->cb) | 1285 | BUILD_BUG_ON (sizeof (((struct sk_buff *)0)->cb) |
1229 | < sizeof (struct skb_data)); | 1286 | < sizeof (struct skb_data)); |
1230 | 1287 | ||
1231 | random_ether_addr(node_id); | 1288 | random_ether_addr(node_id); |
diff --git a/drivers/usb/net/usbnet.h b/drivers/usb/net/usbnet.h index c0746f0454af..07c70abbe0ec 100644 --- a/drivers/usb/net/usbnet.h +++ b/drivers/usb/net/usbnet.h | |||
@@ -30,6 +30,7 @@ struct usbnet { | |||
30 | struct usb_device *udev; | 30 | struct usb_device *udev; |
31 | struct driver_info *driver_info; | 31 | struct driver_info *driver_info; |
32 | wait_queue_head_t *wait; | 32 | wait_queue_head_t *wait; |
33 | struct mutex phy_mutex; | ||
33 | 34 | ||
34 | /* i/o info: pipes etc */ | 35 | /* i/o info: pipes etc */ |
35 | unsigned in, out; | 36 | unsigned in, out; |
@@ -168,9 +169,13 @@ extern void usbnet_defer_kevent (struct usbnet *, int); | |||
168 | extern void usbnet_skb_return (struct usbnet *, struct sk_buff *); | 169 | extern void usbnet_skb_return (struct usbnet *, struct sk_buff *); |
169 | extern void usbnet_unlink_rx_urbs(struct usbnet *); | 170 | extern void usbnet_unlink_rx_urbs(struct usbnet *); |
170 | 171 | ||
172 | extern int usbnet_get_settings (struct net_device *net, struct ethtool_cmd *cmd); | ||
173 | extern int usbnet_set_settings (struct net_device *net, struct ethtool_cmd *cmd); | ||
174 | extern u32 usbnet_get_link (struct net_device *net); | ||
171 | extern u32 usbnet_get_msglevel (struct net_device *); | 175 | extern u32 usbnet_get_msglevel (struct net_device *); |
172 | extern void usbnet_set_msglevel (struct net_device *, u32); | 176 | extern void usbnet_set_msglevel (struct net_device *, u32); |
173 | extern void usbnet_get_drvinfo (struct net_device *, struct ethtool_drvinfo *); | 177 | extern void usbnet_get_drvinfo (struct net_device *, struct ethtool_drvinfo *); |
178 | extern int usbnet_nway_reset(struct net_device *net); | ||
174 | 179 | ||
175 | /* messaging support includes the interface name, so it must not be | 180 | /* messaging support includes the interface name, so it must not be |
176 | * used before it has one ... notably, in minidriver bind() calls. | 181 | * used before it has one ... notably, in minidriver bind() calls. |
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index 5076b9d97057..2a8dd4cc943d 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig | |||
@@ -54,10 +54,10 @@ config USB_SERIAL_GENERIC | |||
54 | properly. | 54 | properly. |
55 | 55 | ||
56 | config USB_SERIAL_AIRCABLE | 56 | config USB_SERIAL_AIRCABLE |
57 | tristate "AIRcable USB Bluetooth Dongle Driver (EXPERIMENTAL)" | 57 | tristate "USB AIRcable Bluetooth Dongle Driver (EXPERIMENTAL)" |
58 | depends on USB_SERIAL && EXPERIMENTAL | 58 | depends on USB_SERIAL && EXPERIMENTAL |
59 | help | 59 | help |
60 | Say Y here if you want to use AIRcable USB Bluetoot Dongle. | 60 | Say Y here if you want to use USB AIRcable Bluetooth Dongle. |
61 | 61 | ||
62 | To compile this driver as a module, choose M here: the module | 62 | To compile this driver as a module, choose M here: the module |
63 | will be called aircable. | 63 | will be called aircable. |
@@ -422,6 +422,16 @@ config USB_SERIAL_MCT_U232 | |||
422 | To compile this driver as a module, choose M here: the | 422 | To compile this driver as a module, choose M here: the |
423 | module will be called mct_u232. | 423 | module will be called mct_u232. |
424 | 424 | ||
425 | config USB_SERIAL_MOS7720 | ||
426 | tristate "USB Moschip 7720 Single Port Serial Driver" | ||
427 | depends on USB_SERIAL | ||
428 | ---help--- | ||
429 | Say Y here if you want to use a USB Serial single port adapter from | ||
430 | Moschip Semiconductor Tech. | ||
431 | |||
432 | To compile this driver as a module, choose M here: the | ||
433 | module will be called mos7720. | ||
434 | |||
425 | config USB_SERIAL_MOS7840 | 435 | config USB_SERIAL_MOS7840 |
426 | tristate "USB Moschip 7840/7820 USB Serial Driver" | 436 | tristate "USB Moschip 7840/7820 USB Serial Driver" |
427 | depends on USB_SERIAL | 437 | depends on USB_SERIAL |
@@ -527,8 +537,7 @@ config USB_SERIAL_OPTION | |||
527 | The USB bus on these cards is not accessible externally. | 537 | The USB bus on these cards is not accessible externally. |
528 | 538 | ||
529 | Supported devices include (some of?) those made by: | 539 | Supported devices include (some of?) those made by: |
530 | Option, Huawei, Audiovox, Sierra Wireless, Novatel Wireless, or | 540 | Option, Huawei, Audiovox, Novatel Wireless, or Anydata. |
531 | Anydata. | ||
532 | 541 | ||
533 | To compile this driver as a module, choose M here: the | 542 | To compile this driver as a module, choose M here: the |
534 | module will be called option. | 543 | module will be called option. |
diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile index 8dce83340e31..a5047dc599bb 100644 --- a/drivers/usb/serial/Makefile +++ b/drivers/usb/serial/Makefile | |||
@@ -34,6 +34,7 @@ obj-$(CONFIG_USB_SERIAL_KEYSPAN_PDA) += keyspan_pda.o | |||
34 | obj-$(CONFIG_USB_SERIAL_KLSI) += kl5kusb105.o | 34 | obj-$(CONFIG_USB_SERIAL_KLSI) += kl5kusb105.o |
35 | obj-$(CONFIG_USB_SERIAL_KOBIL_SCT) += kobil_sct.o | 35 | obj-$(CONFIG_USB_SERIAL_KOBIL_SCT) += kobil_sct.o |
36 | obj-$(CONFIG_USB_SERIAL_MCT_U232) += mct_u232.o | 36 | obj-$(CONFIG_USB_SERIAL_MCT_U232) += mct_u232.o |
37 | obj-$(CONFIG_USB_SERIAL_MOS7720) += mos7720.o | ||
37 | obj-$(CONFIG_USB_SERIAL_MOS7840) += mos7840.o | 38 | obj-$(CONFIG_USB_SERIAL_MOS7840) += mos7840.o |
38 | obj-$(CONFIG_USB_SERIAL_NAVMAN) += navman.o | 39 | obj-$(CONFIG_USB_SERIAL_NAVMAN) += navman.o |
39 | obj-$(CONFIG_USB_SERIAL_OMNINET) += omninet.o | 40 | obj-$(CONFIG_USB_SERIAL_OMNINET) += omninet.o |
diff --git a/drivers/usb/serial/airprime.c b/drivers/usb/serial/airprime.c index 2c19f19b255c..7f5d546da39a 100644 --- a/drivers/usb/serial/airprime.c +++ b/drivers/usb/serial/airprime.c | |||
@@ -18,12 +18,8 @@ | |||
18 | 18 | ||
19 | static struct usb_device_id id_table [] = { | 19 | static struct usb_device_id id_table [] = { |
20 | { USB_DEVICE(0x0c88, 0x17da) }, /* Kyocera Wireless KPC650/Passport */ | 20 | { USB_DEVICE(0x0c88, 0x17da) }, /* Kyocera Wireless KPC650/Passport */ |
21 | { USB_DEVICE(0x0f3d, 0x0112) }, /* AirPrime CDMA Wireless PC Card */ | ||
22 | { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ | ||
23 | { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */ | ||
24 | { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless Aircard 580 */ | ||
25 | { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ | ||
26 | { USB_DEVICE(0x1410, 0x1110) }, /* Novatel Wireless Merlin CDMA */ | 21 | { USB_DEVICE(0x1410, 0x1110) }, /* Novatel Wireless Merlin CDMA */ |
22 | { USB_DEVICE(0x1410, 0x1100) }, /* ExpressCard34 Qualcomm 3G CDMA */ | ||
27 | { }, | 23 | { }, |
28 | }; | 24 | }; |
29 | MODULE_DEVICE_TABLE(usb, id_table); | 25 | MODULE_DEVICE_TABLE(usb, id_table); |
@@ -133,6 +129,7 @@ static int airprime_open(struct usb_serial_port *port, struct file *filp) | |||
133 | } | 129 | } |
134 | urb = usb_alloc_urb(0, GFP_KERNEL); | 130 | urb = usb_alloc_urb(0, GFP_KERNEL); |
135 | if (!urb) { | 131 | if (!urb) { |
132 | kfree(buffer); | ||
136 | dev_err(&port->dev, "%s - no more urbs?\n", | 133 | dev_err(&port->dev, "%s - no more urbs?\n", |
137 | __FUNCTION__); | 134 | __FUNCTION__); |
138 | result = -ENOMEM; | 135 | result = -ENOMEM; |
diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c index 486c7411b9a7..f95d42c0d16a 100644 --- a/drivers/usb/serial/cp2101.c +++ b/drivers/usb/serial/cp2101.c | |||
@@ -64,7 +64,11 @@ static struct usb_device_id id_table [] = { | |||
64 | { USB_DEVICE(0x10C4, 0x80F6) }, /* Suunto sports instrument */ | 64 | { USB_DEVICE(0x10C4, 0x80F6) }, /* Suunto sports instrument */ |
65 | { USB_DEVICE(0x10C4, 0x813D) }, /* Burnside Telecom Deskmobile */ | 65 | { USB_DEVICE(0x10C4, 0x813D) }, /* Burnside Telecom Deskmobile */ |
66 | { USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */ | 66 | { USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */ |
67 | { USB_DEVICE(0x10C4, 0x81C8) }, /* Lipowsky Industrie Elektronik GmbH, Baby-JTAG */ | ||
68 | { USB_DEVICE(0x10C4, 0x81E2) }, /* Lipowsky Industrie Elektronik GmbH, Baby-LIN */ | ||
69 | { USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */ | ||
67 | { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ | 70 | { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ |
71 | { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ | ||
68 | { USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */ | 72 | { USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */ |
69 | { } /* Terminating Entry */ | 73 | { } /* Terminating Entry */ |
70 | }; | 74 | }; |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index d3dc1a15ec6c..c186b4e73c72 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -1,16 +1,16 @@ | |||
1 | /* | 1 | /* |
2 | * USB FTDI SIO driver | 2 | * USB FTDI SIO driver |
3 | * | 3 | * |
4 | * Copyright (C) 1999 - 2001 | 4 | * Copyright (C) 1999 - 2001 |
5 | * Greg Kroah-Hartman (greg@kroah.com) | 5 | * Greg Kroah-Hartman (greg@kroah.com) |
6 | * Bill Ryder (bryder@sgi.com) | 6 | * Bill Ryder (bryder@sgi.com) |
7 | * Copyright (C) 2002 | 7 | * Copyright (C) 2002 |
8 | * Kuba Ober (kuba@mareimbrium.org) | 8 | * Kuba Ober (kuba@mareimbrium.org) |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License as published by | 11 | * it under the terms of the GNU General Public License as published by |
12 | * the Free Software Foundation; either version 2 of the License, or | 12 | * the Free Software Foundation; either version 2 of the License, or |
13 | * (at your option) any later version. | 13 | * (at your option) any later version. |
14 | * | 14 | * |
15 | * See Documentation/usb/usb-serial.txt for more information on using this driver | 15 | * See Documentation/usb/usb-serial.txt for more information on using this driver |
16 | * | 16 | * |
@@ -32,7 +32,7 @@ | |||
32 | * Changed full name of USB-UIRT device to avoid "/" character. | 32 | * Changed full name of USB-UIRT device to avoid "/" character. |
33 | * Added FTDI's alternate PID (0x6006) for FT232/245 devices. | 33 | * Added FTDI's alternate PID (0x6006) for FT232/245 devices. |
34 | * Added PID for "ELV USB Module UO100" from Stefan Frings. | 34 | * Added PID for "ELV USB Module UO100" from Stefan Frings. |
35 | * | 35 | * |
36 | * (21/Oct/2003) Ian Abbott | 36 | * (21/Oct/2003) Ian Abbott |
37 | * Renamed some VID/PID macros for Matrix Orbital and Perle Systems | 37 | * Renamed some VID/PID macros for Matrix Orbital and Perle Systems |
38 | * devices. Removed Matrix Orbital and Perle Systems devices from the | 38 | * devices. Removed Matrix Orbital and Perle Systems devices from the |
@@ -69,7 +69,7 @@ | |||
69 | * does not incure any measurable overhead. This also relies on the fact | 69 | * does not incure any measurable overhead. This also relies on the fact |
70 | * that we have proper reference counting logic for urbs. I nicked this | 70 | * that we have proper reference counting logic for urbs. I nicked this |
71 | * from Greg KH's Visor driver. | 71 | * from Greg KH's Visor driver. |
72 | * | 72 | * |
73 | * (23/Jun/2003) Ian Abbott | 73 | * (23/Jun/2003) Ian Abbott |
74 | * Reduced flip buffer pushes and corrected a data length test in | 74 | * Reduced flip buffer pushes and corrected a data length test in |
75 | * ftdi_read_bulk_callback. | 75 | * ftdi_read_bulk_callback. |
@@ -77,7 +77,7 @@ | |||
77 | * | 77 | * |
78 | * (21/Jun/2003) Erik Nygren | 78 | * (21/Jun/2003) Erik Nygren |
79 | * Added support for Home Electronics Tira-1 IR transceiver using FT232BM chip. | 79 | * Added support for Home Electronics Tira-1 IR transceiver using FT232BM chip. |
80 | * See <http://www.home-electro.com/tira1.htm>. Only operates properly | 80 | * See <http://www.home-electro.com/tira1.htm>. Only operates properly |
81 | * at 100000 and RTS-CTS, so set custom divisor mode on startup. | 81 | * at 100000 and RTS-CTS, so set custom divisor mode on startup. |
82 | * Also force the Tira-1 and USB-UIRT to only use their custom baud rates. | 82 | * Also force the Tira-1 and USB-UIRT to only use their custom baud rates. |
83 | * | 83 | * |
@@ -137,17 +137,17 @@ | |||
137 | * (17/Feb/2003) Bill Ryder | 137 | * (17/Feb/2003) Bill Ryder |
138 | * Added write urb buffer pool on a per device basis | 138 | * Added write urb buffer pool on a per device basis |
139 | * Added more checking for open file on callbacks (fixed OOPS) | 139 | * Added more checking for open file on callbacks (fixed OOPS) |
140 | * Added CrystalFontz 632 and 634 PIDs | 140 | * Added CrystalFontz 632 and 634 PIDs |
141 | * (thanx to CrystalFontz for the sample devices - they flushed out | 141 | * (thanx to CrystalFontz for the sample devices - they flushed out |
142 | * some driver bugs) | 142 | * some driver bugs) |
143 | * Minor debugging message changes | 143 | * Minor debugging message changes |
144 | * Added throttle, unthrottle and chars_in_buffer functions | 144 | * Added throttle, unthrottle and chars_in_buffer functions |
145 | * Fixed FTDI_SIO (the original device) bug | 145 | * Fixed FTDI_SIO (the original device) bug |
146 | * Fixed some shutdown handling | 146 | * Fixed some shutdown handling |
147 | * | 147 | * |
148 | * | 148 | * |
149 | * | 149 | * |
150 | * | 150 | * |
151 | * (07/Jun/2002) Kuba Ober | 151 | * (07/Jun/2002) Kuba Ober |
152 | * Changed FTDI_SIO_BASE_BAUD_TO_DIVISOR macro into ftdi_baud_to_divisor | 152 | * Changed FTDI_SIO_BASE_BAUD_TO_DIVISOR macro into ftdi_baud_to_divisor |
153 | * function. It was getting too complex. | 153 | * function. It was getting too complex. |
@@ -158,7 +158,7 @@ | |||
158 | * | 158 | * |
159 | * (25/Jul/2002) Bill Ryder inserted Dmitri's TIOCMIWAIT patch | 159 | * (25/Jul/2002) Bill Ryder inserted Dmitri's TIOCMIWAIT patch |
160 | * Not tested by me but it doesn't break anything I use. | 160 | * Not tested by me but it doesn't break anything I use. |
161 | * | 161 | * |
162 | * (04/Jan/2002) Kuba Ober | 162 | * (04/Jan/2002) Kuba Ober |
163 | * Implemented 38400 baudrate kludge, where it can be substituted with other | 163 | * Implemented 38400 baudrate kludge, where it can be substituted with other |
164 | * values. That's the only way to set custom baudrates. | 164 | * values. That's the only way to set custom baudrates. |
@@ -179,7 +179,7 @@ | |||
179 | * (the previous version caused panics) | 179 | * (the previous version caused panics) |
180 | * Removed port iteration code since the device only has one I/O port and it | 180 | * Removed port iteration code since the device only has one I/O port and it |
181 | * was wrong anyway. | 181 | * was wrong anyway. |
182 | * | 182 | * |
183 | * (31/May/2001) gkh | 183 | * (31/May/2001) gkh |
184 | * Switched from using spinlock to a semaphore, which fixes lots of problems. | 184 | * Switched from using spinlock to a semaphore, which fixes lots of problems. |
185 | * | 185 | * |
@@ -188,16 +188,16 @@ | |||
188 | * Cleaned up comments for 8U232 | 188 | * Cleaned up comments for 8U232 |
189 | * Added parity, framing and overrun error handling | 189 | * Added parity, framing and overrun error handling |
190 | * Added receive break handling. | 190 | * Added receive break handling. |
191 | * | 191 | * |
192 | * (04/08/2001) gb | 192 | * (04/08/2001) gb |
193 | * Identify version on module load. | 193 | * Identify version on module load. |
194 | * | 194 | * |
195 | * (18/March/2001) Bill Ryder | 195 | * (18/March/2001) Bill Ryder |
196 | * (Not released) | 196 | * (Not released) |
197 | * Added send break handling. (requires kernel patch too) | 197 | * Added send break handling. (requires kernel patch too) |
198 | * Fixed 8U232AM hardware RTS/CTS etc status reporting. | 198 | * Fixed 8U232AM hardware RTS/CTS etc status reporting. |
199 | * Added flipbuf fix copied from generic device | 199 | * Added flipbuf fix copied from generic device |
200 | * | 200 | * |
201 | * (12/3/2000) Bill Ryder | 201 | * (12/3/2000) Bill Ryder |
202 | * Added support for 8U232AM device. | 202 | * Added support for 8U232AM device. |
203 | * Moved PID and VIDs into header file only. | 203 | * Moved PID and VIDs into header file only. |
@@ -211,14 +211,14 @@ | |||
211 | * Cleaned up comments. Removed multiple PID/VID definitions. | 211 | * Cleaned up comments. Removed multiple PID/VID definitions. |
212 | * Factorised cts/dtr code | 212 | * Factorised cts/dtr code |
213 | * Made use of __FUNCTION__ in dbg's | 213 | * Made use of __FUNCTION__ in dbg's |
214 | * | 214 | * |
215 | * (11/01/2000) Adam J. Richter | 215 | * (11/01/2000) Adam J. Richter |
216 | * usb_device_id table support | 216 | * usb_device_id table support |
217 | * | 217 | * |
218 | * (10/05/2000) gkh | 218 | * (10/05/2000) gkh |
219 | * Fixed bug with urb->dev not being set properly, now that the usb | 219 | * Fixed bug with urb->dev not being set properly, now that the usb |
220 | * core needs it. | 220 | * core needs it. |
221 | * | 221 | * |
222 | * (09/11/2000) gkh | 222 | * (09/11/2000) gkh |
223 | * Removed DEBUG #ifdefs with call to usb_serial_debug_data | 223 | * Removed DEBUG #ifdefs with call to usb_serial_debug_data |
224 | * | 224 | * |
@@ -226,11 +226,11 @@ | |||
226 | * Added module_init and module_exit functions to handle the fact that this | 226 | * Added module_init and module_exit functions to handle the fact that this |
227 | * driver is a loadable module now. | 227 | * driver is a loadable module now. |
228 | * | 228 | * |
229 | * (04/04/2000) Bill Ryder | 229 | * (04/04/2000) Bill Ryder |
230 | * Fixed bugs in TCGET/TCSET ioctls (by removing them - they are | 230 | * Fixed bugs in TCGET/TCSET ioctls (by removing them - they are |
231 | * handled elsewhere in the tty io driver chain). | 231 | * handled elsewhere in the tty io driver chain). |
232 | * | 232 | * |
233 | * (03/30/2000) Bill Ryder | 233 | * (03/30/2000) Bill Ryder |
234 | * Implemented lots of ioctls | 234 | * Implemented lots of ioctls |
235 | * Fixed a race condition in write | 235 | * Fixed a race condition in write |
236 | * Changed some dbg's to errs | 236 | * Changed some dbg's to errs |
@@ -311,6 +311,7 @@ static struct usb_device_id id_table_combined [] = { | |||
311 | { USB_DEVICE(FTDI_VID, FTDI_ACTZWAVE_PID) }, | 311 | { USB_DEVICE(FTDI_VID, FTDI_ACTZWAVE_PID) }, |
312 | { USB_DEVICE(FTDI_VID, FTDI_IRTRANS_PID) }, | 312 | { USB_DEVICE(FTDI_VID, FTDI_IRTRANS_PID) }, |
313 | { USB_DEVICE(FTDI_VID, FTDI_IPLUS_PID) }, | 313 | { USB_DEVICE(FTDI_VID, FTDI_IPLUS_PID) }, |
314 | { USB_DEVICE(FTDI_VID, FTDI_DMX4ALL) }, | ||
314 | { USB_DEVICE(FTDI_VID, FTDI_SIO_PID) }, | 315 | { USB_DEVICE(FTDI_VID, FTDI_SIO_PID) }, |
315 | { USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) }, | 316 | { USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) }, |
316 | { USB_DEVICE(FTDI_VID, FTDI_8U232AM_ALT_PID) }, | 317 | { USB_DEVICE(FTDI_VID, FTDI_8U232AM_ALT_PID) }, |
@@ -444,13 +445,13 @@ static struct usb_device_id id_table_combined [] = { | |||
444 | /* { USB_DEVICE(FTDI_VID, FTDI_ELV_WS300PC_PID) }, */ | 445 | /* { USB_DEVICE(FTDI_VID, FTDI_ELV_WS300PC_PID) }, */ |
445 | /* { USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1300PC_PID) }, */ | 446 | /* { USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1300PC_PID) }, */ |
446 | /* { USB_DEVICE(FTDI_VID, FTDI_ELV_WS500_PID) }, */ | 447 | /* { USB_DEVICE(FTDI_VID, FTDI_ELV_WS500_PID) }, */ |
447 | { USB_DEVICE(FTDI_VID, LINX_SDMUSBQSS_PID) }, | 448 | { USB_DEVICE(FTDI_VID, LINX_SDMUSBQSS_PID) }, |
448 | { USB_DEVICE(FTDI_VID, LINX_MASTERDEVEL2_PID) }, | 449 | { USB_DEVICE(FTDI_VID, LINX_MASTERDEVEL2_PID) }, |
449 | { USB_DEVICE(FTDI_VID, LINX_FUTURE_0_PID) }, | 450 | { USB_DEVICE(FTDI_VID, LINX_FUTURE_0_PID) }, |
450 | { USB_DEVICE(FTDI_VID, LINX_FUTURE_1_PID) }, | 451 | { USB_DEVICE(FTDI_VID, LINX_FUTURE_1_PID) }, |
451 | { USB_DEVICE(FTDI_VID, LINX_FUTURE_2_PID) }, | 452 | { USB_DEVICE(FTDI_VID, LINX_FUTURE_2_PID) }, |
452 | { USB_DEVICE(FTDI_VID, FTDI_CCSICDU20_0_PID) }, | 453 | { USB_DEVICE(FTDI_VID, FTDI_CCSICDU20_0_PID) }, |
453 | { USB_DEVICE(FTDI_VID, FTDI_CCSICDU40_1_PID) }, | 454 | { USB_DEVICE(FTDI_VID, FTDI_CCSICDU40_1_PID) }, |
454 | { USB_DEVICE(FTDI_VID, INSIDE_ACCESSO) }, | 455 | { USB_DEVICE(FTDI_VID, INSIDE_ACCESSO) }, |
455 | { USB_DEVICE(INTREPID_VID, INTREPID_VALUECAN_PID) }, | 456 | { USB_DEVICE(INTREPID_VID, INTREPID_VALUECAN_PID) }, |
456 | { USB_DEVICE(INTREPID_VID, INTREPID_NEOVI_PID) }, | 457 | { USB_DEVICE(INTREPID_VID, INTREPID_NEOVI_PID) }, |
@@ -511,6 +512,7 @@ static struct usb_device_id id_table_combined [] = { | |||
511 | { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13M_PID) }, | 512 | { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13M_PID) }, |
512 | { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13S_PID) }, | 513 | { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13S_PID) }, |
513 | { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13U_PID) }, | 514 | { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13U_PID) }, |
515 | { USB_DEVICE(ELEKTOR_VID, ELEKTOR_FT323R_PID) }, | ||
514 | { }, /* Optional parameter entry */ | 516 | { }, /* Optional parameter entry */ |
515 | { } /* Terminating entry */ | 517 | { } /* Terminating entry */ |
516 | }; | 518 | }; |
@@ -522,7 +524,7 @@ static struct usb_driver ftdi_driver = { | |||
522 | .probe = usb_serial_probe, | 524 | .probe = usb_serial_probe, |
523 | .disconnect = usb_serial_disconnect, | 525 | .disconnect = usb_serial_disconnect, |
524 | .id_table = id_table_combined, | 526 | .id_table = id_table_combined, |
525 | .no_dynamic_id = 1, | 527 | .no_dynamic_id = 1, |
526 | }; | 528 | }; |
527 | 529 | ||
528 | static const char *ftdi_chip_name[] = { | 530 | static const char *ftdi_chip_name[] = { |
@@ -548,13 +550,13 @@ struct ftdi_private { | |||
548 | int custom_divisor; /* custom_divisor kludge, this is for baud_base (different from what goes to the chip!) */ | 550 | int custom_divisor; /* custom_divisor kludge, this is for baud_base (different from what goes to the chip!) */ |
549 | __u16 last_set_data_urb_value ; | 551 | __u16 last_set_data_urb_value ; |
550 | /* the last data state set - needed for doing a break */ | 552 | /* the last data state set - needed for doing a break */ |
551 | int write_offset; /* This is the offset in the usb data block to write the serial data - | 553 | int write_offset; /* This is the offset in the usb data block to write the serial data - |
552 | * it is different between devices | 554 | * it is different between devices |
553 | */ | 555 | */ |
554 | int flags; /* some ASYNC_xxxx flags are supported */ | 556 | int flags; /* some ASYNC_xxxx flags are supported */ |
555 | unsigned long last_dtr_rts; /* saved modem control outputs */ | 557 | unsigned long last_dtr_rts; /* saved modem control outputs */ |
556 | wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */ | 558 | wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */ |
557 | char prev_status, diff_status; /* Used for TIOCMIWAIT */ | 559 | char prev_status, diff_status; /* Used for TIOCMIWAIT */ |
558 | __u8 rx_flags; /* receive state flags (throttling) */ | 560 | __u8 rx_flags; /* receive state flags (throttling) */ |
559 | spinlock_t rx_lock; /* spinlock for receive state */ | 561 | spinlock_t rx_lock; /* spinlock for receive state */ |
560 | struct work_struct rx_work; | 562 | struct work_struct rx_work; |
@@ -721,7 +723,7 @@ static int update_mctrl(struct usb_serial_port *port, unsigned int set, unsigned | |||
721 | urb_value |= FTDI_SIO_SET_RTS_HIGH; | 723 | urb_value |= FTDI_SIO_SET_RTS_HIGH; |
722 | rv = usb_control_msg(port->serial->dev, | 724 | rv = usb_control_msg(port->serial->dev, |
723 | usb_sndctrlpipe(port->serial->dev, 0), | 725 | usb_sndctrlpipe(port->serial->dev, 0), |
724 | FTDI_SIO_SET_MODEM_CTRL_REQUEST, | 726 | FTDI_SIO_SET_MODEM_CTRL_REQUEST, |
725 | FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE, | 727 | FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE, |
726 | urb_value, priv->interface, | 728 | urb_value, priv->interface, |
727 | buf, 0, WDR_TIMEOUT); | 729 | buf, 0, WDR_TIMEOUT); |
@@ -768,7 +770,7 @@ static int change_speed(struct usb_serial_port *port) | |||
768 | if (priv->interface) { /* FT2232C */ | 770 | if (priv->interface) { /* FT2232C */ |
769 | urb_index = (__u16)((urb_index << 8) | priv->interface); | 771 | urb_index = (__u16)((urb_index << 8) | priv->interface); |
770 | } | 772 | } |
771 | 773 | ||
772 | rv = usb_control_msg(port->serial->dev, | 774 | rv = usb_control_msg(port->serial->dev, |
773 | usb_sndctrlpipe(port->serial->dev, 0), | 775 | usb_sndctrlpipe(port->serial->dev, 0), |
774 | FTDI_SIO_SET_BAUDRATE_REQUEST, | 776 | FTDI_SIO_SET_BAUDRATE_REQUEST, |
@@ -827,7 +829,7 @@ static __u32 get_ftdi_divisor(struct usb_serial_port * port) | |||
827 | 829 | ||
828 | /* 3. Convert baudrate to device-specific divisor */ | 830 | /* 3. Convert baudrate to device-specific divisor */ |
829 | 831 | ||
830 | if (!baud) baud = 9600; | 832 | if (!baud) baud = 9600; |
831 | switch(priv->chip_type) { | 833 | switch(priv->chip_type) { |
832 | case SIO: /* SIO chip */ | 834 | case SIO: /* SIO chip */ |
833 | switch(baud) { | 835 | switch(baud) { |
@@ -843,7 +845,7 @@ static __u32 get_ftdi_divisor(struct usb_serial_port * port) | |||
843 | case 115200: div_value = ftdi_sio_b115200; break; | 845 | case 115200: div_value = ftdi_sio_b115200; break; |
844 | } /* baud */ | 846 | } /* baud */ |
845 | if (div_value == 0) { | 847 | if (div_value == 0) { |
846 | dbg("%s - Baudrate (%d) requested is not supported", __FUNCTION__, baud); | 848 | dbg("%s - Baudrate (%d) requested is not supported", __FUNCTION__, baud); |
847 | div_value = ftdi_sio_b9600; | 849 | div_value = ftdi_sio_b9600; |
848 | div_okay = 0; | 850 | div_okay = 0; |
849 | } | 851 | } |
@@ -925,7 +927,7 @@ static int set_serial_info(struct usb_serial_port * port, struct serial_struct _ | |||
925 | /* Make the changes - these are privileged changes! */ | 927 | /* Make the changes - these are privileged changes! */ |
926 | 928 | ||
927 | priv->flags = ((priv->flags & ~ASYNC_FLAGS) | | 929 | priv->flags = ((priv->flags & ~ASYNC_FLAGS) | |
928 | (new_serial.flags & ASYNC_FLAGS)); | 930 | (new_serial.flags & ASYNC_FLAGS)); |
929 | priv->custom_divisor = new_serial.custom_divisor; | 931 | priv->custom_divisor = new_serial.custom_divisor; |
930 | 932 | ||
931 | port->tty->low_latency = (priv->flags & ASYNC_LOW_LATENCY) ? 1 : 0; | 933 | port->tty->low_latency = (priv->flags & ASYNC_LOW_LATENCY) ? 1 : 0; |
@@ -950,7 +952,7 @@ check_and_exit: | |||
950 | (old_priv.custom_divisor != priv->custom_divisor))) { | 952 | (old_priv.custom_divisor != priv->custom_divisor))) { |
951 | change_speed(port); | 953 | change_speed(port); |
952 | } | 954 | } |
953 | 955 | ||
954 | return (0); | 956 | return (0); |
955 | 957 | ||
956 | } /* set_serial_info */ | 958 | } /* set_serial_info */ |
@@ -1022,18 +1024,18 @@ static ssize_t show_latency_timer(struct device *dev, struct device_attribute *a | |||
1022 | struct usb_device *udev; | 1024 | struct usb_device *udev; |
1023 | unsigned short latency = 0; | 1025 | unsigned short latency = 0; |
1024 | int rv = 0; | 1026 | int rv = 0; |
1025 | 1027 | ||
1026 | udev = to_usb_device(dev); | 1028 | udev = to_usb_device(dev); |
1027 | 1029 | ||
1028 | dbg("%s",__FUNCTION__); | 1030 | dbg("%s",__FUNCTION__); |
1029 | 1031 | ||
1030 | rv = usb_control_msg(udev, | 1032 | rv = usb_control_msg(udev, |
1031 | usb_rcvctrlpipe(udev, 0), | 1033 | usb_rcvctrlpipe(udev, 0), |
1032 | FTDI_SIO_GET_LATENCY_TIMER_REQUEST, | 1034 | FTDI_SIO_GET_LATENCY_TIMER_REQUEST, |
1033 | FTDI_SIO_GET_LATENCY_TIMER_REQUEST_TYPE, | 1035 | FTDI_SIO_GET_LATENCY_TIMER_REQUEST_TYPE, |
1034 | 0, priv->interface, | 1036 | 0, priv->interface, |
1035 | (char*) &latency, 1, WDR_TIMEOUT); | 1037 | (char*) &latency, 1, WDR_TIMEOUT); |
1036 | 1038 | ||
1037 | if (rv < 0) { | 1039 | if (rv < 0) { |
1038 | dev_err(dev, "Unable to read latency timer: %i", rv); | 1040 | dev_err(dev, "Unable to read latency timer: %i", rv); |
1039 | return -EIO; | 1041 | return -EIO; |
@@ -1051,23 +1053,23 @@ static ssize_t store_latency_timer(struct device *dev, struct device_attribute * | |||
1051 | char buf[1]; | 1053 | char buf[1]; |
1052 | int v = simple_strtoul(valbuf, NULL, 10); | 1054 | int v = simple_strtoul(valbuf, NULL, 10); |
1053 | int rv = 0; | 1055 | int rv = 0; |
1054 | 1056 | ||
1055 | udev = to_usb_device(dev); | 1057 | udev = to_usb_device(dev); |
1056 | 1058 | ||
1057 | dbg("%s: setting latency timer = %i", __FUNCTION__, v); | 1059 | dbg("%s: setting latency timer = %i", __FUNCTION__, v); |
1058 | 1060 | ||
1059 | rv = usb_control_msg(udev, | 1061 | rv = usb_control_msg(udev, |
1060 | usb_sndctrlpipe(udev, 0), | 1062 | usb_sndctrlpipe(udev, 0), |
1061 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST, | 1063 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST, |
1062 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE, | 1064 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE, |
1063 | v, priv->interface, | 1065 | v, priv->interface, |
1064 | buf, 0, WDR_TIMEOUT); | 1066 | buf, 0, WDR_TIMEOUT); |
1065 | 1067 | ||
1066 | if (rv < 0) { | 1068 | if (rv < 0) { |
1067 | dev_err(dev, "Unable to write latency timer: %i", rv); | 1069 | dev_err(dev, "Unable to write latency timer: %i", rv); |
1068 | return -EIO; | 1070 | return -EIO; |
1069 | } | 1071 | } |
1070 | 1072 | ||
1071 | return count; | 1073 | return count; |
1072 | } | 1074 | } |
1073 | 1075 | ||
@@ -1082,23 +1084,23 @@ static ssize_t store_event_char(struct device *dev, struct device_attribute *att | |||
1082 | char buf[1]; | 1084 | char buf[1]; |
1083 | int v = simple_strtoul(valbuf, NULL, 10); | 1085 | int v = simple_strtoul(valbuf, NULL, 10); |
1084 | int rv = 0; | 1086 | int rv = 0; |
1085 | 1087 | ||
1086 | udev = to_usb_device(dev); | 1088 | udev = to_usb_device(dev); |
1087 | 1089 | ||
1088 | dbg("%s: setting event char = %i", __FUNCTION__, v); | 1090 | dbg("%s: setting event char = %i", __FUNCTION__, v); |
1089 | 1091 | ||
1090 | rv = usb_control_msg(udev, | 1092 | rv = usb_control_msg(udev, |
1091 | usb_sndctrlpipe(udev, 0), | 1093 | usb_sndctrlpipe(udev, 0), |
1092 | FTDI_SIO_SET_EVENT_CHAR_REQUEST, | 1094 | FTDI_SIO_SET_EVENT_CHAR_REQUEST, |
1093 | FTDI_SIO_SET_EVENT_CHAR_REQUEST_TYPE, | 1095 | FTDI_SIO_SET_EVENT_CHAR_REQUEST_TYPE, |
1094 | v, priv->interface, | 1096 | v, priv->interface, |
1095 | buf, 0, WDR_TIMEOUT); | 1097 | buf, 0, WDR_TIMEOUT); |
1096 | 1098 | ||
1097 | if (rv < 0) { | 1099 | if (rv < 0) { |
1098 | dbg("Unable to write event character: %i", rv); | 1100 | dbg("Unable to write event character: %i", rv); |
1099 | return -EIO; | 1101 | return -EIO; |
1100 | } | 1102 | } |
1101 | 1103 | ||
1102 | return count; | 1104 | return count; |
1103 | } | 1105 | } |
1104 | 1106 | ||
@@ -1135,11 +1137,11 @@ static void remove_sysfs_attrs(struct usb_serial *serial) | |||
1135 | struct ftdi_private *priv; | 1137 | struct ftdi_private *priv; |
1136 | struct usb_device *udev; | 1138 | struct usb_device *udev; |
1137 | 1139 | ||
1138 | dbg("%s",__FUNCTION__); | 1140 | dbg("%s",__FUNCTION__); |
1139 | 1141 | ||
1140 | priv = usb_get_serial_port_data(serial->port[0]); | 1142 | priv = usb_get_serial_port_data(serial->port[0]); |
1141 | udev = serial->dev; | 1143 | udev = serial->dev; |
1142 | 1144 | ||
1143 | /* XXX see create_sysfs_attrs */ | 1145 | /* XXX see create_sysfs_attrs */ |
1144 | if (priv->chip_type != SIO) { | 1146 | if (priv->chip_type != SIO) { |
1145 | device_remove_file(&udev->dev, &dev_attr_event_char); | 1147 | device_remove_file(&udev->dev, &dev_attr_event_char); |
@@ -1147,7 +1149,7 @@ static void remove_sysfs_attrs(struct usb_serial *serial) | |||
1147 | device_remove_file(&udev->dev, &dev_attr_latency_timer); | 1149 | device_remove_file(&udev->dev, &dev_attr_latency_timer); |
1148 | } | 1150 | } |
1149 | } | 1151 | } |
1150 | 1152 | ||
1151 | } | 1153 | } |
1152 | 1154 | ||
1153 | /* | 1155 | /* |
@@ -1258,7 +1260,7 @@ static void ftdi_HE_TIRA1_setup (struct usb_serial *serial) | |||
1258 | } /* ftdi_HE_TIRA1_setup */ | 1260 | } /* ftdi_HE_TIRA1_setup */ |
1259 | 1261 | ||
1260 | 1262 | ||
1261 | /* ftdi_shutdown is called from usbserial:usb_serial_disconnect | 1263 | /* ftdi_shutdown is called from usbserial:usb_serial_disconnect |
1262 | * it is called when the usb device is disconnected | 1264 | * it is called when the usb device is disconnected |
1263 | * | 1265 | * |
1264 | * usbserial:usb_serial_disconnect | 1266 | * usbserial:usb_serial_disconnect |
@@ -1269,16 +1271,16 @@ static void ftdi_HE_TIRA1_setup (struct usb_serial *serial) | |||
1269 | 1271 | ||
1270 | static void ftdi_shutdown (struct usb_serial *serial) | 1272 | static void ftdi_shutdown (struct usb_serial *serial) |
1271 | { /* ftdi_shutdown */ | 1273 | { /* ftdi_shutdown */ |
1272 | 1274 | ||
1273 | struct usb_serial_port *port = serial->port[0]; | 1275 | struct usb_serial_port *port = serial->port[0]; |
1274 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1276 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
1275 | 1277 | ||
1276 | dbg("%s", __FUNCTION__); | 1278 | dbg("%s", __FUNCTION__); |
1277 | 1279 | ||
1278 | remove_sysfs_attrs(serial); | 1280 | remove_sysfs_attrs(serial); |
1279 | 1281 | ||
1280 | /* all open ports are closed at this point | 1282 | /* all open ports are closed at this point |
1281 | * (by usbserial.c:__serial_close, which calls ftdi_close) | 1283 | * (by usbserial.c:__serial_close, which calls ftdi_close) |
1282 | */ | 1284 | */ |
1283 | 1285 | ||
1284 | if (priv) { | 1286 | if (priv) { |
@@ -1293,7 +1295,7 @@ static int ftdi_open (struct usb_serial_port *port, struct file *filp) | |||
1293 | struct usb_device *dev = port->serial->dev; | 1295 | struct usb_device *dev = port->serial->dev; |
1294 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1296 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
1295 | unsigned long flags; | 1297 | unsigned long flags; |
1296 | 1298 | ||
1297 | int result = 0; | 1299 | int result = 0; |
1298 | char buf[1]; /* Needed for the usb_control_msg I think */ | 1300 | char buf[1]; /* Needed for the usb_control_msg I think */ |
1299 | 1301 | ||
@@ -1312,8 +1314,8 @@ static int ftdi_open (struct usb_serial_port *port, struct file *filp) | |||
1312 | /* No error checking for this (will get errors later anyway) */ | 1314 | /* No error checking for this (will get errors later anyway) */ |
1313 | /* See ftdi_sio.h for description of what is reset */ | 1315 | /* See ftdi_sio.h for description of what is reset */ |
1314 | usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | 1316 | usb_control_msg(dev, usb_sndctrlpipe(dev, 0), |
1315 | FTDI_SIO_RESET_REQUEST, FTDI_SIO_RESET_REQUEST_TYPE, | 1317 | FTDI_SIO_RESET_REQUEST, FTDI_SIO_RESET_REQUEST_TYPE, |
1316 | FTDI_SIO_RESET_SIO, | 1318 | FTDI_SIO_RESET_SIO, |
1317 | priv->interface, buf, 0, WDR_TIMEOUT); | 1319 | priv->interface, buf, 0, WDR_TIMEOUT); |
1318 | 1320 | ||
1319 | /* Termios defaults are set by usb_serial_init. We don't change | 1321 | /* Termios defaults are set by usb_serial_init. We don't change |
@@ -1350,12 +1352,12 @@ static int ftdi_open (struct usb_serial_port *port, struct file *filp) | |||
1350 | 1352 | ||
1351 | 1353 | ||
1352 | 1354 | ||
1353 | /* | 1355 | /* |
1354 | * usbserial:__serial_close only calls ftdi_close if the point is open | 1356 | * usbserial:__serial_close only calls ftdi_close if the point is open |
1355 | * | 1357 | * |
1356 | * This only gets called when it is the last close | 1358 | * This only gets called when it is the last close |
1357 | * | 1359 | * |
1358 | * | 1360 | * |
1359 | */ | 1361 | */ |
1360 | 1362 | ||
1361 | static void ftdi_close (struct usb_serial_port *port, struct file *filp) | 1363 | static void ftdi_close (struct usb_serial_port *port, struct file *filp) |
@@ -1368,14 +1370,14 @@ static void ftdi_close (struct usb_serial_port *port, struct file *filp) | |||
1368 | 1370 | ||
1369 | if (c_cflag & HUPCL){ | 1371 | if (c_cflag & HUPCL){ |
1370 | /* Disable flow control */ | 1372 | /* Disable flow control */ |
1371 | if (usb_control_msg(port->serial->dev, | 1373 | if (usb_control_msg(port->serial->dev, |
1372 | usb_sndctrlpipe(port->serial->dev, 0), | 1374 | usb_sndctrlpipe(port->serial->dev, 0), |
1373 | FTDI_SIO_SET_FLOW_CTRL_REQUEST, | 1375 | FTDI_SIO_SET_FLOW_CTRL_REQUEST, |
1374 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, | 1376 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, |
1375 | 0, priv->interface, buf, 0, | 1377 | 0, priv->interface, buf, 0, |
1376 | WDR_TIMEOUT) < 0) { | 1378 | WDR_TIMEOUT) < 0) { |
1377 | err("error from flowcontrol urb"); | 1379 | err("error from flowcontrol urb"); |
1378 | } | 1380 | } |
1379 | 1381 | ||
1380 | /* drop RTS and DTR */ | 1382 | /* drop RTS and DTR */ |
1381 | clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); | 1383 | clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); |
@@ -1384,14 +1386,14 @@ static void ftdi_close (struct usb_serial_port *port, struct file *filp) | |||
1384 | /* cancel any scheduled reading */ | 1386 | /* cancel any scheduled reading */ |
1385 | cancel_delayed_work(&priv->rx_work); | 1387 | cancel_delayed_work(&priv->rx_work); |
1386 | flush_scheduled_work(); | 1388 | flush_scheduled_work(); |
1387 | 1389 | ||
1388 | /* shutdown our bulk read */ | 1390 | /* shutdown our bulk read */ |
1389 | if (port->read_urb) | 1391 | if (port->read_urb) |
1390 | usb_kill_urb(port->read_urb); | 1392 | usb_kill_urb(port->read_urb); |
1391 | } /* ftdi_close */ | 1393 | } /* ftdi_close */ |
1392 | 1394 | ||
1393 | 1395 | ||
1394 | 1396 | ||
1395 | /* The SIO requires the first byte to have: | 1397 | /* The SIO requires the first byte to have: |
1396 | * B0 1 | 1398 | * B0 1 |
1397 | * B1 0 | 1399 | * B1 0 |
@@ -1423,7 +1425,7 @@ static int ftdi_write (struct usb_serial_port *port, | |||
1423 | return 0; | 1425 | return 0; |
1424 | } | 1426 | } |
1425 | spin_unlock_irqrestore(&priv->tx_lock, flags); | 1427 | spin_unlock_irqrestore(&priv->tx_lock, flags); |
1426 | 1428 | ||
1427 | data_offset = priv->write_offset; | 1429 | data_offset = priv->write_offset; |
1428 | dbg("data_offset set to %d",data_offset); | 1430 | dbg("data_offset set to %d",data_offset); |
1429 | 1431 | ||
@@ -1462,7 +1464,7 @@ static int ftdi_write (struct usb_serial_port *port, | |||
1462 | user_pktsz = todo; | 1464 | user_pktsz = todo; |
1463 | } | 1465 | } |
1464 | /* Write the control byte at the front of the packet*/ | 1466 | /* Write the control byte at the front of the packet*/ |
1465 | *first_byte = 1 | ((user_pktsz) << 2); | 1467 | *first_byte = 1 | ((user_pktsz) << 2); |
1466 | /* Copy data for packet */ | 1468 | /* Copy data for packet */ |
1467 | memcpy (first_byte + data_offset, | 1469 | memcpy (first_byte + data_offset, |
1468 | current_position, user_pktsz); | 1470 | current_position, user_pktsz); |
@@ -1479,7 +1481,7 @@ static int ftdi_write (struct usb_serial_port *port, | |||
1479 | usb_serial_debug_data(debug, &port->dev, __FUNCTION__, transfer_size, buffer); | 1481 | usb_serial_debug_data(debug, &port->dev, __FUNCTION__, transfer_size, buffer); |
1480 | 1482 | ||
1481 | /* fill the buffer and send it */ | 1483 | /* fill the buffer and send it */ |
1482 | usb_fill_bulk_urb(urb, port->serial->dev, | 1484 | usb_fill_bulk_urb(urb, port->serial->dev, |
1483 | usb_sndbulkpipe(port->serial->dev, port->bulk_out_endpointAddress), | 1485 | usb_sndbulkpipe(port->serial->dev, port->bulk_out_endpointAddress), |
1484 | buffer, transfer_size, | 1486 | buffer, transfer_size, |
1485 | ftdi_write_bulk_callback, port); | 1487 | ftdi_write_bulk_callback, port); |
@@ -1520,7 +1522,7 @@ static void ftdi_write_bulk_callback (struct urb *urb) | |||
1520 | kfree (urb->transfer_buffer); | 1522 | kfree (urb->transfer_buffer); |
1521 | 1523 | ||
1522 | dbg("%s - port %d", __FUNCTION__, port->number); | 1524 | dbg("%s - port %d", __FUNCTION__, port->number); |
1523 | 1525 | ||
1524 | if (urb->status) { | 1526 | if (urb->status) { |
1525 | dbg("nonzero write bulk status received: %d", urb->status); | 1527 | dbg("nonzero write bulk status received: %d", urb->status); |
1526 | return; | 1528 | return; |
@@ -1651,7 +1653,7 @@ static void ftdi_process_read (void *param) | |||
1651 | struct tty_struct *tty; | 1653 | struct tty_struct *tty; |
1652 | struct ftdi_private *priv; | 1654 | struct ftdi_private *priv; |
1653 | char error_flag; | 1655 | char error_flag; |
1654 | unsigned char *data; | 1656 | unsigned char *data; |
1655 | 1657 | ||
1656 | int i; | 1658 | int i; |
1657 | int result; | 1659 | int result; |
@@ -1759,7 +1761,7 @@ static void ftdi_process_read (void *param) | |||
1759 | } | 1761 | } |
1760 | if (length > 0) { | 1762 | if (length > 0) { |
1761 | for (i = 2; i < length+2; i++) { | 1763 | for (i = 2; i < length+2; i++) { |
1762 | /* Note that the error flag is duplicated for | 1764 | /* Note that the error flag is duplicated for |
1763 | every character received since we don't know | 1765 | every character received since we don't know |
1764 | which character it applied to */ | 1766 | which character it applied to */ |
1765 | tty_insert_flip_char(tty, data[packet_offset+i], error_flag); | 1767 | tty_insert_flip_char(tty, data[packet_offset+i], error_flag); |
@@ -1773,7 +1775,7 @@ static void ftdi_process_read (void *param) | |||
1773 | This doesn't work well since the application receives a never | 1775 | This doesn't work well since the application receives a never |
1774 | ending stream of bad data - even though new data hasn't been sent. | 1776 | ending stream of bad data - even though new data hasn't been sent. |
1775 | Therefore I (bill) have taken this out. | 1777 | Therefore I (bill) have taken this out. |
1776 | However - this might make sense for framing errors and so on | 1778 | However - this might make sense for framing errors and so on |
1777 | so I am leaving the code in for now. | 1779 | so I am leaving the code in for now. |
1778 | */ | 1780 | */ |
1779 | else { | 1781 | else { |
@@ -1827,7 +1829,7 @@ static void ftdi_process_read (void *param) | |||
1827 | /* if the port is closed stop trying to read */ | 1829 | /* if the port is closed stop trying to read */ |
1828 | if (port->open_count > 0){ | 1830 | if (port->open_count > 0){ |
1829 | /* Continue trying to always read */ | 1831 | /* Continue trying to always read */ |
1830 | usb_fill_bulk_urb(port->read_urb, port->serial->dev, | 1832 | usb_fill_bulk_urb(port->read_urb, port->serial->dev, |
1831 | usb_rcvbulkpipe(port->serial->dev, port->bulk_in_endpointAddress), | 1833 | usb_rcvbulkpipe(port->serial->dev, port->bulk_in_endpointAddress), |
1832 | port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length, | 1834 | port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length, |
1833 | ftdi_read_bulk_callback, port); | 1835 | ftdi_read_bulk_callback, port); |
@@ -1844,9 +1846,9 @@ static void ftdi_process_read (void *param) | |||
1844 | static void ftdi_break_ctl( struct usb_serial_port *port, int break_state ) | 1846 | static void ftdi_break_ctl( struct usb_serial_port *port, int break_state ) |
1845 | { | 1847 | { |
1846 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1848 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
1847 | __u16 urb_value = 0; | 1849 | __u16 urb_value = 0; |
1848 | char buf[1]; | 1850 | char buf[1]; |
1849 | 1851 | ||
1850 | /* break_state = -1 to turn on break, and 0 to turn off break */ | 1852 | /* break_state = -1 to turn on break, and 0 to turn off break */ |
1851 | /* see drivers/char/tty_io.c to see it used */ | 1853 | /* see drivers/char/tty_io.c to see it used */ |
1852 | /* last_set_data_urb_value NEVER has the break bit set in it */ | 1854 | /* last_set_data_urb_value NEVER has the break bit set in it */ |
@@ -1854,20 +1856,20 @@ static void ftdi_break_ctl( struct usb_serial_port *port, int break_state ) | |||
1854 | if (break_state) { | 1856 | if (break_state) { |
1855 | urb_value = priv->last_set_data_urb_value | FTDI_SIO_SET_BREAK; | 1857 | urb_value = priv->last_set_data_urb_value | FTDI_SIO_SET_BREAK; |
1856 | } else { | 1858 | } else { |
1857 | urb_value = priv->last_set_data_urb_value; | 1859 | urb_value = priv->last_set_data_urb_value; |
1858 | } | 1860 | } |
1859 | 1861 | ||
1860 | 1862 | ||
1861 | if (usb_control_msg(port->serial->dev, usb_sndctrlpipe(port->serial->dev, 0), | 1863 | if (usb_control_msg(port->serial->dev, usb_sndctrlpipe(port->serial->dev, 0), |
1862 | FTDI_SIO_SET_DATA_REQUEST, | 1864 | FTDI_SIO_SET_DATA_REQUEST, |
1863 | FTDI_SIO_SET_DATA_REQUEST_TYPE, | 1865 | FTDI_SIO_SET_DATA_REQUEST_TYPE, |
1864 | urb_value , priv->interface, | 1866 | urb_value , priv->interface, |
1865 | buf, 0, WDR_TIMEOUT) < 0) { | 1867 | buf, 0, WDR_TIMEOUT) < 0) { |
1866 | err("%s FAILED to enable/disable break state (state was %d)", __FUNCTION__,break_state); | 1868 | err("%s FAILED to enable/disable break state (state was %d)", __FUNCTION__,break_state); |
1867 | } | 1869 | } |
1868 | 1870 | ||
1869 | dbg("%s break state is %d - urb is %d", __FUNCTION__,break_state, urb_value); | 1871 | dbg("%s break state is %d - urb is %d", __FUNCTION__,break_state, urb_value); |
1870 | 1872 | ||
1871 | } | 1873 | } |
1872 | 1874 | ||
1873 | 1875 | ||
@@ -1883,12 +1885,12 @@ static void ftdi_set_termios (struct usb_serial_port *port, struct termios *old_ | |||
1883 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1885 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
1884 | __u16 urb_value; /* will hold the new flags */ | 1886 | __u16 urb_value; /* will hold the new flags */ |
1885 | char buf[1]; /* Perhaps I should dynamically alloc this? */ | 1887 | char buf[1]; /* Perhaps I should dynamically alloc this? */ |
1886 | 1888 | ||
1887 | // Added for xon/xoff support | 1889 | // Added for xon/xoff support |
1888 | unsigned int iflag = port->tty->termios->c_iflag; | 1890 | unsigned int iflag = port->tty->termios->c_iflag; |
1889 | unsigned char vstop; | 1891 | unsigned char vstop; |
1890 | unsigned char vstart; | 1892 | unsigned char vstart; |
1891 | 1893 | ||
1892 | dbg("%s", __FUNCTION__); | 1894 | dbg("%s", __FUNCTION__); |
1893 | 1895 | ||
1894 | /* Force baud rate if this device requires it, unless it is set to B0. */ | 1896 | /* Force baud rate if this device requires it, unless it is set to B0. */ |
@@ -1906,20 +1908,20 @@ static void ftdi_set_termios (struct usb_serial_port *port, struct termios *old_ | |||
1906 | 1908 | ||
1907 | cflag = port->tty->termios->c_cflag; | 1909 | cflag = port->tty->termios->c_cflag; |
1908 | 1910 | ||
1909 | /* FIXME -For this cut I don't care if the line is really changing or | 1911 | /* FIXME -For this cut I don't care if the line is really changing or |
1910 | not - so just do the change regardless - should be able to | 1912 | not - so just do the change regardless - should be able to |
1911 | compare old_termios and tty->termios */ | 1913 | compare old_termios and tty->termios */ |
1912 | /* NOTE These routines can get interrupted by | 1914 | /* NOTE These routines can get interrupted by |
1913 | ftdi_sio_read_bulk_callback - need to examine what this | 1915 | ftdi_sio_read_bulk_callback - need to examine what this |
1914 | means - don't see any problems yet */ | 1916 | means - don't see any problems yet */ |
1915 | 1917 | ||
1916 | /* Set number of data bits, parity, stop bits */ | 1918 | /* Set number of data bits, parity, stop bits */ |
1917 | 1919 | ||
1918 | urb_value = 0; | 1920 | urb_value = 0; |
1919 | urb_value |= (cflag & CSTOPB ? FTDI_SIO_SET_DATA_STOP_BITS_2 : | 1921 | urb_value |= (cflag & CSTOPB ? FTDI_SIO_SET_DATA_STOP_BITS_2 : |
1920 | FTDI_SIO_SET_DATA_STOP_BITS_1); | 1922 | FTDI_SIO_SET_DATA_STOP_BITS_1); |
1921 | urb_value |= (cflag & PARENB ? | 1923 | urb_value |= (cflag & PARENB ? |
1922 | (cflag & PARODD ? FTDI_SIO_SET_DATA_PARITY_ODD : | 1924 | (cflag & PARODD ? FTDI_SIO_SET_DATA_PARITY_ODD : |
1923 | FTDI_SIO_SET_DATA_PARITY_EVEN) : | 1925 | FTDI_SIO_SET_DATA_PARITY_EVEN) : |
1924 | FTDI_SIO_SET_DATA_PARITY_NONE); | 1926 | FTDI_SIO_SET_DATA_PARITY_NONE); |
1925 | if (cflag & CSIZE) { | 1927 | if (cflag & CSIZE) { |
@@ -1936,25 +1938,25 @@ static void ftdi_set_termios (struct usb_serial_port *port, struct termios *old_ | |||
1936 | /* This is needed by the break command since it uses the same command - but is | 1938 | /* This is needed by the break command since it uses the same command - but is |
1937 | * or'ed with this value */ | 1939 | * or'ed with this value */ |
1938 | priv->last_set_data_urb_value = urb_value; | 1940 | priv->last_set_data_urb_value = urb_value; |
1939 | 1941 | ||
1940 | if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | 1942 | if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), |
1941 | FTDI_SIO_SET_DATA_REQUEST, | 1943 | FTDI_SIO_SET_DATA_REQUEST, |
1942 | FTDI_SIO_SET_DATA_REQUEST_TYPE, | 1944 | FTDI_SIO_SET_DATA_REQUEST_TYPE, |
1943 | urb_value , priv->interface, | 1945 | urb_value , priv->interface, |
1944 | buf, 0, WDR_SHORT_TIMEOUT) < 0) { | 1946 | buf, 0, WDR_SHORT_TIMEOUT) < 0) { |
1945 | err("%s FAILED to set databits/stopbits/parity", __FUNCTION__); | 1947 | err("%s FAILED to set databits/stopbits/parity", __FUNCTION__); |
1946 | } | 1948 | } |
1947 | 1949 | ||
1948 | /* Now do the baudrate */ | 1950 | /* Now do the baudrate */ |
1949 | if ((cflag & CBAUD) == B0 ) { | 1951 | if ((cflag & CBAUD) == B0 ) { |
1950 | /* Disable flow control */ | 1952 | /* Disable flow control */ |
1951 | if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | 1953 | if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), |
1952 | FTDI_SIO_SET_FLOW_CTRL_REQUEST, | 1954 | FTDI_SIO_SET_FLOW_CTRL_REQUEST, |
1953 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, | 1955 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, |
1954 | 0, priv->interface, | 1956 | 0, priv->interface, |
1955 | buf, 0, WDR_TIMEOUT) < 0) { | 1957 | buf, 0, WDR_TIMEOUT) < 0) { |
1956 | err("%s error from disable flowcontrol urb", __FUNCTION__); | 1958 | err("%s error from disable flowcontrol urb", __FUNCTION__); |
1957 | } | 1959 | } |
1958 | /* Drop RTS and DTR */ | 1960 | /* Drop RTS and DTR */ |
1959 | clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); | 1961 | clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); |
1960 | } else { | 1962 | } else { |
@@ -1972,16 +1974,16 @@ static void ftdi_set_termios (struct usb_serial_port *port, struct termios *old_ | |||
1972 | /* Note device also supports DTR/CD (ugh) and Xon/Xoff in hardware */ | 1974 | /* Note device also supports DTR/CD (ugh) and Xon/Xoff in hardware */ |
1973 | if (cflag & CRTSCTS) { | 1975 | if (cflag & CRTSCTS) { |
1974 | dbg("%s Setting to CRTSCTS flow control", __FUNCTION__); | 1976 | dbg("%s Setting to CRTSCTS flow control", __FUNCTION__); |
1975 | if (usb_control_msg(dev, | 1977 | if (usb_control_msg(dev, |
1976 | usb_sndctrlpipe(dev, 0), | 1978 | usb_sndctrlpipe(dev, 0), |
1977 | FTDI_SIO_SET_FLOW_CTRL_REQUEST, | 1979 | FTDI_SIO_SET_FLOW_CTRL_REQUEST, |
1978 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, | 1980 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, |
1979 | 0 , (FTDI_SIO_RTS_CTS_HS | priv->interface), | 1981 | 0 , (FTDI_SIO_RTS_CTS_HS | priv->interface), |
1980 | buf, 0, WDR_TIMEOUT) < 0) { | 1982 | buf, 0, WDR_TIMEOUT) < 0) { |
1981 | err("urb failed to set to rts/cts flow control"); | 1983 | err("urb failed to set to rts/cts flow control"); |
1982 | } | 1984 | } |
1983 | 1985 | ||
1984 | } else { | 1986 | } else { |
1985 | /* | 1987 | /* |
1986 | * Xon/Xoff code | 1988 | * Xon/Xoff code |
1987 | * | 1989 | * |
@@ -2011,16 +2013,16 @@ static void ftdi_set_termios (struct usb_serial_port *port, struct termios *old_ | |||
2011 | /* else clause to only run if cfag ! CRTSCTS and iflag ! XOFF */ | 2013 | /* else clause to only run if cfag ! CRTSCTS and iflag ! XOFF */ |
2012 | /* CHECKME Assuming XON/XOFF handled by tty stack - not by device */ | 2014 | /* CHECKME Assuming XON/XOFF handled by tty stack - not by device */ |
2013 | dbg("%s Turning off hardware flow control", __FUNCTION__); | 2015 | dbg("%s Turning off hardware flow control", __FUNCTION__); |
2014 | if (usb_control_msg(dev, | 2016 | if (usb_control_msg(dev, |
2015 | usb_sndctrlpipe(dev, 0), | 2017 | usb_sndctrlpipe(dev, 0), |
2016 | FTDI_SIO_SET_FLOW_CTRL_REQUEST, | 2018 | FTDI_SIO_SET_FLOW_CTRL_REQUEST, |
2017 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, | 2019 | FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, |
2018 | 0, priv->interface, | 2020 | 0, priv->interface, |
2019 | buf, 0, WDR_TIMEOUT) < 0) { | 2021 | buf, 0, WDR_TIMEOUT) < 0) { |
2020 | err("urb failed to clear flow control"); | 2022 | err("urb failed to clear flow control"); |
2021 | } | 2023 | } |
2022 | } | 2024 | } |
2023 | 2025 | ||
2024 | } | 2026 | } |
2025 | return; | 2027 | return; |
2026 | } /* ftdi_termios */ | 2028 | } /* ftdi_termios */ |
@@ -2036,11 +2038,11 @@ static int ftdi_tiocmget (struct usb_serial_port *port, struct file *file) | |||
2036 | switch (priv->chip_type) { | 2038 | switch (priv->chip_type) { |
2037 | case SIO: | 2039 | case SIO: |
2038 | /* Request the status from the device */ | 2040 | /* Request the status from the device */ |
2039 | if ((ret = usb_control_msg(port->serial->dev, | 2041 | if ((ret = usb_control_msg(port->serial->dev, |
2040 | usb_rcvctrlpipe(port->serial->dev, 0), | 2042 | usb_rcvctrlpipe(port->serial->dev, 0), |
2041 | FTDI_SIO_GET_MODEM_STATUS_REQUEST, | 2043 | FTDI_SIO_GET_MODEM_STATUS_REQUEST, |
2042 | FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE, | 2044 | FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE, |
2043 | 0, 0, | 2045 | 0, 0, |
2044 | buf, 1, WDR_TIMEOUT)) < 0 ) { | 2046 | buf, 1, WDR_TIMEOUT)) < 0 ) { |
2045 | err("%s Could not get modem status of device - err: %d", __FUNCTION__, | 2047 | err("%s Could not get modem status of device - err: %d", __FUNCTION__, |
2046 | ret); | 2048 | ret); |
@@ -2052,11 +2054,11 @@ static int ftdi_tiocmget (struct usb_serial_port *port, struct file *file) | |||
2052 | case FT2232C: | 2054 | case FT2232C: |
2053 | /* the 8U232AM returns a two byte value (the sio is a 1 byte value) - in the same | 2055 | /* the 8U232AM returns a two byte value (the sio is a 1 byte value) - in the same |
2054 | format as the data returned from the in point */ | 2056 | format as the data returned from the in point */ |
2055 | if ((ret = usb_control_msg(port->serial->dev, | 2057 | if ((ret = usb_control_msg(port->serial->dev, |
2056 | usb_rcvctrlpipe(port->serial->dev, 0), | 2058 | usb_rcvctrlpipe(port->serial->dev, 0), |
2057 | FTDI_SIO_GET_MODEM_STATUS_REQUEST, | 2059 | FTDI_SIO_GET_MODEM_STATUS_REQUEST, |
2058 | FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE, | 2060 | FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE, |
2059 | 0, priv->interface, | 2061 | 0, priv->interface, |
2060 | buf, 2, WDR_TIMEOUT)) < 0 ) { | 2062 | buf, 2, WDR_TIMEOUT)) < 0 ) { |
2061 | err("%s Could not get modem status of device - err: %d", __FUNCTION__, | 2063 | err("%s Could not get modem status of device - err: %d", __FUNCTION__, |
2062 | ret); | 2064 | ret); |
@@ -2067,12 +2069,12 @@ static int ftdi_tiocmget (struct usb_serial_port *port, struct file *file) | |||
2067 | return -EFAULT; | 2069 | return -EFAULT; |
2068 | break; | 2070 | break; |
2069 | } | 2071 | } |
2070 | 2072 | ||
2071 | return (buf[0] & FTDI_SIO_DSR_MASK ? TIOCM_DSR : 0) | | 2073 | return (buf[0] & FTDI_SIO_DSR_MASK ? TIOCM_DSR : 0) | |
2072 | (buf[0] & FTDI_SIO_CTS_MASK ? TIOCM_CTS : 0) | | 2074 | (buf[0] & FTDI_SIO_CTS_MASK ? TIOCM_CTS : 0) | |
2073 | (buf[0] & FTDI_SIO_RI_MASK ? TIOCM_RI : 0) | | 2075 | (buf[0] & FTDI_SIO_RI_MASK ? TIOCM_RI : 0) | |
2074 | (buf[0] & FTDI_SIO_RLSD_MASK ? TIOCM_CD : 0) | | 2076 | (buf[0] & FTDI_SIO_RLSD_MASK ? TIOCM_CD : 0) | |
2075 | priv->last_dtr_rts; | 2077 | priv->last_dtr_rts; |
2076 | } | 2078 | } |
2077 | 2079 | ||
2078 | static int ftdi_tiocmset(struct usb_serial_port *port, struct file * file, unsigned int set, unsigned int clear) | 2080 | static int ftdi_tiocmset(struct usb_serial_port *port, struct file * file, unsigned int set, unsigned int clear) |
@@ -2138,11 +2140,11 @@ static int ftdi_ioctl (struct usb_serial_port *port, struct file * file, unsigne | |||
2138 | break; | 2140 | break; |
2139 | default: | 2141 | default: |
2140 | break; | 2142 | break; |
2141 | 2143 | ||
2142 | } | 2144 | } |
2143 | 2145 | ||
2144 | 2146 | ||
2145 | /* This is not necessarily an error - turns out the higher layers will do | 2147 | /* This is not necessarily an error - turns out the higher layers will do |
2146 | * some ioctls itself (see comment above) | 2148 | * some ioctls itself (see comment above) |
2147 | */ | 2149 | */ |
2148 | dbg("%s arg not supported - it was 0x%04x - check /usr/include/asm/ioctls.h", __FUNCTION__, cmd); | 2150 | dbg("%s arg not supported - it was 0x%04x - check /usr/include/asm/ioctls.h", __FUNCTION__, cmd); |
@@ -2199,7 +2201,7 @@ static int __init ftdi_init (void) | |||
2199 | if (retval) | 2201 | if (retval) |
2200 | goto failed_sio_register; | 2202 | goto failed_sio_register; |
2201 | retval = usb_register(&ftdi_driver); | 2203 | retval = usb_register(&ftdi_driver); |
2202 | if (retval) | 2204 | if (retval) |
2203 | goto failed_usb_register; | 2205 | goto failed_usb_register; |
2204 | 2206 | ||
2205 | info(DRIVER_VERSION ":" DRIVER_DESC); | 2207 | info(DRIVER_VERSION ":" DRIVER_DESC); |
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index f0edb87d2dd5..bae117d359af 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h | |||
@@ -55,6 +55,9 @@ | |||
55 | /* iPlus device */ | 55 | /* iPlus device */ |
56 | #define FTDI_IPLUS_PID 0xD070 /* Product Id */ | 56 | #define FTDI_IPLUS_PID 0xD070 /* Product Id */ |
57 | 57 | ||
58 | /* DMX4ALL DMX Interfaces */ | ||
59 | #define FTDI_DMX4ALL 0xC850 | ||
60 | |||
58 | /* www.crystalfontz.com devices - thanx for providing free devices for evaluation ! */ | 61 | /* www.crystalfontz.com devices - thanx for providing free devices for evaluation ! */ |
59 | /* they use the ftdi chipset for the USB interface and the vendor id is the same */ | 62 | /* they use the ftdi chipset for the USB interface and the vendor id is the same */ |
60 | #define FTDI_XF_632_PID 0xFC08 /* 632: 16x2 Character Display */ | 63 | #define FTDI_XF_632_PID 0xFC08 /* 632: 16x2 Character Display */ |
@@ -175,9 +178,15 @@ | |||
175 | #define FTDI_ASK_RDR400_PID 0xC991 /* ASK RDR 400 series card reader */ | 178 | #define FTDI_ASK_RDR400_PID 0xC991 /* ASK RDR 400 series card reader */ |
176 | 179 | ||
177 | /* | 180 | /* |
181 | * FTDI USB UART chips used in construction projects from the | ||
182 | * Elektor Electronics magazine (http://elektor-electronics.co.uk) | ||
183 | */ | ||
184 | #define ELEKTOR_VID 0x0C7D | ||
185 | #define ELEKTOR_FT323R_PID 0x0005 /* RFID-Reader, issue 09-2006 */ | ||
186 | |||
187 | /* | ||
178 | * DSS-20 Sync Station for Sony Ericsson P800 | 188 | * DSS-20 Sync Station for Sony Ericsson P800 |
179 | */ | 189 | */ |
180 | |||
181 | #define FTDI_DSS20_PID 0xFC82 | 190 | #define FTDI_DSS20_PID 0xFC82 |
182 | 191 | ||
183 | /* | 192 | /* |
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index 6238aff1e772..d72cf8bc7f76 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c | |||
@@ -320,6 +320,7 @@ static struct usb_device_id ipaq_id_table [] = { | |||
320 | { USB_DEVICE(0x0B05, 0x9200) }, /* ASUS USB Sync */ | 320 | { USB_DEVICE(0x0B05, 0x9200) }, /* ASUS USB Sync */ |
321 | { USB_DEVICE(0x0B05, 0x9202) }, /* ASUS USB Sync */ | 321 | { USB_DEVICE(0x0B05, 0x9202) }, /* ASUS USB Sync */ |
322 | { USB_DEVICE(0x0BB4, 0x00CE) }, /* HTC USB Sync */ | 322 | { USB_DEVICE(0x0BB4, 0x00CE) }, /* HTC USB Sync */ |
323 | { USB_DEVICE(0x0BB4, 0x00CF) }, /* HTC USB Modem */ | ||
323 | { USB_DEVICE(0x0BB4, 0x0A01) }, /* PocketPC USB Sync */ | 324 | { USB_DEVICE(0x0BB4, 0x0A01) }, /* PocketPC USB Sync */ |
324 | { USB_DEVICE(0x0BB4, 0x0A02) }, /* PocketPC USB Sync */ | 325 | { USB_DEVICE(0x0BB4, 0x0A02) }, /* PocketPC USB Sync */ |
325 | { USB_DEVICE(0x0BB4, 0x0A03) }, /* PocketPC USB Sync */ | 326 | { USB_DEVICE(0x0BB4, 0x0A03) }, /* PocketPC USB Sync */ |
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c new file mode 100644 index 000000000000..82cd15b894b0 --- /dev/null +++ b/drivers/usb/serial/mos7720.c | |||
@@ -0,0 +1,1683 @@ | |||
1 | /* | ||
2 | * mos7720.c | ||
3 | * Controls the Moschip 7720 usb to dual port serial convertor | ||
4 | * | ||
5 | * Copyright 2006 Moschip Semiconductor Tech. Ltd. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation, version 2 of the License. | ||
10 | * | ||
11 | * Developed by: | ||
12 | * VijayaKumar.G.N. <vijaykumar@aspirecom.net> | ||
13 | * AjayKumar <ajay@aspirecom.net> | ||
14 | * Gurudeva.N. <gurudev@aspirecom.net> | ||
15 | * | ||
16 | * Cleaned up from the original by: | ||
17 | * Greg Kroah-Hartman <gregkh@suse.de> | ||
18 | * | ||
19 | * Originally based on drivers/usb/serial/io_edgeport.c which is: | ||
20 | * Copyright (C) 2000 Inside Out Networks, All rights reserved. | ||
21 | * Copyright (C) 2001-2002 Greg Kroah-Hartman <greg@kroah.com> | ||
22 | */ | ||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/errno.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/slab.h> | ||
27 | #include <linux/tty.h> | ||
28 | #include <linux/tty_driver.h> | ||
29 | #include <linux/tty_flip.h> | ||
30 | #include <linux/module.h> | ||
31 | #include <linux/spinlock.h> | ||
32 | #include <linux/serial.h> | ||
33 | #include <linux/serial_reg.h> | ||
34 | #include <linux/usb.h> | ||
35 | #include <linux/usb/serial.h> | ||
36 | #include <asm/uaccess.h> | ||
37 | |||
38 | |||
39 | /* | ||
40 | * Version Information | ||
41 | */ | ||
42 | #define DRIVER_VERSION "1.0.0.4F" | ||
43 | #define DRIVER_AUTHOR "Aspire Communications pvt Ltd." | ||
44 | #define DRIVER_DESC "Moschip USB Serial Driver" | ||
45 | |||
46 | /* default urb timeout */ | ||
47 | #define MOS_WDR_TIMEOUT (HZ * 5) | ||
48 | |||
49 | #define MOS_PORT1 0x0200 | ||
50 | #define MOS_PORT2 0x0300 | ||
51 | #define MOS_VENREG 0x0000 | ||
52 | #define MOS_MAX_PORT 0x02 | ||
53 | #define MOS_WRITE 0x0E | ||
54 | #define MOS_READ 0x0D | ||
55 | |||
56 | /* Interrupt Rotinue Defines */ | ||
57 | #define SERIAL_IIR_RLS 0x06 | ||
58 | #define SERIAL_IIR_RDA 0x04 | ||
59 | #define SERIAL_IIR_CTI 0x0c | ||
60 | #define SERIAL_IIR_THR 0x02 | ||
61 | #define SERIAL_IIR_MS 0x00 | ||
62 | |||
63 | #define NUM_URBS 16 /* URB Count */ | ||
64 | #define URB_TRANSFER_BUFFER_SIZE 32 /* URB Size */ | ||
65 | |||
66 | /* This structure holds all of the local port information */ | ||
67 | struct moschip_port | ||
68 | { | ||
69 | __u8 shadowLCR; /* last LCR value received */ | ||
70 | __u8 shadowMCR; /* last MCR value received */ | ||
71 | __u8 shadowMSR; /* last MSR value received */ | ||
72 | char open; | ||
73 | struct async_icount icount; | ||
74 | struct usb_serial_port *port; /* loop back to the owner */ | ||
75 | struct urb *write_urb_pool[NUM_URBS]; | ||
76 | }; | ||
77 | |||
78 | /* This structure holds all of the individual serial device information */ | ||
79 | struct moschip_serial | ||
80 | { | ||
81 | int interrupt_started; | ||
82 | }; | ||
83 | |||
84 | static int debug; | ||
85 | |||
86 | #define USB_VENDOR_ID_MOSCHIP 0x9710 | ||
87 | #define MOSCHIP_DEVICE_ID_7720 0x7720 | ||
88 | #define MOSCHIP_DEVICE_ID_7715 0x7715 | ||
89 | |||
90 | static struct usb_device_id moschip_port_id_table [] = { | ||
91 | { USB_DEVICE(USB_VENDOR_ID_MOSCHIP,MOSCHIP_DEVICE_ID_7720) }, | ||
92 | { } /* terminating entry */ | ||
93 | }; | ||
94 | MODULE_DEVICE_TABLE(usb, moschip_port_id_table); | ||
95 | |||
96 | |||
97 | /* | ||
98 | * mos7720_interrupt_callback | ||
99 | * this is the callback function for when we have received data on the | ||
100 | * interrupt endpoint. | ||
101 | */ | ||
102 | static void mos7720_interrupt_callback(struct urb *urb) | ||
103 | { | ||
104 | int result; | ||
105 | int length; | ||
106 | __u32 *data; | ||
107 | unsigned int status; | ||
108 | __u8 sp1; | ||
109 | __u8 sp2; | ||
110 | __u8 st; | ||
111 | |||
112 | dbg("%s"," : Entering\n"); | ||
113 | |||
114 | if (!urb) { | ||
115 | dbg("%s","Invalid Pointer !!!!:\n"); | ||
116 | return; | ||
117 | } | ||
118 | |||
119 | switch (urb->status) { | ||
120 | case 0: | ||
121 | /* success */ | ||
122 | break; | ||
123 | case -ECONNRESET: | ||
124 | case -ENOENT: | ||
125 | case -ESHUTDOWN: | ||
126 | /* this urb is terminated, clean up */ | ||
127 | dbg("%s - urb shutting down with status: %d", __FUNCTION__, | ||
128 | urb->status); | ||
129 | return; | ||
130 | default: | ||
131 | dbg("%s - nonzero urb status received: %d", __FUNCTION__, | ||
132 | urb->status); | ||
133 | goto exit; | ||
134 | } | ||
135 | |||
136 | length = urb->actual_length; | ||
137 | data = urb->transfer_buffer; | ||
138 | |||
139 | /* Moschip get 4 bytes | ||
140 | * Byte 1 IIR Port 1 (port.number is 0) | ||
141 | * Byte 2 IIR Port 2 (port.number is 1) | ||
142 | * Byte 3 -------------- | ||
143 | * Byte 4 FIFO status for both */ | ||
144 | if (length && length > 4) { | ||
145 | dbg("Wrong data !!!"); | ||
146 | return; | ||
147 | } | ||
148 | |||
149 | status = *data; | ||
150 | |||
151 | sp1 = (status & 0xff000000)>>24; | ||
152 | sp2 = (status & 0x00ff0000)>>16; | ||
153 | st = status & 0x000000ff; | ||
154 | |||
155 | if ((sp1 & 0x01) || (sp2 & 0x01)) { | ||
156 | /* No Interrupt Pending in both the ports */ | ||
157 | dbg("No Interrupt !!!"); | ||
158 | } else { | ||
159 | switch (sp1 & 0x0f) { | ||
160 | case SERIAL_IIR_RLS: | ||
161 | dbg("Serial Port 1: Receiver status error or address " | ||
162 | "bit detected in 9-bit mode\n"); | ||
163 | break; | ||
164 | case SERIAL_IIR_CTI: | ||
165 | dbg("Serial Port 1: Receiver time out"); | ||
166 | break; | ||
167 | case SERIAL_IIR_MS: | ||
168 | dbg("Serial Port 1: Modem status change"); | ||
169 | break; | ||
170 | } | ||
171 | |||
172 | switch (sp2 & 0x0f) { | ||
173 | case SERIAL_IIR_RLS: | ||
174 | dbg("Serial Port 2: Receiver status error or address " | ||
175 | "bit detected in 9-bit mode"); | ||
176 | break; | ||
177 | case SERIAL_IIR_CTI: | ||
178 | dbg("Serial Port 2: Receiver time out"); | ||
179 | break; | ||
180 | case SERIAL_IIR_MS: | ||
181 | dbg("Serial Port 2: Modem status change"); | ||
182 | break; | ||
183 | } | ||
184 | } | ||
185 | |||
186 | exit: | ||
187 | result = usb_submit_urb(urb, GFP_ATOMIC); | ||
188 | if (result) | ||
189 | dev_err(&urb->dev->dev, | ||
190 | "%s - Error %d submitting control urb\n", | ||
191 | __FUNCTION__, result); | ||
192 | return; | ||
193 | } | ||
194 | |||
195 | /* | ||
196 | * mos7720_bulk_in_callback | ||
197 | * this is the callback function for when we have received data on the | ||
198 | * bulk in endpoint. | ||
199 | */ | ||
200 | static void mos7720_bulk_in_callback(struct urb *urb) | ||
201 | { | ||
202 | int status; | ||
203 | unsigned char *data ; | ||
204 | struct usb_serial_port *port; | ||
205 | struct moschip_port *mos7720_port; | ||
206 | struct tty_struct *tty; | ||
207 | |||
208 | if (urb->status) { | ||
209 | dbg("nonzero read bulk status received: %d",urb->status); | ||
210 | return; | ||
211 | } | ||
212 | |||
213 | mos7720_port = urb->context; | ||
214 | if (!mos7720_port) { | ||
215 | dbg("%s","NULL mos7720_port pointer \n"); | ||
216 | return ; | ||
217 | } | ||
218 | |||
219 | port = mos7720_port->port; | ||
220 | |||
221 | dbg("Entering...%s", __FUNCTION__); | ||
222 | |||
223 | data = urb->transfer_buffer; | ||
224 | |||
225 | tty = port->tty; | ||
226 | if (tty && urb->actual_length) { | ||
227 | tty_buffer_request_room(tty, urb->actual_length); | ||
228 | tty_insert_flip_string(tty, data, urb->actual_length); | ||
229 | tty_flip_buffer_push(tty); | ||
230 | } | ||
231 | |||
232 | if (!port->read_urb) { | ||
233 | dbg("URB KILLED !!!"); | ||
234 | return; | ||
235 | } | ||
236 | |||
237 | if (port->read_urb->status != -EINPROGRESS) { | ||
238 | port->read_urb->dev = port->serial->dev; | ||
239 | |||
240 | status = usb_submit_urb(port->read_urb, GFP_ATOMIC); | ||
241 | if (status) | ||
242 | dbg("usb_submit_urb(read bulk) failed, status = %d", | ||
243 | status); | ||
244 | } | ||
245 | } | ||
246 | |||
247 | /* | ||
248 | * mos7720_bulk_out_data_callback | ||
249 | * this is the callback function for when we have finished sending serial | ||
250 | * data on the bulk out endpoint. | ||
251 | */ | ||
252 | static void mos7720_bulk_out_data_callback(struct urb *urb) | ||
253 | { | ||
254 | struct moschip_port *mos7720_port; | ||
255 | struct tty_struct *tty; | ||
256 | |||
257 | if (urb->status) { | ||
258 | dbg("nonzero write bulk status received:%d", urb->status); | ||
259 | return; | ||
260 | } | ||
261 | |||
262 | mos7720_port = urb->context; | ||
263 | if (!mos7720_port) { | ||
264 | dbg("NULL mos7720_port pointer"); | ||
265 | return ; | ||
266 | } | ||
267 | |||
268 | dbg("Entering ........."); | ||
269 | |||
270 | tty = mos7720_port->port->tty; | ||
271 | |||
272 | if (tty && mos7720_port->open) { | ||
273 | /* let the tty driver wakeup if it has a special * | ||
274 | * write_wakeup function */ | ||
275 | if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && | ||
276 | tty->ldisc.write_wakeup) | ||
277 | (tty->ldisc.write_wakeup)(tty); | ||
278 | |||
279 | /* tell the tty driver that something has changed */ | ||
280 | wake_up_interruptible(&tty->write_wait); | ||
281 | } | ||
282 | |||
283 | /* schedule_work(&mos7720_port->port->work); */ | ||
284 | } | ||
285 | |||
286 | /* | ||
287 | * send_mos_cmd | ||
288 | * this function will be used for sending command to device | ||
289 | */ | ||
290 | static int send_mos_cmd(struct usb_serial *serial, __u8 request, __u16 value, | ||
291 | __u16 index, void *data) | ||
292 | { | ||
293 | int status; | ||
294 | unsigned int pipe; | ||
295 | u16 product = le16_to_cpu(serial->dev->descriptor.idProduct); | ||
296 | __u8 requesttype; | ||
297 | __u16 size = 0x0000; | ||
298 | |||
299 | if (value < MOS_MAX_PORT) { | ||
300 | if (product == MOSCHIP_DEVICE_ID_7715) { | ||
301 | value = value*0x100+0x100; | ||
302 | } else { | ||
303 | value = value*0x100+0x200; | ||
304 | } | ||
305 | } else { | ||
306 | value = 0x0000; | ||
307 | if ((product == MOSCHIP_DEVICE_ID_7715) && | ||
308 | (index != 0x08)) { | ||
309 | dbg("serial->product== MOSCHIP_DEVICE_ID_7715"); | ||
310 | //index = 0x01 ; | ||
311 | } | ||
312 | } | ||
313 | |||
314 | if (request == MOS_WRITE) { | ||
315 | request = (__u8)MOS_WRITE; | ||
316 | requesttype = (__u8)0x40; | ||
317 | value = value + (__u16)*((unsigned char *)data); | ||
318 | data = NULL; | ||
319 | pipe = usb_sndctrlpipe(serial->dev, 0); | ||
320 | } else { | ||
321 | request = (__u8)MOS_READ; | ||
322 | requesttype = (__u8)0xC0; | ||
323 | size = 0x01; | ||
324 | pipe = usb_rcvctrlpipe(serial->dev,0); | ||
325 | } | ||
326 | |||
327 | status = usb_control_msg(serial->dev, pipe, request, requesttype, | ||
328 | value, index, data, size, MOS_WDR_TIMEOUT); | ||
329 | |||
330 | if (status < 0) | ||
331 | dbg("Command Write failed Value %x index %x\n",value,index); | ||
332 | |||
333 | return status; | ||
334 | } | ||
335 | |||
336 | static int mos7720_open(struct usb_serial_port *port, struct file * filp) | ||
337 | { | ||
338 | struct usb_serial *serial; | ||
339 | struct usb_serial_port *port0; | ||
340 | struct urb *urb; | ||
341 | struct moschip_serial *mos7720_serial; | ||
342 | struct moschip_port *mos7720_port; | ||
343 | int response; | ||
344 | int port_number; | ||
345 | char data; | ||
346 | int j; | ||
347 | |||
348 | serial = port->serial; | ||
349 | |||
350 | mos7720_port = usb_get_serial_port_data(port); | ||
351 | if (mos7720_port == NULL) | ||
352 | return -ENODEV; | ||
353 | |||
354 | port0 = serial->port[0]; | ||
355 | |||
356 | mos7720_serial = usb_get_serial_data(serial); | ||
357 | |||
358 | if (mos7720_serial == NULL || port0 == NULL) | ||
359 | return -ENODEV; | ||
360 | |||
361 | usb_clear_halt(serial->dev, port->write_urb->pipe); | ||
362 | usb_clear_halt(serial->dev, port->read_urb->pipe); | ||
363 | |||
364 | /* Initialising the write urb pool */ | ||
365 | for (j = 0; j < NUM_URBS; ++j) { | ||
366 | urb = usb_alloc_urb(0,SLAB_ATOMIC); | ||
367 | mos7720_port->write_urb_pool[j] = urb; | ||
368 | |||
369 | if (urb == NULL) { | ||
370 | err("No more urbs???"); | ||
371 | continue; | ||
372 | } | ||
373 | |||
374 | urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE, | ||
375 | GFP_KERNEL); | ||
376 | if (!urb->transfer_buffer) { | ||
377 | err("%s-out of memory for urb buffers.", __FUNCTION__); | ||
378 | continue; | ||
379 | } | ||
380 | } | ||
381 | |||
382 | /* Initialize MCS7720 -- Write Init values to corresponding Registers | ||
383 | * | ||
384 | * Register Index | ||
385 | * 1 : IER | ||
386 | * 2 : FCR | ||
387 | * 3 : LCR | ||
388 | * 4 : MCR | ||
389 | * | ||
390 | * 0x08 : SP1/2 Control Reg | ||
391 | */ | ||
392 | port_number = port->number - port->serial->minor; | ||
393 | send_mos_cmd(port->serial, MOS_READ, port_number, UART_LSR, &data); | ||
394 | dbg("SS::%p LSR:%x\n",mos7720_port, data); | ||
395 | |||
396 | dbg("Check:Sending Command .........."); | ||
397 | |||
398 | data = 0x02; | ||
399 | send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, 0x01, &data); | ||
400 | data = 0x02; | ||
401 | send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, 0x02, &data); | ||
402 | |||
403 | data = 0x00; | ||
404 | send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data); | ||
405 | data = 0x00; | ||
406 | send_mos_cmd(serial, MOS_WRITE, port_number, 0x02, &data); | ||
407 | |||
408 | data = 0xCF; | ||
409 | send_mos_cmd(serial, MOS_WRITE, port_number, 0x02, &data); | ||
410 | data = 0x03; | ||
411 | mos7720_port->shadowLCR = data; | ||
412 | send_mos_cmd(serial, MOS_WRITE, port_number, 0x03, &data); | ||
413 | data = 0x0b; | ||
414 | mos7720_port->shadowMCR = data; | ||
415 | send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data); | ||
416 | data = 0x0b; | ||
417 | send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data); | ||
418 | |||
419 | data = 0x00; | ||
420 | send_mos_cmd(serial, MOS_READ, MOS_MAX_PORT, 0x08, &data); | ||
421 | data = 0x00; | ||
422 | send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, 0x08, &data); | ||
423 | |||
424 | /* data = 0x00; | ||
425 | send_mos_cmd(serial, MOS_READ, MOS_MAX_PORT, port_number + 1, &data); | ||
426 | data = 0x03; | ||
427 | send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, port_number + 1, &data); | ||
428 | data = 0x00; | ||
429 | send_mos_cmd(port->serial, MOS_WRITE, MOS_MAX_PORT, port_number + 1, &data); | ||
430 | */ | ||
431 | data = 0x00; | ||
432 | send_mos_cmd(serial, MOS_READ, MOS_MAX_PORT, 0x08, &data); | ||
433 | |||
434 | data = data | (port->number - port->serial->minor + 1); | ||
435 | send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, 0x08, &data); | ||
436 | |||
437 | data = 0x83; | ||
438 | mos7720_port->shadowLCR = data; | ||
439 | send_mos_cmd(serial, MOS_WRITE, port_number, 0x03, &data); | ||
440 | data = 0x0c; | ||
441 | send_mos_cmd(serial, MOS_WRITE, port_number, 0x00, &data); | ||
442 | data = 0x00; | ||
443 | send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data); | ||
444 | data = 0x03; | ||
445 | mos7720_port->shadowLCR = data; | ||
446 | send_mos_cmd(serial, MOS_WRITE, port_number, 0x03, &data); | ||
447 | data = 0x0c; | ||
448 | send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data); | ||
449 | data = 0x0c; | ||
450 | send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data); | ||
451 | |||
452 | //Matrix | ||
453 | |||
454 | /* force low_latency on so that our tty_push actually forces * | ||
455 | * the data through,otherwise it is scheduled, and with * | ||
456 | * high data rates (like with OHCI) data can get lost. */ | ||
457 | |||
458 | if (port->tty) | ||
459 | port->tty->low_latency = 1; | ||
460 | |||
461 | /* see if we've set up our endpoint info yet * | ||
462 | * (can't set it up in mos7720_startup as the * | ||
463 | * structures were not set up at that time.) */ | ||
464 | if (!mos7720_serial->interrupt_started) { | ||
465 | dbg("Interrupt buffer NULL !!!"); | ||
466 | |||
467 | /* not set up yet, so do it now */ | ||
468 | mos7720_serial->interrupt_started = 1; | ||
469 | |||
470 | dbg("To Submit URB !!!"); | ||
471 | |||
472 | /* set up our interrupt urb */ | ||
473 | usb_fill_int_urb(port0->interrupt_in_urb, serial->dev, | ||
474 | usb_rcvintpipe(serial->dev, | ||
475 | port->interrupt_in_endpointAddress), | ||
476 | port0->interrupt_in_buffer, | ||
477 | port0->interrupt_in_urb->transfer_buffer_length, | ||
478 | mos7720_interrupt_callback, mos7720_port, | ||
479 | port0->interrupt_in_urb->interval); | ||
480 | |||
481 | /* start interrupt read for this mos7720 this interrupt * | ||
482 | * will continue as long as the mos7720 is connected */ | ||
483 | dbg("Submit URB over !!!"); | ||
484 | response = usb_submit_urb(port0->interrupt_in_urb, GFP_KERNEL); | ||
485 | if (response) | ||
486 | dev_err(&port->dev, | ||
487 | "%s - Error %d submitting control urb", | ||
488 | __FUNCTION__, response); | ||
489 | } | ||
490 | |||
491 | /* set up our bulk in urb */ | ||
492 | usb_fill_bulk_urb(port->read_urb, serial->dev, | ||
493 | usb_rcvbulkpipe(serial->dev, | ||
494 | port->bulk_in_endpointAddress), | ||
495 | port->bulk_in_buffer, | ||
496 | port->read_urb->transfer_buffer_length, | ||
497 | mos7720_bulk_in_callback, mos7720_port); | ||
498 | response = usb_submit_urb(port->read_urb, GFP_KERNEL); | ||
499 | if (response) | ||
500 | dev_err(&port->dev, | ||
501 | "%s - Error %d submitting read urb", __FUNCTION__, response); | ||
502 | |||
503 | /* initialize our icount structure */ | ||
504 | memset(&(mos7720_port->icount), 0x00, sizeof(mos7720_port->icount)); | ||
505 | |||
506 | /* initialize our port settings */ | ||
507 | mos7720_port->shadowMCR = UART_MCR_OUT2; /* Must set to enable ints! */ | ||
508 | |||
509 | /* send a open port command */ | ||
510 | mos7720_port->open = 1; | ||
511 | |||
512 | return 0; | ||
513 | } | ||
514 | |||
515 | /* | ||
516 | * mos7720_chars_in_buffer | ||
517 | * this function is called by the tty driver when it wants to know how many | ||
518 | * bytes of data we currently have outstanding in the port (data that has | ||
519 | * been written, but hasn't made it out the port yet) | ||
520 | * If successful, we return the number of bytes left to be written in the | ||
521 | * system, | ||
522 | * Otherwise we return a negative error number. | ||
523 | */ | ||
524 | static int mos7720_chars_in_buffer(struct usb_serial_port *port) | ||
525 | { | ||
526 | int i; | ||
527 | int chars = 0; | ||
528 | struct moschip_port *mos7720_port; | ||
529 | |||
530 | dbg("%s:entering ...........", __FUNCTION__); | ||
531 | |||
532 | mos7720_port = usb_get_serial_port_data(port); | ||
533 | if (mos7720_port == NULL) { | ||
534 | dbg("%s:leaving ...........", __FUNCTION__); | ||
535 | return -ENODEV; | ||
536 | } | ||
537 | |||
538 | for (i = 0; i < NUM_URBS; ++i) { | ||
539 | if (mos7720_port->write_urb_pool[i]->status == -EINPROGRESS) | ||
540 | chars += URB_TRANSFER_BUFFER_SIZE; | ||
541 | } | ||
542 | dbg("%s - returns %d", __FUNCTION__, chars); | ||
543 | return chars; | ||
544 | } | ||
545 | |||
546 | static void mos7720_close(struct usb_serial_port *port, struct file *filp) | ||
547 | { | ||
548 | struct usb_serial *serial; | ||
549 | struct moschip_port *mos7720_port; | ||
550 | char data; | ||
551 | int j; | ||
552 | |||
553 | dbg("mos7720_close:entering..."); | ||
554 | |||
555 | serial = port->serial; | ||
556 | |||
557 | mos7720_port = usb_get_serial_port_data(port); | ||
558 | if (mos7720_port == NULL) | ||
559 | return; | ||
560 | |||
561 | for (j = 0; j < NUM_URBS; ++j) | ||
562 | usb_kill_urb(mos7720_port->write_urb_pool[j]); | ||
563 | |||
564 | /* Freeing Write URBs */ | ||
565 | for (j = 0; j < NUM_URBS; ++j) { | ||
566 | if (mos7720_port->write_urb_pool[j]) { | ||
567 | kfree(mos7720_port->write_urb_pool[j]->transfer_buffer); | ||
568 | usb_free_urb(mos7720_port->write_urb_pool[j]); | ||
569 | } | ||
570 | } | ||
571 | |||
572 | /* While closing port, shutdown all bulk read, write * | ||
573 | * and interrupt read if they exists */ | ||
574 | if (serial->dev) { | ||
575 | dbg("Shutdown bulk write"); | ||
576 | usb_kill_urb(port->write_urb); | ||
577 | dbg("Shutdown bulk read"); | ||
578 | usb_kill_urb(port->read_urb); | ||
579 | } | ||
580 | |||
581 | data = 0x00; | ||
582 | send_mos_cmd(serial, MOS_WRITE, port->number - port->serial->minor, | ||
583 | 0x04, &data); | ||
584 | |||
585 | data = 0x00; | ||
586 | send_mos_cmd(serial, MOS_WRITE, port->number - port->serial->minor, | ||
587 | 0x01, &data); | ||
588 | |||
589 | mos7720_port->open = 0; | ||
590 | |||
591 | dbg("Leaving %s", __FUNCTION__); | ||
592 | } | ||
593 | |||
594 | static void mos7720_break(struct usb_serial_port *port, int break_state) | ||
595 | { | ||
596 | unsigned char data; | ||
597 | struct usb_serial *serial; | ||
598 | struct moschip_port *mos7720_port; | ||
599 | |||
600 | dbg("Entering %s", __FUNCTION__); | ||
601 | |||
602 | serial = port->serial; | ||
603 | |||
604 | mos7720_port = usb_get_serial_port_data(port); | ||
605 | if (mos7720_port == NULL) | ||
606 | return; | ||
607 | |||
608 | if (break_state == -1) | ||
609 | data = mos7720_port->shadowLCR | UART_LCR_SBC; | ||
610 | else | ||
611 | data = mos7720_port->shadowLCR & ~UART_LCR_SBC; | ||
612 | |||
613 | mos7720_port->shadowLCR = data; | ||
614 | send_mos_cmd(serial, MOS_WRITE, port->number - port->serial->minor, | ||
615 | 0x03, &data); | ||
616 | |||
617 | return; | ||
618 | } | ||
619 | |||
620 | /* | ||
621 | * mos7720_write_room | ||
622 | * this function is called by the tty driver when it wants to know how many | ||
623 | * bytes of data we can accept for a specific port. | ||
624 | * If successful, we return the amount of room that we have for this port | ||
625 | * Otherwise we return a negative error number. | ||
626 | */ | ||
627 | static int mos7720_write_room(struct usb_serial_port *port) | ||
628 | { | ||
629 | struct moschip_port *mos7720_port; | ||
630 | int room = 0; | ||
631 | int i; | ||
632 | |||
633 | dbg("%s:entering ...........", __FUNCTION__); | ||
634 | |||
635 | mos7720_port = usb_get_serial_port_data(port); | ||
636 | if (mos7720_port == NULL) { | ||
637 | dbg("%s:leaving ...........", __FUNCTION__); | ||
638 | return -ENODEV; | ||
639 | } | ||
640 | |||
641 | for (i = 0; i < NUM_URBS; ++i) { | ||
642 | if (mos7720_port->write_urb_pool[i]->status != -EINPROGRESS) | ||
643 | room += URB_TRANSFER_BUFFER_SIZE; | ||
644 | } | ||
645 | |||
646 | dbg("%s - returns %d", __FUNCTION__, room); | ||
647 | return room; | ||
648 | } | ||
649 | |||
650 | static int mos7720_write(struct usb_serial_port *port, | ||
651 | const unsigned char *data, int count) | ||
652 | { | ||
653 | int status; | ||
654 | int i; | ||
655 | int bytes_sent = 0; | ||
656 | int transfer_size; | ||
657 | |||
658 | struct moschip_port *mos7720_port; | ||
659 | struct usb_serial *serial; | ||
660 | struct urb *urb; | ||
661 | const unsigned char *current_position = data; | ||
662 | |||
663 | dbg("%s:entering ...........", __FUNCTION__); | ||
664 | |||
665 | serial = port->serial; | ||
666 | |||
667 | mos7720_port = usb_get_serial_port_data(port); | ||
668 | if (mos7720_port == NULL) { | ||
669 | dbg("mos7720_port is NULL"); | ||
670 | return -ENODEV; | ||
671 | } | ||
672 | |||
673 | /* try to find a free urb in the list */ | ||
674 | urb = NULL; | ||
675 | |||
676 | for (i = 0; i < NUM_URBS; ++i) { | ||
677 | if (mos7720_port->write_urb_pool[i]->status != -EINPROGRESS) { | ||
678 | urb = mos7720_port->write_urb_pool[i]; | ||
679 | dbg("URB:%d",i); | ||
680 | break; | ||
681 | } | ||
682 | } | ||
683 | |||
684 | if (urb == NULL) { | ||
685 | dbg("%s - no more free urbs", __FUNCTION__); | ||
686 | goto exit; | ||
687 | } | ||
688 | |||
689 | if (urb->transfer_buffer == NULL) { | ||
690 | urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE, | ||
691 | GFP_KERNEL); | ||
692 | if (urb->transfer_buffer == NULL) { | ||
693 | err("%s no more kernel memory...", __FUNCTION__); | ||
694 | goto exit; | ||
695 | } | ||
696 | } | ||
697 | transfer_size = min (count, URB_TRANSFER_BUFFER_SIZE); | ||
698 | |||
699 | memcpy(urb->transfer_buffer, current_position, transfer_size); | ||
700 | usb_serial_debug_data(debug, &port->dev, __FUNCTION__, transfer_size, | ||
701 | urb->transfer_buffer); | ||
702 | |||
703 | /* fill urb with data and submit */ | ||
704 | usb_fill_bulk_urb(urb, serial->dev, | ||
705 | usb_sndbulkpipe(serial->dev, | ||
706 | port->bulk_out_endpointAddress), | ||
707 | urb->transfer_buffer, transfer_size, | ||
708 | mos7720_bulk_out_data_callback, mos7720_port); | ||
709 | |||
710 | /* send it down the pipe */ | ||
711 | status = usb_submit_urb(urb,GFP_ATOMIC); | ||
712 | if (status) { | ||
713 | err("%s - usb_submit_urb(write bulk) failed with status = %d", | ||
714 | __FUNCTION__, status); | ||
715 | bytes_sent = status; | ||
716 | goto exit; | ||
717 | } | ||
718 | bytes_sent = transfer_size; | ||
719 | |||
720 | exit: | ||
721 | return bytes_sent; | ||
722 | } | ||
723 | |||
724 | static void mos7720_throttle(struct usb_serial_port *port) | ||
725 | { | ||
726 | struct moschip_port *mos7720_port; | ||
727 | struct tty_struct *tty; | ||
728 | int status; | ||
729 | |||
730 | dbg("%s- port %d\n", __FUNCTION__, port->number); | ||
731 | |||
732 | mos7720_port = usb_get_serial_port_data(port); | ||
733 | |||
734 | if (mos7720_port == NULL) | ||
735 | return; | ||
736 | |||
737 | if (!mos7720_port->open) { | ||
738 | dbg("port not opened"); | ||
739 | return; | ||
740 | } | ||
741 | |||
742 | dbg("%s: Entering ..........", __FUNCTION__); | ||
743 | |||
744 | tty = port->tty; | ||
745 | if (!tty) { | ||
746 | dbg("%s - no tty available", __FUNCTION__); | ||
747 | return; | ||
748 | } | ||
749 | |||
750 | /* if we are implementing XON/XOFF, send the stop character */ | ||
751 | if (I_IXOFF(tty)) { | ||
752 | unsigned char stop_char = STOP_CHAR(tty); | ||
753 | status = mos7720_write(port, &stop_char, 1); | ||
754 | if (status <= 0) | ||
755 | return; | ||
756 | } | ||
757 | |||
758 | /* if we are implementing RTS/CTS, toggle that line */ | ||
759 | if (tty->termios->c_cflag & CRTSCTS) { | ||
760 | mos7720_port->shadowMCR &= ~UART_MCR_RTS; | ||
761 | status = send_mos_cmd(port->serial, MOS_WRITE, | ||
762 | port->number - port->serial->minor, | ||
763 | UART_MCR, &mos7720_port->shadowMCR); | ||
764 | if (status != 0) | ||
765 | return; | ||
766 | } | ||
767 | } | ||
768 | |||
769 | static void mos7720_unthrottle(struct usb_serial_port *port) | ||
770 | { | ||
771 | struct tty_struct *tty; | ||
772 | int status; | ||
773 | struct moschip_port *mos7720_port = usb_get_serial_port_data(port); | ||
774 | |||
775 | if (mos7720_port == NULL) | ||
776 | return; | ||
777 | |||
778 | if (!mos7720_port->open) { | ||
779 | dbg("%s - port not opened", __FUNCTION__); | ||
780 | return; | ||
781 | } | ||
782 | |||
783 | dbg("%s: Entering ..........", __FUNCTION__); | ||
784 | |||
785 | tty = port->tty; | ||
786 | if (!tty) { | ||
787 | dbg("%s - no tty available", __FUNCTION__); | ||
788 | return; | ||
789 | } | ||
790 | |||
791 | /* if we are implementing XON/XOFF, send the start character */ | ||
792 | if (I_IXOFF(tty)) { | ||
793 | unsigned char start_char = START_CHAR(tty); | ||
794 | status = mos7720_write(port, &start_char, 1); | ||
795 | if (status <= 0) | ||
796 | return; | ||
797 | } | ||
798 | |||
799 | /* if we are implementing RTS/CTS, toggle that line */ | ||
800 | if (tty->termios->c_cflag & CRTSCTS) { | ||
801 | mos7720_port->shadowMCR |= UART_MCR_RTS; | ||
802 | status = send_mos_cmd(port->serial, MOS_WRITE, | ||
803 | port->number - port->serial->minor, | ||
804 | UART_MCR, &mos7720_port->shadowMCR); | ||
805 | if (status != 0) | ||
806 | return; | ||
807 | } | ||
808 | } | ||
809 | |||
810 | static int set_higher_rates(struct moschip_port *mos7720_port, | ||
811 | unsigned int baud) | ||
812 | { | ||
813 | unsigned char data; | ||
814 | struct usb_serial_port *port; | ||
815 | struct usb_serial *serial; | ||
816 | int port_number; | ||
817 | |||
818 | if (mos7720_port == NULL) | ||
819 | return -EINVAL; | ||
820 | |||
821 | port = mos7720_port->port; | ||
822 | serial = port->serial; | ||
823 | |||
824 | /*********************************************** | ||
825 | * Init Sequence for higher rates | ||
826 | ***********************************************/ | ||
827 | dbg("Sending Setting Commands .........."); | ||
828 | port_number = port->number - port->serial->minor; | ||
829 | |||
830 | data = 0x000; | ||
831 | send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data); | ||
832 | data = 0x000; | ||
833 | send_mos_cmd(serial, MOS_WRITE, port_number, 0x02, &data); | ||
834 | data = 0x0CF; | ||
835 | send_mos_cmd(serial, MOS_WRITE, port->number, 0x02, &data); | ||
836 | data = 0x00b; | ||
837 | mos7720_port->shadowMCR = data; | ||
838 | send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data); | ||
839 | data = 0x00b; | ||
840 | send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data); | ||
841 | |||
842 | data = 0x000; | ||
843 | send_mos_cmd(serial, MOS_READ, MOS_MAX_PORT, 0x08, &data); | ||
844 | data = 0x000; | ||
845 | send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, 0x08, &data); | ||
846 | |||
847 | |||
848 | /*********************************************** | ||
849 | * Set for higher rates * | ||
850 | ***********************************************/ | ||
851 | |||
852 | data = baud * 0x10; | ||
853 | send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, port_number + 1,&data); | ||
854 | |||
855 | data = 0x003; | ||
856 | send_mos_cmd(serial, MOS_READ, MOS_MAX_PORT, 0x08, &data); | ||
857 | data = 0x003; | ||
858 | send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, 0x08, &data); | ||
859 | |||
860 | data = 0x02b; | ||
861 | mos7720_port->shadowMCR = data; | ||
862 | send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data); | ||
863 | data = 0x02b; | ||
864 | send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data); | ||
865 | |||
866 | /*********************************************** | ||
867 | * Set DLL/DLM | ||
868 | ***********************************************/ | ||
869 | |||
870 | data = mos7720_port->shadowLCR | UART_LCR_DLAB; | ||
871 | mos7720_port->shadowLCR = data; | ||
872 | send_mos_cmd(serial, MOS_WRITE, port_number, 0x03, &data); | ||
873 | |||
874 | data = 0x001; /* DLL */ | ||
875 | send_mos_cmd(serial, MOS_WRITE, port_number, 0x00, &data); | ||
876 | data = 0x000; /* DLM */ | ||
877 | send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data); | ||
878 | |||
879 | data = mos7720_port->shadowLCR & ~UART_LCR_DLAB; | ||
880 | mos7720_port->shadowLCR = data; | ||
881 | send_mos_cmd(serial, MOS_WRITE, port_number, 0x03, &data); | ||
882 | |||
883 | return 0; | ||
884 | } | ||
885 | |||
886 | /* baud rate information */ | ||
887 | struct divisor_table_entry | ||
888 | { | ||
889 | __u32 baudrate; | ||
890 | __u16 divisor; | ||
891 | }; | ||
892 | |||
893 | /* Define table of divisors for moschip 7720 hardware * | ||
894 | * These assume a 3.6864MHz crystal, the standard /16, and * | ||
895 | * MCR.7 = 0. */ | ||
896 | static struct divisor_table_entry divisor_table[] = { | ||
897 | { 50, 2304}, | ||
898 | { 110, 1047}, /* 2094.545455 => 230450 => .0217 % over */ | ||
899 | { 134, 857}, /* 1713.011152 => 230398.5 => .00065% under */ | ||
900 | { 150, 768}, | ||
901 | { 300, 384}, | ||
902 | { 600, 192}, | ||
903 | { 1200, 96}, | ||
904 | { 1800, 64}, | ||
905 | { 2400, 48}, | ||
906 | { 4800, 24}, | ||
907 | { 7200, 16}, | ||
908 | { 9600, 12}, | ||
909 | { 19200, 6}, | ||
910 | { 38400, 3}, | ||
911 | { 57600, 2}, | ||
912 | { 115200, 1}, | ||
913 | }; | ||
914 | |||
915 | /***************************************************************************** | ||
916 | * calc_baud_rate_divisor | ||
917 | * this function calculates the proper baud rate divisor for the specified | ||
918 | * baud rate. | ||
919 | *****************************************************************************/ | ||
920 | static int calc_baud_rate_divisor(int baudrate, int *divisor) | ||
921 | { | ||
922 | int i; | ||
923 | __u16 custom; | ||
924 | __u16 round1; | ||
925 | __u16 round; | ||
926 | |||
927 | |||
928 | dbg("%s - %d", __FUNCTION__, baudrate); | ||
929 | |||
930 | for (i = 0; i < ARRAY_SIZE(divisor_table); i++) { | ||
931 | if (divisor_table[i].baudrate == baudrate) { | ||
932 | *divisor = divisor_table[i].divisor; | ||
933 | return 0; | ||
934 | } | ||
935 | } | ||
936 | |||
937 | /* After trying for all the standard baud rates * | ||
938 | * Try calculating the divisor for this baud rate */ | ||
939 | if (baudrate > 75 && baudrate < 230400) { | ||
940 | /* get the divisor */ | ||
941 | custom = (__u16)(230400L / baudrate); | ||
942 | |||
943 | /* Check for round off */ | ||
944 | round1 = (__u16)(2304000L / baudrate); | ||
945 | round = (__u16)(round1 - (custom * 10)); | ||
946 | if (round > 4) | ||
947 | custom++; | ||
948 | *divisor = custom; | ||
949 | |||
950 | dbg("Baud %d = %d",baudrate, custom); | ||
951 | return 0; | ||
952 | } | ||
953 | |||
954 | dbg("Baud calculation Failed..."); | ||
955 | return -EINVAL; | ||
956 | } | ||
957 | |||
958 | /* | ||
959 | * send_cmd_write_baud_rate | ||
960 | * this function sends the proper command to change the baud rate of the | ||
961 | * specified port. | ||
962 | */ | ||
963 | static int send_cmd_write_baud_rate(struct moschip_port *mos7720_port, | ||
964 | int baudrate) | ||
965 | { | ||
966 | struct usb_serial_port *port; | ||
967 | struct usb_serial *serial; | ||
968 | int divisor; | ||
969 | int status; | ||
970 | unsigned char data; | ||
971 | unsigned char number; | ||
972 | |||
973 | if (mos7720_port == NULL) | ||
974 | return -1; | ||
975 | |||
976 | port = mos7720_port->port; | ||
977 | serial = port->serial; | ||
978 | |||
979 | dbg("%s: Entering ..........", __FUNCTION__); | ||
980 | |||
981 | number = port->number - port->serial->minor; | ||
982 | dbg("%s - port = %d, baud = %d", __FUNCTION__, port->number, baudrate); | ||
983 | |||
984 | /* Calculate the Divisor */ | ||
985 | status = calc_baud_rate_divisor(baudrate, &divisor); | ||
986 | if (status) { | ||
987 | err("%s - bad baud rate", __FUNCTION__); | ||
988 | return status; | ||
989 | } | ||
990 | |||
991 | /* Enable access to divisor latch */ | ||
992 | data = mos7720_port->shadowLCR | UART_LCR_DLAB; | ||
993 | mos7720_port->shadowLCR = data; | ||
994 | send_mos_cmd(serial, MOS_WRITE, number, UART_LCR, &data); | ||
995 | |||
996 | /* Write the divisor */ | ||
997 | data = ((unsigned char)(divisor & 0xff)); | ||
998 | send_mos_cmd(serial, MOS_WRITE, number, 0x00, &data); | ||
999 | |||
1000 | data = ((unsigned char)((divisor & 0xff00) >> 8)); | ||
1001 | send_mos_cmd(serial, MOS_WRITE, number, 0x01, &data); | ||
1002 | |||
1003 | /* Disable access to divisor latch */ | ||
1004 | data = mos7720_port->shadowLCR & ~UART_LCR_DLAB; | ||
1005 | mos7720_port->shadowLCR = data; | ||
1006 | send_mos_cmd(serial, MOS_WRITE, number, 0x03, &data); | ||
1007 | |||
1008 | return status; | ||
1009 | } | ||
1010 | |||
1011 | /* | ||
1012 | * change_port_settings | ||
1013 | * This routine is called to set the UART on the device to match | ||
1014 | * the specified new settings. | ||
1015 | */ | ||
1016 | static void change_port_settings(struct moschip_port *mos7720_port, | ||
1017 | struct termios *old_termios) | ||
1018 | { | ||
1019 | struct usb_serial_port *port; | ||
1020 | struct usb_serial *serial; | ||
1021 | struct tty_struct *tty; | ||
1022 | int baud; | ||
1023 | unsigned cflag; | ||
1024 | unsigned iflag; | ||
1025 | __u8 mask = 0xff; | ||
1026 | __u8 lData; | ||
1027 | __u8 lParity; | ||
1028 | __u8 lStop; | ||
1029 | int status; | ||
1030 | int port_number; | ||
1031 | char data; | ||
1032 | |||
1033 | if (mos7720_port == NULL) | ||
1034 | return ; | ||
1035 | |||
1036 | port = mos7720_port->port; | ||
1037 | serial = port->serial; | ||
1038 | port_number = port->number - port->serial->minor; | ||
1039 | |||
1040 | dbg("%s - port %d", __FUNCTION__, port->number); | ||
1041 | |||
1042 | if (!mos7720_port->open) { | ||
1043 | dbg("%s - port not opened", __FUNCTION__); | ||
1044 | return; | ||
1045 | } | ||
1046 | |||
1047 | tty = mos7720_port->port->tty; | ||
1048 | |||
1049 | if ((!tty) || (!tty->termios)) { | ||
1050 | dbg("%s - no tty structures", __FUNCTION__); | ||
1051 | return; | ||
1052 | } | ||
1053 | |||
1054 | dbg("%s: Entering ..........", __FUNCTION__); | ||
1055 | |||
1056 | lData = UART_LCR_WLEN8; | ||
1057 | lStop = 0x00; /* 1 stop bit */ | ||
1058 | lParity = 0x00; /* No parity */ | ||
1059 | |||
1060 | cflag = tty->termios->c_cflag; | ||
1061 | iflag = tty->termios->c_iflag; | ||
1062 | |||
1063 | /* Change the number of bits */ | ||
1064 | switch (cflag & CSIZE) { | ||
1065 | case CS5: | ||
1066 | lData = UART_LCR_WLEN5; | ||
1067 | mask = 0x1f; | ||
1068 | break; | ||
1069 | |||
1070 | case CS6: | ||
1071 | lData = UART_LCR_WLEN6; | ||
1072 | mask = 0x3f; | ||
1073 | break; | ||
1074 | |||
1075 | case CS7: | ||
1076 | lData = UART_LCR_WLEN7; | ||
1077 | mask = 0x7f; | ||
1078 | break; | ||
1079 | default: | ||
1080 | case CS8: | ||
1081 | lData = UART_LCR_WLEN8; | ||
1082 | break; | ||
1083 | } | ||
1084 | |||
1085 | /* Change the Parity bit */ | ||
1086 | if (cflag & PARENB) { | ||
1087 | if (cflag & PARODD) { | ||
1088 | lParity = UART_LCR_PARITY; | ||
1089 | dbg("%s - parity = odd", __FUNCTION__); | ||
1090 | } else { | ||
1091 | lParity = (UART_LCR_EPAR | UART_LCR_PARITY); | ||
1092 | dbg("%s - parity = even", __FUNCTION__); | ||
1093 | } | ||
1094 | |||
1095 | } else { | ||
1096 | dbg("%s - parity = none", __FUNCTION__); | ||
1097 | } | ||
1098 | |||
1099 | if (cflag & CMSPAR) | ||
1100 | lParity = lParity | 0x20; | ||
1101 | |||
1102 | /* Change the Stop bit */ | ||
1103 | if (cflag & CSTOPB) { | ||
1104 | lStop = UART_LCR_STOP; | ||
1105 | dbg("%s - stop bits = 2", __FUNCTION__); | ||
1106 | } else { | ||
1107 | lStop = 0x00; | ||
1108 | dbg("%s - stop bits = 1", __FUNCTION__); | ||
1109 | } | ||
1110 | |||
1111 | #define LCR_BITS_MASK 0x03 /* Mask for bits/char field */ | ||
1112 | #define LCR_STOP_MASK 0x04 /* Mask for stop bits field */ | ||
1113 | #define LCR_PAR_MASK 0x38 /* Mask for parity field */ | ||
1114 | |||
1115 | /* Update the LCR with the correct value */ | ||
1116 | mos7720_port->shadowLCR &= ~(LCR_BITS_MASK | LCR_STOP_MASK | LCR_PAR_MASK); | ||
1117 | mos7720_port->shadowLCR |= (lData | lParity | lStop); | ||
1118 | |||
1119 | |||
1120 | /* Disable Interrupts */ | ||
1121 | data = 0x00; | ||
1122 | send_mos_cmd(serial,MOS_WRITE,port->number - port->serial->minor, UART_IER, &data); | ||
1123 | |||
1124 | data = 0x00; | ||
1125 | send_mos_cmd(serial, MOS_WRITE, port_number, UART_FCR, &data); | ||
1126 | |||
1127 | data = 0xcf; | ||
1128 | send_mos_cmd(serial, MOS_WRITE, port_number, UART_FCR, &data); | ||
1129 | |||
1130 | /* Send the updated LCR value to the mos7720 */ | ||
1131 | data = mos7720_port->shadowLCR; | ||
1132 | send_mos_cmd(serial, MOS_WRITE, port_number, UART_LCR, &data); | ||
1133 | |||
1134 | data = 0x00b; | ||
1135 | mos7720_port->shadowMCR = data; | ||
1136 | send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data); | ||
1137 | data = 0x00b; | ||
1138 | send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data); | ||
1139 | |||
1140 | /* set up the MCR register and send it to the mos7720 */ | ||
1141 | mos7720_port->shadowMCR = UART_MCR_OUT2; | ||
1142 | if (cflag & CBAUD) | ||
1143 | mos7720_port->shadowMCR |= (UART_MCR_DTR | UART_MCR_RTS); | ||
1144 | |||
1145 | if (cflag & CRTSCTS) { | ||
1146 | mos7720_port->shadowMCR |= (UART_MCR_XONANY); | ||
1147 | |||
1148 | /* To set hardware flow control to the specified * | ||
1149 | * serial port, in SP1/2_CONTROL_REG */ | ||
1150 | if (port->number) { | ||
1151 | data = 0x001; | ||
1152 | send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, | ||
1153 | 0x08, &data); | ||
1154 | } else { | ||
1155 | data = 0x002; | ||
1156 | send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, | ||
1157 | 0x08, &data); | ||
1158 | } | ||
1159 | } else { | ||
1160 | mos7720_port->shadowMCR &= ~(UART_MCR_XONANY); | ||
1161 | } | ||
1162 | |||
1163 | data = mos7720_port->shadowMCR; | ||
1164 | send_mos_cmd(serial, MOS_WRITE, port_number, UART_MCR, &data); | ||
1165 | |||
1166 | /* Determine divisor based on baud rate */ | ||
1167 | baud = tty_get_baud_rate(tty); | ||
1168 | if (!baud) { | ||
1169 | /* pick a default, any default... */ | ||
1170 | dbg("Picked default baud..."); | ||
1171 | baud = 9600; | ||
1172 | } | ||
1173 | |||
1174 | if (baud >= 230400) { | ||
1175 | set_higher_rates(mos7720_port, baud); | ||
1176 | /* Enable Interrupts */ | ||
1177 | data = 0x0c; | ||
1178 | send_mos_cmd(serial, MOS_WRITE, port_number, UART_IER, &data); | ||
1179 | return; | ||
1180 | } | ||
1181 | |||
1182 | dbg("%s - baud rate = %d", __FUNCTION__, baud); | ||
1183 | status = send_cmd_write_baud_rate(mos7720_port, baud); | ||
1184 | |||
1185 | /* Enable Interrupts */ | ||
1186 | data = 0x0c; | ||
1187 | send_mos_cmd(serial, MOS_WRITE, port_number, UART_IER, &data); | ||
1188 | |||
1189 | if (port->read_urb->status != -EINPROGRESS) { | ||
1190 | port->read_urb->dev = serial->dev; | ||
1191 | |||
1192 | status = usb_submit_urb(port->read_urb, GFP_ATOMIC); | ||
1193 | if (status) | ||
1194 | dbg("usb_submit_urb(read bulk) failed, status = %d", | ||
1195 | status); | ||
1196 | } | ||
1197 | return; | ||
1198 | } | ||
1199 | |||
1200 | /* | ||
1201 | * mos7720_set_termios | ||
1202 | * this function is called by the tty driver when it wants to change the | ||
1203 | * termios structure. | ||
1204 | */ | ||
1205 | static void mos7720_set_termios(struct usb_serial_port *port, | ||
1206 | struct termios *old_termios) | ||
1207 | { | ||
1208 | int status; | ||
1209 | unsigned int cflag; | ||
1210 | struct usb_serial *serial; | ||
1211 | struct moschip_port *mos7720_port; | ||
1212 | struct tty_struct *tty; | ||
1213 | |||
1214 | serial = port->serial; | ||
1215 | |||
1216 | mos7720_port = usb_get_serial_port_data(port); | ||
1217 | |||
1218 | if (mos7720_port == NULL) | ||
1219 | return; | ||
1220 | |||
1221 | tty = port->tty; | ||
1222 | |||
1223 | if (!port->tty || !port->tty->termios) { | ||
1224 | dbg("%s - no tty or termios", __FUNCTION__); | ||
1225 | return; | ||
1226 | } | ||
1227 | |||
1228 | if (!mos7720_port->open) { | ||
1229 | dbg("%s - port not opened", __FUNCTION__); | ||
1230 | return; | ||
1231 | } | ||
1232 | |||
1233 | dbg("%s\n","setting termios - ASPIRE"); | ||
1234 | |||
1235 | cflag = tty->termios->c_cflag; | ||
1236 | |||
1237 | if (!cflag) { | ||
1238 | printk("%s %s\n",__FUNCTION__,"cflag is NULL"); | ||
1239 | return; | ||
1240 | } | ||
1241 | |||
1242 | /* check that they really want us to change something */ | ||
1243 | if (old_termios) { | ||
1244 | if ((cflag == old_termios->c_cflag) && | ||
1245 | (RELEVANT_IFLAG(tty->termios->c_iflag) == | ||
1246 | RELEVANT_IFLAG(old_termios->c_iflag))) { | ||
1247 | dbg("Nothing to change"); | ||
1248 | return; | ||
1249 | } | ||
1250 | } | ||
1251 | |||
1252 | dbg("%s - clfag %08x iflag %08x", __FUNCTION__, | ||
1253 | tty->termios->c_cflag, | ||
1254 | RELEVANT_IFLAG(tty->termios->c_iflag)); | ||
1255 | |||
1256 | if (old_termios) | ||
1257 | dbg("%s - old clfag %08x old iflag %08x", __FUNCTION__, | ||
1258 | old_termios->c_cflag, | ||
1259 | RELEVANT_IFLAG(old_termios->c_iflag)); | ||
1260 | |||
1261 | dbg("%s - port %d", __FUNCTION__, port->number); | ||
1262 | |||
1263 | /* change the port settings to the new ones specified */ | ||
1264 | change_port_settings(mos7720_port, old_termios); | ||
1265 | |||
1266 | if(!port->read_urb) { | ||
1267 | dbg("%s","URB KILLED !!!!!\n"); | ||
1268 | return; | ||
1269 | } | ||
1270 | |||
1271 | if(port->read_urb->status != -EINPROGRESS) { | ||
1272 | port->read_urb->dev = serial->dev; | ||
1273 | status = usb_submit_urb(port->read_urb, GFP_ATOMIC); | ||
1274 | if (status) | ||
1275 | dbg("usb_submit_urb(read bulk) failed, status = %d", | ||
1276 | status); | ||
1277 | } | ||
1278 | return; | ||
1279 | } | ||
1280 | |||
1281 | /* | ||
1282 | * get_lsr_info - get line status register info | ||
1283 | * | ||
1284 | * Purpose: Let user call ioctl() to get info when the UART physically | ||
1285 | * is emptied. On bus types like RS485, the transmitter must | ||
1286 | * release the bus after transmitting. This must be done when | ||
1287 | * the transmit shift register is empty, not be done when the | ||
1288 | * transmit holding register is empty. This functionality | ||
1289 | * allows an RS485 driver to be written in user space. | ||
1290 | */ | ||
1291 | static int get_lsr_info(struct moschip_port *mos7720_port, | ||
1292 | unsigned int __user *value) | ||
1293 | { | ||
1294 | int count; | ||
1295 | unsigned int result = 0; | ||
1296 | |||
1297 | count = mos7720_chars_in_buffer(mos7720_port->port); | ||
1298 | if (count == 0) { | ||
1299 | dbg("%s -- Empty", __FUNCTION__); | ||
1300 | result = TIOCSER_TEMT; | ||
1301 | } | ||
1302 | |||
1303 | if (copy_to_user(value, &result, sizeof(int))) | ||
1304 | return -EFAULT; | ||
1305 | return 0; | ||
1306 | } | ||
1307 | |||
1308 | /* | ||
1309 | * get_number_bytes_avail - get number of bytes available | ||
1310 | * | ||
1311 | * Purpose: Let user call ioctl to get the count of number of bytes available. | ||
1312 | */ | ||
1313 | static int get_number_bytes_avail(struct moschip_port *mos7720_port, | ||
1314 | unsigned int __user *value) | ||
1315 | { | ||
1316 | unsigned int result = 0; | ||
1317 | struct tty_struct *tty = mos7720_port->port->tty; | ||
1318 | |||
1319 | if (!tty) | ||
1320 | return -ENOIOCTLCMD; | ||
1321 | |||
1322 | result = tty->read_cnt; | ||
1323 | |||
1324 | dbg("%s(%d) = %d", __FUNCTION__, mos7720_port->port->number, result); | ||
1325 | if (copy_to_user(value, &result, sizeof(int))) | ||
1326 | return -EFAULT; | ||
1327 | |||
1328 | return -ENOIOCTLCMD; | ||
1329 | } | ||
1330 | |||
1331 | static int set_modem_info(struct moschip_port *mos7720_port, unsigned int cmd, | ||
1332 | unsigned int __user *value) | ||
1333 | { | ||
1334 | unsigned int mcr ; | ||
1335 | unsigned int arg; | ||
1336 | unsigned char data; | ||
1337 | |||
1338 | struct usb_serial_port *port; | ||
1339 | |||
1340 | if (mos7720_port == NULL) | ||
1341 | return -1; | ||
1342 | |||
1343 | port = (struct usb_serial_port*)mos7720_port->port; | ||
1344 | mcr = mos7720_port->shadowMCR; | ||
1345 | |||
1346 | if (copy_from_user(&arg, value, sizeof(int))) | ||
1347 | return -EFAULT; | ||
1348 | |||
1349 | switch (cmd) { | ||
1350 | case TIOCMBIS: | ||
1351 | if (arg & TIOCM_RTS) | ||
1352 | mcr |= UART_MCR_RTS; | ||
1353 | if (arg & TIOCM_DTR) | ||
1354 | mcr |= UART_MCR_RTS; | ||
1355 | if (arg & TIOCM_LOOP) | ||
1356 | mcr |= UART_MCR_LOOP; | ||
1357 | break; | ||
1358 | |||
1359 | case TIOCMBIC: | ||
1360 | if (arg & TIOCM_RTS) | ||
1361 | mcr &= ~UART_MCR_RTS; | ||
1362 | if (arg & TIOCM_DTR) | ||
1363 | mcr &= ~UART_MCR_RTS; | ||
1364 | if (arg & TIOCM_LOOP) | ||
1365 | mcr &= ~UART_MCR_LOOP; | ||
1366 | break; | ||
1367 | |||
1368 | case TIOCMSET: | ||
1369 | /* turn off the RTS and DTR and LOOPBACK | ||
1370 | * and then only turn on what was asked to */ | ||
1371 | mcr &= ~(UART_MCR_RTS | UART_MCR_DTR | UART_MCR_LOOP); | ||
1372 | mcr |= ((arg & TIOCM_RTS) ? UART_MCR_RTS : 0); | ||
1373 | mcr |= ((arg & TIOCM_DTR) ? UART_MCR_DTR : 0); | ||
1374 | mcr |= ((arg & TIOCM_LOOP) ? UART_MCR_LOOP : 0); | ||
1375 | break; | ||
1376 | } | ||
1377 | |||
1378 | mos7720_port->shadowMCR = mcr; | ||
1379 | |||
1380 | data = mos7720_port->shadowMCR; | ||
1381 | send_mos_cmd(port->serial, MOS_WRITE, | ||
1382 | port->number - port->serial->minor, UART_MCR, &data); | ||
1383 | |||
1384 | return 0; | ||
1385 | } | ||
1386 | |||
1387 | static int get_modem_info(struct moschip_port *mos7720_port, | ||
1388 | unsigned int __user *value) | ||
1389 | { | ||
1390 | unsigned int result = 0; | ||
1391 | unsigned int msr = mos7720_port->shadowMSR; | ||
1392 | unsigned int mcr = mos7720_port->shadowMCR; | ||
1393 | |||
1394 | result = ((mcr & UART_MCR_DTR) ? TIOCM_DTR: 0) /* 0x002 */ | ||
1395 | | ((mcr & UART_MCR_RTS) ? TIOCM_RTS: 0) /* 0x004 */ | ||
1396 | | ((msr & UART_MSR_CTS) ? TIOCM_CTS: 0) /* 0x020 */ | ||
1397 | | ((msr & UART_MSR_DCD) ? TIOCM_CAR: 0) /* 0x040 */ | ||
1398 | | ((msr & UART_MSR_RI) ? TIOCM_RI: 0) /* 0x080 */ | ||
1399 | | ((msr & UART_MSR_DSR) ? TIOCM_DSR: 0); /* 0x100 */ | ||
1400 | |||
1401 | |||
1402 | dbg("%s -- %x", __FUNCTION__, result); | ||
1403 | |||
1404 | if (copy_to_user(value, &result, sizeof(int))) | ||
1405 | return -EFAULT; | ||
1406 | return 0; | ||
1407 | } | ||
1408 | |||
1409 | static int get_serial_info(struct moschip_port *mos7720_port, | ||
1410 | struct serial_struct __user *retinfo) | ||
1411 | { | ||
1412 | struct serial_struct tmp; | ||
1413 | |||
1414 | if (!retinfo) | ||
1415 | return -EFAULT; | ||
1416 | |||
1417 | memset(&tmp, 0, sizeof(tmp)); | ||
1418 | |||
1419 | tmp.type = PORT_16550A; | ||
1420 | tmp.line = mos7720_port->port->serial->minor; | ||
1421 | tmp.port = mos7720_port->port->number; | ||
1422 | tmp.irq = 0; | ||
1423 | tmp.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ; | ||
1424 | tmp.xmit_fifo_size = NUM_URBS * URB_TRANSFER_BUFFER_SIZE; | ||
1425 | tmp.baud_base = 9600; | ||
1426 | tmp.close_delay = 5*HZ; | ||
1427 | tmp.closing_wait = 30*HZ; | ||
1428 | |||
1429 | if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) | ||
1430 | return -EFAULT; | ||
1431 | return 0; | ||
1432 | } | ||
1433 | |||
1434 | static int mos7720_ioctl(struct usb_serial_port *port, struct file *file, | ||
1435 | unsigned int cmd, unsigned long arg) | ||
1436 | { | ||
1437 | struct moschip_port *mos7720_port; | ||
1438 | struct async_icount cnow; | ||
1439 | struct async_icount cprev; | ||
1440 | struct serial_icounter_struct icount; | ||
1441 | |||
1442 | mos7720_port = usb_get_serial_port_data(port); | ||
1443 | if (mos7720_port == NULL) | ||
1444 | return -ENODEV; | ||
1445 | |||
1446 | dbg("%s - port %d, cmd = 0x%x", __FUNCTION__, port->number, cmd); | ||
1447 | |||
1448 | switch (cmd) { | ||
1449 | case TIOCINQ: | ||
1450 | /* return number of bytes available */ | ||
1451 | dbg("%s (%d) TIOCINQ", __FUNCTION__, port->number); | ||
1452 | return get_number_bytes_avail(mos7720_port, | ||
1453 | (unsigned int __user *)arg); | ||
1454 | break; | ||
1455 | |||
1456 | case TIOCSERGETLSR: | ||
1457 | dbg("%s (%d) TIOCSERGETLSR", __FUNCTION__, port->number); | ||
1458 | return get_lsr_info(mos7720_port, (unsigned int __user *)arg); | ||
1459 | return 0; | ||
1460 | |||
1461 | case TIOCMBIS: | ||
1462 | case TIOCMBIC: | ||
1463 | case TIOCMSET: | ||
1464 | dbg("%s (%d) TIOCMSET/TIOCMBIC/TIOCMSET", __FUNCTION__, | ||
1465 | port->number); | ||
1466 | return set_modem_info(mos7720_port, cmd, | ||
1467 | (unsigned int __user *)arg); | ||
1468 | |||
1469 | case TIOCMGET: | ||
1470 | dbg("%s (%d) TIOCMGET", __FUNCTION__, port->number); | ||
1471 | return get_modem_info(mos7720_port, | ||
1472 | (unsigned int __user *)arg); | ||
1473 | |||
1474 | case TIOCGSERIAL: | ||
1475 | dbg("%s (%d) TIOCGSERIAL", __FUNCTION__, port->number); | ||
1476 | return get_serial_info(mos7720_port, | ||
1477 | (struct serial_struct __user *)arg); | ||
1478 | |||
1479 | case TIOCSSERIAL: | ||
1480 | dbg("%s (%d) TIOCSSERIAL", __FUNCTION__, port->number); | ||
1481 | break; | ||
1482 | |||
1483 | case TIOCMIWAIT: | ||
1484 | dbg("%s (%d) TIOCMIWAIT", __FUNCTION__, port->number); | ||
1485 | cprev = mos7720_port->icount; | ||
1486 | while (1) { | ||
1487 | if (signal_pending(current)) | ||
1488 | return -ERESTARTSYS; | ||
1489 | cnow = mos7720_port->icount; | ||
1490 | if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && | ||
1491 | cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) | ||
1492 | return -EIO; /* no change => error */ | ||
1493 | if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || | ||
1494 | ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || | ||
1495 | ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || | ||
1496 | ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) { | ||
1497 | return 0; | ||
1498 | } | ||
1499 | cprev = cnow; | ||
1500 | } | ||
1501 | /* NOTREACHED */ | ||
1502 | break; | ||
1503 | |||
1504 | case TIOCGICOUNT: | ||
1505 | cnow = mos7720_port->icount; | ||
1506 | icount.cts = cnow.cts; | ||
1507 | icount.dsr = cnow.dsr; | ||
1508 | icount.rng = cnow.rng; | ||
1509 | icount.dcd = cnow.dcd; | ||
1510 | icount.rx = cnow.rx; | ||
1511 | icount.tx = cnow.tx; | ||
1512 | icount.frame = cnow.frame; | ||
1513 | icount.overrun = cnow.overrun; | ||
1514 | icount.parity = cnow.parity; | ||
1515 | icount.brk = cnow.brk; | ||
1516 | icount.buf_overrun = cnow.buf_overrun; | ||
1517 | |||
1518 | dbg("%s (%d) TIOCGICOUNT RX=%d, TX=%d", __FUNCTION__, | ||
1519 | port->number, icount.rx, icount.tx ); | ||
1520 | if (copy_to_user((void __user *)arg, &icount, sizeof(icount))) | ||
1521 | return -EFAULT; | ||
1522 | return 0; | ||
1523 | } | ||
1524 | |||
1525 | return -ENOIOCTLCMD; | ||
1526 | } | ||
1527 | |||
1528 | static int mos7720_startup(struct usb_serial *serial) | ||
1529 | { | ||
1530 | struct moschip_serial *mos7720_serial; | ||
1531 | struct moschip_port *mos7720_port; | ||
1532 | struct usb_device *dev; | ||
1533 | int i; | ||
1534 | char data; | ||
1535 | |||
1536 | dbg("%s: Entering ..........", __FUNCTION__); | ||
1537 | |||
1538 | if (!serial) { | ||
1539 | dbg("Invalid Handler"); | ||
1540 | return -ENODEV; | ||
1541 | } | ||
1542 | |||
1543 | dev = serial->dev; | ||
1544 | |||
1545 | /* create our private serial structure */ | ||
1546 | mos7720_serial = kzalloc(sizeof(struct moschip_serial), GFP_KERNEL); | ||
1547 | if (mos7720_serial == NULL) { | ||
1548 | err("%s - Out of memory", __FUNCTION__); | ||
1549 | return -ENOMEM; | ||
1550 | } | ||
1551 | |||
1552 | usb_set_serial_data(serial, mos7720_serial); | ||
1553 | |||
1554 | /* we set up the pointers to the endpoints in the mos7720_open * | ||
1555 | * function, as the structures aren't created yet. */ | ||
1556 | |||
1557 | /* set up port private structures */ | ||
1558 | for (i = 0; i < serial->num_ports; ++i) { | ||
1559 | mos7720_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL); | ||
1560 | if (mos7720_port == NULL) { | ||
1561 | err("%s - Out of memory", __FUNCTION__); | ||
1562 | usb_set_serial_data(serial, NULL); | ||
1563 | kfree(mos7720_serial); | ||
1564 | return -ENOMEM; | ||
1565 | } | ||
1566 | |||
1567 | /* Initialize all port interrupt end point to port 0 int | ||
1568 | * endpoint. Our device has only one interrupt endpoint | ||
1569 | * comman to all ports */ | ||
1570 | serial->port[i]->interrupt_in_endpointAddress = serial->port[0]->interrupt_in_endpointAddress; | ||
1571 | |||
1572 | mos7720_port->port = serial->port[i]; | ||
1573 | usb_set_serial_port_data(serial->port[i], mos7720_port); | ||
1574 | |||
1575 | dbg("port number is %d", serial->port[i]->number); | ||
1576 | dbg("serial number is %d", serial->minor); | ||
1577 | } | ||
1578 | |||
1579 | |||
1580 | /* setting configuration feature to one */ | ||
1581 | usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), | ||
1582 | (__u8)0x03, 0x00,0x01,0x00, NULL, 0x00, 5*HZ); | ||
1583 | |||
1584 | send_mos_cmd(serial,MOS_READ,0x00, UART_LSR, &data); // LSR For Port 1 | ||
1585 | dbg("LSR:%x",data); | ||
1586 | |||
1587 | send_mos_cmd(serial,MOS_READ,0x01, UART_LSR, &data); // LSR For Port 2 | ||
1588 | dbg("LSR:%x",data); | ||
1589 | |||
1590 | return 0; | ||
1591 | } | ||
1592 | |||
1593 | static void mos7720_shutdown(struct usb_serial *serial) | ||
1594 | { | ||
1595 | int i; | ||
1596 | |||
1597 | /* free private structure allocated for serial port */ | ||
1598 | for (i=0; i < serial->num_ports; ++i) { | ||
1599 | kfree(usb_get_serial_port_data(serial->port[i])); | ||
1600 | usb_set_serial_port_data(serial->port[i], NULL); | ||
1601 | } | ||
1602 | |||
1603 | /* free private structure allocated for serial device */ | ||
1604 | kfree(usb_get_serial_data(serial)); | ||
1605 | usb_set_serial_data(serial, NULL); | ||
1606 | } | ||
1607 | |||
1608 | static struct usb_serial_driver moschip7720_2port_driver = { | ||
1609 | .driver = { | ||
1610 | .owner = THIS_MODULE, | ||
1611 | .name = "moschip7720", | ||
1612 | }, | ||
1613 | .description = "Moschip 2 port adapter", | ||
1614 | .id_table = moschip_port_id_table, | ||
1615 | .num_interrupt_in = 1, | ||
1616 | .num_bulk_in = 2, | ||
1617 | .num_bulk_out = 2, | ||
1618 | .num_ports = 2, | ||
1619 | .open = mos7720_open, | ||
1620 | .close = mos7720_close, | ||
1621 | .throttle = mos7720_throttle, | ||
1622 | .unthrottle = mos7720_unthrottle, | ||
1623 | .attach = mos7720_startup, | ||
1624 | .shutdown = mos7720_shutdown, | ||
1625 | .ioctl = mos7720_ioctl, | ||
1626 | .set_termios = mos7720_set_termios, | ||
1627 | .write = mos7720_write, | ||
1628 | .write_room = mos7720_write_room, | ||
1629 | .chars_in_buffer = mos7720_chars_in_buffer, | ||
1630 | .break_ctl = mos7720_break, | ||
1631 | .read_bulk_callback = mos7720_bulk_in_callback, | ||
1632 | }; | ||
1633 | |||
1634 | static struct usb_driver usb_driver = { | ||
1635 | .name = "moschip7720", | ||
1636 | .probe = usb_serial_probe, | ||
1637 | .disconnect = usb_serial_disconnect, | ||
1638 | .id_table = moschip_port_id_table, | ||
1639 | }; | ||
1640 | |||
1641 | static int __init moschip7720_init(void) | ||
1642 | { | ||
1643 | int retval; | ||
1644 | |||
1645 | dbg("%s: Entering ..........", __FUNCTION__); | ||
1646 | |||
1647 | /* Register with the usb serial */ | ||
1648 | retval = usb_serial_register(&moschip7720_2port_driver); | ||
1649 | if (retval) | ||
1650 | goto failed_port_device_register; | ||
1651 | |||
1652 | info(DRIVER_DESC " " DRIVER_VERSION); | ||
1653 | |||
1654 | /* Register with the usb */ | ||
1655 | retval = usb_register(&usb_driver); | ||
1656 | if (retval) | ||
1657 | goto failed_usb_register; | ||
1658 | |||
1659 | return 0; | ||
1660 | |||
1661 | failed_usb_register: | ||
1662 | usb_serial_deregister(&moschip7720_2port_driver); | ||
1663 | |||
1664 | failed_port_device_register: | ||
1665 | return retval; | ||
1666 | } | ||
1667 | |||
1668 | static void __exit moschip7720_exit(void) | ||
1669 | { | ||
1670 | usb_deregister(&usb_driver); | ||
1671 | usb_serial_deregister(&moschip7720_2port_driver); | ||
1672 | } | ||
1673 | |||
1674 | module_init(moschip7720_init); | ||
1675 | module_exit(moschip7720_exit); | ||
1676 | |||
1677 | /* Module information */ | ||
1678 | MODULE_AUTHOR( DRIVER_AUTHOR ); | ||
1679 | MODULE_DESCRIPTION( DRIVER_DESC ); | ||
1680 | MODULE_LICENSE("GPL"); | ||
1681 | |||
1682 | module_param(debug, bool, S_IRUGO | S_IWUSR); | ||
1683 | MODULE_PARM_DESC(debug, "Debug enabled or not"); | ||
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 021be39fe16e..5b71962d0351 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c | |||
@@ -2413,11 +2413,12 @@ static int mos7840_ioctl(struct usb_serial_port *port, struct file *file, | |||
2413 | } | 2413 | } |
2414 | 2414 | ||
2415 | mos7840_port = mos7840_get_port_private(port); | 2415 | mos7840_port = mos7840_get_port_private(port); |
2416 | tty = mos7840_port->port->tty; | ||
2417 | 2416 | ||
2418 | if (mos7840_port == NULL) | 2417 | if (mos7840_port == NULL) |
2419 | return -1; | 2418 | return -1; |
2420 | 2419 | ||
2420 | tty = mos7840_port->port->tty; | ||
2421 | |||
2421 | dbg("%s - port %d, cmd = 0x%x", __FUNCTION__, port->number, cmd); | 2422 | dbg("%s - port %d, cmd = 0x%x", __FUNCTION__, port->number, cmd); |
2422 | 2423 | ||
2423 | switch (cmd) { | 2424 | switch (cmd) { |
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index d29638daa987..4b5097fa48d7 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c | |||
@@ -1,75 +1,713 @@ | |||
1 | /* | 1 | /* |
2 | * Sierra Wireless CDMA Wireless Serial USB driver | 2 | USB Driver for Sierra Wireless |
3 | * | 3 | |
4 | * Current Copy modified by: Kevin Lloyd <linux@sierrawireless.com> | 4 | Copyright (C) 2006 Kevin Lloyd <linux@sierrawireless.com> |
5 | * Original Copyright (C) 2005-2006 Greg Kroah-Hartman <gregkh@suse.de> | 5 | |
6 | * | 6 | IMPORTANT DISCLAIMER: This driver is not commercially supported by |
7 | * This program is free software; you can redistribute it and/or | 7 | Sierra Wireless. Use at your own risk. |
8 | * modify it under the terms of the GNU General Public License version | 8 | |
9 | * 2 as published by the Free Software Foundation. | 9 | This driver is free software; you can redistribute it and/or modify |
10 | */ | 10 | it under the terms of Version 2 of the GNU General Public License as |
11 | published by the Free Software Foundation. | ||
12 | |||
13 | Portions based on the option driver by Matthias Urlichs <smurf@smurf.noris.de> | ||
14 | Whom based his on the Keyspan driver by Hugh Blemings <hugh@blemings.org> | ||
15 | |||
16 | History: | ||
17 | */ | ||
18 | |||
19 | #define DRIVER_VERSION "v.1.0.5" | ||
20 | #define DRIVER_AUTHOR "Kevin Lloyd <linux@sierrawireless.com>" | ||
21 | #define DRIVER_DESC "USB Driver for Sierra Wireless USB modems" | ||
11 | 22 | ||
12 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
13 | #include <linux/init.h> | 24 | #include <linux/jiffies.h> |
25 | #include <linux/errno.h> | ||
14 | #include <linux/tty.h> | 26 | #include <linux/tty.h> |
27 | #include <linux/tty_flip.h> | ||
15 | #include <linux/module.h> | 28 | #include <linux/module.h> |
16 | #include <linux/usb.h> | 29 | #include <linux/usb.h> |
17 | #include <linux/usb/serial.h> | 30 | #include <linux/usb/serial.h> |
18 | 31 | ||
32 | |||
19 | static struct usb_device_id id_table [] = { | 33 | static struct usb_device_id id_table [] = { |
20 | { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */ | 34 | { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */ |
21 | { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */ | 35 | { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */ |
22 | { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ | 36 | { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ |
23 | { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */ | 37 | { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */ |
38 | { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ | ||
24 | { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ | 39 | { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ |
25 | { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */ | 40 | { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */ |
41 | { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 for Europe */ | ||
26 | { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 */ | 42 | { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 */ |
27 | { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */ | 43 | { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */ |
28 | /* Following devices are supported in the airprime.c driver */ | 44 | |
29 | /* { USB_DEVICE(0x1199, 0x0112) }, */ /* Sierra Wireless AirCard 580 */ | 45 | { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */ |
30 | /* { USB_DEVICE(0x0F3D, 0x0112) }, */ /* AirPrime/Sierra PC 5220 */ | 46 | { USB_DEVICE(0x0F3D, 0x0112) }, /* AirPrime/Sierra PC 5220 */ |
31 | { } | 47 | { } |
32 | }; | 48 | }; |
33 | MODULE_DEVICE_TABLE(usb, id_table); | 49 | MODULE_DEVICE_TABLE(usb, id_table); |
34 | 50 | ||
51 | static struct usb_device_id id_table_1port [] = { | ||
52 | { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */ | ||
53 | { USB_DEVICE(0x0F3D, 0x0112) }, /* AirPrime/Sierra PC 5220 */ | ||
54 | { } | ||
55 | }; | ||
56 | |||
57 | static struct usb_device_id id_table_3port [] = { | ||
58 | { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */ | ||
59 | { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */ | ||
60 | { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ | ||
61 | { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */ | ||
62 | { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ | ||
63 | { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ | ||
64 | { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */ | ||
65 | { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 for Europe */ | ||
66 | { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 */ | ||
67 | { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */ | ||
68 | { } | ||
69 | }; | ||
70 | |||
35 | static struct usb_driver sierra_driver = { | 71 | static struct usb_driver sierra_driver = { |
36 | .name = "sierra_wireless", | 72 | .name = "sierra", |
37 | .probe = usb_serial_probe, | 73 | .probe = usb_serial_probe, |
38 | .disconnect = usb_serial_disconnect, | 74 | .disconnect = usb_serial_disconnect, |
39 | .id_table = id_table, | 75 | .id_table = id_table, |
76 | .no_dynamic_id = 1, | ||
77 | }; | ||
78 | |||
79 | |||
80 | static int debug; | ||
81 | |||
82 | /* per port private data */ | ||
83 | #define N_IN_URB 4 | ||
84 | #define N_OUT_URB 1 | ||
85 | #define IN_BUFLEN 4096 | ||
86 | #define OUT_BUFLEN 128 | ||
87 | |||
88 | struct sierra_port_private { | ||
89 | /* Input endpoints and buffer for this port */ | ||
90 | struct urb *in_urbs[N_IN_URB]; | ||
91 | char in_buffer[N_IN_URB][IN_BUFLEN]; | ||
92 | /* Output endpoints and buffer for this port */ | ||
93 | struct urb *out_urbs[N_OUT_URB]; | ||
94 | char out_buffer[N_OUT_URB][OUT_BUFLEN]; | ||
95 | |||
96 | /* Settings for the port */ | ||
97 | int rts_state; /* Handshaking pins (outputs) */ | ||
98 | int dtr_state; | ||
99 | int cts_state; /* Handshaking pins (inputs) */ | ||
100 | int dsr_state; | ||
101 | int dcd_state; | ||
102 | int ri_state; | ||
103 | |||
104 | unsigned long tx_start_time[N_OUT_URB]; | ||
105 | }; | ||
106 | |||
107 | static int sierra_send_setup(struct usb_serial_port *port) | ||
108 | { | ||
109 | struct usb_serial *serial = port->serial; | ||
110 | struct sierra_port_private *portdata; | ||
111 | |||
112 | dbg("%s", __FUNCTION__); | ||
113 | |||
114 | portdata = usb_get_serial_port_data(port); | ||
115 | |||
116 | if (port->tty) { | ||
117 | int val = 0; | ||
118 | if (portdata->dtr_state) | ||
119 | val |= 0x01; | ||
120 | if (portdata->rts_state) | ||
121 | val |= 0x02; | ||
122 | |||
123 | return usb_control_msg(serial->dev, | ||
124 | usb_rcvctrlpipe(serial->dev, 0), | ||
125 | 0x22,0x21,val,0,NULL,0,USB_CTRL_SET_TIMEOUT); | ||
126 | } | ||
127 | |||
128 | return 0; | ||
129 | } | ||
130 | |||
131 | static void sierra_rx_throttle(struct usb_serial_port *port) | ||
132 | { | ||
133 | dbg("%s", __FUNCTION__); | ||
134 | } | ||
135 | |||
136 | static void sierra_rx_unthrottle(struct usb_serial_port *port) | ||
137 | { | ||
138 | dbg("%s", __FUNCTION__); | ||
139 | } | ||
140 | |||
141 | static void sierra_break_ctl(struct usb_serial_port *port, int break_state) | ||
142 | { | ||
143 | /* Unfortunately, I don't know how to send a break */ | ||
144 | dbg("%s", __FUNCTION__); | ||
145 | } | ||
146 | |||
147 | static void sierra_set_termios(struct usb_serial_port *port, | ||
148 | struct termios *old_termios) | ||
149 | { | ||
150 | dbg("%s", __FUNCTION__); | ||
151 | |||
152 | sierra_send_setup(port); | ||
153 | } | ||
154 | |||
155 | static int sierra_tiocmget(struct usb_serial_port *port, struct file *file) | ||
156 | { | ||
157 | unsigned int value; | ||
158 | struct sierra_port_private *portdata; | ||
159 | |||
160 | portdata = usb_get_serial_port_data(port); | ||
161 | |||
162 | value = ((portdata->rts_state) ? TIOCM_RTS : 0) | | ||
163 | ((portdata->dtr_state) ? TIOCM_DTR : 0) | | ||
164 | ((portdata->cts_state) ? TIOCM_CTS : 0) | | ||
165 | ((portdata->dsr_state) ? TIOCM_DSR : 0) | | ||
166 | ((portdata->dcd_state) ? TIOCM_CAR : 0) | | ||
167 | ((portdata->ri_state) ? TIOCM_RNG : 0); | ||
168 | |||
169 | return value; | ||
170 | } | ||
171 | |||
172 | static int sierra_tiocmset(struct usb_serial_port *port, struct file *file, | ||
173 | unsigned int set, unsigned int clear) | ||
174 | { | ||
175 | struct sierra_port_private *portdata; | ||
176 | |||
177 | portdata = usb_get_serial_port_data(port); | ||
178 | |||
179 | if (set & TIOCM_RTS) | ||
180 | portdata->rts_state = 1; | ||
181 | if (set & TIOCM_DTR) | ||
182 | portdata->dtr_state = 1; | ||
183 | |||
184 | if (clear & TIOCM_RTS) | ||
185 | portdata->rts_state = 0; | ||
186 | if (clear & TIOCM_DTR) | ||
187 | portdata->dtr_state = 0; | ||
188 | return sierra_send_setup(port); | ||
189 | } | ||
190 | |||
191 | static int sierra_ioctl(struct usb_serial_port *port, struct file *file, | ||
192 | unsigned int cmd, unsigned long arg) | ||
193 | { | ||
194 | return -ENOIOCTLCMD; | ||
195 | } | ||
196 | |||
197 | /* Write */ | ||
198 | static int sierra_write(struct usb_serial_port *port, | ||
199 | const unsigned char *buf, int count) | ||
200 | { | ||
201 | struct sierra_port_private *portdata; | ||
202 | int i; | ||
203 | int left, todo; | ||
204 | struct urb *this_urb = NULL; /* spurious */ | ||
205 | int err; | ||
206 | |||
207 | portdata = usb_get_serial_port_data(port); | ||
208 | |||
209 | dbg("%s: write (%d chars)", __FUNCTION__, count); | ||
210 | |||
211 | i = 0; | ||
212 | left = count; | ||
213 | for (i=0; left > 0 && i < N_OUT_URB; i++) { | ||
214 | todo = left; | ||
215 | if (todo > OUT_BUFLEN) | ||
216 | todo = OUT_BUFLEN; | ||
217 | |||
218 | this_urb = portdata->out_urbs[i]; | ||
219 | if (this_urb->status == -EINPROGRESS) { | ||
220 | if (time_before(jiffies, | ||
221 | portdata->tx_start_time[i] + 10 * HZ)) | ||
222 | continue; | ||
223 | usb_unlink_urb(this_urb); | ||
224 | continue; | ||
225 | } | ||
226 | if (this_urb->status != 0) | ||
227 | dbg("usb_write %p failed (err=%d)", | ||
228 | this_urb, this_urb->status); | ||
229 | |||
230 | dbg("%s: endpoint %d buf %d", __FUNCTION__, | ||
231 | usb_pipeendpoint(this_urb->pipe), i); | ||
232 | |||
233 | /* send the data */ | ||
234 | memcpy (this_urb->transfer_buffer, buf, todo); | ||
235 | this_urb->transfer_buffer_length = todo; | ||
236 | |||
237 | this_urb->dev = port->serial->dev; | ||
238 | err = usb_submit_urb(this_urb, GFP_ATOMIC); | ||
239 | if (err) { | ||
240 | dbg("usb_submit_urb %p (write bulk) failed " | ||
241 | "(%d, has %d)", this_urb, | ||
242 | err, this_urb->status); | ||
243 | continue; | ||
244 | } | ||
245 | portdata->tx_start_time[i] = jiffies; | ||
246 | buf += todo; | ||
247 | left -= todo; | ||
248 | } | ||
249 | |||
250 | count -= left; | ||
251 | dbg("%s: wrote (did %d)", __FUNCTION__, count); | ||
252 | return count; | ||
253 | } | ||
254 | |||
255 | static void sierra_indat_callback(struct urb *urb) | ||
256 | { | ||
257 | int err; | ||
258 | int endpoint; | ||
259 | struct usb_serial_port *port; | ||
260 | struct tty_struct *tty; | ||
261 | unsigned char *data = urb->transfer_buffer; | ||
262 | |||
263 | dbg("%s: %p", __FUNCTION__, urb); | ||
264 | |||
265 | endpoint = usb_pipeendpoint(urb->pipe); | ||
266 | port = (struct usb_serial_port *) urb->context; | ||
267 | |||
268 | if (urb->status) { | ||
269 | dbg("%s: nonzero status: %d on endpoint %02x.", | ||
270 | __FUNCTION__, urb->status, endpoint); | ||
271 | } else { | ||
272 | tty = port->tty; | ||
273 | if (urb->actual_length) { | ||
274 | tty_buffer_request_room(tty, urb->actual_length); | ||
275 | tty_insert_flip_string(tty, data, urb->actual_length); | ||
276 | tty_flip_buffer_push(tty); | ||
277 | } else { | ||
278 | dbg("%s: empty read urb received", __FUNCTION__); | ||
279 | } | ||
280 | |||
281 | /* Resubmit urb so we continue receiving */ | ||
282 | if (port->open_count && urb->status != -ESHUTDOWN) { | ||
283 | err = usb_submit_urb(urb, GFP_ATOMIC); | ||
284 | if (err) | ||
285 | printk(KERN_ERR "%s: resubmit read urb failed. " | ||
286 | "(%d)", __FUNCTION__, err); | ||
287 | } | ||
288 | } | ||
289 | return; | ||
290 | } | ||
291 | |||
292 | static void sierra_outdat_callback(struct urb *urb) | ||
293 | { | ||
294 | struct usb_serial_port *port; | ||
295 | |||
296 | dbg("%s", __FUNCTION__); | ||
297 | |||
298 | port = (struct usb_serial_port *) urb->context; | ||
299 | |||
300 | usb_serial_port_softint(port); | ||
301 | } | ||
302 | |||
303 | static void sierra_instat_callback(struct urb *urb) | ||
304 | { | ||
305 | int err; | ||
306 | struct usb_serial_port *port = (struct usb_serial_port *) urb->context; | ||
307 | struct sierra_port_private *portdata = usb_get_serial_port_data(port); | ||
308 | struct usb_serial *serial = port->serial; | ||
309 | |||
310 | dbg("%s", __FUNCTION__); | ||
311 | dbg("%s: urb %p port %p has data %p", __FUNCTION__,urb,port,portdata); | ||
312 | |||
313 | if (urb->status == 0) { | ||
314 | struct usb_ctrlrequest *req_pkt = | ||
315 | (struct usb_ctrlrequest *)urb->transfer_buffer; | ||
316 | |||
317 | if (!req_pkt) { | ||
318 | dbg("%s: NULL req_pkt\n", __FUNCTION__); | ||
319 | return; | ||
320 | } | ||
321 | if ((req_pkt->bRequestType == 0xA1) && | ||
322 | (req_pkt->bRequest == 0x20)) { | ||
323 | int old_dcd_state; | ||
324 | unsigned char signals = *((unsigned char *) | ||
325 | urb->transfer_buffer + | ||
326 | sizeof(struct usb_ctrlrequest)); | ||
327 | |||
328 | dbg("%s: signal x%x", __FUNCTION__, signals); | ||
329 | |||
330 | old_dcd_state = portdata->dcd_state; | ||
331 | portdata->cts_state = 1; | ||
332 | portdata->dcd_state = ((signals & 0x01) ? 1 : 0); | ||
333 | portdata->dsr_state = ((signals & 0x02) ? 1 : 0); | ||
334 | portdata->ri_state = ((signals & 0x08) ? 1 : 0); | ||
335 | |||
336 | if (port->tty && !C_CLOCAL(port->tty) && | ||
337 | old_dcd_state && !portdata->dcd_state) | ||
338 | tty_hangup(port->tty); | ||
339 | } else { | ||
340 | dbg("%s: type %x req %x", __FUNCTION__, | ||
341 | req_pkt->bRequestType,req_pkt->bRequest); | ||
342 | } | ||
343 | } else | ||
344 | dbg("%s: error %d", __FUNCTION__, urb->status); | ||
345 | |||
346 | /* Resubmit urb so we continue receiving IRQ data */ | ||
347 | if (urb->status != -ESHUTDOWN) { | ||
348 | urb->dev = serial->dev; | ||
349 | err = usb_submit_urb(urb, GFP_ATOMIC); | ||
350 | if (err) | ||
351 | dbg("%s: resubmit intr urb failed. (%d)", | ||
352 | __FUNCTION__, err); | ||
353 | } | ||
354 | } | ||
355 | |||
356 | static int sierra_write_room(struct usb_serial_port *port) | ||
357 | { | ||
358 | struct sierra_port_private *portdata; | ||
359 | int i; | ||
360 | int data_len = 0; | ||
361 | struct urb *this_urb; | ||
362 | |||
363 | portdata = usb_get_serial_port_data(port); | ||
364 | |||
365 | for (i=0; i < N_OUT_URB; i++) { | ||
366 | this_urb = portdata->out_urbs[i]; | ||
367 | if (this_urb && this_urb->status != -EINPROGRESS) | ||
368 | data_len += OUT_BUFLEN; | ||
369 | } | ||
370 | |||
371 | dbg("%s: %d", __FUNCTION__, data_len); | ||
372 | return data_len; | ||
373 | } | ||
374 | |||
375 | static int sierra_chars_in_buffer(struct usb_serial_port *port) | ||
376 | { | ||
377 | struct sierra_port_private *portdata; | ||
378 | int i; | ||
379 | int data_len = 0; | ||
380 | struct urb *this_urb; | ||
381 | |||
382 | portdata = usb_get_serial_port_data(port); | ||
383 | |||
384 | for (i=0; i < N_OUT_URB; i++) { | ||
385 | this_urb = portdata->out_urbs[i]; | ||
386 | if (this_urb && this_urb->status == -EINPROGRESS) | ||
387 | data_len += this_urb->transfer_buffer_length; | ||
388 | } | ||
389 | dbg("%s: %d", __FUNCTION__, data_len); | ||
390 | return data_len; | ||
391 | } | ||
392 | |||
393 | static int sierra_open(struct usb_serial_port *port, struct file *filp) | ||
394 | { | ||
395 | struct sierra_port_private *portdata; | ||
396 | struct usb_serial *serial = port->serial; | ||
397 | int i, err; | ||
398 | struct urb *urb; | ||
399 | |||
400 | portdata = usb_get_serial_port_data(port); | ||
401 | |||
402 | dbg("%s", __FUNCTION__); | ||
403 | |||
404 | /* Set some sane defaults */ | ||
405 | portdata->rts_state = 1; | ||
406 | portdata->dtr_state = 1; | ||
407 | |||
408 | /* Reset low level data toggle and start reading from endpoints */ | ||
409 | for (i = 0; i < N_IN_URB; i++) { | ||
410 | urb = portdata->in_urbs[i]; | ||
411 | if (! urb) | ||
412 | continue; | ||
413 | if (urb->dev != serial->dev) { | ||
414 | dbg("%s: dev %p != %p", __FUNCTION__, | ||
415 | urb->dev, serial->dev); | ||
416 | continue; | ||
417 | } | ||
418 | |||
419 | /* | ||
420 | * make sure endpoint data toggle is synchronized with the | ||
421 | * device | ||
422 | */ | ||
423 | usb_clear_halt(urb->dev, urb->pipe); | ||
424 | |||
425 | err = usb_submit_urb(urb, GFP_KERNEL); | ||
426 | if (err) { | ||
427 | dbg("%s: submit urb %d failed (%d) %d", | ||
428 | __FUNCTION__, i, err, | ||
429 | urb->transfer_buffer_length); | ||
430 | } | ||
431 | } | ||
432 | |||
433 | /* Reset low level data toggle on out endpoints */ | ||
434 | for (i = 0; i < N_OUT_URB; i++) { | ||
435 | urb = portdata->out_urbs[i]; | ||
436 | if (! urb) | ||
437 | continue; | ||
438 | urb->dev = serial->dev; | ||
439 | /* usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), | ||
440 | usb_pipeout(urb->pipe), 0); */ | ||
441 | } | ||
442 | |||
443 | port->tty->low_latency = 1; | ||
444 | |||
445 | sierra_send_setup(port); | ||
446 | |||
447 | return (0); | ||
448 | } | ||
449 | |||
450 | static inline void stop_urb(struct urb *urb) | ||
451 | { | ||
452 | if (urb && urb->status == -EINPROGRESS) | ||
453 | usb_kill_urb(urb); | ||
454 | } | ||
455 | |||
456 | static void sierra_close(struct usb_serial_port *port, struct file *filp) | ||
457 | { | ||
458 | int i; | ||
459 | struct usb_serial *serial = port->serial; | ||
460 | struct sierra_port_private *portdata; | ||
461 | |||
462 | dbg("%s", __FUNCTION__); | ||
463 | portdata = usb_get_serial_port_data(port); | ||
464 | |||
465 | portdata->rts_state = 0; | ||
466 | portdata->dtr_state = 0; | ||
467 | |||
468 | if (serial->dev) { | ||
469 | sierra_send_setup(port); | ||
470 | |||
471 | /* Stop reading/writing urbs */ | ||
472 | for (i = 0; i < N_IN_URB; i++) | ||
473 | stop_urb(portdata->in_urbs[i]); | ||
474 | for (i = 0; i < N_OUT_URB; i++) | ||
475 | stop_urb(portdata->out_urbs[i]); | ||
476 | } | ||
477 | port->tty = NULL; | ||
478 | } | ||
479 | |||
480 | /* Helper functions used by sierra_setup_urbs */ | ||
481 | static struct urb *sierra_setup_urb(struct usb_serial *serial, int endpoint, | ||
482 | int dir, void *ctx, char *buf, int len, | ||
483 | usb_complete_t callback) | ||
484 | { | ||
485 | struct urb *urb; | ||
486 | |||
487 | if (endpoint == -1) | ||
488 | return NULL; /* endpoint not needed */ | ||
489 | |||
490 | urb = usb_alloc_urb(0, GFP_KERNEL); /* No ISO */ | ||
491 | if (urb == NULL) { | ||
492 | dbg("%s: alloc for endpoint %d failed.", __FUNCTION__, endpoint); | ||
493 | return NULL; | ||
494 | } | ||
495 | |||
496 | /* Fill URB using supplied data. */ | ||
497 | usb_fill_bulk_urb(urb, serial->dev, | ||
498 | usb_sndbulkpipe(serial->dev, endpoint) | dir, | ||
499 | buf, len, callback, ctx); | ||
500 | |||
501 | return urb; | ||
502 | } | ||
503 | |||
504 | /* Setup urbs */ | ||
505 | static void sierra_setup_urbs(struct usb_serial *serial) | ||
506 | { | ||
507 | int i,j; | ||
508 | struct usb_serial_port *port; | ||
509 | struct sierra_port_private *portdata; | ||
510 | |||
511 | dbg("%s", __FUNCTION__); | ||
512 | |||
513 | for (i = 0; i < serial->num_ports; i++) { | ||
514 | port = serial->port[i]; | ||
515 | portdata = usb_get_serial_port_data(port); | ||
516 | |||
517 | /* Do indat endpoints first */ | ||
518 | for (j = 0; j < N_IN_URB; ++j) { | ||
519 | portdata->in_urbs[j] = sierra_setup_urb (serial, | ||
520 | port->bulk_in_endpointAddress, USB_DIR_IN, port, | ||
521 | portdata->in_buffer[j], IN_BUFLEN, sierra_indat_callback); | ||
522 | } | ||
523 | |||
524 | /* outdat endpoints */ | ||
525 | for (j = 0; j < N_OUT_URB; ++j) { | ||
526 | portdata->out_urbs[j] = sierra_setup_urb (serial, | ||
527 | port->bulk_out_endpointAddress, USB_DIR_OUT, port, | ||
528 | portdata->out_buffer[j], OUT_BUFLEN, sierra_outdat_callback); | ||
529 | } | ||
530 | } | ||
531 | } | ||
532 | |||
533 | static int sierra_startup(struct usb_serial *serial) | ||
534 | { | ||
535 | int i, err; | ||
536 | struct usb_serial_port *port; | ||
537 | struct sierra_port_private *portdata; | ||
538 | |||
539 | dbg("%s", __FUNCTION__); | ||
540 | |||
541 | /* Now setup per port private data */ | ||
542 | for (i = 0; i < serial->num_ports; i++) { | ||
543 | port = serial->port[i]; | ||
544 | portdata = kzalloc(sizeof(*portdata), GFP_KERNEL); | ||
545 | if (!portdata) { | ||
546 | dbg("%s: kmalloc for sierra_port_private (%d) failed!.", | ||
547 | __FUNCTION__, i); | ||
548 | return (1); | ||
549 | } | ||
550 | |||
551 | usb_set_serial_port_data(port, portdata); | ||
552 | |||
553 | if (! port->interrupt_in_urb) | ||
554 | continue; | ||
555 | err = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); | ||
556 | if (err) | ||
557 | dbg("%s: submit irq_in urb failed %d", | ||
558 | __FUNCTION__, err); | ||
559 | } | ||
560 | |||
561 | sierra_setup_urbs(serial); | ||
562 | |||
563 | return (0); | ||
564 | } | ||
565 | |||
566 | static void sierra_shutdown(struct usb_serial *serial) | ||
567 | { | ||
568 | int i, j; | ||
569 | struct usb_serial_port *port; | ||
570 | struct sierra_port_private *portdata; | ||
571 | |||
572 | dbg("%s", __FUNCTION__); | ||
573 | |||
574 | /* Stop reading/writing urbs */ | ||
575 | for (i = 0; i < serial->num_ports; ++i) { | ||
576 | port = serial->port[i]; | ||
577 | portdata = usb_get_serial_port_data(port); | ||
578 | for (j = 0; j < N_IN_URB; j++) | ||
579 | stop_urb(portdata->in_urbs[j]); | ||
580 | for (j = 0; j < N_OUT_URB; j++) | ||
581 | stop_urb(portdata->out_urbs[j]); | ||
582 | } | ||
583 | |||
584 | /* Now free them */ | ||
585 | for (i = 0; i < serial->num_ports; ++i) { | ||
586 | port = serial->port[i]; | ||
587 | portdata = usb_get_serial_port_data(port); | ||
588 | |||
589 | for (j = 0; j < N_IN_URB; j++) { | ||
590 | if (portdata->in_urbs[j]) { | ||
591 | usb_free_urb(portdata->in_urbs[j]); | ||
592 | portdata->in_urbs[j] = NULL; | ||
593 | } | ||
594 | } | ||
595 | for (j = 0; j < N_OUT_URB; j++) { | ||
596 | if (portdata->out_urbs[j]) { | ||
597 | usb_free_urb(portdata->out_urbs[j]); | ||
598 | portdata->out_urbs[j] = NULL; | ||
599 | } | ||
600 | } | ||
601 | } | ||
602 | |||
603 | /* Now free per port private data */ | ||
604 | for (i = 0; i < serial->num_ports; i++) { | ||
605 | port = serial->port[i]; | ||
606 | kfree(usb_get_serial_port_data(port)); | ||
607 | } | ||
608 | } | ||
609 | |||
610 | static struct usb_serial_driver sierra_1port_device = { | ||
611 | .driver = { | ||
612 | .owner = THIS_MODULE, | ||
613 | .name = "sierra1", | ||
614 | }, | ||
615 | .description = "Sierra USB modem (1 port)", | ||
616 | .id_table = id_table_1port, | ||
617 | .num_interrupt_in = NUM_DONT_CARE, | ||
618 | .num_bulk_in = 1, | ||
619 | .num_bulk_out = 1, | ||
620 | .num_ports = 1, | ||
621 | .open = sierra_open, | ||
622 | .close = sierra_close, | ||
623 | .write = sierra_write, | ||
624 | .write_room = sierra_write_room, | ||
625 | .chars_in_buffer = sierra_chars_in_buffer, | ||
626 | .throttle = sierra_rx_throttle, | ||
627 | .unthrottle = sierra_rx_unthrottle, | ||
628 | .ioctl = sierra_ioctl, | ||
629 | .set_termios = sierra_set_termios, | ||
630 | .break_ctl = sierra_break_ctl, | ||
631 | .tiocmget = sierra_tiocmget, | ||
632 | .tiocmset = sierra_tiocmset, | ||
633 | .attach = sierra_startup, | ||
634 | .shutdown = sierra_shutdown, | ||
635 | .read_int_callback = sierra_instat_callback, | ||
40 | }; | 636 | }; |
41 | 637 | ||
42 | static struct usb_serial_driver sierra_device = { | 638 | static struct usb_serial_driver sierra_3port_device = { |
43 | .driver = { | 639 | .driver = { |
44 | .owner = THIS_MODULE, | 640 | .owner = THIS_MODULE, |
45 | .name = "Sierra_Wireless", | 641 | .name = "sierra3", |
46 | }, | 642 | }, |
47 | .id_table = id_table, | 643 | .description = "Sierra USB modem (3 port)", |
48 | .num_interrupt_in = NUM_DONT_CARE, | 644 | .id_table = id_table_3port, |
49 | .num_bulk_in = NUM_DONT_CARE, | 645 | .num_interrupt_in = NUM_DONT_CARE, |
50 | .num_bulk_out = NUM_DONT_CARE, | 646 | .num_bulk_in = 3, |
51 | .num_ports = 3, | 647 | .num_bulk_out = 3, |
648 | .num_ports = 3, | ||
649 | .open = sierra_open, | ||
650 | .close = sierra_close, | ||
651 | .write = sierra_write, | ||
652 | .write_room = sierra_write_room, | ||
653 | .chars_in_buffer = sierra_chars_in_buffer, | ||
654 | .throttle = sierra_rx_throttle, | ||
655 | .unthrottle = sierra_rx_unthrottle, | ||
656 | .ioctl = sierra_ioctl, | ||
657 | .set_termios = sierra_set_termios, | ||
658 | .break_ctl = sierra_break_ctl, | ||
659 | .tiocmget = sierra_tiocmget, | ||
660 | .tiocmset = sierra_tiocmset, | ||
661 | .attach = sierra_startup, | ||
662 | .shutdown = sierra_shutdown, | ||
663 | .read_int_callback = sierra_instat_callback, | ||
52 | }; | 664 | }; |
53 | 665 | ||
666 | /* Functions used by new usb-serial code. */ | ||
54 | static int __init sierra_init(void) | 667 | static int __init sierra_init(void) |
55 | { | 668 | { |
56 | int retval; | 669 | int retval; |
57 | 670 | retval = usb_serial_register(&sierra_1port_device); | |
58 | retval = usb_serial_register(&sierra_device); | 671 | if (retval) |
672 | goto failed_1port_device_register; | ||
673 | retval = usb_serial_register(&sierra_3port_device); | ||
59 | if (retval) | 674 | if (retval) |
60 | return retval; | 675 | goto failed_3port_device_register; |
676 | |||
677 | |||
61 | retval = usb_register(&sierra_driver); | 678 | retval = usb_register(&sierra_driver); |
62 | if (retval) | 679 | if (retval) |
63 | usb_serial_deregister(&sierra_device); | 680 | goto failed_driver_register; |
681 | |||
682 | info(DRIVER_DESC ": " DRIVER_VERSION); | ||
683 | |||
684 | return 0; | ||
685 | |||
686 | failed_driver_register: | ||
687 | usb_serial_deregister(&sierra_3port_device); | ||
688 | failed_3port_device_register: | ||
689 | usb_serial_deregister(&sierra_1port_device); | ||
690 | failed_1port_device_register: | ||
64 | return retval; | 691 | return retval; |
65 | } | 692 | } |
66 | 693 | ||
67 | static void __exit sierra_exit(void) | 694 | static void __exit sierra_exit(void) |
68 | { | 695 | { |
69 | usb_deregister(&sierra_driver); | 696 | usb_deregister (&sierra_driver); |
70 | usb_serial_deregister(&sierra_device); | 697 | usb_serial_deregister(&sierra_1port_device); |
698 | usb_serial_deregister(&sierra_3port_device); | ||
71 | } | 699 | } |
72 | 700 | ||
73 | module_init(sierra_init); | 701 | module_init(sierra_init); |
74 | module_exit(sierra_exit); | 702 | module_exit(sierra_exit); |
703 | |||
704 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
705 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
706 | MODULE_VERSION(DRIVER_VERSION); | ||
75 | MODULE_LICENSE("GPL"); | 707 | MODULE_LICENSE("GPL"); |
708 | |||
709 | #ifdef CONFIG_USB_DEBUG | ||
710 | module_param(debug, bool, S_IRUGO | S_IWUSR); | ||
711 | MODULE_PARM_DESC(debug, "Debug messages"); | ||
712 | #endif | ||
713 | |||
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index c9a8d50106d1..efb047f431e8 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
@@ -55,7 +55,8 @@ UNUSUAL_DEV( 0x03eb, 0x2002, 0x0100, 0x0100, | |||
55 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 55 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
56 | US_FL_IGNORE_RESIDUE), | 56 | US_FL_IGNORE_RESIDUE), |
57 | 57 | ||
58 | UNUSUAL_DEV( 0x03ee, 0x6901, 0x0000, 0x0100, | 58 | /* modified by Tobias Lorenz <tobias.lorenz@gmx.net> */ |
59 | UNUSUAL_DEV( 0x03ee, 0x6901, 0x0000, 0x0200, | ||
59 | "Mitsumi", | 60 | "Mitsumi", |
60 | "USB FDD", | 61 | "USB FDD", |
61 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 62 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
@@ -182,6 +183,20 @@ UNUSUAL_DEV( 0x0421, 0x044e, 0x0100, 0x0100, | |||
182 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 183 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
183 | US_FL_IGNORE_RESIDUE | US_FL_FIX_CAPACITY ), | 184 | US_FL_IGNORE_RESIDUE | US_FL_FIX_CAPACITY ), |
184 | 185 | ||
186 | /* Reported by Bardur Arantsson <bardur@scientician.net> */ | ||
187 | UNUSUAL_DEV( 0x0421, 0x047c, 0x0370, 0x0370, | ||
188 | "Nokia", | ||
189 | "6131", | ||
190 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
191 | US_FL_MAX_SECTORS_64 ), | ||
192 | |||
193 | /* Reported by Alex Corcoles <alex@corcoles.net> */ | ||
194 | UNUSUAL_DEV( 0x0421, 0x0495, 0x0370, 0x0370, | ||
195 | "Nokia", | ||
196 | "6234", | ||
197 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
198 | US_FL_MAX_SECTORS_64 ), | ||
199 | |||
185 | /* Reported by Olaf Hering <olh@suse.de> from novell bug #105878 */ | 200 | /* Reported by Olaf Hering <olh@suse.de> from novell bug #105878 */ |
186 | UNUSUAL_DEV( 0x0424, 0x0fdc, 0x0210, 0x0210, | 201 | UNUSUAL_DEV( 0x0424, 0x0fdc, 0x0210, 0x0210, |
187 | "SMSC", | 202 | "SMSC", |
@@ -1221,7 +1236,7 @@ UNUSUAL_DEV( 0x0e21, 0x0520, 0x0100, 0x0100, | |||
1221 | "Cowon Systems", | 1236 | "Cowon Systems", |
1222 | "iAUDIO M5", | 1237 | "iAUDIO M5", |
1223 | US_SC_DEVICE, US_PR_BULK, NULL, | 1238 | US_SC_DEVICE, US_PR_BULK, NULL, |
1224 | 0 ), | 1239 | US_FL_NEED_OVERRIDE ), |
1225 | 1240 | ||
1226 | /* Submitted by Antoine Mairesse <antoine.mairesse@free.fr> */ | 1241 | /* Submitted by Antoine Mairesse <antoine.mairesse@free.fr> */ |
1227 | UNUSUAL_DEV( 0x0ed1, 0x6660, 0x0100, 0x0300, | 1242 | UNUSUAL_DEV( 0x0ed1, 0x6660, 0x0100, 0x0300, |
@@ -1294,8 +1309,10 @@ UNUSUAL_DEV( 0x0fce, 0xe030, 0x0000, 0x0000, | |||
1294 | /* Reported by Kevin Cernekee <kpc-usbdev@gelato.uiuc.edu> | 1309 | /* Reported by Kevin Cernekee <kpc-usbdev@gelato.uiuc.edu> |
1295 | * Tested on hardware version 1.10. | 1310 | * Tested on hardware version 1.10. |
1296 | * Entry is needed only for the initializer function override. | 1311 | * Entry is needed only for the initializer function override. |
1312 | * Devices with bcd > 110 seem to not need it while those | ||
1313 | * with bcd < 110 appear to need it. | ||
1297 | */ | 1314 | */ |
1298 | UNUSUAL_DEV( 0x1019, 0x0c55, 0x0110, 0x0110, | 1315 | UNUSUAL_DEV( 0x1019, 0x0c55, 0x0000, 0x0110, |
1299 | "Desknote", | 1316 | "Desknote", |
1300 | "UCR-61S2B", | 1317 | "UCR-61S2B", |
1301 | US_SC_DEVICE, US_PR_DEVICE, usb_stor_ucr61s2b_init, | 1318 | US_SC_DEVICE, US_PR_DEVICE, usb_stor_ucr61s2b_init, |
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index daaa486159cf..7a43020fa583 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig | |||
@@ -701,7 +701,6 @@ config FB_NVIDIA | |||
701 | depends on FB && PCI | 701 | depends on FB && PCI |
702 | select I2C_ALGOBIT if FB_NVIDIA_I2C | 702 | select I2C_ALGOBIT if FB_NVIDIA_I2C |
703 | select I2C if FB_NVIDIA_I2C | 703 | select I2C if FB_NVIDIA_I2C |
704 | select FB_DDC if FB_NVIDIA_I2C | ||
705 | select FB_MODE_HELPERS | 704 | select FB_MODE_HELPERS |
706 | select FB_CFB_FILLRECT | 705 | select FB_CFB_FILLRECT |
707 | select FB_CFB_COPYAREA | 706 | select FB_CFB_COPYAREA |
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c index b77b30923928..e815b354c09d 100644 --- a/drivers/video/aty/atyfb_base.c +++ b/drivers/video/aty/atyfb_base.c | |||
@@ -406,7 +406,7 @@ static struct { | |||
406 | { PCI_CHIP_MACH64LB, "3D RAGE LT PRO (Mach64 LB, AGP)", 236, 75, 100, 135, ATI_CHIP_264LTPRO }, | 406 | { PCI_CHIP_MACH64LB, "3D RAGE LT PRO (Mach64 LB, AGP)", 236, 75, 100, 135, ATI_CHIP_264LTPRO }, |
407 | { PCI_CHIP_MACH64LD, "3D RAGE LT PRO (Mach64 LD, AGP)", 230, 100, 100, 135, ATI_CHIP_264LTPRO }, | 407 | { PCI_CHIP_MACH64LD, "3D RAGE LT PRO (Mach64 LD, AGP)", 230, 100, 100, 135, ATI_CHIP_264LTPRO }, |
408 | { PCI_CHIP_MACH64LI, "3D RAGE LT PRO (Mach64 LI, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO | M64F_G3_PB_1_1 | M64F_G3_PB_1024x768 }, | 408 | { PCI_CHIP_MACH64LI, "3D RAGE LT PRO (Mach64 LI, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO | M64F_G3_PB_1_1 | M64F_G3_PB_1024x768 }, |
409 | { PCI_CHIP_MACH64LP, "3D RAGE LT PRO (Mach64 LP, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO }, | 409 | { PCI_CHIP_MACH64LP, "3D RAGE LT PRO (Mach64 LP, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO | M64F_G3_PB_1024x768 }, |
410 | { PCI_CHIP_MACH64LQ, "3D RAGE LT PRO (Mach64 LQ, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO }, | 410 | { PCI_CHIP_MACH64LQ, "3D RAGE LT PRO (Mach64 LQ, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO }, |
411 | 411 | ||
412 | { PCI_CHIP_MACH64GM, "3D RAGE XL (Mach64 GM, AGP 2x)", 230, 83, 63, 135, ATI_CHIP_264XL }, | 412 | { PCI_CHIP_MACH64GM, "3D RAGE XL (Mach64 GM, AGP 2x)", 230, 83, 63, 135, ATI_CHIP_264XL }, |
diff --git a/drivers/video/aty/radeon_i2c.c b/drivers/video/aty/radeon_i2c.c index 676754520099..869725a13c21 100644 --- a/drivers/video/aty/radeon_i2c.c +++ b/drivers/video/aty/radeon_i2c.c | |||
@@ -139,7 +139,13 @@ void radeon_delete_i2c_busses(struct radeonfb_info *rinfo) | |||
139 | int radeon_probe_i2c_connector(struct radeonfb_info *rinfo, int conn, | 139 | int radeon_probe_i2c_connector(struct radeonfb_info *rinfo, int conn, |
140 | u8 **out_edid) | 140 | u8 **out_edid) |
141 | { | 141 | { |
142 | u8 *edid = fb_ddc_read(&rinfo->i2c[conn-1].adapter); | 142 | u32 reg = rinfo->i2c[conn-1].ddc_reg; |
143 | u8 *edid; | ||
144 | |||
145 | OUTREG(reg, INREG(reg) & | ||
146 | ~(VGA_DDC_DATA_OUTPUT | VGA_DDC_CLK_OUTPUT)); | ||
147 | |||
148 | edid = fb_ddc_read(&rinfo->i2c[conn-1].adapter); | ||
143 | 149 | ||
144 | if (out_edid) | 150 | if (out_edid) |
145 | *out_edid = edid; | 151 | *out_edid = edid; |
diff --git a/drivers/video/backlight/corgi_bl.c b/drivers/video/backlight/corgi_bl.c index 2ebbfd95145f..d07ecb53c68b 100644 --- a/drivers/video/backlight/corgi_bl.c +++ b/drivers/video/backlight/corgi_bl.c | |||
@@ -111,7 +111,7 @@ static struct backlight_properties corgibl_data = { | |||
111 | .update_status = corgibl_set_intensity, | 111 | .update_status = corgibl_set_intensity, |
112 | }; | 112 | }; |
113 | 113 | ||
114 | static int __init corgibl_probe(struct platform_device *pdev) | 114 | static int corgibl_probe(struct platform_device *pdev) |
115 | { | 115 | { |
116 | struct corgibl_machinfo *machinfo = pdev->dev.platform_data; | 116 | struct corgibl_machinfo *machinfo = pdev->dev.platform_data; |
117 | 117 | ||
@@ -166,4 +166,4 @@ module_exit(corgibl_exit); | |||
166 | 166 | ||
167 | MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>"); | 167 | MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>"); |
168 | MODULE_DESCRIPTION("Corgi Backlight Driver"); | 168 | MODULE_DESCRIPTION("Corgi Backlight Driver"); |
169 | MODULE_LICENSE("GPLv2"); | 169 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/video/backlight/hp680_bl.c b/drivers/video/backlight/hp680_bl.c index fe1488374f62..e3993213d10e 100644 --- a/drivers/video/backlight/hp680_bl.c +++ b/drivers/video/backlight/hp680_bl.c | |||
@@ -19,7 +19,7 @@ | |||
19 | #include <linux/backlight.h> | 19 | #include <linux/backlight.h> |
20 | 20 | ||
21 | #include <asm/cpu/dac.h> | 21 | #include <asm/cpu/dac.h> |
22 | #include <asm/hp6xx/hp6xx.h> | 22 | #include <asm/hp6xx.h> |
23 | #include <asm/hd64461.h> | 23 | #include <asm/hd64461.h> |
24 | 24 | ||
25 | #define HP680_MAX_INTENSITY 255 | 25 | #define HP680_MAX_INTENSITY 255 |
diff --git a/drivers/video/controlfb.c b/drivers/video/controlfb.c index 8cc6c0e2d27a..04c6d928189b 100644 --- a/drivers/video/controlfb.c +++ b/drivers/video/controlfb.c | |||
@@ -415,13 +415,15 @@ static int __init init_control(struct fb_info_control *p) | |||
415 | full = p->total_vram == 0x400000; | 415 | full = p->total_vram == 0x400000; |
416 | 416 | ||
417 | /* Try to pick a video mode out of NVRAM if we have one. */ | 417 | /* Try to pick a video mode out of NVRAM if we have one. */ |
418 | #ifdef CONFIG_NVRAM | ||
418 | if (default_cmode == CMODE_NVRAM){ | 419 | if (default_cmode == CMODE_NVRAM){ |
419 | cmode = nvram_read_byte(NV_CMODE); | 420 | cmode = nvram_read_byte(NV_CMODE); |
420 | if(cmode < CMODE_8 || cmode > CMODE_32) | 421 | if(cmode < CMODE_8 || cmode > CMODE_32) |
421 | cmode = CMODE_8; | 422 | cmode = CMODE_8; |
422 | } else | 423 | } else |
424 | #endif | ||
423 | cmode=default_cmode; | 425 | cmode=default_cmode; |
424 | 426 | #ifdef CONFIG_NVRAM | |
425 | if (default_vmode == VMODE_NVRAM) { | 427 | if (default_vmode == VMODE_NVRAM) { |
426 | vmode = nvram_read_byte(NV_VMODE); | 428 | vmode = nvram_read_byte(NV_VMODE); |
427 | if (vmode < 1 || vmode > VMODE_MAX || | 429 | if (vmode < 1 || vmode > VMODE_MAX || |
@@ -432,7 +434,9 @@ static int __init init_control(struct fb_info_control *p) | |||
432 | if (control_mac_modes[vmode - 1].m[full] < cmode) | 434 | if (control_mac_modes[vmode - 1].m[full] < cmode) |
433 | vmode = VMODE_640_480_60; | 435 | vmode = VMODE_640_480_60; |
434 | } | 436 | } |
435 | } else { | 437 | } else |
438 | #endif | ||
439 | { | ||
436 | vmode=default_vmode; | 440 | vmode=default_vmode; |
437 | if (control_mac_modes[vmode - 1].m[full] < cmode) { | 441 | if (control_mac_modes[vmode - 1].m[full] < cmode) { |
438 | if (cmode > CMODE_8) | 442 | if (cmode > CMODE_8) |
diff --git a/drivers/video/fb_ddc.c b/drivers/video/fb_ddc.c index 3aa6ebf68f17..f836137a0eda 100644 --- a/drivers/video/fb_ddc.c +++ b/drivers/video/fb_ddc.c | |||
@@ -20,26 +20,26 @@ | |||
20 | static unsigned char *fb_do_probe_ddc_edid(struct i2c_adapter *adapter) | 20 | static unsigned char *fb_do_probe_ddc_edid(struct i2c_adapter *adapter) |
21 | { | 21 | { |
22 | unsigned char start = 0x0; | 22 | unsigned char start = 0x0; |
23 | unsigned char *buf = kmalloc(EDID_LENGTH, GFP_KERNEL); | ||
23 | struct i2c_msg msgs[] = { | 24 | struct i2c_msg msgs[] = { |
24 | { | 25 | { |
25 | .addr = DDC_ADDR, | 26 | .addr = DDC_ADDR, |
27 | .flags = 0, | ||
26 | .len = 1, | 28 | .len = 1, |
27 | .buf = &start, | 29 | .buf = &start, |
28 | }, { | 30 | }, { |
29 | .addr = DDC_ADDR, | 31 | .addr = DDC_ADDR, |
30 | .flags = I2C_M_RD, | 32 | .flags = I2C_M_RD, |
31 | .len = EDID_LENGTH, | 33 | .len = EDID_LENGTH, |
34 | .buf = buf, | ||
32 | } | 35 | } |
33 | }; | 36 | }; |
34 | unsigned char *buf; | ||
35 | 37 | ||
36 | buf = kmalloc(EDID_LENGTH, GFP_KERNEL); | ||
37 | if (!buf) { | 38 | if (!buf) { |
38 | dev_warn(&adapter->dev, "unable to allocate memory for EDID " | 39 | dev_warn(&adapter->dev, "unable to allocate memory for EDID " |
39 | "block.\n"); | 40 | "block.\n"); |
40 | return NULL; | 41 | return NULL; |
41 | } | 42 | } |
42 | msgs[1].buf = buf; | ||
43 | 43 | ||
44 | if (i2c_transfer(adapter, msgs, 2) == 2) | 44 | if (i2c_transfer(adapter, msgs, 2) == 2) |
45 | return buf; | 45 | return buf; |
diff --git a/drivers/video/hitfb.c b/drivers/video/hitfb.c index 3afb472763c0..3dc49424dc75 100644 --- a/drivers/video/hitfb.c +++ b/drivers/video/hitfb.c | |||
@@ -29,7 +29,6 @@ | |||
29 | #include <asm/io.h> | 29 | #include <asm/io.h> |
30 | #include <asm/hd64461.h> | 30 | #include <asm/hd64461.h> |
31 | #include <asm/cpu/dac.h> | 31 | #include <asm/cpu/dac.h> |
32 | #include <asm/hp6xx/hp6xx.h> | ||
33 | 32 | ||
34 | #define WIDTH 640 | 33 | #define WIDTH 640 |
35 | 34 | ||
diff --git a/drivers/video/igafb.c b/drivers/video/igafb.c index 67f384f86758..e6df492c22a5 100644 --- a/drivers/video/igafb.c +++ b/drivers/video/igafb.c | |||
@@ -573,3 +573,10 @@ int __init igafb_setup(char *options) | |||
573 | 573 | ||
574 | module_init(igafb_init); | 574 | module_init(igafb_init); |
575 | MODULE_LICENSE("GPL"); | 575 | MODULE_LICENSE("GPL"); |
576 | static struct pci_device_id igafb_pci_tbl[] __devinitdata = { | ||
577 | { PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_1682, | ||
578 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | ||
579 | { } | ||
580 | }; | ||
581 | |||
582 | MODULE_DEVICE_TABLE(pci, igafb_pci_tbl); | ||
diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c index eeeeff9a09eb..a95836839e1e 100644 --- a/drivers/video/intelfb/intelfbhw.c +++ b/drivers/video/intelfb/intelfbhw.c | |||
@@ -161,7 +161,7 @@ intelfbhw_get_memory(struct pci_dev *pdev, int *aperture_size, | |||
161 | return 1; | 161 | return 1; |
162 | 162 | ||
163 | /* Find the bridge device. It is always 0:0.0 */ | 163 | /* Find the bridge device. It is always 0:0.0 */ |
164 | if (!(bridge_dev = pci_find_slot(0, PCI_DEVFN(0, 0)))) { | 164 | if (!(bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0)))) { |
165 | ERR_MSG("cannot find bridge device\n"); | 165 | ERR_MSG("cannot find bridge device\n"); |
166 | return 1; | 166 | return 1; |
167 | } | 167 | } |
@@ -169,6 +169,8 @@ intelfbhw_get_memory(struct pci_dev *pdev, int *aperture_size, | |||
169 | /* Get the fb aperture size and "stolen" memory amount. */ | 169 | /* Get the fb aperture size and "stolen" memory amount. */ |
170 | tmp = 0; | 170 | tmp = 0; |
171 | pci_read_config_word(bridge_dev, INTEL_GMCH_CTRL, &tmp); | 171 | pci_read_config_word(bridge_dev, INTEL_GMCH_CTRL, &tmp); |
172 | pci_dev_put(bridge_dev); | ||
173 | |||
172 | switch (pdev->device) { | 174 | switch (pdev->device) { |
173 | case PCI_DEVICE_ID_INTEL_915G: | 175 | case PCI_DEVICE_ID_INTEL_915G: |
174 | case PCI_DEVICE_ID_INTEL_915GM: | 176 | case PCI_DEVICE_ID_INTEL_915GM: |
@@ -662,7 +664,7 @@ intelfbhw_print_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw) | |||
662 | int index = dinfo->pll_index; | 664 | int index = dinfo->pll_index; |
663 | DBG_MSG("intelfbhw_print_hw_state\n"); | 665 | DBG_MSG("intelfbhw_print_hw_state\n"); |
664 | 666 | ||
665 | if (!hw || !dinfo) | 667 | if (!hw) |
666 | return; | 668 | return; |
667 | /* Read in as much of the HW state as possible. */ | 669 | /* Read in as much of the HW state as possible. */ |
668 | printk("hw state dump start\n"); | 670 | printk("hw state dump start\n"); |
diff --git a/drivers/video/nvidia/nv_hw.c b/drivers/video/nvidia/nv_hw.c index 9ed640d35728..ea426115c6f9 100644 --- a/drivers/video/nvidia/nv_hw.c +++ b/drivers/video/nvidia/nv_hw.c | |||
@@ -145,12 +145,18 @@ static void nvGetClocks(struct nvidia_par *par, unsigned int *MClk, | |||
145 | 145 | ||
146 | if (par->Architecture >= NV_ARCH_40) { | 146 | if (par->Architecture >= NV_ARCH_40) { |
147 | pll = NV_RD32(par->PMC, 0x4020); | 147 | pll = NV_RD32(par->PMC, 0x4020); |
148 | P = (pll >> 16) & 0x03; | 148 | P = (pll >> 16) & 0x07; |
149 | pll = NV_RD32(par->PMC, 0x4024); | 149 | pll = NV_RD32(par->PMC, 0x4024); |
150 | M = pll & 0xFF; | 150 | M = pll & 0xFF; |
151 | N = (pll >> 8) & 0xFF; | 151 | N = (pll >> 8) & 0xFF; |
152 | MB = (pll >> 16) & 0xFF; | 152 | if (((par->Chipset & 0xfff0) == 0x0290) || |
153 | NB = (pll >> 24) & 0xFF; | 153 | ((par->Chipset & 0xfff0) == 0x0390)) { |
154 | MB = 1; | ||
155 | NB = 1; | ||
156 | } else { | ||
157 | MB = (pll >> 16) & 0xFF; | ||
158 | NB = (pll >> 24) & 0xFF; | ||
159 | } | ||
154 | *MClk = ((N * NB * par->CrystalFreqKHz) / (M * MB)) >> P; | 160 | *MClk = ((N * NB * par->CrystalFreqKHz) / (M * MB)) >> P; |
155 | 161 | ||
156 | pll = NV_RD32(par->PMC, 0x4000); | 162 | pll = NV_RD32(par->PMC, 0x4000); |
diff --git a/drivers/video/nvidia/nv_i2c.c b/drivers/video/nvidia/nv_i2c.c index e48de3c9fd13..19eef3a09023 100644 --- a/drivers/video/nvidia/nv_i2c.c +++ b/drivers/video/nvidia/nv_i2c.c | |||
@@ -160,12 +160,51 @@ void nvidia_delete_i2c_busses(struct nvidia_par *par) | |||
160 | 160 | ||
161 | } | 161 | } |
162 | 162 | ||
163 | static u8 *nvidia_do_probe_i2c_edid(struct nvidia_i2c_chan *chan) | ||
164 | { | ||
165 | u8 start = 0x0; | ||
166 | struct i2c_msg msgs[] = { | ||
167 | { | ||
168 | .addr = 0x50, | ||
169 | .len = 1, | ||
170 | .buf = &start, | ||
171 | }, { | ||
172 | .addr = 0x50, | ||
173 | .flags = I2C_M_RD, | ||
174 | .len = EDID_LENGTH, | ||
175 | }, | ||
176 | }; | ||
177 | u8 *buf; | ||
178 | |||
179 | if (!chan->par) | ||
180 | return NULL; | ||
181 | |||
182 | buf = kmalloc(EDID_LENGTH, GFP_KERNEL); | ||
183 | if (!buf) { | ||
184 | dev_warn(&chan->par->pci_dev->dev, "Out of memory!\n"); | ||
185 | return NULL; | ||
186 | } | ||
187 | msgs[1].buf = buf; | ||
188 | |||
189 | if (i2c_transfer(&chan->adapter, msgs, 2) == 2) | ||
190 | return buf; | ||
191 | dev_dbg(&chan->par->pci_dev->dev, "Unable to read EDID block.\n"); | ||
192 | kfree(buf); | ||
193 | return NULL; | ||
194 | } | ||
195 | |||
163 | int nvidia_probe_i2c_connector(struct fb_info *info, int conn, u8 **out_edid) | 196 | int nvidia_probe_i2c_connector(struct fb_info *info, int conn, u8 **out_edid) |
164 | { | 197 | { |
165 | struct nvidia_par *par = info->par; | 198 | struct nvidia_par *par = info->par; |
166 | u8 *edid; | 199 | u8 *edid = NULL; |
167 | 200 | int i; | |
168 | edid = fb_ddc_read(&par->chan[conn - 1].adapter); | 201 | |
202 | for (i = 0; i < 3; i++) { | ||
203 | /* Do the real work */ | ||
204 | edid = nvidia_do_probe_i2c_edid(&par->chan[conn - 1]); | ||
205 | if (edid) | ||
206 | break; | ||
207 | } | ||
169 | 208 | ||
170 | if (!edid && conn == 1) { | 209 | if (!edid && conn == 1) { |
171 | /* try to get from firmware */ | 210 | /* try to get from firmware */ |
diff --git a/drivers/video/nvidia/nv_setup.c b/drivers/video/nvidia/nv_setup.c index a18a9aebf05f..eab3e282a4de 100644 --- a/drivers/video/nvidia/nv_setup.c +++ b/drivers/video/nvidia/nv_setup.c | |||
@@ -262,7 +262,7 @@ static void nv10GetConfig(struct nvidia_par *par) | |||
262 | #endif | 262 | #endif |
263 | 263 | ||
264 | dev = pci_find_slot(0, 1); | 264 | dev = pci_find_slot(0, 1); |
265 | if ((par->Chipset && 0xffff) == 0x01a0) { | 265 | if ((par->Chipset & 0xffff) == 0x01a0) { |
266 | int amt = 0; | 266 | int amt = 0; |
267 | 267 | ||
268 | pci_read_config_dword(dev, 0x7c, &amt); | 268 | pci_read_config_dword(dev, 0x7c, &amt); |
@@ -359,6 +359,7 @@ int NVCommonSetup(struct fb_info *info) | |||
359 | case 0x0186: | 359 | case 0x0186: |
360 | case 0x0187: | 360 | case 0x0187: |
361 | case 0x018D: | 361 | case 0x018D: |
362 | case 0x0228: | ||
362 | case 0x0286: | 363 | case 0x0286: |
363 | case 0x028C: | 364 | case 0x028C: |
364 | case 0x0316: | 365 | case 0x0316: |
@@ -382,6 +383,10 @@ int NVCommonSetup(struct fb_info *info) | |||
382 | case 0x034C: | 383 | case 0x034C: |
383 | case 0x0160: | 384 | case 0x0160: |
384 | case 0x0166: | 385 | case 0x0166: |
386 | case 0x0169: | ||
387 | case 0x016B: | ||
388 | case 0x016C: | ||
389 | case 0x016D: | ||
385 | case 0x00C8: | 390 | case 0x00C8: |
386 | case 0x00CC: | 391 | case 0x00CC: |
387 | case 0x0144: | 392 | case 0x0144: |
@@ -639,12 +644,23 @@ int NVCommonSetup(struct fb_info *info) | |||
639 | par->fpHeight = NV_RD32(par->PRAMDAC, 0x0800) + 1; | 644 | par->fpHeight = NV_RD32(par->PRAMDAC, 0x0800) + 1; |
640 | par->fpSyncs = NV_RD32(par->PRAMDAC, 0x0848) & 0x30000033; | 645 | par->fpSyncs = NV_RD32(par->PRAMDAC, 0x0848) & 0x30000033; |
641 | 646 | ||
642 | printk("Panel size is %i x %i\n", par->fpWidth, par->fpHeight); | 647 | printk("nvidiafb: Panel size is %i x %i\n", par->fpWidth, par->fpHeight); |
643 | } | 648 | } |
644 | 649 | ||
645 | if (monA) | 650 | if (monA) |
646 | info->monspecs = *monA; | 651 | info->monspecs = *monA; |
647 | 652 | ||
653 | if (!par->FlatPanel || !par->twoHeads) | ||
654 | par->FPDither = 0; | ||
655 | |||
656 | par->LVDS = 0; | ||
657 | if (par->FlatPanel && par->twoHeads) { | ||
658 | NV_WR32(par->PRAMDAC0, 0x08B0, 0x00010004); | ||
659 | if (par->PRAMDAC0[0x08b4] & 1) | ||
660 | par->LVDS = 1; | ||
661 | printk("nvidiafb: Panel is %s\n", par->LVDS ? "LVDS" : "TMDS"); | ||
662 | } | ||
663 | |||
648 | kfree(edidA); | 664 | kfree(edidA); |
649 | kfree(edidB); | 665 | kfree(edidB); |
650 | done: | 666 | done: |
diff --git a/drivers/video/nvidia/nv_type.h b/drivers/video/nvidia/nv_type.h index acdc26693402..86e65dea60d3 100644 --- a/drivers/video/nvidia/nv_type.h +++ b/drivers/video/nvidia/nv_type.h | |||
@@ -129,6 +129,7 @@ struct nvidia_par { | |||
129 | int fpHeight; | 129 | int fpHeight; |
130 | int PanelTweak; | 130 | int PanelTweak; |
131 | int paneltweak; | 131 | int paneltweak; |
132 | int LVDS; | ||
132 | int pm_state; | 133 | int pm_state; |
133 | u32 crtcSync_read; | 134 | u32 crtcSync_read; |
134 | u32 fpSyncs; | 135 | u32 fpSyncs; |
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c index eb24107bcc81..538e947610e1 100644 --- a/drivers/video/nvidia/nvidia.c +++ b/drivers/video/nvidia/nvidia.c | |||
@@ -1160,20 +1160,20 @@ static u32 __devinit nvidia_get_arch(struct fb_info *info) | |||
1160 | case 0x0340: /* GeForceFX 5700 */ | 1160 | case 0x0340: /* GeForceFX 5700 */ |
1161 | arch = NV_ARCH_30; | 1161 | arch = NV_ARCH_30; |
1162 | break; | 1162 | break; |
1163 | case 0x0040: | 1163 | case 0x0040: /* GeForce 6800 */ |
1164 | case 0x00C0: | 1164 | case 0x00C0: /* GeForce 6800 */ |
1165 | case 0x0120: | 1165 | case 0x0120: /* GeForce 6800 */ |
1166 | case 0x0130: | 1166 | case 0x0130: |
1167 | case 0x0140: | 1167 | case 0x0140: /* GeForce 6600 */ |
1168 | case 0x0160: | 1168 | case 0x0160: /* GeForce 6200 */ |
1169 | case 0x01D0: | 1169 | case 0x01D0: /* GeForce 7200, 7300, 7400 */ |
1170 | case 0x0090: | 1170 | case 0x0090: /* GeForce 7800 */ |
1171 | case 0x0210: | 1171 | case 0x0210: /* GeForce 6800 */ |
1172 | case 0x0220: | 1172 | case 0x0220: /* GeForce 6200 */ |
1173 | case 0x0230: | 1173 | case 0x0230: |
1174 | case 0x0240: | 1174 | case 0x0240: /* GeForce 6100 */ |
1175 | case 0x0290: | 1175 | case 0x0290: /* GeForce 7900 */ |
1176 | case 0x0390: | 1176 | case 0x0390: /* GeForce 7600 */ |
1177 | arch = NV_ARCH_40; | 1177 | arch = NV_ARCH_40; |
1178 | break; | 1178 | break; |
1179 | case 0x0020: /* TNT, TNT2 */ | 1179 | case 0x0020: /* TNT, TNT2 */ |
diff --git a/drivers/video/offb.c b/drivers/video/offb.c index bad0e98fb3b6..9a40bbecf76b 100644 --- a/drivers/video/offb.c +++ b/drivers/video/offb.c | |||
@@ -157,7 +157,7 @@ static int offb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, | |||
157 | out_le32(par->cmap_adr + 0xb4, (red << 16 | green << 8 | blue)); | 157 | out_le32(par->cmap_adr + 0xb4, (red << 16 | green << 8 | blue)); |
158 | break; | 158 | break; |
159 | case cmap_gxt2000: | 159 | case cmap_gxt2000: |
160 | out_le32((unsigned __iomem *) par->cmap_adr + regno, | 160 | out_le32(((unsigned __iomem *) par->cmap_adr) + regno, |
161 | (red << 16 | green << 8 | blue)); | 161 | (red << 16 | green << 8 | blue)); |
162 | break; | 162 | break; |
163 | } | 163 | } |
@@ -213,7 +213,7 @@ static int offb_blank(int blank, struct fb_info *info) | |||
213 | out_le32(par->cmap_adr + 0xb4, 0); | 213 | out_le32(par->cmap_adr + 0xb4, 0); |
214 | break; | 214 | break; |
215 | case cmap_gxt2000: | 215 | case cmap_gxt2000: |
216 | out_le32((unsigned __iomem *) par->cmap_adr + i, | 216 | out_le32(((unsigned __iomem *) par->cmap_adr) + i, |
217 | 0); | 217 | 0); |
218 | break; | 218 | break; |
219 | } | 219 | } |
@@ -226,13 +226,23 @@ static int offb_blank(int blank, struct fb_info *info) | |||
226 | static void __iomem *offb_map_reg(struct device_node *np, int index, | 226 | static void __iomem *offb_map_reg(struct device_node *np, int index, |
227 | unsigned long offset, unsigned long size) | 227 | unsigned long offset, unsigned long size) |
228 | { | 228 | { |
229 | struct resource r; | 229 | const u32 *addrp; |
230 | 230 | u64 asize, taddr; | |
231 | if (of_address_to_resource(np, index, &r)) | 231 | unsigned int flags; |
232 | return 0; | 232 | |
233 | if ((r.start + offset + size) > r.end) | 233 | addrp = of_get_pci_address(np, index, &asize, &flags); |
234 | return 0; | 234 | if (addrp == NULL) |
235 | return ioremap(r.start + offset, size); | 235 | addrp = of_get_address(np, index, &asize, &flags); |
236 | if (addrp == NULL) | ||
237 | return NULL; | ||
238 | if ((flags & (IORESOURCE_IO | IORESOURCE_MEM)) == 0) | ||
239 | return NULL; | ||
240 | if ((offset + size) > asize) | ||
241 | return NULL; | ||
242 | taddr = of_translate_address(np, addrp); | ||
243 | if (taddr == OF_BAD_ADDR) | ||
244 | return NULL; | ||
245 | return ioremap(taddr + offset, size); | ||
236 | } | 246 | } |
237 | 247 | ||
238 | static void __init offb_init_fb(const char *name, const char *full_name, | 248 | static void __init offb_init_fb(const char *name, const char *full_name, |
@@ -289,7 +299,6 @@ static void __init offb_init_fb(const char *name, const char *full_name, | |||
289 | 299 | ||
290 | par->cmap_type = cmap_unknown; | 300 | par->cmap_type = cmap_unknown; |
291 | if (depth == 8) { | 301 | if (depth == 8) { |
292 | /* Palette hacks disabled for now */ | ||
293 | if (dp && !strncmp(name, "ATY,Rage128", 11)) { | 302 | if (dp && !strncmp(name, "ATY,Rage128", 11)) { |
294 | par->cmap_adr = offb_map_reg(dp, 2, 0, 0x1fff); | 303 | par->cmap_adr = offb_map_reg(dp, 2, 0, 0x1fff); |
295 | if (par->cmap_adr) | 304 | if (par->cmap_adr) |
@@ -313,7 +322,8 @@ static void __init offb_init_fb(const char *name, const char *full_name, | |||
313 | ioremap(base + 0x7ff000, 0x1000) + 0xcc0; | 322 | ioremap(base + 0x7ff000, 0x1000) + 0xcc0; |
314 | par->cmap_data = par->cmap_adr + 1; | 323 | par->cmap_data = par->cmap_adr + 1; |
315 | par->cmap_type = cmap_m64; | 324 | par->cmap_type = cmap_m64; |
316 | } else if (dp && device_is_compatible(dp, "pci1014,b7")) { | 325 | } else if (dp && (device_is_compatible(dp, "pci1014,b7") || |
326 | device_is_compatible(dp, "pci1014,21c"))) { | ||
317 | par->cmap_adr = offb_map_reg(dp, 0, 0x6000, 0x1000); | 327 | par->cmap_adr = offb_map_reg(dp, 0, 0x6000, 0x1000); |
318 | if (par->cmap_adr) | 328 | if (par->cmap_adr) |
319 | par->cmap_type = cmap_gxt2000; | 329 | par->cmap_type = cmap_gxt2000; |
@@ -433,7 +443,7 @@ static void __init offb_init_nodriver(struct device_node *dp, int no_real_node) | |||
433 | pp = get_property(dp, "linux,bootx-linebytes", &len); | 443 | pp = get_property(dp, "linux,bootx-linebytes", &len); |
434 | if (pp == NULL) | 444 | if (pp == NULL) |
435 | pp = get_property(dp, "linebytes", &len); | 445 | pp = get_property(dp, "linebytes", &len); |
436 | if (pp && len == sizeof(u32)) | 446 | if (pp && len == sizeof(u32) && (*pp != 0xffffffffu)) |
437 | pitch = *pp; | 447 | pitch = *pp; |
438 | else | 448 | else |
439 | pitch = width * ((depth + 7) / 8); | 449 | pitch = width * ((depth + 7) / 8); |
@@ -496,7 +506,7 @@ static void __init offb_init_nodriver(struct device_node *dp, int no_real_node) | |||
496 | offb_init_fb(no_real_node ? "bootx" : dp->name, | 506 | offb_init_fb(no_real_node ? "bootx" : dp->name, |
497 | no_real_node ? "display" : dp->full_name, | 507 | no_real_node ? "display" : dp->full_name, |
498 | width, height, depth, pitch, address, | 508 | width, height, depth, pitch, address, |
499 | no_real_node ? dp : NULL); | 509 | no_real_node ? NULL : dp); |
500 | } | 510 | } |
501 | } | 511 | } |
502 | 512 | ||
diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c index 983be3ec2345..fdb33cd21a27 100644 --- a/drivers/video/platinumfb.c +++ b/drivers/video/platinumfb.c | |||
@@ -339,11 +339,12 @@ static int __devinit platinum_init_fb(struct fb_info *info) | |||
339 | 339 | ||
340 | sense = read_platinum_sense(pinfo); | 340 | sense = read_platinum_sense(pinfo); |
341 | printk(KERN_INFO "platinumfb: Monitor sense value = 0x%x, ", sense); | 341 | printk(KERN_INFO "platinumfb: Monitor sense value = 0x%x, ", sense); |
342 | |||
343 | if (default_vmode == VMODE_NVRAM) { | 342 | if (default_vmode == VMODE_NVRAM) { |
343 | #ifdef CONFIG_NVRAM | ||
344 | default_vmode = nvram_read_byte(NV_VMODE); | 344 | default_vmode = nvram_read_byte(NV_VMODE); |
345 | if (default_vmode <= 0 || default_vmode > VMODE_MAX || | 345 | if (default_vmode <= 0 || default_vmode > VMODE_MAX || |
346 | !platinum_reg_init[default_vmode-1]) | 346 | !platinum_reg_init[default_vmode-1]) |
347 | #endif | ||
347 | default_vmode = VMODE_CHOOSE; | 348 | default_vmode = VMODE_CHOOSE; |
348 | } | 349 | } |
349 | if (default_vmode == VMODE_CHOOSE) { | 350 | if (default_vmode == VMODE_CHOOSE) { |
@@ -351,8 +352,10 @@ static int __devinit platinum_init_fb(struct fb_info *info) | |||
351 | } | 352 | } |
352 | if (default_vmode <= 0 || default_vmode > VMODE_MAX) | 353 | if (default_vmode <= 0 || default_vmode > VMODE_MAX) |
353 | default_vmode = VMODE_640_480_60; | 354 | default_vmode = VMODE_640_480_60; |
355 | #ifdef CONFIG_NVRAM | ||
354 | if (default_cmode == CMODE_NVRAM) | 356 | if (default_cmode == CMODE_NVRAM) |
355 | default_cmode = nvram_read_byte(NV_CMODE); | 357 | default_cmode = nvram_read_byte(NV_CMODE); |
358 | #endif | ||
356 | if (default_cmode < CMODE_8 || default_cmode > CMODE_32) | 359 | if (default_cmode < CMODE_8 || default_cmode > CMODE_32) |
357 | default_cmode = CMODE_8; | 360 | default_cmode = CMODE_8; |
358 | /* | 361 | /* |
diff --git a/drivers/video/pnx4008/pnxrgbfb.c b/drivers/video/pnx4008/pnxrgbfb.c index 7d9453c91a42..f29e66e2d774 100644 --- a/drivers/video/pnx4008/pnxrgbfb.c +++ b/drivers/video/pnx4008/pnxrgbfb.c | |||
@@ -154,7 +154,8 @@ static int __devinit rgbfb_probe(struct platform_device *pdev) | |||
154 | goto err1; | 154 | goto err1; |
155 | } | 155 | } |
156 | 156 | ||
157 | if (!fb_get_options("pnxrgbfb", &option) && !strcmp(option, "nocursor")) | 157 | if (!fb_get_options("pnxrgbfb", &option) && option && |
158 | !strcmp(option, "nocursor")) | ||
158 | rgbfb_ops.fb_cursor = no_cursor; | 159 | rgbfb_ops.fb_cursor = no_cursor; |
159 | 160 | ||
160 | info->node = -1; | 161 | info->node = -1; |
@@ -191,7 +192,7 @@ err: | |||
191 | 192 | ||
192 | static struct platform_driver rgbfb_driver = { | 193 | static struct platform_driver rgbfb_driver = { |
193 | .driver = { | 194 | .driver = { |
194 | .name = "rgbfb", | 195 | .name = "pnx4008-rgbfb", |
195 | }, | 196 | }, |
196 | .probe = rgbfb_probe, | 197 | .probe = rgbfb_probe, |
197 | .remove = rgbfb_remove, | 198 | .remove = rgbfb_remove, |
diff --git a/drivers/video/pnx4008/sdum.c b/drivers/video/pnx4008/sdum.c index 51f0ecc2a511..d23bf0d659b6 100644 --- a/drivers/video/pnx4008/sdum.c +++ b/drivers/video/pnx4008/sdum.c | |||
@@ -848,7 +848,7 @@ static int sdum_remove(struct platform_device *pdev) | |||
848 | 848 | ||
849 | static struct platform_driver sdum_driver = { | 849 | static struct platform_driver sdum_driver = { |
850 | .driver = { | 850 | .driver = { |
851 | .name = "sdum", | 851 | .name = "pnx4008-sdum", |
852 | }, | 852 | }, |
853 | .probe = sdum_probe, | 853 | .probe = sdum_probe, |
854 | .remove = sdum_remove, | 854 | .remove = sdum_remove, |
diff --git a/drivers/video/valkyriefb.c b/drivers/video/valkyriefb.c index 47f27924a7d7..06fc19a61192 100644 --- a/drivers/video/valkyriefb.c +++ b/drivers/video/valkyriefb.c | |||
@@ -284,7 +284,7 @@ static void __init valkyrie_choose_mode(struct fb_info_valkyrie *p) | |||
284 | printk(KERN_INFO "Monitor sense value = 0x%x\n", p->sense); | 284 | printk(KERN_INFO "Monitor sense value = 0x%x\n", p->sense); |
285 | 285 | ||
286 | /* Try to pick a video mode out of NVRAM if we have one. */ | 286 | /* Try to pick a video mode out of NVRAM if we have one. */ |
287 | #ifndef CONFIG_MAC | 287 | #if !defined(CONFIG_MAC) && defined(CONFIG_NVRAM) |
288 | if (default_vmode == VMODE_NVRAM) { | 288 | if (default_vmode == VMODE_NVRAM) { |
289 | default_vmode = nvram_read_byte(NV_VMODE); | 289 | default_vmode = nvram_read_byte(NV_VMODE); |
290 | if (default_vmode <= 0 | 290 | if (default_vmode <= 0 |
@@ -297,7 +297,7 @@ static void __init valkyrie_choose_mode(struct fb_info_valkyrie *p) | |||
297 | default_vmode = mac_map_monitor_sense(p->sense); | 297 | default_vmode = mac_map_monitor_sense(p->sense); |
298 | if (!valkyrie_reg_init[default_vmode - 1]) | 298 | if (!valkyrie_reg_init[default_vmode - 1]) |
299 | default_vmode = VMODE_640_480_67; | 299 | default_vmode = VMODE_640_480_67; |
300 | #ifndef CONFIG_MAC | 300 | #if !defined(CONFIG_MAC) && defined(CONFIG_NVRAM) |
301 | if (default_cmode == CMODE_NVRAM) | 301 | if (default_cmode == CMODE_NVRAM) |
302 | default_cmode = nvram_read_byte(NV_CMODE); | 302 | default_cmode = nvram_read_byte(NV_CMODE); |
303 | #endif | 303 | #endif |
diff --git a/drivers/w1/Kconfig b/drivers/w1/Kconfig index 27c9d05d03ef..c287a9ae4fdd 100644 --- a/drivers/w1/Kconfig +++ b/drivers/w1/Kconfig | |||
@@ -2,7 +2,6 @@ menu "Dallas's 1-wire bus" | |||
2 | 2 | ||
3 | config W1 | 3 | config W1 |
4 | tristate "Dallas's 1-wire support" | 4 | tristate "Dallas's 1-wire support" |
5 | depends on CONNECTOR | ||
6 | ---help--- | 5 | ---help--- |
7 | Dallas' 1-wire bus is useful to connect slow 1-pin devices | 6 | Dallas' 1-wire bus is useful to connect slow 1-pin devices |
8 | such as iButtons and thermal sensors. | 7 | such as iButtons and thermal sensors. |
diff --git a/drivers/w1/masters/matrox_w1.c b/drivers/w1/masters/matrox_w1.c index 2788b8ca9bb1..6f9d880ab2e9 100644 --- a/drivers/w1/masters/matrox_w1.c +++ b/drivers/w1/masters/matrox_w1.c | |||
@@ -215,6 +215,8 @@ static int __devinit matrox_w1_probe(struct pci_dev *pdev, const struct pci_devi | |||
215 | return 0; | 215 | return 0; |
216 | 216 | ||
217 | err_out_free_device: | 217 | err_out_free_device: |
218 | if (dev->virt_addr) | ||
219 | iounmap(dev->virt_addr); | ||
218 | kfree(dev); | 220 | kfree(dev); |
219 | 221 | ||
220 | return err; | 222 | return err; |