diff options
Diffstat (limited to 'drivers')
372 files changed, 11153 insertions, 8470 deletions
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index c7b10b4298e9..66cc3f36a954 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile | |||
@@ -32,6 +32,7 @@ acpi-$(CONFIG_ACPI_SLEEP) += proc.o | |||
32 | # | 32 | # |
33 | acpi-y += bus.o glue.o | 33 | acpi-y += bus.o glue.o |
34 | acpi-y += scan.o | 34 | acpi-y += scan.o |
35 | acpi-y += processor_pdc.o | ||
35 | acpi-y += ec.o | 36 | acpi-y += ec.o |
36 | acpi-$(CONFIG_ACPI_DOCK) += dock.o | 37 | acpi-$(CONFIG_ACPI_DOCK) += dock.o |
37 | acpi-y += pci_root.o pci_link.o pci_irq.o pci_bind.o | 38 | acpi-y += pci_root.o pci_link.o pci_irq.o pci_bind.o |
diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index 23e5a0519af5..2815df66f6f7 100644 --- a/drivers/acpi/blacklist.c +++ b/drivers/acpi/blacklist.c | |||
@@ -185,6 +185,12 @@ static int __init dmi_disable_osi_vista(const struct dmi_system_id *d) | |||
185 | acpi_osi_setup("!Windows 2006"); | 185 | acpi_osi_setup("!Windows 2006"); |
186 | return 0; | 186 | return 0; |
187 | } | 187 | } |
188 | static int __init dmi_disable_osi_win7(const struct dmi_system_id *d) | ||
189 | { | ||
190 | printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident); | ||
191 | acpi_osi_setup("!Windows 2009"); | ||
192 | return 0; | ||
193 | } | ||
188 | 194 | ||
189 | static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { | 195 | static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { |
190 | { | 196 | { |
@@ -211,6 +217,14 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { | |||
211 | DMI_MATCH(DMI_PRODUCT_NAME, "Sony VGN-SR290J"), | 217 | DMI_MATCH(DMI_PRODUCT_NAME, "Sony VGN-SR290J"), |
212 | }, | 218 | }, |
213 | }, | 219 | }, |
220 | { | ||
221 | .callback = dmi_disable_osi_win7, | ||
222 | .ident = "ASUS K50IJ", | ||
223 | .matches = { | ||
224 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), | ||
225 | DMI_MATCH(DMI_PRODUCT_NAME, "K50IJ"), | ||
226 | }, | ||
227 | }, | ||
214 | 228 | ||
215 | /* | 229 | /* |
216 | * BIOS invocation of _OSI(Linux) is almost always a BIOS bug. | 230 | * BIOS invocation of _OSI(Linux) is almost always a BIOS bug. |
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 65f7e335f122..cf761b904e4a 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c | |||
@@ -397,6 +397,7 @@ acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context) | |||
397 | union acpi_object *out_obj; | 397 | union acpi_object *out_obj; |
398 | u8 uuid[16]; | 398 | u8 uuid[16]; |
399 | u32 errors; | 399 | u32 errors; |
400 | struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL}; | ||
400 | 401 | ||
401 | if (!context) | 402 | if (!context) |
402 | return AE_ERROR; | 403 | return AE_ERROR; |
@@ -419,16 +420,16 @@ acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context) | |||
419 | in_params[3].buffer.length = context->cap.length; | 420 | in_params[3].buffer.length = context->cap.length; |
420 | in_params[3].buffer.pointer = context->cap.pointer; | 421 | in_params[3].buffer.pointer = context->cap.pointer; |
421 | 422 | ||
422 | status = acpi_evaluate_object(handle, "_OSC", &input, &context->ret); | 423 | status = acpi_evaluate_object(handle, "_OSC", &input, &output); |
423 | if (ACPI_FAILURE(status)) | 424 | if (ACPI_FAILURE(status)) |
424 | return status; | 425 | return status; |
425 | 426 | ||
426 | /* return buffer should have the same length as cap buffer */ | 427 | if (!output.length) |
427 | if (context->ret.length != context->cap.length) | ||
428 | return AE_NULL_OBJECT; | 428 | return AE_NULL_OBJECT; |
429 | 429 | ||
430 | out_obj = context->ret.pointer; | 430 | out_obj = output.pointer; |
431 | if (out_obj->type != ACPI_TYPE_BUFFER) { | 431 | if (out_obj->type != ACPI_TYPE_BUFFER |
432 | || out_obj->buffer.length != context->cap.length) { | ||
432 | acpi_print_osc_error(handle, context, | 433 | acpi_print_osc_error(handle, context, |
433 | "_OSC evaluation returned wrong type"); | 434 | "_OSC evaluation returned wrong type"); |
434 | status = AE_TYPE; | 435 | status = AE_TYPE; |
@@ -457,11 +458,20 @@ acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context) | |||
457 | goto out_kfree; | 458 | goto out_kfree; |
458 | } | 459 | } |
459 | out_success: | 460 | out_success: |
460 | return AE_OK; | 461 | context->ret.length = out_obj->buffer.length; |
462 | context->ret.pointer = kmalloc(context->ret.length, GFP_KERNEL); | ||
463 | if (!context->ret.pointer) { | ||
464 | status = AE_NO_MEMORY; | ||
465 | goto out_kfree; | ||
466 | } | ||
467 | memcpy(context->ret.pointer, out_obj->buffer.pointer, | ||
468 | context->ret.length); | ||
469 | status = AE_OK; | ||
461 | 470 | ||
462 | out_kfree: | 471 | out_kfree: |
463 | kfree(context->ret.pointer); | 472 | kfree(output.pointer); |
464 | context->ret.pointer = NULL; | 473 | if (status != AE_OK) |
474 | context->ret.pointer = NULL; | ||
465 | return status; | 475 | return status; |
466 | } | 476 | } |
467 | EXPORT_SYMBOL(acpi_run_osc); | 477 | EXPORT_SYMBOL(acpi_run_osc); |
@@ -888,6 +898,8 @@ static int __init acpi_bus_init(void) | |||
888 | goto error1; | 898 | goto error1; |
889 | } | 899 | } |
890 | 900 | ||
901 | acpi_early_processor_set_pdc(); | ||
902 | |||
891 | /* | 903 | /* |
892 | * Maybe EC region is required at bus_scan/acpi_get_devices. So it | 904 | * Maybe EC region is required at bus_scan/acpi_get_devices. So it |
893 | * is necessary to enable it as early as possible. | 905 | * is necessary to enable it as early as possible. |
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 75b147f5c8fd..fd1801bdee66 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -916,6 +916,7 @@ static int ec_validate_ecdt(const struct dmi_system_id *id) | |||
916 | /* MSI EC needs special treatment, enable it */ | 916 | /* MSI EC needs special treatment, enable it */ |
917 | static int ec_flag_msi(const struct dmi_system_id *id) | 917 | static int ec_flag_msi(const struct dmi_system_id *id) |
918 | { | 918 | { |
919 | printk(KERN_DEBUG PREFIX "Detected MSI hardware, enabling workarounds.\n"); | ||
919 | EC_FLAGS_MSI = 1; | 920 | EC_FLAGS_MSI = 1; |
920 | EC_FLAGS_VALIDATE_ECDT = 1; | 921 | EC_FLAGS_VALIDATE_ECDT = 1; |
921 | return 0; | 922 | return 0; |
@@ -928,8 +929,13 @@ static struct dmi_system_id __initdata ec_dmi_table[] = { | |||
928 | DMI_MATCH(DMI_BOARD_NAME, "JFL92") }, NULL}, | 929 | DMI_MATCH(DMI_BOARD_NAME, "JFL92") }, NULL}, |
929 | { | 930 | { |
930 | ec_flag_msi, "MSI hardware", { | 931 | ec_flag_msi, "MSI hardware", { |
931 | DMI_MATCH(DMI_BIOS_VENDOR, "Micro-Star"), | 932 | DMI_MATCH(DMI_BIOS_VENDOR, "Micro-Star")}, NULL}, |
932 | DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-Star") }, NULL}, | 933 | { |
934 | ec_flag_msi, "MSI hardware", { | ||
935 | DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star")}, NULL}, | ||
936 | { | ||
937 | ec_flag_msi, "MSI hardware", { | ||
938 | DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-Star")}, NULL}, | ||
933 | { | 939 | { |
934 | ec_validate_ecdt, "ASUS hardware", { | 940 | ec_validate_ecdt, "ASUS hardware", { |
935 | DMI_MATCH(DMI_BIOS_VENDOR, "ASUS") }, NULL}, | 941 | DMI_MATCH(DMI_BIOS_VENDOR, "ASUS") }, NULL}, |
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 074cf8682d52..cb28e0502acc 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h | |||
@@ -43,6 +43,7 @@ int acpi_power_transition(struct acpi_device *device, int state); | |||
43 | extern int acpi_power_nocheck; | 43 | extern int acpi_power_nocheck; |
44 | 44 | ||
45 | int acpi_wakeup_device_init(void); | 45 | int acpi_wakeup_device_init(void); |
46 | void acpi_early_processor_set_pdc(void); | ||
46 | 47 | ||
47 | /* -------------------------------------------------------------------------- | 48 | /* -------------------------------------------------------------------------- |
48 | Embedded Controller | 49 | Embedded Controller |
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 41731236f9a1..9863c98c81ba 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c | |||
@@ -124,29 +124,6 @@ static const struct file_operations acpi_processor_info_fops = { | |||
124 | 124 | ||
125 | DEFINE_PER_CPU(struct acpi_processor *, processors); | 125 | DEFINE_PER_CPU(struct acpi_processor *, processors); |
126 | struct acpi_processor_errata errata __read_mostly; | 126 | struct acpi_processor_errata errata __read_mostly; |
127 | static int set_no_mwait(const struct dmi_system_id *id) | ||
128 | { | ||
129 | printk(KERN_NOTICE PREFIX "%s detected - " | ||
130 | "disabling mwait for CPU C-states\n", id->ident); | ||
131 | idle_nomwait = 1; | ||
132 | return 0; | ||
133 | } | ||
134 | |||
135 | static struct dmi_system_id __cpuinitdata processor_idle_dmi_table[] = { | ||
136 | { | ||
137 | set_no_mwait, "IFL91 board", { | ||
138 | DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"), | ||
139 | DMI_MATCH(DMI_SYS_VENDOR, "ZEPTO"), | ||
140 | DMI_MATCH(DMI_PRODUCT_VERSION, "3215W"), | ||
141 | DMI_MATCH(DMI_BOARD_NAME, "IFL91") }, NULL}, | ||
142 | { | ||
143 | set_no_mwait, "Extensa 5220", { | ||
144 | DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), | ||
145 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
146 | DMI_MATCH(DMI_PRODUCT_VERSION, "0100"), | ||
147 | DMI_MATCH(DMI_BOARD_NAME, "Columbia") }, NULL}, | ||
148 | {}, | ||
149 | }; | ||
150 | 127 | ||
151 | /* -------------------------------------------------------------------------- | 128 | /* -------------------------------------------------------------------------- |
152 | Errata Handling | 129 | Errata Handling |
@@ -277,45 +254,6 @@ static int acpi_processor_errata(struct acpi_processor *pr) | |||
277 | } | 254 | } |
278 | 255 | ||
279 | /* -------------------------------------------------------------------------- | 256 | /* -------------------------------------------------------------------------- |
280 | Common ACPI processor functions | ||
281 | -------------------------------------------------------------------------- */ | ||
282 | |||
283 | /* | ||
284 | * _PDC is required for a BIOS-OS handshake for most of the newer | ||
285 | * ACPI processor features. | ||
286 | */ | ||
287 | static int acpi_processor_set_pdc(struct acpi_processor *pr) | ||
288 | { | ||
289 | struct acpi_object_list *pdc_in = pr->pdc; | ||
290 | acpi_status status = AE_OK; | ||
291 | |||
292 | |||
293 | if (!pdc_in) | ||
294 | return status; | ||
295 | if (idle_nomwait) { | ||
296 | /* | ||
297 | * If mwait is disabled for CPU C-states, the C2C3_FFH access | ||
298 | * mode will be disabled in the parameter of _PDC object. | ||
299 | * Of course C1_FFH access mode will also be disabled. | ||
300 | */ | ||
301 | union acpi_object *obj; | ||
302 | u32 *buffer = NULL; | ||
303 | |||
304 | obj = pdc_in->pointer; | ||
305 | buffer = (u32 *)(obj->buffer.pointer); | ||
306 | buffer[2] &= ~(ACPI_PDC_C_C2C3_FFH | ACPI_PDC_C_C1_FFH); | ||
307 | |||
308 | } | ||
309 | status = acpi_evaluate_object(pr->handle, "_PDC", pdc_in, NULL); | ||
310 | |||
311 | if (ACPI_FAILURE(status)) | ||
312 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
313 | "Could not evaluate _PDC, using legacy perf. control...\n")); | ||
314 | |||
315 | return status; | ||
316 | } | ||
317 | |||
318 | /* -------------------------------------------------------------------------- | ||
319 | FS Interface (/proc) | 257 | FS Interface (/proc) |
320 | -------------------------------------------------------------------------- */ | 258 | -------------------------------------------------------------------------- */ |
321 | 259 | ||
@@ -825,9 +763,7 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device) | |||
825 | } | 763 | } |
826 | 764 | ||
827 | /* _PDC call should be done before doing anything else (if reqd.). */ | 765 | /* _PDC call should be done before doing anything else (if reqd.). */ |
828 | arch_acpi_processor_init_pdc(pr); | 766 | acpi_processor_set_pdc(pr->handle); |
829 | acpi_processor_set_pdc(pr); | ||
830 | arch_acpi_processor_cleanup_pdc(pr); | ||
831 | 767 | ||
832 | #ifdef CONFIG_CPU_FREQ | 768 | #ifdef CONFIG_CPU_FREQ |
833 | acpi_processor_ppc_has_changed(pr, 0); | 769 | acpi_processor_ppc_has_changed(pr, 0); |
@@ -1145,11 +1081,6 @@ static int __init acpi_processor_init(void) | |||
1145 | if (!acpi_processor_dir) | 1081 | if (!acpi_processor_dir) |
1146 | return -ENOMEM; | 1082 | return -ENOMEM; |
1147 | #endif | 1083 | #endif |
1148 | /* | ||
1149 | * Check whether the system is DMI table. If yes, OSPM | ||
1150 | * should not use mwait for CPU-states. | ||
1151 | */ | ||
1152 | dmi_check_system(processor_idle_dmi_table); | ||
1153 | result = cpuidle_register_driver(&acpi_idle_driver); | 1084 | result = cpuidle_register_driver(&acpi_idle_driver); |
1154 | if (result < 0) | 1085 | if (result < 0) |
1155 | goto out_proc; | 1086 | goto out_proc; |
diff --git a/drivers/acpi/processor_pdc.c b/drivers/acpi/processor_pdc.c new file mode 100644 index 000000000000..30e4dc0cdf30 --- /dev/null +++ b/drivers/acpi/processor_pdc.c | |||
@@ -0,0 +1,165 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2005 Intel Corporation | ||
3 | * Copyright (C) 2009 Hewlett-Packard Development Company, L.P. | ||
4 | * | ||
5 | * Alex Chiang <achiang@hp.com> | ||
6 | * - Unified x86/ia64 implementations | ||
7 | * Venkatesh Pallipadi <venkatesh.pallipadi@intel.com> | ||
8 | * - Added _PDC for platforms with Intel CPUs | ||
9 | */ | ||
10 | #include <linux/dmi.h> | ||
11 | |||
12 | #include <acpi/acpi_drivers.h> | ||
13 | #include <acpi/processor.h> | ||
14 | |||
15 | #include "internal.h" | ||
16 | |||
17 | #define PREFIX "ACPI: " | ||
18 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT | ||
19 | ACPI_MODULE_NAME("processor_pdc"); | ||
20 | |||
21 | static int set_no_mwait(const struct dmi_system_id *id) | ||
22 | { | ||
23 | printk(KERN_NOTICE PREFIX "%s detected - " | ||
24 | "disabling mwait for CPU C-states\n", id->ident); | ||
25 | idle_nomwait = 1; | ||
26 | return 0; | ||
27 | } | ||
28 | |||
29 | static struct dmi_system_id __cpuinitdata processor_idle_dmi_table[] = { | ||
30 | { | ||
31 | set_no_mwait, "IFL91 board", { | ||
32 | DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"), | ||
33 | DMI_MATCH(DMI_SYS_VENDOR, "ZEPTO"), | ||
34 | DMI_MATCH(DMI_PRODUCT_VERSION, "3215W"), | ||
35 | DMI_MATCH(DMI_BOARD_NAME, "IFL91") }, NULL}, | ||
36 | { | ||
37 | set_no_mwait, "Extensa 5220", { | ||
38 | DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), | ||
39 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
40 | DMI_MATCH(DMI_PRODUCT_VERSION, "0100"), | ||
41 | DMI_MATCH(DMI_BOARD_NAME, "Columbia") }, NULL}, | ||
42 | {}, | ||
43 | }; | ||
44 | |||
45 | static void acpi_set_pdc_bits(u32 *buf) | ||
46 | { | ||
47 | buf[0] = ACPI_PDC_REVISION_ID; | ||
48 | buf[1] = 1; | ||
49 | |||
50 | /* Enable coordination with firmware's _TSD info */ | ||
51 | buf[2] = ACPI_PDC_SMP_T_SWCOORD; | ||
52 | |||
53 | /* Twiddle arch-specific bits needed for _PDC */ | ||
54 | arch_acpi_set_pdc_bits(buf); | ||
55 | } | ||
56 | |||
57 | static struct acpi_object_list *acpi_processor_alloc_pdc(void) | ||
58 | { | ||
59 | struct acpi_object_list *obj_list; | ||
60 | union acpi_object *obj; | ||
61 | u32 *buf; | ||
62 | |||
63 | /* allocate and initialize pdc. It will be used later. */ | ||
64 | obj_list = kmalloc(sizeof(struct acpi_object_list), GFP_KERNEL); | ||
65 | if (!obj_list) { | ||
66 | printk(KERN_ERR "Memory allocation error\n"); | ||
67 | return NULL; | ||
68 | } | ||
69 | |||
70 | obj = kmalloc(sizeof(union acpi_object), GFP_KERNEL); | ||
71 | if (!obj) { | ||
72 | printk(KERN_ERR "Memory allocation error\n"); | ||
73 | kfree(obj_list); | ||
74 | return NULL; | ||
75 | } | ||
76 | |||
77 | buf = kmalloc(12, GFP_KERNEL); | ||
78 | if (!buf) { | ||
79 | printk(KERN_ERR "Memory allocation error\n"); | ||
80 | kfree(obj); | ||
81 | kfree(obj_list); | ||
82 | return NULL; | ||
83 | } | ||
84 | |||
85 | acpi_set_pdc_bits(buf); | ||
86 | |||
87 | obj->type = ACPI_TYPE_BUFFER; | ||
88 | obj->buffer.length = 12; | ||
89 | obj->buffer.pointer = (u8 *) buf; | ||
90 | obj_list->count = 1; | ||
91 | obj_list->pointer = obj; | ||
92 | |||
93 | return obj_list; | ||
94 | } | ||
95 | |||
96 | /* | ||
97 | * _PDC is required for a BIOS-OS handshake for most of the newer | ||
98 | * ACPI processor features. | ||
99 | */ | ||
100 | static int | ||
101 | acpi_processor_eval_pdc(acpi_handle handle, struct acpi_object_list *pdc_in) | ||
102 | { | ||
103 | acpi_status status = AE_OK; | ||
104 | |||
105 | if (idle_nomwait) { | ||
106 | /* | ||
107 | * If mwait is disabled for CPU C-states, the C2C3_FFH access | ||
108 | * mode will be disabled in the parameter of _PDC object. | ||
109 | * Of course C1_FFH access mode will also be disabled. | ||
110 | */ | ||
111 | union acpi_object *obj; | ||
112 | u32 *buffer = NULL; | ||
113 | |||
114 | obj = pdc_in->pointer; | ||
115 | buffer = (u32 *)(obj->buffer.pointer); | ||
116 | buffer[2] &= ~(ACPI_PDC_C_C2C3_FFH | ACPI_PDC_C_C1_FFH); | ||
117 | |||
118 | } | ||
119 | status = acpi_evaluate_object(handle, "_PDC", pdc_in, NULL); | ||
120 | |||
121 | if (ACPI_FAILURE(status)) | ||
122 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
123 | "Could not evaluate _PDC, using legacy perf. control.\n")); | ||
124 | |||
125 | return status; | ||
126 | } | ||
127 | |||
128 | void acpi_processor_set_pdc(acpi_handle handle) | ||
129 | { | ||
130 | struct acpi_object_list *obj_list; | ||
131 | |||
132 | if (arch_has_acpi_pdc() == false) | ||
133 | return; | ||
134 | |||
135 | obj_list = acpi_processor_alloc_pdc(); | ||
136 | if (!obj_list) | ||
137 | return; | ||
138 | |||
139 | acpi_processor_eval_pdc(handle, obj_list); | ||
140 | |||
141 | kfree(obj_list->pointer->buffer.pointer); | ||
142 | kfree(obj_list->pointer); | ||
143 | kfree(obj_list); | ||
144 | } | ||
145 | EXPORT_SYMBOL_GPL(acpi_processor_set_pdc); | ||
146 | |||
147 | static acpi_status | ||
148 | early_init_pdc(acpi_handle handle, u32 lvl, void *context, void **rv) | ||
149 | { | ||
150 | acpi_processor_set_pdc(handle); | ||
151 | return AE_OK; | ||
152 | } | ||
153 | |||
154 | void acpi_early_processor_set_pdc(void) | ||
155 | { | ||
156 | /* | ||
157 | * Check whether the system is DMI table. If yes, OSPM | ||
158 | * should not use mwait for CPU-states. | ||
159 | */ | ||
160 | dmi_check_system(processor_idle_dmi_table); | ||
161 | |||
162 | acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, | ||
163 | ACPI_UINT32_MAX, | ||
164 | early_init_pdc, NULL, NULL, NULL); | ||
165 | } | ||
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 5f2c379ab7bf..79d33d908b5a 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c | |||
@@ -81,6 +81,23 @@ static int acpi_sleep_prepare(u32 acpi_state) | |||
81 | #ifdef CONFIG_ACPI_SLEEP | 81 | #ifdef CONFIG_ACPI_SLEEP |
82 | static u32 acpi_target_sleep_state = ACPI_STATE_S0; | 82 | static u32 acpi_target_sleep_state = ACPI_STATE_S0; |
83 | /* | 83 | /* |
84 | * According to the ACPI specification the BIOS should make sure that ACPI is | ||
85 | * enabled and SCI_EN bit is set on wake-up from S1 - S3 sleep states. Still, | ||
86 | * some BIOSes don't do that and therefore we use acpi_enable() to enable ACPI | ||
87 | * on such systems during resume. Unfortunately that doesn't help in | ||
88 | * particularly pathological cases in which SCI_EN has to be set directly on | ||
89 | * resume, although the specification states very clearly that this flag is | ||
90 | * owned by the hardware. The set_sci_en_on_resume variable will be set in such | ||
91 | * cases. | ||
92 | */ | ||
93 | static bool set_sci_en_on_resume; | ||
94 | |||
95 | void __init acpi_set_sci_en_on_resume(void) | ||
96 | { | ||
97 | set_sci_en_on_resume = true; | ||
98 | } | ||
99 | |||
100 | /* | ||
84 | * ACPI 1.0 wants us to execute _PTS before suspending devices, so we allow the | 101 | * ACPI 1.0 wants us to execute _PTS before suspending devices, so we allow the |
85 | * user to request that behavior by using the 'acpi_old_suspend_ordering' | 102 | * user to request that behavior by using the 'acpi_old_suspend_ordering' |
86 | * kernel command line option that causes the following variable to be set. | 103 | * kernel command line option that causes the following variable to be set. |
@@ -170,18 +187,6 @@ static void acpi_pm_end(void) | |||
170 | #endif /* CONFIG_ACPI_SLEEP */ | 187 | #endif /* CONFIG_ACPI_SLEEP */ |
171 | 188 | ||
172 | #ifdef CONFIG_SUSPEND | 189 | #ifdef CONFIG_SUSPEND |
173 | /* | ||
174 | * According to the ACPI specification the BIOS should make sure that ACPI is | ||
175 | * enabled and SCI_EN bit is set on wake-up from S1 - S3 sleep states. Still, | ||
176 | * some BIOSes don't do that and therefore we use acpi_enable() to enable ACPI | ||
177 | * on such systems during resume. Unfortunately that doesn't help in | ||
178 | * particularly pathological cases in which SCI_EN has to be set directly on | ||
179 | * resume, although the specification states very clearly that this flag is | ||
180 | * owned by the hardware. The set_sci_en_on_resume variable will be set in such | ||
181 | * cases. | ||
182 | */ | ||
183 | static bool set_sci_en_on_resume; | ||
184 | |||
185 | extern void do_suspend_lowlevel(void); | 190 | extern void do_suspend_lowlevel(void); |
186 | 191 | ||
187 | static u32 acpi_suspend_states[] = { | 192 | static u32 acpi_suspend_states[] = { |
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 05dff631591c..72e76b4b6538 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
@@ -999,8 +999,10 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) | |||
999 | sprintf(name, "acpi_video%d", count++); | 999 | sprintf(name, "acpi_video%d", count++); |
1000 | device->backlight = backlight_device_register(name, | 1000 | device->backlight = backlight_device_register(name, |
1001 | NULL, device, &acpi_backlight_ops); | 1001 | NULL, device, &acpi_backlight_ops); |
1002 | device->backlight->props.max_brightness = device->brightness->count-3; | ||
1003 | kfree(name); | 1002 | kfree(name); |
1003 | if (IS_ERR(device->backlight)) | ||
1004 | return; | ||
1005 | device->backlight->props.max_brightness = device->brightness->count-3; | ||
1004 | 1006 | ||
1005 | result = sysfs_create_link(&device->backlight->dev.kobj, | 1007 | result = sysfs_create_link(&device->backlight->dev.kobj, |
1006 | &device->dev->dev.kobj, "device"); | 1008 | &device->dev->dev.kobj, "device"); |
@@ -1979,6 +1981,10 @@ acpi_video_switch_brightness(struct acpi_video_device *device, int event) | |||
1979 | unsigned long long level_current, level_next; | 1981 | unsigned long long level_current, level_next; |
1980 | int result = -EINVAL; | 1982 | int result = -EINVAL; |
1981 | 1983 | ||
1984 | /* no warning message if acpi_backlight=vendor is used */ | ||
1985 | if (!acpi_video_backlight_support()) | ||
1986 | return 0; | ||
1987 | |||
1982 | if (!device->brightness) | 1988 | if (!device->brightness) |
1983 | goto out; | 1989 | goto out; |
1984 | 1990 | ||
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 85844d053846..56c6374a3989 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig | |||
@@ -40,7 +40,6 @@ config ATA_VERBOSE_ERROR | |||
40 | config ATA_ACPI | 40 | config ATA_ACPI |
41 | bool "ATA ACPI Support" | 41 | bool "ATA ACPI Support" |
42 | depends on ACPI && PCI | 42 | depends on ACPI && PCI |
43 | select ACPI_DOCK | ||
44 | default y | 43 | default y |
45 | help | 44 | help |
46 | This option adds support for ATA-related ACPI objects. | 45 | This option adds support for ATA-related ACPI objects. |
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 1683ebda900b..f4ea5a8c325b 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c | |||
@@ -3022,7 +3022,7 @@ static inline ata_xlat_func_t ata_get_xlat_func(struct ata_device *dev, u8 cmd) | |||
3022 | case WRITE_16: | 3022 | case WRITE_16: |
3023 | return ata_scsi_rw_xlat; | 3023 | return ata_scsi_rw_xlat; |
3024 | 3024 | ||
3025 | case 0x93 /*WRITE_SAME_16*/: | 3025 | case WRITE_SAME_16: |
3026 | return ata_scsi_write_same_xlat; | 3026 | return ata_scsi_write_same_xlat; |
3027 | 3027 | ||
3028 | case SYNCHRONIZE_CACHE: | 3028 | case SYNCHRONIZE_CACHE: |
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index efa8773bef5a..741065c9da67 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c | |||
@@ -2275,7 +2275,7 @@ void ata_sff_drain_fifo(struct ata_queued_cmd *qc) | |||
2275 | ap = qc->ap; | 2275 | ap = qc->ap; |
2276 | /* Drain up to 64K of data before we give up this recovery method */ | 2276 | /* Drain up to 64K of data before we give up this recovery method */ |
2277 | for (count = 0; (ap->ops->sff_check_status(ap) & ATA_DRQ) | 2277 | for (count = 0; (ap->ops->sff_check_status(ap) & ATA_DRQ) |
2278 | && count < 32768; count++) | 2278 | && count < 65536; count += 2) |
2279 | ioread16(ap->ioaddr.data_addr); | 2279 | ioread16(ap->ioaddr.data_addr); |
2280 | 2280 | ||
2281 | /* Can become DEBUG later */ | 2281 | /* Can become DEBUG later */ |
diff --git a/drivers/ata/pata_bf54x.c b/drivers/ata/pata_bf54x.c index c4b47a3e5446..02c81f12c702 100644 --- a/drivers/ata/pata_bf54x.c +++ b/drivers/ata/pata_bf54x.c | |||
@@ -1557,6 +1557,25 @@ static unsigned short atapi_io_port[] = { | |||
1557 | P_ATAPI_DMARQ, | 1557 | P_ATAPI_DMARQ, |
1558 | P_ATAPI_INTRQ, | 1558 | P_ATAPI_INTRQ, |
1559 | P_ATAPI_IORDY, | 1559 | P_ATAPI_IORDY, |
1560 | P_ATAPI_D0A, | ||
1561 | P_ATAPI_D1A, | ||
1562 | P_ATAPI_D2A, | ||
1563 | P_ATAPI_D3A, | ||
1564 | P_ATAPI_D4A, | ||
1565 | P_ATAPI_D5A, | ||
1566 | P_ATAPI_D6A, | ||
1567 | P_ATAPI_D7A, | ||
1568 | P_ATAPI_D8A, | ||
1569 | P_ATAPI_D9A, | ||
1570 | P_ATAPI_D10A, | ||
1571 | P_ATAPI_D11A, | ||
1572 | P_ATAPI_D12A, | ||
1573 | P_ATAPI_D13A, | ||
1574 | P_ATAPI_D14A, | ||
1575 | P_ATAPI_D15A, | ||
1576 | P_ATAPI_A0A, | ||
1577 | P_ATAPI_A1A, | ||
1578 | P_ATAPI_A2A, | ||
1560 | 0 | 1579 | 0 |
1561 | }; | 1580 | }; |
1562 | 1581 | ||
diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c index dadfc358ba1c..0efb1f58f255 100644 --- a/drivers/ata/pata_cmd64x.c +++ b/drivers/ata/pata_cmd64x.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #include <linux/libata.h> | 31 | #include <linux/libata.h> |
32 | 32 | ||
33 | #define DRV_NAME "pata_cmd64x" | 33 | #define DRV_NAME "pata_cmd64x" |
34 | #define DRV_VERSION "0.3.1" | 34 | #define DRV_VERSION "0.2.5" |
35 | 35 | ||
36 | /* | 36 | /* |
37 | * CMD64x specific registers definition. | 37 | * CMD64x specific registers definition. |
@@ -219,7 +219,7 @@ static void cmd64x_set_dmamode(struct ata_port *ap, struct ata_device *adev) | |||
219 | regU |= udma_data[adev->dma_mode - XFER_UDMA_0] << shift; | 219 | regU |= udma_data[adev->dma_mode - XFER_UDMA_0] << shift; |
220 | /* Merge the control bits */ | 220 | /* Merge the control bits */ |
221 | regU |= 1 << adev->devno; /* UDMA on */ | 221 | regU |= 1 << adev->devno; /* UDMA on */ |
222 | if (adev->dma_mode > 2) /* 15nS timing */ | 222 | if (adev->dma_mode > XFER_UDMA_2) /* 15nS timing */ |
223 | regU |= 4 << adev->devno; | 223 | regU |= 4 << adev->devno; |
224 | } else { | 224 | } else { |
225 | regU &= ~ (1 << adev->devno); /* UDMA off */ | 225 | regU &= ~ (1 << adev->devno); /* UDMA off */ |
@@ -254,109 +254,17 @@ static void cmd648_bmdma_stop(struct ata_queued_cmd *qc) | |||
254 | } | 254 | } |
255 | 255 | ||
256 | /** | 256 | /** |
257 | * cmd64x_bmdma_stop - DMA stop callback | 257 | * cmd646r1_dma_stop - DMA stop callback |
258 | * @qc: Command in progress | 258 | * @qc: Command in progress |
259 | * | 259 | * |
260 | * Track the completion of live DMA commands and clear the | 260 | * Stub for now while investigating the r1 quirk in the old driver. |
261 | * host->private_data DMA tracking flag as we do. | ||
262 | */ | 261 | */ |
263 | 262 | ||
264 | static void cmd64x_bmdma_stop(struct ata_queued_cmd *qc) | 263 | static void cmd646r1_bmdma_stop(struct ata_queued_cmd *qc) |
265 | { | 264 | { |
266 | struct ata_port *ap = qc->ap; | ||
267 | ata_bmdma_stop(qc); | 265 | ata_bmdma_stop(qc); |
268 | WARN_ON(ap->host->private_data != ap); | ||
269 | ap->host->private_data = NULL; | ||
270 | } | ||
271 | |||
272 | /** | ||
273 | * cmd64x_qc_defer - Defer logic for chip limits | ||
274 | * @qc: queued command | ||
275 | * | ||
276 | * Decide whether we can issue the command. Called under the host lock. | ||
277 | */ | ||
278 | |||
279 | static int cmd64x_qc_defer(struct ata_queued_cmd *qc) | ||
280 | { | ||
281 | struct ata_host *host = qc->ap->host; | ||
282 | struct ata_port *alt = host->ports[1 ^ qc->ap->port_no]; | ||
283 | int rc; | ||
284 | int dma = 0; | ||
285 | |||
286 | /* Apply the ATA rules first */ | ||
287 | rc = ata_std_qc_defer(qc); | ||
288 | if (rc) | ||
289 | return rc; | ||
290 | |||
291 | if (qc->tf.protocol == ATAPI_PROT_DMA || | ||
292 | qc->tf.protocol == ATA_PROT_DMA) | ||
293 | dma = 1; | ||
294 | |||
295 | /* If the other port is not live then issue the command */ | ||
296 | if (alt == NULL || !alt->qc_active) { | ||
297 | if (dma) | ||
298 | host->private_data = qc->ap; | ||
299 | return 0; | ||
300 | } | ||
301 | /* If there is a live DMA command then wait */ | ||
302 | if (host->private_data != NULL) | ||
303 | return ATA_DEFER_PORT; | ||
304 | if (dma) | ||
305 | /* Cannot overlap our DMA command */ | ||
306 | return ATA_DEFER_PORT; | ||
307 | return 0; | ||
308 | } | 266 | } |
309 | 267 | ||
310 | /** | ||
311 | * cmd64x_interrupt - ATA host interrupt handler | ||
312 | * @irq: irq line (unused) | ||
313 | * @dev_instance: pointer to our ata_host information structure | ||
314 | * | ||
315 | * Our interrupt handler for PCI IDE devices. Calls | ||
316 | * ata_sff_host_intr() for each port that is flagging an IRQ. We cannot | ||
317 | * use the defaults as we need to avoid touching status/altstatus during | ||
318 | * a DMA. | ||
319 | * | ||
320 | * LOCKING: | ||
321 | * Obtains host lock during operation. | ||
322 | * | ||
323 | * RETURNS: | ||
324 | * IRQ_NONE or IRQ_HANDLED. | ||
325 | */ | ||
326 | irqreturn_t cmd64x_interrupt(int irq, void *dev_instance) | ||
327 | { | ||
328 | struct ata_host *host = dev_instance; | ||
329 | struct pci_dev *pdev = to_pci_dev(host->dev); | ||
330 | unsigned int i; | ||
331 | unsigned int handled = 0; | ||
332 | unsigned long flags; | ||
333 | static const u8 irq_reg[2] = { CFR, ARTTIM23 }; | ||
334 | static const u8 irq_mask[2] = { 1 << 2, 1 << 4 }; | ||
335 | |||
336 | /* TODO: make _irqsave conditional on x86 PCI IDE legacy mode */ | ||
337 | spin_lock_irqsave(&host->lock, flags); | ||
338 | |||
339 | for (i = 0; i < host->n_ports; i++) { | ||
340 | struct ata_port *ap; | ||
341 | u8 reg; | ||
342 | |||
343 | pci_read_config_byte(pdev, irq_reg[i], ®); | ||
344 | ap = host->ports[i]; | ||
345 | if (ap && (reg & irq_mask[i]) && | ||
346 | !(ap->flags & ATA_FLAG_DISABLED)) { | ||
347 | struct ata_queued_cmd *qc; | ||
348 | |||
349 | qc = ata_qc_from_tag(ap, ap->link.active_tag); | ||
350 | if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING)) && | ||
351 | (qc->flags & ATA_QCFLAG_ACTIVE)) | ||
352 | handled |= ata_sff_host_intr(ap, qc); | ||
353 | } | ||
354 | } | ||
355 | |||
356 | spin_unlock_irqrestore(&host->lock, flags); | ||
357 | |||
358 | return IRQ_RETVAL(handled); | ||
359 | } | ||
360 | static struct scsi_host_template cmd64x_sht = { | 268 | static struct scsi_host_template cmd64x_sht = { |
361 | ATA_BMDMA_SHT(DRV_NAME), | 269 | ATA_BMDMA_SHT(DRV_NAME), |
362 | }; | 270 | }; |
@@ -365,8 +273,6 @@ static const struct ata_port_operations cmd64x_base_ops = { | |||
365 | .inherits = &ata_bmdma_port_ops, | 273 | .inherits = &ata_bmdma_port_ops, |
366 | .set_piomode = cmd64x_set_piomode, | 274 | .set_piomode = cmd64x_set_piomode, |
367 | .set_dmamode = cmd64x_set_dmamode, | 275 | .set_dmamode = cmd64x_set_dmamode, |
368 | .bmdma_stop = cmd64x_bmdma_stop, | ||
369 | .qc_defer = cmd64x_qc_defer, | ||
370 | }; | 276 | }; |
371 | 277 | ||
372 | static struct ata_port_operations cmd64x_port_ops = { | 278 | static struct ata_port_operations cmd64x_port_ops = { |
@@ -376,6 +282,7 @@ static struct ata_port_operations cmd64x_port_ops = { | |||
376 | 282 | ||
377 | static struct ata_port_operations cmd646r1_port_ops = { | 283 | static struct ata_port_operations cmd646r1_port_ops = { |
378 | .inherits = &cmd64x_base_ops, | 284 | .inherits = &cmd64x_base_ops, |
285 | .bmdma_stop = cmd646r1_bmdma_stop, | ||
379 | .cable_detect = ata_cable_40wire, | 286 | .cable_detect = ata_cable_40wire, |
380 | }; | 287 | }; |
381 | 288 | ||
@@ -383,7 +290,6 @@ static struct ata_port_operations cmd648_port_ops = { | |||
383 | .inherits = &cmd64x_base_ops, | 290 | .inherits = &cmd64x_base_ops, |
384 | .bmdma_stop = cmd648_bmdma_stop, | 291 | .bmdma_stop = cmd648_bmdma_stop, |
385 | .cable_detect = cmd648_cable_detect, | 292 | .cable_detect = cmd648_cable_detect, |
386 | .qc_defer = ata_std_qc_defer | ||
387 | }; | 293 | }; |
388 | 294 | ||
389 | static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | 295 | static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) |
@@ -432,7 +338,6 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
432 | const struct ata_port_info *ppi[] = { &cmd_info[id->driver_data], NULL }; | 338 | const struct ata_port_info *ppi[] = { &cmd_info[id->driver_data], NULL }; |
433 | u8 mrdmode; | 339 | u8 mrdmode; |
434 | int rc; | 340 | int rc; |
435 | struct ata_host *host; | ||
436 | 341 | ||
437 | rc = pcim_enable_device(pdev); | 342 | rc = pcim_enable_device(pdev); |
438 | if (rc) | 343 | if (rc) |
@@ -450,25 +355,20 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
450 | ppi[0] = &cmd_info[3]; | 355 | ppi[0] = &cmd_info[3]; |
451 | } | 356 | } |
452 | 357 | ||
453 | |||
454 | pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 64); | 358 | pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 64); |
455 | pci_read_config_byte(pdev, MRDMODE, &mrdmode); | 359 | pci_read_config_byte(pdev, MRDMODE, &mrdmode); |
456 | mrdmode &= ~ 0x30; /* IRQ set up */ | 360 | mrdmode &= ~ 0x30; /* IRQ set up */ |
457 | mrdmode |= 0x02; /* Memory read line enable */ | 361 | mrdmode |= 0x02; /* Memory read line enable */ |
458 | pci_write_config_byte(pdev, MRDMODE, mrdmode); | 362 | pci_write_config_byte(pdev, MRDMODE, mrdmode); |
459 | 363 | ||
364 | /* Force PIO 0 here.. */ | ||
365 | |||
460 | /* PPC specific fixup copied from old driver */ | 366 | /* PPC specific fixup copied from old driver */ |
461 | #ifdef CONFIG_PPC | 367 | #ifdef CONFIG_PPC |
462 | pci_write_config_byte(pdev, UDIDETCR0, 0xF0); | 368 | pci_write_config_byte(pdev, UDIDETCR0, 0xF0); |
463 | #endif | 369 | #endif |
464 | rc = ata_pci_sff_prepare_host(pdev, ppi, &host); | ||
465 | if (rc) | ||
466 | return rc; | ||
467 | /* We use this pointer to track the AP which has DMA running */ | ||
468 | host->private_data = NULL; | ||
469 | 370 | ||
470 | pci_set_master(pdev); | 371 | return ata_pci_sff_init_one(pdev, ppi, &cmd64x_sht, NULL); |
471 | return ata_pci_sff_activate_host(host, cmd64x_interrupt, &cmd64x_sht); | ||
472 | } | 372 | } |
473 | 373 | ||
474 | #ifdef CONFIG_PM | 374 | #ifdef CONFIG_PM |
diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c index 9a09a1b11ca5..dd26bc73bd9a 100644 --- a/drivers/ata/pata_hpt3x2n.c +++ b/drivers/ata/pata_hpt3x2n.c | |||
@@ -8,7 +8,7 @@ | |||
8 | * Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org> | 8 | * Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org> |
9 | * Portions Copyright (C) 2001 Sun Microsystems, Inc. | 9 | * Portions Copyright (C) 2001 Sun Microsystems, Inc. |
10 | * Portions Copyright (C) 2003 Red Hat Inc | 10 | * Portions Copyright (C) 2003 Red Hat Inc |
11 | * Portions Copyright (C) 2005-2007 MontaVista Software, Inc. | 11 | * Portions Copyright (C) 2005-2009 MontaVista Software, Inc. |
12 | * | 12 | * |
13 | * | 13 | * |
14 | * TODO | 14 | * TODO |
@@ -25,7 +25,7 @@ | |||
25 | #include <linux/libata.h> | 25 | #include <linux/libata.h> |
26 | 26 | ||
27 | #define DRV_NAME "pata_hpt3x2n" | 27 | #define DRV_NAME "pata_hpt3x2n" |
28 | #define DRV_VERSION "0.3.7" | 28 | #define DRV_VERSION "0.3.8" |
29 | 29 | ||
30 | enum { | 30 | enum { |
31 | HPT_PCI_FAST = (1 << 31), | 31 | HPT_PCI_FAST = (1 << 31), |
@@ -264,7 +264,7 @@ static void hpt3x2n_bmdma_stop(struct ata_queued_cmd *qc) | |||
264 | 264 | ||
265 | static void hpt3x2n_set_clock(struct ata_port *ap, int source) | 265 | static void hpt3x2n_set_clock(struct ata_port *ap, int source) |
266 | { | 266 | { |
267 | void __iomem *bmdma = ap->ioaddr.bmdma_addr; | 267 | void __iomem *bmdma = ap->ioaddr.bmdma_addr - ap->port_no * 8; |
268 | 268 | ||
269 | /* Tristate the bus */ | 269 | /* Tristate the bus */ |
270 | iowrite8(0x80, bmdma+0x73); | 270 | iowrite8(0x80, bmdma+0x73); |
@@ -274,9 +274,9 @@ static void hpt3x2n_set_clock(struct ata_port *ap, int source) | |||
274 | iowrite8(source, bmdma+0x7B); | 274 | iowrite8(source, bmdma+0x7B); |
275 | iowrite8(0xC0, bmdma+0x79); | 275 | iowrite8(0xC0, bmdma+0x79); |
276 | 276 | ||
277 | /* Reset state machines */ | 277 | /* Reset state machines, avoid enabling the disabled channels */ |
278 | iowrite8(0x37, bmdma+0x70); | 278 | iowrite8(ioread8(bmdma+0x70) | 0x32, bmdma+0x70); |
279 | iowrite8(0x37, bmdma+0x74); | 279 | iowrite8(ioread8(bmdma+0x74) | 0x32, bmdma+0x74); |
280 | 280 | ||
281 | /* Complete reset */ | 281 | /* Complete reset */ |
282 | iowrite8(0x00, bmdma+0x79); | 282 | iowrite8(0x00, bmdma+0x79); |
@@ -286,21 +286,10 @@ static void hpt3x2n_set_clock(struct ata_port *ap, int source) | |||
286 | iowrite8(0x00, bmdma+0x77); | 286 | iowrite8(0x00, bmdma+0x77); |
287 | } | 287 | } |
288 | 288 | ||
289 | /* Check if our partner interface is busy */ | ||
290 | |||
291 | static int hpt3x2n_pair_idle(struct ata_port *ap) | ||
292 | { | ||
293 | struct ata_host *host = ap->host; | ||
294 | struct ata_port *pair = host->ports[ap->port_no ^ 1]; | ||
295 | |||
296 | if (pair->hsm_task_state == HSM_ST_IDLE) | ||
297 | return 1; | ||
298 | return 0; | ||
299 | } | ||
300 | |||
301 | static int hpt3x2n_use_dpll(struct ata_port *ap, int writing) | 289 | static int hpt3x2n_use_dpll(struct ata_port *ap, int writing) |
302 | { | 290 | { |
303 | long flags = (long)ap->host->private_data; | 291 | long flags = (long)ap->host->private_data; |
292 | |||
304 | /* See if we should use the DPLL */ | 293 | /* See if we should use the DPLL */ |
305 | if (writing) | 294 | if (writing) |
306 | return USE_DPLL; /* Needed for write */ | 295 | return USE_DPLL; /* Needed for write */ |
@@ -309,20 +298,35 @@ static int hpt3x2n_use_dpll(struct ata_port *ap, int writing) | |||
309 | return 0; | 298 | return 0; |
310 | } | 299 | } |
311 | 300 | ||
301 | static int hpt3x2n_qc_defer(struct ata_queued_cmd *qc) | ||
302 | { | ||
303 | struct ata_port *ap = qc->ap; | ||
304 | struct ata_port *alt = ap->host->ports[ap->port_no ^ 1]; | ||
305 | int rc, flags = (long)ap->host->private_data; | ||
306 | int dpll = hpt3x2n_use_dpll(ap, qc->tf.flags & ATA_TFLAG_WRITE); | ||
307 | |||
308 | /* First apply the usual rules */ | ||
309 | rc = ata_std_qc_defer(qc); | ||
310 | if (rc != 0) | ||
311 | return rc; | ||
312 | |||
313 | if ((flags & USE_DPLL) != dpll && alt->qc_active) | ||
314 | return ATA_DEFER_PORT; | ||
315 | return 0; | ||
316 | } | ||
317 | |||
312 | static unsigned int hpt3x2n_qc_issue(struct ata_queued_cmd *qc) | 318 | static unsigned int hpt3x2n_qc_issue(struct ata_queued_cmd *qc) |
313 | { | 319 | { |
314 | struct ata_taskfile *tf = &qc->tf; | ||
315 | struct ata_port *ap = qc->ap; | 320 | struct ata_port *ap = qc->ap; |
316 | int flags = (long)ap->host->private_data; | 321 | int flags = (long)ap->host->private_data; |
322 | int dpll = hpt3x2n_use_dpll(ap, qc->tf.flags & ATA_TFLAG_WRITE); | ||
317 | 323 | ||
318 | if (hpt3x2n_pair_idle(ap)) { | 324 | if ((flags & USE_DPLL) != dpll) { |
319 | int dpll = hpt3x2n_use_dpll(ap, (tf->flags & ATA_TFLAG_WRITE)); | 325 | flags &= ~USE_DPLL; |
320 | if ((flags & USE_DPLL) != dpll) { | 326 | flags |= dpll; |
321 | if (dpll == 1) | 327 | ap->host->private_data = (void *)(long)flags; |
322 | hpt3x2n_set_clock(ap, 0x21); | 328 | |
323 | else | 329 | hpt3x2n_set_clock(ap, dpll ? 0x21 : 0x23); |
324 | hpt3x2n_set_clock(ap, 0x23); | ||
325 | } | ||
326 | } | 330 | } |
327 | return ata_sff_qc_issue(qc); | 331 | return ata_sff_qc_issue(qc); |
328 | } | 332 | } |
@@ -339,6 +343,8 @@ static struct ata_port_operations hpt3x2n_port_ops = { | |||
339 | .inherits = &ata_bmdma_port_ops, | 343 | .inherits = &ata_bmdma_port_ops, |
340 | 344 | ||
341 | .bmdma_stop = hpt3x2n_bmdma_stop, | 345 | .bmdma_stop = hpt3x2n_bmdma_stop, |
346 | |||
347 | .qc_defer = hpt3x2n_qc_defer, | ||
342 | .qc_issue = hpt3x2n_qc_issue, | 348 | .qc_issue = hpt3x2n_qc_issue, |
343 | 349 | ||
344 | .cable_detect = hpt3x2n_cable_detect, | 350 | .cable_detect = hpt3x2n_cable_detect, |
@@ -454,7 +460,7 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
454 | unsigned int f_low, f_high; | 460 | unsigned int f_low, f_high; |
455 | int adjust; | 461 | int adjust; |
456 | unsigned long iobase = pci_resource_start(dev, 4); | 462 | unsigned long iobase = pci_resource_start(dev, 4); |
457 | void *hpriv = NULL; | 463 | void *hpriv = (void *)USE_DPLL; |
458 | int rc; | 464 | int rc; |
459 | 465 | ||
460 | rc = pcim_enable_device(dev); | 466 | rc = pcim_enable_device(dev); |
@@ -539,7 +545,7 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
539 | /* Set our private data up. We only need a few flags so we use | 545 | /* Set our private data up. We only need a few flags so we use |
540 | it directly */ | 546 | it directly */ |
541 | if (pci_mhz > 60) { | 547 | if (pci_mhz > 60) { |
542 | hpriv = (void *)PCI66; | 548 | hpriv = (void *)(PCI66 | USE_DPLL); |
543 | /* | 549 | /* |
544 | * On HPT371N, if ATA clock is 66 MHz we must set bit 2 in | 550 | * On HPT371N, if ATA clock is 66 MHz we must set bit 2 in |
545 | * the MISC. register to stretch the UltraDMA Tss timing. | 551 | * the MISC. register to stretch the UltraDMA Tss timing. |
diff --git a/drivers/ata/pata_octeon_cf.c b/drivers/ata/pata_octeon_cf.c index d6f69561dc86..37ef416c1242 100644 --- a/drivers/ata/pata_octeon_cf.c +++ b/drivers/ata/pata_octeon_cf.c | |||
@@ -853,7 +853,7 @@ static int __devinit octeon_cf_probe(struct platform_device *pdev) | |||
853 | return -EINVAL; | 853 | return -EINVAL; |
854 | 854 | ||
855 | cs1 = devm_ioremap_nocache(&pdev->dev, res_cs1->start, | 855 | cs1 = devm_ioremap_nocache(&pdev->dev, res_cs1->start, |
856 | res_cs0->end - res_cs1->start + 1); | 856 | resource_size(res_cs1)); |
857 | 857 | ||
858 | if (!cs1) | 858 | if (!cs1) |
859 | return -ENOMEM; | 859 | return -ENOMEM; |
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index a8a7be0d06ff..df8ee325d3ca 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c | |||
@@ -59,6 +59,7 @@ | |||
59 | #include <linux/dmapool.h> | 59 | #include <linux/dmapool.h> |
60 | #include <linux/dma-mapping.h> | 60 | #include <linux/dma-mapping.h> |
61 | #include <linux/device.h> | 61 | #include <linux/device.h> |
62 | #include <linux/clk.h> | ||
62 | #include <linux/platform_device.h> | 63 | #include <linux/platform_device.h> |
63 | #include <linux/ata_platform.h> | 64 | #include <linux/ata_platform.h> |
64 | #include <linux/mbus.h> | 65 | #include <linux/mbus.h> |
@@ -538,6 +539,7 @@ struct mv_port_signal { | |||
538 | 539 | ||
539 | struct mv_host_priv { | 540 | struct mv_host_priv { |
540 | u32 hp_flags; | 541 | u32 hp_flags; |
542 | unsigned int board_idx; | ||
541 | u32 main_irq_mask; | 543 | u32 main_irq_mask; |
542 | struct mv_port_signal signal[8]; | 544 | struct mv_port_signal signal[8]; |
543 | const struct mv_hw_ops *ops; | 545 | const struct mv_hw_ops *ops; |
@@ -548,6 +550,10 @@ struct mv_host_priv { | |||
548 | u32 irq_cause_offset; | 550 | u32 irq_cause_offset; |
549 | u32 irq_mask_offset; | 551 | u32 irq_mask_offset; |
550 | u32 unmask_all_irqs; | 552 | u32 unmask_all_irqs; |
553 | |||
554 | #if defined(CONFIG_HAVE_CLK) | ||
555 | struct clk *clk; | ||
556 | #endif | ||
551 | /* | 557 | /* |
552 | * These consistent DMA memory pools give us guaranteed | 558 | * These consistent DMA memory pools give us guaranteed |
553 | * alignment for hardware-accessed data structures, | 559 | * alignment for hardware-accessed data structures, |
@@ -2775,7 +2781,7 @@ static void mv_port_intr(struct ata_port *ap, u32 port_cause) | |||
2775 | struct mv_port_priv *pp; | 2781 | struct mv_port_priv *pp; |
2776 | int edma_was_enabled; | 2782 | int edma_was_enabled; |
2777 | 2783 | ||
2778 | if (!ap || (ap->flags & ATA_FLAG_DISABLED)) { | 2784 | if (ap->flags & ATA_FLAG_DISABLED) { |
2779 | mv_unexpected_intr(ap, 0); | 2785 | mv_unexpected_intr(ap, 0); |
2780 | return; | 2786 | return; |
2781 | } | 2787 | } |
@@ -3393,7 +3399,7 @@ static void mv_soc_reset_hc_port(struct mv_host_priv *hpriv, | |||
3393 | ZERO(0x024); /* respq outp */ | 3399 | ZERO(0x024); /* respq outp */ |
3394 | ZERO(0x020); /* respq inp */ | 3400 | ZERO(0x020); /* respq inp */ |
3395 | ZERO(0x02c); /* test control */ | 3401 | ZERO(0x02c); /* test control */ |
3396 | writel(0xbc, port_mmio + EDMA_IORDY_TMOUT); | 3402 | writel(0x800, port_mmio + EDMA_IORDY_TMOUT); |
3397 | } | 3403 | } |
3398 | 3404 | ||
3399 | #undef ZERO | 3405 | #undef ZERO |
@@ -3854,7 +3860,6 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx) | |||
3854 | /** | 3860 | /** |
3855 | * mv_init_host - Perform some early initialization of the host. | 3861 | * mv_init_host - Perform some early initialization of the host. |
3856 | * @host: ATA host to initialize | 3862 | * @host: ATA host to initialize |
3857 | * @board_idx: controller index | ||
3858 | * | 3863 | * |
3859 | * If possible, do an early global reset of the host. Then do | 3864 | * If possible, do an early global reset of the host. Then do |
3860 | * our port init and clear/unmask all/relevant host interrupts. | 3865 | * our port init and clear/unmask all/relevant host interrupts. |
@@ -3862,13 +3867,13 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx) | |||
3862 | * LOCKING: | 3867 | * LOCKING: |
3863 | * Inherited from caller. | 3868 | * Inherited from caller. |
3864 | */ | 3869 | */ |
3865 | static int mv_init_host(struct ata_host *host, unsigned int board_idx) | 3870 | static int mv_init_host(struct ata_host *host) |
3866 | { | 3871 | { |
3867 | int rc = 0, n_hc, port, hc; | 3872 | int rc = 0, n_hc, port, hc; |
3868 | struct mv_host_priv *hpriv = host->private_data; | 3873 | struct mv_host_priv *hpriv = host->private_data; |
3869 | void __iomem *mmio = hpriv->base; | 3874 | void __iomem *mmio = hpriv->base; |
3870 | 3875 | ||
3871 | rc = mv_chip_id(host, board_idx); | 3876 | rc = mv_chip_id(host, hpriv->board_idx); |
3872 | if (rc) | 3877 | if (rc) |
3873 | goto done; | 3878 | goto done; |
3874 | 3879 | ||
@@ -3905,14 +3910,6 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx) | |||
3905 | void __iomem *port_mmio = mv_port_base(mmio, port); | 3910 | void __iomem *port_mmio = mv_port_base(mmio, port); |
3906 | 3911 | ||
3907 | mv_port_init(&ap->ioaddr, port_mmio); | 3912 | mv_port_init(&ap->ioaddr, port_mmio); |
3908 | |||
3909 | #ifdef CONFIG_PCI | ||
3910 | if (!IS_SOC(hpriv)) { | ||
3911 | unsigned int offset = port_mmio - mmio; | ||
3912 | ata_port_pbar_desc(ap, MV_PRIMARY_BAR, -1, "mmio"); | ||
3913 | ata_port_pbar_desc(ap, MV_PRIMARY_BAR, offset, "port"); | ||
3914 | } | ||
3915 | #endif | ||
3916 | } | 3913 | } |
3917 | 3914 | ||
3918 | for (hc = 0; hc < n_hc; hc++) { | 3915 | for (hc = 0; hc < n_hc; hc++) { |
@@ -4035,12 +4032,21 @@ static int mv_platform_probe(struct platform_device *pdev) | |||
4035 | return -ENOMEM; | 4032 | return -ENOMEM; |
4036 | host->private_data = hpriv; | 4033 | host->private_data = hpriv; |
4037 | hpriv->n_ports = n_ports; | 4034 | hpriv->n_ports = n_ports; |
4035 | hpriv->board_idx = chip_soc; | ||
4038 | 4036 | ||
4039 | host->iomap = NULL; | 4037 | host->iomap = NULL; |
4040 | hpriv->base = devm_ioremap(&pdev->dev, res->start, | 4038 | hpriv->base = devm_ioremap(&pdev->dev, res->start, |
4041 | resource_size(res)); | 4039 | resource_size(res)); |
4042 | hpriv->base -= SATAHC0_REG_BASE; | 4040 | hpriv->base -= SATAHC0_REG_BASE; |
4043 | 4041 | ||
4042 | #if defined(CONFIG_HAVE_CLK) | ||
4043 | hpriv->clk = clk_get(&pdev->dev, NULL); | ||
4044 | if (IS_ERR(hpriv->clk)) | ||
4045 | dev_notice(&pdev->dev, "cannot get clkdev\n"); | ||
4046 | else | ||
4047 | clk_enable(hpriv->clk); | ||
4048 | #endif | ||
4049 | |||
4044 | /* | 4050 | /* |
4045 | * (Re-)program MBUS remapping windows if we are asked to. | 4051 | * (Re-)program MBUS remapping windows if we are asked to. |
4046 | */ | 4052 | */ |
@@ -4049,12 +4055,12 @@ static int mv_platform_probe(struct platform_device *pdev) | |||
4049 | 4055 | ||
4050 | rc = mv_create_dma_pools(hpriv, &pdev->dev); | 4056 | rc = mv_create_dma_pools(hpriv, &pdev->dev); |
4051 | if (rc) | 4057 | if (rc) |
4052 | return rc; | 4058 | goto err; |
4053 | 4059 | ||
4054 | /* initialize adapter */ | 4060 | /* initialize adapter */ |
4055 | rc = mv_init_host(host, chip_soc); | 4061 | rc = mv_init_host(host); |
4056 | if (rc) | 4062 | if (rc) |
4057 | return rc; | 4063 | goto err; |
4058 | 4064 | ||
4059 | dev_printk(KERN_INFO, &pdev->dev, | 4065 | dev_printk(KERN_INFO, &pdev->dev, |
4060 | "slots %u ports %d\n", (unsigned)MV_MAX_Q_DEPTH, | 4066 | "slots %u ports %d\n", (unsigned)MV_MAX_Q_DEPTH, |
@@ -4062,6 +4068,15 @@ static int mv_platform_probe(struct platform_device *pdev) | |||
4062 | 4068 | ||
4063 | return ata_host_activate(host, platform_get_irq(pdev, 0), mv_interrupt, | 4069 | return ata_host_activate(host, platform_get_irq(pdev, 0), mv_interrupt, |
4064 | IRQF_SHARED, &mv6_sht); | 4070 | IRQF_SHARED, &mv6_sht); |
4071 | err: | ||
4072 | #if defined(CONFIG_HAVE_CLK) | ||
4073 | if (!IS_ERR(hpriv->clk)) { | ||
4074 | clk_disable(hpriv->clk); | ||
4075 | clk_put(hpriv->clk); | ||
4076 | } | ||
4077 | #endif | ||
4078 | |||
4079 | return rc; | ||
4065 | } | 4080 | } |
4066 | 4081 | ||
4067 | /* | 4082 | /* |
@@ -4076,14 +4091,66 @@ static int __devexit mv_platform_remove(struct platform_device *pdev) | |||
4076 | { | 4091 | { |
4077 | struct device *dev = &pdev->dev; | 4092 | struct device *dev = &pdev->dev; |
4078 | struct ata_host *host = dev_get_drvdata(dev); | 4093 | struct ata_host *host = dev_get_drvdata(dev); |
4079 | 4094 | #if defined(CONFIG_HAVE_CLK) | |
4095 | struct mv_host_priv *hpriv = host->private_data; | ||
4096 | #endif | ||
4080 | ata_host_detach(host); | 4097 | ata_host_detach(host); |
4098 | |||
4099 | #if defined(CONFIG_HAVE_CLK) | ||
4100 | if (!IS_ERR(hpriv->clk)) { | ||
4101 | clk_disable(hpriv->clk); | ||
4102 | clk_put(hpriv->clk); | ||
4103 | } | ||
4104 | #endif | ||
4081 | return 0; | 4105 | return 0; |
4082 | } | 4106 | } |
4083 | 4107 | ||
4108 | #ifdef CONFIG_PM | ||
4109 | static int mv_platform_suspend(struct platform_device *pdev, pm_message_t state) | ||
4110 | { | ||
4111 | struct ata_host *host = dev_get_drvdata(&pdev->dev); | ||
4112 | if (host) | ||
4113 | return ata_host_suspend(host, state); | ||
4114 | else | ||
4115 | return 0; | ||
4116 | } | ||
4117 | |||
4118 | static int mv_platform_resume(struct platform_device *pdev) | ||
4119 | { | ||
4120 | struct ata_host *host = dev_get_drvdata(&pdev->dev); | ||
4121 | int ret; | ||
4122 | |||
4123 | if (host) { | ||
4124 | struct mv_host_priv *hpriv = host->private_data; | ||
4125 | const struct mv_sata_platform_data *mv_platform_data = \ | ||
4126 | pdev->dev.platform_data; | ||
4127 | /* | ||
4128 | * (Re-)program MBUS remapping windows if we are asked to. | ||
4129 | */ | ||
4130 | if (mv_platform_data->dram != NULL) | ||
4131 | mv_conf_mbus_windows(hpriv, mv_platform_data->dram); | ||
4132 | |||
4133 | /* initialize adapter */ | ||
4134 | ret = mv_init_host(host); | ||
4135 | if (ret) { | ||
4136 | printk(KERN_ERR DRV_NAME ": Error during HW init\n"); | ||
4137 | return ret; | ||
4138 | } | ||
4139 | ata_host_resume(host); | ||
4140 | } | ||
4141 | |||
4142 | return 0; | ||
4143 | } | ||
4144 | #else | ||
4145 | #define mv_platform_suspend NULL | ||
4146 | #define mv_platform_resume NULL | ||
4147 | #endif | ||
4148 | |||
4084 | static struct platform_driver mv_platform_driver = { | 4149 | static struct platform_driver mv_platform_driver = { |
4085 | .probe = mv_platform_probe, | 4150 | .probe = mv_platform_probe, |
4086 | .remove = __devexit_p(mv_platform_remove), | 4151 | .remove = __devexit_p(mv_platform_remove), |
4152 | .suspend = mv_platform_suspend, | ||
4153 | .resume = mv_platform_resume, | ||
4087 | .driver = { | 4154 | .driver = { |
4088 | .name = DRV_NAME, | 4155 | .name = DRV_NAME, |
4089 | .owner = THIS_MODULE, | 4156 | .owner = THIS_MODULE, |
@@ -4094,6 +4161,9 @@ static struct platform_driver mv_platform_driver = { | |||
4094 | #ifdef CONFIG_PCI | 4161 | #ifdef CONFIG_PCI |
4095 | static int mv_pci_init_one(struct pci_dev *pdev, | 4162 | static int mv_pci_init_one(struct pci_dev *pdev, |
4096 | const struct pci_device_id *ent); | 4163 | const struct pci_device_id *ent); |
4164 | #ifdef CONFIG_PM | ||
4165 | static int mv_pci_device_resume(struct pci_dev *pdev); | ||
4166 | #endif | ||
4097 | 4167 | ||
4098 | 4168 | ||
4099 | static struct pci_driver mv_pci_driver = { | 4169 | static struct pci_driver mv_pci_driver = { |
@@ -4101,6 +4171,11 @@ static struct pci_driver mv_pci_driver = { | |||
4101 | .id_table = mv_pci_tbl, | 4171 | .id_table = mv_pci_tbl, |
4102 | .probe = mv_pci_init_one, | 4172 | .probe = mv_pci_init_one, |
4103 | .remove = ata_pci_remove_one, | 4173 | .remove = ata_pci_remove_one, |
4174 | #ifdef CONFIG_PM | ||
4175 | .suspend = ata_pci_device_suspend, | ||
4176 | .resume = mv_pci_device_resume, | ||
4177 | #endif | ||
4178 | |||
4104 | }; | 4179 | }; |
4105 | 4180 | ||
4106 | /* move to PCI layer or libata core? */ | 4181 | /* move to PCI layer or libata core? */ |
@@ -4194,7 +4269,7 @@ static int mv_pci_init_one(struct pci_dev *pdev, | |||
4194 | const struct ata_port_info *ppi[] = { &mv_port_info[board_idx], NULL }; | 4269 | const struct ata_port_info *ppi[] = { &mv_port_info[board_idx], NULL }; |
4195 | struct ata_host *host; | 4270 | struct ata_host *host; |
4196 | struct mv_host_priv *hpriv; | 4271 | struct mv_host_priv *hpriv; |
4197 | int n_ports, rc; | 4272 | int n_ports, port, rc; |
4198 | 4273 | ||
4199 | if (!printed_version++) | 4274 | if (!printed_version++) |
4200 | dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n"); | 4275 | dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n"); |
@@ -4208,6 +4283,7 @@ static int mv_pci_init_one(struct pci_dev *pdev, | |||
4208 | return -ENOMEM; | 4283 | return -ENOMEM; |
4209 | host->private_data = hpriv; | 4284 | host->private_data = hpriv; |
4210 | hpriv->n_ports = n_ports; | 4285 | hpriv->n_ports = n_ports; |
4286 | hpriv->board_idx = board_idx; | ||
4211 | 4287 | ||
4212 | /* acquire resources */ | 4288 | /* acquire resources */ |
4213 | rc = pcim_enable_device(pdev); | 4289 | rc = pcim_enable_device(pdev); |
@@ -4230,8 +4306,17 @@ static int mv_pci_init_one(struct pci_dev *pdev, | |||
4230 | if (rc) | 4306 | if (rc) |
4231 | return rc; | 4307 | return rc; |
4232 | 4308 | ||
4309 | for (port = 0; port < host->n_ports; port++) { | ||
4310 | struct ata_port *ap = host->ports[port]; | ||
4311 | void __iomem *port_mmio = mv_port_base(hpriv->base, port); | ||
4312 | unsigned int offset = port_mmio - hpriv->base; | ||
4313 | |||
4314 | ata_port_pbar_desc(ap, MV_PRIMARY_BAR, -1, "mmio"); | ||
4315 | ata_port_pbar_desc(ap, MV_PRIMARY_BAR, offset, "port"); | ||
4316 | } | ||
4317 | |||
4233 | /* initialize adapter */ | 4318 | /* initialize adapter */ |
4234 | rc = mv_init_host(host, board_idx); | 4319 | rc = mv_init_host(host); |
4235 | if (rc) | 4320 | if (rc) |
4236 | return rc; | 4321 | return rc; |
4237 | 4322 | ||
@@ -4247,6 +4332,27 @@ static int mv_pci_init_one(struct pci_dev *pdev, | |||
4247 | return ata_host_activate(host, pdev->irq, mv_interrupt, IRQF_SHARED, | 4332 | return ata_host_activate(host, pdev->irq, mv_interrupt, IRQF_SHARED, |
4248 | IS_GEN_I(hpriv) ? &mv5_sht : &mv6_sht); | 4333 | IS_GEN_I(hpriv) ? &mv5_sht : &mv6_sht); |
4249 | } | 4334 | } |
4335 | |||
4336 | #ifdef CONFIG_PM | ||
4337 | static int mv_pci_device_resume(struct pci_dev *pdev) | ||
4338 | { | ||
4339 | struct ata_host *host = dev_get_drvdata(&pdev->dev); | ||
4340 | int rc; | ||
4341 | |||
4342 | rc = ata_pci_device_do_resume(pdev); | ||
4343 | if (rc) | ||
4344 | return rc; | ||
4345 | |||
4346 | /* initialize adapter */ | ||
4347 | rc = mv_init_host(host); | ||
4348 | if (rc) | ||
4349 | return rc; | ||
4350 | |||
4351 | ata_host_resume(host); | ||
4352 | |||
4353 | return 0; | ||
4354 | } | ||
4355 | #endif | ||
4250 | #endif | 4356 | #endif |
4251 | 4357 | ||
4252 | static int mv_platform_probe(struct platform_device *pdev); | 4358 | static int mv_platform_probe(struct platform_device *pdev); |
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 63c143e54a57..c0c5a43d9fb3 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c | |||
@@ -703,9 +703,9 @@ int bus_add_driver(struct device_driver *drv) | |||
703 | return 0; | 703 | return 0; |
704 | 704 | ||
705 | out_unregister: | 705 | out_unregister: |
706 | kobject_put(&priv->kobj); | ||
706 | kfree(drv->p); | 707 | kfree(drv->p); |
707 | drv->p = NULL; | 708 | drv->p = NULL; |
708 | kobject_put(&priv->kobj); | ||
709 | out_put_bus: | 709 | out_put_bus: |
710 | bus_put(bus); | 710 | bus_put(bus); |
711 | return error; | 711 | return error; |
diff --git a/drivers/base/core.c b/drivers/base/core.c index f1290cbd1350..282025770429 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -446,7 +446,8 @@ struct kset *devices_kset; | |||
446 | * @dev: device. | 446 | * @dev: device. |
447 | * @attr: device attribute descriptor. | 447 | * @attr: device attribute descriptor. |
448 | */ | 448 | */ |
449 | int device_create_file(struct device *dev, struct device_attribute *attr) | 449 | int device_create_file(struct device *dev, |
450 | const struct device_attribute *attr) | ||
450 | { | 451 | { |
451 | int error = 0; | 452 | int error = 0; |
452 | if (dev) | 453 | if (dev) |
@@ -459,7 +460,8 @@ int device_create_file(struct device *dev, struct device_attribute *attr) | |||
459 | * @dev: device. | 460 | * @dev: device. |
460 | * @attr: device attribute descriptor. | 461 | * @attr: device attribute descriptor. |
461 | */ | 462 | */ |
462 | void device_remove_file(struct device *dev, struct device_attribute *attr) | 463 | void device_remove_file(struct device *dev, |
464 | const struct device_attribute *attr) | ||
463 | { | 465 | { |
464 | if (dev) | 466 | if (dev) |
465 | sysfs_remove_file(&dev->kobj, &attr->attr); | 467 | sysfs_remove_file(&dev->kobj, &attr->attr); |
@@ -470,7 +472,8 @@ void device_remove_file(struct device *dev, struct device_attribute *attr) | |||
470 | * @dev: device. | 472 | * @dev: device. |
471 | * @attr: device binary attribute descriptor. | 473 | * @attr: device binary attribute descriptor. |
472 | */ | 474 | */ |
473 | int device_create_bin_file(struct device *dev, struct bin_attribute *attr) | 475 | int device_create_bin_file(struct device *dev, |
476 | const struct bin_attribute *attr) | ||
474 | { | 477 | { |
475 | int error = -EINVAL; | 478 | int error = -EINVAL; |
476 | if (dev) | 479 | if (dev) |
@@ -484,7 +487,8 @@ EXPORT_SYMBOL_GPL(device_create_bin_file); | |||
484 | * @dev: device. | 487 | * @dev: device. |
485 | * @attr: device binary attribute descriptor. | 488 | * @attr: device binary attribute descriptor. |
486 | */ | 489 | */ |
487 | void device_remove_bin_file(struct device *dev, struct bin_attribute *attr) | 490 | void device_remove_bin_file(struct device *dev, |
491 | const struct bin_attribute *attr) | ||
488 | { | 492 | { |
489 | if (dev) | 493 | if (dev) |
490 | sysfs_remove_bin_file(&dev->kobj, attr); | 494 | sysfs_remove_bin_file(&dev->kobj, attr); |
@@ -905,8 +909,10 @@ int device_add(struct device *dev) | |||
905 | dev->init_name = NULL; | 909 | dev->init_name = NULL; |
906 | } | 910 | } |
907 | 911 | ||
908 | if (!dev_name(dev)) | 912 | if (!dev_name(dev)) { |
913 | error = -EINVAL; | ||
909 | goto name_error; | 914 | goto name_error; |
915 | } | ||
910 | 916 | ||
911 | pr_debug("device: '%s': %s\n", dev_name(dev), __func__); | 917 | pr_debug("device: '%s': %s\n", dev_name(dev), __func__); |
912 | 918 | ||
diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c index 50375bb8e51d..090dd4851301 100644 --- a/drivers/base/devtmpfs.c +++ b/drivers/base/devtmpfs.c | |||
@@ -32,7 +32,7 @@ static int dev_mount = 1; | |||
32 | static int dev_mount; | 32 | static int dev_mount; |
33 | #endif | 33 | #endif |
34 | 34 | ||
35 | static rwlock_t dirlock; | 35 | static DEFINE_MUTEX(dirlock); |
36 | 36 | ||
37 | static int __init mount_param(char *str) | 37 | static int __init mount_param(char *str) |
38 | { | 38 | { |
@@ -93,7 +93,7 @@ static int create_path(const char *nodepath) | |||
93 | { | 93 | { |
94 | int err; | 94 | int err; |
95 | 95 | ||
96 | read_lock(&dirlock); | 96 | mutex_lock(&dirlock); |
97 | err = dev_mkdir(nodepath, 0755); | 97 | err = dev_mkdir(nodepath, 0755); |
98 | if (err == -ENOENT) { | 98 | if (err == -ENOENT) { |
99 | char *path; | 99 | char *path; |
@@ -101,8 +101,10 @@ static int create_path(const char *nodepath) | |||
101 | 101 | ||
102 | /* parent directories do not exist, create them */ | 102 | /* parent directories do not exist, create them */ |
103 | path = kstrdup(nodepath, GFP_KERNEL); | 103 | path = kstrdup(nodepath, GFP_KERNEL); |
104 | if (!path) | 104 | if (!path) { |
105 | return -ENOMEM; | 105 | err = -ENOMEM; |
106 | goto out; | ||
107 | } | ||
106 | s = path; | 108 | s = path; |
107 | for (;;) { | 109 | for (;;) { |
108 | s = strchr(s, '/'); | 110 | s = strchr(s, '/'); |
@@ -117,7 +119,8 @@ static int create_path(const char *nodepath) | |||
117 | } | 119 | } |
118 | kfree(path); | 120 | kfree(path); |
119 | } | 121 | } |
120 | read_unlock(&dirlock); | 122 | out: |
123 | mutex_unlock(&dirlock); | ||
121 | return err; | 124 | return err; |
122 | } | 125 | } |
123 | 126 | ||
@@ -229,7 +232,7 @@ static int delete_path(const char *nodepath) | |||
229 | if (!path) | 232 | if (!path) |
230 | return -ENOMEM; | 233 | return -ENOMEM; |
231 | 234 | ||
232 | write_lock(&dirlock); | 235 | mutex_lock(&dirlock); |
233 | for (;;) { | 236 | for (;;) { |
234 | char *base; | 237 | char *base; |
235 | 238 | ||
@@ -241,7 +244,7 @@ static int delete_path(const char *nodepath) | |||
241 | if (err) | 244 | if (err) |
242 | break; | 245 | break; |
243 | } | 246 | } |
244 | write_unlock(&dirlock); | 247 | mutex_unlock(&dirlock); |
245 | 248 | ||
246 | kfree(path); | 249 | kfree(path); |
247 | return err; | 250 | return err; |
@@ -352,8 +355,6 @@ int __init devtmpfs_init(void) | |||
352 | int err; | 355 | int err; |
353 | struct vfsmount *mnt; | 356 | struct vfsmount *mnt; |
354 | 357 | ||
355 | rwlock_init(&dirlock); | ||
356 | |||
357 | err = register_filesystem(&dev_fs_type); | 358 | err = register_filesystem(&dev_fs_type); |
358 | if (err) { | 359 | if (err) { |
359 | printk(KERN_ERR "devtmpfs: unable to register devtmpfs " | 360 | printk(KERN_ERR "devtmpfs: unable to register devtmpfs " |
diff --git a/drivers/base/driver.c b/drivers/base/driver.c index f367885a7646..90c9fff09ead 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c | |||
@@ -98,7 +98,7 @@ EXPORT_SYMBOL_GPL(driver_find_device); | |||
98 | * @attr: driver attribute descriptor. | 98 | * @attr: driver attribute descriptor. |
99 | */ | 99 | */ |
100 | int driver_create_file(struct device_driver *drv, | 100 | int driver_create_file(struct device_driver *drv, |
101 | struct driver_attribute *attr) | 101 | const struct driver_attribute *attr) |
102 | { | 102 | { |
103 | int error; | 103 | int error; |
104 | if (drv) | 104 | if (drv) |
@@ -115,7 +115,7 @@ EXPORT_SYMBOL_GPL(driver_create_file); | |||
115 | * @attr: driver attribute descriptor. | 115 | * @attr: driver attribute descriptor. |
116 | */ | 116 | */ |
117 | void driver_remove_file(struct device_driver *drv, | 117 | void driver_remove_file(struct device_driver *drv, |
118 | struct driver_attribute *attr) | 118 | const struct driver_attribute *attr) |
119 | { | 119 | { |
120 | if (drv) | 120 | if (drv) |
121 | sysfs_remove_file(&drv->p->kobj, &attr->attr); | 121 | sysfs_remove_file(&drv->p->kobj, &attr->attr); |
diff --git a/drivers/base/memory.c b/drivers/base/memory.c index c4c8f2e1dd15..d7d77d4a402c 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c | |||
@@ -63,6 +63,20 @@ void unregister_memory_notifier(struct notifier_block *nb) | |||
63 | } | 63 | } |
64 | EXPORT_SYMBOL(unregister_memory_notifier); | 64 | EXPORT_SYMBOL(unregister_memory_notifier); |
65 | 65 | ||
66 | static ATOMIC_NOTIFIER_HEAD(memory_isolate_chain); | ||
67 | |||
68 | int register_memory_isolate_notifier(struct notifier_block *nb) | ||
69 | { | ||
70 | return atomic_notifier_chain_register(&memory_isolate_chain, nb); | ||
71 | } | ||
72 | EXPORT_SYMBOL(register_memory_isolate_notifier); | ||
73 | |||
74 | void unregister_memory_isolate_notifier(struct notifier_block *nb) | ||
75 | { | ||
76 | atomic_notifier_chain_unregister(&memory_isolate_chain, nb); | ||
77 | } | ||
78 | EXPORT_SYMBOL(unregister_memory_isolate_notifier); | ||
79 | |||
66 | /* | 80 | /* |
67 | * register_memory - Setup a sysfs device for a memory block | 81 | * register_memory - Setup a sysfs device for a memory block |
68 | */ | 82 | */ |
@@ -157,6 +171,11 @@ int memory_notify(unsigned long val, void *v) | |||
157 | return blocking_notifier_call_chain(&memory_chain, val, v); | 171 | return blocking_notifier_call_chain(&memory_chain, val, v); |
158 | } | 172 | } |
159 | 173 | ||
174 | int memory_isolate_notify(unsigned long val, void *v) | ||
175 | { | ||
176 | return atomic_notifier_call_chain(&memory_isolate_chain, val, v); | ||
177 | } | ||
178 | |||
160 | /* | 179 | /* |
161 | * MEMORY_HOTPLUG depends on SPARSEMEM in mm/Kconfig, so it is | 180 | * MEMORY_HOTPLUG depends on SPARSEMEM in mm/Kconfig, so it is |
162 | * OK to have direct references to sparsemem variables in here. | 181 | * OK to have direct references to sparsemem variables in here. |
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 9d2ee25deaf5..58efaf2f1259 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c | |||
@@ -441,6 +441,7 @@ error: | |||
441 | platform_device_put(pdev); | 441 | platform_device_put(pdev); |
442 | return ERR_PTR(retval); | 442 | return ERR_PTR(retval); |
443 | } | 443 | } |
444 | EXPORT_SYMBOL_GPL(platform_device_register_data); | ||
444 | 445 | ||
445 | static int platform_drv_probe(struct device *_dev) | 446 | static int platform_drv_probe(struct device *_dev) |
446 | { | 447 | { |
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 1a216c114a0f..48adf80926a0 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c | |||
@@ -161,6 +161,32 @@ void device_pm_move_last(struct device *dev) | |||
161 | list_move_tail(&dev->power.entry, &dpm_list); | 161 | list_move_tail(&dev->power.entry, &dpm_list); |
162 | } | 162 | } |
163 | 163 | ||
164 | static ktime_t initcall_debug_start(struct device *dev) | ||
165 | { | ||
166 | ktime_t calltime = ktime_set(0, 0); | ||
167 | |||
168 | if (initcall_debug) { | ||
169 | pr_info("calling %s+ @ %i\n", | ||
170 | dev_name(dev), task_pid_nr(current)); | ||
171 | calltime = ktime_get(); | ||
172 | } | ||
173 | |||
174 | return calltime; | ||
175 | } | ||
176 | |||
177 | static void initcall_debug_report(struct device *dev, ktime_t calltime, | ||
178 | int error) | ||
179 | { | ||
180 | ktime_t delta, rettime; | ||
181 | |||
182 | if (initcall_debug) { | ||
183 | rettime = ktime_get(); | ||
184 | delta = ktime_sub(rettime, calltime); | ||
185 | pr_info("call %s+ returned %d after %Ld usecs\n", dev_name(dev), | ||
186 | error, (unsigned long long)ktime_to_ns(delta) >> 10); | ||
187 | } | ||
188 | } | ||
189 | |||
164 | /** | 190 | /** |
165 | * pm_op - Execute the PM operation appropriate for given PM event. | 191 | * pm_op - Execute the PM operation appropriate for given PM event. |
166 | * @dev: Device to handle. | 192 | * @dev: Device to handle. |
@@ -172,13 +198,9 @@ static int pm_op(struct device *dev, | |||
172 | pm_message_t state) | 198 | pm_message_t state) |
173 | { | 199 | { |
174 | int error = 0; | 200 | int error = 0; |
175 | ktime_t calltime, delta, rettime; | 201 | ktime_t calltime; |
176 | 202 | ||
177 | if (initcall_debug) { | 203 | calltime = initcall_debug_start(dev); |
178 | pr_info("calling %s+ @ %i\n", | ||
179 | dev_name(dev), task_pid_nr(current)); | ||
180 | calltime = ktime_get(); | ||
181 | } | ||
182 | 204 | ||
183 | switch (state.event) { | 205 | switch (state.event) { |
184 | #ifdef CONFIG_SUSPEND | 206 | #ifdef CONFIG_SUSPEND |
@@ -227,12 +249,7 @@ static int pm_op(struct device *dev, | |||
227 | error = -EINVAL; | 249 | error = -EINVAL; |
228 | } | 250 | } |
229 | 251 | ||
230 | if (initcall_debug) { | 252 | initcall_debug_report(dev, calltime, error); |
231 | rettime = ktime_get(); | ||
232 | delta = ktime_sub(rettime, calltime); | ||
233 | pr_info("call %s+ returned %d after %Ld usecs\n", dev_name(dev), | ||
234 | error, (unsigned long long)ktime_to_ns(delta) >> 10); | ||
235 | } | ||
236 | 253 | ||
237 | return error; | 254 | return error; |
238 | } | 255 | } |
@@ -309,8 +326,9 @@ static int pm_noirq_op(struct device *dev, | |||
309 | if (initcall_debug) { | 326 | if (initcall_debug) { |
310 | rettime = ktime_get(); | 327 | rettime = ktime_get(); |
311 | delta = ktime_sub(rettime, calltime); | 328 | delta = ktime_sub(rettime, calltime); |
312 | printk("initcall %s_i+ returned %d after %Ld usecs\n", dev_name(dev), | 329 | printk("initcall %s_i+ returned %d after %Ld usecs\n", |
313 | error, (unsigned long long)ktime_to_ns(delta) >> 10); | 330 | dev_name(dev), error, |
331 | (unsigned long long)ktime_to_ns(delta) >> 10); | ||
314 | } | 332 | } |
315 | 333 | ||
316 | return error; | 334 | return error; |
@@ -354,6 +372,23 @@ static void pm_dev_err(struct device *dev, pm_message_t state, char *info, | |||
354 | kobject_name(&dev->kobj), pm_verb(state.event), info, error); | 372 | kobject_name(&dev->kobj), pm_verb(state.event), info, error); |
355 | } | 373 | } |
356 | 374 | ||
375 | static void dpm_show_time(ktime_t starttime, pm_message_t state, char *info) | ||
376 | { | ||
377 | ktime_t calltime; | ||
378 | s64 usecs64; | ||
379 | int usecs; | ||
380 | |||
381 | calltime = ktime_get(); | ||
382 | usecs64 = ktime_to_ns(ktime_sub(calltime, starttime)); | ||
383 | do_div(usecs64, NSEC_PER_USEC); | ||
384 | usecs = usecs64; | ||
385 | if (usecs == 0) | ||
386 | usecs = 1; | ||
387 | pr_info("PM: %s%s%s of devices complete after %ld.%03ld msecs\n", | ||
388 | info ?: "", info ? " " : "", pm_verb(state.event), | ||
389 | usecs / USEC_PER_MSEC, usecs % USEC_PER_MSEC); | ||
390 | } | ||
391 | |||
357 | /*------------------------- Resume routines -------------------------*/ | 392 | /*------------------------- Resume routines -------------------------*/ |
358 | 393 | ||
359 | /** | 394 | /** |
@@ -390,6 +425,7 @@ static int device_resume_noirq(struct device *dev, pm_message_t state) | |||
390 | void dpm_resume_noirq(pm_message_t state) | 425 | void dpm_resume_noirq(pm_message_t state) |
391 | { | 426 | { |
392 | struct device *dev; | 427 | struct device *dev; |
428 | ktime_t starttime = ktime_get(); | ||
393 | 429 | ||
394 | mutex_lock(&dpm_list_mtx); | 430 | mutex_lock(&dpm_list_mtx); |
395 | transition_started = false; | 431 | transition_started = false; |
@@ -403,11 +439,32 @@ void dpm_resume_noirq(pm_message_t state) | |||
403 | pm_dev_err(dev, state, " early", error); | 439 | pm_dev_err(dev, state, " early", error); |
404 | } | 440 | } |
405 | mutex_unlock(&dpm_list_mtx); | 441 | mutex_unlock(&dpm_list_mtx); |
442 | dpm_show_time(starttime, state, "early"); | ||
406 | resume_device_irqs(); | 443 | resume_device_irqs(); |
407 | } | 444 | } |
408 | EXPORT_SYMBOL_GPL(dpm_resume_noirq); | 445 | EXPORT_SYMBOL_GPL(dpm_resume_noirq); |
409 | 446 | ||
410 | /** | 447 | /** |
448 | * legacy_resume - Execute a legacy (bus or class) resume callback for device. | ||
449 | * dev: Device to resume. | ||
450 | * cb: Resume callback to execute. | ||
451 | */ | ||
452 | static int legacy_resume(struct device *dev, int (*cb)(struct device *dev)) | ||
453 | { | ||
454 | int error; | ||
455 | ktime_t calltime; | ||
456 | |||
457 | calltime = initcall_debug_start(dev); | ||
458 | |||
459 | error = cb(dev); | ||
460 | suspend_report_result(cb, error); | ||
461 | |||
462 | initcall_debug_report(dev, calltime, error); | ||
463 | |||
464 | return error; | ||
465 | } | ||
466 | |||
467 | /** | ||
411 | * device_resume - Execute "resume" callbacks for given device. | 468 | * device_resume - Execute "resume" callbacks for given device. |
412 | * @dev: Device to handle. | 469 | * @dev: Device to handle. |
413 | * @state: PM transition of the system being carried out. | 470 | * @state: PM transition of the system being carried out. |
@@ -427,7 +484,7 @@ static int device_resume(struct device *dev, pm_message_t state) | |||
427 | error = pm_op(dev, dev->bus->pm, state); | 484 | error = pm_op(dev, dev->bus->pm, state); |
428 | } else if (dev->bus->resume) { | 485 | } else if (dev->bus->resume) { |
429 | pm_dev_dbg(dev, state, "legacy "); | 486 | pm_dev_dbg(dev, state, "legacy "); |
430 | error = dev->bus->resume(dev); | 487 | error = legacy_resume(dev, dev->bus->resume); |
431 | } | 488 | } |
432 | if (error) | 489 | if (error) |
433 | goto End; | 490 | goto End; |
@@ -448,7 +505,7 @@ static int device_resume(struct device *dev, pm_message_t state) | |||
448 | error = pm_op(dev, dev->class->pm, state); | 505 | error = pm_op(dev, dev->class->pm, state); |
449 | } else if (dev->class->resume) { | 506 | } else if (dev->class->resume) { |
450 | pm_dev_dbg(dev, state, "legacy class "); | 507 | pm_dev_dbg(dev, state, "legacy class "); |
451 | error = dev->class->resume(dev); | 508 | error = legacy_resume(dev, dev->class->resume); |
452 | } | 509 | } |
453 | } | 510 | } |
454 | End: | 511 | End: |
@@ -468,6 +525,7 @@ static int device_resume(struct device *dev, pm_message_t state) | |||
468 | static void dpm_resume(pm_message_t state) | 525 | static void dpm_resume(pm_message_t state) |
469 | { | 526 | { |
470 | struct list_head list; | 527 | struct list_head list; |
528 | ktime_t starttime = ktime_get(); | ||
471 | 529 | ||
472 | INIT_LIST_HEAD(&list); | 530 | INIT_LIST_HEAD(&list); |
473 | mutex_lock(&dpm_list_mtx); | 531 | mutex_lock(&dpm_list_mtx); |
@@ -496,6 +554,7 @@ static void dpm_resume(pm_message_t state) | |||
496 | } | 554 | } |
497 | list_splice(&list, &dpm_list); | 555 | list_splice(&list, &dpm_list); |
498 | mutex_unlock(&dpm_list_mtx); | 556 | mutex_unlock(&dpm_list_mtx); |
557 | dpm_show_time(starttime, state, NULL); | ||
499 | } | 558 | } |
500 | 559 | ||
501 | /** | 560 | /** |
@@ -548,7 +607,7 @@ static void dpm_complete(pm_message_t state) | |||
548 | mutex_unlock(&dpm_list_mtx); | 607 | mutex_unlock(&dpm_list_mtx); |
549 | 608 | ||
550 | device_complete(dev, state); | 609 | device_complete(dev, state); |
551 | pm_runtime_put_noidle(dev); | 610 | pm_runtime_put_sync(dev); |
552 | 611 | ||
553 | mutex_lock(&dpm_list_mtx); | 612 | mutex_lock(&dpm_list_mtx); |
554 | } | 613 | } |
@@ -628,6 +687,7 @@ static int device_suspend_noirq(struct device *dev, pm_message_t state) | |||
628 | int dpm_suspend_noirq(pm_message_t state) | 687 | int dpm_suspend_noirq(pm_message_t state) |
629 | { | 688 | { |
630 | struct device *dev; | 689 | struct device *dev; |
690 | ktime_t starttime = ktime_get(); | ||
631 | int error = 0; | 691 | int error = 0; |
632 | 692 | ||
633 | suspend_device_irqs(); | 693 | suspend_device_irqs(); |
@@ -643,11 +703,34 @@ int dpm_suspend_noirq(pm_message_t state) | |||
643 | mutex_unlock(&dpm_list_mtx); | 703 | mutex_unlock(&dpm_list_mtx); |
644 | if (error) | 704 | if (error) |
645 | dpm_resume_noirq(resume_event(state)); | 705 | dpm_resume_noirq(resume_event(state)); |
706 | else | ||
707 | dpm_show_time(starttime, state, "late"); | ||
646 | return error; | 708 | return error; |
647 | } | 709 | } |
648 | EXPORT_SYMBOL_GPL(dpm_suspend_noirq); | 710 | EXPORT_SYMBOL_GPL(dpm_suspend_noirq); |
649 | 711 | ||
650 | /** | 712 | /** |
713 | * legacy_suspend - Execute a legacy (bus or class) suspend callback for device. | ||
714 | * dev: Device to suspend. | ||
715 | * cb: Suspend callback to execute. | ||
716 | */ | ||
717 | static int legacy_suspend(struct device *dev, pm_message_t state, | ||
718 | int (*cb)(struct device *dev, pm_message_t state)) | ||
719 | { | ||
720 | int error; | ||
721 | ktime_t calltime; | ||
722 | |||
723 | calltime = initcall_debug_start(dev); | ||
724 | |||
725 | error = cb(dev, state); | ||
726 | suspend_report_result(cb, error); | ||
727 | |||
728 | initcall_debug_report(dev, calltime, error); | ||
729 | |||
730 | return error; | ||
731 | } | ||
732 | |||
733 | /** | ||
651 | * device_suspend - Execute "suspend" callbacks for given device. | 734 | * device_suspend - Execute "suspend" callbacks for given device. |
652 | * @dev: Device to handle. | 735 | * @dev: Device to handle. |
653 | * @state: PM transition of the system being carried out. | 736 | * @state: PM transition of the system being carried out. |
@@ -664,8 +747,7 @@ static int device_suspend(struct device *dev, pm_message_t state) | |||
664 | error = pm_op(dev, dev->class->pm, state); | 747 | error = pm_op(dev, dev->class->pm, state); |
665 | } else if (dev->class->suspend) { | 748 | } else if (dev->class->suspend) { |
666 | pm_dev_dbg(dev, state, "legacy class "); | 749 | pm_dev_dbg(dev, state, "legacy class "); |
667 | error = dev->class->suspend(dev, state); | 750 | error = legacy_suspend(dev, state, dev->class->suspend); |
668 | suspend_report_result(dev->class->suspend, error); | ||
669 | } | 751 | } |
670 | if (error) | 752 | if (error) |
671 | goto End; | 753 | goto End; |
@@ -686,8 +768,7 @@ static int device_suspend(struct device *dev, pm_message_t state) | |||
686 | error = pm_op(dev, dev->bus->pm, state); | 768 | error = pm_op(dev, dev->bus->pm, state); |
687 | } else if (dev->bus->suspend) { | 769 | } else if (dev->bus->suspend) { |
688 | pm_dev_dbg(dev, state, "legacy "); | 770 | pm_dev_dbg(dev, state, "legacy "); |
689 | error = dev->bus->suspend(dev, state); | 771 | error = legacy_suspend(dev, state, dev->bus->suspend); |
690 | suspend_report_result(dev->bus->suspend, error); | ||
691 | } | 772 | } |
692 | } | 773 | } |
693 | End: | 774 | End: |
@@ -703,6 +784,7 @@ static int device_suspend(struct device *dev, pm_message_t state) | |||
703 | static int dpm_suspend(pm_message_t state) | 784 | static int dpm_suspend(pm_message_t state) |
704 | { | 785 | { |
705 | struct list_head list; | 786 | struct list_head list; |
787 | ktime_t starttime = ktime_get(); | ||
706 | int error = 0; | 788 | int error = 0; |
707 | 789 | ||
708 | INIT_LIST_HEAD(&list); | 790 | INIT_LIST_HEAD(&list); |
@@ -728,6 +810,8 @@ static int dpm_suspend(pm_message_t state) | |||
728 | } | 810 | } |
729 | list_splice(&list, dpm_list.prev); | 811 | list_splice(&list, dpm_list.prev); |
730 | mutex_unlock(&dpm_list_mtx); | 812 | mutex_unlock(&dpm_list_mtx); |
813 | if (!error) | ||
814 | dpm_show_time(starttime, state, NULL); | ||
731 | return error; | 815 | return error; |
732 | } | 816 | } |
733 | 817 | ||
@@ -796,7 +880,7 @@ static int dpm_prepare(pm_message_t state) | |||
796 | pm_runtime_get_noresume(dev); | 880 | pm_runtime_get_noresume(dev); |
797 | if (pm_runtime_barrier(dev) && device_may_wakeup(dev)) { | 881 | if (pm_runtime_barrier(dev) && device_may_wakeup(dev)) { |
798 | /* Wake-up requested during system sleep transition. */ | 882 | /* Wake-up requested during system sleep transition. */ |
799 | pm_runtime_put_noidle(dev); | 883 | pm_runtime_put_sync(dev); |
800 | error = -EBUSY; | 884 | error = -EBUSY; |
801 | } else { | 885 | } else { |
802 | error = device_prepare(dev, state); | 886 | error = device_prepare(dev, state); |
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index 40d7720a4b21..f8b044e8aef7 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c | |||
@@ -85,6 +85,19 @@ static int __pm_runtime_idle(struct device *dev) | |||
85 | dev->bus->pm->runtime_idle(dev); | 85 | dev->bus->pm->runtime_idle(dev); |
86 | 86 | ||
87 | spin_lock_irq(&dev->power.lock); | 87 | spin_lock_irq(&dev->power.lock); |
88 | } else if (dev->type && dev->type->pm && dev->type->pm->runtime_idle) { | ||
89 | spin_unlock_irq(&dev->power.lock); | ||
90 | |||
91 | dev->type->pm->runtime_idle(dev); | ||
92 | |||
93 | spin_lock_irq(&dev->power.lock); | ||
94 | } else if (dev->class && dev->class->pm | ||
95 | && dev->class->pm->runtime_idle) { | ||
96 | spin_unlock_irq(&dev->power.lock); | ||
97 | |||
98 | dev->class->pm->runtime_idle(dev); | ||
99 | |||
100 | spin_lock_irq(&dev->power.lock); | ||
88 | } | 101 | } |
89 | 102 | ||
90 | dev->power.idle_notification = false; | 103 | dev->power.idle_notification = false; |
@@ -194,6 +207,22 @@ int __pm_runtime_suspend(struct device *dev, bool from_wq) | |||
194 | 207 | ||
195 | spin_lock_irq(&dev->power.lock); | 208 | spin_lock_irq(&dev->power.lock); |
196 | dev->power.runtime_error = retval; | 209 | dev->power.runtime_error = retval; |
210 | } else if (dev->type && dev->type->pm | ||
211 | && dev->type->pm->runtime_suspend) { | ||
212 | spin_unlock_irq(&dev->power.lock); | ||
213 | |||
214 | retval = dev->type->pm->runtime_suspend(dev); | ||
215 | |||
216 | spin_lock_irq(&dev->power.lock); | ||
217 | dev->power.runtime_error = retval; | ||
218 | } else if (dev->class && dev->class->pm | ||
219 | && dev->class->pm->runtime_suspend) { | ||
220 | spin_unlock_irq(&dev->power.lock); | ||
221 | |||
222 | retval = dev->class->pm->runtime_suspend(dev); | ||
223 | |||
224 | spin_lock_irq(&dev->power.lock); | ||
225 | dev->power.runtime_error = retval; | ||
197 | } else { | 226 | } else { |
198 | retval = -ENOSYS; | 227 | retval = -ENOSYS; |
199 | } | 228 | } |
@@ -359,6 +388,22 @@ int __pm_runtime_resume(struct device *dev, bool from_wq) | |||
359 | 388 | ||
360 | spin_lock_irq(&dev->power.lock); | 389 | spin_lock_irq(&dev->power.lock); |
361 | dev->power.runtime_error = retval; | 390 | dev->power.runtime_error = retval; |
391 | } else if (dev->type && dev->type->pm | ||
392 | && dev->type->pm->runtime_resume) { | ||
393 | spin_unlock_irq(&dev->power.lock); | ||
394 | |||
395 | retval = dev->type->pm->runtime_resume(dev); | ||
396 | |||
397 | spin_lock_irq(&dev->power.lock); | ||
398 | dev->power.runtime_error = retval; | ||
399 | } else if (dev->class && dev->class->pm | ||
400 | && dev->class->pm->runtime_resume) { | ||
401 | spin_unlock_irq(&dev->power.lock); | ||
402 | |||
403 | retval = dev->class->pm->runtime_resume(dev); | ||
404 | |||
405 | spin_lock_irq(&dev->power.lock); | ||
406 | dev->power.runtime_error = retval; | ||
362 | } else { | 407 | } else { |
363 | retval = -ENOSYS; | 408 | retval = -ENOSYS; |
364 | } | 409 | } |
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 4d2905996751..a699f09ddf7c 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c | |||
@@ -307,6 +307,7 @@ static void btusb_bulk_complete(struct urb *urb) | |||
307 | return; | 307 | return; |
308 | 308 | ||
309 | usb_anchor_urb(urb, &data->bulk_anchor); | 309 | usb_anchor_urb(urb, &data->bulk_anchor); |
310 | usb_mark_last_busy(data->udev); | ||
310 | 311 | ||
311 | err = usb_submit_urb(urb, GFP_ATOMIC); | 312 | err = usb_submit_urb(urb, GFP_ATOMIC); |
312 | if (err < 0) { | 313 | if (err < 0) { |
diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c index e989f67bb61f..3d9c61e5acbf 100644 --- a/drivers/char/hw_random/core.c +++ b/drivers/char/hw_random/core.c | |||
@@ -158,10 +158,11 @@ static ssize_t rng_dev_read(struct file *filp, char __user *buf, | |||
158 | goto out; | 158 | goto out; |
159 | } | 159 | } |
160 | } | 160 | } |
161 | out_unlock: | ||
162 | mutex_unlock(&rng_mutex); | ||
163 | out: | 161 | out: |
164 | return ret ? : err; | 162 | return ret ? : err; |
163 | out_unlock: | ||
164 | mutex_unlock(&rng_mutex); | ||
165 | goto out; | ||
165 | } | 166 | } |
166 | 167 | ||
167 | 168 | ||
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 679cd08b80b4..176f1751237f 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
@@ -3204,7 +3204,7 @@ static __devinit int init_ipmi_si(void) | |||
3204 | #ifdef CONFIG_ACPI | 3204 | #ifdef CONFIG_ACPI |
3205 | spmi_find_bmc(); | 3205 | spmi_find_bmc(); |
3206 | #endif | 3206 | #endif |
3207 | #ifdef CONFIG_PNP | 3207 | #ifdef CONFIG_ACPI |
3208 | pnp_register_driver(&ipmi_pnp_driver); | 3208 | pnp_register_driver(&ipmi_pnp_driver); |
3209 | #endif | 3209 | #endif |
3210 | 3210 | ||
@@ -3330,7 +3330,7 @@ static __exit void cleanup_ipmi_si(void) | |||
3330 | #ifdef CONFIG_PCI | 3330 | #ifdef CONFIG_PCI |
3331 | pci_unregister_driver(&ipmi_pci_driver); | 3331 | pci_unregister_driver(&ipmi_pci_driver); |
3332 | #endif | 3332 | #endif |
3333 | #ifdef CONFIG_PNP | 3333 | #ifdef CONFIG_ACPI |
3334 | pnp_unregister_driver(&ipmi_pnp_driver); | 3334 | pnp_unregister_driver(&ipmi_pnp_driver); |
3335 | #endif | 3335 | #endif |
3336 | 3336 | ||
diff --git a/drivers/char/nozomi.c b/drivers/char/nozomi.c index d3400b20444f..7d73cd430340 100644 --- a/drivers/char/nozomi.c +++ b/drivers/char/nozomi.c | |||
@@ -358,7 +358,7 @@ struct port { | |||
358 | u8 update_flow_control; | 358 | u8 update_flow_control; |
359 | struct ctrl_ul ctrl_ul; | 359 | struct ctrl_ul ctrl_ul; |
360 | struct ctrl_dl ctrl_dl; | 360 | struct ctrl_dl ctrl_dl; |
361 | struct kfifo *fifo_ul; | 361 | struct kfifo fifo_ul; |
362 | void __iomem *dl_addr[2]; | 362 | void __iomem *dl_addr[2]; |
363 | u32 dl_size[2]; | 363 | u32 dl_size[2]; |
364 | u8 toggle_dl; | 364 | u8 toggle_dl; |
@@ -685,8 +685,6 @@ static int nozomi_read_config_table(struct nozomi *dc) | |||
685 | dump_table(dc); | 685 | dump_table(dc); |
686 | 686 | ||
687 | for (i = PORT_MDM; i < MAX_PORT; i++) { | 687 | for (i = PORT_MDM; i < MAX_PORT; i++) { |
688 | dc->port[i].fifo_ul = | ||
689 | kfifo_alloc(FIFO_BUFFER_SIZE_UL, GFP_ATOMIC, NULL); | ||
690 | memset(&dc->port[i].ctrl_dl, 0, sizeof(struct ctrl_dl)); | 688 | memset(&dc->port[i].ctrl_dl, 0, sizeof(struct ctrl_dl)); |
691 | memset(&dc->port[i].ctrl_ul, 0, sizeof(struct ctrl_ul)); | 689 | memset(&dc->port[i].ctrl_ul, 0, sizeof(struct ctrl_ul)); |
692 | } | 690 | } |
@@ -798,7 +796,7 @@ static int send_data(enum port_type index, struct nozomi *dc) | |||
798 | struct tty_struct *tty = tty_port_tty_get(&port->port); | 796 | struct tty_struct *tty = tty_port_tty_get(&port->port); |
799 | 797 | ||
800 | /* Get data from tty and place in buf for now */ | 798 | /* Get data from tty and place in buf for now */ |
801 | size = __kfifo_get(port->fifo_ul, dc->send_buf, | 799 | size = kfifo_out(&port->fifo_ul, dc->send_buf, |
802 | ul_size < SEND_BUF_MAX ? ul_size : SEND_BUF_MAX); | 800 | ul_size < SEND_BUF_MAX ? ul_size : SEND_BUF_MAX); |
803 | 801 | ||
804 | if (size == 0) { | 802 | if (size == 0) { |
@@ -988,11 +986,11 @@ static int receive_flow_control(struct nozomi *dc) | |||
988 | 986 | ||
989 | } else if (old_ctrl.CTS == 0 && ctrl_dl.CTS == 1) { | 987 | } else if (old_ctrl.CTS == 0 && ctrl_dl.CTS == 1) { |
990 | 988 | ||
991 | if (__kfifo_len(dc->port[port].fifo_ul)) { | 989 | if (kfifo_len(&dc->port[port].fifo_ul)) { |
992 | DBG1("Enable interrupt (0x%04X) on port: %d", | 990 | DBG1("Enable interrupt (0x%04X) on port: %d", |
993 | enable_ier, port); | 991 | enable_ier, port); |
994 | DBG1("Data in buffer [%d], enable transmit! ", | 992 | DBG1("Data in buffer [%d], enable transmit! ", |
995 | __kfifo_len(dc->port[port].fifo_ul)); | 993 | kfifo_len(&dc->port[port].fifo_ul)); |
996 | enable_transmit_ul(port, dc); | 994 | enable_transmit_ul(port, dc); |
997 | } else { | 995 | } else { |
998 | DBG1("No data in buffer..."); | 996 | DBG1("No data in buffer..."); |
@@ -1433,6 +1431,16 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev, | |||
1433 | goto err_free_sbuf; | 1431 | goto err_free_sbuf; |
1434 | } | 1432 | } |
1435 | 1433 | ||
1434 | for (i = PORT_MDM; i < MAX_PORT; i++) { | ||
1435 | if (kfifo_alloc(&dc->port[i].fifo_ul, | ||
1436 | FIFO_BUFFER_SIZE_UL, GFP_ATOMIC)) { | ||
1437 | dev_err(&pdev->dev, | ||
1438 | "Could not allocate kfifo buffer\n"); | ||
1439 | ret = -ENOMEM; | ||
1440 | goto err_free_kfifo; | ||
1441 | } | ||
1442 | } | ||
1443 | |||
1436 | spin_lock_init(&dc->spin_mutex); | 1444 | spin_lock_init(&dc->spin_mutex); |
1437 | 1445 | ||
1438 | nozomi_setup_private_data(dc); | 1446 | nozomi_setup_private_data(dc); |
@@ -1445,7 +1453,7 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev, | |||
1445 | NOZOMI_NAME, dc); | 1453 | NOZOMI_NAME, dc); |
1446 | if (unlikely(ret)) { | 1454 | if (unlikely(ret)) { |
1447 | dev_err(&pdev->dev, "can't request irq %d\n", pdev->irq); | 1455 | dev_err(&pdev->dev, "can't request irq %d\n", pdev->irq); |
1448 | goto err_free_sbuf; | 1456 | goto err_free_kfifo; |
1449 | } | 1457 | } |
1450 | 1458 | ||
1451 | DBG1("base_addr: %p", dc->base_addr); | 1459 | DBG1("base_addr: %p", dc->base_addr); |
@@ -1464,13 +1472,28 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev, | |||
1464 | dc->state = NOZOMI_STATE_ENABLED; | 1472 | dc->state = NOZOMI_STATE_ENABLED; |
1465 | 1473 | ||
1466 | for (i = 0; i < MAX_PORT; i++) { | 1474 | for (i = 0; i < MAX_PORT; i++) { |
1475 | struct device *tty_dev; | ||
1476 | |||
1467 | mutex_init(&dc->port[i].tty_sem); | 1477 | mutex_init(&dc->port[i].tty_sem); |
1468 | tty_port_init(&dc->port[i].port); | 1478 | tty_port_init(&dc->port[i].port); |
1469 | tty_register_device(ntty_driver, dc->index_start + i, | 1479 | tty_dev = tty_register_device(ntty_driver, dc->index_start + i, |
1470 | &pdev->dev); | 1480 | &pdev->dev); |
1481 | |||
1482 | if (IS_ERR(tty_dev)) { | ||
1483 | ret = PTR_ERR(tty_dev); | ||
1484 | dev_err(&pdev->dev, "Could not allocate tty?\n"); | ||
1485 | goto err_free_tty; | ||
1486 | } | ||
1471 | } | 1487 | } |
1488 | |||
1472 | return 0; | 1489 | return 0; |
1473 | 1490 | ||
1491 | err_free_tty: | ||
1492 | for (i = dc->index_start; i < dc->index_start + MAX_PORT; ++i) | ||
1493 | tty_unregister_device(ntty_driver, i); | ||
1494 | err_free_kfifo: | ||
1495 | for (i = 0; i < MAX_PORT; i++) | ||
1496 | kfifo_free(&dc->port[i].fifo_ul); | ||
1474 | err_free_sbuf: | 1497 | err_free_sbuf: |
1475 | kfree(dc->send_buf); | 1498 | kfree(dc->send_buf); |
1476 | iounmap(dc->base_addr); | 1499 | iounmap(dc->base_addr); |
@@ -1536,8 +1559,7 @@ static void __devexit nozomi_card_exit(struct pci_dev *pdev) | |||
1536 | free_irq(pdev->irq, dc); | 1559 | free_irq(pdev->irq, dc); |
1537 | 1560 | ||
1538 | for (i = 0; i < MAX_PORT; i++) | 1561 | for (i = 0; i < MAX_PORT; i++) |
1539 | if (dc->port[i].fifo_ul) | 1562 | kfifo_free(&dc->port[i].fifo_ul); |
1540 | kfifo_free(dc->port[i].fifo_ul); | ||
1541 | 1563 | ||
1542 | kfree(dc->send_buf); | 1564 | kfree(dc->send_buf); |
1543 | 1565 | ||
@@ -1673,7 +1695,7 @@ static int ntty_write(struct tty_struct *tty, const unsigned char *buffer, | |||
1673 | goto exit; | 1695 | goto exit; |
1674 | } | 1696 | } |
1675 | 1697 | ||
1676 | rval = __kfifo_put(port->fifo_ul, (unsigned char *)buffer, count); | 1698 | rval = kfifo_in(&port->fifo_ul, (unsigned char *)buffer, count); |
1677 | 1699 | ||
1678 | /* notify card */ | 1700 | /* notify card */ |
1679 | if (unlikely(dc == NULL)) { | 1701 | if (unlikely(dc == NULL)) { |
@@ -1721,7 +1743,7 @@ static int ntty_write_room(struct tty_struct *tty) | |||
1721 | if (!port->port.count) | 1743 | if (!port->port.count) |
1722 | goto exit; | 1744 | goto exit; |
1723 | 1745 | ||
1724 | room = port->fifo_ul->size - __kfifo_len(port->fifo_ul); | 1746 | room = port->fifo_ul.size - kfifo_len(&port->fifo_ul); |
1725 | 1747 | ||
1726 | exit: | 1748 | exit: |
1727 | mutex_unlock(&port->tty_sem); | 1749 | mutex_unlock(&port->tty_sem); |
@@ -1878,7 +1900,7 @@ static s32 ntty_chars_in_buffer(struct tty_struct *tty) | |||
1878 | goto exit_in_buffer; | 1900 | goto exit_in_buffer; |
1879 | } | 1901 | } |
1880 | 1902 | ||
1881 | rval = __kfifo_len(port->fifo_ul); | 1903 | rval = kfifo_len(&port->fifo_ul); |
1882 | 1904 | ||
1883 | exit_in_buffer: | 1905 | exit_in_buffer: |
1884 | return rval; | 1906 | return rval; |
diff --git a/drivers/char/nwflash.c b/drivers/char/nwflash.c index 8c7df5ba088f..f80810901db6 100644 --- a/drivers/char/nwflash.c +++ b/drivers/char/nwflash.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
28 | #include <linux/smp_lock.h> | 28 | #include <linux/smp_lock.h> |
29 | #include <linux/mutex.h> | 29 | #include <linux/mutex.h> |
30 | #include <linux/jiffies.h> | ||
30 | 31 | ||
31 | #include <asm/hardware/dec21285.h> | 32 | #include <asm/hardware/dec21285.h> |
32 | #include <asm/io.h> | 33 | #include <asm/io.h> |
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index 8c262aaf7c26..0798754a607c 100644 --- a/drivers/char/sonypi.c +++ b/drivers/char/sonypi.c | |||
@@ -487,7 +487,7 @@ static struct sonypi_device { | |||
487 | int camera_power; | 487 | int camera_power; |
488 | int bluetooth_power; | 488 | int bluetooth_power; |
489 | struct mutex lock; | 489 | struct mutex lock; |
490 | struct kfifo *fifo; | 490 | struct kfifo fifo; |
491 | spinlock_t fifo_lock; | 491 | spinlock_t fifo_lock; |
492 | wait_queue_head_t fifo_proc_list; | 492 | wait_queue_head_t fifo_proc_list; |
493 | struct fasync_struct *fifo_async; | 493 | struct fasync_struct *fifo_async; |
@@ -496,7 +496,7 @@ static struct sonypi_device { | |||
496 | struct input_dev *input_jog_dev; | 496 | struct input_dev *input_jog_dev; |
497 | struct input_dev *input_key_dev; | 497 | struct input_dev *input_key_dev; |
498 | struct work_struct input_work; | 498 | struct work_struct input_work; |
499 | struct kfifo *input_fifo; | 499 | struct kfifo input_fifo; |
500 | spinlock_t input_fifo_lock; | 500 | spinlock_t input_fifo_lock; |
501 | } sonypi_device; | 501 | } sonypi_device; |
502 | 502 | ||
@@ -777,8 +777,9 @@ static void input_keyrelease(struct work_struct *work) | |||
777 | { | 777 | { |
778 | struct sonypi_keypress kp; | 778 | struct sonypi_keypress kp; |
779 | 779 | ||
780 | while (kfifo_get(sonypi_device.input_fifo, (unsigned char *)&kp, | 780 | while (kfifo_out_locked(&sonypi_device.input_fifo, (unsigned char *)&kp, |
781 | sizeof(kp)) == sizeof(kp)) { | 781 | sizeof(kp), &sonypi_device.input_fifo_lock) |
782 | == sizeof(kp)) { | ||
782 | msleep(10); | 783 | msleep(10); |
783 | input_report_key(kp.dev, kp.key, 0); | 784 | input_report_key(kp.dev, kp.key, 0); |
784 | input_sync(kp.dev); | 785 | input_sync(kp.dev); |
@@ -827,8 +828,9 @@ static void sonypi_report_input_event(u8 event) | |||
827 | if (kp.dev) { | 828 | if (kp.dev) { |
828 | input_report_key(kp.dev, kp.key, 1); | 829 | input_report_key(kp.dev, kp.key, 1); |
829 | input_sync(kp.dev); | 830 | input_sync(kp.dev); |
830 | kfifo_put(sonypi_device.input_fifo, | 831 | kfifo_in_locked(&sonypi_device.input_fifo, |
831 | (unsigned char *)&kp, sizeof(kp)); | 832 | (unsigned char *)&kp, sizeof(kp), |
833 | &sonypi_device.input_fifo_lock); | ||
832 | schedule_work(&sonypi_device.input_work); | 834 | schedule_work(&sonypi_device.input_work); |
833 | } | 835 | } |
834 | } | 836 | } |
@@ -880,7 +882,8 @@ found: | |||
880 | acpi_bus_generate_proc_event(sonypi_acpi_device, 1, event); | 882 | acpi_bus_generate_proc_event(sonypi_acpi_device, 1, event); |
881 | #endif | 883 | #endif |
882 | 884 | ||
883 | kfifo_put(sonypi_device.fifo, (unsigned char *)&event, sizeof(event)); | 885 | kfifo_in_locked(&sonypi_device.fifo, (unsigned char *)&event, |
886 | sizeof(event), &sonypi_device.fifo_lock); | ||
884 | kill_fasync(&sonypi_device.fifo_async, SIGIO, POLL_IN); | 887 | kill_fasync(&sonypi_device.fifo_async, SIGIO, POLL_IN); |
885 | wake_up_interruptible(&sonypi_device.fifo_proc_list); | 888 | wake_up_interruptible(&sonypi_device.fifo_proc_list); |
886 | 889 | ||
@@ -906,7 +909,7 @@ static int sonypi_misc_open(struct inode *inode, struct file *file) | |||
906 | mutex_lock(&sonypi_device.lock); | 909 | mutex_lock(&sonypi_device.lock); |
907 | /* Flush input queue on first open */ | 910 | /* Flush input queue on first open */ |
908 | if (!sonypi_device.open_count) | 911 | if (!sonypi_device.open_count) |
909 | kfifo_reset(sonypi_device.fifo); | 912 | kfifo_reset(&sonypi_device.fifo); |
910 | sonypi_device.open_count++; | 913 | sonypi_device.open_count++; |
911 | mutex_unlock(&sonypi_device.lock); | 914 | mutex_unlock(&sonypi_device.lock); |
912 | unlock_kernel(); | 915 | unlock_kernel(); |
@@ -919,17 +922,18 @@ static ssize_t sonypi_misc_read(struct file *file, char __user *buf, | |||
919 | ssize_t ret; | 922 | ssize_t ret; |
920 | unsigned char c; | 923 | unsigned char c; |
921 | 924 | ||
922 | if ((kfifo_len(sonypi_device.fifo) == 0) && | 925 | if ((kfifo_len(&sonypi_device.fifo) == 0) && |
923 | (file->f_flags & O_NONBLOCK)) | 926 | (file->f_flags & O_NONBLOCK)) |
924 | return -EAGAIN; | 927 | return -EAGAIN; |
925 | 928 | ||
926 | ret = wait_event_interruptible(sonypi_device.fifo_proc_list, | 929 | ret = wait_event_interruptible(sonypi_device.fifo_proc_list, |
927 | kfifo_len(sonypi_device.fifo) != 0); | 930 | kfifo_len(&sonypi_device.fifo) != 0); |
928 | if (ret) | 931 | if (ret) |
929 | return ret; | 932 | return ret; |
930 | 933 | ||
931 | while (ret < count && | 934 | while (ret < count && |
932 | (kfifo_get(sonypi_device.fifo, &c, sizeof(c)) == sizeof(c))) { | 935 | (kfifo_out_locked(&sonypi_device.fifo, &c, sizeof(c), |
936 | &sonypi_device.fifo_lock) == sizeof(c))) { | ||
933 | if (put_user(c, buf++)) | 937 | if (put_user(c, buf++)) |
934 | return -EFAULT; | 938 | return -EFAULT; |
935 | ret++; | 939 | ret++; |
@@ -946,7 +950,7 @@ static ssize_t sonypi_misc_read(struct file *file, char __user *buf, | |||
946 | static unsigned int sonypi_misc_poll(struct file *file, poll_table *wait) | 950 | static unsigned int sonypi_misc_poll(struct file *file, poll_table *wait) |
947 | { | 951 | { |
948 | poll_wait(file, &sonypi_device.fifo_proc_list, wait); | 952 | poll_wait(file, &sonypi_device.fifo_proc_list, wait); |
949 | if (kfifo_len(sonypi_device.fifo)) | 953 | if (kfifo_len(&sonypi_device.fifo)) |
950 | return POLLIN | POLLRDNORM; | 954 | return POLLIN | POLLRDNORM; |
951 | return 0; | 955 | return 0; |
952 | } | 956 | } |
@@ -1313,11 +1317,10 @@ static int __devinit sonypi_probe(struct platform_device *dev) | |||
1313 | "http://www.linux.it/~malattia/wiki/index.php/Sony_drivers\n"); | 1317 | "http://www.linux.it/~malattia/wiki/index.php/Sony_drivers\n"); |
1314 | 1318 | ||
1315 | spin_lock_init(&sonypi_device.fifo_lock); | 1319 | spin_lock_init(&sonypi_device.fifo_lock); |
1316 | sonypi_device.fifo = kfifo_alloc(SONYPI_BUF_SIZE, GFP_KERNEL, | 1320 | error = kfifo_alloc(&sonypi_device.fifo, SONYPI_BUF_SIZE, GFP_KERNEL); |
1317 | &sonypi_device.fifo_lock); | 1321 | if (error) { |
1318 | if (IS_ERR(sonypi_device.fifo)) { | ||
1319 | printk(KERN_ERR "sonypi: kfifo_alloc failed\n"); | 1322 | printk(KERN_ERR "sonypi: kfifo_alloc failed\n"); |
1320 | return PTR_ERR(sonypi_device.fifo); | 1323 | return error; |
1321 | } | 1324 | } |
1322 | 1325 | ||
1323 | init_waitqueue_head(&sonypi_device.fifo_proc_list); | 1326 | init_waitqueue_head(&sonypi_device.fifo_proc_list); |
@@ -1393,12 +1396,10 @@ static int __devinit sonypi_probe(struct platform_device *dev) | |||
1393 | } | 1396 | } |
1394 | 1397 | ||
1395 | spin_lock_init(&sonypi_device.input_fifo_lock); | 1398 | spin_lock_init(&sonypi_device.input_fifo_lock); |
1396 | sonypi_device.input_fifo = | 1399 | error = kfifo_alloc(&sonypi_device.input_fifo, SONYPI_BUF_SIZE, |
1397 | kfifo_alloc(SONYPI_BUF_SIZE, GFP_KERNEL, | 1400 | GFP_KERNEL); |
1398 | &sonypi_device.input_fifo_lock); | 1401 | if (error) { |
1399 | if (IS_ERR(sonypi_device.input_fifo)) { | ||
1400 | printk(KERN_ERR "sonypi: kfifo_alloc failed\n"); | 1402 | printk(KERN_ERR "sonypi: kfifo_alloc failed\n"); |
1401 | error = PTR_ERR(sonypi_device.input_fifo); | ||
1402 | goto err_inpdev_unregister; | 1403 | goto err_inpdev_unregister; |
1403 | } | 1404 | } |
1404 | 1405 | ||
@@ -1423,7 +1424,7 @@ static int __devinit sonypi_probe(struct platform_device *dev) | |||
1423 | pci_disable_device(pcidev); | 1424 | pci_disable_device(pcidev); |
1424 | err_put_pcidev: | 1425 | err_put_pcidev: |
1425 | pci_dev_put(pcidev); | 1426 | pci_dev_put(pcidev); |
1426 | kfifo_free(sonypi_device.fifo); | 1427 | kfifo_free(&sonypi_device.fifo); |
1427 | 1428 | ||
1428 | return error; | 1429 | return error; |
1429 | } | 1430 | } |
@@ -1438,7 +1439,7 @@ static int __devexit sonypi_remove(struct platform_device *dev) | |||
1438 | if (useinput) { | 1439 | if (useinput) { |
1439 | input_unregister_device(sonypi_device.input_key_dev); | 1440 | input_unregister_device(sonypi_device.input_key_dev); |
1440 | input_unregister_device(sonypi_device.input_jog_dev); | 1441 | input_unregister_device(sonypi_device.input_jog_dev); |
1441 | kfifo_free(sonypi_device.input_fifo); | 1442 | kfifo_free(&sonypi_device.input_fifo); |
1442 | } | 1443 | } |
1443 | 1444 | ||
1444 | misc_deregister(&sonypi_misc_device); | 1445 | misc_deregister(&sonypi_misc_device); |
@@ -1451,7 +1452,7 @@ static int __devexit sonypi_remove(struct platform_device *dev) | |||
1451 | pci_dev_put(sonypi_device.dev); | 1452 | pci_dev_put(sonypi_device.dev); |
1452 | } | 1453 | } |
1453 | 1454 | ||
1454 | kfifo_free(sonypi_device.fifo); | 1455 | kfifo_free(&sonypi_device.fifo); |
1455 | 1456 | ||
1456 | return 0; | 1457 | return 0; |
1457 | } | 1458 | } |
diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index f15112569c1d..efc1a61ca231 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c | |||
@@ -815,7 +815,7 @@ atc_is_tx_complete(struct dma_chan *chan, | |||
815 | dev_vdbg(chan2dev(chan), "is_tx_complete: %d (d%d, u%d)\n", | 815 | dev_vdbg(chan2dev(chan), "is_tx_complete: %d (d%d, u%d)\n", |
816 | cookie, done ? *done : 0, used ? *used : 0); | 816 | cookie, done ? *done : 0, used ? *used : 0); |
817 | 817 | ||
818 | spin_lock_bh(atchan->lock); | 818 | spin_lock_bh(&atchan->lock); |
819 | 819 | ||
820 | last_complete = atchan->completed_cookie; | 820 | last_complete = atchan->completed_cookie; |
821 | last_used = chan->cookie; | 821 | last_used = chan->cookie; |
@@ -830,7 +830,7 @@ atc_is_tx_complete(struct dma_chan *chan, | |||
830 | ret = dma_async_is_complete(cookie, last_complete, last_used); | 830 | ret = dma_async_is_complete(cookie, last_complete, last_used); |
831 | } | 831 | } |
832 | 832 | ||
833 | spin_unlock_bh(atchan->lock); | 833 | spin_unlock_bh(&atchan->lock); |
834 | 834 | ||
835 | if (done) | 835 | if (done) |
836 | *done = last_complete; | 836 | *done = last_complete; |
diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c index 4a99cd94536b..b5f2ee0f8e2c 100644 --- a/drivers/dma/coh901318.c +++ b/drivers/dma/coh901318.c | |||
@@ -1294,8 +1294,8 @@ static int __exit coh901318_remove(struct platform_device *pdev) | |||
1294 | dma_async_device_unregister(&base->dma_slave); | 1294 | dma_async_device_unregister(&base->dma_slave); |
1295 | coh901318_pool_destroy(&base->pool); | 1295 | coh901318_pool_destroy(&base->pool); |
1296 | free_irq(platform_get_irq(pdev, 0), base); | 1296 | free_irq(platform_get_irq(pdev, 0), base); |
1297 | kfree(base); | ||
1298 | iounmap(base->virtbase); | 1297 | iounmap(base->virtbase); |
1298 | kfree(base); | ||
1299 | release_mem_region(pdev->resource->start, | 1299 | release_mem_region(pdev->resource->start, |
1300 | resource_size(pdev->resource)); | 1300 | resource_size(pdev->resource)); |
1301 | return 0; | 1301 | return 0; |
diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c index 285bed0fe17b..d28369f7afd2 100644 --- a/drivers/dma/dw_dmac.c +++ b/drivers/dma/dw_dmac.c | |||
@@ -1270,8 +1270,6 @@ static int __init dw_probe(struct platform_device *pdev) | |||
1270 | goto err_kfree; | 1270 | goto err_kfree; |
1271 | } | 1271 | } |
1272 | 1272 | ||
1273 | memset(dw, 0, sizeof *dw); | ||
1274 | |||
1275 | dw->regs = ioremap(io->start, DW_REGLEN); | 1273 | dw->regs = ioremap(io->start, DW_REGLEN); |
1276 | if (!dw->regs) { | 1274 | if (!dw->regs) { |
1277 | err = -ENOMEM; | 1275 | err = -ENOMEM; |
diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c index c524d36d3c2e..dcc4ab78b32b 100644 --- a/drivers/dma/ioat/dma.c +++ b/drivers/dma/ioat/dma.c | |||
@@ -1032,7 +1032,7 @@ int __devinit ioat_probe(struct ioatdma_device *device) | |||
1032 | dma->dev = &pdev->dev; | 1032 | dma->dev = &pdev->dev; |
1033 | 1033 | ||
1034 | if (!dma->chancnt) { | 1034 | if (!dma->chancnt) { |
1035 | dev_err(dev, "zero channels detected\n"); | 1035 | dev_err(dev, "channel enumeration error\n"); |
1036 | goto err_setup_interrupts; | 1036 | goto err_setup_interrupts; |
1037 | } | 1037 | } |
1038 | 1038 | ||
diff --git a/drivers/dma/ioat/dma.h b/drivers/dma/ioat/dma.h index 45edde996480..bbc3e78ef333 100644 --- a/drivers/dma/ioat/dma.h +++ b/drivers/dma/ioat/dma.h | |||
@@ -60,6 +60,7 @@ | |||
60 | * @dca: direct cache access context | 60 | * @dca: direct cache access context |
61 | * @intr_quirk: interrupt setup quirk (for ioat_v1 devices) | 61 | * @intr_quirk: interrupt setup quirk (for ioat_v1 devices) |
62 | * @enumerate_channels: hw version specific channel enumeration | 62 | * @enumerate_channels: hw version specific channel enumeration |
63 | * @reset_hw: hw version specific channel (re)initialization | ||
63 | * @cleanup_tasklet: select between the v2 and v3 cleanup routines | 64 | * @cleanup_tasklet: select between the v2 and v3 cleanup routines |
64 | * @timer_fn: select between the v2 and v3 timer watchdog routines | 65 | * @timer_fn: select between the v2 and v3 timer watchdog routines |
65 | * @self_test: hardware version specific self test for each supported op type | 66 | * @self_test: hardware version specific self test for each supported op type |
@@ -78,6 +79,7 @@ struct ioatdma_device { | |||
78 | struct dca_provider *dca; | 79 | struct dca_provider *dca; |
79 | void (*intr_quirk)(struct ioatdma_device *device); | 80 | void (*intr_quirk)(struct ioatdma_device *device); |
80 | int (*enumerate_channels)(struct ioatdma_device *device); | 81 | int (*enumerate_channels)(struct ioatdma_device *device); |
82 | int (*reset_hw)(struct ioat_chan_common *chan); | ||
81 | void (*cleanup_tasklet)(unsigned long data); | 83 | void (*cleanup_tasklet)(unsigned long data); |
82 | void (*timer_fn)(unsigned long data); | 84 | void (*timer_fn)(unsigned long data); |
83 | int (*self_test)(struct ioatdma_device *device); | 85 | int (*self_test)(struct ioatdma_device *device); |
@@ -264,6 +266,22 @@ static inline void ioat_suspend(struct ioat_chan_common *chan) | |||
264 | writeb(IOAT_CHANCMD_SUSPEND, chan->reg_base + IOAT_CHANCMD_OFFSET(ver)); | 266 | writeb(IOAT_CHANCMD_SUSPEND, chan->reg_base + IOAT_CHANCMD_OFFSET(ver)); |
265 | } | 267 | } |
266 | 268 | ||
269 | static inline void ioat_reset(struct ioat_chan_common *chan) | ||
270 | { | ||
271 | u8 ver = chan->device->version; | ||
272 | |||
273 | writeb(IOAT_CHANCMD_RESET, chan->reg_base + IOAT_CHANCMD_OFFSET(ver)); | ||
274 | } | ||
275 | |||
276 | static inline bool ioat_reset_pending(struct ioat_chan_common *chan) | ||
277 | { | ||
278 | u8 ver = chan->device->version; | ||
279 | u8 cmd; | ||
280 | |||
281 | cmd = readb(chan->reg_base + IOAT_CHANCMD_OFFSET(ver)); | ||
282 | return (cmd & IOAT_CHANCMD_RESET) == IOAT_CHANCMD_RESET; | ||
283 | } | ||
284 | |||
267 | static inline void ioat_set_chainaddr(struct ioat_dma_chan *ioat, u64 addr) | 285 | static inline void ioat_set_chainaddr(struct ioat_dma_chan *ioat, u64 addr) |
268 | { | 286 | { |
269 | struct ioat_chan_common *chan = &ioat->base; | 287 | struct ioat_chan_common *chan = &ioat->base; |
diff --git a/drivers/dma/ioat/dma_v2.c b/drivers/dma/ioat/dma_v2.c index 8f1f7f05deaa..5f7a500e18d0 100644 --- a/drivers/dma/ioat/dma_v2.c +++ b/drivers/dma/ioat/dma_v2.c | |||
@@ -239,20 +239,50 @@ void __ioat2_restart_chan(struct ioat2_dma_chan *ioat) | |||
239 | __ioat2_start_null_desc(ioat); | 239 | __ioat2_start_null_desc(ioat); |
240 | } | 240 | } |
241 | 241 | ||
242 | static void ioat2_restart_channel(struct ioat2_dma_chan *ioat) | 242 | int ioat2_quiesce(struct ioat_chan_common *chan, unsigned long tmo) |
243 | { | 243 | { |
244 | struct ioat_chan_common *chan = &ioat->base; | 244 | unsigned long end = jiffies + tmo; |
245 | unsigned long phys_complete; | 245 | int err = 0; |
246 | u32 status; | 246 | u32 status; |
247 | 247 | ||
248 | status = ioat_chansts(chan); | 248 | status = ioat_chansts(chan); |
249 | if (is_ioat_active(status) || is_ioat_idle(status)) | 249 | if (is_ioat_active(status) || is_ioat_idle(status)) |
250 | ioat_suspend(chan); | 250 | ioat_suspend(chan); |
251 | while (is_ioat_active(status) || is_ioat_idle(status)) { | 251 | while (is_ioat_active(status) || is_ioat_idle(status)) { |
252 | if (end && time_after(jiffies, end)) { | ||
253 | err = -ETIMEDOUT; | ||
254 | break; | ||
255 | } | ||
252 | status = ioat_chansts(chan); | 256 | status = ioat_chansts(chan); |
253 | cpu_relax(); | 257 | cpu_relax(); |
254 | } | 258 | } |
255 | 259 | ||
260 | return err; | ||
261 | } | ||
262 | |||
263 | int ioat2_reset_sync(struct ioat_chan_common *chan, unsigned long tmo) | ||
264 | { | ||
265 | unsigned long end = jiffies + tmo; | ||
266 | int err = 0; | ||
267 | |||
268 | ioat_reset(chan); | ||
269 | while (ioat_reset_pending(chan)) { | ||
270 | if (end && time_after(jiffies, end)) { | ||
271 | err = -ETIMEDOUT; | ||
272 | break; | ||
273 | } | ||
274 | cpu_relax(); | ||
275 | } | ||
276 | |||
277 | return err; | ||
278 | } | ||
279 | |||
280 | static void ioat2_restart_channel(struct ioat2_dma_chan *ioat) | ||
281 | { | ||
282 | struct ioat_chan_common *chan = &ioat->base; | ||
283 | unsigned long phys_complete; | ||
284 | |||
285 | ioat2_quiesce(chan, 0); | ||
256 | if (ioat_cleanup_preamble(chan, &phys_complete)) | 286 | if (ioat_cleanup_preamble(chan, &phys_complete)) |
257 | __cleanup(ioat, phys_complete); | 287 | __cleanup(ioat, phys_complete); |
258 | 288 | ||
@@ -318,6 +348,19 @@ void ioat2_timer_event(unsigned long data) | |||
318 | spin_unlock_bh(&chan->cleanup_lock); | 348 | spin_unlock_bh(&chan->cleanup_lock); |
319 | } | 349 | } |
320 | 350 | ||
351 | static int ioat2_reset_hw(struct ioat_chan_common *chan) | ||
352 | { | ||
353 | /* throw away whatever the channel was doing and get it initialized */ | ||
354 | u32 chanerr; | ||
355 | |||
356 | ioat2_quiesce(chan, msecs_to_jiffies(100)); | ||
357 | |||
358 | chanerr = readl(chan->reg_base + IOAT_CHANERR_OFFSET); | ||
359 | writel(chanerr, chan->reg_base + IOAT_CHANERR_OFFSET); | ||
360 | |||
361 | return ioat2_reset_sync(chan, msecs_to_jiffies(200)); | ||
362 | } | ||
363 | |||
321 | /** | 364 | /** |
322 | * ioat2_enumerate_channels - find and initialize the device's channels | 365 | * ioat2_enumerate_channels - find and initialize the device's channels |
323 | * @device: the device to be enumerated | 366 | * @device: the device to be enumerated |
@@ -360,6 +403,10 @@ int ioat2_enumerate_channels(struct ioatdma_device *device) | |||
360 | (unsigned long) ioat); | 403 | (unsigned long) ioat); |
361 | ioat->xfercap_log = xfercap_log; | 404 | ioat->xfercap_log = xfercap_log; |
362 | spin_lock_init(&ioat->ring_lock); | 405 | spin_lock_init(&ioat->ring_lock); |
406 | if (device->reset_hw(&ioat->base)) { | ||
407 | i = 0; | ||
408 | break; | ||
409 | } | ||
363 | } | 410 | } |
364 | dma->chancnt = i; | 411 | dma->chancnt = i; |
365 | return i; | 412 | return i; |
@@ -467,7 +514,6 @@ int ioat2_alloc_chan_resources(struct dma_chan *c) | |||
467 | struct ioat2_dma_chan *ioat = to_ioat2_chan(c); | 514 | struct ioat2_dma_chan *ioat = to_ioat2_chan(c); |
468 | struct ioat_chan_common *chan = &ioat->base; | 515 | struct ioat_chan_common *chan = &ioat->base; |
469 | struct ioat_ring_ent **ring; | 516 | struct ioat_ring_ent **ring; |
470 | u32 chanerr; | ||
471 | int order; | 517 | int order; |
472 | 518 | ||
473 | /* have we already been set up? */ | 519 | /* have we already been set up? */ |
@@ -477,12 +523,6 @@ int ioat2_alloc_chan_resources(struct dma_chan *c) | |||
477 | /* Setup register to interrupt and write completion status on error */ | 523 | /* Setup register to interrupt and write completion status on error */ |
478 | writew(IOAT_CHANCTRL_RUN, chan->reg_base + IOAT_CHANCTRL_OFFSET); | 524 | writew(IOAT_CHANCTRL_RUN, chan->reg_base + IOAT_CHANCTRL_OFFSET); |
479 | 525 | ||
480 | chanerr = readl(chan->reg_base + IOAT_CHANERR_OFFSET); | ||
481 | if (chanerr) { | ||
482 | dev_err(to_dev(chan), "CHANERR = %x, clearing\n", chanerr); | ||
483 | writel(chanerr, chan->reg_base + IOAT_CHANERR_OFFSET); | ||
484 | } | ||
485 | |||
486 | /* allocate a completion writeback area */ | 526 | /* allocate a completion writeback area */ |
487 | /* doing 2 32bit writes to mmio since 1 64b write doesn't work */ | 527 | /* doing 2 32bit writes to mmio since 1 64b write doesn't work */ |
488 | chan->completion = pci_pool_alloc(chan->device->completion_pool, | 528 | chan->completion = pci_pool_alloc(chan->device->completion_pool, |
@@ -746,13 +786,7 @@ void ioat2_free_chan_resources(struct dma_chan *c) | |||
746 | tasklet_disable(&chan->cleanup_task); | 786 | tasklet_disable(&chan->cleanup_task); |
747 | del_timer_sync(&chan->timer); | 787 | del_timer_sync(&chan->timer); |
748 | device->cleanup_tasklet((unsigned long) ioat); | 788 | device->cleanup_tasklet((unsigned long) ioat); |
749 | 789 | device->reset_hw(chan); | |
750 | /* Delay 100ms after reset to allow internal DMA logic to quiesce | ||
751 | * before removing DMA descriptor resources. | ||
752 | */ | ||
753 | writeb(IOAT_CHANCMD_RESET, | ||
754 | chan->reg_base + IOAT_CHANCMD_OFFSET(chan->device->version)); | ||
755 | mdelay(100); | ||
756 | 790 | ||
757 | spin_lock_bh(&ioat->ring_lock); | 791 | spin_lock_bh(&ioat->ring_lock); |
758 | descs = ioat2_ring_space(ioat); | 792 | descs = ioat2_ring_space(ioat); |
@@ -839,6 +873,7 @@ int __devinit ioat2_dma_probe(struct ioatdma_device *device, int dca) | |||
839 | int err; | 873 | int err; |
840 | 874 | ||
841 | device->enumerate_channels = ioat2_enumerate_channels; | 875 | device->enumerate_channels = ioat2_enumerate_channels; |
876 | device->reset_hw = ioat2_reset_hw; | ||
842 | device->cleanup_tasklet = ioat2_cleanup_tasklet; | 877 | device->cleanup_tasklet = ioat2_cleanup_tasklet; |
843 | device->timer_fn = ioat2_timer_event; | 878 | device->timer_fn = ioat2_timer_event; |
844 | device->self_test = ioat_dma_self_test; | 879 | device->self_test = ioat_dma_self_test; |
diff --git a/drivers/dma/ioat/dma_v2.h b/drivers/dma/ioat/dma_v2.h index 1d849ef74d5f..3afad8da43cc 100644 --- a/drivers/dma/ioat/dma_v2.h +++ b/drivers/dma/ioat/dma_v2.h | |||
@@ -185,6 +185,8 @@ bool reshape_ring(struct ioat2_dma_chan *ioat, int order); | |||
185 | void __ioat2_issue_pending(struct ioat2_dma_chan *ioat); | 185 | void __ioat2_issue_pending(struct ioat2_dma_chan *ioat); |
186 | void ioat2_cleanup_tasklet(unsigned long data); | 186 | void ioat2_cleanup_tasklet(unsigned long data); |
187 | void ioat2_timer_event(unsigned long data); | 187 | void ioat2_timer_event(unsigned long data); |
188 | int ioat2_quiesce(struct ioat_chan_common *chan, unsigned long tmo); | ||
189 | int ioat2_reset_sync(struct ioat_chan_common *chan, unsigned long tmo); | ||
188 | extern struct kobj_type ioat2_ktype; | 190 | extern struct kobj_type ioat2_ktype; |
189 | extern struct kmem_cache *ioat2_cache; | 191 | extern struct kmem_cache *ioat2_cache; |
190 | #endif /* IOATDMA_V2_H */ | 192 | #endif /* IOATDMA_V2_H */ |
diff --git a/drivers/dma/ioat/dma_v3.c b/drivers/dma/ioat/dma_v3.c index 42f6f10fb0cc..9908c9e94b2d 100644 --- a/drivers/dma/ioat/dma_v3.c +++ b/drivers/dma/ioat/dma_v3.c | |||
@@ -650,9 +650,11 @@ __ioat3_prep_pq_lock(struct dma_chan *c, enum sum_check_flags *result, | |||
650 | 650 | ||
651 | num_descs = ioat2_xferlen_to_descs(ioat, len); | 651 | num_descs = ioat2_xferlen_to_descs(ioat, len); |
652 | /* we need 2x the number of descriptors to cover greater than 3 | 652 | /* we need 2x the number of descriptors to cover greater than 3 |
653 | * sources | 653 | * sources (we need 1 extra source in the q-only continuation |
654 | * case and 3 extra sources in the p+q continuation case. | ||
654 | */ | 655 | */ |
655 | if (src_cnt > 3 || flags & DMA_PREP_CONTINUE) { | 656 | if (src_cnt + dmaf_p_disabled_continue(flags) > 3 || |
657 | (dmaf_continue(flags) && !dmaf_p_disabled_continue(flags))) { | ||
656 | with_ext = 1; | 658 | with_ext = 1; |
657 | num_descs *= 2; | 659 | num_descs *= 2; |
658 | } else | 660 | } else |
@@ -1128,6 +1130,45 @@ static int __devinit ioat3_dma_self_test(struct ioatdma_device *device) | |||
1128 | return 0; | 1130 | return 0; |
1129 | } | 1131 | } |
1130 | 1132 | ||
1133 | static int ioat3_reset_hw(struct ioat_chan_common *chan) | ||
1134 | { | ||
1135 | /* throw away whatever the channel was doing and get it | ||
1136 | * initialized, with ioat3 specific workarounds | ||
1137 | */ | ||
1138 | struct ioatdma_device *device = chan->device; | ||
1139 | struct pci_dev *pdev = device->pdev; | ||
1140 | u32 chanerr; | ||
1141 | u16 dev_id; | ||
1142 | int err; | ||
1143 | |||
1144 | ioat2_quiesce(chan, msecs_to_jiffies(100)); | ||
1145 | |||
1146 | chanerr = readl(chan->reg_base + IOAT_CHANERR_OFFSET); | ||
1147 | writel(chanerr, chan->reg_base + IOAT_CHANERR_OFFSET); | ||
1148 | |||
1149 | /* -= IOAT ver.3 workarounds =- */ | ||
1150 | /* Write CHANERRMSK_INT with 3E07h to mask out the errors | ||
1151 | * that can cause stability issues for IOAT ver.3, and clear any | ||
1152 | * pending errors | ||
1153 | */ | ||
1154 | pci_write_config_dword(pdev, IOAT_PCI_CHANERRMASK_INT_OFFSET, 0x3e07); | ||
1155 | err = pci_read_config_dword(pdev, IOAT_PCI_CHANERR_INT_OFFSET, &chanerr); | ||
1156 | if (err) { | ||
1157 | dev_err(&pdev->dev, "channel error register unreachable\n"); | ||
1158 | return err; | ||
1159 | } | ||
1160 | pci_write_config_dword(pdev, IOAT_PCI_CHANERR_INT_OFFSET, chanerr); | ||
1161 | |||
1162 | /* Clear DMAUNCERRSTS Cfg-Reg Parity Error status bit | ||
1163 | * (workaround for spurious config parity error after restart) | ||
1164 | */ | ||
1165 | pci_read_config_word(pdev, IOAT_PCI_DEVICE_ID_OFFSET, &dev_id); | ||
1166 | if (dev_id == PCI_DEVICE_ID_INTEL_IOAT_TBG0) | ||
1167 | pci_write_config_dword(pdev, IOAT_PCI_DMAUNCERRSTS_OFFSET, 0x10); | ||
1168 | |||
1169 | return ioat2_reset_sync(chan, msecs_to_jiffies(200)); | ||
1170 | } | ||
1171 | |||
1131 | int __devinit ioat3_dma_probe(struct ioatdma_device *device, int dca) | 1172 | int __devinit ioat3_dma_probe(struct ioatdma_device *device, int dca) |
1132 | { | 1173 | { |
1133 | struct pci_dev *pdev = device->pdev; | 1174 | struct pci_dev *pdev = device->pdev; |
@@ -1137,10 +1178,10 @@ int __devinit ioat3_dma_probe(struct ioatdma_device *device, int dca) | |||
1137 | struct ioat_chan_common *chan; | 1178 | struct ioat_chan_common *chan; |
1138 | bool is_raid_device = false; | 1179 | bool is_raid_device = false; |
1139 | int err; | 1180 | int err; |
1140 | u16 dev_id; | ||
1141 | u32 cap; | 1181 | u32 cap; |
1142 | 1182 | ||
1143 | device->enumerate_channels = ioat2_enumerate_channels; | 1183 | device->enumerate_channels = ioat2_enumerate_channels; |
1184 | device->reset_hw = ioat3_reset_hw; | ||
1144 | device->self_test = ioat3_dma_self_test; | 1185 | device->self_test = ioat3_dma_self_test; |
1145 | dma = &device->common; | 1186 | dma = &device->common; |
1146 | dma->device_prep_dma_memcpy = ioat2_dma_prep_memcpy_lock; | 1187 | dma->device_prep_dma_memcpy = ioat2_dma_prep_memcpy_lock; |
@@ -1216,19 +1257,6 @@ int __devinit ioat3_dma_probe(struct ioatdma_device *device, int dca) | |||
1216 | dma->device_prep_dma_xor_val = NULL; | 1257 | dma->device_prep_dma_xor_val = NULL; |
1217 | #endif | 1258 | #endif |
1218 | 1259 | ||
1219 | /* -= IOAT ver.3 workarounds =- */ | ||
1220 | /* Write CHANERRMSK_INT with 3E07h to mask out the errors | ||
1221 | * that can cause stability issues for IOAT ver.3 | ||
1222 | */ | ||
1223 | pci_write_config_dword(pdev, IOAT_PCI_CHANERRMASK_INT_OFFSET, 0x3e07); | ||
1224 | |||
1225 | /* Clear DMAUNCERRSTS Cfg-Reg Parity Error status bit | ||
1226 | * (workaround for spurious config parity error after restart) | ||
1227 | */ | ||
1228 | pci_read_config_word(pdev, IOAT_PCI_DEVICE_ID_OFFSET, &dev_id); | ||
1229 | if (dev_id == PCI_DEVICE_ID_INTEL_IOAT_TBG0) | ||
1230 | pci_write_config_dword(pdev, IOAT_PCI_DMAUNCERRSTS_OFFSET, 0x10); | ||
1231 | |||
1232 | err = ioat_probe(device); | 1260 | err = ioat_probe(device); |
1233 | if (err) | 1261 | if (err) |
1234 | return err; | 1262 | return err; |
diff --git a/drivers/dma/ioat/registers.h b/drivers/dma/ioat/registers.h index f015ec196700..e8ae63baf588 100644 --- a/drivers/dma/ioat/registers.h +++ b/drivers/dma/ioat/registers.h | |||
@@ -27,6 +27,7 @@ | |||
27 | 27 | ||
28 | #define IOAT_PCI_DEVICE_ID_OFFSET 0x02 | 28 | #define IOAT_PCI_DEVICE_ID_OFFSET 0x02 |
29 | #define IOAT_PCI_DMAUNCERRSTS_OFFSET 0x148 | 29 | #define IOAT_PCI_DMAUNCERRSTS_OFFSET 0x148 |
30 | #define IOAT_PCI_CHANERR_INT_OFFSET 0x180 | ||
30 | #define IOAT_PCI_CHANERRMASK_INT_OFFSET 0x184 | 31 | #define IOAT_PCI_CHANERRMASK_INT_OFFSET 0x184 |
31 | 32 | ||
32 | /* MMIO Device Registers */ | 33 | /* MMIO Device Registers */ |
diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c index 2e4a54c8afeb..d10cc899c460 100644 --- a/drivers/dma/shdma.c +++ b/drivers/dma/shdma.c | |||
@@ -23,16 +23,19 @@ | |||
23 | #include <linux/dmaengine.h> | 23 | #include <linux/dmaengine.h> |
24 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
25 | #include <linux/dma-mapping.h> | 25 | #include <linux/dma-mapping.h> |
26 | #include <linux/dmapool.h> | ||
27 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
28 | #include <cpu/dma.h> | 27 | #include <cpu/dma.h> |
29 | #include <asm/dma-sh.h> | 28 | #include <asm/dma-sh.h> |
30 | #include "shdma.h" | 29 | #include "shdma.h" |
31 | 30 | ||
32 | /* DMA descriptor control */ | 31 | /* DMA descriptor control */ |
33 | #define DESC_LAST (-1) | 32 | enum sh_dmae_desc_status { |
34 | #define DESC_COMP (1) | 33 | DESC_IDLE, |
35 | #define DESC_NCOMP (0) | 34 | DESC_PREPARED, |
35 | DESC_SUBMITTED, | ||
36 | DESC_COMPLETED, /* completed, have to call callback */ | ||
37 | DESC_WAITING, /* callback called, waiting for ack / re-submit */ | ||
38 | }; | ||
36 | 39 | ||
37 | #define NR_DESCS_PER_CHANNEL 32 | 40 | #define NR_DESCS_PER_CHANNEL 32 |
38 | /* | 41 | /* |
@@ -45,6 +48,8 @@ | |||
45 | */ | 48 | */ |
46 | #define RS_DEFAULT (RS_DUAL) | 49 | #define RS_DEFAULT (RS_DUAL) |
47 | 50 | ||
51 | static void sh_dmae_chan_ld_cleanup(struct sh_dmae_chan *sh_chan, bool all); | ||
52 | |||
48 | #define SH_DMAC_CHAN_BASE(id) (dma_base_addr[id]) | 53 | #define SH_DMAC_CHAN_BASE(id) (dma_base_addr[id]) |
49 | static void sh_dmae_writel(struct sh_dmae_chan *sh_dc, u32 data, u32 reg) | 54 | static void sh_dmae_writel(struct sh_dmae_chan *sh_dc, u32 data, u32 reg) |
50 | { | 55 | { |
@@ -106,11 +111,11 @@ static inline unsigned int calc_xmit_shift(struct sh_dmae_chan *sh_chan) | |||
106 | return ts_shift[(chcr & CHCR_TS_MASK) >> CHCR_TS_SHIFT]; | 111 | return ts_shift[(chcr & CHCR_TS_MASK) >> CHCR_TS_SHIFT]; |
107 | } | 112 | } |
108 | 113 | ||
109 | static void dmae_set_reg(struct sh_dmae_chan *sh_chan, struct sh_dmae_regs hw) | 114 | static void dmae_set_reg(struct sh_dmae_chan *sh_chan, struct sh_dmae_regs *hw) |
110 | { | 115 | { |
111 | sh_dmae_writel(sh_chan, hw.sar, SAR); | 116 | sh_dmae_writel(sh_chan, hw->sar, SAR); |
112 | sh_dmae_writel(sh_chan, hw.dar, DAR); | 117 | sh_dmae_writel(sh_chan, hw->dar, DAR); |
113 | sh_dmae_writel(sh_chan, hw.tcr >> calc_xmit_shift(sh_chan), TCR); | 118 | sh_dmae_writel(sh_chan, hw->tcr >> calc_xmit_shift(sh_chan), TCR); |
114 | } | 119 | } |
115 | 120 | ||
116 | static void dmae_start(struct sh_dmae_chan *sh_chan) | 121 | static void dmae_start(struct sh_dmae_chan *sh_chan) |
@@ -184,8 +189,9 @@ static int dmae_set_dmars(struct sh_dmae_chan *sh_chan, u16 val) | |||
184 | 189 | ||
185 | static dma_cookie_t sh_dmae_tx_submit(struct dma_async_tx_descriptor *tx) | 190 | static dma_cookie_t sh_dmae_tx_submit(struct dma_async_tx_descriptor *tx) |
186 | { | 191 | { |
187 | struct sh_desc *desc = tx_to_sh_desc(tx); | 192 | struct sh_desc *desc = tx_to_sh_desc(tx), *chunk, *last = desc, *c; |
188 | struct sh_dmae_chan *sh_chan = to_sh_chan(tx->chan); | 193 | struct sh_dmae_chan *sh_chan = to_sh_chan(tx->chan); |
194 | dma_async_tx_callback callback = tx->callback; | ||
189 | dma_cookie_t cookie; | 195 | dma_cookie_t cookie; |
190 | 196 | ||
191 | spin_lock_bh(&sh_chan->desc_lock); | 197 | spin_lock_bh(&sh_chan->desc_lock); |
@@ -195,45 +201,53 @@ static dma_cookie_t sh_dmae_tx_submit(struct dma_async_tx_descriptor *tx) | |||
195 | if (cookie < 0) | 201 | if (cookie < 0) |
196 | cookie = 1; | 202 | cookie = 1; |
197 | 203 | ||
198 | /* If desc only in the case of 1 */ | 204 | sh_chan->common.cookie = cookie; |
199 | if (desc->async_tx.cookie != -EBUSY) | 205 | tx->cookie = cookie; |
200 | desc->async_tx.cookie = cookie; | 206 | |
201 | sh_chan->common.cookie = desc->async_tx.cookie; | 207 | /* Mark all chunks of this descriptor as submitted, move to the queue */ |
208 | list_for_each_entry_safe(chunk, c, desc->node.prev, node) { | ||
209 | /* | ||
210 | * All chunks are on the global ld_free, so, we have to find | ||
211 | * the end of the chain ourselves | ||
212 | */ | ||
213 | if (chunk != desc && (chunk->mark == DESC_IDLE || | ||
214 | chunk->async_tx.cookie > 0 || | ||
215 | chunk->async_tx.cookie == -EBUSY || | ||
216 | &chunk->node == &sh_chan->ld_free)) | ||
217 | break; | ||
218 | chunk->mark = DESC_SUBMITTED; | ||
219 | /* Callback goes to the last chunk */ | ||
220 | chunk->async_tx.callback = NULL; | ||
221 | chunk->cookie = cookie; | ||
222 | list_move_tail(&chunk->node, &sh_chan->ld_queue); | ||
223 | last = chunk; | ||
224 | } | ||
225 | |||
226 | last->async_tx.callback = callback; | ||
227 | last->async_tx.callback_param = tx->callback_param; | ||
202 | 228 | ||
203 | list_splice_init(&desc->tx_list, sh_chan->ld_queue.prev); | 229 | dev_dbg(sh_chan->dev, "submit #%d@%p on %d: %x[%d] -> %x\n", |
230 | tx->cookie, &last->async_tx, sh_chan->id, | ||
231 | desc->hw.sar, desc->hw.tcr, desc->hw.dar); | ||
204 | 232 | ||
205 | spin_unlock_bh(&sh_chan->desc_lock); | 233 | spin_unlock_bh(&sh_chan->desc_lock); |
206 | 234 | ||
207 | return cookie; | 235 | return cookie; |
208 | } | 236 | } |
209 | 237 | ||
238 | /* Called with desc_lock held */ | ||
210 | static struct sh_desc *sh_dmae_get_desc(struct sh_dmae_chan *sh_chan) | 239 | static struct sh_desc *sh_dmae_get_desc(struct sh_dmae_chan *sh_chan) |
211 | { | 240 | { |
212 | struct sh_desc *desc, *_desc, *ret = NULL; | 241 | struct sh_desc *desc; |
213 | 242 | ||
214 | spin_lock_bh(&sh_chan->desc_lock); | 243 | list_for_each_entry(desc, &sh_chan->ld_free, node) |
215 | list_for_each_entry_safe(desc, _desc, &sh_chan->ld_free, node) { | 244 | if (desc->mark != DESC_PREPARED) { |
216 | if (async_tx_test_ack(&desc->async_tx)) { | 245 | BUG_ON(desc->mark != DESC_IDLE); |
217 | list_del(&desc->node); | 246 | list_del(&desc->node); |
218 | ret = desc; | 247 | return desc; |
219 | break; | ||
220 | } | 248 | } |
221 | } | ||
222 | spin_unlock_bh(&sh_chan->desc_lock); | ||
223 | |||
224 | return ret; | ||
225 | } | ||
226 | |||
227 | static void sh_dmae_put_desc(struct sh_dmae_chan *sh_chan, struct sh_desc *desc) | ||
228 | { | ||
229 | if (desc) { | ||
230 | spin_lock_bh(&sh_chan->desc_lock); | ||
231 | |||
232 | list_splice_init(&desc->tx_list, &sh_chan->ld_free); | ||
233 | list_add(&desc->node, &sh_chan->ld_free); | ||
234 | 249 | ||
235 | spin_unlock_bh(&sh_chan->desc_lock); | 250 | return NULL; |
236 | } | ||
237 | } | 251 | } |
238 | 252 | ||
239 | static int sh_dmae_alloc_chan_resources(struct dma_chan *chan) | 253 | static int sh_dmae_alloc_chan_resources(struct dma_chan *chan) |
@@ -252,11 +266,10 @@ static int sh_dmae_alloc_chan_resources(struct dma_chan *chan) | |||
252 | dma_async_tx_descriptor_init(&desc->async_tx, | 266 | dma_async_tx_descriptor_init(&desc->async_tx, |
253 | &sh_chan->common); | 267 | &sh_chan->common); |
254 | desc->async_tx.tx_submit = sh_dmae_tx_submit; | 268 | desc->async_tx.tx_submit = sh_dmae_tx_submit; |
255 | desc->async_tx.flags = DMA_CTRL_ACK; | 269 | desc->mark = DESC_IDLE; |
256 | INIT_LIST_HEAD(&desc->tx_list); | ||
257 | sh_dmae_put_desc(sh_chan, desc); | ||
258 | 270 | ||
259 | spin_lock_bh(&sh_chan->desc_lock); | 271 | spin_lock_bh(&sh_chan->desc_lock); |
272 | list_add(&desc->node, &sh_chan->ld_free); | ||
260 | sh_chan->descs_allocated++; | 273 | sh_chan->descs_allocated++; |
261 | } | 274 | } |
262 | spin_unlock_bh(&sh_chan->desc_lock); | 275 | spin_unlock_bh(&sh_chan->desc_lock); |
@@ -273,7 +286,10 @@ static void sh_dmae_free_chan_resources(struct dma_chan *chan) | |||
273 | struct sh_desc *desc, *_desc; | 286 | struct sh_desc *desc, *_desc; |
274 | LIST_HEAD(list); | 287 | LIST_HEAD(list); |
275 | 288 | ||
276 | BUG_ON(!list_empty(&sh_chan->ld_queue)); | 289 | /* Prepared and not submitted descriptors can still be on the queue */ |
290 | if (!list_empty(&sh_chan->ld_queue)) | ||
291 | sh_dmae_chan_ld_cleanup(sh_chan, true); | ||
292 | |||
277 | spin_lock_bh(&sh_chan->desc_lock); | 293 | spin_lock_bh(&sh_chan->desc_lock); |
278 | 294 | ||
279 | list_splice_init(&sh_chan->ld_free, &list); | 295 | list_splice_init(&sh_chan->ld_free, &list); |
@@ -292,6 +308,8 @@ static struct dma_async_tx_descriptor *sh_dmae_prep_memcpy( | |||
292 | struct sh_dmae_chan *sh_chan; | 308 | struct sh_dmae_chan *sh_chan; |
293 | struct sh_desc *first = NULL, *prev = NULL, *new; | 309 | struct sh_desc *first = NULL, *prev = NULL, *new; |
294 | size_t copy_size; | 310 | size_t copy_size; |
311 | LIST_HEAD(tx_list); | ||
312 | int chunks = (len + SH_DMA_TCR_MAX) / (SH_DMA_TCR_MAX + 1); | ||
295 | 313 | ||
296 | if (!chan) | 314 | if (!chan) |
297 | return NULL; | 315 | return NULL; |
@@ -301,108 +319,189 @@ static struct dma_async_tx_descriptor *sh_dmae_prep_memcpy( | |||
301 | 319 | ||
302 | sh_chan = to_sh_chan(chan); | 320 | sh_chan = to_sh_chan(chan); |
303 | 321 | ||
322 | /* Have to lock the whole loop to protect against concurrent release */ | ||
323 | spin_lock_bh(&sh_chan->desc_lock); | ||
324 | |||
325 | /* | ||
326 | * Chaining: | ||
327 | * first descriptor is what user is dealing with in all API calls, its | ||
328 | * cookie is at first set to -EBUSY, at tx-submit to a positive | ||
329 | * number | ||
330 | * if more than one chunk is needed further chunks have cookie = -EINVAL | ||
331 | * the last chunk, if not equal to the first, has cookie = -ENOSPC | ||
332 | * all chunks are linked onto the tx_list head with their .node heads | ||
333 | * only during this function, then they are immediately spliced | ||
334 | * back onto the free list in form of a chain | ||
335 | */ | ||
304 | do { | 336 | do { |
305 | /* Allocate the link descriptor from DMA pool */ | 337 | /* Allocate the link descriptor from the free list */ |
306 | new = sh_dmae_get_desc(sh_chan); | 338 | new = sh_dmae_get_desc(sh_chan); |
307 | if (!new) { | 339 | if (!new) { |
308 | dev_err(sh_chan->dev, | 340 | dev_err(sh_chan->dev, |
309 | "No free memory for link descriptor\n"); | 341 | "No free memory for link descriptor\n"); |
310 | goto err_get_desc; | 342 | list_for_each_entry(new, &tx_list, node) |
343 | new->mark = DESC_IDLE; | ||
344 | list_splice(&tx_list, &sh_chan->ld_free); | ||
345 | spin_unlock_bh(&sh_chan->desc_lock); | ||
346 | return NULL; | ||
311 | } | 347 | } |
312 | 348 | ||
313 | copy_size = min(len, (size_t)SH_DMA_TCR_MAX); | 349 | copy_size = min(len, (size_t)SH_DMA_TCR_MAX + 1); |
314 | 350 | ||
315 | new->hw.sar = dma_src; | 351 | new->hw.sar = dma_src; |
316 | new->hw.dar = dma_dest; | 352 | new->hw.dar = dma_dest; |
317 | new->hw.tcr = copy_size; | 353 | new->hw.tcr = copy_size; |
318 | if (!first) | 354 | if (!first) { |
355 | /* First desc */ | ||
356 | new->async_tx.cookie = -EBUSY; | ||
319 | first = new; | 357 | first = new; |
358 | } else { | ||
359 | /* Other desc - invisible to the user */ | ||
360 | new->async_tx.cookie = -EINVAL; | ||
361 | } | ||
320 | 362 | ||
321 | new->mark = DESC_NCOMP; | 363 | dev_dbg(sh_chan->dev, |
322 | async_tx_ack(&new->async_tx); | 364 | "chaining %u of %u with %p, dst %x, cookie %d\n", |
365 | copy_size, len, &new->async_tx, dma_dest, | ||
366 | new->async_tx.cookie); | ||
367 | |||
368 | new->mark = DESC_PREPARED; | ||
369 | new->async_tx.flags = flags; | ||
370 | new->chunks = chunks--; | ||
323 | 371 | ||
324 | prev = new; | 372 | prev = new; |
325 | len -= copy_size; | 373 | len -= copy_size; |
326 | dma_src += copy_size; | 374 | dma_src += copy_size; |
327 | dma_dest += copy_size; | 375 | dma_dest += copy_size; |
328 | /* Insert the link descriptor to the LD ring */ | 376 | /* Insert the link descriptor to the LD ring */ |
329 | list_add_tail(&new->node, &first->tx_list); | 377 | list_add_tail(&new->node, &tx_list); |
330 | } while (len); | 378 | } while (len); |
331 | 379 | ||
332 | new->async_tx.flags = flags; /* client is in control of this ack */ | 380 | if (new != first) |
333 | new->async_tx.cookie = -EBUSY; /* Last desc */ | 381 | new->async_tx.cookie = -ENOSPC; |
334 | 382 | ||
335 | return &first->async_tx; | 383 | /* Put them back on the free list, so, they don't get lost */ |
384 | list_splice_tail(&tx_list, &sh_chan->ld_free); | ||
336 | 385 | ||
337 | err_get_desc: | 386 | spin_unlock_bh(&sh_chan->desc_lock); |
338 | sh_dmae_put_desc(sh_chan, first); | ||
339 | return NULL; | ||
340 | 387 | ||
388 | return &first->async_tx; | ||
341 | } | 389 | } |
342 | 390 | ||
343 | /* | 391 | static dma_async_tx_callback __ld_cleanup(struct sh_dmae_chan *sh_chan, bool all) |
344 | * sh_chan_ld_cleanup - Clean up link descriptors | ||
345 | * | ||
346 | * This function clean up the ld_queue of DMA channel. | ||
347 | */ | ||
348 | static void sh_dmae_chan_ld_cleanup(struct sh_dmae_chan *sh_chan) | ||
349 | { | 392 | { |
350 | struct sh_desc *desc, *_desc; | 393 | struct sh_desc *desc, *_desc; |
394 | /* Is the "exposed" head of a chain acked? */ | ||
395 | bool head_acked = false; | ||
396 | dma_cookie_t cookie = 0; | ||
397 | dma_async_tx_callback callback = NULL; | ||
398 | void *param = NULL; | ||
351 | 399 | ||
352 | spin_lock_bh(&sh_chan->desc_lock); | 400 | spin_lock_bh(&sh_chan->desc_lock); |
353 | list_for_each_entry_safe(desc, _desc, &sh_chan->ld_queue, node) { | 401 | list_for_each_entry_safe(desc, _desc, &sh_chan->ld_queue, node) { |
354 | dma_async_tx_callback callback; | 402 | struct dma_async_tx_descriptor *tx = &desc->async_tx; |
355 | void *callback_param; | 403 | |
356 | 404 | BUG_ON(tx->cookie > 0 && tx->cookie != desc->cookie); | |
357 | /* non send data */ | 405 | BUG_ON(desc->mark != DESC_SUBMITTED && |
358 | if (desc->mark == DESC_NCOMP) | 406 | desc->mark != DESC_COMPLETED && |
407 | desc->mark != DESC_WAITING); | ||
408 | |||
409 | /* | ||
410 | * queue is ordered, and we use this loop to (1) clean up all | ||
411 | * completed descriptors, and to (2) update descriptor flags of | ||
412 | * any chunks in a (partially) completed chain | ||
413 | */ | ||
414 | if (!all && desc->mark == DESC_SUBMITTED && | ||
415 | desc->cookie != cookie) | ||
359 | break; | 416 | break; |
360 | 417 | ||
361 | /* send data sesc */ | 418 | if (tx->cookie > 0) |
362 | callback = desc->async_tx.callback; | 419 | cookie = tx->cookie; |
363 | callback_param = desc->async_tx.callback_param; | ||
364 | 420 | ||
365 | /* Remove from ld_queue list */ | 421 | if (desc->mark == DESC_COMPLETED && desc->chunks == 1) { |
366 | list_splice_init(&desc->tx_list, &sh_chan->ld_free); | 422 | BUG_ON(sh_chan->completed_cookie != desc->cookie - 1); |
423 | sh_chan->completed_cookie = desc->cookie; | ||
424 | } | ||
367 | 425 | ||
368 | dev_dbg(sh_chan->dev, "link descriptor %p will be recycle.\n", | 426 | /* Call callback on the last chunk */ |
369 | desc); | 427 | if (desc->mark == DESC_COMPLETED && tx->callback) { |
428 | desc->mark = DESC_WAITING; | ||
429 | callback = tx->callback; | ||
430 | param = tx->callback_param; | ||
431 | dev_dbg(sh_chan->dev, "descriptor #%d@%p on %d callback\n", | ||
432 | tx->cookie, tx, sh_chan->id); | ||
433 | BUG_ON(desc->chunks != 1); | ||
434 | break; | ||
435 | } | ||
370 | 436 | ||
371 | list_move(&desc->node, &sh_chan->ld_free); | 437 | if (tx->cookie > 0 || tx->cookie == -EBUSY) { |
372 | /* Run the link descriptor callback function */ | 438 | if (desc->mark == DESC_COMPLETED) { |
373 | if (callback) { | 439 | BUG_ON(tx->cookie < 0); |
374 | spin_unlock_bh(&sh_chan->desc_lock); | 440 | desc->mark = DESC_WAITING; |
375 | dev_dbg(sh_chan->dev, "link descriptor %p callback\n", | 441 | } |
376 | desc); | 442 | head_acked = async_tx_test_ack(tx); |
377 | callback(callback_param); | 443 | } else { |
378 | spin_lock_bh(&sh_chan->desc_lock); | 444 | switch (desc->mark) { |
445 | case DESC_COMPLETED: | ||
446 | desc->mark = DESC_WAITING; | ||
447 | /* Fall through */ | ||
448 | case DESC_WAITING: | ||
449 | if (head_acked) | ||
450 | async_tx_ack(&desc->async_tx); | ||
451 | } | ||
452 | } | ||
453 | |||
454 | dev_dbg(sh_chan->dev, "descriptor %p #%d completed.\n", | ||
455 | tx, tx->cookie); | ||
456 | |||
457 | if (((desc->mark == DESC_COMPLETED || | ||
458 | desc->mark == DESC_WAITING) && | ||
459 | async_tx_test_ack(&desc->async_tx)) || all) { | ||
460 | /* Remove from ld_queue list */ | ||
461 | desc->mark = DESC_IDLE; | ||
462 | list_move(&desc->node, &sh_chan->ld_free); | ||
379 | } | 463 | } |
380 | } | 464 | } |
381 | spin_unlock_bh(&sh_chan->desc_lock); | 465 | spin_unlock_bh(&sh_chan->desc_lock); |
466 | |||
467 | if (callback) | ||
468 | callback(param); | ||
469 | |||
470 | return callback; | ||
471 | } | ||
472 | |||
473 | /* | ||
474 | * sh_chan_ld_cleanup - Clean up link descriptors | ||
475 | * | ||
476 | * This function cleans up the ld_queue of DMA channel. | ||
477 | */ | ||
478 | static void sh_dmae_chan_ld_cleanup(struct sh_dmae_chan *sh_chan, bool all) | ||
479 | { | ||
480 | while (__ld_cleanup(sh_chan, all)) | ||
481 | ; | ||
382 | } | 482 | } |
383 | 483 | ||
384 | static void sh_chan_xfer_ld_queue(struct sh_dmae_chan *sh_chan) | 484 | static void sh_chan_xfer_ld_queue(struct sh_dmae_chan *sh_chan) |
385 | { | 485 | { |
386 | struct list_head *ld_node; | 486 | struct sh_desc *sd; |
387 | struct sh_dmae_regs hw; | ||
388 | 487 | ||
488 | spin_lock_bh(&sh_chan->desc_lock); | ||
389 | /* DMA work check */ | 489 | /* DMA work check */ |
390 | if (dmae_is_busy(sh_chan)) | 490 | if (dmae_is_busy(sh_chan)) { |
491 | spin_unlock_bh(&sh_chan->desc_lock); | ||
391 | return; | 492 | return; |
493 | } | ||
392 | 494 | ||
393 | /* Find the first un-transfer desciptor */ | 495 | /* Find the first un-transfer desciptor */ |
394 | for (ld_node = sh_chan->ld_queue.next; | 496 | list_for_each_entry(sd, &sh_chan->ld_queue, node) |
395 | (ld_node != &sh_chan->ld_queue) | 497 | if (sd->mark == DESC_SUBMITTED) { |
396 | && (to_sh_desc(ld_node)->mark == DESC_COMP); | 498 | /* Get the ld start address from ld_queue */ |
397 | ld_node = ld_node->next) | 499 | dmae_set_reg(sh_chan, &sd->hw); |
398 | cpu_relax(); | 500 | dmae_start(sh_chan); |
399 | 501 | break; | |
400 | if (ld_node != &sh_chan->ld_queue) { | 502 | } |
401 | /* Get the ld start address from ld_queue */ | 503 | |
402 | hw = to_sh_desc(ld_node)->hw; | 504 | spin_unlock_bh(&sh_chan->desc_lock); |
403 | dmae_set_reg(sh_chan, hw); | ||
404 | dmae_start(sh_chan); | ||
405 | } | ||
406 | } | 505 | } |
407 | 506 | ||
408 | static void sh_dmae_memcpy_issue_pending(struct dma_chan *chan) | 507 | static void sh_dmae_memcpy_issue_pending(struct dma_chan *chan) |
@@ -420,12 +519,11 @@ static enum dma_status sh_dmae_is_complete(struct dma_chan *chan, | |||
420 | dma_cookie_t last_used; | 519 | dma_cookie_t last_used; |
421 | dma_cookie_t last_complete; | 520 | dma_cookie_t last_complete; |
422 | 521 | ||
423 | sh_dmae_chan_ld_cleanup(sh_chan); | 522 | sh_dmae_chan_ld_cleanup(sh_chan, false); |
424 | 523 | ||
425 | last_used = chan->cookie; | 524 | last_used = chan->cookie; |
426 | last_complete = sh_chan->completed_cookie; | 525 | last_complete = sh_chan->completed_cookie; |
427 | if (last_complete == -EBUSY) | 526 | BUG_ON(last_complete < 0); |
428 | last_complete = last_used; | ||
429 | 527 | ||
430 | if (done) | 528 | if (done) |
431 | *done = last_complete; | 529 | *done = last_complete; |
@@ -480,11 +578,13 @@ static irqreturn_t sh_dmae_err(int irq, void *data) | |||
480 | err = sh_dmae_rst(0); | 578 | err = sh_dmae_rst(0); |
481 | if (err) | 579 | if (err) |
482 | return err; | 580 | return err; |
581 | #ifdef SH_DMAC_BASE1 | ||
483 | if (shdev->pdata.mode & SHDMA_DMAOR1) { | 582 | if (shdev->pdata.mode & SHDMA_DMAOR1) { |
484 | err = sh_dmae_rst(1); | 583 | err = sh_dmae_rst(1); |
485 | if (err) | 584 | if (err) |
486 | return err; | 585 | return err; |
487 | } | 586 | } |
587 | #endif | ||
488 | disable_irq(irq); | 588 | disable_irq(irq); |
489 | return IRQ_HANDLED; | 589 | return IRQ_HANDLED; |
490 | } | 590 | } |
@@ -494,35 +594,25 @@ static irqreturn_t sh_dmae_err(int irq, void *data) | |||
494 | static void dmae_do_tasklet(unsigned long data) | 594 | static void dmae_do_tasklet(unsigned long data) |
495 | { | 595 | { |
496 | struct sh_dmae_chan *sh_chan = (struct sh_dmae_chan *)data; | 596 | struct sh_dmae_chan *sh_chan = (struct sh_dmae_chan *)data; |
497 | struct sh_desc *desc, *_desc, *cur_desc = NULL; | 597 | struct sh_desc *desc; |
498 | u32 sar_buf = sh_dmae_readl(sh_chan, SAR); | 598 | u32 sar_buf = sh_dmae_readl(sh_chan, SAR); |
499 | 599 | ||
500 | list_for_each_entry_safe(desc, _desc, | 600 | spin_lock(&sh_chan->desc_lock); |
501 | &sh_chan->ld_queue, node) { | 601 | list_for_each_entry(desc, &sh_chan->ld_queue, node) { |
502 | if ((desc->hw.sar + desc->hw.tcr) == sar_buf) { | 602 | if ((desc->hw.sar + desc->hw.tcr) == sar_buf && |
503 | cur_desc = desc; | 603 | desc->mark == DESC_SUBMITTED) { |
604 | dev_dbg(sh_chan->dev, "done #%d@%p dst %u\n", | ||
605 | desc->async_tx.cookie, &desc->async_tx, | ||
606 | desc->hw.dar); | ||
607 | desc->mark = DESC_COMPLETED; | ||
504 | break; | 608 | break; |
505 | } | 609 | } |
506 | } | 610 | } |
611 | spin_unlock(&sh_chan->desc_lock); | ||
507 | 612 | ||
508 | if (cur_desc) { | ||
509 | switch (cur_desc->async_tx.cookie) { | ||
510 | case 0: /* other desc data */ | ||
511 | break; | ||
512 | case -EBUSY: /* last desc */ | ||
513 | sh_chan->completed_cookie = | ||
514 | cur_desc->async_tx.cookie; | ||
515 | break; | ||
516 | default: /* first desc ( 0 < )*/ | ||
517 | sh_chan->completed_cookie = | ||
518 | cur_desc->async_tx.cookie - 1; | ||
519 | break; | ||
520 | } | ||
521 | cur_desc->mark = DESC_COMP; | ||
522 | } | ||
523 | /* Next desc */ | 613 | /* Next desc */ |
524 | sh_chan_xfer_ld_queue(sh_chan); | 614 | sh_chan_xfer_ld_queue(sh_chan); |
525 | sh_dmae_chan_ld_cleanup(sh_chan); | 615 | sh_dmae_chan_ld_cleanup(sh_chan, false); |
526 | } | 616 | } |
527 | 617 | ||
528 | static unsigned int get_dmae_irq(unsigned int id) | 618 | static unsigned int get_dmae_irq(unsigned int id) |
diff --git a/drivers/dma/shdma.h b/drivers/dma/shdma.h index 60b81e529b42..108f1cffb6f5 100644 --- a/drivers/dma/shdma.h +++ b/drivers/dma/shdma.h | |||
@@ -13,9 +13,9 @@ | |||
13 | #ifndef __DMA_SHDMA_H | 13 | #ifndef __DMA_SHDMA_H |
14 | #define __DMA_SHDMA_H | 14 | #define __DMA_SHDMA_H |
15 | 15 | ||
16 | #include <linux/device.h> | ||
17 | #include <linux/dmapool.h> | ||
18 | #include <linux/dmaengine.h> | 16 | #include <linux/dmaengine.h> |
17 | #include <linux/interrupt.h> | ||
18 | #include <linux/list.h> | ||
19 | 19 | ||
20 | #define SH_DMA_TCR_MAX 0x00FFFFFF /* 16MB */ | 20 | #define SH_DMA_TCR_MAX 0x00FFFFFF /* 16MB */ |
21 | 21 | ||
@@ -26,13 +26,16 @@ struct sh_dmae_regs { | |||
26 | }; | 26 | }; |
27 | 27 | ||
28 | struct sh_desc { | 28 | struct sh_desc { |
29 | struct list_head tx_list; | ||
30 | struct sh_dmae_regs hw; | 29 | struct sh_dmae_regs hw; |
31 | struct list_head node; | 30 | struct list_head node; |
32 | struct dma_async_tx_descriptor async_tx; | 31 | struct dma_async_tx_descriptor async_tx; |
32 | dma_cookie_t cookie; | ||
33 | int chunks; | ||
33 | int mark; | 34 | int mark; |
34 | }; | 35 | }; |
35 | 36 | ||
37 | struct device; | ||
38 | |||
36 | struct sh_dmae_chan { | 39 | struct sh_dmae_chan { |
37 | dma_cookie_t completed_cookie; /* The maximum cookie completed */ | 40 | dma_cookie_t completed_cookie; /* The maximum cookie completed */ |
38 | spinlock_t desc_lock; /* Descriptor operation lock */ | 41 | spinlock_t desc_lock; /* Descriptor operation lock */ |
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index df5b68433f34..c5facd951dda 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c | |||
@@ -1700,11 +1700,14 @@ static void f10_map_sysaddr_to_csrow(struct mem_ctl_info *mci, | |||
1700 | */ | 1700 | */ |
1701 | static void amd64_debug_display_dimm_sizes(int ctrl, struct amd64_pvt *pvt) | 1701 | static void amd64_debug_display_dimm_sizes(int ctrl, struct amd64_pvt *pvt) |
1702 | { | 1702 | { |
1703 | int dimm, size0, size1; | 1703 | int dimm, size0, size1, factor = 0; |
1704 | u32 dbam; | 1704 | u32 dbam; |
1705 | u32 *dcsb; | 1705 | u32 *dcsb; |
1706 | 1706 | ||
1707 | if (boot_cpu_data.x86 == 0xf) { | 1707 | if (boot_cpu_data.x86 == 0xf) { |
1708 | if (pvt->dclr0 & F10_WIDTH_128) | ||
1709 | factor = 1; | ||
1710 | |||
1708 | /* K8 families < revF not supported yet */ | 1711 | /* K8 families < revF not supported yet */ |
1709 | if (pvt->ext_model < K8_REV_F) | 1712 | if (pvt->ext_model < K8_REV_F) |
1710 | return; | 1713 | return; |
@@ -1732,7 +1735,8 @@ static void amd64_debug_display_dimm_sizes(int ctrl, struct amd64_pvt *pvt) | |||
1732 | size1 = pvt->ops->dbam_to_cs(pvt, DBAM_DIMM(dimm, dbam)); | 1735 | size1 = pvt->ops->dbam_to_cs(pvt, DBAM_DIMM(dimm, dbam)); |
1733 | 1736 | ||
1734 | edac_printk(KERN_DEBUG, EDAC_MC, " %d: %5dMB %d: %5dMB\n", | 1737 | edac_printk(KERN_DEBUG, EDAC_MC, " %d: %5dMB %d: %5dMB\n", |
1735 | dimm * 2, size0, dimm * 2 + 1, size1); | 1738 | dimm * 2, size0 << factor, |
1739 | dimm * 2 + 1, size1 << factor); | ||
1736 | } | 1740 | } |
1737 | } | 1741 | } |
1738 | 1742 | ||
@@ -2345,7 +2349,7 @@ static void amd64_read_mc_registers(struct amd64_pvt *pvt) | |||
2345 | amd64_read_pci_cfg(pvt->dram_f2_ctl, F10_DCLR_0, &pvt->dclr0); | 2349 | amd64_read_pci_cfg(pvt->dram_f2_ctl, F10_DCLR_0, &pvt->dclr0); |
2346 | amd64_read_pci_cfg(pvt->dram_f2_ctl, F10_DCHR_0, &pvt->dchr0); | 2350 | amd64_read_pci_cfg(pvt->dram_f2_ctl, F10_DCHR_0, &pvt->dchr0); |
2347 | 2351 | ||
2348 | if (!dct_ganging_enabled(pvt)) { | 2352 | if (!dct_ganging_enabled(pvt) && boot_cpu_data.x86 >= 0x10) { |
2349 | amd64_read_pci_cfg(pvt->dram_f2_ctl, F10_DCLR_1, &pvt->dclr1); | 2353 | amd64_read_pci_cfg(pvt->dram_f2_ctl, F10_DCLR_1, &pvt->dclr1); |
2350 | amd64_read_pci_cfg(pvt->dram_f2_ctl, F10_DCHR_1, &pvt->dchr1); | 2354 | amd64_read_pci_cfg(pvt->dram_f2_ctl, F10_DCHR_1, &pvt->dchr1); |
2351 | } | 2355 | } |
@@ -2686,9 +2690,8 @@ static int amd64_check_ecc_enabled(struct amd64_pvt *pvt) | |||
2686 | amd64_printk(KERN_WARNING, "%s", ecc_warning); | 2690 | amd64_printk(KERN_WARNING, "%s", ecc_warning); |
2687 | return -ENODEV; | 2691 | return -ENODEV; |
2688 | } | 2692 | } |
2689 | } else | ||
2690 | /* CLEAR the override, since BIOS controlled it */ | ||
2691 | ecc_enable_override = 0; | 2693 | ecc_enable_override = 0; |
2694 | } | ||
2692 | 2695 | ||
2693 | return 0; | 2696 | return 0; |
2694 | } | 2697 | } |
@@ -2925,16 +2928,15 @@ static void __devexit amd64_remove_one_instance(struct pci_dev *pdev) | |||
2925 | 2928 | ||
2926 | amd64_free_mc_sibling_devices(pvt); | 2929 | amd64_free_mc_sibling_devices(pvt); |
2927 | 2930 | ||
2928 | kfree(pvt); | ||
2929 | mci->pvt_info = NULL; | ||
2930 | |||
2931 | mci_lookup[pvt->mc_node_id] = NULL; | ||
2932 | |||
2933 | /* unregister from EDAC MCE */ | 2931 | /* unregister from EDAC MCE */ |
2934 | amd_report_gart_errors(false); | 2932 | amd_report_gart_errors(false); |
2935 | amd_unregister_ecc_decoder(amd64_decode_bus_error); | 2933 | amd_unregister_ecc_decoder(amd64_decode_bus_error); |
2936 | 2934 | ||
2937 | /* Free the EDAC CORE resources */ | 2935 | /* Free the EDAC CORE resources */ |
2936 | mci->pvt_info = NULL; | ||
2937 | mci_lookup[pvt->mc_node_id] = NULL; | ||
2938 | |||
2939 | kfree(pvt); | ||
2938 | edac_mc_free(mci); | 2940 | edac_mc_free(mci); |
2939 | } | 2941 | } |
2940 | 2942 | ||
@@ -3011,25 +3013,29 @@ static void amd64_setup_pci_device(void) | |||
3011 | static int __init amd64_edac_init(void) | 3013 | static int __init amd64_edac_init(void) |
3012 | { | 3014 | { |
3013 | int nb, err = -ENODEV; | 3015 | int nb, err = -ENODEV; |
3016 | bool load_ok = false; | ||
3014 | 3017 | ||
3015 | edac_printk(KERN_INFO, EDAC_MOD_STR, EDAC_AMD64_VERSION "\n"); | 3018 | edac_printk(KERN_INFO, EDAC_MOD_STR, EDAC_AMD64_VERSION "\n"); |
3016 | 3019 | ||
3017 | opstate_init(); | 3020 | opstate_init(); |
3018 | 3021 | ||
3019 | if (cache_k8_northbridges() < 0) | 3022 | if (cache_k8_northbridges() < 0) |
3020 | return err; | 3023 | goto err_ret; |
3021 | 3024 | ||
3022 | msrs = msrs_alloc(); | 3025 | msrs = msrs_alloc(); |
3026 | if (!msrs) | ||
3027 | goto err_ret; | ||
3023 | 3028 | ||
3024 | err = pci_register_driver(&amd64_pci_driver); | 3029 | err = pci_register_driver(&amd64_pci_driver); |
3025 | if (err) | 3030 | if (err) |
3026 | return err; | 3031 | goto err_pci; |
3027 | 3032 | ||
3028 | /* | 3033 | /* |
3029 | * At this point, the array 'pvt_lookup[]' contains pointers to alloc'd | 3034 | * At this point, the array 'pvt_lookup[]' contains pointers to alloc'd |
3030 | * amd64_pvt structs. These will be used in the 2nd stage init function | 3035 | * amd64_pvt structs. These will be used in the 2nd stage init function |
3031 | * to finish initialization of the MC instances. | 3036 | * to finish initialization of the MC instances. |
3032 | */ | 3037 | */ |
3038 | err = -ENODEV; | ||
3033 | for (nb = 0; nb < num_k8_northbridges; nb++) { | 3039 | for (nb = 0; nb < num_k8_northbridges; nb++) { |
3034 | if (!pvt_lookup[nb]) | 3040 | if (!pvt_lookup[nb]) |
3035 | continue; | 3041 | continue; |
@@ -3037,16 +3043,21 @@ static int __init amd64_edac_init(void) | |||
3037 | err = amd64_init_2nd_stage(pvt_lookup[nb]); | 3043 | err = amd64_init_2nd_stage(pvt_lookup[nb]); |
3038 | if (err) | 3044 | if (err) |
3039 | goto err_2nd_stage; | 3045 | goto err_2nd_stage; |
3040 | } | ||
3041 | 3046 | ||
3042 | amd64_setup_pci_device(); | 3047 | load_ok = true; |
3048 | } | ||
3043 | 3049 | ||
3044 | return 0; | 3050 | if (load_ok) { |
3051 | amd64_setup_pci_device(); | ||
3052 | return 0; | ||
3053 | } | ||
3045 | 3054 | ||
3046 | err_2nd_stage: | 3055 | err_2nd_stage: |
3047 | debugf0("2nd stage failed\n"); | ||
3048 | pci_unregister_driver(&amd64_pci_driver); | 3056 | pci_unregister_driver(&amd64_pci_driver); |
3049 | 3057 | err_pci: | |
3058 | msrs_free(msrs); | ||
3059 | msrs = NULL; | ||
3060 | err_ret: | ||
3050 | return err; | 3061 | return err; |
3051 | } | 3062 | } |
3052 | 3063 | ||
diff --git a/drivers/edac/edac_pci_sysfs.c b/drivers/edac/edac_pci_sysfs.c index 422728cfe994..fb60a877d768 100644 --- a/drivers/edac/edac_pci_sysfs.c +++ b/drivers/edac/edac_pci_sysfs.c | |||
@@ -534,8 +534,6 @@ static void edac_pci_dev_parity_clear(struct pci_dev *dev) | |||
534 | { | 534 | { |
535 | u8 header_type; | 535 | u8 header_type; |
536 | 536 | ||
537 | debugf0("%s()\n", __func__); | ||
538 | |||
539 | get_pci_parity_status(dev, 0); | 537 | get_pci_parity_status(dev, 0); |
540 | 538 | ||
541 | /* read the device TYPE, looking for bridges */ | 539 | /* read the device TYPE, looking for bridges */ |
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index ff2f1042cb44..766c46875a20 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c | |||
@@ -434,11 +434,11 @@ static int drm_version(struct drm_device *dev, void *data, | |||
434 | * Looks up the ioctl function in the ::ioctls table, checking for root | 434 | * Looks up the ioctl function in the ::ioctls table, checking for root |
435 | * previleges if so required, and dispatches to the respective function. | 435 | * previleges if so required, and dispatches to the respective function. |
436 | */ | 436 | */ |
437 | int drm_ioctl(struct inode *inode, struct file *filp, | 437 | long drm_ioctl(struct file *filp, |
438 | unsigned int cmd, unsigned long arg) | 438 | unsigned int cmd, unsigned long arg) |
439 | { | 439 | { |
440 | struct drm_file *file_priv = filp->private_data; | 440 | struct drm_file *file_priv = filp->private_data; |
441 | struct drm_device *dev = file_priv->minor->dev; | 441 | struct drm_device *dev; |
442 | struct drm_ioctl_desc *ioctl; | 442 | struct drm_ioctl_desc *ioctl; |
443 | drm_ioctl_t *func; | 443 | drm_ioctl_t *func; |
444 | unsigned int nr = DRM_IOCTL_NR(cmd); | 444 | unsigned int nr = DRM_IOCTL_NR(cmd); |
@@ -446,6 +446,7 @@ int drm_ioctl(struct inode *inode, struct file *filp, | |||
446 | char stack_kdata[128]; | 446 | char stack_kdata[128]; |
447 | char *kdata = NULL; | 447 | char *kdata = NULL; |
448 | 448 | ||
449 | dev = file_priv->minor->dev; | ||
449 | atomic_inc(&dev->ioctl_count); | 450 | atomic_inc(&dev->ioctl_count); |
450 | atomic_inc(&dev->counts[_DRM_STAT_IOCTLS]); | 451 | atomic_inc(&dev->counts[_DRM_STAT_IOCTLS]); |
451 | ++file_priv->ioctl_count; | 452 | ++file_priv->ioctl_count; |
@@ -501,7 +502,13 @@ int drm_ioctl(struct inode *inode, struct file *filp, | |||
501 | goto err_i1; | 502 | goto err_i1; |
502 | } | 503 | } |
503 | } | 504 | } |
504 | retcode = func(dev, kdata, file_priv); | 505 | if (ioctl->flags & DRM_UNLOCKED) |
506 | retcode = func(dev, kdata, file_priv); | ||
507 | else { | ||
508 | lock_kernel(); | ||
509 | retcode = func(dev, kdata, file_priv); | ||
510 | unlock_kernel(); | ||
511 | } | ||
505 | 512 | ||
506 | if (cmd & IOC_OUT) { | 513 | if (cmd & IOC_OUT) { |
507 | if (copy_to_user((void __user *)arg, kdata, | 514 | if (copy_to_user((void __user *)arg, kdata, |
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index c39b26f1abed..5c9f79877cbf 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c | |||
@@ -913,7 +913,7 @@ static int drm_cvt_modes(struct drm_connector *connector, | |||
913 | const int rates[] = { 60, 85, 75, 60, 50 }; | 913 | const int rates[] = { 60, 85, 75, 60, 50 }; |
914 | 914 | ||
915 | for (i = 0; i < 4; i++) { | 915 | for (i = 0; i < 4; i++) { |
916 | int width, height; | 916 | int uninitialized_var(width), height; |
917 | cvt = &(timing->data.other_data.data.cvt[i]); | 917 | cvt = &(timing->data.other_data.data.cvt[i]); |
918 | 918 | ||
919 | height = (cvt->code[0] + ((cvt->code[1] & 0xf0) << 8) + 1) * 2; | 919 | height = (cvt->code[0] + ((cvt->code[1] & 0xf0) << 8) + 1) * 2; |
diff --git a/drivers/gpu/drm/drm_ioc32.c b/drivers/gpu/drm/drm_ioc32.c index 282d9fdf9f4e..d61d185cf040 100644 --- a/drivers/gpu/drm/drm_ioc32.c +++ b/drivers/gpu/drm/drm_ioc32.c | |||
@@ -104,7 +104,7 @@ static int compat_drm_version(struct file *file, unsigned int cmd, | |||
104 | &version->desc)) | 104 | &version->desc)) |
105 | return -EFAULT; | 105 | return -EFAULT; |
106 | 106 | ||
107 | err = drm_ioctl(file->f_path.dentry->d_inode, file, | 107 | err = drm_ioctl(file, |
108 | DRM_IOCTL_VERSION, (unsigned long)version); | 108 | DRM_IOCTL_VERSION, (unsigned long)version); |
109 | if (err) | 109 | if (err) |
110 | return err; | 110 | return err; |
@@ -145,8 +145,7 @@ static int compat_drm_getunique(struct file *file, unsigned int cmd, | |||
145 | &u->unique)) | 145 | &u->unique)) |
146 | return -EFAULT; | 146 | return -EFAULT; |
147 | 147 | ||
148 | err = drm_ioctl(file->f_path.dentry->d_inode, file, | 148 | err = drm_ioctl(file, DRM_IOCTL_GET_UNIQUE, (unsigned long)u); |
149 | DRM_IOCTL_GET_UNIQUE, (unsigned long)u); | ||
150 | if (err) | 149 | if (err) |
151 | return err; | 150 | return err; |
152 | 151 | ||
@@ -174,8 +173,7 @@ static int compat_drm_setunique(struct file *file, unsigned int cmd, | |||
174 | &u->unique)) | 173 | &u->unique)) |
175 | return -EFAULT; | 174 | return -EFAULT; |
176 | 175 | ||
177 | return drm_ioctl(file->f_path.dentry->d_inode, file, | 176 | return drm_ioctl(file, DRM_IOCTL_SET_UNIQUE, (unsigned long)u); |
178 | DRM_IOCTL_SET_UNIQUE, (unsigned long)u); | ||
179 | } | 177 | } |
180 | 178 | ||
181 | typedef struct drm_map32 { | 179 | typedef struct drm_map32 { |
@@ -205,8 +203,7 @@ static int compat_drm_getmap(struct file *file, unsigned int cmd, | |||
205 | if (__put_user(idx, &map->offset)) | 203 | if (__put_user(idx, &map->offset)) |
206 | return -EFAULT; | 204 | return -EFAULT; |
207 | 205 | ||
208 | err = drm_ioctl(file->f_path.dentry->d_inode, file, | 206 | err = drm_ioctl(file, DRM_IOCTL_GET_MAP, (unsigned long)map); |
209 | DRM_IOCTL_GET_MAP, (unsigned long)map); | ||
210 | if (err) | 207 | if (err) |
211 | return err; | 208 | return err; |
212 | 209 | ||
@@ -246,8 +243,7 @@ static int compat_drm_addmap(struct file *file, unsigned int cmd, | |||
246 | || __put_user(m32.flags, &map->flags)) | 243 | || __put_user(m32.flags, &map->flags)) |
247 | return -EFAULT; | 244 | return -EFAULT; |
248 | 245 | ||
249 | err = drm_ioctl(file->f_path.dentry->d_inode, file, | 246 | err = drm_ioctl(file, DRM_IOCTL_ADD_MAP, (unsigned long)map); |
250 | DRM_IOCTL_ADD_MAP, (unsigned long)map); | ||
251 | if (err) | 247 | if (err) |
252 | return err; | 248 | return err; |
253 | 249 | ||
@@ -284,8 +280,7 @@ static int compat_drm_rmmap(struct file *file, unsigned int cmd, | |||
284 | if (__put_user((void *)(unsigned long)handle, &map->handle)) | 280 | if (__put_user((void *)(unsigned long)handle, &map->handle)) |
285 | return -EFAULT; | 281 | return -EFAULT; |
286 | 282 | ||
287 | return drm_ioctl(file->f_path.dentry->d_inode, file, | 283 | return drm_ioctl(file, DRM_IOCTL_RM_MAP, (unsigned long)map); |
288 | DRM_IOCTL_RM_MAP, (unsigned long)map); | ||
289 | } | 284 | } |
290 | 285 | ||
291 | typedef struct drm_client32 { | 286 | typedef struct drm_client32 { |
@@ -314,8 +309,7 @@ static int compat_drm_getclient(struct file *file, unsigned int cmd, | |||
314 | if (__put_user(idx, &client->idx)) | 309 | if (__put_user(idx, &client->idx)) |
315 | return -EFAULT; | 310 | return -EFAULT; |
316 | 311 | ||
317 | err = drm_ioctl(file->f_path.dentry->d_inode, file, | 312 | err = drm_ioctl(file, DRM_IOCTL_GET_CLIENT, (unsigned long)client); |
318 | DRM_IOCTL_GET_CLIENT, (unsigned long)client); | ||
319 | if (err) | 313 | if (err) |
320 | return err; | 314 | return err; |
321 | 315 | ||
@@ -351,8 +345,7 @@ static int compat_drm_getstats(struct file *file, unsigned int cmd, | |||
351 | if (!access_ok(VERIFY_WRITE, stats, sizeof(*stats))) | 345 | if (!access_ok(VERIFY_WRITE, stats, sizeof(*stats))) |
352 | return -EFAULT; | 346 | return -EFAULT; |
353 | 347 | ||
354 | err = drm_ioctl(file->f_path.dentry->d_inode, file, | 348 | err = drm_ioctl(file, DRM_IOCTL_GET_STATS, (unsigned long)stats); |
355 | DRM_IOCTL_GET_STATS, (unsigned long)stats); | ||
356 | if (err) | 349 | if (err) |
357 | return err; | 350 | return err; |
358 | 351 | ||
@@ -395,8 +388,7 @@ static int compat_drm_addbufs(struct file *file, unsigned int cmd, | |||
395 | || __put_user(agp_start, &buf->agp_start)) | 388 | || __put_user(agp_start, &buf->agp_start)) |
396 | return -EFAULT; | 389 | return -EFAULT; |
397 | 390 | ||
398 | err = drm_ioctl(file->f_path.dentry->d_inode, file, | 391 | err = drm_ioctl(file, DRM_IOCTL_ADD_BUFS, (unsigned long)buf); |
399 | DRM_IOCTL_ADD_BUFS, (unsigned long)buf); | ||
400 | if (err) | 392 | if (err) |
401 | return err; | 393 | return err; |
402 | 394 | ||
@@ -427,8 +419,7 @@ static int compat_drm_markbufs(struct file *file, unsigned int cmd, | |||
427 | || __put_user(b32.high_mark, &buf->high_mark)) | 419 | || __put_user(b32.high_mark, &buf->high_mark)) |
428 | return -EFAULT; | 420 | return -EFAULT; |
429 | 421 | ||
430 | return drm_ioctl(file->f_path.dentry->d_inode, file, | 422 | return drm_ioctl(file, DRM_IOCTL_MARK_BUFS, (unsigned long)buf); |
431 | DRM_IOCTL_MARK_BUFS, (unsigned long)buf); | ||
432 | } | 423 | } |
433 | 424 | ||
434 | typedef struct drm_buf_info32 { | 425 | typedef struct drm_buf_info32 { |
@@ -469,8 +460,7 @@ static int compat_drm_infobufs(struct file *file, unsigned int cmd, | |||
469 | || __put_user(list, &request->list)) | 460 | || __put_user(list, &request->list)) |
470 | return -EFAULT; | 461 | return -EFAULT; |
471 | 462 | ||
472 | err = drm_ioctl(file->f_path.dentry->d_inode, file, | 463 | err = drm_ioctl(file, DRM_IOCTL_INFO_BUFS, (unsigned long)request); |
473 | DRM_IOCTL_INFO_BUFS, (unsigned long)request); | ||
474 | if (err) | 464 | if (err) |
475 | return err; | 465 | return err; |
476 | 466 | ||
@@ -531,8 +521,7 @@ static int compat_drm_mapbufs(struct file *file, unsigned int cmd, | |||
531 | || __put_user(list, &request->list)) | 521 | || __put_user(list, &request->list)) |
532 | return -EFAULT; | 522 | return -EFAULT; |
533 | 523 | ||
534 | err = drm_ioctl(file->f_path.dentry->d_inode, file, | 524 | err = drm_ioctl(file, DRM_IOCTL_MAP_BUFS, (unsigned long)request); |
535 | DRM_IOCTL_MAP_BUFS, (unsigned long)request); | ||
536 | if (err) | 525 | if (err) |
537 | return err; | 526 | return err; |
538 | 527 | ||
@@ -578,8 +567,7 @@ static int compat_drm_freebufs(struct file *file, unsigned int cmd, | |||
578 | &request->list)) | 567 | &request->list)) |
579 | return -EFAULT; | 568 | return -EFAULT; |
580 | 569 | ||
581 | return drm_ioctl(file->f_path.dentry->d_inode, file, | 570 | return drm_ioctl(file, DRM_IOCTL_FREE_BUFS, (unsigned long)request); |
582 | DRM_IOCTL_FREE_BUFS, (unsigned long)request); | ||
583 | } | 571 | } |
584 | 572 | ||
585 | typedef struct drm_ctx_priv_map32 { | 573 | typedef struct drm_ctx_priv_map32 { |
@@ -605,8 +593,7 @@ static int compat_drm_setsareactx(struct file *file, unsigned int cmd, | |||
605 | &request->handle)) | 593 | &request->handle)) |
606 | return -EFAULT; | 594 | return -EFAULT; |
607 | 595 | ||
608 | return drm_ioctl(file->f_path.dentry->d_inode, file, | 596 | return drm_ioctl(file, DRM_IOCTL_SET_SAREA_CTX, (unsigned long)request); |
609 | DRM_IOCTL_SET_SAREA_CTX, (unsigned long)request); | ||
610 | } | 597 | } |
611 | 598 | ||
612 | static int compat_drm_getsareactx(struct file *file, unsigned int cmd, | 599 | static int compat_drm_getsareactx(struct file *file, unsigned int cmd, |
@@ -628,8 +615,7 @@ static int compat_drm_getsareactx(struct file *file, unsigned int cmd, | |||
628 | if (__put_user(ctx_id, &request->ctx_id)) | 615 | if (__put_user(ctx_id, &request->ctx_id)) |
629 | return -EFAULT; | 616 | return -EFAULT; |
630 | 617 | ||
631 | err = drm_ioctl(file->f_path.dentry->d_inode, file, | 618 | err = drm_ioctl(file, DRM_IOCTL_GET_SAREA_CTX, (unsigned long)request); |
632 | DRM_IOCTL_GET_SAREA_CTX, (unsigned long)request); | ||
633 | if (err) | 619 | if (err) |
634 | return err; | 620 | return err; |
635 | 621 | ||
@@ -664,8 +650,7 @@ static int compat_drm_resctx(struct file *file, unsigned int cmd, | |||
664 | &res->contexts)) | 650 | &res->contexts)) |
665 | return -EFAULT; | 651 | return -EFAULT; |
666 | 652 | ||
667 | err = drm_ioctl(file->f_path.dentry->d_inode, file, | 653 | err = drm_ioctl(file, DRM_IOCTL_RES_CTX, (unsigned long)res); |
668 | DRM_IOCTL_RES_CTX, (unsigned long)res); | ||
669 | if (err) | 654 | if (err) |
670 | return err; | 655 | return err; |
671 | 656 | ||
@@ -718,8 +703,7 @@ static int compat_drm_dma(struct file *file, unsigned int cmd, | |||
718 | &d->request_sizes)) | 703 | &d->request_sizes)) |
719 | return -EFAULT; | 704 | return -EFAULT; |
720 | 705 | ||
721 | err = drm_ioctl(file->f_path.dentry->d_inode, file, | 706 | err = drm_ioctl(file, DRM_IOCTL_DMA, (unsigned long)d); |
722 | DRM_IOCTL_DMA, (unsigned long)d); | ||
723 | if (err) | 707 | if (err) |
724 | return err; | 708 | return err; |
725 | 709 | ||
@@ -751,8 +735,7 @@ static int compat_drm_agp_enable(struct file *file, unsigned int cmd, | |||
751 | if (put_user(m32.mode, &mode->mode)) | 735 | if (put_user(m32.mode, &mode->mode)) |
752 | return -EFAULT; | 736 | return -EFAULT; |
753 | 737 | ||
754 | return drm_ioctl(file->f_path.dentry->d_inode, file, | 738 | return drm_ioctl(file, DRM_IOCTL_AGP_ENABLE, (unsigned long)mode); |
755 | DRM_IOCTL_AGP_ENABLE, (unsigned long)mode); | ||
756 | } | 739 | } |
757 | 740 | ||
758 | typedef struct drm_agp_info32 { | 741 | typedef struct drm_agp_info32 { |
@@ -781,8 +764,7 @@ static int compat_drm_agp_info(struct file *file, unsigned int cmd, | |||
781 | if (!access_ok(VERIFY_WRITE, info, sizeof(*info))) | 764 | if (!access_ok(VERIFY_WRITE, info, sizeof(*info))) |
782 | return -EFAULT; | 765 | return -EFAULT; |
783 | 766 | ||
784 | err = drm_ioctl(file->f_path.dentry->d_inode, file, | 767 | err = drm_ioctl(file, DRM_IOCTL_AGP_INFO, (unsigned long)info); |
785 | DRM_IOCTL_AGP_INFO, (unsigned long)info); | ||
786 | if (err) | 768 | if (err) |
787 | return err; | 769 | return err; |
788 | 770 | ||
@@ -827,16 +809,14 @@ static int compat_drm_agp_alloc(struct file *file, unsigned int cmd, | |||
827 | || __put_user(req32.type, &request->type)) | 809 | || __put_user(req32.type, &request->type)) |
828 | return -EFAULT; | 810 | return -EFAULT; |
829 | 811 | ||
830 | err = drm_ioctl(file->f_path.dentry->d_inode, file, | 812 | err = drm_ioctl(file, DRM_IOCTL_AGP_ALLOC, (unsigned long)request); |
831 | DRM_IOCTL_AGP_ALLOC, (unsigned long)request); | ||
832 | if (err) | 813 | if (err) |
833 | return err; | 814 | return err; |
834 | 815 | ||
835 | if (__get_user(req32.handle, &request->handle) | 816 | if (__get_user(req32.handle, &request->handle) |
836 | || __get_user(req32.physical, &request->physical) | 817 | || __get_user(req32.physical, &request->physical) |
837 | || copy_to_user(argp, &req32, sizeof(req32))) { | 818 | || copy_to_user(argp, &req32, sizeof(req32))) { |
838 | drm_ioctl(file->f_path.dentry->d_inode, file, | 819 | drm_ioctl(file, DRM_IOCTL_AGP_FREE, (unsigned long)request); |
839 | DRM_IOCTL_AGP_FREE, (unsigned long)request); | ||
840 | return -EFAULT; | 820 | return -EFAULT; |
841 | } | 821 | } |
842 | 822 | ||
@@ -856,8 +836,7 @@ static int compat_drm_agp_free(struct file *file, unsigned int cmd, | |||
856 | || __put_user(handle, &request->handle)) | 836 | || __put_user(handle, &request->handle)) |
857 | return -EFAULT; | 837 | return -EFAULT; |
858 | 838 | ||
859 | return drm_ioctl(file->f_path.dentry->d_inode, file, | 839 | return drm_ioctl(file, DRM_IOCTL_AGP_FREE, (unsigned long)request); |
860 | DRM_IOCTL_AGP_FREE, (unsigned long)request); | ||
861 | } | 840 | } |
862 | 841 | ||
863 | typedef struct drm_agp_binding32 { | 842 | typedef struct drm_agp_binding32 { |
@@ -881,8 +860,7 @@ static int compat_drm_agp_bind(struct file *file, unsigned int cmd, | |||
881 | || __put_user(req32.offset, &request->offset)) | 860 | || __put_user(req32.offset, &request->offset)) |
882 | return -EFAULT; | 861 | return -EFAULT; |
883 | 862 | ||
884 | return drm_ioctl(file->f_path.dentry->d_inode, file, | 863 | return drm_ioctl(file, DRM_IOCTL_AGP_BIND, (unsigned long)request); |
885 | DRM_IOCTL_AGP_BIND, (unsigned long)request); | ||
886 | } | 864 | } |
887 | 865 | ||
888 | static int compat_drm_agp_unbind(struct file *file, unsigned int cmd, | 866 | static int compat_drm_agp_unbind(struct file *file, unsigned int cmd, |
@@ -898,8 +876,7 @@ static int compat_drm_agp_unbind(struct file *file, unsigned int cmd, | |||
898 | || __put_user(handle, &request->handle)) | 876 | || __put_user(handle, &request->handle)) |
899 | return -EFAULT; | 877 | return -EFAULT; |
900 | 878 | ||
901 | return drm_ioctl(file->f_path.dentry->d_inode, file, | 879 | return drm_ioctl(file, DRM_IOCTL_AGP_UNBIND, (unsigned long)request); |
902 | DRM_IOCTL_AGP_UNBIND, (unsigned long)request); | ||
903 | } | 880 | } |
904 | #endif /* __OS_HAS_AGP */ | 881 | #endif /* __OS_HAS_AGP */ |
905 | 882 | ||
@@ -923,8 +900,7 @@ static int compat_drm_sg_alloc(struct file *file, unsigned int cmd, | |||
923 | || __put_user(x, &request->size)) | 900 | || __put_user(x, &request->size)) |
924 | return -EFAULT; | 901 | return -EFAULT; |
925 | 902 | ||
926 | err = drm_ioctl(file->f_path.dentry->d_inode, file, | 903 | err = drm_ioctl(file, DRM_IOCTL_SG_ALLOC, (unsigned long)request); |
927 | DRM_IOCTL_SG_ALLOC, (unsigned long)request); | ||
928 | if (err) | 904 | if (err) |
929 | return err; | 905 | return err; |
930 | 906 | ||
@@ -950,8 +926,7 @@ static int compat_drm_sg_free(struct file *file, unsigned int cmd, | |||
950 | || __put_user(x << PAGE_SHIFT, &request->handle)) | 926 | || __put_user(x << PAGE_SHIFT, &request->handle)) |
951 | return -EFAULT; | 927 | return -EFAULT; |
952 | 928 | ||
953 | return drm_ioctl(file->f_path.dentry->d_inode, file, | 929 | return drm_ioctl(file, DRM_IOCTL_SG_FREE, (unsigned long)request); |
954 | DRM_IOCTL_SG_FREE, (unsigned long)request); | ||
955 | } | 930 | } |
956 | 931 | ||
957 | #if defined(CONFIG_X86) || defined(CONFIG_IA64) | 932 | #if defined(CONFIG_X86) || defined(CONFIG_IA64) |
@@ -981,8 +956,7 @@ static int compat_drm_update_draw(struct file *file, unsigned int cmd, | |||
981 | __put_user(update32.data, &request->data)) | 956 | __put_user(update32.data, &request->data)) |
982 | return -EFAULT; | 957 | return -EFAULT; |
983 | 958 | ||
984 | err = drm_ioctl(file->f_path.dentry->d_inode, file, | 959 | err = drm_ioctl(file, DRM_IOCTL_UPDATE_DRAW, (unsigned long)request); |
985 | DRM_IOCTL_UPDATE_DRAW, (unsigned long)request); | ||
986 | return err; | 960 | return err; |
987 | } | 961 | } |
988 | #endif | 962 | #endif |
@@ -1023,8 +997,7 @@ static int compat_drm_wait_vblank(struct file *file, unsigned int cmd, | |||
1023 | || __put_user(req32.request.signal, &request->request.signal)) | 997 | || __put_user(req32.request.signal, &request->request.signal)) |
1024 | return -EFAULT; | 998 | return -EFAULT; |
1025 | 999 | ||
1026 | err = drm_ioctl(file->f_path.dentry->d_inode, file, | 1000 | err = drm_ioctl(file, DRM_IOCTL_WAIT_VBLANK, (unsigned long)request); |
1027 | DRM_IOCTL_WAIT_VBLANK, (unsigned long)request); | ||
1028 | if (err) | 1001 | if (err) |
1029 | return err; | 1002 | return err; |
1030 | 1003 | ||
@@ -1094,16 +1067,14 @@ long drm_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
1094 | * than always failing. | 1067 | * than always failing. |
1095 | */ | 1068 | */ |
1096 | if (nr >= ARRAY_SIZE(drm_compat_ioctls)) | 1069 | if (nr >= ARRAY_SIZE(drm_compat_ioctls)) |
1097 | return drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg); | 1070 | return drm_ioctl(filp, cmd, arg); |
1098 | 1071 | ||
1099 | fn = drm_compat_ioctls[nr]; | 1072 | fn = drm_compat_ioctls[nr]; |
1100 | 1073 | ||
1101 | lock_kernel(); /* XXX for now */ | ||
1102 | if (fn != NULL) | 1074 | if (fn != NULL) |
1103 | ret = (*fn) (filp, cmd, arg); | 1075 | ret = (*fn) (filp, cmd, arg); |
1104 | else | 1076 | else |
1105 | ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg); | 1077 | ret = drm_ioctl(filp, cmd, arg); |
1106 | unlock_kernel(); | ||
1107 | 1078 | ||
1108 | return ret; | 1079 | return ret; |
1109 | } | 1080 | } |
diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index d7d7eac3ddd2..cdec32977129 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c | |||
@@ -358,7 +358,7 @@ struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm, | |||
358 | if (entry->size >= size + wasted) { | 358 | if (entry->size >= size + wasted) { |
359 | if (!best_match) | 359 | if (!best_match) |
360 | return entry; | 360 | return entry; |
361 | if (size < best_size) { | 361 | if (entry->size < best_size) { |
362 | best = entry; | 362 | best = entry; |
363 | best_size = entry->size; | 363 | best_size = entry->size; |
364 | } | 364 | } |
@@ -408,7 +408,7 @@ struct drm_mm_node *drm_mm_search_free_in_range(const struct drm_mm *mm, | |||
408 | if (entry->size >= size + wasted) { | 408 | if (entry->size >= size + wasted) { |
409 | if (!best_match) | 409 | if (!best_match) |
410 | return entry; | 410 | return entry; |
411 | if (size < best_size) { | 411 | if (entry->size < best_size) { |
412 | best = entry; | 412 | best = entry; |
413 | best_size = entry->size; | 413 | best_size = entry->size; |
414 | } | 414 | } |
diff --git a/drivers/gpu/drm/i2c/ch7006_drv.c b/drivers/gpu/drm/i2c/ch7006_drv.c index 9422a74c8b54..81681a07a806 100644 --- a/drivers/gpu/drm/i2c/ch7006_drv.c +++ b/drivers/gpu/drm/i2c/ch7006_drv.c | |||
@@ -408,6 +408,11 @@ static int ch7006_probe(struct i2c_client *client, const struct i2c_device_id *i | |||
408 | 408 | ||
409 | ch7006_info(client, "Detected version ID: %x\n", val); | 409 | ch7006_info(client, "Detected version ID: %x\n", val); |
410 | 410 | ||
411 | /* I don't know what this is for, but otherwise I get no | ||
412 | * signal. | ||
413 | */ | ||
414 | ch7006_write(client, 0x3d, 0x0); | ||
415 | |||
411 | return 0; | 416 | return 0; |
412 | 417 | ||
413 | fail: | 418 | fail: |
diff --git a/drivers/gpu/drm/i2c/ch7006_mode.c b/drivers/gpu/drm/i2c/ch7006_mode.c index 87f5445092e8..e447dfb63890 100644 --- a/drivers/gpu/drm/i2c/ch7006_mode.c +++ b/drivers/gpu/drm/i2c/ch7006_mode.c | |||
@@ -427,11 +427,6 @@ void ch7006_state_load(struct i2c_client *client, | |||
427 | ch7006_load_reg(client, state, CH7006_SUBC_INC7); | 427 | ch7006_load_reg(client, state, CH7006_SUBC_INC7); |
428 | ch7006_load_reg(client, state, CH7006_PLL_CONTROL); | 428 | ch7006_load_reg(client, state, CH7006_PLL_CONTROL); |
429 | ch7006_load_reg(client, state, CH7006_CALC_SUBC_INC0); | 429 | ch7006_load_reg(client, state, CH7006_CALC_SUBC_INC0); |
430 | |||
431 | /* I don't know what this is for, but otherwise I get no | ||
432 | * signal. | ||
433 | */ | ||
434 | ch7006_write(client, 0x3d, 0x0); | ||
435 | } | 430 | } |
436 | 431 | ||
437 | void ch7006_state_save(struct i2c_client *client, | 432 | void ch7006_state_save(struct i2c_client *client, |
diff --git a/drivers/gpu/drm/i810/i810_dma.c b/drivers/gpu/drm/i810/i810_dma.c index 7d1d88cdf2dc..de32d22a8c39 100644 --- a/drivers/gpu/drm/i810/i810_dma.c +++ b/drivers/gpu/drm/i810/i810_dma.c | |||
@@ -115,7 +115,7 @@ static int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma) | |||
115 | static const struct file_operations i810_buffer_fops = { | 115 | static const struct file_operations i810_buffer_fops = { |
116 | .open = drm_open, | 116 | .open = drm_open, |
117 | .release = drm_release, | 117 | .release = drm_release, |
118 | .ioctl = drm_ioctl, | 118 | .unlocked_ioctl = drm_ioctl, |
119 | .mmap = i810_mmap_buffers, | 119 | .mmap = i810_mmap_buffers, |
120 | .fasync = drm_fasync, | 120 | .fasync = drm_fasync, |
121 | }; | 121 | }; |
diff --git a/drivers/gpu/drm/i810/i810_drv.c b/drivers/gpu/drm/i810/i810_drv.c index fabb9a817966..c1e02752e023 100644 --- a/drivers/gpu/drm/i810/i810_drv.c +++ b/drivers/gpu/drm/i810/i810_drv.c | |||
@@ -59,7 +59,7 @@ static struct drm_driver driver = { | |||
59 | .owner = THIS_MODULE, | 59 | .owner = THIS_MODULE, |
60 | .open = drm_open, | 60 | .open = drm_open, |
61 | .release = drm_release, | 61 | .release = drm_release, |
62 | .ioctl = drm_ioctl, | 62 | .unlocked_ioctl = drm_ioctl, |
63 | .mmap = drm_mmap, | 63 | .mmap = drm_mmap, |
64 | .poll = drm_poll, | 64 | .poll = drm_poll, |
65 | .fasync = drm_fasync, | 65 | .fasync = drm_fasync, |
diff --git a/drivers/gpu/drm/i830/i830_dma.c b/drivers/gpu/drm/i830/i830_dma.c index 877bf6cb14a4..06bd732e6463 100644 --- a/drivers/gpu/drm/i830/i830_dma.c +++ b/drivers/gpu/drm/i830/i830_dma.c | |||
@@ -117,7 +117,7 @@ static int i830_mmap_buffers(struct file *filp, struct vm_area_struct *vma) | |||
117 | static const struct file_operations i830_buffer_fops = { | 117 | static const struct file_operations i830_buffer_fops = { |
118 | .open = drm_open, | 118 | .open = drm_open, |
119 | .release = drm_release, | 119 | .release = drm_release, |
120 | .ioctl = drm_ioctl, | 120 | .unlocked_ioctl = drm_ioctl, |
121 | .mmap = i830_mmap_buffers, | 121 | .mmap = i830_mmap_buffers, |
122 | .fasync = drm_fasync, | 122 | .fasync = drm_fasync, |
123 | }; | 123 | }; |
diff --git a/drivers/gpu/drm/i830/i830_drv.c b/drivers/gpu/drm/i830/i830_drv.c index 389597e4a623..44f990bed8f4 100644 --- a/drivers/gpu/drm/i830/i830_drv.c +++ b/drivers/gpu/drm/i830/i830_drv.c | |||
@@ -70,7 +70,7 @@ static struct drm_driver driver = { | |||
70 | .owner = THIS_MODULE, | 70 | .owner = THIS_MODULE, |
71 | .open = drm_open, | 71 | .open = drm_open, |
72 | .release = drm_release, | 72 | .release = drm_release, |
73 | .ioctl = drm_ioctl, | 73 | .unlocked_ioctl = drm_ioctl, |
74 | .mmap = drm_mmap, | 74 | .mmap = drm_mmap, |
75 | .poll = drm_poll, | 75 | .poll = drm_poll, |
76 | .fasync = drm_fasync, | 76 | .fasync = drm_fasync, |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 2fa217862058..24286ca168fc 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -329,7 +329,7 @@ static struct drm_driver driver = { | |||
329 | .owner = THIS_MODULE, | 329 | .owner = THIS_MODULE, |
330 | .open = drm_open, | 330 | .open = drm_open, |
331 | .release = drm_release, | 331 | .release = drm_release, |
332 | .ioctl = drm_ioctl, | 332 | .unlocked_ioctl = drm_ioctl, |
333 | .mmap = drm_gem_mmap, | 333 | .mmap = drm_gem_mmap, |
334 | .poll = drm_poll, | 334 | .poll = drm_poll, |
335 | .fasync = drm_fasync, | 335 | .fasync = drm_fasync, |
diff --git a/drivers/gpu/drm/i915/i915_ioc32.c b/drivers/gpu/drm/i915/i915_ioc32.c index 1fe68a251b75..13b028994b2b 100644 --- a/drivers/gpu/drm/i915/i915_ioc32.c +++ b/drivers/gpu/drm/i915/i915_ioc32.c | |||
@@ -66,8 +66,7 @@ static int compat_i915_batchbuffer(struct file *file, unsigned int cmd, | |||
66 | &batchbuffer->cliprects)) | 66 | &batchbuffer->cliprects)) |
67 | return -EFAULT; | 67 | return -EFAULT; |
68 | 68 | ||
69 | return drm_ioctl(file->f_path.dentry->d_inode, file, | 69 | return drm_ioctl(file, DRM_IOCTL_I915_BATCHBUFFER, |
70 | DRM_IOCTL_I915_BATCHBUFFER, | ||
71 | (unsigned long)batchbuffer); | 70 | (unsigned long)batchbuffer); |
72 | } | 71 | } |
73 | 72 | ||
@@ -102,8 +101,8 @@ static int compat_i915_cmdbuffer(struct file *file, unsigned int cmd, | |||
102 | &cmdbuffer->cliprects)) | 101 | &cmdbuffer->cliprects)) |
103 | return -EFAULT; | 102 | return -EFAULT; |
104 | 103 | ||
105 | return drm_ioctl(file->f_path.dentry->d_inode, file, | 104 | return drm_ioctl(file, DRM_IOCTL_I915_CMDBUFFER, |
106 | DRM_IOCTL_I915_CMDBUFFER, (unsigned long)cmdbuffer); | 105 | (unsigned long)cmdbuffer); |
107 | } | 106 | } |
108 | 107 | ||
109 | typedef struct drm_i915_irq_emit32 { | 108 | typedef struct drm_i915_irq_emit32 { |
@@ -125,8 +124,8 @@ static int compat_i915_irq_emit(struct file *file, unsigned int cmd, | |||
125 | &request->irq_seq)) | 124 | &request->irq_seq)) |
126 | return -EFAULT; | 125 | return -EFAULT; |
127 | 126 | ||
128 | return drm_ioctl(file->f_path.dentry->d_inode, file, | 127 | return drm_ioctl(file, DRM_IOCTL_I915_IRQ_EMIT, |
129 | DRM_IOCTL_I915_IRQ_EMIT, (unsigned long)request); | 128 | (unsigned long)request); |
130 | } | 129 | } |
131 | typedef struct drm_i915_getparam32 { | 130 | typedef struct drm_i915_getparam32 { |
132 | int param; | 131 | int param; |
@@ -149,8 +148,8 @@ static int compat_i915_getparam(struct file *file, unsigned int cmd, | |||
149 | &request->value)) | 148 | &request->value)) |
150 | return -EFAULT; | 149 | return -EFAULT; |
151 | 150 | ||
152 | return drm_ioctl(file->f_path.dentry->d_inode, file, | 151 | return drm_ioctl(file, DRM_IOCTL_I915_GETPARAM, |
153 | DRM_IOCTL_I915_GETPARAM, (unsigned long)request); | 152 | (unsigned long)request); |
154 | } | 153 | } |
155 | 154 | ||
156 | typedef struct drm_i915_mem_alloc32 { | 155 | typedef struct drm_i915_mem_alloc32 { |
@@ -178,8 +177,8 @@ static int compat_i915_alloc(struct file *file, unsigned int cmd, | |||
178 | &request->region_offset)) | 177 | &request->region_offset)) |
179 | return -EFAULT; | 178 | return -EFAULT; |
180 | 179 | ||
181 | return drm_ioctl(file->f_path.dentry->d_inode, file, | 180 | return drm_ioctl(file, DRM_IOCTL_I915_ALLOC, |
182 | DRM_IOCTL_I915_ALLOC, (unsigned long)request); | 181 | (unsigned long)request); |
183 | } | 182 | } |
184 | 183 | ||
185 | drm_ioctl_compat_t *i915_compat_ioctls[] = { | 184 | drm_ioctl_compat_t *i915_compat_ioctls[] = { |
@@ -211,12 +210,10 @@ long i915_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
211 | if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(i915_compat_ioctls)) | 210 | if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(i915_compat_ioctls)) |
212 | fn = i915_compat_ioctls[nr - DRM_COMMAND_BASE]; | 211 | fn = i915_compat_ioctls[nr - DRM_COMMAND_BASE]; |
213 | 212 | ||
214 | lock_kernel(); /* XXX for now */ | ||
215 | if (fn != NULL) | 213 | if (fn != NULL) |
216 | ret = (*fn) (filp, cmd, arg); | 214 | ret = (*fn) (filp, cmd, arg); |
217 | else | 215 | else |
218 | ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg); | 216 | ret = drm_ioctl(filp, cmd, arg); |
219 | unlock_kernel(); | ||
220 | 217 | ||
221 | return ret; | 218 | return ret; |
222 | } | 219 | } |
diff --git a/drivers/gpu/drm/mga/mga_drv.c b/drivers/gpu/drm/mga/mga_drv.c index 97ee566ef749..ddfe16197b59 100644 --- a/drivers/gpu/drm/mga/mga_drv.c +++ b/drivers/gpu/drm/mga/mga_drv.c | |||
@@ -68,7 +68,7 @@ static struct drm_driver driver = { | |||
68 | .owner = THIS_MODULE, | 68 | .owner = THIS_MODULE, |
69 | .open = drm_open, | 69 | .open = drm_open, |
70 | .release = drm_release, | 70 | .release = drm_release, |
71 | .ioctl = drm_ioctl, | 71 | .unlocked_ioctl = drm_ioctl, |
72 | .mmap = drm_mmap, | 72 | .mmap = drm_mmap, |
73 | .poll = drm_poll, | 73 | .poll = drm_poll, |
74 | .fasync = drm_fasync, | 74 | .fasync = drm_fasync, |
diff --git a/drivers/gpu/drm/mga/mga_ioc32.c b/drivers/gpu/drm/mga/mga_ioc32.c index 30d00478ddee..c1f877b7bac1 100644 --- a/drivers/gpu/drm/mga/mga_ioc32.c +++ b/drivers/gpu/drm/mga/mga_ioc32.c | |||
@@ -100,8 +100,7 @@ static int compat_mga_init(struct file *file, unsigned int cmd, | |||
100 | if (err) | 100 | if (err) |
101 | return -EFAULT; | 101 | return -EFAULT; |
102 | 102 | ||
103 | return drm_ioctl(file->f_path.dentry->d_inode, file, | 103 | return drm_ioctl(file, DRM_IOCTL_MGA_INIT, (unsigned long)init); |
104 | DRM_IOCTL_MGA_INIT, (unsigned long)init); | ||
105 | } | 104 | } |
106 | 105 | ||
107 | typedef struct drm_mga_getparam32 { | 106 | typedef struct drm_mga_getparam32 { |
@@ -125,8 +124,7 @@ static int compat_mga_getparam(struct file *file, unsigned int cmd, | |||
125 | &getparam->value)) | 124 | &getparam->value)) |
126 | return -EFAULT; | 125 | return -EFAULT; |
127 | 126 | ||
128 | return drm_ioctl(file->f_path.dentry->d_inode, file, | 127 | return drm_ioctl(file, DRM_IOCTL_MGA_GETPARAM, (unsigned long)getparam); |
129 | DRM_IOCTL_MGA_GETPARAM, (unsigned long)getparam); | ||
130 | } | 128 | } |
131 | 129 | ||
132 | typedef struct drm_mga_drm_bootstrap32 { | 130 | typedef struct drm_mga_drm_bootstrap32 { |
@@ -166,8 +164,7 @@ static int compat_mga_dma_bootstrap(struct file *file, unsigned int cmd, | |||
166 | || __put_user(dma_bootstrap32.agp_size, &dma_bootstrap->agp_size)) | 164 | || __put_user(dma_bootstrap32.agp_size, &dma_bootstrap->agp_size)) |
167 | return -EFAULT; | 165 | return -EFAULT; |
168 | 166 | ||
169 | err = drm_ioctl(file->f_path.dentry->d_inode, file, | 167 | err = drm_ioctl(file, DRM_IOCTL_MGA_DMA_BOOTSTRAP, |
170 | DRM_IOCTL_MGA_DMA_BOOTSTRAP, | ||
171 | (unsigned long)dma_bootstrap); | 168 | (unsigned long)dma_bootstrap); |
172 | if (err) | 169 | if (err) |
173 | return err; | 170 | return err; |
@@ -220,12 +217,10 @@ long mga_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
220 | if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(mga_compat_ioctls)) | 217 | if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(mga_compat_ioctls)) |
221 | fn = mga_compat_ioctls[nr - DRM_COMMAND_BASE]; | 218 | fn = mga_compat_ioctls[nr - DRM_COMMAND_BASE]; |
222 | 219 | ||
223 | lock_kernel(); /* XXX for now */ | ||
224 | if (fn != NULL) | 220 | if (fn != NULL) |
225 | ret = (*fn) (filp, cmd, arg); | 221 | ret = (*fn) (filp, cmd, arg); |
226 | else | 222 | else |
227 | ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg); | 223 | ret = drm_ioctl(filp, cmd, arg); |
228 | unlock_kernel(); | ||
229 | 224 | ||
230 | return ret; | 225 | return ret; |
231 | } | 226 | } |
diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile index 1d90d4d0144f..48c290b5da8c 100644 --- a/drivers/gpu/drm/nouveau/Makefile +++ b/drivers/gpu/drm/nouveau/Makefile | |||
@@ -8,14 +8,15 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \ | |||
8 | nouveau_sgdma.o nouveau_dma.o \ | 8 | nouveau_sgdma.o nouveau_dma.o \ |
9 | nouveau_bo.o nouveau_fence.o nouveau_gem.o nouveau_ttm.o \ | 9 | nouveau_bo.o nouveau_fence.o nouveau_gem.o nouveau_ttm.o \ |
10 | nouveau_hw.o nouveau_calc.o nouveau_bios.o nouveau_i2c.o \ | 10 | nouveau_hw.o nouveau_calc.o nouveau_bios.o nouveau_i2c.o \ |
11 | nouveau_display.o nouveau_connector.o nouveau_fbcon.o \ | 11 | nouveau_display.o nouveau_connector.o nouveau_fbcon.o \ |
12 | nouveau_dp.o \ | 12 | nouveau_dp.o nouveau_grctx.o \ |
13 | nv04_timer.o \ | 13 | nv04_timer.o \ |
14 | nv04_mc.o nv40_mc.o nv50_mc.o \ | 14 | nv04_mc.o nv40_mc.o nv50_mc.o \ |
15 | nv04_fb.o nv10_fb.o nv40_fb.o \ | 15 | nv04_fb.o nv10_fb.o nv40_fb.o \ |
16 | nv04_fifo.o nv10_fifo.o nv40_fifo.o nv50_fifo.o \ | 16 | nv04_fifo.o nv10_fifo.o nv40_fifo.o nv50_fifo.o \ |
17 | nv04_graph.o nv10_graph.o nv20_graph.o \ | 17 | nv04_graph.o nv10_graph.o nv20_graph.o \ |
18 | nv40_graph.o nv50_graph.o \ | 18 | nv40_graph.o nv50_graph.o \ |
19 | nv40_grctx.o \ | ||
19 | nv04_instmem.o nv50_instmem.o \ | 20 | nv04_instmem.o nv50_instmem.o \ |
20 | nv50_crtc.o nv50_dac.o nv50_sor.o \ | 21 | nv50_crtc.o nv50_dac.o nv50_sor.o \ |
21 | nv50_cursor.o nv50_display.o nv50_fbcon.o \ | 22 | nv50_cursor.o nv50_display.o nv50_fbcon.o \ |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 5eec5ed69489..ba143972769f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c | |||
@@ -181,43 +181,42 @@ struct methods { | |||
181 | const char desc[8]; | 181 | const char desc[8]; |
182 | void (*loadbios)(struct drm_device *, uint8_t *); | 182 | void (*loadbios)(struct drm_device *, uint8_t *); |
183 | const bool rw; | 183 | const bool rw; |
184 | int score; | ||
185 | }; | 184 | }; |
186 | 185 | ||
187 | static struct methods nv04_methods[] = { | 186 | static struct methods nv04_methods[] = { |
188 | { "PROM", load_vbios_prom, false }, | 187 | { "PROM", load_vbios_prom, false }, |
189 | { "PRAMIN", load_vbios_pramin, true }, | 188 | { "PRAMIN", load_vbios_pramin, true }, |
190 | { "PCIROM", load_vbios_pci, true }, | 189 | { "PCIROM", load_vbios_pci, true }, |
191 | { } | ||
192 | }; | 190 | }; |
193 | 191 | ||
194 | static struct methods nv50_methods[] = { | 192 | static struct methods nv50_methods[] = { |
195 | { "PRAMIN", load_vbios_pramin, true }, | 193 | { "PRAMIN", load_vbios_pramin, true }, |
196 | { "PROM", load_vbios_prom, false }, | 194 | { "PROM", load_vbios_prom, false }, |
197 | { "PCIROM", load_vbios_pci, true }, | 195 | { "PCIROM", load_vbios_pci, true }, |
198 | { } | ||
199 | }; | 196 | }; |
200 | 197 | ||
198 | #define METHODCNT 3 | ||
199 | |||
201 | static bool NVShadowVBIOS(struct drm_device *dev, uint8_t *data) | 200 | static bool NVShadowVBIOS(struct drm_device *dev, uint8_t *data) |
202 | { | 201 | { |
203 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 202 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
204 | struct methods *methods, *method; | 203 | struct methods *methods; |
204 | int i; | ||
205 | int testscore = 3; | 205 | int testscore = 3; |
206 | int scores[METHODCNT]; | ||
206 | 207 | ||
207 | if (nouveau_vbios) { | 208 | if (nouveau_vbios) { |
208 | method = nv04_methods; | 209 | methods = nv04_methods; |
209 | while (method->loadbios) { | 210 | for (i = 0; i < METHODCNT; i++) |
210 | if (!strcasecmp(nouveau_vbios, method->desc)) | 211 | if (!strcasecmp(nouveau_vbios, methods[i].desc)) |
211 | break; | 212 | break; |
212 | method++; | ||
213 | } | ||
214 | 213 | ||
215 | if (method->loadbios) { | 214 | if (i < METHODCNT) { |
216 | NV_INFO(dev, "Attempting to use BIOS image from %s\n", | 215 | NV_INFO(dev, "Attempting to use BIOS image from %s\n", |
217 | method->desc); | 216 | methods[i].desc); |
218 | 217 | ||
219 | method->loadbios(dev, data); | 218 | methods[i].loadbios(dev, data); |
220 | if (score_vbios(dev, data, method->rw)) | 219 | if (score_vbios(dev, data, methods[i].rw)) |
221 | return true; | 220 | return true; |
222 | } | 221 | } |
223 | 222 | ||
@@ -229,28 +228,24 @@ static bool NVShadowVBIOS(struct drm_device *dev, uint8_t *data) | |||
229 | else | 228 | else |
230 | methods = nv50_methods; | 229 | methods = nv50_methods; |
231 | 230 | ||
232 | method = methods; | 231 | for (i = 0; i < METHODCNT; i++) { |
233 | while (method->loadbios) { | ||
234 | NV_TRACE(dev, "Attempting to load BIOS image from %s\n", | 232 | NV_TRACE(dev, "Attempting to load BIOS image from %s\n", |
235 | method->desc); | 233 | methods[i].desc); |
236 | data[0] = data[1] = 0; /* avoid reuse of previous image */ | 234 | data[0] = data[1] = 0; /* avoid reuse of previous image */ |
237 | method->loadbios(dev, data); | 235 | methods[i].loadbios(dev, data); |
238 | method->score = score_vbios(dev, data, method->rw); | 236 | scores[i] = score_vbios(dev, data, methods[i].rw); |
239 | if (method->score == testscore) | 237 | if (scores[i] == testscore) |
240 | return true; | 238 | return true; |
241 | method++; | ||
242 | } | 239 | } |
243 | 240 | ||
244 | while (--testscore > 0) { | 241 | while (--testscore > 0) { |
245 | method = methods; | 242 | for (i = 0; i < METHODCNT; i++) { |
246 | while (method->loadbios) { | 243 | if (scores[i] == testscore) { |
247 | if (method->score == testscore) { | ||
248 | NV_TRACE(dev, "Using BIOS image from %s\n", | 244 | NV_TRACE(dev, "Using BIOS image from %s\n", |
249 | method->desc); | 245 | methods[i].desc); |
250 | method->loadbios(dev, data); | 246 | methods[i].loadbios(dev, data); |
251 | return true; | 247 | return true; |
252 | } | 248 | } |
253 | method++; | ||
254 | } | 249 | } |
255 | } | 250 | } |
256 | 251 | ||
@@ -261,10 +256,7 @@ static bool NVShadowVBIOS(struct drm_device *dev, uint8_t *data) | |||
261 | struct init_tbl_entry { | 256 | struct init_tbl_entry { |
262 | char *name; | 257 | char *name; |
263 | uint8_t id; | 258 | uint8_t id; |
264 | int length; | 259 | int (*handler)(struct nvbios *, uint16_t, struct init_exec *); |
265 | int length_offset; | ||
266 | int length_multiplier; | ||
267 | bool (*handler)(struct nvbios *, uint16_t, struct init_exec *); | ||
268 | }; | 260 | }; |
269 | 261 | ||
270 | struct bit_entry { | 262 | struct bit_entry { |
@@ -820,7 +812,7 @@ static uint32_t get_tmds_index_reg(struct drm_device *dev, uint8_t mlv) | |||
820 | } | 812 | } |
821 | } | 813 | } |
822 | 814 | ||
823 | static bool | 815 | static int |
824 | init_io_restrict_prog(struct nvbios *bios, uint16_t offset, | 816 | init_io_restrict_prog(struct nvbios *bios, uint16_t offset, |
825 | struct init_exec *iexec) | 817 | struct init_exec *iexec) |
826 | { | 818 | { |
@@ -852,9 +844,10 @@ init_io_restrict_prog(struct nvbios *bios, uint16_t offset, | |||
852 | uint32_t reg = ROM32(bios->data[offset + 7]); | 844 | uint32_t reg = ROM32(bios->data[offset + 7]); |
853 | uint8_t config; | 845 | uint8_t config; |
854 | uint32_t configval; | 846 | uint32_t configval; |
847 | int len = 11 + count * 4; | ||
855 | 848 | ||
856 | if (!iexec->execute) | 849 | if (!iexec->execute) |
857 | return true; | 850 | return len; |
858 | 851 | ||
859 | BIOSLOG(bios, "0x%04X: Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X, " | 852 | BIOSLOG(bios, "0x%04X: Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X, " |
860 | "Shift: 0x%02X, Count: 0x%02X, Reg: 0x%08X\n", | 853 | "Shift: 0x%02X, Count: 0x%02X, Reg: 0x%08X\n", |
@@ -865,7 +858,7 @@ init_io_restrict_prog(struct nvbios *bios, uint16_t offset, | |||
865 | NV_ERROR(bios->dev, | 858 | NV_ERROR(bios->dev, |
866 | "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n", | 859 | "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n", |
867 | offset, config, count); | 860 | offset, config, count); |
868 | return false; | 861 | return 0; |
869 | } | 862 | } |
870 | 863 | ||
871 | configval = ROM32(bios->data[offset + 11 + config * 4]); | 864 | configval = ROM32(bios->data[offset + 11 + config * 4]); |
@@ -874,10 +867,10 @@ init_io_restrict_prog(struct nvbios *bios, uint16_t offset, | |||
874 | 867 | ||
875 | bios_wr32(bios, reg, configval); | 868 | bios_wr32(bios, reg, configval); |
876 | 869 | ||
877 | return true; | 870 | return len; |
878 | } | 871 | } |
879 | 872 | ||
880 | static bool | 873 | static int |
881 | init_repeat(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | 874 | init_repeat(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) |
882 | { | 875 | { |
883 | /* | 876 | /* |
@@ -912,10 +905,10 @@ init_repeat(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
912 | 905 | ||
913 | iexec->repeat = false; | 906 | iexec->repeat = false; |
914 | 907 | ||
915 | return true; | 908 | return 2; |
916 | } | 909 | } |
917 | 910 | ||
918 | static bool | 911 | static int |
919 | init_io_restrict_pll(struct nvbios *bios, uint16_t offset, | 912 | init_io_restrict_pll(struct nvbios *bios, uint16_t offset, |
920 | struct init_exec *iexec) | 913 | struct init_exec *iexec) |
921 | { | 914 | { |
@@ -951,9 +944,10 @@ init_io_restrict_pll(struct nvbios *bios, uint16_t offset, | |||
951 | uint32_t reg = ROM32(bios->data[offset + 8]); | 944 | uint32_t reg = ROM32(bios->data[offset + 8]); |
952 | uint8_t config; | 945 | uint8_t config; |
953 | uint16_t freq; | 946 | uint16_t freq; |
947 | int len = 12 + count * 2; | ||
954 | 948 | ||
955 | if (!iexec->execute) | 949 | if (!iexec->execute) |
956 | return true; | 950 | return len; |
957 | 951 | ||
958 | BIOSLOG(bios, "0x%04X: Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X, " | 952 | BIOSLOG(bios, "0x%04X: Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X, " |
959 | "Shift: 0x%02X, IO Flag Condition: 0x%02X, " | 953 | "Shift: 0x%02X, IO Flag Condition: 0x%02X, " |
@@ -966,7 +960,7 @@ init_io_restrict_pll(struct nvbios *bios, uint16_t offset, | |||
966 | NV_ERROR(bios->dev, | 960 | NV_ERROR(bios->dev, |
967 | "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n", | 961 | "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n", |
968 | offset, config, count); | 962 | offset, config, count); |
969 | return false; | 963 | return 0; |
970 | } | 964 | } |
971 | 965 | ||
972 | freq = ROM16(bios->data[offset + 12 + config * 2]); | 966 | freq = ROM16(bios->data[offset + 12 + config * 2]); |
@@ -986,10 +980,10 @@ init_io_restrict_pll(struct nvbios *bios, uint16_t offset, | |||
986 | 980 | ||
987 | setPLL(bios, reg, freq * 10); | 981 | setPLL(bios, reg, freq * 10); |
988 | 982 | ||
989 | return true; | 983 | return len; |
990 | } | 984 | } |
991 | 985 | ||
992 | static bool | 986 | static int |
993 | init_end_repeat(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | 987 | init_end_repeat(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) |
994 | { | 988 | { |
995 | /* | 989 | /* |
@@ -1007,12 +1001,12 @@ init_end_repeat(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
1007 | * we're not in repeat mode | 1001 | * we're not in repeat mode |
1008 | */ | 1002 | */ |
1009 | if (iexec->repeat) | 1003 | if (iexec->repeat) |
1010 | return false; | 1004 | return 0; |
1011 | 1005 | ||
1012 | return true; | 1006 | return 1; |
1013 | } | 1007 | } |
1014 | 1008 | ||
1015 | static bool | 1009 | static int |
1016 | init_copy(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | 1010 | init_copy(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) |
1017 | { | 1011 | { |
1018 | /* | 1012 | /* |
@@ -1041,7 +1035,7 @@ init_copy(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
1041 | uint8_t crtcdata; | 1035 | uint8_t crtcdata; |
1042 | 1036 | ||
1043 | if (!iexec->execute) | 1037 | if (!iexec->execute) |
1044 | return true; | 1038 | return 11; |
1045 | 1039 | ||
1046 | BIOSLOG(bios, "0x%04X: Reg: 0x%08X, Shift: 0x%02X, SrcMask: 0x%02X, " | 1040 | BIOSLOG(bios, "0x%04X: Reg: 0x%08X, Shift: 0x%02X, SrcMask: 0x%02X, " |
1047 | "Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X\n", | 1041 | "Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X\n", |
@@ -1060,10 +1054,10 @@ init_copy(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
1060 | crtcdata |= (uint8_t)data; | 1054 | crtcdata |= (uint8_t)data; |
1061 | bios_idxprt_wr(bios, crtcport, crtcindex, crtcdata); | 1055 | bios_idxprt_wr(bios, crtcport, crtcindex, crtcdata); |
1062 | 1056 | ||
1063 | return true; | 1057 | return 11; |
1064 | } | 1058 | } |
1065 | 1059 | ||
1066 | static bool | 1060 | static int |
1067 | init_not(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | 1061 | init_not(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) |
1068 | { | 1062 | { |
1069 | /* | 1063 | /* |
@@ -1079,10 +1073,10 @@ init_not(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
1079 | BIOSLOG(bios, "0x%04X: ------ Executing following commands ------\n", offset); | 1073 | BIOSLOG(bios, "0x%04X: ------ Executing following commands ------\n", offset); |
1080 | 1074 | ||
1081 | iexec->execute = !iexec->execute; | 1075 | iexec->execute = !iexec->execute; |
1082 | return true; | 1076 | return 1; |
1083 | } | 1077 | } |
1084 | 1078 | ||
1085 | static bool | 1079 | static int |
1086 | init_io_flag_condition(struct nvbios *bios, uint16_t offset, | 1080 | init_io_flag_condition(struct nvbios *bios, uint16_t offset, |
1087 | struct init_exec *iexec) | 1081 | struct init_exec *iexec) |
1088 | { | 1082 | { |
@@ -1100,7 +1094,7 @@ init_io_flag_condition(struct nvbios *bios, uint16_t offset, | |||
1100 | uint8_t cond = bios->data[offset + 1]; | 1094 | uint8_t cond = bios->data[offset + 1]; |
1101 | 1095 | ||
1102 | if (!iexec->execute) | 1096 | if (!iexec->execute) |
1103 | return true; | 1097 | return 2; |
1104 | 1098 | ||
1105 | if (io_flag_condition_met(bios, offset, cond)) | 1099 | if (io_flag_condition_met(bios, offset, cond)) |
1106 | BIOSLOG(bios, "0x%04X: Condition fulfilled -- continuing to execute\n", offset); | 1100 | BIOSLOG(bios, "0x%04X: Condition fulfilled -- continuing to execute\n", offset); |
@@ -1109,10 +1103,10 @@ init_io_flag_condition(struct nvbios *bios, uint16_t offset, | |||
1109 | iexec->execute = false; | 1103 | iexec->execute = false; |
1110 | } | 1104 | } |
1111 | 1105 | ||
1112 | return true; | 1106 | return 2; |
1113 | } | 1107 | } |
1114 | 1108 | ||
1115 | static bool | 1109 | static int |
1116 | init_idx_addr_latched(struct nvbios *bios, uint16_t offset, | 1110 | init_idx_addr_latched(struct nvbios *bios, uint16_t offset, |
1117 | struct init_exec *iexec) | 1111 | struct init_exec *iexec) |
1118 | { | 1112 | { |
@@ -1140,11 +1134,12 @@ init_idx_addr_latched(struct nvbios *bios, uint16_t offset, | |||
1140 | uint32_t mask = ROM32(bios->data[offset + 9]); | 1134 | uint32_t mask = ROM32(bios->data[offset + 9]); |
1141 | uint32_t data = ROM32(bios->data[offset + 13]); | 1135 | uint32_t data = ROM32(bios->data[offset + 13]); |
1142 | uint8_t count = bios->data[offset + 17]; | 1136 | uint8_t count = bios->data[offset + 17]; |
1137 | int len = 18 + count * 2; | ||
1143 | uint32_t value; | 1138 | uint32_t value; |
1144 | int i; | 1139 | int i; |
1145 | 1140 | ||
1146 | if (!iexec->execute) | 1141 | if (!iexec->execute) |
1147 | return true; | 1142 | return len; |
1148 | 1143 | ||
1149 | BIOSLOG(bios, "0x%04X: ControlReg: 0x%08X, DataReg: 0x%08X, " | 1144 | BIOSLOG(bios, "0x%04X: ControlReg: 0x%08X, DataReg: 0x%08X, " |
1150 | "Mask: 0x%08X, Data: 0x%08X, Count: 0x%02X\n", | 1145 | "Mask: 0x%08X, Data: 0x%08X, Count: 0x%02X\n", |
@@ -1164,10 +1159,10 @@ init_idx_addr_latched(struct nvbios *bios, uint16_t offset, | |||
1164 | bios_wr32(bios, controlreg, value); | 1159 | bios_wr32(bios, controlreg, value); |
1165 | } | 1160 | } |
1166 | 1161 | ||
1167 | return true; | 1162 | return len; |
1168 | } | 1163 | } |
1169 | 1164 | ||
1170 | static bool | 1165 | static int |
1171 | init_io_restrict_pll2(struct nvbios *bios, uint16_t offset, | 1166 | init_io_restrict_pll2(struct nvbios *bios, uint16_t offset, |
1172 | struct init_exec *iexec) | 1167 | struct init_exec *iexec) |
1173 | { | 1168 | { |
@@ -1196,25 +1191,26 @@ init_io_restrict_pll2(struct nvbios *bios, uint16_t offset, | |||
1196 | uint8_t shift = bios->data[offset + 5]; | 1191 | uint8_t shift = bios->data[offset + 5]; |
1197 | uint8_t count = bios->data[offset + 6]; | 1192 | uint8_t count = bios->data[offset + 6]; |
1198 | uint32_t reg = ROM32(bios->data[offset + 7]); | 1193 | uint32_t reg = ROM32(bios->data[offset + 7]); |
1194 | int len = 11 + count * 4; | ||
1199 | uint8_t config; | 1195 | uint8_t config; |
1200 | uint32_t freq; | 1196 | uint32_t freq; |
1201 | 1197 | ||
1202 | if (!iexec->execute) | 1198 | if (!iexec->execute) |
1203 | return true; | 1199 | return len; |
1204 | 1200 | ||
1205 | BIOSLOG(bios, "0x%04X: Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X, " | 1201 | BIOSLOG(bios, "0x%04X: Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X, " |
1206 | "Shift: 0x%02X, Count: 0x%02X, Reg: 0x%08X\n", | 1202 | "Shift: 0x%02X, Count: 0x%02X, Reg: 0x%08X\n", |
1207 | offset, crtcport, crtcindex, mask, shift, count, reg); | 1203 | offset, crtcport, crtcindex, mask, shift, count, reg); |
1208 | 1204 | ||
1209 | if (!reg) | 1205 | if (!reg) |
1210 | return true; | 1206 | return len; |
1211 | 1207 | ||
1212 | config = (bios_idxprt_rd(bios, crtcport, crtcindex) & mask) >> shift; | 1208 | config = (bios_idxprt_rd(bios, crtcport, crtcindex) & mask) >> shift; |
1213 | if (config > count) { | 1209 | if (config > count) { |
1214 | NV_ERROR(bios->dev, | 1210 | NV_ERROR(bios->dev, |
1215 | "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n", | 1211 | "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n", |
1216 | offset, config, count); | 1212 | offset, config, count); |
1217 | return false; | 1213 | return 0; |
1218 | } | 1214 | } |
1219 | 1215 | ||
1220 | freq = ROM32(bios->data[offset + 11 + config * 4]); | 1216 | freq = ROM32(bios->data[offset + 11 + config * 4]); |
@@ -1224,10 +1220,10 @@ init_io_restrict_pll2(struct nvbios *bios, uint16_t offset, | |||
1224 | 1220 | ||
1225 | setPLL(bios, reg, freq); | 1221 | setPLL(bios, reg, freq); |
1226 | 1222 | ||
1227 | return true; | 1223 | return len; |
1228 | } | 1224 | } |
1229 | 1225 | ||
1230 | static bool | 1226 | static int |
1231 | init_pll2(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | 1227 | init_pll2(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) |
1232 | { | 1228 | { |
1233 | /* | 1229 | /* |
@@ -1244,16 +1240,16 @@ init_pll2(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
1244 | uint32_t freq = ROM32(bios->data[offset + 5]); | 1240 | uint32_t freq = ROM32(bios->data[offset + 5]); |
1245 | 1241 | ||
1246 | if (!iexec->execute) | 1242 | if (!iexec->execute) |
1247 | return true; | 1243 | return 9; |
1248 | 1244 | ||
1249 | BIOSLOG(bios, "0x%04X: Reg: 0x%04X, Freq: %dkHz\n", | 1245 | BIOSLOG(bios, "0x%04X: Reg: 0x%04X, Freq: %dkHz\n", |
1250 | offset, reg, freq); | 1246 | offset, reg, freq); |
1251 | 1247 | ||
1252 | setPLL(bios, reg, freq); | 1248 | setPLL(bios, reg, freq); |
1253 | return true; | 1249 | return 9; |
1254 | } | 1250 | } |
1255 | 1251 | ||
1256 | static bool | 1252 | static int |
1257 | init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | 1253 | init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) |
1258 | { | 1254 | { |
1259 | /* | 1255 | /* |
@@ -1277,12 +1273,13 @@ init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
1277 | uint8_t i2c_index = bios->data[offset + 1]; | 1273 | uint8_t i2c_index = bios->data[offset + 1]; |
1278 | uint8_t i2c_address = bios->data[offset + 2]; | 1274 | uint8_t i2c_address = bios->data[offset + 2]; |
1279 | uint8_t count = bios->data[offset + 3]; | 1275 | uint8_t count = bios->data[offset + 3]; |
1276 | int len = 4 + count * 3; | ||
1280 | struct nouveau_i2c_chan *chan; | 1277 | struct nouveau_i2c_chan *chan; |
1281 | struct i2c_msg msg; | 1278 | struct i2c_msg msg; |
1282 | int i; | 1279 | int i; |
1283 | 1280 | ||
1284 | if (!iexec->execute) | 1281 | if (!iexec->execute) |
1285 | return true; | 1282 | return len; |
1286 | 1283 | ||
1287 | BIOSLOG(bios, "0x%04X: DCBI2CIndex: 0x%02X, I2CAddress: 0x%02X, " | 1284 | BIOSLOG(bios, "0x%04X: DCBI2CIndex: 0x%02X, I2CAddress: 0x%02X, " |
1288 | "Count: 0x%02X\n", | 1285 | "Count: 0x%02X\n", |
@@ -1290,7 +1287,7 @@ init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
1290 | 1287 | ||
1291 | chan = init_i2c_device_find(bios->dev, i2c_index); | 1288 | chan = init_i2c_device_find(bios->dev, i2c_index); |
1292 | if (!chan) | 1289 | if (!chan) |
1293 | return false; | 1290 | return 0; |
1294 | 1291 | ||
1295 | for (i = 0; i < count; i++) { | 1292 | for (i = 0; i < count; i++) { |
1296 | uint8_t i2c_reg = bios->data[offset + 4 + i * 3]; | 1293 | uint8_t i2c_reg = bios->data[offset + 4 + i * 3]; |
@@ -1303,7 +1300,7 @@ init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
1303 | msg.len = 1; | 1300 | msg.len = 1; |
1304 | msg.buf = &value; | 1301 | msg.buf = &value; |
1305 | if (i2c_transfer(&chan->adapter, &msg, 1) != 1) | 1302 | if (i2c_transfer(&chan->adapter, &msg, 1) != 1) |
1306 | return false; | 1303 | return 0; |
1307 | 1304 | ||
1308 | BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X, Value: 0x%02X, " | 1305 | BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X, Value: 0x%02X, " |
1309 | "Mask: 0x%02X, Data: 0x%02X\n", | 1306 | "Mask: 0x%02X, Data: 0x%02X\n", |
@@ -1317,14 +1314,14 @@ init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
1317 | msg.len = 1; | 1314 | msg.len = 1; |
1318 | msg.buf = &value; | 1315 | msg.buf = &value; |
1319 | if (i2c_transfer(&chan->adapter, &msg, 1) != 1) | 1316 | if (i2c_transfer(&chan->adapter, &msg, 1) != 1) |
1320 | return false; | 1317 | return 0; |
1321 | } | 1318 | } |
1322 | } | 1319 | } |
1323 | 1320 | ||
1324 | return true; | 1321 | return len; |
1325 | } | 1322 | } |
1326 | 1323 | ||
1327 | static bool | 1324 | static int |
1328 | init_zm_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | 1325 | init_zm_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) |
1329 | { | 1326 | { |
1330 | /* | 1327 | /* |
@@ -1346,12 +1343,13 @@ init_zm_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
1346 | uint8_t i2c_index = bios->data[offset + 1]; | 1343 | uint8_t i2c_index = bios->data[offset + 1]; |
1347 | uint8_t i2c_address = bios->data[offset + 2]; | 1344 | uint8_t i2c_address = bios->data[offset + 2]; |
1348 | uint8_t count = bios->data[offset + 3]; | 1345 | uint8_t count = bios->data[offset + 3]; |
1346 | int len = 4 + count * 2; | ||
1349 | struct nouveau_i2c_chan *chan; | 1347 | struct nouveau_i2c_chan *chan; |
1350 | struct i2c_msg msg; | 1348 | struct i2c_msg msg; |
1351 | int i; | 1349 | int i; |
1352 | 1350 | ||
1353 | if (!iexec->execute) | 1351 | if (!iexec->execute) |
1354 | return true; | 1352 | return len; |
1355 | 1353 | ||
1356 | BIOSLOG(bios, "0x%04X: DCBI2CIndex: 0x%02X, I2CAddress: 0x%02X, " | 1354 | BIOSLOG(bios, "0x%04X: DCBI2CIndex: 0x%02X, I2CAddress: 0x%02X, " |
1357 | "Count: 0x%02X\n", | 1355 | "Count: 0x%02X\n", |
@@ -1359,7 +1357,7 @@ init_zm_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
1359 | 1357 | ||
1360 | chan = init_i2c_device_find(bios->dev, i2c_index); | 1358 | chan = init_i2c_device_find(bios->dev, i2c_index); |
1361 | if (!chan) | 1359 | if (!chan) |
1362 | return false; | 1360 | return 0; |
1363 | 1361 | ||
1364 | for (i = 0; i < count; i++) { | 1362 | for (i = 0; i < count; i++) { |
1365 | uint8_t i2c_reg = bios->data[offset + 4 + i * 2]; | 1363 | uint8_t i2c_reg = bios->data[offset + 4 + i * 2]; |
@@ -1374,14 +1372,14 @@ init_zm_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
1374 | msg.len = 1; | 1372 | msg.len = 1; |
1375 | msg.buf = &data; | 1373 | msg.buf = &data; |
1376 | if (i2c_transfer(&chan->adapter, &msg, 1) != 1) | 1374 | if (i2c_transfer(&chan->adapter, &msg, 1) != 1) |
1377 | return false; | 1375 | return 0; |
1378 | } | 1376 | } |
1379 | } | 1377 | } |
1380 | 1378 | ||
1381 | return true; | 1379 | return len; |
1382 | } | 1380 | } |
1383 | 1381 | ||
1384 | static bool | 1382 | static int |
1385 | init_zm_i2c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | 1383 | init_zm_i2c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) |
1386 | { | 1384 | { |
1387 | /* | 1385 | /* |
@@ -1401,13 +1399,14 @@ init_zm_i2c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
1401 | uint8_t i2c_index = bios->data[offset + 1]; | 1399 | uint8_t i2c_index = bios->data[offset + 1]; |
1402 | uint8_t i2c_address = bios->data[offset + 2]; | 1400 | uint8_t i2c_address = bios->data[offset + 2]; |
1403 | uint8_t count = bios->data[offset + 3]; | 1401 | uint8_t count = bios->data[offset + 3]; |
1402 | int len = 4 + count; | ||
1404 | struct nouveau_i2c_chan *chan; | 1403 | struct nouveau_i2c_chan *chan; |
1405 | struct i2c_msg msg; | 1404 | struct i2c_msg msg; |
1406 | uint8_t data[256]; | 1405 | uint8_t data[256]; |
1407 | int i; | 1406 | int i; |
1408 | 1407 | ||
1409 | if (!iexec->execute) | 1408 | if (!iexec->execute) |
1410 | return true; | 1409 | return len; |
1411 | 1410 | ||
1412 | BIOSLOG(bios, "0x%04X: DCBI2CIndex: 0x%02X, I2CAddress: 0x%02X, " | 1411 | BIOSLOG(bios, "0x%04X: DCBI2CIndex: 0x%02X, I2CAddress: 0x%02X, " |
1413 | "Count: 0x%02X\n", | 1412 | "Count: 0x%02X\n", |
@@ -1415,7 +1414,7 @@ init_zm_i2c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
1415 | 1414 | ||
1416 | chan = init_i2c_device_find(bios->dev, i2c_index); | 1415 | chan = init_i2c_device_find(bios->dev, i2c_index); |
1417 | if (!chan) | 1416 | if (!chan) |
1418 | return false; | 1417 | return 0; |
1419 | 1418 | ||
1420 | for (i = 0; i < count; i++) { | 1419 | for (i = 0; i < count; i++) { |
1421 | data[i] = bios->data[offset + 4 + i]; | 1420 | data[i] = bios->data[offset + 4 + i]; |
@@ -1429,13 +1428,13 @@ init_zm_i2c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
1429 | msg.len = count; | 1428 | msg.len = count; |
1430 | msg.buf = data; | 1429 | msg.buf = data; |
1431 | if (i2c_transfer(&chan->adapter, &msg, 1) != 1) | 1430 | if (i2c_transfer(&chan->adapter, &msg, 1) != 1) |
1432 | return false; | 1431 | return 0; |
1433 | } | 1432 | } |
1434 | 1433 | ||
1435 | return true; | 1434 | return len; |
1436 | } | 1435 | } |
1437 | 1436 | ||
1438 | static bool | 1437 | static int |
1439 | init_tmds(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | 1438 | init_tmds(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) |
1440 | { | 1439 | { |
1441 | /* | 1440 | /* |
@@ -1460,7 +1459,7 @@ init_tmds(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
1460 | uint32_t reg, value; | 1459 | uint32_t reg, value; |
1461 | 1460 | ||
1462 | if (!iexec->execute) | 1461 | if (!iexec->execute) |
1463 | return true; | 1462 | return 5; |
1464 | 1463 | ||
1465 | BIOSLOG(bios, "0x%04X: MagicLookupValue: 0x%02X, TMDSAddr: 0x%02X, " | 1464 | BIOSLOG(bios, "0x%04X: MagicLookupValue: 0x%02X, TMDSAddr: 0x%02X, " |
1466 | "Mask: 0x%02X, Data: 0x%02X\n", | 1465 | "Mask: 0x%02X, Data: 0x%02X\n", |
@@ -1468,7 +1467,7 @@ init_tmds(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
1468 | 1467 | ||
1469 | reg = get_tmds_index_reg(bios->dev, mlv); | 1468 | reg = get_tmds_index_reg(bios->dev, mlv); |
1470 | if (!reg) | 1469 | if (!reg) |
1471 | return false; | 1470 | return 0; |
1472 | 1471 | ||
1473 | bios_wr32(bios, reg, | 1472 | bios_wr32(bios, reg, |
1474 | tmdsaddr | NV_PRAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE); | 1473 | tmdsaddr | NV_PRAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE); |
@@ -1476,10 +1475,10 @@ init_tmds(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
1476 | bios_wr32(bios, reg + 4, value); | 1475 | bios_wr32(bios, reg + 4, value); |
1477 | bios_wr32(bios, reg, tmdsaddr); | 1476 | bios_wr32(bios, reg, tmdsaddr); |
1478 | 1477 | ||
1479 | return true; | 1478 | return 5; |
1480 | } | 1479 | } |
1481 | 1480 | ||
1482 | static bool | 1481 | static int |
1483 | init_zm_tmds_group(struct nvbios *bios, uint16_t offset, | 1482 | init_zm_tmds_group(struct nvbios *bios, uint16_t offset, |
1484 | struct init_exec *iexec) | 1483 | struct init_exec *iexec) |
1485 | { | 1484 | { |
@@ -1500,18 +1499,19 @@ init_zm_tmds_group(struct nvbios *bios, uint16_t offset, | |||
1500 | 1499 | ||
1501 | uint8_t mlv = bios->data[offset + 1]; | 1500 | uint8_t mlv = bios->data[offset + 1]; |
1502 | uint8_t count = bios->data[offset + 2]; | 1501 | uint8_t count = bios->data[offset + 2]; |
1502 | int len = 3 + count * 2; | ||
1503 | uint32_t reg; | 1503 | uint32_t reg; |
1504 | int i; | 1504 | int i; |
1505 | 1505 | ||
1506 | if (!iexec->execute) | 1506 | if (!iexec->execute) |
1507 | return true; | 1507 | return len; |
1508 | 1508 | ||
1509 | BIOSLOG(bios, "0x%04X: MagicLookupValue: 0x%02X, Count: 0x%02X\n", | 1509 | BIOSLOG(bios, "0x%04X: MagicLookupValue: 0x%02X, Count: 0x%02X\n", |
1510 | offset, mlv, count); | 1510 | offset, mlv, count); |
1511 | 1511 | ||
1512 | reg = get_tmds_index_reg(bios->dev, mlv); | 1512 | reg = get_tmds_index_reg(bios->dev, mlv); |
1513 | if (!reg) | 1513 | if (!reg) |
1514 | return false; | 1514 | return 0; |
1515 | 1515 | ||
1516 | for (i = 0; i < count; i++) { | 1516 | for (i = 0; i < count; i++) { |
1517 | uint8_t tmdsaddr = bios->data[offset + 3 + i * 2]; | 1517 | uint8_t tmdsaddr = bios->data[offset + 3 + i * 2]; |
@@ -1521,10 +1521,10 @@ init_zm_tmds_group(struct nvbios *bios, uint16_t offset, | |||
1521 | bios_wr32(bios, reg, tmdsaddr); | 1521 | bios_wr32(bios, reg, tmdsaddr); |
1522 | } | 1522 | } |
1523 | 1523 | ||
1524 | return true; | 1524 | return len; |
1525 | } | 1525 | } |
1526 | 1526 | ||
1527 | static bool | 1527 | static int |
1528 | init_cr_idx_adr_latch(struct nvbios *bios, uint16_t offset, | 1528 | init_cr_idx_adr_latch(struct nvbios *bios, uint16_t offset, |
1529 | struct init_exec *iexec) | 1529 | struct init_exec *iexec) |
1530 | { | 1530 | { |
@@ -1547,11 +1547,12 @@ init_cr_idx_adr_latch(struct nvbios *bios, uint16_t offset, | |||
1547 | uint8_t crtcindex2 = bios->data[offset + 2]; | 1547 | uint8_t crtcindex2 = bios->data[offset + 2]; |
1548 | uint8_t baseaddr = bios->data[offset + 3]; | 1548 | uint8_t baseaddr = bios->data[offset + 3]; |
1549 | uint8_t count = bios->data[offset + 4]; | 1549 | uint8_t count = bios->data[offset + 4]; |
1550 | int len = 5 + count; | ||
1550 | uint8_t oldaddr, data; | 1551 | uint8_t oldaddr, data; |
1551 | int i; | 1552 | int i; |
1552 | 1553 | ||
1553 | if (!iexec->execute) | 1554 | if (!iexec->execute) |
1554 | return true; | 1555 | return len; |
1555 | 1556 | ||
1556 | BIOSLOG(bios, "0x%04X: Index1: 0x%02X, Index2: 0x%02X, " | 1557 | BIOSLOG(bios, "0x%04X: Index1: 0x%02X, Index2: 0x%02X, " |
1557 | "BaseAddr: 0x%02X, Count: 0x%02X\n", | 1558 | "BaseAddr: 0x%02X, Count: 0x%02X\n", |
@@ -1568,10 +1569,10 @@ init_cr_idx_adr_latch(struct nvbios *bios, uint16_t offset, | |||
1568 | 1569 | ||
1569 | bios_idxprt_wr(bios, NV_CIO_CRX__COLOR, crtcindex1, oldaddr); | 1570 | bios_idxprt_wr(bios, NV_CIO_CRX__COLOR, crtcindex1, oldaddr); |
1570 | 1571 | ||
1571 | return true; | 1572 | return len; |
1572 | } | 1573 | } |
1573 | 1574 | ||
1574 | static bool | 1575 | static int |
1575 | init_cr(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | 1576 | init_cr(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) |
1576 | { | 1577 | { |
1577 | /* | 1578 | /* |
@@ -1592,7 +1593,7 @@ init_cr(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
1592 | uint8_t value; | 1593 | uint8_t value; |
1593 | 1594 | ||
1594 | if (!iexec->execute) | 1595 | if (!iexec->execute) |
1595 | return true; | 1596 | return 4; |
1596 | 1597 | ||
1597 | BIOSLOG(bios, "0x%04X: Index: 0x%02X, Mask: 0x%02X, Data: 0x%02X\n", | 1598 | BIOSLOG(bios, "0x%04X: Index: 0x%02X, Mask: 0x%02X, Data: 0x%02X\n", |
1598 | offset, crtcindex, mask, data); | 1599 | offset, crtcindex, mask, data); |
@@ -1601,10 +1602,10 @@ init_cr(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
1601 | value |= data; | 1602 | value |= data; |
1602 | bios_idxprt_wr(bios, NV_CIO_CRX__COLOR, crtcindex, value); | 1603 | bios_idxprt_wr(bios, NV_CIO_CRX__COLOR, crtcindex, value); |
1603 | 1604 | ||
1604 | return true; | 1605 | return 4; |
1605 | } | 1606 | } |
1606 | 1607 | ||
1607 | static bool | 1608 | static int |
1608 | init_zm_cr(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | 1609 | init_zm_cr(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) |
1609 | { | 1610 | { |
1610 | /* | 1611 | /* |
@@ -1621,14 +1622,14 @@ init_zm_cr(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
1621 | uint8_t data = bios->data[offset + 2]; | 1622 | uint8_t data = bios->data[offset + 2]; |
1622 | 1623 | ||
1623 | if (!iexec->execute) | 1624 | if (!iexec->execute) |
1624 | return true; | 1625 | return 3; |
1625 | 1626 | ||
1626 | bios_idxprt_wr(bios, NV_CIO_CRX__COLOR, crtcindex, data); | 1627 | bios_idxprt_wr(bios, NV_CIO_CRX__COLOR, crtcindex, data); |
1627 | 1628 | ||
1628 | return true; | 1629 | return 3; |
1629 | } | 1630 | } |
1630 | 1631 | ||
1631 | static bool | 1632 | static int |
1632 | init_zm_cr_group(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | 1633 | init_zm_cr_group(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) |
1633 | { | 1634 | { |
1634 | /* | 1635 | /* |
@@ -1645,18 +1646,19 @@ init_zm_cr_group(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
1645 | */ | 1646 | */ |
1646 | 1647 | ||
1647 | uint8_t count = bios->data[offset + 1]; | 1648 | uint8_t count = bios->data[offset + 1]; |
1649 | int len = 2 + count * 2; | ||
1648 | int i; | 1650 | int i; |
1649 | 1651 | ||
1650 | if (!iexec->execute) | 1652 | if (!iexec->execute) |
1651 | return true; | 1653 | return len; |
1652 | 1654 | ||
1653 | for (i = 0; i < count; i++) | 1655 | for (i = 0; i < count; i++) |
1654 | init_zm_cr(bios, offset + 2 + 2 * i - 1, iexec); | 1656 | init_zm_cr(bios, offset + 2 + 2 * i - 1, iexec); |
1655 | 1657 | ||
1656 | return true; | 1658 | return len; |
1657 | } | 1659 | } |
1658 | 1660 | ||
1659 | static bool | 1661 | static int |
1660 | init_condition_time(struct nvbios *bios, uint16_t offset, | 1662 | init_condition_time(struct nvbios *bios, uint16_t offset, |
1661 | struct init_exec *iexec) | 1663 | struct init_exec *iexec) |
1662 | { | 1664 | { |
@@ -1680,7 +1682,7 @@ init_condition_time(struct nvbios *bios, uint16_t offset, | |||
1680 | unsigned cnt; | 1682 | unsigned cnt; |
1681 | 1683 | ||
1682 | if (!iexec->execute) | 1684 | if (!iexec->execute) |
1683 | return true; | 1685 | return 3; |
1684 | 1686 | ||
1685 | if (retries > 100) | 1687 | if (retries > 100) |
1686 | retries = 100; | 1688 | retries = 100; |
@@ -1711,10 +1713,10 @@ init_condition_time(struct nvbios *bios, uint16_t offset, | |||
1711 | iexec->execute = false; | 1713 | iexec->execute = false; |
1712 | } | 1714 | } |
1713 | 1715 | ||
1714 | return true; | 1716 | return 3; |
1715 | } | 1717 | } |
1716 | 1718 | ||
1717 | static bool | 1719 | static int |
1718 | init_zm_reg_sequence(struct nvbios *bios, uint16_t offset, | 1720 | init_zm_reg_sequence(struct nvbios *bios, uint16_t offset, |
1719 | struct init_exec *iexec) | 1721 | struct init_exec *iexec) |
1720 | { | 1722 | { |
@@ -1734,10 +1736,11 @@ init_zm_reg_sequence(struct nvbios *bios, uint16_t offset, | |||
1734 | 1736 | ||
1735 | uint32_t basereg = ROM32(bios->data[offset + 1]); | 1737 | uint32_t basereg = ROM32(bios->data[offset + 1]); |
1736 | uint32_t count = bios->data[offset + 5]; | 1738 | uint32_t count = bios->data[offset + 5]; |
1739 | int len = 6 + count * 4; | ||
1737 | int i; | 1740 | int i; |
1738 | 1741 | ||
1739 | if (!iexec->execute) | 1742 | if (!iexec->execute) |
1740 | return true; | 1743 | return len; |
1741 | 1744 | ||
1742 | BIOSLOG(bios, "0x%04X: BaseReg: 0x%08X, Count: 0x%02X\n", | 1745 | BIOSLOG(bios, "0x%04X: BaseReg: 0x%08X, Count: 0x%02X\n", |
1743 | offset, basereg, count); | 1746 | offset, basereg, count); |
@@ -1749,10 +1752,10 @@ init_zm_reg_sequence(struct nvbios *bios, uint16_t offset, | |||
1749 | bios_wr32(bios, reg, data); | 1752 | bios_wr32(bios, reg, data); |
1750 | } | 1753 | } |
1751 | 1754 | ||
1752 | return true; | 1755 | return len; |
1753 | } | 1756 | } |
1754 | 1757 | ||
1755 | static bool | 1758 | static int |
1756 | init_sub_direct(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | 1759 | init_sub_direct(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) |
1757 | { | 1760 | { |
1758 | /* | 1761 | /* |
@@ -1768,7 +1771,7 @@ init_sub_direct(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
1768 | uint16_t sub_offset = ROM16(bios->data[offset + 1]); | 1771 | uint16_t sub_offset = ROM16(bios->data[offset + 1]); |
1769 | 1772 | ||
1770 | if (!iexec->execute) | 1773 | if (!iexec->execute) |
1771 | return true; | 1774 | return 3; |
1772 | 1775 | ||
1773 | BIOSLOG(bios, "0x%04X: Executing subroutine at 0x%04X\n", | 1776 | BIOSLOG(bios, "0x%04X: Executing subroutine at 0x%04X\n", |
1774 | offset, sub_offset); | 1777 | offset, sub_offset); |
@@ -1777,10 +1780,10 @@ init_sub_direct(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
1777 | 1780 | ||
1778 | BIOSLOG(bios, "0x%04X: End of 0x%04X subroutine\n", offset, sub_offset); | 1781 | BIOSLOG(bios, "0x%04X: End of 0x%04X subroutine\n", offset, sub_offset); |
1779 | 1782 | ||
1780 | return true; | 1783 | return 3; |
1781 | } | 1784 | } |
1782 | 1785 | ||
1783 | static bool | 1786 | static int |
1784 | init_copy_nv_reg(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | 1787 | init_copy_nv_reg(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) |
1785 | { | 1788 | { |
1786 | /* | 1789 | /* |
@@ -1808,7 +1811,7 @@ init_copy_nv_reg(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
1808 | uint32_t srcvalue, dstvalue; | 1811 | uint32_t srcvalue, dstvalue; |
1809 | 1812 | ||
1810 | if (!iexec->execute) | 1813 | if (!iexec->execute) |
1811 | return true; | 1814 | return 22; |
1812 | 1815 | ||
1813 | BIOSLOG(bios, "0x%04X: SrcReg: 0x%08X, Shift: 0x%02X, SrcMask: 0x%08X, " | 1816 | BIOSLOG(bios, "0x%04X: SrcReg: 0x%08X, Shift: 0x%02X, SrcMask: 0x%08X, " |
1814 | "Xor: 0x%08X, DstReg: 0x%08X, DstMask: 0x%08X\n", | 1817 | "Xor: 0x%08X, DstReg: 0x%08X, DstMask: 0x%08X\n", |
@@ -1827,10 +1830,10 @@ init_copy_nv_reg(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
1827 | 1830 | ||
1828 | bios_wr32(bios, dstreg, dstvalue | srcvalue); | 1831 | bios_wr32(bios, dstreg, dstvalue | srcvalue); |
1829 | 1832 | ||
1830 | return true; | 1833 | return 22; |
1831 | } | 1834 | } |
1832 | 1835 | ||
1833 | static bool | 1836 | static int |
1834 | init_zm_index_io(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | 1837 | init_zm_index_io(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) |
1835 | { | 1838 | { |
1836 | /* | 1839 | /* |
@@ -1848,14 +1851,14 @@ init_zm_index_io(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
1848 | uint8_t data = bios->data[offset + 4]; | 1851 | uint8_t data = bios->data[offset + 4]; |
1849 | 1852 | ||
1850 | if (!iexec->execute) | 1853 | if (!iexec->execute) |
1851 | return true; | 1854 | return 5; |
1852 | 1855 | ||
1853 | bios_idxprt_wr(bios, crtcport, crtcindex, data); | 1856 | bios_idxprt_wr(bios, crtcport, crtcindex, data); |
1854 | 1857 | ||
1855 | return true; | 1858 | return 5; |
1856 | } | 1859 | } |
1857 | 1860 | ||
1858 | static bool | 1861 | static int |
1859 | init_compute_mem(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | 1862 | init_compute_mem(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) |
1860 | { | 1863 | { |
1861 | /* | 1864 | /* |
@@ -1904,7 +1907,7 @@ init_compute_mem(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
1904 | struct drm_nouveau_private *dev_priv = bios->dev->dev_private; | 1907 | struct drm_nouveau_private *dev_priv = bios->dev->dev_private; |
1905 | 1908 | ||
1906 | if (dev_priv->card_type >= NV_50) | 1909 | if (dev_priv->card_type >= NV_50) |
1907 | return true; | 1910 | return 1; |
1908 | 1911 | ||
1909 | /* | 1912 | /* |
1910 | * On every card I've seen, this step gets done for us earlier in | 1913 | * On every card I've seen, this step gets done for us earlier in |
@@ -1922,10 +1925,10 @@ init_compute_mem(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
1922 | /* write back the saved configuration value */ | 1925 | /* write back the saved configuration value */ |
1923 | bios_wr32(bios, NV_PFB_CFG0, bios->state.saved_nv_pfb_cfg0); | 1926 | bios_wr32(bios, NV_PFB_CFG0, bios->state.saved_nv_pfb_cfg0); |
1924 | 1927 | ||
1925 | return true; | 1928 | return 1; |
1926 | } | 1929 | } |
1927 | 1930 | ||
1928 | static bool | 1931 | static int |
1929 | init_reset(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | 1932 | init_reset(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) |
1930 | { | 1933 | { |
1931 | /* | 1934 | /* |
@@ -1959,10 +1962,10 @@ init_reset(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
1959 | pci_nv_20 &= ~NV_PBUS_PCI_NV_20_ROM_SHADOW_ENABLED; /* 0xfffffffe */ | 1962 | pci_nv_20 &= ~NV_PBUS_PCI_NV_20_ROM_SHADOW_ENABLED; /* 0xfffffffe */ |
1960 | bios_wr32(bios, NV_PBUS_PCI_NV_20, pci_nv_20); | 1963 | bios_wr32(bios, NV_PBUS_PCI_NV_20, pci_nv_20); |
1961 | 1964 | ||
1962 | return true; | 1965 | return 13; |
1963 | } | 1966 | } |
1964 | 1967 | ||
1965 | static bool | 1968 | static int |
1966 | init_configure_mem(struct nvbios *bios, uint16_t offset, | 1969 | init_configure_mem(struct nvbios *bios, uint16_t offset, |
1967 | struct init_exec *iexec) | 1970 | struct init_exec *iexec) |
1968 | { | 1971 | { |
@@ -1983,7 +1986,7 @@ init_configure_mem(struct nvbios *bios, uint16_t offset, | |||
1983 | uint32_t reg, data; | 1986 | uint32_t reg, data; |
1984 | 1987 | ||
1985 | if (bios->major_version > 2) | 1988 | if (bios->major_version > 2) |
1986 | return false; | 1989 | return 0; |
1987 | 1990 | ||
1988 | bios_idxprt_wr(bios, NV_VIO_SRX, NV_VIO_SR_CLOCK_INDEX, bios_idxprt_rd( | 1991 | bios_idxprt_wr(bios, NV_VIO_SRX, NV_VIO_SR_CLOCK_INDEX, bios_idxprt_rd( |
1989 | bios, NV_VIO_SRX, NV_VIO_SR_CLOCK_INDEX) | 0x20); | 1992 | bios, NV_VIO_SRX, NV_VIO_SR_CLOCK_INDEX) | 0x20); |
@@ -2015,10 +2018,10 @@ init_configure_mem(struct nvbios *bios, uint16_t offset, | |||
2015 | bios_wr32(bios, reg, data); | 2018 | bios_wr32(bios, reg, data); |
2016 | } | 2019 | } |
2017 | 2020 | ||
2018 | return true; | 2021 | return 1; |
2019 | } | 2022 | } |
2020 | 2023 | ||
2021 | static bool | 2024 | static int |
2022 | init_configure_clk(struct nvbios *bios, uint16_t offset, | 2025 | init_configure_clk(struct nvbios *bios, uint16_t offset, |
2023 | struct init_exec *iexec) | 2026 | struct init_exec *iexec) |
2024 | { | 2027 | { |
@@ -2038,7 +2041,7 @@ init_configure_clk(struct nvbios *bios, uint16_t offset, | |||
2038 | int clock; | 2041 | int clock; |
2039 | 2042 | ||
2040 | if (bios->major_version > 2) | 2043 | if (bios->major_version > 2) |
2041 | return false; | 2044 | return 0; |
2042 | 2045 | ||
2043 | clock = ROM16(bios->data[meminitoffs + 4]) * 10; | 2046 | clock = ROM16(bios->data[meminitoffs + 4]) * 10; |
2044 | setPLL(bios, NV_PRAMDAC_NVPLL_COEFF, clock); | 2047 | setPLL(bios, NV_PRAMDAC_NVPLL_COEFF, clock); |
@@ -2048,10 +2051,10 @@ init_configure_clk(struct nvbios *bios, uint16_t offset, | |||
2048 | clock *= 2; | 2051 | clock *= 2; |
2049 | setPLL(bios, NV_PRAMDAC_MPLL_COEFF, clock); | 2052 | setPLL(bios, NV_PRAMDAC_MPLL_COEFF, clock); |
2050 | 2053 | ||
2051 | return true; | 2054 | return 1; |
2052 | } | 2055 | } |
2053 | 2056 | ||
2054 | static bool | 2057 | static int |
2055 | init_configure_preinit(struct nvbios *bios, uint16_t offset, | 2058 | init_configure_preinit(struct nvbios *bios, uint16_t offset, |
2056 | struct init_exec *iexec) | 2059 | struct init_exec *iexec) |
2057 | { | 2060 | { |
@@ -2071,15 +2074,15 @@ init_configure_preinit(struct nvbios *bios, uint16_t offset, | |||
2071 | uint8_t cr3c = ((straps << 2) & 0xf0) | (straps & (1 << 6)); | 2074 | uint8_t cr3c = ((straps << 2) & 0xf0) | (straps & (1 << 6)); |
2072 | 2075 | ||
2073 | if (bios->major_version > 2) | 2076 | if (bios->major_version > 2) |
2074 | return false; | 2077 | return 0; |
2075 | 2078 | ||
2076 | bios_idxprt_wr(bios, NV_CIO_CRX__COLOR, | 2079 | bios_idxprt_wr(bios, NV_CIO_CRX__COLOR, |
2077 | NV_CIO_CRE_SCRATCH4__INDEX, cr3c); | 2080 | NV_CIO_CRE_SCRATCH4__INDEX, cr3c); |
2078 | 2081 | ||
2079 | return true; | 2082 | return 1; |
2080 | } | 2083 | } |
2081 | 2084 | ||
2082 | static bool | 2085 | static int |
2083 | init_io(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | 2086 | init_io(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) |
2084 | { | 2087 | { |
2085 | /* | 2088 | /* |
@@ -2099,7 +2102,7 @@ init_io(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
2099 | uint8_t data = bios->data[offset + 4]; | 2102 | uint8_t data = bios->data[offset + 4]; |
2100 | 2103 | ||
2101 | if (!iexec->execute) | 2104 | if (!iexec->execute) |
2102 | return true; | 2105 | return 5; |
2103 | 2106 | ||
2104 | BIOSLOG(bios, "0x%04X: Port: 0x%04X, Mask: 0x%02X, Data: 0x%02X\n", | 2107 | BIOSLOG(bios, "0x%04X: Port: 0x%04X, Mask: 0x%02X, Data: 0x%02X\n", |
2105 | offset, crtcport, mask, data); | 2108 | offset, crtcport, mask, data); |
@@ -2158,15 +2161,15 @@ init_io(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
2158 | for (i = 0; i < 2; i++) | 2161 | for (i = 0; i < 2; i++) |
2159 | bios_wr32(bios, 0x614108 + (i*0x800), bios_rd32( | 2162 | bios_wr32(bios, 0x614108 + (i*0x800), bios_rd32( |
2160 | bios, 0x614108 + (i*0x800)) & 0x0fffffff); | 2163 | bios, 0x614108 + (i*0x800)) & 0x0fffffff); |
2161 | return true; | 2164 | return 5; |
2162 | } | 2165 | } |
2163 | 2166 | ||
2164 | bios_port_wr(bios, crtcport, (bios_port_rd(bios, crtcport) & mask) | | 2167 | bios_port_wr(bios, crtcport, (bios_port_rd(bios, crtcport) & mask) | |
2165 | data); | 2168 | data); |
2166 | return true; | 2169 | return 5; |
2167 | } | 2170 | } |
2168 | 2171 | ||
2169 | static bool | 2172 | static int |
2170 | init_sub(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | 2173 | init_sub(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) |
2171 | { | 2174 | { |
2172 | /* | 2175 | /* |
@@ -2181,7 +2184,7 @@ init_sub(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
2181 | uint8_t sub = bios->data[offset + 1]; | 2184 | uint8_t sub = bios->data[offset + 1]; |
2182 | 2185 | ||
2183 | if (!iexec->execute) | 2186 | if (!iexec->execute) |
2184 | return true; | 2187 | return 2; |
2185 | 2188 | ||
2186 | BIOSLOG(bios, "0x%04X: Calling script %d\n", offset, sub); | 2189 | BIOSLOG(bios, "0x%04X: Calling script %d\n", offset, sub); |
2187 | 2190 | ||
@@ -2191,10 +2194,10 @@ init_sub(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
2191 | 2194 | ||
2192 | BIOSLOG(bios, "0x%04X: End of script %d\n", offset, sub); | 2195 | BIOSLOG(bios, "0x%04X: End of script %d\n", offset, sub); |
2193 | 2196 | ||
2194 | return true; | 2197 | return 2; |
2195 | } | 2198 | } |
2196 | 2199 | ||
2197 | static bool | 2200 | static int |
2198 | init_ram_condition(struct nvbios *bios, uint16_t offset, | 2201 | init_ram_condition(struct nvbios *bios, uint16_t offset, |
2199 | struct init_exec *iexec) | 2202 | struct init_exec *iexec) |
2200 | { | 2203 | { |
@@ -2215,7 +2218,7 @@ init_ram_condition(struct nvbios *bios, uint16_t offset, | |||
2215 | uint8_t data; | 2218 | uint8_t data; |
2216 | 2219 | ||
2217 | if (!iexec->execute) | 2220 | if (!iexec->execute) |
2218 | return true; | 2221 | return 3; |
2219 | 2222 | ||
2220 | data = bios_rd32(bios, NV_PFB_BOOT_0) & mask; | 2223 | data = bios_rd32(bios, NV_PFB_BOOT_0) & mask; |
2221 | 2224 | ||
@@ -2229,10 +2232,10 @@ init_ram_condition(struct nvbios *bios, uint16_t offset, | |||
2229 | iexec->execute = false; | 2232 | iexec->execute = false; |
2230 | } | 2233 | } |
2231 | 2234 | ||
2232 | return true; | 2235 | return 3; |
2233 | } | 2236 | } |
2234 | 2237 | ||
2235 | static bool | 2238 | static int |
2236 | init_nv_reg(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | 2239 | init_nv_reg(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) |
2237 | { | 2240 | { |
2238 | /* | 2241 | /* |
@@ -2251,17 +2254,17 @@ init_nv_reg(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
2251 | uint32_t data = ROM32(bios->data[offset + 9]); | 2254 | uint32_t data = ROM32(bios->data[offset + 9]); |
2252 | 2255 | ||
2253 | if (!iexec->execute) | 2256 | if (!iexec->execute) |
2254 | return true; | 2257 | return 13; |
2255 | 2258 | ||
2256 | BIOSLOG(bios, "0x%04X: Reg: 0x%08X, Mask: 0x%08X, Data: 0x%08X\n", | 2259 | BIOSLOG(bios, "0x%04X: Reg: 0x%08X, Mask: 0x%08X, Data: 0x%08X\n", |
2257 | offset, reg, mask, data); | 2260 | offset, reg, mask, data); |
2258 | 2261 | ||
2259 | bios_wr32(bios, reg, (bios_rd32(bios, reg) & mask) | data); | 2262 | bios_wr32(bios, reg, (bios_rd32(bios, reg) & mask) | data); |
2260 | 2263 | ||
2261 | return true; | 2264 | return 13; |
2262 | } | 2265 | } |
2263 | 2266 | ||
2264 | static bool | 2267 | static int |
2265 | init_macro(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | 2268 | init_macro(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) |
2266 | { | 2269 | { |
2267 | /* | 2270 | /* |
@@ -2285,7 +2288,7 @@ init_macro(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
2285 | int i; | 2288 | int i; |
2286 | 2289 | ||
2287 | if (!iexec->execute) | 2290 | if (!iexec->execute) |
2288 | return true; | 2291 | return 2; |
2289 | 2292 | ||
2290 | BIOSLOG(bios, "0x%04X: Macro: 0x%02X, MacroTableIndex: 0x%02X, " | 2293 | BIOSLOG(bios, "0x%04X: Macro: 0x%02X, MacroTableIndex: 0x%02X, " |
2291 | "Count: 0x%02X\n", | 2294 | "Count: 0x%02X\n", |
@@ -2300,10 +2303,10 @@ init_macro(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
2300 | bios_wr32(bios, reg, data); | 2303 | bios_wr32(bios, reg, data); |
2301 | } | 2304 | } |
2302 | 2305 | ||
2303 | return true; | 2306 | return 2; |
2304 | } | 2307 | } |
2305 | 2308 | ||
2306 | static bool | 2309 | static int |
2307 | init_done(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | 2310 | init_done(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) |
2308 | { | 2311 | { |
2309 | /* | 2312 | /* |
@@ -2315,10 +2318,10 @@ init_done(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
2315 | */ | 2318 | */ |
2316 | 2319 | ||
2317 | /* mild retval abuse to stop parsing this table */ | 2320 | /* mild retval abuse to stop parsing this table */ |
2318 | return false; | 2321 | return 0; |
2319 | } | 2322 | } |
2320 | 2323 | ||
2321 | static bool | 2324 | static int |
2322 | init_resume(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | 2325 | init_resume(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) |
2323 | { | 2326 | { |
2324 | /* | 2327 | /* |
@@ -2330,15 +2333,15 @@ init_resume(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
2330 | */ | 2333 | */ |
2331 | 2334 | ||
2332 | if (iexec->execute) | 2335 | if (iexec->execute) |
2333 | return true; | 2336 | return 1; |
2334 | 2337 | ||
2335 | iexec->execute = true; | 2338 | iexec->execute = true; |
2336 | BIOSLOG(bios, "0x%04X: ---- Executing following commands ----\n", offset); | 2339 | BIOSLOG(bios, "0x%04X: ---- Executing following commands ----\n", offset); |
2337 | 2340 | ||
2338 | return true; | 2341 | return 1; |
2339 | } | 2342 | } |
2340 | 2343 | ||
2341 | static bool | 2344 | static int |
2342 | init_time(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | 2345 | init_time(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) |
2343 | { | 2346 | { |
2344 | /* | 2347 | /* |
@@ -2353,7 +2356,7 @@ init_time(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
2353 | unsigned time = ROM16(bios->data[offset + 1]); | 2356 | unsigned time = ROM16(bios->data[offset + 1]); |
2354 | 2357 | ||
2355 | if (!iexec->execute) | 2358 | if (!iexec->execute) |
2356 | return true; | 2359 | return 3; |
2357 | 2360 | ||
2358 | BIOSLOG(bios, "0x%04X: Sleeping for 0x%04X microseconds\n", | 2361 | BIOSLOG(bios, "0x%04X: Sleeping for 0x%04X microseconds\n", |
2359 | offset, time); | 2362 | offset, time); |
@@ -2363,10 +2366,10 @@ init_time(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
2363 | else | 2366 | else |
2364 | msleep((time + 900) / 1000); | 2367 | msleep((time + 900) / 1000); |
2365 | 2368 | ||
2366 | return true; | 2369 | return 3; |
2367 | } | 2370 | } |
2368 | 2371 | ||
2369 | static bool | 2372 | static int |
2370 | init_condition(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | 2373 | init_condition(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) |
2371 | { | 2374 | { |
2372 | /* | 2375 | /* |
@@ -2383,7 +2386,7 @@ init_condition(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
2383 | uint8_t cond = bios->data[offset + 1]; | 2386 | uint8_t cond = bios->data[offset + 1]; |
2384 | 2387 | ||
2385 | if (!iexec->execute) | 2388 | if (!iexec->execute) |
2386 | return true; | 2389 | return 2; |
2387 | 2390 | ||
2388 | BIOSLOG(bios, "0x%04X: Condition: 0x%02X\n", offset, cond); | 2391 | BIOSLOG(bios, "0x%04X: Condition: 0x%02X\n", offset, cond); |
2389 | 2392 | ||
@@ -2394,10 +2397,10 @@ init_condition(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
2394 | iexec->execute = false; | 2397 | iexec->execute = false; |
2395 | } | 2398 | } |
2396 | 2399 | ||
2397 | return true; | 2400 | return 2; |
2398 | } | 2401 | } |
2399 | 2402 | ||
2400 | static bool | 2403 | static int |
2401 | init_io_condition(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | 2404 | init_io_condition(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) |
2402 | { | 2405 | { |
2403 | /* | 2406 | /* |
@@ -2414,7 +2417,7 @@ init_io_condition(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
2414 | uint8_t cond = bios->data[offset + 1]; | 2417 | uint8_t cond = bios->data[offset + 1]; |
2415 | 2418 | ||
2416 | if (!iexec->execute) | 2419 | if (!iexec->execute) |
2417 | return true; | 2420 | return 2; |
2418 | 2421 | ||
2419 | BIOSLOG(bios, "0x%04X: IO condition: 0x%02X\n", offset, cond); | 2422 | BIOSLOG(bios, "0x%04X: IO condition: 0x%02X\n", offset, cond); |
2420 | 2423 | ||
@@ -2425,10 +2428,10 @@ init_io_condition(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
2425 | iexec->execute = false; | 2428 | iexec->execute = false; |
2426 | } | 2429 | } |
2427 | 2430 | ||
2428 | return true; | 2431 | return 2; |
2429 | } | 2432 | } |
2430 | 2433 | ||
2431 | static bool | 2434 | static int |
2432 | init_index_io(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | 2435 | init_index_io(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) |
2433 | { | 2436 | { |
2434 | /* | 2437 | /* |
@@ -2451,7 +2454,7 @@ init_index_io(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
2451 | uint8_t value; | 2454 | uint8_t value; |
2452 | 2455 | ||
2453 | if (!iexec->execute) | 2456 | if (!iexec->execute) |
2454 | return true; | 2457 | return 6; |
2455 | 2458 | ||
2456 | BIOSLOG(bios, "0x%04X: Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X, " | 2459 | BIOSLOG(bios, "0x%04X: Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X, " |
2457 | "Data: 0x%02X\n", | 2460 | "Data: 0x%02X\n", |
@@ -2460,10 +2463,10 @@ init_index_io(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
2460 | value = (bios_idxprt_rd(bios, crtcport, crtcindex) & mask) | data; | 2463 | value = (bios_idxprt_rd(bios, crtcport, crtcindex) & mask) | data; |
2461 | bios_idxprt_wr(bios, crtcport, crtcindex, value); | 2464 | bios_idxprt_wr(bios, crtcport, crtcindex, value); |
2462 | 2465 | ||
2463 | return true; | 2466 | return 6; |
2464 | } | 2467 | } |
2465 | 2468 | ||
2466 | static bool | 2469 | static int |
2467 | init_pll(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | 2470 | init_pll(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) |
2468 | { | 2471 | { |
2469 | /* | 2472 | /* |
@@ -2481,16 +2484,16 @@ init_pll(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
2481 | uint16_t freq = ROM16(bios->data[offset + 5]); | 2484 | uint16_t freq = ROM16(bios->data[offset + 5]); |
2482 | 2485 | ||
2483 | if (!iexec->execute) | 2486 | if (!iexec->execute) |
2484 | return true; | 2487 | return 7; |
2485 | 2488 | ||
2486 | BIOSLOG(bios, "0x%04X: Reg: 0x%08X, Freq: %d0kHz\n", offset, reg, freq); | 2489 | BIOSLOG(bios, "0x%04X: Reg: 0x%08X, Freq: %d0kHz\n", offset, reg, freq); |
2487 | 2490 | ||
2488 | setPLL(bios, reg, freq * 10); | 2491 | setPLL(bios, reg, freq * 10); |
2489 | 2492 | ||
2490 | return true; | 2493 | return 7; |
2491 | } | 2494 | } |
2492 | 2495 | ||
2493 | static bool | 2496 | static int |
2494 | init_zm_reg(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | 2497 | init_zm_reg(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) |
2495 | { | 2498 | { |
2496 | /* | 2499 | /* |
@@ -2507,17 +2510,17 @@ init_zm_reg(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
2507 | uint32_t value = ROM32(bios->data[offset + 5]); | 2510 | uint32_t value = ROM32(bios->data[offset + 5]); |
2508 | 2511 | ||
2509 | if (!iexec->execute) | 2512 | if (!iexec->execute) |
2510 | return true; | 2513 | return 9; |
2511 | 2514 | ||
2512 | if (reg == 0x000200) | 2515 | if (reg == 0x000200) |
2513 | value |= 1; | 2516 | value |= 1; |
2514 | 2517 | ||
2515 | bios_wr32(bios, reg, value); | 2518 | bios_wr32(bios, reg, value); |
2516 | 2519 | ||
2517 | return true; | 2520 | return 9; |
2518 | } | 2521 | } |
2519 | 2522 | ||
2520 | static bool | 2523 | static int |
2521 | init_ram_restrict_pll(struct nvbios *bios, uint16_t offset, | 2524 | init_ram_restrict_pll(struct nvbios *bios, uint16_t offset, |
2522 | struct init_exec *iexec) | 2525 | struct init_exec *iexec) |
2523 | { | 2526 | { |
@@ -2543,14 +2546,15 @@ init_ram_restrict_pll(struct nvbios *bios, uint16_t offset, | |||
2543 | uint8_t type = bios->data[offset + 1]; | 2546 | uint8_t type = bios->data[offset + 1]; |
2544 | uint32_t freq = ROM32(bios->data[offset + 2 + (index * 4)]); | 2547 | uint32_t freq = ROM32(bios->data[offset + 2 + (index * 4)]); |
2545 | uint8_t *pll_limits = &bios->data[bios->pll_limit_tbl_ptr], *entry; | 2548 | uint8_t *pll_limits = &bios->data[bios->pll_limit_tbl_ptr], *entry; |
2549 | int len = 2 + bios->ram_restrict_group_count * 4; | ||
2546 | int i; | 2550 | int i; |
2547 | 2551 | ||
2548 | if (!iexec->execute) | 2552 | if (!iexec->execute) |
2549 | return true; | 2553 | return len; |
2550 | 2554 | ||
2551 | if (!bios->pll_limit_tbl_ptr || (pll_limits[0] & 0xf0) != 0x30) { | 2555 | if (!bios->pll_limit_tbl_ptr || (pll_limits[0] & 0xf0) != 0x30) { |
2552 | NV_ERROR(dev, "PLL limits table not version 3.x\n"); | 2556 | NV_ERROR(dev, "PLL limits table not version 3.x\n"); |
2553 | return true; /* deliberate, allow default clocks to remain */ | 2557 | return len; /* deliberate, allow default clocks to remain */ |
2554 | } | 2558 | } |
2555 | 2559 | ||
2556 | entry = pll_limits + pll_limits[1]; | 2560 | entry = pll_limits + pll_limits[1]; |
@@ -2563,15 +2567,15 @@ init_ram_restrict_pll(struct nvbios *bios, uint16_t offset, | |||
2563 | offset, type, reg, freq); | 2567 | offset, type, reg, freq); |
2564 | 2568 | ||
2565 | setPLL(bios, reg, freq); | 2569 | setPLL(bios, reg, freq); |
2566 | return true; | 2570 | return len; |
2567 | } | 2571 | } |
2568 | } | 2572 | } |
2569 | 2573 | ||
2570 | NV_ERROR(dev, "PLL type 0x%02x not found in PLL limits table", type); | 2574 | NV_ERROR(dev, "PLL type 0x%02x not found in PLL limits table", type); |
2571 | return true; | 2575 | return len; |
2572 | } | 2576 | } |
2573 | 2577 | ||
2574 | static bool | 2578 | static int |
2575 | init_8c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | 2579 | init_8c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) |
2576 | { | 2580 | { |
2577 | /* | 2581 | /* |
@@ -2581,10 +2585,10 @@ init_8c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
2581 | * | 2585 | * |
2582 | */ | 2586 | */ |
2583 | 2587 | ||
2584 | return true; | 2588 | return 1; |
2585 | } | 2589 | } |
2586 | 2590 | ||
2587 | static bool | 2591 | static int |
2588 | init_8d(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | 2592 | init_8d(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) |
2589 | { | 2593 | { |
2590 | /* | 2594 | /* |
@@ -2594,10 +2598,10 @@ init_8d(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
2594 | * | 2598 | * |
2595 | */ | 2599 | */ |
2596 | 2600 | ||
2597 | return true; | 2601 | return 1; |
2598 | } | 2602 | } |
2599 | 2603 | ||
2600 | static bool | 2604 | static int |
2601 | init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | 2605 | init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) |
2602 | { | 2606 | { |
2603 | /* | 2607 | /* |
@@ -2615,14 +2619,17 @@ init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
2615 | const uint8_t *gpio_entry; | 2619 | const uint8_t *gpio_entry; |
2616 | int i; | 2620 | int i; |
2617 | 2621 | ||
2622 | if (!iexec->execute) | ||
2623 | return 1; | ||
2624 | |||
2618 | if (bios->bdcb.version != 0x40) { | 2625 | if (bios->bdcb.version != 0x40) { |
2619 | NV_ERROR(bios->dev, "DCB table not version 4.0\n"); | 2626 | NV_ERROR(bios->dev, "DCB table not version 4.0\n"); |
2620 | return false; | 2627 | return 0; |
2621 | } | 2628 | } |
2622 | 2629 | ||
2623 | if (!bios->bdcb.gpio_table_ptr) { | 2630 | if (!bios->bdcb.gpio_table_ptr) { |
2624 | NV_WARN(bios->dev, "Invalid pointer to INIT_8E table\n"); | 2631 | NV_WARN(bios->dev, "Invalid pointer to INIT_8E table\n"); |
2625 | return false; | 2632 | return 0; |
2626 | } | 2633 | } |
2627 | 2634 | ||
2628 | gpio_entry = gpio_table + gpio_table[1]; | 2635 | gpio_entry = gpio_table + gpio_table[1]; |
@@ -2660,13 +2667,10 @@ init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
2660 | bios_wr32(bios, r, v); | 2667 | bios_wr32(bios, r, v); |
2661 | } | 2668 | } |
2662 | 2669 | ||
2663 | return true; | 2670 | return 1; |
2664 | } | 2671 | } |
2665 | 2672 | ||
2666 | /* hack to avoid moving the itbl_entry array before this function */ | 2673 | static int |
2667 | int init_ram_restrict_zm_reg_group_blocklen; | ||
2668 | |||
2669 | static bool | ||
2670 | init_ram_restrict_zm_reg_group(struct nvbios *bios, uint16_t offset, | 2674 | init_ram_restrict_zm_reg_group(struct nvbios *bios, uint16_t offset, |
2671 | struct init_exec *iexec) | 2675 | struct init_exec *iexec) |
2672 | { | 2676 | { |
@@ -2692,21 +2696,21 @@ init_ram_restrict_zm_reg_group(struct nvbios *bios, uint16_t offset, | |||
2692 | uint8_t regincrement = bios->data[offset + 5]; | 2696 | uint8_t regincrement = bios->data[offset + 5]; |
2693 | uint8_t count = bios->data[offset + 6]; | 2697 | uint8_t count = bios->data[offset + 6]; |
2694 | uint32_t strap_ramcfg, data; | 2698 | uint32_t strap_ramcfg, data; |
2695 | uint16_t blocklen; | 2699 | /* previously set by 'M' BIT table */ |
2700 | uint16_t blocklen = bios->ram_restrict_group_count * 4; | ||
2701 | int len = 7 + count * blocklen; | ||
2696 | uint8_t index; | 2702 | uint8_t index; |
2697 | int i; | 2703 | int i; |
2698 | 2704 | ||
2699 | /* previously set by 'M' BIT table */ | ||
2700 | blocklen = init_ram_restrict_zm_reg_group_blocklen; | ||
2701 | 2705 | ||
2702 | if (!iexec->execute) | 2706 | if (!iexec->execute) |
2703 | return true; | 2707 | return len; |
2704 | 2708 | ||
2705 | if (!blocklen) { | 2709 | if (!blocklen) { |
2706 | NV_ERROR(bios->dev, | 2710 | NV_ERROR(bios->dev, |
2707 | "0x%04X: Zero block length - has the M table " | 2711 | "0x%04X: Zero block length - has the M table " |
2708 | "been parsed?\n", offset); | 2712 | "been parsed?\n", offset); |
2709 | return false; | 2713 | return 0; |
2710 | } | 2714 | } |
2711 | 2715 | ||
2712 | strap_ramcfg = (bios_rd32(bios, NV_PEXTDEV_BOOT_0) >> 2) & 0xf; | 2716 | strap_ramcfg = (bios_rd32(bios, NV_PEXTDEV_BOOT_0) >> 2) & 0xf; |
@@ -2724,10 +2728,10 @@ init_ram_restrict_zm_reg_group(struct nvbios *bios, uint16_t offset, | |||
2724 | reg += regincrement; | 2728 | reg += regincrement; |
2725 | } | 2729 | } |
2726 | 2730 | ||
2727 | return true; | 2731 | return len; |
2728 | } | 2732 | } |
2729 | 2733 | ||
2730 | static bool | 2734 | static int |
2731 | init_copy_zm_reg(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | 2735 | init_copy_zm_reg(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) |
2732 | { | 2736 | { |
2733 | /* | 2737 | /* |
@@ -2744,14 +2748,14 @@ init_copy_zm_reg(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
2744 | uint32_t dstreg = ROM32(bios->data[offset + 5]); | 2748 | uint32_t dstreg = ROM32(bios->data[offset + 5]); |
2745 | 2749 | ||
2746 | if (!iexec->execute) | 2750 | if (!iexec->execute) |
2747 | return true; | 2751 | return 9; |
2748 | 2752 | ||
2749 | bios_wr32(bios, dstreg, bios_rd32(bios, srcreg)); | 2753 | bios_wr32(bios, dstreg, bios_rd32(bios, srcreg)); |
2750 | 2754 | ||
2751 | return true; | 2755 | return 9; |
2752 | } | 2756 | } |
2753 | 2757 | ||
2754 | static bool | 2758 | static int |
2755 | init_zm_reg_group_addr_latched(struct nvbios *bios, uint16_t offset, | 2759 | init_zm_reg_group_addr_latched(struct nvbios *bios, uint16_t offset, |
2756 | struct init_exec *iexec) | 2760 | struct init_exec *iexec) |
2757 | { | 2761 | { |
@@ -2769,20 +2773,21 @@ init_zm_reg_group_addr_latched(struct nvbios *bios, uint16_t offset, | |||
2769 | 2773 | ||
2770 | uint32_t reg = ROM32(bios->data[offset + 1]); | 2774 | uint32_t reg = ROM32(bios->data[offset + 1]); |
2771 | uint8_t count = bios->data[offset + 5]; | 2775 | uint8_t count = bios->data[offset + 5]; |
2776 | int len = 6 + count * 4; | ||
2772 | int i; | 2777 | int i; |
2773 | 2778 | ||
2774 | if (!iexec->execute) | 2779 | if (!iexec->execute) |
2775 | return true; | 2780 | return len; |
2776 | 2781 | ||
2777 | for (i = 0; i < count; i++) { | 2782 | for (i = 0; i < count; i++) { |
2778 | uint32_t data = ROM32(bios->data[offset + 6 + 4 * i]); | 2783 | uint32_t data = ROM32(bios->data[offset + 6 + 4 * i]); |
2779 | bios_wr32(bios, reg, data); | 2784 | bios_wr32(bios, reg, data); |
2780 | } | 2785 | } |
2781 | 2786 | ||
2782 | return true; | 2787 | return len; |
2783 | } | 2788 | } |
2784 | 2789 | ||
2785 | static bool | 2790 | static int |
2786 | init_reserved(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | 2791 | init_reserved(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) |
2787 | { | 2792 | { |
2788 | /* | 2793 | /* |
@@ -2793,10 +2798,10 @@ init_reserved(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
2793 | * Seemingly does nothing | 2798 | * Seemingly does nothing |
2794 | */ | 2799 | */ |
2795 | 2800 | ||
2796 | return true; | 2801 | return 1; |
2797 | } | 2802 | } |
2798 | 2803 | ||
2799 | static bool | 2804 | static int |
2800 | init_96(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | 2805 | init_96(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) |
2801 | { | 2806 | { |
2802 | /* | 2807 | /* |
@@ -2829,13 +2834,13 @@ init_96(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
2829 | val <<= bios->data[offset + 16]; | 2834 | val <<= bios->data[offset + 16]; |
2830 | 2835 | ||
2831 | if (!iexec->execute) | 2836 | if (!iexec->execute) |
2832 | return true; | 2837 | return 17; |
2833 | 2838 | ||
2834 | bios_wr32(bios, reg, (bios_rd32(bios, reg) & mask) | val); | 2839 | bios_wr32(bios, reg, (bios_rd32(bios, reg) & mask) | val); |
2835 | return true; | 2840 | return 17; |
2836 | } | 2841 | } |
2837 | 2842 | ||
2838 | static bool | 2843 | static int |
2839 | init_97(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | 2844 | init_97(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) |
2840 | { | 2845 | { |
2841 | /* | 2846 | /* |
@@ -2859,13 +2864,13 @@ init_97(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
2859 | val = (val & mask) | ((val + add) & ~mask); | 2864 | val = (val & mask) | ((val + add) & ~mask); |
2860 | 2865 | ||
2861 | if (!iexec->execute) | 2866 | if (!iexec->execute) |
2862 | return true; | 2867 | return 13; |
2863 | 2868 | ||
2864 | bios_wr32(bios, reg, val); | 2869 | bios_wr32(bios, reg, val); |
2865 | return true; | 2870 | return 13; |
2866 | } | 2871 | } |
2867 | 2872 | ||
2868 | static bool | 2873 | static int |
2869 | init_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | 2874 | init_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) |
2870 | { | 2875 | { |
2871 | /* | 2876 | /* |
@@ -2883,32 +2888,33 @@ init_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
2883 | struct drm_device *dev = bios->dev; | 2888 | struct drm_device *dev = bios->dev; |
2884 | struct nouveau_i2c_chan *auxch; | 2889 | struct nouveau_i2c_chan *auxch; |
2885 | uint32_t addr = ROM32(bios->data[offset + 1]); | 2890 | uint32_t addr = ROM32(bios->data[offset + 1]); |
2886 | uint8_t len = bios->data[offset + 5]; | 2891 | uint8_t count = bios->data[offset + 5]; |
2892 | int len = 6 + count * 2; | ||
2887 | int ret, i; | 2893 | int ret, i; |
2888 | 2894 | ||
2889 | if (!bios->display.output) { | 2895 | if (!bios->display.output) { |
2890 | NV_ERROR(dev, "INIT_AUXCH: no active output\n"); | 2896 | NV_ERROR(dev, "INIT_AUXCH: no active output\n"); |
2891 | return false; | 2897 | return 0; |
2892 | } | 2898 | } |
2893 | 2899 | ||
2894 | auxch = init_i2c_device_find(dev, bios->display.output->i2c_index); | 2900 | auxch = init_i2c_device_find(dev, bios->display.output->i2c_index); |
2895 | if (!auxch) { | 2901 | if (!auxch) { |
2896 | NV_ERROR(dev, "INIT_AUXCH: couldn't get auxch %d\n", | 2902 | NV_ERROR(dev, "INIT_AUXCH: couldn't get auxch %d\n", |
2897 | bios->display.output->i2c_index); | 2903 | bios->display.output->i2c_index); |
2898 | return false; | 2904 | return 0; |
2899 | } | 2905 | } |
2900 | 2906 | ||
2901 | if (!iexec->execute) | 2907 | if (!iexec->execute) |
2902 | return true; | 2908 | return len; |
2903 | 2909 | ||
2904 | offset += 6; | 2910 | offset += 6; |
2905 | for (i = 0; i < len; i++, offset += 2) { | 2911 | for (i = 0; i < count; i++, offset += 2) { |
2906 | uint8_t data; | 2912 | uint8_t data; |
2907 | 2913 | ||
2908 | ret = nouveau_dp_auxch(auxch, 9, addr, &data, 1); | 2914 | ret = nouveau_dp_auxch(auxch, 9, addr, &data, 1); |
2909 | if (ret) { | 2915 | if (ret) { |
2910 | NV_ERROR(dev, "INIT_AUXCH: rd auxch fail %d\n", ret); | 2916 | NV_ERROR(dev, "INIT_AUXCH: rd auxch fail %d\n", ret); |
2911 | return false; | 2917 | return 0; |
2912 | } | 2918 | } |
2913 | 2919 | ||
2914 | data &= bios->data[offset + 0]; | 2920 | data &= bios->data[offset + 0]; |
@@ -2917,14 +2923,14 @@ init_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
2917 | ret = nouveau_dp_auxch(auxch, 8, addr, &data, 1); | 2923 | ret = nouveau_dp_auxch(auxch, 8, addr, &data, 1); |
2918 | if (ret) { | 2924 | if (ret) { |
2919 | NV_ERROR(dev, "INIT_AUXCH: wr auxch fail %d\n", ret); | 2925 | NV_ERROR(dev, "INIT_AUXCH: wr auxch fail %d\n", ret); |
2920 | return false; | 2926 | return 0; |
2921 | } | 2927 | } |
2922 | } | 2928 | } |
2923 | 2929 | ||
2924 | return true; | 2930 | return len; |
2925 | } | 2931 | } |
2926 | 2932 | ||
2927 | static bool | 2933 | static int |
2928 | init_zm_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | 2934 | init_zm_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) |
2929 | { | 2935 | { |
2930 | /* | 2936 | /* |
@@ -2941,106 +2947,99 @@ init_zm_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
2941 | struct drm_device *dev = bios->dev; | 2947 | struct drm_device *dev = bios->dev; |
2942 | struct nouveau_i2c_chan *auxch; | 2948 | struct nouveau_i2c_chan *auxch; |
2943 | uint32_t addr = ROM32(bios->data[offset + 1]); | 2949 | uint32_t addr = ROM32(bios->data[offset + 1]); |
2944 | uint8_t len = bios->data[offset + 5]; | 2950 | uint8_t count = bios->data[offset + 5]; |
2951 | int len = 6 + count; | ||
2945 | int ret, i; | 2952 | int ret, i; |
2946 | 2953 | ||
2947 | if (!bios->display.output) { | 2954 | if (!bios->display.output) { |
2948 | NV_ERROR(dev, "INIT_ZM_AUXCH: no active output\n"); | 2955 | NV_ERROR(dev, "INIT_ZM_AUXCH: no active output\n"); |
2949 | return false; | 2956 | return 0; |
2950 | } | 2957 | } |
2951 | 2958 | ||
2952 | auxch = init_i2c_device_find(dev, bios->display.output->i2c_index); | 2959 | auxch = init_i2c_device_find(dev, bios->display.output->i2c_index); |
2953 | if (!auxch) { | 2960 | if (!auxch) { |
2954 | NV_ERROR(dev, "INIT_ZM_AUXCH: couldn't get auxch %d\n", | 2961 | NV_ERROR(dev, "INIT_ZM_AUXCH: couldn't get auxch %d\n", |
2955 | bios->display.output->i2c_index); | 2962 | bios->display.output->i2c_index); |
2956 | return false; | 2963 | return 0; |
2957 | } | 2964 | } |
2958 | 2965 | ||
2959 | if (!iexec->execute) | 2966 | if (!iexec->execute) |
2960 | return true; | 2967 | return len; |
2961 | 2968 | ||
2962 | offset += 6; | 2969 | offset += 6; |
2963 | for (i = 0; i < len; i++, offset++) { | 2970 | for (i = 0; i < count; i++, offset++) { |
2964 | ret = nouveau_dp_auxch(auxch, 8, addr, &bios->data[offset], 1); | 2971 | ret = nouveau_dp_auxch(auxch, 8, addr, &bios->data[offset], 1); |
2965 | if (ret) { | 2972 | if (ret) { |
2966 | NV_ERROR(dev, "INIT_ZM_AUXCH: wr auxch fail %d\n", ret); | 2973 | NV_ERROR(dev, "INIT_ZM_AUXCH: wr auxch fail %d\n", ret); |
2967 | return false; | 2974 | return 0; |
2968 | } | 2975 | } |
2969 | } | 2976 | } |
2970 | 2977 | ||
2971 | return true; | 2978 | return len; |
2972 | } | 2979 | } |
2973 | 2980 | ||
2974 | static struct init_tbl_entry itbl_entry[] = { | 2981 | static struct init_tbl_entry itbl_entry[] = { |
2975 | /* command name , id , length , offset , mult , command handler */ | 2982 | /* command name , id , length , offset , mult , command handler */ |
2976 | /* INIT_PROG (0x31, 15, 10, 4) removed due to no example of use */ | 2983 | /* INIT_PROG (0x31, 15, 10, 4) removed due to no example of use */ |
2977 | { "INIT_IO_RESTRICT_PROG" , 0x32, 11 , 6 , 4 , init_io_restrict_prog }, | 2984 | { "INIT_IO_RESTRICT_PROG" , 0x32, init_io_restrict_prog }, |
2978 | { "INIT_REPEAT" , 0x33, 2 , 0 , 0 , init_repeat }, | 2985 | { "INIT_REPEAT" , 0x33, init_repeat }, |
2979 | { "INIT_IO_RESTRICT_PLL" , 0x34, 12 , 7 , 2 , init_io_restrict_pll }, | 2986 | { "INIT_IO_RESTRICT_PLL" , 0x34, init_io_restrict_pll }, |
2980 | { "INIT_END_REPEAT" , 0x36, 1 , 0 , 0 , init_end_repeat }, | 2987 | { "INIT_END_REPEAT" , 0x36, init_end_repeat }, |
2981 | { "INIT_COPY" , 0x37, 11 , 0 , 0 , init_copy }, | 2988 | { "INIT_COPY" , 0x37, init_copy }, |
2982 | { "INIT_NOT" , 0x38, 1 , 0 , 0 , init_not }, | 2989 | { "INIT_NOT" , 0x38, init_not }, |
2983 | { "INIT_IO_FLAG_CONDITION" , 0x39, 2 , 0 , 0 , init_io_flag_condition }, | 2990 | { "INIT_IO_FLAG_CONDITION" , 0x39, init_io_flag_condition }, |
2984 | { "INIT_INDEX_ADDRESS_LATCHED" , 0x49, 18 , 17 , 2 , init_idx_addr_latched }, | 2991 | { "INIT_INDEX_ADDRESS_LATCHED" , 0x49, init_idx_addr_latched }, |
2985 | { "INIT_IO_RESTRICT_PLL2" , 0x4A, 11 , 6 , 4 , init_io_restrict_pll2 }, | 2992 | { "INIT_IO_RESTRICT_PLL2" , 0x4A, init_io_restrict_pll2 }, |
2986 | { "INIT_PLL2" , 0x4B, 9 , 0 , 0 , init_pll2 }, | 2993 | { "INIT_PLL2" , 0x4B, init_pll2 }, |
2987 | { "INIT_I2C_BYTE" , 0x4C, 4 , 3 , 3 , init_i2c_byte }, | 2994 | { "INIT_I2C_BYTE" , 0x4C, init_i2c_byte }, |
2988 | { "INIT_ZM_I2C_BYTE" , 0x4D, 4 , 3 , 2 , init_zm_i2c_byte }, | 2995 | { "INIT_ZM_I2C_BYTE" , 0x4D, init_zm_i2c_byte }, |
2989 | { "INIT_ZM_I2C" , 0x4E, 4 , 3 , 1 , init_zm_i2c }, | 2996 | { "INIT_ZM_I2C" , 0x4E, init_zm_i2c }, |
2990 | { "INIT_TMDS" , 0x4F, 5 , 0 , 0 , init_tmds }, | 2997 | { "INIT_TMDS" , 0x4F, init_tmds }, |
2991 | { "INIT_ZM_TMDS_GROUP" , 0x50, 3 , 2 , 2 , init_zm_tmds_group }, | 2998 | { "INIT_ZM_TMDS_GROUP" , 0x50, init_zm_tmds_group }, |
2992 | { "INIT_CR_INDEX_ADDRESS_LATCHED" , 0x51, 5 , 4 , 1 , init_cr_idx_adr_latch }, | 2999 | { "INIT_CR_INDEX_ADDRESS_LATCHED" , 0x51, init_cr_idx_adr_latch }, |
2993 | { "INIT_CR" , 0x52, 4 , 0 , 0 , init_cr }, | 3000 | { "INIT_CR" , 0x52, init_cr }, |
2994 | { "INIT_ZM_CR" , 0x53, 3 , 0 , 0 , init_zm_cr }, | 3001 | { "INIT_ZM_CR" , 0x53, init_zm_cr }, |
2995 | { "INIT_ZM_CR_GROUP" , 0x54, 2 , 1 , 2 , init_zm_cr_group }, | 3002 | { "INIT_ZM_CR_GROUP" , 0x54, init_zm_cr_group }, |
2996 | { "INIT_CONDITION_TIME" , 0x56, 3 , 0 , 0 , init_condition_time }, | 3003 | { "INIT_CONDITION_TIME" , 0x56, init_condition_time }, |
2997 | { "INIT_ZM_REG_SEQUENCE" , 0x58, 6 , 5 , 4 , init_zm_reg_sequence }, | 3004 | { "INIT_ZM_REG_SEQUENCE" , 0x58, init_zm_reg_sequence }, |
2998 | /* INIT_INDIRECT_REG (0x5A, 7, 0, 0) removed due to no example of use */ | 3005 | /* INIT_INDIRECT_REG (0x5A, 7, 0, 0) removed due to no example of use */ |
2999 | { "INIT_SUB_DIRECT" , 0x5B, 3 , 0 , 0 , init_sub_direct }, | 3006 | { "INIT_SUB_DIRECT" , 0x5B, init_sub_direct }, |
3000 | { "INIT_COPY_NV_REG" , 0x5F, 22 , 0 , 0 , init_copy_nv_reg }, | 3007 | { "INIT_COPY_NV_REG" , 0x5F, init_copy_nv_reg }, |
3001 | { "INIT_ZM_INDEX_IO" , 0x62, 5 , 0 , 0 , init_zm_index_io }, | 3008 | { "INIT_ZM_INDEX_IO" , 0x62, init_zm_index_io }, |
3002 | { "INIT_COMPUTE_MEM" , 0x63, 1 , 0 , 0 , init_compute_mem }, | 3009 | { "INIT_COMPUTE_MEM" , 0x63, init_compute_mem }, |
3003 | { "INIT_RESET" , 0x65, 13 , 0 , 0 , init_reset }, | 3010 | { "INIT_RESET" , 0x65, init_reset }, |
3004 | { "INIT_CONFIGURE_MEM" , 0x66, 1 , 0 , 0 , init_configure_mem }, | 3011 | { "INIT_CONFIGURE_MEM" , 0x66, init_configure_mem }, |
3005 | { "INIT_CONFIGURE_CLK" , 0x67, 1 , 0 , 0 , init_configure_clk }, | 3012 | { "INIT_CONFIGURE_CLK" , 0x67, init_configure_clk }, |
3006 | { "INIT_CONFIGURE_PREINIT" , 0x68, 1 , 0 , 0 , init_configure_preinit }, | 3013 | { "INIT_CONFIGURE_PREINIT" , 0x68, init_configure_preinit }, |
3007 | { "INIT_IO" , 0x69, 5 , 0 , 0 , init_io }, | 3014 | { "INIT_IO" , 0x69, init_io }, |
3008 | { "INIT_SUB" , 0x6B, 2 , 0 , 0 , init_sub }, | 3015 | { "INIT_SUB" , 0x6B, init_sub }, |
3009 | { "INIT_RAM_CONDITION" , 0x6D, 3 , 0 , 0 , init_ram_condition }, | 3016 | { "INIT_RAM_CONDITION" , 0x6D, init_ram_condition }, |
3010 | { "INIT_NV_REG" , 0x6E, 13 , 0 , 0 , init_nv_reg }, | 3017 | { "INIT_NV_REG" , 0x6E, init_nv_reg }, |
3011 | { "INIT_MACRO" , 0x6F, 2 , 0 , 0 , init_macro }, | 3018 | { "INIT_MACRO" , 0x6F, init_macro }, |
3012 | { "INIT_DONE" , 0x71, 1 , 0 , 0 , init_done }, | 3019 | { "INIT_DONE" , 0x71, init_done }, |
3013 | { "INIT_RESUME" , 0x72, 1 , 0 , 0 , init_resume }, | 3020 | { "INIT_RESUME" , 0x72, init_resume }, |
3014 | /* INIT_RAM_CONDITION2 (0x73, 9, 0, 0) removed due to no example of use */ | 3021 | /* INIT_RAM_CONDITION2 (0x73, 9, 0, 0) removed due to no example of use */ |
3015 | { "INIT_TIME" , 0x74, 3 , 0 , 0 , init_time }, | 3022 | { "INIT_TIME" , 0x74, init_time }, |
3016 | { "INIT_CONDITION" , 0x75, 2 , 0 , 0 , init_condition }, | 3023 | { "INIT_CONDITION" , 0x75, init_condition }, |
3017 | { "INIT_IO_CONDITION" , 0x76, 2 , 0 , 0 , init_io_condition }, | 3024 | { "INIT_IO_CONDITION" , 0x76, init_io_condition }, |
3018 | { "INIT_INDEX_IO" , 0x78, 6 , 0 , 0 , init_index_io }, | 3025 | { "INIT_INDEX_IO" , 0x78, init_index_io }, |
3019 | { "INIT_PLL" , 0x79, 7 , 0 , 0 , init_pll }, | 3026 | { "INIT_PLL" , 0x79, init_pll }, |
3020 | { "INIT_ZM_REG" , 0x7A, 9 , 0 , 0 , init_zm_reg }, | 3027 | { "INIT_ZM_REG" , 0x7A, init_zm_reg }, |
3021 | /* INIT_RAM_RESTRICT_PLL's length is adjusted by the BIT M table */ | 3028 | { "INIT_RAM_RESTRICT_PLL" , 0x87, init_ram_restrict_pll }, |
3022 | { "INIT_RAM_RESTRICT_PLL" , 0x87, 2 , 0 , 0 , init_ram_restrict_pll }, | 3029 | { "INIT_8C" , 0x8C, init_8c }, |
3023 | { "INIT_8C" , 0x8C, 1 , 0 , 0 , init_8c }, | 3030 | { "INIT_8D" , 0x8D, init_8d }, |
3024 | { "INIT_8D" , 0x8D, 1 , 0 , 0 , init_8d }, | 3031 | { "INIT_GPIO" , 0x8E, init_gpio }, |
3025 | { "INIT_GPIO" , 0x8E, 1 , 0 , 0 , init_gpio }, | 3032 | { "INIT_RAM_RESTRICT_ZM_REG_GROUP" , 0x8F, init_ram_restrict_zm_reg_group }, |
3026 | /* INIT_RAM_RESTRICT_ZM_REG_GROUP's mult is loaded by M table in BIT */ | 3033 | { "INIT_COPY_ZM_REG" , 0x90, init_copy_zm_reg }, |
3027 | { "INIT_RAM_RESTRICT_ZM_REG_GROUP" , 0x8F, 7 , 6 , 0 , init_ram_restrict_zm_reg_group }, | 3034 | { "INIT_ZM_REG_GROUP_ADDRESS_LATCHED" , 0x91, init_zm_reg_group_addr_latched }, |
3028 | { "INIT_COPY_ZM_REG" , 0x90, 9 , 0 , 0 , init_copy_zm_reg }, | 3035 | { "INIT_RESERVED" , 0x92, init_reserved }, |
3029 | { "INIT_ZM_REG_GROUP_ADDRESS_LATCHED" , 0x91, 6 , 5 , 4 , init_zm_reg_group_addr_latched }, | 3036 | { "INIT_96" , 0x96, init_96 }, |
3030 | { "INIT_RESERVED" , 0x92, 1 , 0 , 0 , init_reserved }, | 3037 | { "INIT_97" , 0x97, init_97 }, |
3031 | { "INIT_96" , 0x96, 17 , 0 , 0 , init_96 }, | 3038 | { "INIT_AUXCH" , 0x98, init_auxch }, |
3032 | { "INIT_97" , 0x97, 13 , 0 , 0 , init_97 }, | 3039 | { "INIT_ZM_AUXCH" , 0x99, init_zm_auxch }, |
3033 | { "INIT_AUXCH" , 0x98, 6 , 5 , 2 , init_auxch }, | 3040 | { NULL , 0 , NULL } |
3034 | { "INIT_ZM_AUXCH" , 0x99, 6 , 5 , 1 , init_zm_auxch }, | ||
3035 | { NULL , 0 , 0 , 0 , 0 , NULL } | ||
3036 | }; | 3041 | }; |
3037 | 3042 | ||
3038 | static unsigned int get_init_table_entry_length(struct nvbios *bios, unsigned int offset, int i) | ||
3039 | { | ||
3040 | /* Calculates the length of a given init table entry. */ | ||
3041 | return itbl_entry[i].length + bios->data[offset + itbl_entry[i].length_offset]*itbl_entry[i].length_multiplier; | ||
3042 | } | ||
3043 | |||
3044 | #define MAX_TABLE_OPS 1000 | 3043 | #define MAX_TABLE_OPS 1000 |
3045 | 3044 | ||
3046 | static int | 3045 | static int |
@@ -3056,7 +3055,7 @@ parse_init_table(struct nvbios *bios, unsigned int offset, | |||
3056 | * is changed back to EXECUTE. | 3055 | * is changed back to EXECUTE. |
3057 | */ | 3056 | */ |
3058 | 3057 | ||
3059 | int count = 0, i; | 3058 | int count = 0, i, res; |
3060 | uint8_t id; | 3059 | uint8_t id; |
3061 | 3060 | ||
3062 | /* | 3061 | /* |
@@ -3076,22 +3075,21 @@ parse_init_table(struct nvbios *bios, unsigned int offset, | |||
3076 | offset, itbl_entry[i].id, itbl_entry[i].name); | 3075 | offset, itbl_entry[i].id, itbl_entry[i].name); |
3077 | 3076 | ||
3078 | /* execute eventual command handler */ | 3077 | /* execute eventual command handler */ |
3079 | if (itbl_entry[i].handler) | 3078 | res = (*itbl_entry[i].handler)(bios, offset, iexec); |
3080 | if (!(*itbl_entry[i].handler)(bios, offset, iexec)) | 3079 | if (!res) |
3081 | break; | 3080 | break; |
3081 | /* | ||
3082 | * Add the offset of the current command including all data | ||
3083 | * of that command. The offset will then be pointing on the | ||
3084 | * next op code. | ||
3085 | */ | ||
3086 | offset += res; | ||
3082 | } else { | 3087 | } else { |
3083 | NV_ERROR(bios->dev, | 3088 | NV_ERROR(bios->dev, |
3084 | "0x%04X: Init table command not found: " | 3089 | "0x%04X: Init table command not found: " |
3085 | "0x%02X\n", offset, id); | 3090 | "0x%02X\n", offset, id); |
3086 | return -ENOENT; | 3091 | return -ENOENT; |
3087 | } | 3092 | } |
3088 | |||
3089 | /* | ||
3090 | * Add the offset of the current command including all data | ||
3091 | * of that command. The offset will then be pointing on the | ||
3092 | * next op code. | ||
3093 | */ | ||
3094 | offset += get_init_table_entry_length(bios, offset, i); | ||
3095 | } | 3093 | } |
3096 | 3094 | ||
3097 | if (offset >= bios->length) | 3095 | if (offset >= bios->length) |
@@ -3854,7 +3852,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, | |||
3854 | * script tables is a pointer to the script to execute. | 3852 | * script tables is a pointer to the script to execute. |
3855 | */ | 3853 | */ |
3856 | 3854 | ||
3857 | NV_DEBUG(dev, "Searching for output entry for %d %d %d\n", | 3855 | NV_DEBUG_KMS(dev, "Searching for output entry for %d %d %d\n", |
3858 | dcbent->type, dcbent->location, dcbent->or); | 3856 | dcbent->type, dcbent->location, dcbent->or); |
3859 | otable = bios_output_config_match(dev, dcbent, table[1] + | 3857 | otable = bios_output_config_match(dev, dcbent, table[1] + |
3860 | bios->display.script_table_ptr, | 3858 | bios->display.script_table_ptr, |
@@ -3884,7 +3882,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, | |||
3884 | if (pxclk == 0) { | 3882 | if (pxclk == 0) { |
3885 | script = ROM16(otable[6]); | 3883 | script = ROM16(otable[6]); |
3886 | if (!script) { | 3884 | if (!script) { |
3887 | NV_DEBUG(dev, "output script 0 not found\n"); | 3885 | NV_DEBUG_KMS(dev, "output script 0 not found\n"); |
3888 | return 1; | 3886 | return 1; |
3889 | } | 3887 | } |
3890 | 3888 | ||
@@ -3894,7 +3892,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, | |||
3894 | if (pxclk == -1) { | 3892 | if (pxclk == -1) { |
3895 | script = ROM16(otable[8]); | 3893 | script = ROM16(otable[8]); |
3896 | if (!script) { | 3894 | if (!script) { |
3897 | NV_DEBUG(dev, "output script 1 not found\n"); | 3895 | NV_DEBUG_KMS(dev, "output script 1 not found\n"); |
3898 | return 1; | 3896 | return 1; |
3899 | } | 3897 | } |
3900 | 3898 | ||
@@ -3907,7 +3905,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, | |||
3907 | else | 3905 | else |
3908 | script = 0; | 3906 | script = 0; |
3909 | if (!script) { | 3907 | if (!script) { |
3910 | NV_DEBUG(dev, "output script 2 not found\n"); | 3908 | NV_DEBUG_KMS(dev, "output script 2 not found\n"); |
3911 | return 1; | 3909 | return 1; |
3912 | } | 3910 | } |
3913 | 3911 | ||
@@ -3931,7 +3929,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, | |||
3931 | if (script) | 3929 | if (script) |
3932 | script = clkcmptable(bios, script, -pxclk); | 3930 | script = clkcmptable(bios, script, -pxclk); |
3933 | if (!script) { | 3931 | if (!script) { |
3934 | NV_DEBUG(dev, "clock script 1 not found\n"); | 3932 | NV_DEBUG_KMS(dev, "clock script 1 not found\n"); |
3935 | return 1; | 3933 | return 1; |
3936 | } | 3934 | } |
3937 | 3935 | ||
@@ -4606,10 +4604,6 @@ parse_bit_M_tbl_entry(struct drm_device *dev, struct nvbios *bios, | |||
4606 | * stuff that we don't use - their use currently unknown | 4604 | * stuff that we don't use - their use currently unknown |
4607 | */ | 4605 | */ |
4608 | 4606 | ||
4609 | uint16_t rr_strap_xlat; | ||
4610 | uint8_t rr_group_count; | ||
4611 | int i; | ||
4612 | |||
4613 | /* | 4607 | /* |
4614 | * Older bios versions don't have a sufficiently long table for | 4608 | * Older bios versions don't have a sufficiently long table for |
4615 | * what we want | 4609 | * what we want |
@@ -4618,24 +4612,13 @@ parse_bit_M_tbl_entry(struct drm_device *dev, struct nvbios *bios, | |||
4618 | return 0; | 4612 | return 0; |
4619 | 4613 | ||
4620 | if (bitentry->id[1] < 2) { | 4614 | if (bitentry->id[1] < 2) { |
4621 | rr_group_count = bios->data[bitentry->offset + 2]; | 4615 | bios->ram_restrict_group_count = bios->data[bitentry->offset + 2]; |
4622 | rr_strap_xlat = ROM16(bios->data[bitentry->offset + 3]); | 4616 | bios->ram_restrict_tbl_ptr = ROM16(bios->data[bitentry->offset + 3]); |
4623 | } else { | 4617 | } else { |
4624 | rr_group_count = bios->data[bitentry->offset + 0]; | 4618 | bios->ram_restrict_group_count = bios->data[bitentry->offset + 0]; |
4625 | rr_strap_xlat = ROM16(bios->data[bitentry->offset + 1]); | 4619 | bios->ram_restrict_tbl_ptr = ROM16(bios->data[bitentry->offset + 1]); |
4626 | } | 4620 | } |
4627 | 4621 | ||
4628 | /* adjust length of INIT_87 */ | ||
4629 | for (i = 0; itbl_entry[i].name && (itbl_entry[i].id != 0x87); i++); | ||
4630 | itbl_entry[i].length += rr_group_count * 4; | ||
4631 | |||
4632 | /* set up multiplier for INIT_RAM_RESTRICT_ZM_REG_GROUP */ | ||
4633 | for (; itbl_entry[i].name && (itbl_entry[i].id != 0x8f); i++); | ||
4634 | itbl_entry[i].length_multiplier = rr_group_count * 4; | ||
4635 | |||
4636 | init_ram_restrict_zm_reg_group_blocklen = itbl_entry[i].length_multiplier; | ||
4637 | bios->ram_restrict_tbl_ptr = rr_strap_xlat; | ||
4638 | |||
4639 | return 0; | 4622 | return 0; |
4640 | } | 4623 | } |
4641 | 4624 | ||
@@ -5234,7 +5217,7 @@ parse_dcb_connector_table(struct nvbios *bios) | |||
5234 | int i; | 5217 | int i; |
5235 | 5218 | ||
5236 | if (!bios->bdcb.connector_table_ptr) { | 5219 | if (!bios->bdcb.connector_table_ptr) { |
5237 | NV_DEBUG(dev, "No DCB connector table present\n"); | 5220 | NV_DEBUG_KMS(dev, "No DCB connector table present\n"); |
5238 | return; | 5221 | return; |
5239 | } | 5222 | } |
5240 | 5223 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.h b/drivers/gpu/drm/nouveau/nouveau_bios.h index 1d5f10bd78ed..058e98c76d89 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.h +++ b/drivers/gpu/drm/nouveau/nouveau_bios.h | |||
@@ -227,6 +227,7 @@ struct nvbios { | |||
227 | 227 | ||
228 | uint16_t pll_limit_tbl_ptr; | 228 | uint16_t pll_limit_tbl_ptr; |
229 | uint16_t ram_restrict_tbl_ptr; | 229 | uint16_t ram_restrict_tbl_ptr; |
230 | uint8_t ram_restrict_group_count; | ||
230 | 231 | ||
231 | uint16_t some_script_ptr; /* BIT I + 14 */ | 232 | uint16_t some_script_ptr; /* BIT I + 14 */ |
232 | uint16_t init96_tbl_ptr; /* BIT I + 16 */ | 233 | uint16_t init96_tbl_ptr; /* BIT I + 16 */ |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index aa2dfbc3e351..0cad6d834eb2 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c | |||
@@ -154,6 +154,11 @@ nouveau_bo_placement_set(struct nouveau_bo *nvbo, uint32_t memtype) | |||
154 | nvbo->placement.busy_placement = nvbo->placements; | 154 | nvbo->placement.busy_placement = nvbo->placements; |
155 | nvbo->placement.num_placement = n; | 155 | nvbo->placement.num_placement = n; |
156 | nvbo->placement.num_busy_placement = n; | 156 | nvbo->placement.num_busy_placement = n; |
157 | |||
158 | if (nvbo->pin_refcnt) { | ||
159 | while (n--) | ||
160 | nvbo->placements[n] |= TTM_PL_FLAG_NO_EVICT; | ||
161 | } | ||
157 | } | 162 | } |
158 | 163 | ||
159 | int | 164 | int |
@@ -400,10 +405,16 @@ nouveau_bo_evict_flags(struct ttm_buffer_object *bo, struct ttm_placement *pl) | |||
400 | struct nouveau_bo *nvbo = nouveau_bo(bo); | 405 | struct nouveau_bo *nvbo = nouveau_bo(bo); |
401 | 406 | ||
402 | switch (bo->mem.mem_type) { | 407 | switch (bo->mem.mem_type) { |
408 | case TTM_PL_VRAM: | ||
409 | nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_TT | | ||
410 | TTM_PL_FLAG_SYSTEM); | ||
411 | break; | ||
403 | default: | 412 | default: |
404 | nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_SYSTEM); | 413 | nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_SYSTEM); |
405 | break; | 414 | break; |
406 | } | 415 | } |
416 | |||
417 | *pl = nvbo->placement; | ||
407 | } | 418 | } |
408 | 419 | ||
409 | 420 | ||
@@ -455,11 +466,8 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, int no_wait, | |||
455 | int ret; | 466 | int ret; |
456 | 467 | ||
457 | chan = nvbo->channel; | 468 | chan = nvbo->channel; |
458 | if (!chan || nvbo->tile_flags || nvbo->no_vm) { | 469 | if (!chan || nvbo->tile_flags || nvbo->no_vm) |
459 | chan = dev_priv->channel; | 470 | chan = dev_priv->channel; |
460 | if (!chan) | ||
461 | return -EINVAL; | ||
462 | } | ||
463 | 471 | ||
464 | src_offset = old_mem->mm_node->start << PAGE_SHIFT; | 472 | src_offset = old_mem->mm_node->start << PAGE_SHIFT; |
465 | dst_offset = new_mem->mm_node->start << PAGE_SHIFT; | 473 | dst_offset = new_mem->mm_node->start << PAGE_SHIFT; |
@@ -625,7 +633,8 @@ nouveau_bo_move(struct ttm_buffer_object *bo, bool evict, bool intr, | |||
625 | return ret; | 633 | return ret; |
626 | } | 634 | } |
627 | 635 | ||
628 | if (dev_priv->init_state != NOUVEAU_CARD_INIT_DONE) | 636 | if (dev_priv->init_state != NOUVEAU_CARD_INIT_DONE || |
637 | !dev_priv->channel) | ||
629 | return ttm_bo_move_memcpy(bo, evict, no_wait, new_mem); | 638 | return ttm_bo_move_memcpy(bo, evict, no_wait, new_mem); |
630 | 639 | ||
631 | if (old_mem->mem_type == TTM_PL_SYSTEM && !bo->ttm) { | 640 | if (old_mem->mem_type == TTM_PL_SYSTEM && !bo->ttm) { |
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 032cf098fa1c..5a10deb8bdbd 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c | |||
@@ -86,7 +86,7 @@ nouveau_connector_destroy(struct drm_connector *drm_connector) | |||
86 | struct nouveau_connector *connector = nouveau_connector(drm_connector); | 86 | struct nouveau_connector *connector = nouveau_connector(drm_connector); |
87 | struct drm_device *dev = connector->base.dev; | 87 | struct drm_device *dev = connector->base.dev; |
88 | 88 | ||
89 | NV_DEBUG(dev, "\n"); | 89 | NV_DEBUG_KMS(dev, "\n"); |
90 | 90 | ||
91 | if (!connector) | 91 | if (!connector) |
92 | return; | 92 | return; |
@@ -420,7 +420,7 @@ nouveau_connector_native_mode(struct nouveau_connector *connector) | |||
420 | /* Use preferred mode if there is one.. */ | 420 | /* Use preferred mode if there is one.. */ |
421 | list_for_each_entry(mode, &connector->base.probed_modes, head) { | 421 | list_for_each_entry(mode, &connector->base.probed_modes, head) { |
422 | if (mode->type & DRM_MODE_TYPE_PREFERRED) { | 422 | if (mode->type & DRM_MODE_TYPE_PREFERRED) { |
423 | NV_DEBUG(dev, "native mode from preferred\n"); | 423 | NV_DEBUG_KMS(dev, "native mode from preferred\n"); |
424 | return drm_mode_duplicate(dev, mode); | 424 | return drm_mode_duplicate(dev, mode); |
425 | } | 425 | } |
426 | } | 426 | } |
@@ -445,7 +445,7 @@ nouveau_connector_native_mode(struct nouveau_connector *connector) | |||
445 | largest = mode; | 445 | largest = mode; |
446 | } | 446 | } |
447 | 447 | ||
448 | NV_DEBUG(dev, "native mode from largest: %dx%d@%d\n", | 448 | NV_DEBUG_KMS(dev, "native mode from largest: %dx%d@%d\n", |
449 | high_w, high_h, high_v); | 449 | high_w, high_h, high_v); |
450 | return largest ? drm_mode_duplicate(dev, largest) : NULL; | 450 | return largest ? drm_mode_duplicate(dev, largest) : NULL; |
451 | } | 451 | } |
@@ -725,7 +725,7 @@ nouveau_connector_create(struct drm_device *dev, int index, int type) | |||
725 | struct drm_encoder *encoder; | 725 | struct drm_encoder *encoder; |
726 | int ret; | 726 | int ret; |
727 | 727 | ||
728 | NV_DEBUG(dev, "\n"); | 728 | NV_DEBUG_KMS(dev, "\n"); |
729 | 729 | ||
730 | nv_connector = kzalloc(sizeof(*nv_connector), GFP_KERNEL); | 730 | nv_connector = kzalloc(sizeof(*nv_connector), GFP_KERNEL); |
731 | if (!nv_connector) | 731 | if (!nv_connector) |
diff --git a/drivers/gpu/drm/nouveau/nouveau_dp.c b/drivers/gpu/drm/nouveau/nouveau_dp.c index de61f4640e12..9e2926c48579 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dp.c +++ b/drivers/gpu/drm/nouveau/nouveau_dp.c | |||
@@ -187,7 +187,7 @@ nouveau_dp_link_train_adjust(struct drm_encoder *encoder, uint8_t *config) | |||
187 | if (ret) | 187 | if (ret) |
188 | return false; | 188 | return false; |
189 | 189 | ||
190 | NV_DEBUG(dev, "\t\tadjust 0x%02x 0x%02x\n", request[0], request[1]); | 190 | NV_DEBUG_KMS(dev, "\t\tadjust 0x%02x 0x%02x\n", request[0], request[1]); |
191 | 191 | ||
192 | /* Keep all lanes at the same level.. */ | 192 | /* Keep all lanes at the same level.. */ |
193 | for (i = 0; i < nv_encoder->dp.link_nr; i++) { | 193 | for (i = 0; i < nv_encoder->dp.link_nr; i++) { |
@@ -228,7 +228,7 @@ nouveau_dp_link_train_commit(struct drm_encoder *encoder, uint8_t *config) | |||
228 | int or = nv_encoder->or, link = !(nv_encoder->dcb->sorconf.link & 1); | 228 | int or = nv_encoder->or, link = !(nv_encoder->dcb->sorconf.link & 1); |
229 | int dpe_headerlen, ret, i; | 229 | int dpe_headerlen, ret, i; |
230 | 230 | ||
231 | NV_DEBUG(dev, "\t\tconfig 0x%02x 0x%02x 0x%02x 0x%02x\n", | 231 | NV_DEBUG_KMS(dev, "\t\tconfig 0x%02x 0x%02x 0x%02x 0x%02x\n", |
232 | config[0], config[1], config[2], config[3]); | 232 | config[0], config[1], config[2], config[3]); |
233 | 233 | ||
234 | dpe = nouveau_bios_dp_table(dev, nv_encoder->dcb, &dpe_headerlen); | 234 | dpe = nouveau_bios_dp_table(dev, nv_encoder->dcb, &dpe_headerlen); |
@@ -276,12 +276,12 @@ nouveau_dp_link_train(struct drm_encoder *encoder) | |||
276 | bool cr_done, cr_max_vs, eq_done; | 276 | bool cr_done, cr_max_vs, eq_done; |
277 | int ret = 0, i, tries, voltage; | 277 | int ret = 0, i, tries, voltage; |
278 | 278 | ||
279 | NV_DEBUG(dev, "link training!!\n"); | 279 | NV_DEBUG_KMS(dev, "link training!!\n"); |
280 | train: | 280 | train: |
281 | cr_done = eq_done = false; | 281 | cr_done = eq_done = false; |
282 | 282 | ||
283 | /* set link configuration */ | 283 | /* set link configuration */ |
284 | NV_DEBUG(dev, "\tbegin train: bw %d, lanes %d\n", | 284 | NV_DEBUG_KMS(dev, "\tbegin train: bw %d, lanes %d\n", |
285 | nv_encoder->dp.link_bw, nv_encoder->dp.link_nr); | 285 | nv_encoder->dp.link_bw, nv_encoder->dp.link_nr); |
286 | 286 | ||
287 | ret = nouveau_dp_link_bw_set(encoder, nv_encoder->dp.link_bw); | 287 | ret = nouveau_dp_link_bw_set(encoder, nv_encoder->dp.link_bw); |
@@ -297,7 +297,7 @@ train: | |||
297 | return false; | 297 | return false; |
298 | 298 | ||
299 | /* clock recovery */ | 299 | /* clock recovery */ |
300 | NV_DEBUG(dev, "\tbegin cr\n"); | 300 | NV_DEBUG_KMS(dev, "\tbegin cr\n"); |
301 | ret = nouveau_dp_link_train_set(encoder, DP_TRAINING_PATTERN_1); | 301 | ret = nouveau_dp_link_train_set(encoder, DP_TRAINING_PATTERN_1); |
302 | if (ret) | 302 | if (ret) |
303 | goto stop; | 303 | goto stop; |
@@ -314,7 +314,7 @@ train: | |||
314 | ret = auxch_rd(encoder, DP_LANE0_1_STATUS, status, 2); | 314 | ret = auxch_rd(encoder, DP_LANE0_1_STATUS, status, 2); |
315 | if (ret) | 315 | if (ret) |
316 | break; | 316 | break; |
317 | NV_DEBUG(dev, "\t\tstatus: 0x%02x 0x%02x\n", | 317 | NV_DEBUG_KMS(dev, "\t\tstatus: 0x%02x 0x%02x\n", |
318 | status[0], status[1]); | 318 | status[0], status[1]); |
319 | 319 | ||
320 | cr_done = true; | 320 | cr_done = true; |
@@ -346,7 +346,7 @@ train: | |||
346 | goto stop; | 346 | goto stop; |
347 | 347 | ||
348 | /* channel equalisation */ | 348 | /* channel equalisation */ |
349 | NV_DEBUG(dev, "\tbegin eq\n"); | 349 | NV_DEBUG_KMS(dev, "\tbegin eq\n"); |
350 | ret = nouveau_dp_link_train_set(encoder, DP_TRAINING_PATTERN_2); | 350 | ret = nouveau_dp_link_train_set(encoder, DP_TRAINING_PATTERN_2); |
351 | if (ret) | 351 | if (ret) |
352 | goto stop; | 352 | goto stop; |
@@ -357,7 +357,7 @@ train: | |||
357 | ret = auxch_rd(encoder, DP_LANE0_1_STATUS, status, 3); | 357 | ret = auxch_rd(encoder, DP_LANE0_1_STATUS, status, 3); |
358 | if (ret) | 358 | if (ret) |
359 | break; | 359 | break; |
360 | NV_DEBUG(dev, "\t\tstatus: 0x%02x 0x%02x\n", | 360 | NV_DEBUG_KMS(dev, "\t\tstatus: 0x%02x 0x%02x\n", |
361 | status[0], status[1]); | 361 | status[0], status[1]); |
362 | 362 | ||
363 | eq_done = true; | 363 | eq_done = true; |
@@ -395,9 +395,9 @@ stop: | |||
395 | 395 | ||
396 | /* retry at a lower setting, if possible */ | 396 | /* retry at a lower setting, if possible */ |
397 | if (!ret && !(eq_done && cr_done)) { | 397 | if (!ret && !(eq_done && cr_done)) { |
398 | NV_DEBUG(dev, "\twe failed\n"); | 398 | NV_DEBUG_KMS(dev, "\twe failed\n"); |
399 | if (nv_encoder->dp.link_bw != DP_LINK_BW_1_62) { | 399 | if (nv_encoder->dp.link_bw != DP_LINK_BW_1_62) { |
400 | NV_DEBUG(dev, "retry link training at low rate\n"); | 400 | NV_DEBUG_KMS(dev, "retry link training at low rate\n"); |
401 | nv_encoder->dp.link_bw = DP_LINK_BW_1_62; | 401 | nv_encoder->dp.link_bw = DP_LINK_BW_1_62; |
402 | goto train; | 402 | goto train; |
403 | } | 403 | } |
@@ -418,7 +418,7 @@ nouveau_dp_detect(struct drm_encoder *encoder) | |||
418 | if (ret) | 418 | if (ret) |
419 | return false; | 419 | return false; |
420 | 420 | ||
421 | NV_DEBUG(dev, "encoder: link_bw %d, link_nr %d\n" | 421 | NV_DEBUG_KMS(dev, "encoder: link_bw %d, link_nr %d\n" |
422 | "display: link_bw %d, link_nr %d version 0x%02x\n", | 422 | "display: link_bw %d, link_nr %d version 0x%02x\n", |
423 | nv_encoder->dcb->dpconf.link_bw, | 423 | nv_encoder->dcb->dpconf.link_bw, |
424 | nv_encoder->dcb->dpconf.link_nr, | 424 | nv_encoder->dcb->dpconf.link_nr, |
@@ -446,7 +446,7 @@ nouveau_dp_auxch(struct nouveau_i2c_chan *auxch, int cmd, int addr, | |||
446 | uint32_t tmp, ctrl, stat = 0, data32[4] = {}; | 446 | uint32_t tmp, ctrl, stat = 0, data32[4] = {}; |
447 | int ret = 0, i, index = auxch->rd; | 447 | int ret = 0, i, index = auxch->rd; |
448 | 448 | ||
449 | NV_DEBUG(dev, "ch %d cmd %d addr 0x%x len %d\n", index, cmd, addr, data_nr); | 449 | NV_DEBUG_KMS(dev, "ch %d cmd %d addr 0x%x len %d\n", index, cmd, addr, data_nr); |
450 | 450 | ||
451 | tmp = nv_rd32(dev, NV50_AUXCH_CTRL(auxch->rd)); | 451 | tmp = nv_rd32(dev, NV50_AUXCH_CTRL(auxch->rd)); |
452 | nv_wr32(dev, NV50_AUXCH_CTRL(auxch->rd), tmp | 0x00100000); | 452 | nv_wr32(dev, NV50_AUXCH_CTRL(auxch->rd), tmp | 0x00100000); |
@@ -472,7 +472,7 @@ nouveau_dp_auxch(struct nouveau_i2c_chan *auxch, int cmd, int addr, | |||
472 | if (!(cmd & 1)) { | 472 | if (!(cmd & 1)) { |
473 | memcpy(data32, data, data_nr); | 473 | memcpy(data32, data, data_nr); |
474 | for (i = 0; i < 4; i++) { | 474 | for (i = 0; i < 4; i++) { |
475 | NV_DEBUG(dev, "wr %d: 0x%08x\n", i, data32[i]); | 475 | NV_DEBUG_KMS(dev, "wr %d: 0x%08x\n", i, data32[i]); |
476 | nv_wr32(dev, NV50_AUXCH_DATA_OUT(index, i), data32[i]); | 476 | nv_wr32(dev, NV50_AUXCH_DATA_OUT(index, i), data32[i]); |
477 | } | 477 | } |
478 | } | 478 | } |
@@ -504,7 +504,7 @@ nouveau_dp_auxch(struct nouveau_i2c_chan *auxch, int cmd, int addr, | |||
504 | if (cmd & 1) { | 504 | if (cmd & 1) { |
505 | for (i = 0; i < 4; i++) { | 505 | for (i = 0; i < 4; i++) { |
506 | data32[i] = nv_rd32(dev, NV50_AUXCH_DATA_IN(index, i)); | 506 | data32[i] = nv_rd32(dev, NV50_AUXCH_DATA_IN(index, i)); |
507 | NV_DEBUG(dev, "rd %d: 0x%08x\n", i, data32[i]); | 507 | NV_DEBUG_KMS(dev, "rd %d: 0x%08x\n", i, data32[i]); |
508 | } | 508 | } |
509 | memcpy(data, data32, data_nr); | 509 | memcpy(data, data32, data_nr); |
510 | } | 510 | } |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c index 35249c35118f..06eb993e0883 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.c +++ b/drivers/gpu/drm/nouveau/nouveau_drv.c | |||
@@ -35,6 +35,10 @@ | |||
35 | 35 | ||
36 | #include "drm_pciids.h" | 36 | #include "drm_pciids.h" |
37 | 37 | ||
38 | MODULE_PARM_DESC(ctxfw, "Use external firmware blob for grctx init (NV40)"); | ||
39 | int nouveau_ctxfw = 0; | ||
40 | module_param_named(ctxfw, nouveau_ctxfw, int, 0400); | ||
41 | |||
38 | MODULE_PARM_DESC(noagp, "Disable AGP"); | 42 | MODULE_PARM_DESC(noagp, "Disable AGP"); |
39 | int nouveau_noagp; | 43 | int nouveau_noagp; |
40 | module_param_named(noagp, nouveau_noagp, int, 0400); | 44 | module_param_named(noagp, nouveau_noagp, int, 0400); |
@@ -273,7 +277,7 @@ nouveau_pci_resume(struct pci_dev *pdev) | |||
273 | 277 | ||
274 | for (i = 0; i < dev_priv->engine.fifo.channels; i++) { | 278 | for (i = 0; i < dev_priv->engine.fifo.channels; i++) { |
275 | chan = dev_priv->fifos[i]; | 279 | chan = dev_priv->fifos[i]; |
276 | if (!chan) | 280 | if (!chan || !chan->pushbuf_bo) |
277 | continue; | 281 | continue; |
278 | 282 | ||
279 | for (j = 0; j < NOUVEAU_DMA_SKIPS; j++) | 283 | for (j = 0; j < NOUVEAU_DMA_SKIPS; j++) |
@@ -341,7 +345,7 @@ static struct drm_driver driver = { | |||
341 | .owner = THIS_MODULE, | 345 | .owner = THIS_MODULE, |
342 | .open = drm_open, | 346 | .open = drm_open, |
343 | .release = drm_release, | 347 | .release = drm_release, |
344 | .ioctl = drm_ioctl, | 348 | .unlocked_ioctl = drm_ioctl, |
345 | .mmap = nouveau_ttm_mmap, | 349 | .mmap = nouveau_ttm_mmap, |
346 | .poll = drm_poll, | 350 | .poll = drm_poll, |
347 | .fasync = drm_fasync, | 351 | .fasync = drm_fasync, |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 88b4c7b77e7f..5f8cbb79c499 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h | |||
@@ -54,6 +54,7 @@ struct nouveau_fpriv { | |||
54 | #include "nouveau_drm.h" | 54 | #include "nouveau_drm.h" |
55 | #include "nouveau_reg.h" | 55 | #include "nouveau_reg.h" |
56 | #include "nouveau_bios.h" | 56 | #include "nouveau_bios.h" |
57 | struct nouveau_grctx; | ||
57 | 58 | ||
58 | #define MAX_NUM_DCB_ENTRIES 16 | 59 | #define MAX_NUM_DCB_ENTRIES 16 |
59 | 60 | ||
@@ -317,6 +318,7 @@ struct nouveau_pgraph_engine { | |||
317 | bool accel_blocked; | 318 | bool accel_blocked; |
318 | void *ctxprog; | 319 | void *ctxprog; |
319 | void *ctxvals; | 320 | void *ctxvals; |
321 | int grctx_size; | ||
320 | 322 | ||
321 | int (*init)(struct drm_device *); | 323 | int (*init)(struct drm_device *); |
322 | void (*takedown)(struct drm_device *); | 324 | void (*takedown)(struct drm_device *); |
@@ -647,6 +649,7 @@ extern int nouveau_fbpercrtc; | |||
647 | extern char *nouveau_tv_norm; | 649 | extern char *nouveau_tv_norm; |
648 | extern int nouveau_reg_debug; | 650 | extern int nouveau_reg_debug; |
649 | extern char *nouveau_vbios; | 651 | extern char *nouveau_vbios; |
652 | extern int nouveau_ctxfw; | ||
650 | 653 | ||
651 | /* nouveau_state.c */ | 654 | /* nouveau_state.c */ |
652 | extern void nouveau_preclose(struct drm_device *dev, struct drm_file *); | 655 | extern void nouveau_preclose(struct drm_device *dev, struct drm_file *); |
@@ -959,9 +962,7 @@ extern int nv40_graph_create_context(struct nouveau_channel *); | |||
959 | extern void nv40_graph_destroy_context(struct nouveau_channel *); | 962 | extern void nv40_graph_destroy_context(struct nouveau_channel *); |
960 | extern int nv40_graph_load_context(struct nouveau_channel *); | 963 | extern int nv40_graph_load_context(struct nouveau_channel *); |
961 | extern int nv40_graph_unload_context(struct drm_device *); | 964 | extern int nv40_graph_unload_context(struct drm_device *); |
962 | extern int nv40_grctx_init(struct drm_device *); | 965 | extern void nv40_grctx_init(struct nouveau_grctx *); |
963 | extern void nv40_grctx_fini(struct drm_device *); | ||
964 | extern void nv40_grctx_vals_load(struct drm_device *, struct nouveau_gpuobj *); | ||
965 | 966 | ||
966 | /* nv50_graph.c */ | 967 | /* nv50_graph.c */ |
967 | extern struct nouveau_pgraph_object_class nv50_graph_grclass[]; | 968 | extern struct nouveau_pgraph_object_class nv50_graph_grclass[]; |
@@ -975,6 +976,12 @@ extern int nv50_graph_load_context(struct nouveau_channel *); | |||
975 | extern int nv50_graph_unload_context(struct drm_device *); | 976 | extern int nv50_graph_unload_context(struct drm_device *); |
976 | extern void nv50_graph_context_switch(struct drm_device *); | 977 | extern void nv50_graph_context_switch(struct drm_device *); |
977 | 978 | ||
979 | /* nouveau_grctx.c */ | ||
980 | extern int nouveau_grctx_prog_load(struct drm_device *); | ||
981 | extern void nouveau_grctx_vals_load(struct drm_device *, | ||
982 | struct nouveau_gpuobj *); | ||
983 | extern void nouveau_grctx_fini(struct drm_device *); | ||
984 | |||
978 | /* nv04_instmem.c */ | 985 | /* nv04_instmem.c */ |
979 | extern int nv04_instmem_init(struct drm_device *); | 986 | extern int nv04_instmem_init(struct drm_device *); |
980 | extern void nv04_instmem_takedown(struct drm_device *); | 987 | extern void nv04_instmem_takedown(struct drm_device *); |
@@ -1207,14 +1214,24 @@ static inline void nv_wo32(struct drm_device *dev, struct nouveau_gpuobj *obj, | |||
1207 | pci_name(d->pdev), ##arg) | 1214 | pci_name(d->pdev), ##arg) |
1208 | #ifndef NV_DEBUG_NOTRACE | 1215 | #ifndef NV_DEBUG_NOTRACE |
1209 | #define NV_DEBUG(d, fmt, arg...) do { \ | 1216 | #define NV_DEBUG(d, fmt, arg...) do { \ |
1210 | if (drm_debug) { \ | 1217 | if (drm_debug & DRM_UT_DRIVER) { \ |
1218 | NV_PRINTK(KERN_DEBUG, d, "%s:%d - " fmt, __func__, \ | ||
1219 | __LINE__, ##arg); \ | ||
1220 | } \ | ||
1221 | } while (0) | ||
1222 | #define NV_DEBUG_KMS(d, fmt, arg...) do { \ | ||
1223 | if (drm_debug & DRM_UT_KMS) { \ | ||
1211 | NV_PRINTK(KERN_DEBUG, d, "%s:%d - " fmt, __func__, \ | 1224 | NV_PRINTK(KERN_DEBUG, d, "%s:%d - " fmt, __func__, \ |
1212 | __LINE__, ##arg); \ | 1225 | __LINE__, ##arg); \ |
1213 | } \ | 1226 | } \ |
1214 | } while (0) | 1227 | } while (0) |
1215 | #else | 1228 | #else |
1216 | #define NV_DEBUG(d, fmt, arg...) do { \ | 1229 | #define NV_DEBUG(d, fmt, arg...) do { \ |
1217 | if (drm_debug) \ | 1230 | if (drm_debug & DRM_UT_DRIVER) \ |
1231 | NV_PRINTK(KERN_DEBUG, d, fmt, ##arg); \ | ||
1232 | } while (0) | ||
1233 | #define NV_DEBUG_KMS(d, fmt, arg...) do { \ | ||
1234 | if (drm_debug & DRM_UT_KMS) \ | ||
1218 | NV_PRINTK(KERN_DEBUG, d, fmt, ##arg); \ | 1235 | NV_PRINTK(KERN_DEBUG, d, fmt, ##arg); \ |
1219 | } while (0) | 1236 | } while (0) |
1220 | #endif | 1237 | #endif |
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 36e8c5e4503a..84af25c238b6 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c | |||
@@ -58,7 +58,7 @@ nouveau_fbcon_sync(struct fb_info *info) | |||
58 | struct nouveau_channel *chan = dev_priv->channel; | 58 | struct nouveau_channel *chan = dev_priv->channel; |
59 | int ret, i; | 59 | int ret, i; |
60 | 60 | ||
61 | if (!chan->accel_done || | 61 | if (!chan || !chan->accel_done || |
62 | info->state != FBINFO_STATE_RUNNING || | 62 | info->state != FBINFO_STATE_RUNNING || |
63 | info->flags & FBINFO_HWACCEL_DISABLED) | 63 | info->flags & FBINFO_HWACCEL_DISABLED) |
64 | return 0; | 64 | return 0; |
@@ -318,14 +318,16 @@ nouveau_fbcon_create(struct drm_device *dev, uint32_t fb_width, | |||
318 | par->nouveau_fb = nouveau_fb; | 318 | par->nouveau_fb = nouveau_fb; |
319 | par->dev = dev; | 319 | par->dev = dev; |
320 | 320 | ||
321 | switch (dev_priv->card_type) { | 321 | if (dev_priv->channel) { |
322 | case NV_50: | 322 | switch (dev_priv->card_type) { |
323 | nv50_fbcon_accel_init(info); | 323 | case NV_50: |
324 | break; | 324 | nv50_fbcon_accel_init(info); |
325 | default: | 325 | break; |
326 | nv04_fbcon_accel_init(info); | 326 | default: |
327 | break; | 327 | nv04_fbcon_accel_init(info); |
328 | }; | 328 | break; |
329 | }; | ||
330 | } | ||
329 | 331 | ||
330 | nouveau_fbcon_zfill(dev); | 332 | nouveau_fbcon_zfill(dev); |
331 | 333 | ||
@@ -347,7 +349,7 @@ out: | |||
347 | int | 349 | int |
348 | nouveau_fbcon_probe(struct drm_device *dev) | 350 | nouveau_fbcon_probe(struct drm_device *dev) |
349 | { | 351 | { |
350 | NV_DEBUG(dev, "\n"); | 352 | NV_DEBUG_KMS(dev, "\n"); |
351 | 353 | ||
352 | return drm_fb_helper_single_fb_probe(dev, 32, nouveau_fbcon_create); | 354 | return drm_fb_helper_single_fb_probe(dev, 32, nouveau_fbcon_create); |
353 | } | 355 | } |
diff --git a/drivers/gpu/drm/nouveau/nouveau_grctx.c b/drivers/gpu/drm/nouveau/nouveau_grctx.c new file mode 100644 index 000000000000..419f4c2b3b89 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nouveau_grctx.c | |||
@@ -0,0 +1,161 @@ | |||
1 | /* | ||
2 | * Copyright 2009 Red Hat Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | * Authors: Ben Skeggs | ||
23 | */ | ||
24 | |||
25 | #include <linux/firmware.h> | ||
26 | |||
27 | #include "drmP.h" | ||
28 | #include "nouveau_drv.h" | ||
29 | |||
30 | struct nouveau_ctxprog { | ||
31 | uint32_t signature; | ||
32 | uint8_t version; | ||
33 | uint16_t length; | ||
34 | uint32_t data[]; | ||
35 | } __attribute__ ((packed)); | ||
36 | |||
37 | struct nouveau_ctxvals { | ||
38 | uint32_t signature; | ||
39 | uint8_t version; | ||
40 | uint32_t length; | ||
41 | struct { | ||
42 | uint32_t offset; | ||
43 | uint32_t value; | ||
44 | } data[]; | ||
45 | } __attribute__ ((packed)); | ||
46 | |||
47 | int | ||
48 | nouveau_grctx_prog_load(struct drm_device *dev) | ||
49 | { | ||
50 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
51 | struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; | ||
52 | const int chipset = dev_priv->chipset; | ||
53 | const struct firmware *fw; | ||
54 | const struct nouveau_ctxprog *cp; | ||
55 | const struct nouveau_ctxvals *cv; | ||
56 | char name[32]; | ||
57 | int ret, i; | ||
58 | |||
59 | if (pgraph->accel_blocked) | ||
60 | return -ENODEV; | ||
61 | |||
62 | if (!pgraph->ctxprog) { | ||
63 | sprintf(name, "nouveau/nv%02x.ctxprog", chipset); | ||
64 | ret = request_firmware(&fw, name, &dev->pdev->dev); | ||
65 | if (ret) { | ||
66 | NV_ERROR(dev, "No ctxprog for NV%02x\n", chipset); | ||
67 | return ret; | ||
68 | } | ||
69 | |||
70 | pgraph->ctxprog = kmalloc(fw->size, GFP_KERNEL); | ||
71 | if (!pgraph->ctxprog) { | ||
72 | NV_ERROR(dev, "OOM copying ctxprog\n"); | ||
73 | release_firmware(fw); | ||
74 | return -ENOMEM; | ||
75 | } | ||
76 | memcpy(pgraph->ctxprog, fw->data, fw->size); | ||
77 | |||
78 | cp = pgraph->ctxprog; | ||
79 | if (le32_to_cpu(cp->signature) != 0x5043564e || | ||
80 | cp->version != 0 || | ||
81 | le16_to_cpu(cp->length) != ((fw->size - 7) / 4)) { | ||
82 | NV_ERROR(dev, "ctxprog invalid\n"); | ||
83 | release_firmware(fw); | ||
84 | nouveau_grctx_fini(dev); | ||
85 | return -EINVAL; | ||
86 | } | ||
87 | release_firmware(fw); | ||
88 | } | ||
89 | |||
90 | if (!pgraph->ctxvals) { | ||
91 | sprintf(name, "nouveau/nv%02x.ctxvals", chipset); | ||
92 | ret = request_firmware(&fw, name, &dev->pdev->dev); | ||
93 | if (ret) { | ||
94 | NV_ERROR(dev, "No ctxvals for NV%02x\n", chipset); | ||
95 | nouveau_grctx_fini(dev); | ||
96 | return ret; | ||
97 | } | ||
98 | |||
99 | pgraph->ctxvals = kmalloc(fw->size, GFP_KERNEL); | ||
100 | if (!pgraph->ctxprog) { | ||
101 | NV_ERROR(dev, "OOM copying ctxprog\n"); | ||
102 | release_firmware(fw); | ||
103 | nouveau_grctx_fini(dev); | ||
104 | return -ENOMEM; | ||
105 | } | ||
106 | memcpy(pgraph->ctxvals, fw->data, fw->size); | ||
107 | |||
108 | cv = (void *)pgraph->ctxvals; | ||
109 | if (le32_to_cpu(cv->signature) != 0x5643564e || | ||
110 | cv->version != 0 || | ||
111 | le32_to_cpu(cv->length) != ((fw->size - 9) / 8)) { | ||
112 | NV_ERROR(dev, "ctxvals invalid\n"); | ||
113 | release_firmware(fw); | ||
114 | nouveau_grctx_fini(dev); | ||
115 | return -EINVAL; | ||
116 | } | ||
117 | release_firmware(fw); | ||
118 | } | ||
119 | |||
120 | cp = pgraph->ctxprog; | ||
121 | |||
122 | nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0); | ||
123 | for (i = 0; i < le16_to_cpu(cp->length); i++) | ||
124 | nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, | ||
125 | le32_to_cpu(cp->data[i])); | ||
126 | |||
127 | return 0; | ||
128 | } | ||
129 | |||
130 | void | ||
131 | nouveau_grctx_fini(struct drm_device *dev) | ||
132 | { | ||
133 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
134 | struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; | ||
135 | |||
136 | if (pgraph->ctxprog) { | ||
137 | kfree(pgraph->ctxprog); | ||
138 | pgraph->ctxprog = NULL; | ||
139 | } | ||
140 | |||
141 | if (pgraph->ctxvals) { | ||
142 | kfree(pgraph->ctxprog); | ||
143 | pgraph->ctxvals = NULL; | ||
144 | } | ||
145 | } | ||
146 | |||
147 | void | ||
148 | nouveau_grctx_vals_load(struct drm_device *dev, struct nouveau_gpuobj *ctx) | ||
149 | { | ||
150 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
151 | struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; | ||
152 | struct nouveau_ctxvals *cv = pgraph->ctxvals; | ||
153 | int i; | ||
154 | |||
155 | if (!cv) | ||
156 | return; | ||
157 | |||
158 | for (i = 0; i < le32_to_cpu(cv->length); i++) | ||
159 | nv_wo32(dev, ctx, le32_to_cpu(cv->data[i].offset), | ||
160 | le32_to_cpu(cv->data[i].value)); | ||
161 | } | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_grctx.h b/drivers/gpu/drm/nouveau/nouveau_grctx.h new file mode 100644 index 000000000000..5d39c4ce8006 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nouveau_grctx.h | |||
@@ -0,0 +1,133 @@ | |||
1 | #ifndef __NOUVEAU_GRCTX_H__ | ||
2 | #define __NOUVEAU_GRCTX_H__ | ||
3 | |||
4 | struct nouveau_grctx { | ||
5 | struct drm_device *dev; | ||
6 | |||
7 | enum { | ||
8 | NOUVEAU_GRCTX_PROG, | ||
9 | NOUVEAU_GRCTX_VALS | ||
10 | } mode; | ||
11 | void *data; | ||
12 | |||
13 | uint32_t ctxprog_max; | ||
14 | uint32_t ctxprog_len; | ||
15 | uint32_t ctxprog_reg; | ||
16 | int ctxprog_label[32]; | ||
17 | uint32_t ctxvals_pos; | ||
18 | uint32_t ctxvals_base; | ||
19 | }; | ||
20 | |||
21 | #ifdef CP_CTX | ||
22 | static inline void | ||
23 | cp_out(struct nouveau_grctx *ctx, uint32_t inst) | ||
24 | { | ||
25 | uint32_t *ctxprog = ctx->data; | ||
26 | |||
27 | if (ctx->mode != NOUVEAU_GRCTX_PROG) | ||
28 | return; | ||
29 | |||
30 | BUG_ON(ctx->ctxprog_len == ctx->ctxprog_max); | ||
31 | ctxprog[ctx->ctxprog_len++] = inst; | ||
32 | } | ||
33 | |||
34 | static inline void | ||
35 | cp_lsr(struct nouveau_grctx *ctx, uint32_t val) | ||
36 | { | ||
37 | cp_out(ctx, CP_LOAD_SR | val); | ||
38 | } | ||
39 | |||
40 | static inline void | ||
41 | cp_ctx(struct nouveau_grctx *ctx, uint32_t reg, uint32_t length) | ||
42 | { | ||
43 | ctx->ctxprog_reg = (reg - 0x00400000) >> 2; | ||
44 | |||
45 | ctx->ctxvals_base = ctx->ctxvals_pos; | ||
46 | ctx->ctxvals_pos = ctx->ctxvals_base + length; | ||
47 | |||
48 | if (length > (CP_CTX_COUNT >> CP_CTX_COUNT_SHIFT)) { | ||
49 | cp_lsr(ctx, length); | ||
50 | length = 0; | ||
51 | } | ||
52 | |||
53 | cp_out(ctx, CP_CTX | (length << CP_CTX_COUNT_SHIFT) | ctx->ctxprog_reg); | ||
54 | } | ||
55 | |||
56 | static inline void | ||
57 | cp_name(struct nouveau_grctx *ctx, int name) | ||
58 | { | ||
59 | uint32_t *ctxprog = ctx->data; | ||
60 | int i; | ||
61 | |||
62 | if (ctx->mode != NOUVEAU_GRCTX_PROG) | ||
63 | return; | ||
64 | |||
65 | ctx->ctxprog_label[name] = ctx->ctxprog_len; | ||
66 | for (i = 0; i < ctx->ctxprog_len; i++) { | ||
67 | if ((ctxprog[i] & 0xfff00000) != 0xff400000) | ||
68 | continue; | ||
69 | if ((ctxprog[i] & CP_BRA_IP) != ((name) << CP_BRA_IP_SHIFT)) | ||
70 | continue; | ||
71 | ctxprog[i] = (ctxprog[i] & 0x00ff00ff) | | ||
72 | (ctx->ctxprog_len << CP_BRA_IP_SHIFT); | ||
73 | } | ||
74 | } | ||
75 | |||
76 | static inline void | ||
77 | _cp_bra(struct nouveau_grctx *ctx, u32 mod, int flag, int state, int name) | ||
78 | { | ||
79 | int ip = 0; | ||
80 | |||
81 | if (mod != 2) { | ||
82 | ip = ctx->ctxprog_label[name] << CP_BRA_IP_SHIFT; | ||
83 | if (ip == 0) | ||
84 | ip = 0xff000000 | (name << CP_BRA_IP_SHIFT); | ||
85 | } | ||
86 | |||
87 | cp_out(ctx, CP_BRA | (mod << 18) | ip | flag | | ||
88 | (state ? 0 : CP_BRA_IF_CLEAR)); | ||
89 | } | ||
90 | #define cp_bra(c,f,s,n) _cp_bra((c), 0, CP_FLAG_##f, CP_FLAG_##f##_##s, n) | ||
91 | #ifdef CP_BRA_MOD | ||
92 | #define cp_cal(c,f,s,n) _cp_bra((c), 1, CP_FLAG_##f, CP_FLAG_##f##_##s, n) | ||
93 | #define cp_ret(c,f,s) _cp_bra((c), 2, CP_FLAG_##f, CP_FLAG_##f##_##s, 0) | ||
94 | #endif | ||
95 | |||
96 | static inline void | ||
97 | _cp_wait(struct nouveau_grctx *ctx, int flag, int state) | ||
98 | { | ||
99 | cp_out(ctx, CP_WAIT | flag | (state ? CP_WAIT_SET : 0)); | ||
100 | } | ||
101 | #define cp_wait(c,f,s) _cp_wait((c), CP_FLAG_##f, CP_FLAG_##f##_##s) | ||
102 | |||
103 | static inline void | ||
104 | _cp_set(struct nouveau_grctx *ctx, int flag, int state) | ||
105 | { | ||
106 | cp_out(ctx, CP_SET | flag | (state ? CP_SET_1 : 0)); | ||
107 | } | ||
108 | #define cp_set(c,f,s) _cp_set((c), CP_FLAG_##f, CP_FLAG_##f##_##s) | ||
109 | |||
110 | static inline void | ||
111 | cp_pos(struct nouveau_grctx *ctx, int offset) | ||
112 | { | ||
113 | ctx->ctxvals_pos = offset; | ||
114 | ctx->ctxvals_base = ctx->ctxvals_pos; | ||
115 | |||
116 | cp_lsr(ctx, ctx->ctxvals_pos); | ||
117 | cp_out(ctx, CP_SET_CONTEXT_POINTER); | ||
118 | } | ||
119 | |||
120 | static inline void | ||
121 | gr_def(struct nouveau_grctx *ctx, uint32_t reg, uint32_t val) | ||
122 | { | ||
123 | if (ctx->mode != NOUVEAU_GRCTX_VALS) | ||
124 | return; | ||
125 | |||
126 | reg = (reg - 0x00400000) / 4; | ||
127 | reg = (reg - ctx->ctxprog_reg) + ctx->ctxvals_base; | ||
128 | |||
129 | nv_wo32(ctx->dev, ctx->data, reg, val); | ||
130 | } | ||
131 | #endif | ||
132 | |||
133 | #endif | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_ioc32.c b/drivers/gpu/drm/nouveau/nouveau_ioc32.c index a2c30f4611ba..475ba810bba3 100644 --- a/drivers/gpu/drm/nouveau/nouveau_ioc32.c +++ b/drivers/gpu/drm/nouveau/nouveau_ioc32.c | |||
@@ -61,12 +61,10 @@ long nouveau_compat_ioctl(struct file *filp, unsigned int cmd, | |||
61 | if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(mga_compat_ioctls)) | 61 | if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(mga_compat_ioctls)) |
62 | fn = nouveau_compat_ioctls[nr - DRM_COMMAND_BASE]; | 62 | fn = nouveau_compat_ioctls[nr - DRM_COMMAND_BASE]; |
63 | #endif | 63 | #endif |
64 | lock_kernel(); /* XXX for now */ | ||
65 | if (fn != NULL) | 64 | if (fn != NULL) |
66 | ret = (*fn)(filp, cmd, arg); | 65 | ret = (*fn)(filp, cmd, arg); |
67 | else | 66 | else |
68 | ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg); | 67 | ret = drm_ioctl(filp, cmd, arg); |
69 | unlock_kernel(); | ||
70 | 68 | ||
71 | return ret; | 69 | return ret; |
72 | } | 70 | } |
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 2ed41d339f6a..e76ec2d207a9 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c | |||
@@ -299,12 +299,57 @@ nouveau_vga_set_decode(void *priv, bool state) | |||
299 | return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM; | 299 | return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM; |
300 | } | 300 | } |
301 | 301 | ||
302 | static int | ||
303 | nouveau_card_init_channel(struct drm_device *dev) | ||
304 | { | ||
305 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
306 | struct nouveau_gpuobj *gpuobj; | ||
307 | int ret; | ||
308 | |||
309 | ret = nouveau_channel_alloc(dev, &dev_priv->channel, | ||
310 | (struct drm_file *)-2, | ||
311 | NvDmaFB, NvDmaTT); | ||
312 | if (ret) | ||
313 | return ret; | ||
314 | |||
315 | gpuobj = NULL; | ||
316 | ret = nouveau_gpuobj_dma_new(dev_priv->channel, NV_CLASS_DMA_IN_MEMORY, | ||
317 | 0, nouveau_mem_fb_amount(dev), | ||
318 | NV_DMA_ACCESS_RW, NV_DMA_TARGET_VIDMEM, | ||
319 | &gpuobj); | ||
320 | if (ret) | ||
321 | goto out_err; | ||
322 | |||
323 | ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, NvDmaVRAM, | ||
324 | gpuobj, NULL); | ||
325 | if (ret) | ||
326 | goto out_err; | ||
327 | |||
328 | gpuobj = NULL; | ||
329 | ret = nouveau_gpuobj_gart_dma_new(dev_priv->channel, 0, | ||
330 | dev_priv->gart_info.aper_size, | ||
331 | NV_DMA_ACCESS_RW, &gpuobj, NULL); | ||
332 | if (ret) | ||
333 | goto out_err; | ||
334 | |||
335 | ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, NvDmaGART, | ||
336 | gpuobj, NULL); | ||
337 | if (ret) | ||
338 | goto out_err; | ||
339 | |||
340 | return 0; | ||
341 | out_err: | ||
342 | nouveau_gpuobj_del(dev, &gpuobj); | ||
343 | nouveau_channel_free(dev_priv->channel); | ||
344 | dev_priv->channel = NULL; | ||
345 | return ret; | ||
346 | } | ||
347 | |||
302 | int | 348 | int |
303 | nouveau_card_init(struct drm_device *dev) | 349 | nouveau_card_init(struct drm_device *dev) |
304 | { | 350 | { |
305 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 351 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
306 | struct nouveau_engine *engine; | 352 | struct nouveau_engine *engine; |
307 | struct nouveau_gpuobj *gpuobj; | ||
308 | int ret; | 353 | int ret; |
309 | 354 | ||
310 | NV_DEBUG(dev, "prev state = %d\n", dev_priv->init_state); | 355 | NV_DEBUG(dev, "prev state = %d\n", dev_priv->init_state); |
@@ -317,7 +362,7 @@ nouveau_card_init(struct drm_device *dev) | |||
317 | /* Initialise internal driver API hooks */ | 362 | /* Initialise internal driver API hooks */ |
318 | ret = nouveau_init_engine_ptrs(dev); | 363 | ret = nouveau_init_engine_ptrs(dev); |
319 | if (ret) | 364 | if (ret) |
320 | return ret; | 365 | goto out; |
321 | engine = &dev_priv->engine; | 366 | engine = &dev_priv->engine; |
322 | dev_priv->init_state = NOUVEAU_CARD_INIT_FAILED; | 367 | dev_priv->init_state = NOUVEAU_CARD_INIT_FAILED; |
323 | 368 | ||
@@ -325,12 +370,12 @@ nouveau_card_init(struct drm_device *dev) | |||
325 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | 370 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { |
326 | ret = nouveau_bios_init(dev); | 371 | ret = nouveau_bios_init(dev); |
327 | if (ret) | 372 | if (ret) |
328 | return ret; | 373 | goto out; |
329 | } | 374 | } |
330 | 375 | ||
331 | ret = nouveau_gpuobj_early_init(dev); | 376 | ret = nouveau_gpuobj_early_init(dev); |
332 | if (ret) | 377 | if (ret) |
333 | return ret; | 378 | goto out_bios; |
334 | 379 | ||
335 | /* Initialise instance memory, must happen before mem_init so we | 380 | /* Initialise instance memory, must happen before mem_init so we |
336 | * know exactly how much VRAM we're able to use for "normal" | 381 | * know exactly how much VRAM we're able to use for "normal" |
@@ -338,100 +383,68 @@ nouveau_card_init(struct drm_device *dev) | |||
338 | */ | 383 | */ |
339 | ret = engine->instmem.init(dev); | 384 | ret = engine->instmem.init(dev); |
340 | if (ret) | 385 | if (ret) |
341 | return ret; | 386 | goto out_gpuobj_early; |
342 | 387 | ||
343 | /* Setup the memory manager */ | 388 | /* Setup the memory manager */ |
344 | ret = nouveau_mem_init(dev); | 389 | ret = nouveau_mem_init(dev); |
345 | if (ret) | 390 | if (ret) |
346 | return ret; | 391 | goto out_instmem; |
347 | 392 | ||
348 | ret = nouveau_gpuobj_init(dev); | 393 | ret = nouveau_gpuobj_init(dev); |
349 | if (ret) | 394 | if (ret) |
350 | return ret; | 395 | goto out_mem; |
351 | 396 | ||
352 | /* PMC */ | 397 | /* PMC */ |
353 | ret = engine->mc.init(dev); | 398 | ret = engine->mc.init(dev); |
354 | if (ret) | 399 | if (ret) |
355 | return ret; | 400 | goto out_gpuobj; |
356 | 401 | ||
357 | /* PTIMER */ | 402 | /* PTIMER */ |
358 | ret = engine->timer.init(dev); | 403 | ret = engine->timer.init(dev); |
359 | if (ret) | 404 | if (ret) |
360 | return ret; | 405 | goto out_mc; |
361 | 406 | ||
362 | /* PFB */ | 407 | /* PFB */ |
363 | ret = engine->fb.init(dev); | 408 | ret = engine->fb.init(dev); |
364 | if (ret) | 409 | if (ret) |
365 | return ret; | 410 | goto out_timer; |
366 | 411 | ||
367 | /* PGRAPH */ | 412 | /* PGRAPH */ |
368 | ret = engine->graph.init(dev); | 413 | ret = engine->graph.init(dev); |
369 | if (ret) | 414 | if (ret) |
370 | return ret; | 415 | goto out_fb; |
371 | 416 | ||
372 | /* PFIFO */ | 417 | /* PFIFO */ |
373 | ret = engine->fifo.init(dev); | 418 | ret = engine->fifo.init(dev); |
374 | if (ret) | 419 | if (ret) |
375 | return ret; | 420 | goto out_graph; |
376 | 421 | ||
377 | /* this call irq_preinstall, register irq handler and | 422 | /* this call irq_preinstall, register irq handler and |
378 | * call irq_postinstall | 423 | * call irq_postinstall |
379 | */ | 424 | */ |
380 | ret = drm_irq_install(dev); | 425 | ret = drm_irq_install(dev); |
381 | if (ret) | 426 | if (ret) |
382 | return ret; | 427 | goto out_fifo; |
383 | 428 | ||
384 | ret = drm_vblank_init(dev, 0); | 429 | ret = drm_vblank_init(dev, 0); |
385 | if (ret) | 430 | if (ret) |
386 | return ret; | 431 | goto out_irq; |
387 | 432 | ||
388 | /* what about PVIDEO/PCRTC/PRAMDAC etc? */ | 433 | /* what about PVIDEO/PCRTC/PRAMDAC etc? */ |
389 | 434 | ||
390 | ret = nouveau_channel_alloc(dev, &dev_priv->channel, | 435 | if (!engine->graph.accel_blocked) { |
391 | (struct drm_file *)-2, | 436 | ret = nouveau_card_init_channel(dev); |
392 | NvDmaFB, NvDmaTT); | 437 | if (ret) |
393 | if (ret) | 438 | goto out_irq; |
394 | return ret; | ||
395 | |||
396 | gpuobj = NULL; | ||
397 | ret = nouveau_gpuobj_dma_new(dev_priv->channel, NV_CLASS_DMA_IN_MEMORY, | ||
398 | 0, nouveau_mem_fb_amount(dev), | ||
399 | NV_DMA_ACCESS_RW, NV_DMA_TARGET_VIDMEM, | ||
400 | &gpuobj); | ||
401 | if (ret) | ||
402 | return ret; | ||
403 | |||
404 | ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, NvDmaVRAM, | ||
405 | gpuobj, NULL); | ||
406 | if (ret) { | ||
407 | nouveau_gpuobj_del(dev, &gpuobj); | ||
408 | return ret; | ||
409 | } | ||
410 | |||
411 | gpuobj = NULL; | ||
412 | ret = nouveau_gpuobj_gart_dma_new(dev_priv->channel, 0, | ||
413 | dev_priv->gart_info.aper_size, | ||
414 | NV_DMA_ACCESS_RW, &gpuobj, NULL); | ||
415 | if (ret) | ||
416 | return ret; | ||
417 | |||
418 | ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, NvDmaGART, | ||
419 | gpuobj, NULL); | ||
420 | if (ret) { | ||
421 | nouveau_gpuobj_del(dev, &gpuobj); | ||
422 | return ret; | ||
423 | } | 439 | } |
424 | 440 | ||
425 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | 441 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { |
426 | if (dev_priv->card_type >= NV_50) { | 442 | if (dev_priv->card_type >= NV_50) |
427 | ret = nv50_display_create(dev); | 443 | ret = nv50_display_create(dev); |
428 | if (ret) | 444 | else |
429 | return ret; | ||
430 | } else { | ||
431 | ret = nv04_display_create(dev); | 445 | ret = nv04_display_create(dev); |
432 | if (ret) | 446 | if (ret) |
433 | return ret; | 447 | goto out_irq; |
434 | } | ||
435 | } | 448 | } |
436 | 449 | ||
437 | ret = nouveau_backlight_init(dev); | 450 | ret = nouveau_backlight_init(dev); |
@@ -444,6 +457,32 @@ nouveau_card_init(struct drm_device *dev) | |||
444 | drm_helper_initial_config(dev); | 457 | drm_helper_initial_config(dev); |
445 | 458 | ||
446 | return 0; | 459 | return 0; |
460 | |||
461 | out_irq: | ||
462 | drm_irq_uninstall(dev); | ||
463 | out_fifo: | ||
464 | engine->fifo.takedown(dev); | ||
465 | out_graph: | ||
466 | engine->graph.takedown(dev); | ||
467 | out_fb: | ||
468 | engine->fb.takedown(dev); | ||
469 | out_timer: | ||
470 | engine->timer.takedown(dev); | ||
471 | out_mc: | ||
472 | engine->mc.takedown(dev); | ||
473 | out_gpuobj: | ||
474 | nouveau_gpuobj_takedown(dev); | ||
475 | out_mem: | ||
476 | nouveau_mem_close(dev); | ||
477 | out_instmem: | ||
478 | engine->instmem.takedown(dev); | ||
479 | out_gpuobj_early: | ||
480 | nouveau_gpuobj_late_takedown(dev); | ||
481 | out_bios: | ||
482 | nouveau_bios_takedown(dev); | ||
483 | out: | ||
484 | vga_client_register(dev->pdev, NULL, NULL, NULL); | ||
485 | return ret; | ||
447 | } | 486 | } |
448 | 487 | ||
449 | static void nouveau_card_takedown(struct drm_device *dev) | 488 | static void nouveau_card_takedown(struct drm_device *dev) |
diff --git a/drivers/gpu/drm/nouveau/nv04_crtc.c b/drivers/gpu/drm/nouveau/nv04_crtc.c index b91363606055..d2f143ed97c1 100644 --- a/drivers/gpu/drm/nouveau/nv04_crtc.c +++ b/drivers/gpu/drm/nouveau/nv04_crtc.c | |||
@@ -143,10 +143,10 @@ static void nv_crtc_calc_state_ext(struct drm_crtc *crtc, struct drm_display_mod | |||
143 | state->pllsel |= nv_crtc->index ? PLLSEL_VPLL2_MASK : PLLSEL_VPLL1_MASK; | 143 | state->pllsel |= nv_crtc->index ? PLLSEL_VPLL2_MASK : PLLSEL_VPLL1_MASK; |
144 | 144 | ||
145 | if (pv->NM2) | 145 | if (pv->NM2) |
146 | NV_TRACE(dev, "vpll: n1 %d n2 %d m1 %d m2 %d log2p %d\n", | 146 | NV_DEBUG_KMS(dev, "vpll: n1 %d n2 %d m1 %d m2 %d log2p %d\n", |
147 | pv->N1, pv->N2, pv->M1, pv->M2, pv->log2P); | 147 | pv->N1, pv->N2, pv->M1, pv->M2, pv->log2P); |
148 | else | 148 | else |
149 | NV_TRACE(dev, "vpll: n %d m %d log2p %d\n", | 149 | NV_DEBUG_KMS(dev, "vpll: n %d m %d log2p %d\n", |
150 | pv->N1, pv->M1, pv->log2P); | 150 | pv->N1, pv->M1, pv->log2P); |
151 | 151 | ||
152 | nv_crtc->cursor.set_offset(nv_crtc, nv_crtc->cursor.offset); | 152 | nv_crtc->cursor.set_offset(nv_crtc, nv_crtc->cursor.offset); |
@@ -160,7 +160,7 @@ nv_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
160 | unsigned char seq1 = 0, crtc17 = 0; | 160 | unsigned char seq1 = 0, crtc17 = 0; |
161 | unsigned char crtc1A; | 161 | unsigned char crtc1A; |
162 | 162 | ||
163 | NV_TRACE(dev, "Setting dpms mode %d on CRTC %d\n", mode, | 163 | NV_DEBUG_KMS(dev, "Setting dpms mode %d on CRTC %d\n", mode, |
164 | nv_crtc->index); | 164 | nv_crtc->index); |
165 | 165 | ||
166 | if (nv_crtc->last_dpms == mode) /* Don't do unnecesary mode changes. */ | 166 | if (nv_crtc->last_dpms == mode) /* Don't do unnecesary mode changes. */ |
@@ -603,7 +603,7 @@ nv_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, | |||
603 | struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); | 603 | struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); |
604 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 604 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
605 | 605 | ||
606 | NV_DEBUG(dev, "CTRC mode on CRTC %d:\n", nv_crtc->index); | 606 | NV_DEBUG_KMS(dev, "CTRC mode on CRTC %d:\n", nv_crtc->index); |
607 | drm_mode_debug_printmodeline(adjusted_mode); | 607 | drm_mode_debug_printmodeline(adjusted_mode); |
608 | 608 | ||
609 | /* unlock must come after turning off FP_TG_CONTROL in output_prepare */ | 609 | /* unlock must come after turning off FP_TG_CONTROL in output_prepare */ |
@@ -703,7 +703,7 @@ static void nv_crtc_destroy(struct drm_crtc *crtc) | |||
703 | { | 703 | { |
704 | struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); | 704 | struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); |
705 | 705 | ||
706 | NV_DEBUG(crtc->dev, "\n"); | 706 | NV_DEBUG_KMS(crtc->dev, "\n"); |
707 | 707 | ||
708 | if (!nv_crtc) | 708 | if (!nv_crtc) |
709 | return; | 709 | return; |
diff --git a/drivers/gpu/drm/nouveau/nv04_dac.c b/drivers/gpu/drm/nouveau/nv04_dac.c index a5fa51714e87..d9f32879ba38 100644 --- a/drivers/gpu/drm/nouveau/nv04_dac.c +++ b/drivers/gpu/drm/nouveau/nv04_dac.c | |||
@@ -205,7 +205,7 @@ out: | |||
205 | NVWriteVgaSeq(dev, 0, NV_VIO_SR_CLOCK_INDEX, saved_seq1); | 205 | NVWriteVgaSeq(dev, 0, NV_VIO_SR_CLOCK_INDEX, saved_seq1); |
206 | 206 | ||
207 | if (blue == 0x18) { | 207 | if (blue == 0x18) { |
208 | NV_TRACE(dev, "Load detected on head A\n"); | 208 | NV_INFO(dev, "Load detected on head A\n"); |
209 | return connector_status_connected; | 209 | return connector_status_connected; |
210 | } | 210 | } |
211 | 211 | ||
@@ -350,14 +350,10 @@ static void nv04_dac_mode_set(struct drm_encoder *encoder, | |||
350 | struct drm_display_mode *mode, | 350 | struct drm_display_mode *mode, |
351 | struct drm_display_mode *adjusted_mode) | 351 | struct drm_display_mode *adjusted_mode) |
352 | { | 352 | { |
353 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | ||
354 | struct drm_device *dev = encoder->dev; | 353 | struct drm_device *dev = encoder->dev; |
355 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 354 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
356 | int head = nouveau_crtc(encoder->crtc)->index; | 355 | int head = nouveau_crtc(encoder->crtc)->index; |
357 | 356 | ||
358 | NV_TRACE(dev, "%s called for encoder %d\n", __func__, | ||
359 | nv_encoder->dcb->index); | ||
360 | |||
361 | if (nv_gf4_disp_arch(dev)) { | 357 | if (nv_gf4_disp_arch(dev)) { |
362 | struct drm_encoder *rebind; | 358 | struct drm_encoder *rebind; |
363 | uint32_t dac_offset = nv04_dac_output_offset(encoder); | 359 | uint32_t dac_offset = nv04_dac_output_offset(encoder); |
@@ -466,7 +462,7 @@ static void nv04_dac_destroy(struct drm_encoder *encoder) | |||
466 | { | 462 | { |
467 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | 463 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); |
468 | 464 | ||
469 | NV_DEBUG(encoder->dev, "\n"); | 465 | NV_DEBUG_KMS(encoder->dev, "\n"); |
470 | 466 | ||
471 | drm_encoder_cleanup(encoder); | 467 | drm_encoder_cleanup(encoder); |
472 | kfree(nv_encoder); | 468 | kfree(nv_encoder); |
diff --git a/drivers/gpu/drm/nouveau/nv04_dfp.c b/drivers/gpu/drm/nouveau/nv04_dfp.c index e5b33339d595..483f875bdb6a 100644 --- a/drivers/gpu/drm/nouveau/nv04_dfp.c +++ b/drivers/gpu/drm/nouveau/nv04_dfp.c | |||
@@ -261,7 +261,7 @@ static void nv04_dfp_mode_set(struct drm_encoder *encoder, | |||
261 | struct drm_display_mode *output_mode = &nv_encoder->mode; | 261 | struct drm_display_mode *output_mode = &nv_encoder->mode; |
262 | uint32_t mode_ratio, panel_ratio; | 262 | uint32_t mode_ratio, panel_ratio; |
263 | 263 | ||
264 | NV_DEBUG(dev, "Output mode on CRTC %d:\n", nv_crtc->index); | 264 | NV_DEBUG_KMS(dev, "Output mode on CRTC %d:\n", nv_crtc->index); |
265 | drm_mode_debug_printmodeline(output_mode); | 265 | drm_mode_debug_printmodeline(output_mode); |
266 | 266 | ||
267 | /* Initialize the FP registers in this CRTC. */ | 267 | /* Initialize the FP registers in this CRTC. */ |
@@ -413,7 +413,9 @@ static void nv04_dfp_commit(struct drm_encoder *encoder) | |||
413 | struct dcb_entry *dcbe = nv_encoder->dcb; | 413 | struct dcb_entry *dcbe = nv_encoder->dcb; |
414 | int head = nouveau_crtc(encoder->crtc)->index; | 414 | int head = nouveau_crtc(encoder->crtc)->index; |
415 | 415 | ||
416 | NV_TRACE(dev, "%s called for encoder %d\n", __func__, nv_encoder->dcb->index); | 416 | NV_INFO(dev, "Output %s is running on CRTC %d using output %c\n", |
417 | drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), | ||
418 | nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); | ||
417 | 419 | ||
418 | if (dcbe->type == OUTPUT_TMDS) | 420 | if (dcbe->type == OUTPUT_TMDS) |
419 | run_tmds_table(dev, dcbe, head, nv_encoder->mode.clock); | 421 | run_tmds_table(dev, dcbe, head, nv_encoder->mode.clock); |
@@ -550,7 +552,7 @@ static void nv04_dfp_destroy(struct drm_encoder *encoder) | |||
550 | { | 552 | { |
551 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | 553 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); |
552 | 554 | ||
553 | NV_DEBUG(encoder->dev, "\n"); | 555 | NV_DEBUG_KMS(encoder->dev, "\n"); |
554 | 556 | ||
555 | drm_encoder_cleanup(encoder); | 557 | drm_encoder_cleanup(encoder); |
556 | kfree(nv_encoder); | 558 | kfree(nv_encoder); |
diff --git a/drivers/gpu/drm/nouveau/nv04_display.c b/drivers/gpu/drm/nouveau/nv04_display.c index b47c757ff48b..ef77215fa5b9 100644 --- a/drivers/gpu/drm/nouveau/nv04_display.c +++ b/drivers/gpu/drm/nouveau/nv04_display.c | |||
@@ -99,10 +99,11 @@ nv04_display_create(struct drm_device *dev) | |||
99 | uint16_t connector[16] = { 0 }; | 99 | uint16_t connector[16] = { 0 }; |
100 | int i, ret; | 100 | int i, ret; |
101 | 101 | ||
102 | NV_DEBUG(dev, "\n"); | 102 | NV_DEBUG_KMS(dev, "\n"); |
103 | 103 | ||
104 | if (nv_two_heads(dev)) | 104 | if (nv_two_heads(dev)) |
105 | nv04_display_store_initial_head_owner(dev); | 105 | nv04_display_store_initial_head_owner(dev); |
106 | nouveau_hw_save_vga_fonts(dev, 1); | ||
106 | 107 | ||
107 | drm_mode_config_init(dev); | 108 | drm_mode_config_init(dev); |
108 | drm_mode_create_scaling_mode_property(dev); | 109 | drm_mode_create_scaling_mode_property(dev); |
@@ -203,8 +204,6 @@ nv04_display_create(struct drm_device *dev) | |||
203 | /* Save previous state */ | 204 | /* Save previous state */ |
204 | NVLockVgaCrtcs(dev, false); | 205 | NVLockVgaCrtcs(dev, false); |
205 | 206 | ||
206 | nouveau_hw_save_vga_fonts(dev, 1); | ||
207 | |||
208 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) | 207 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) |
209 | crtc->funcs->save(crtc); | 208 | crtc->funcs->save(crtc); |
210 | 209 | ||
@@ -223,7 +222,7 @@ nv04_display_destroy(struct drm_device *dev) | |||
223 | struct drm_encoder *encoder; | 222 | struct drm_encoder *encoder; |
224 | struct drm_crtc *crtc; | 223 | struct drm_crtc *crtc; |
225 | 224 | ||
226 | NV_DEBUG(dev, "\n"); | 225 | NV_DEBUG_KMS(dev, "\n"); |
227 | 226 | ||
228 | /* Turn every CRTC off. */ | 227 | /* Turn every CRTC off. */ |
229 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | 228 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
@@ -246,9 +245,9 @@ nv04_display_destroy(struct drm_device *dev) | |||
246 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) | 245 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) |
247 | crtc->funcs->restore(crtc); | 246 | crtc->funcs->restore(crtc); |
248 | 247 | ||
249 | nouveau_hw_save_vga_fonts(dev, 0); | ||
250 | |||
251 | drm_mode_config_cleanup(dev); | 248 | drm_mode_config_cleanup(dev); |
249 | |||
250 | nouveau_hw_save_vga_fonts(dev, 0); | ||
252 | } | 251 | } |
253 | 252 | ||
254 | void | 253 | void |
diff --git a/drivers/gpu/drm/nouveau/nv04_graph.c b/drivers/gpu/drm/nouveau/nv04_graph.c index 396ee92118f6..d561d773c0f4 100644 --- a/drivers/gpu/drm/nouveau/nv04_graph.c +++ b/drivers/gpu/drm/nouveau/nv04_graph.c | |||
@@ -543,7 +543,7 @@ nv04_graph_mthd_set_operation(struct nouveau_channel *chan, int grclass, | |||
543 | 543 | ||
544 | nv_wi32(dev, instance, tmp); | 544 | nv_wi32(dev, instance, tmp); |
545 | nv_wr32(dev, NV04_PGRAPH_CTX_SWITCH1, tmp); | 545 | nv_wr32(dev, NV04_PGRAPH_CTX_SWITCH1, tmp); |
546 | nv_wr32(dev, NV04_PGRAPH_CTX_CACHE1 + subc, tmp); | 546 | nv_wr32(dev, NV04_PGRAPH_CTX_CACHE1 + (subc<<2), tmp); |
547 | return 0; | 547 | return 0; |
548 | } | 548 | } |
549 | 549 | ||
diff --git a/drivers/gpu/drm/nouveau/nv10_graph.c b/drivers/gpu/drm/nouveau/nv10_graph.c index 6bf6804bb0ef..6870e0ee2e7e 100644 --- a/drivers/gpu/drm/nouveau/nv10_graph.c +++ b/drivers/gpu/drm/nouveau/nv10_graph.c | |||
@@ -389,49 +389,50 @@ struct graph_state { | |||
389 | int nv10[ARRAY_SIZE(nv10_graph_ctx_regs)]; | 389 | int nv10[ARRAY_SIZE(nv10_graph_ctx_regs)]; |
390 | int nv17[ARRAY_SIZE(nv17_graph_ctx_regs)]; | 390 | int nv17[ARRAY_SIZE(nv17_graph_ctx_regs)]; |
391 | struct pipe_state pipe_state; | 391 | struct pipe_state pipe_state; |
392 | uint32_t lma_window[4]; | ||
392 | }; | 393 | }; |
393 | 394 | ||
395 | #define PIPE_SAVE(dev, state, addr) \ | ||
396 | do { \ | ||
397 | int __i; \ | ||
398 | nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, addr); \ | ||
399 | for (__i = 0; __i < ARRAY_SIZE(state); __i++) \ | ||
400 | state[__i] = nv_rd32(dev, NV10_PGRAPH_PIPE_DATA); \ | ||
401 | } while (0) | ||
402 | |||
403 | #define PIPE_RESTORE(dev, state, addr) \ | ||
404 | do { \ | ||
405 | int __i; \ | ||
406 | nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, addr); \ | ||
407 | for (__i = 0; __i < ARRAY_SIZE(state); __i++) \ | ||
408 | nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, state[__i]); \ | ||
409 | } while (0) | ||
410 | |||
394 | static void nv10_graph_save_pipe(struct nouveau_channel *chan) | 411 | static void nv10_graph_save_pipe(struct nouveau_channel *chan) |
395 | { | 412 | { |
396 | struct drm_device *dev = chan->dev; | 413 | struct drm_device *dev = chan->dev; |
397 | struct graph_state *pgraph_ctx = chan->pgraph_ctx; | 414 | struct graph_state *pgraph_ctx = chan->pgraph_ctx; |
398 | struct pipe_state *fifo_pipe_state = &pgraph_ctx->pipe_state; | 415 | struct pipe_state *pipe = &pgraph_ctx->pipe_state; |
399 | int i; | 416 | |
400 | #define PIPE_SAVE(addr) \ | 417 | PIPE_SAVE(dev, pipe->pipe_0x4400, 0x4400); |
401 | do { \ | 418 | PIPE_SAVE(dev, pipe->pipe_0x0200, 0x0200); |
402 | nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, addr); \ | 419 | PIPE_SAVE(dev, pipe->pipe_0x6400, 0x6400); |
403 | for (i = 0; i < ARRAY_SIZE(fifo_pipe_state->pipe_##addr); i++) \ | 420 | PIPE_SAVE(dev, pipe->pipe_0x6800, 0x6800); |
404 | fifo_pipe_state->pipe_##addr[i] = nv_rd32(dev, NV10_PGRAPH_PIPE_DATA); \ | 421 | PIPE_SAVE(dev, pipe->pipe_0x6c00, 0x6c00); |
405 | } while (0) | 422 | PIPE_SAVE(dev, pipe->pipe_0x7000, 0x7000); |
406 | 423 | PIPE_SAVE(dev, pipe->pipe_0x7400, 0x7400); | |
407 | PIPE_SAVE(0x4400); | 424 | PIPE_SAVE(dev, pipe->pipe_0x7800, 0x7800); |
408 | PIPE_SAVE(0x0200); | 425 | PIPE_SAVE(dev, pipe->pipe_0x0040, 0x0040); |
409 | PIPE_SAVE(0x6400); | 426 | PIPE_SAVE(dev, pipe->pipe_0x0000, 0x0000); |
410 | PIPE_SAVE(0x6800); | ||
411 | PIPE_SAVE(0x6c00); | ||
412 | PIPE_SAVE(0x7000); | ||
413 | PIPE_SAVE(0x7400); | ||
414 | PIPE_SAVE(0x7800); | ||
415 | PIPE_SAVE(0x0040); | ||
416 | PIPE_SAVE(0x0000); | ||
417 | |||
418 | #undef PIPE_SAVE | ||
419 | } | 427 | } |
420 | 428 | ||
421 | static void nv10_graph_load_pipe(struct nouveau_channel *chan) | 429 | static void nv10_graph_load_pipe(struct nouveau_channel *chan) |
422 | { | 430 | { |
423 | struct drm_device *dev = chan->dev; | 431 | struct drm_device *dev = chan->dev; |
424 | struct graph_state *pgraph_ctx = chan->pgraph_ctx; | 432 | struct graph_state *pgraph_ctx = chan->pgraph_ctx; |
425 | struct pipe_state *fifo_pipe_state = &pgraph_ctx->pipe_state; | 433 | struct pipe_state *pipe = &pgraph_ctx->pipe_state; |
426 | int i; | ||
427 | uint32_t xfmode0, xfmode1; | 434 | uint32_t xfmode0, xfmode1; |
428 | #define PIPE_RESTORE(addr) \ | 435 | int i; |
429 | do { \ | ||
430 | nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, addr); \ | ||
431 | for (i = 0; i < ARRAY_SIZE(fifo_pipe_state->pipe_##addr); i++) \ | ||
432 | nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, fifo_pipe_state->pipe_##addr[i]); \ | ||
433 | } while (0) | ||
434 | |||
435 | 436 | ||
436 | nouveau_wait_for_idle(dev); | 437 | nouveau_wait_for_idle(dev); |
437 | /* XXX check haiku comments */ | 438 | /* XXX check haiku comments */ |
@@ -457,24 +458,22 @@ static void nv10_graph_load_pipe(struct nouveau_channel *chan) | |||
457 | nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000008); | 458 | nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000008); |
458 | 459 | ||
459 | 460 | ||
460 | PIPE_RESTORE(0x0200); | 461 | PIPE_RESTORE(dev, pipe->pipe_0x0200, 0x0200); |
461 | nouveau_wait_for_idle(dev); | 462 | nouveau_wait_for_idle(dev); |
462 | 463 | ||
463 | /* restore XFMODE */ | 464 | /* restore XFMODE */ |
464 | nv_wr32(dev, NV10_PGRAPH_XFMODE0, xfmode0); | 465 | nv_wr32(dev, NV10_PGRAPH_XFMODE0, xfmode0); |
465 | nv_wr32(dev, NV10_PGRAPH_XFMODE1, xfmode1); | 466 | nv_wr32(dev, NV10_PGRAPH_XFMODE1, xfmode1); |
466 | PIPE_RESTORE(0x6400); | 467 | PIPE_RESTORE(dev, pipe->pipe_0x6400, 0x6400); |
467 | PIPE_RESTORE(0x6800); | 468 | PIPE_RESTORE(dev, pipe->pipe_0x6800, 0x6800); |
468 | PIPE_RESTORE(0x6c00); | 469 | PIPE_RESTORE(dev, pipe->pipe_0x6c00, 0x6c00); |
469 | PIPE_RESTORE(0x7000); | 470 | PIPE_RESTORE(dev, pipe->pipe_0x7000, 0x7000); |
470 | PIPE_RESTORE(0x7400); | 471 | PIPE_RESTORE(dev, pipe->pipe_0x7400, 0x7400); |
471 | PIPE_RESTORE(0x7800); | 472 | PIPE_RESTORE(dev, pipe->pipe_0x7800, 0x7800); |
472 | PIPE_RESTORE(0x4400); | 473 | PIPE_RESTORE(dev, pipe->pipe_0x4400, 0x4400); |
473 | PIPE_RESTORE(0x0000); | 474 | PIPE_RESTORE(dev, pipe->pipe_0x0000, 0x0000); |
474 | PIPE_RESTORE(0x0040); | 475 | PIPE_RESTORE(dev, pipe->pipe_0x0040, 0x0040); |
475 | nouveau_wait_for_idle(dev); | 476 | nouveau_wait_for_idle(dev); |
476 | |||
477 | #undef PIPE_RESTORE | ||
478 | } | 477 | } |
479 | 478 | ||
480 | static void nv10_graph_create_pipe(struct nouveau_channel *chan) | 479 | static void nv10_graph_create_pipe(struct nouveau_channel *chan) |
@@ -832,6 +831,9 @@ int nv10_graph_init(struct drm_device *dev) | |||
832 | (1<<31)); | 831 | (1<<31)); |
833 | if (dev_priv->chipset >= 0x17) { | 832 | if (dev_priv->chipset >= 0x17) { |
834 | nv_wr32(dev, NV10_PGRAPH_DEBUG_4, 0x1f000000); | 833 | nv_wr32(dev, NV10_PGRAPH_DEBUG_4, 0x1f000000); |
834 | nv_wr32(dev, 0x400a10, 0x3ff3fb6); | ||
835 | nv_wr32(dev, 0x400838, 0x2f8684); | ||
836 | nv_wr32(dev, 0x40083c, 0x115f3f); | ||
835 | nv_wr32(dev, 0x004006b0, 0x40000020); | 837 | nv_wr32(dev, 0x004006b0, 0x40000020); |
836 | } else | 838 | } else |
837 | nv_wr32(dev, NV10_PGRAPH_DEBUG_4, 0x00000000); | 839 | nv_wr32(dev, NV10_PGRAPH_DEBUG_4, 0x00000000); |
@@ -867,6 +869,115 @@ void nv10_graph_takedown(struct drm_device *dev) | |||
867 | { | 869 | { |
868 | } | 870 | } |
869 | 871 | ||
872 | static int | ||
873 | nv17_graph_mthd_lma_window(struct nouveau_channel *chan, int grclass, | ||
874 | int mthd, uint32_t data) | ||
875 | { | ||
876 | struct drm_device *dev = chan->dev; | ||
877 | struct graph_state *ctx = chan->pgraph_ctx; | ||
878 | struct pipe_state *pipe = &ctx->pipe_state; | ||
879 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
880 | struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; | ||
881 | uint32_t pipe_0x0040[1], pipe_0x64c0[8], pipe_0x6a80[3], pipe_0x6ab0[3]; | ||
882 | uint32_t xfmode0, xfmode1; | ||
883 | int i; | ||
884 | |||
885 | ctx->lma_window[(mthd - 0x1638) / 4] = data; | ||
886 | |||
887 | if (mthd != 0x1644) | ||
888 | return 0; | ||
889 | |||
890 | nouveau_wait_for_idle(dev); | ||
891 | |||
892 | PIPE_SAVE(dev, pipe_0x0040, 0x0040); | ||
893 | PIPE_SAVE(dev, pipe->pipe_0x0200, 0x0200); | ||
894 | |||
895 | PIPE_RESTORE(dev, ctx->lma_window, 0x6790); | ||
896 | |||
897 | nouveau_wait_for_idle(dev); | ||
898 | |||
899 | xfmode0 = nv_rd32(dev, NV10_PGRAPH_XFMODE0); | ||
900 | xfmode1 = nv_rd32(dev, NV10_PGRAPH_XFMODE1); | ||
901 | |||
902 | PIPE_SAVE(dev, pipe->pipe_0x4400, 0x4400); | ||
903 | PIPE_SAVE(dev, pipe_0x64c0, 0x64c0); | ||
904 | PIPE_SAVE(dev, pipe_0x6ab0, 0x6ab0); | ||
905 | PIPE_SAVE(dev, pipe_0x6a80, 0x6a80); | ||
906 | |||
907 | nouveau_wait_for_idle(dev); | ||
908 | |||
909 | nv_wr32(dev, NV10_PGRAPH_XFMODE0, 0x10000000); | ||
910 | nv_wr32(dev, NV10_PGRAPH_XFMODE1, 0x00000000); | ||
911 | nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x000064c0); | ||
912 | for (i = 0; i < 4; i++) | ||
913 | nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x3f800000); | ||
914 | for (i = 0; i < 4; i++) | ||
915 | nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000000); | ||
916 | |||
917 | nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00006ab0); | ||
918 | for (i = 0; i < 3; i++) | ||
919 | nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x3f800000); | ||
920 | |||
921 | nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00006a80); | ||
922 | for (i = 0; i < 3; i++) | ||
923 | nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000000); | ||
924 | |||
925 | nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00000040); | ||
926 | nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000008); | ||
927 | |||
928 | PIPE_RESTORE(dev, pipe->pipe_0x0200, 0x0200); | ||
929 | |||
930 | nouveau_wait_for_idle(dev); | ||
931 | |||
932 | PIPE_RESTORE(dev, pipe_0x0040, 0x0040); | ||
933 | |||
934 | nv_wr32(dev, NV10_PGRAPH_XFMODE0, xfmode0); | ||
935 | nv_wr32(dev, NV10_PGRAPH_XFMODE1, xfmode1); | ||
936 | |||
937 | PIPE_RESTORE(dev, pipe_0x64c0, 0x64c0); | ||
938 | PIPE_RESTORE(dev, pipe_0x6ab0, 0x6ab0); | ||
939 | PIPE_RESTORE(dev, pipe_0x6a80, 0x6a80); | ||
940 | PIPE_RESTORE(dev, pipe->pipe_0x4400, 0x4400); | ||
941 | |||
942 | nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x000000c0); | ||
943 | nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000000); | ||
944 | |||
945 | nouveau_wait_for_idle(dev); | ||
946 | |||
947 | pgraph->fifo_access(dev, true); | ||
948 | |||
949 | return 0; | ||
950 | } | ||
951 | |||
952 | static int | ||
953 | nv17_graph_mthd_lma_enable(struct nouveau_channel *chan, int grclass, | ||
954 | int mthd, uint32_t data) | ||
955 | { | ||
956 | struct drm_device *dev = chan->dev; | ||
957 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
958 | struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; | ||
959 | |||
960 | nouveau_wait_for_idle(dev); | ||
961 | |||
962 | nv_wr32(dev, NV10_PGRAPH_DEBUG_4, | ||
963 | nv_rd32(dev, NV10_PGRAPH_DEBUG_4) | 0x1 << 8); | ||
964 | nv_wr32(dev, 0x004006b0, | ||
965 | nv_rd32(dev, 0x004006b0) | 0x8 << 24); | ||
966 | |||
967 | pgraph->fifo_access(dev, true); | ||
968 | |||
969 | return 0; | ||
970 | } | ||
971 | |||
972 | static struct nouveau_pgraph_object_method nv17_graph_celsius_mthds[] = { | ||
973 | { 0x1638, nv17_graph_mthd_lma_window }, | ||
974 | { 0x163c, nv17_graph_mthd_lma_window }, | ||
975 | { 0x1640, nv17_graph_mthd_lma_window }, | ||
976 | { 0x1644, nv17_graph_mthd_lma_window }, | ||
977 | { 0x1658, nv17_graph_mthd_lma_enable }, | ||
978 | {} | ||
979 | }; | ||
980 | |||
870 | struct nouveau_pgraph_object_class nv10_graph_grclass[] = { | 981 | struct nouveau_pgraph_object_class nv10_graph_grclass[] = { |
871 | { 0x0030, false, NULL }, /* null */ | 982 | { 0x0030, false, NULL }, /* null */ |
872 | { 0x0039, false, NULL }, /* m2mf */ | 983 | { 0x0039, false, NULL }, /* m2mf */ |
@@ -887,6 +998,6 @@ struct nouveau_pgraph_object_class nv10_graph_grclass[] = { | |||
887 | { 0x0095, false, NULL }, /* multitex_tri */ | 998 | { 0x0095, false, NULL }, /* multitex_tri */ |
888 | { 0x0056, false, NULL }, /* celcius (nv10) */ | 999 | { 0x0056, false, NULL }, /* celcius (nv10) */ |
889 | { 0x0096, false, NULL }, /* celcius (nv11) */ | 1000 | { 0x0096, false, NULL }, /* celcius (nv11) */ |
890 | { 0x0099, false, NULL }, /* celcius (nv17) */ | 1001 | { 0x0099, false, nv17_graph_celsius_mthds }, /* celcius (nv17) */ |
891 | {} | 1002 | {} |
892 | }; | 1003 | }; |
diff --git a/drivers/gpu/drm/nouveau/nv17_tv.c b/drivers/gpu/drm/nouveau/nv17_tv.c index 46cfd9c60478..81c01353a9f9 100644 --- a/drivers/gpu/drm/nouveau/nv17_tv.c +++ b/drivers/gpu/drm/nouveau/nv17_tv.c | |||
@@ -219,7 +219,7 @@ static void nv17_tv_dpms(struct drm_encoder *encoder, int mode) | |||
219 | return; | 219 | return; |
220 | nouveau_encoder(encoder)->last_dpms = mode; | 220 | nouveau_encoder(encoder)->last_dpms = mode; |
221 | 221 | ||
222 | NV_TRACE(dev, "Setting dpms mode %d on TV encoder (output %d)\n", | 222 | NV_INFO(dev, "Setting dpms mode %d on TV encoder (output %d)\n", |
223 | mode, nouveau_encoder(encoder)->dcb->index); | 223 | mode, nouveau_encoder(encoder)->dcb->index); |
224 | 224 | ||
225 | regs->ptv_200 &= ~1; | 225 | regs->ptv_200 &= ~1; |
@@ -619,7 +619,7 @@ static void nv17_tv_destroy(struct drm_encoder *encoder) | |||
619 | { | 619 | { |
620 | struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder); | 620 | struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder); |
621 | 621 | ||
622 | NV_DEBUG(encoder->dev, "\n"); | 622 | NV_DEBUG_KMS(encoder->dev, "\n"); |
623 | 623 | ||
624 | drm_encoder_cleanup(encoder); | 624 | drm_encoder_cleanup(encoder); |
625 | kfree(tv_enc); | 625 | kfree(tv_enc); |
diff --git a/drivers/gpu/drm/nouveau/nv40_graph.c b/drivers/gpu/drm/nouveau/nv40_graph.c index 7e8547cb5833..2b332bb55acf 100644 --- a/drivers/gpu/drm/nouveau/nv40_graph.c +++ b/drivers/gpu/drm/nouveau/nv40_graph.c | |||
@@ -24,36 +24,10 @@ | |||
24 | * | 24 | * |
25 | */ | 25 | */ |
26 | 26 | ||
27 | #include <linux/firmware.h> | ||
28 | |||
29 | #include "drmP.h" | 27 | #include "drmP.h" |
30 | #include "drm.h" | 28 | #include "drm.h" |
31 | #include "nouveau_drv.h" | 29 | #include "nouveau_drv.h" |
32 | 30 | #include "nouveau_grctx.h" | |
33 | MODULE_FIRMWARE("nouveau/nv40.ctxprog"); | ||
34 | MODULE_FIRMWARE("nouveau/nv40.ctxvals"); | ||
35 | MODULE_FIRMWARE("nouveau/nv41.ctxprog"); | ||
36 | MODULE_FIRMWARE("nouveau/nv41.ctxvals"); | ||
37 | MODULE_FIRMWARE("nouveau/nv42.ctxprog"); | ||
38 | MODULE_FIRMWARE("nouveau/nv42.ctxvals"); | ||
39 | MODULE_FIRMWARE("nouveau/nv43.ctxprog"); | ||
40 | MODULE_FIRMWARE("nouveau/nv43.ctxvals"); | ||
41 | MODULE_FIRMWARE("nouveau/nv44.ctxprog"); | ||
42 | MODULE_FIRMWARE("nouveau/nv44.ctxvals"); | ||
43 | MODULE_FIRMWARE("nouveau/nv46.ctxprog"); | ||
44 | MODULE_FIRMWARE("nouveau/nv46.ctxvals"); | ||
45 | MODULE_FIRMWARE("nouveau/nv47.ctxprog"); | ||
46 | MODULE_FIRMWARE("nouveau/nv47.ctxvals"); | ||
47 | MODULE_FIRMWARE("nouveau/nv49.ctxprog"); | ||
48 | MODULE_FIRMWARE("nouveau/nv49.ctxvals"); | ||
49 | MODULE_FIRMWARE("nouveau/nv4a.ctxprog"); | ||
50 | MODULE_FIRMWARE("nouveau/nv4a.ctxvals"); | ||
51 | MODULE_FIRMWARE("nouveau/nv4b.ctxprog"); | ||
52 | MODULE_FIRMWARE("nouveau/nv4b.ctxvals"); | ||
53 | MODULE_FIRMWARE("nouveau/nv4c.ctxprog"); | ||
54 | MODULE_FIRMWARE("nouveau/nv4c.ctxvals"); | ||
55 | MODULE_FIRMWARE("nouveau/nv4e.ctxprog"); | ||
56 | MODULE_FIRMWARE("nouveau/nv4e.ctxvals"); | ||
57 | 31 | ||
58 | struct nouveau_channel * | 32 | struct nouveau_channel * |
59 | nv40_graph_channel(struct drm_device *dev) | 33 | nv40_graph_channel(struct drm_device *dev) |
@@ -83,27 +57,30 @@ nv40_graph_create_context(struct nouveau_channel *chan) | |||
83 | { | 57 | { |
84 | struct drm_device *dev = chan->dev; | 58 | struct drm_device *dev = chan->dev; |
85 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 59 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
86 | struct nouveau_gpuobj *ctx; | 60 | struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; |
87 | int ret; | 61 | int ret; |
88 | 62 | ||
89 | /* Allocate a 175KiB block of PRAMIN to store the context. This | 63 | ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, pgraph->grctx_size, |
90 | * is massive overkill for a lot of chipsets, but it should be safe | 64 | 16, NVOBJ_FLAG_ZERO_ALLOC, |
91 | * until we're able to implement this properly (will happen at more | 65 | &chan->ramin_grctx); |
92 | * or less the same time we're able to write our own context programs. | ||
93 | */ | ||
94 | ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, 175*1024, 16, | ||
95 | NVOBJ_FLAG_ZERO_ALLOC, | ||
96 | &chan->ramin_grctx); | ||
97 | if (ret) | 66 | if (ret) |
98 | return ret; | 67 | return ret; |
99 | ctx = chan->ramin_grctx->gpuobj; | ||
100 | 68 | ||
101 | /* Initialise default context values */ | 69 | /* Initialise default context values */ |
102 | dev_priv->engine.instmem.prepare_access(dev, true); | 70 | dev_priv->engine.instmem.prepare_access(dev, true); |
103 | nv40_grctx_vals_load(dev, ctx); | 71 | if (!pgraph->ctxprog) { |
104 | nv_wo32(dev, ctx, 0, ctx->im_pramin->start); | 72 | struct nouveau_grctx ctx = {}; |
105 | dev_priv->engine.instmem.finish_access(dev); | ||
106 | 73 | ||
74 | ctx.dev = chan->dev; | ||
75 | ctx.mode = NOUVEAU_GRCTX_VALS; | ||
76 | ctx.data = chan->ramin_grctx->gpuobj; | ||
77 | nv40_grctx_init(&ctx); | ||
78 | } else { | ||
79 | nouveau_grctx_vals_load(dev, chan->ramin_grctx->gpuobj); | ||
80 | } | ||
81 | nv_wo32(dev, chan->ramin_grctx->gpuobj, 0, | ||
82 | chan->ramin_grctx->gpuobj->im_pramin->start); | ||
83 | dev_priv->engine.instmem.finish_access(dev); | ||
107 | return 0; | 84 | return 0; |
108 | } | 85 | } |
109 | 86 | ||
@@ -204,139 +181,6 @@ nv40_graph_unload_context(struct drm_device *dev) | |||
204 | return ret; | 181 | return ret; |
205 | } | 182 | } |
206 | 183 | ||
207 | struct nouveau_ctxprog { | ||
208 | uint32_t signature; | ||
209 | uint8_t version; | ||
210 | uint16_t length; | ||
211 | uint32_t data[]; | ||
212 | } __attribute__ ((packed)); | ||
213 | |||
214 | struct nouveau_ctxvals { | ||
215 | uint32_t signature; | ||
216 | uint8_t version; | ||
217 | uint32_t length; | ||
218 | struct { | ||
219 | uint32_t offset; | ||
220 | uint32_t value; | ||
221 | } data[]; | ||
222 | } __attribute__ ((packed)); | ||
223 | |||
224 | int | ||
225 | nv40_grctx_init(struct drm_device *dev) | ||
226 | { | ||
227 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
228 | struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; | ||
229 | const int chipset = dev_priv->chipset; | ||
230 | const struct firmware *fw; | ||
231 | const struct nouveau_ctxprog *cp; | ||
232 | const struct nouveau_ctxvals *cv; | ||
233 | char name[32]; | ||
234 | int ret, i; | ||
235 | |||
236 | pgraph->accel_blocked = true; | ||
237 | |||
238 | if (!pgraph->ctxprog) { | ||
239 | sprintf(name, "nouveau/nv%02x.ctxprog", chipset); | ||
240 | ret = request_firmware(&fw, name, &dev->pdev->dev); | ||
241 | if (ret) { | ||
242 | NV_ERROR(dev, "No ctxprog for NV%02x\n", chipset); | ||
243 | return ret; | ||
244 | } | ||
245 | |||
246 | pgraph->ctxprog = kmalloc(fw->size, GFP_KERNEL); | ||
247 | if (!pgraph->ctxprog) { | ||
248 | NV_ERROR(dev, "OOM copying ctxprog\n"); | ||
249 | release_firmware(fw); | ||
250 | return -ENOMEM; | ||
251 | } | ||
252 | memcpy(pgraph->ctxprog, fw->data, fw->size); | ||
253 | |||
254 | cp = pgraph->ctxprog; | ||
255 | if (le32_to_cpu(cp->signature) != 0x5043564e || | ||
256 | cp->version != 0 || | ||
257 | le16_to_cpu(cp->length) != ((fw->size - 7) / 4)) { | ||
258 | NV_ERROR(dev, "ctxprog invalid\n"); | ||
259 | release_firmware(fw); | ||
260 | nv40_grctx_fini(dev); | ||
261 | return -EINVAL; | ||
262 | } | ||
263 | release_firmware(fw); | ||
264 | } | ||
265 | |||
266 | if (!pgraph->ctxvals) { | ||
267 | sprintf(name, "nouveau/nv%02x.ctxvals", chipset); | ||
268 | ret = request_firmware(&fw, name, &dev->pdev->dev); | ||
269 | if (ret) { | ||
270 | NV_ERROR(dev, "No ctxvals for NV%02x\n", chipset); | ||
271 | nv40_grctx_fini(dev); | ||
272 | return ret; | ||
273 | } | ||
274 | |||
275 | pgraph->ctxvals = kmalloc(fw->size, GFP_KERNEL); | ||
276 | if (!pgraph->ctxprog) { | ||
277 | NV_ERROR(dev, "OOM copying ctxprog\n"); | ||
278 | release_firmware(fw); | ||
279 | nv40_grctx_fini(dev); | ||
280 | return -ENOMEM; | ||
281 | } | ||
282 | memcpy(pgraph->ctxvals, fw->data, fw->size); | ||
283 | |||
284 | cv = (void *)pgraph->ctxvals; | ||
285 | if (le32_to_cpu(cv->signature) != 0x5643564e || | ||
286 | cv->version != 0 || | ||
287 | le32_to_cpu(cv->length) != ((fw->size - 9) / 8)) { | ||
288 | NV_ERROR(dev, "ctxvals invalid\n"); | ||
289 | release_firmware(fw); | ||
290 | nv40_grctx_fini(dev); | ||
291 | return -EINVAL; | ||
292 | } | ||
293 | release_firmware(fw); | ||
294 | } | ||
295 | |||
296 | cp = pgraph->ctxprog; | ||
297 | |||
298 | nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0); | ||
299 | for (i = 0; i < le16_to_cpu(cp->length); i++) | ||
300 | nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, | ||
301 | le32_to_cpu(cp->data[i])); | ||
302 | |||
303 | pgraph->accel_blocked = false; | ||
304 | return 0; | ||
305 | } | ||
306 | |||
307 | void | ||
308 | nv40_grctx_fini(struct drm_device *dev) | ||
309 | { | ||
310 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
311 | struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; | ||
312 | |||
313 | if (pgraph->ctxprog) { | ||
314 | kfree(pgraph->ctxprog); | ||
315 | pgraph->ctxprog = NULL; | ||
316 | } | ||
317 | |||
318 | if (pgraph->ctxvals) { | ||
319 | kfree(pgraph->ctxprog); | ||
320 | pgraph->ctxvals = NULL; | ||
321 | } | ||
322 | } | ||
323 | |||
324 | void | ||
325 | nv40_grctx_vals_load(struct drm_device *dev, struct nouveau_gpuobj *ctx) | ||
326 | { | ||
327 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
328 | struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; | ||
329 | struct nouveau_ctxvals *cv = pgraph->ctxvals; | ||
330 | int i; | ||
331 | |||
332 | if (!cv) | ||
333 | return; | ||
334 | |||
335 | for (i = 0; i < le32_to_cpu(cv->length); i++) | ||
336 | nv_wo32(dev, ctx, le32_to_cpu(cv->data[i].offset), | ||
337 | le32_to_cpu(cv->data[i].value)); | ||
338 | } | ||
339 | |||
340 | /* | 184 | /* |
341 | * G70 0x47 | 185 | * G70 0x47 |
342 | * G71 0x49 | 186 | * G71 0x49 |
@@ -359,7 +203,26 @@ nv40_graph_init(struct drm_device *dev) | |||
359 | nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) | | 203 | nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) | |
360 | NV_PMC_ENABLE_PGRAPH); | 204 | NV_PMC_ENABLE_PGRAPH); |
361 | 205 | ||
362 | nv40_grctx_init(dev); | 206 | if (nouveau_ctxfw) { |
207 | nouveau_grctx_prog_load(dev); | ||
208 | dev_priv->engine.graph.grctx_size = 175 * 1024; | ||
209 | } | ||
210 | |||
211 | if (!dev_priv->engine.graph.ctxprog) { | ||
212 | struct nouveau_grctx ctx = {}; | ||
213 | uint32_t cp[256]; | ||
214 | |||
215 | ctx.dev = dev; | ||
216 | ctx.mode = NOUVEAU_GRCTX_PROG; | ||
217 | ctx.data = cp; | ||
218 | ctx.ctxprog_max = 256; | ||
219 | nv40_grctx_init(&ctx); | ||
220 | dev_priv->engine.graph.grctx_size = ctx.ctxvals_pos * 4; | ||
221 | |||
222 | nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0); | ||
223 | for (i = 0; i < ctx.ctxprog_len; i++) | ||
224 | nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, cp[i]); | ||
225 | } | ||
363 | 226 | ||
364 | /* No context present currently */ | 227 | /* No context present currently */ |
365 | nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, 0x00000000); | 228 | nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, 0x00000000); |
@@ -539,6 +402,7 @@ nv40_graph_init(struct drm_device *dev) | |||
539 | 402 | ||
540 | void nv40_graph_takedown(struct drm_device *dev) | 403 | void nv40_graph_takedown(struct drm_device *dev) |
541 | { | 404 | { |
405 | nouveau_grctx_fini(dev); | ||
542 | } | 406 | } |
543 | 407 | ||
544 | struct nouveau_pgraph_object_class nv40_graph_grclass[] = { | 408 | struct nouveau_pgraph_object_class nv40_graph_grclass[] = { |
diff --git a/drivers/gpu/drm/nouveau/nv40_grctx.c b/drivers/gpu/drm/nouveau/nv40_grctx.c new file mode 100644 index 000000000000..11b11c31f543 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nv40_grctx.c | |||
@@ -0,0 +1,678 @@ | |||
1 | /* | ||
2 | * Copyright 2009 Red Hat Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | * Authors: Ben Skeggs | ||
23 | */ | ||
24 | |||
25 | /* NVIDIA context programs handle a number of other conditions which are | ||
26 | * not implemented in our versions. It's not clear why NVIDIA context | ||
27 | * programs have this code, nor whether it's strictly necessary for | ||
28 | * correct operation. We'll implement additional handling if/when we | ||
29 | * discover it's necessary. | ||
30 | * | ||
31 | * - On context save, NVIDIA set 0x400314 bit 0 to 1 if the "3D state" | ||
32 | * flag is set, this gets saved into the context. | ||
33 | * - On context save, the context program for all cards load nsource | ||
34 | * into a flag register and check for ILLEGAL_MTHD. If it's set, | ||
35 | * opcode 0x60000d is called before resuming normal operation. | ||
36 | * - Some context programs check more conditions than the above. NV44 | ||
37 | * checks: ((nsource & 0x0857) || (0x400718 & 0x0100) || (intr & 0x0001)) | ||
38 | * and calls 0x60000d before resuming normal operation. | ||
39 | * - At the very beginning of NVIDIA's context programs, flag 9 is checked | ||
40 | * and if true 0x800001 is called with count=0, pos=0, the flag is cleared | ||
41 | * and then the ctxprog is aborted. It looks like a complicated NOP, | ||
42 | * its purpose is unknown. | ||
43 | * - In the section of code that loads the per-vs state, NVIDIA check | ||
44 | * flag 10. If it's set, they only transfer the small 0x300 byte block | ||
45 | * of state + the state for a single vs as opposed to the state for | ||
46 | * all vs units. It doesn't seem likely that it'll occur in normal | ||
47 | * operation, especially seeing as it appears NVIDIA may have screwed | ||
48 | * up the ctxprogs for some cards and have an invalid instruction | ||
49 | * rather than a cp_lsr(ctx, dwords_for_1_vs_unit) instruction. | ||
50 | * - There's a number of places where context offset 0 (where we place | ||
51 | * the PRAMIN offset of the context) is loaded into either 0x408000, | ||
52 | * 0x408004 or 0x408008. Not sure what's up there either. | ||
53 | * - The ctxprogs for some cards save 0x400a00 again during the cleanup | ||
54 | * path for auto-loadctx. | ||
55 | */ | ||
56 | |||
57 | #define CP_FLAG_CLEAR 0 | ||
58 | #define CP_FLAG_SET 1 | ||
59 | #define CP_FLAG_SWAP_DIRECTION ((0 * 32) + 0) | ||
60 | #define CP_FLAG_SWAP_DIRECTION_LOAD 0 | ||
61 | #define CP_FLAG_SWAP_DIRECTION_SAVE 1 | ||
62 | #define CP_FLAG_USER_SAVE ((0 * 32) + 5) | ||
63 | #define CP_FLAG_USER_SAVE_NOT_PENDING 0 | ||
64 | #define CP_FLAG_USER_SAVE_PENDING 1 | ||
65 | #define CP_FLAG_USER_LOAD ((0 * 32) + 6) | ||
66 | #define CP_FLAG_USER_LOAD_NOT_PENDING 0 | ||
67 | #define CP_FLAG_USER_LOAD_PENDING 1 | ||
68 | #define CP_FLAG_STATUS ((3 * 32) + 0) | ||
69 | #define CP_FLAG_STATUS_IDLE 0 | ||
70 | #define CP_FLAG_STATUS_BUSY 1 | ||
71 | #define CP_FLAG_AUTO_SAVE ((3 * 32) + 4) | ||
72 | #define CP_FLAG_AUTO_SAVE_NOT_PENDING 0 | ||
73 | #define CP_FLAG_AUTO_SAVE_PENDING 1 | ||
74 | #define CP_FLAG_AUTO_LOAD ((3 * 32) + 5) | ||
75 | #define CP_FLAG_AUTO_LOAD_NOT_PENDING 0 | ||
76 | #define CP_FLAG_AUTO_LOAD_PENDING 1 | ||
77 | #define CP_FLAG_UNK54 ((3 * 32) + 6) | ||
78 | #define CP_FLAG_UNK54_CLEAR 0 | ||
79 | #define CP_FLAG_UNK54_SET 1 | ||
80 | #define CP_FLAG_ALWAYS ((3 * 32) + 8) | ||
81 | #define CP_FLAG_ALWAYS_FALSE 0 | ||
82 | #define CP_FLAG_ALWAYS_TRUE 1 | ||
83 | #define CP_FLAG_UNK57 ((3 * 32) + 9) | ||
84 | #define CP_FLAG_UNK57_CLEAR 0 | ||
85 | #define CP_FLAG_UNK57_SET 1 | ||
86 | |||
87 | #define CP_CTX 0x00100000 | ||
88 | #define CP_CTX_COUNT 0x000fc000 | ||
89 | #define CP_CTX_COUNT_SHIFT 14 | ||
90 | #define CP_CTX_REG 0x00003fff | ||
91 | #define CP_LOAD_SR 0x00200000 | ||
92 | #define CP_LOAD_SR_VALUE 0x000fffff | ||
93 | #define CP_BRA 0x00400000 | ||
94 | #define CP_BRA_IP 0x0000ff00 | ||
95 | #define CP_BRA_IP_SHIFT 8 | ||
96 | #define CP_BRA_IF_CLEAR 0x00000080 | ||
97 | #define CP_BRA_FLAG 0x0000007f | ||
98 | #define CP_WAIT 0x00500000 | ||
99 | #define CP_WAIT_SET 0x00000080 | ||
100 | #define CP_WAIT_FLAG 0x0000007f | ||
101 | #define CP_SET 0x00700000 | ||
102 | #define CP_SET_1 0x00000080 | ||
103 | #define CP_SET_FLAG 0x0000007f | ||
104 | #define CP_NEXT_TO_SWAP 0x00600007 | ||
105 | #define CP_NEXT_TO_CURRENT 0x00600009 | ||
106 | #define CP_SET_CONTEXT_POINTER 0x0060000a | ||
107 | #define CP_END 0x0060000e | ||
108 | #define CP_LOAD_MAGIC_UNK01 0x00800001 /* unknown */ | ||
109 | #define CP_LOAD_MAGIC_NV44TCL 0x00800029 /* per-vs state (0x4497) */ | ||
110 | #define CP_LOAD_MAGIC_NV40TCL 0x00800041 /* per-vs state (0x4097) */ | ||
111 | |||
112 | #include "drmP.h" | ||
113 | #include "nouveau_drv.h" | ||
114 | #include "nouveau_grctx.h" | ||
115 | |||
116 | /* TODO: | ||
117 | * - get vs count from 0x1540 | ||
118 | * - document unimplemented bits compared to nvidia | ||
119 | * - nsource handling | ||
120 | * - R0 & 0x0200 handling | ||
121 | * - single-vs handling | ||
122 | * - 400314 bit 0 | ||
123 | */ | ||
124 | |||
125 | static int | ||
126 | nv40_graph_4097(struct drm_device *dev) | ||
127 | { | ||
128 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
129 | |||
130 | if ((dev_priv->chipset & 0xf0) == 0x60) | ||
131 | return 0; | ||
132 | |||
133 | return !!(0x0baf & (1 << dev_priv->chipset)); | ||
134 | } | ||
135 | |||
136 | static int | ||
137 | nv40_graph_vs_count(struct drm_device *dev) | ||
138 | { | ||
139 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
140 | |||
141 | switch (dev_priv->chipset) { | ||
142 | case 0x47: | ||
143 | case 0x49: | ||
144 | case 0x4b: | ||
145 | return 8; | ||
146 | case 0x40: | ||
147 | return 6; | ||
148 | case 0x41: | ||
149 | case 0x42: | ||
150 | return 5; | ||
151 | case 0x43: | ||
152 | case 0x44: | ||
153 | case 0x46: | ||
154 | case 0x4a: | ||
155 | return 3; | ||
156 | case 0x4c: | ||
157 | case 0x4e: | ||
158 | case 0x67: | ||
159 | default: | ||
160 | return 1; | ||
161 | } | ||
162 | } | ||
163 | |||
164 | |||
165 | enum cp_label { | ||
166 | cp_check_load = 1, | ||
167 | cp_setup_auto_load, | ||
168 | cp_setup_load, | ||
169 | cp_setup_save, | ||
170 | cp_swap_state, | ||
171 | cp_swap_state3d_3_is_save, | ||
172 | cp_prepare_exit, | ||
173 | cp_exit, | ||
174 | }; | ||
175 | |||
176 | static void | ||
177 | nv40_graph_construct_general(struct nouveau_grctx *ctx) | ||
178 | { | ||
179 | struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; | ||
180 | int i; | ||
181 | |||
182 | cp_ctx(ctx, 0x4000a4, 1); | ||
183 | gr_def(ctx, 0x4000a4, 0x00000008); | ||
184 | cp_ctx(ctx, 0x400144, 58); | ||
185 | gr_def(ctx, 0x400144, 0x00000001); | ||
186 | cp_ctx(ctx, 0x400314, 1); | ||
187 | gr_def(ctx, 0x400314, 0x00000000); | ||
188 | cp_ctx(ctx, 0x400400, 10); | ||
189 | cp_ctx(ctx, 0x400480, 10); | ||
190 | cp_ctx(ctx, 0x400500, 19); | ||
191 | gr_def(ctx, 0x400514, 0x00040000); | ||
192 | gr_def(ctx, 0x400524, 0x55555555); | ||
193 | gr_def(ctx, 0x400528, 0x55555555); | ||
194 | gr_def(ctx, 0x40052c, 0x55555555); | ||
195 | gr_def(ctx, 0x400530, 0x55555555); | ||
196 | cp_ctx(ctx, 0x400560, 6); | ||
197 | gr_def(ctx, 0x400568, 0x0000ffff); | ||
198 | gr_def(ctx, 0x40056c, 0x0000ffff); | ||
199 | cp_ctx(ctx, 0x40057c, 5); | ||
200 | cp_ctx(ctx, 0x400710, 3); | ||
201 | gr_def(ctx, 0x400710, 0x20010001); | ||
202 | gr_def(ctx, 0x400714, 0x0f73ef00); | ||
203 | cp_ctx(ctx, 0x400724, 1); | ||
204 | gr_def(ctx, 0x400724, 0x02008821); | ||
205 | cp_ctx(ctx, 0x400770, 3); | ||
206 | if (dev_priv->chipset == 0x40) { | ||
207 | cp_ctx(ctx, 0x400814, 4); | ||
208 | cp_ctx(ctx, 0x400828, 5); | ||
209 | cp_ctx(ctx, 0x400840, 5); | ||
210 | gr_def(ctx, 0x400850, 0x00000040); | ||
211 | cp_ctx(ctx, 0x400858, 4); | ||
212 | gr_def(ctx, 0x400858, 0x00000040); | ||
213 | gr_def(ctx, 0x40085c, 0x00000040); | ||
214 | gr_def(ctx, 0x400864, 0x80000000); | ||
215 | cp_ctx(ctx, 0x40086c, 9); | ||
216 | gr_def(ctx, 0x40086c, 0x80000000); | ||
217 | gr_def(ctx, 0x400870, 0x80000000); | ||
218 | gr_def(ctx, 0x400874, 0x80000000); | ||
219 | gr_def(ctx, 0x400878, 0x80000000); | ||
220 | gr_def(ctx, 0x400888, 0x00000040); | ||
221 | gr_def(ctx, 0x40088c, 0x80000000); | ||
222 | cp_ctx(ctx, 0x4009c0, 8); | ||
223 | gr_def(ctx, 0x4009cc, 0x80000000); | ||
224 | gr_def(ctx, 0x4009dc, 0x80000000); | ||
225 | } else { | ||
226 | cp_ctx(ctx, 0x400840, 20); | ||
227 | if (!nv40_graph_4097(ctx->dev)) { | ||
228 | for (i = 0; i < 8; i++) | ||
229 | gr_def(ctx, 0x400860 + (i * 4), 0x00000001); | ||
230 | } | ||
231 | gr_def(ctx, 0x400880, 0x00000040); | ||
232 | gr_def(ctx, 0x400884, 0x00000040); | ||
233 | gr_def(ctx, 0x400888, 0x00000040); | ||
234 | cp_ctx(ctx, 0x400894, 11); | ||
235 | gr_def(ctx, 0x400894, 0x00000040); | ||
236 | if (nv40_graph_4097(ctx->dev)) { | ||
237 | for (i = 0; i < 8; i++) | ||
238 | gr_def(ctx, 0x4008a0 + (i * 4), 0x80000000); | ||
239 | } | ||
240 | cp_ctx(ctx, 0x4008e0, 2); | ||
241 | cp_ctx(ctx, 0x4008f8, 2); | ||
242 | if (dev_priv->chipset == 0x4c || | ||
243 | (dev_priv->chipset & 0xf0) == 0x60) | ||
244 | cp_ctx(ctx, 0x4009f8, 1); | ||
245 | } | ||
246 | cp_ctx(ctx, 0x400a00, 73); | ||
247 | gr_def(ctx, 0x400b0c, 0x0b0b0b0c); | ||
248 | cp_ctx(ctx, 0x401000, 4); | ||
249 | cp_ctx(ctx, 0x405004, 1); | ||
250 | switch (dev_priv->chipset) { | ||
251 | case 0x47: | ||
252 | case 0x49: | ||
253 | case 0x4b: | ||
254 | cp_ctx(ctx, 0x403448, 1); | ||
255 | gr_def(ctx, 0x403448, 0x00001010); | ||
256 | break; | ||
257 | default: | ||
258 | cp_ctx(ctx, 0x403440, 1); | ||
259 | switch (dev_priv->chipset) { | ||
260 | case 0x40: | ||
261 | gr_def(ctx, 0x403440, 0x00000010); | ||
262 | break; | ||
263 | case 0x44: | ||
264 | case 0x46: | ||
265 | case 0x4a: | ||
266 | gr_def(ctx, 0x403440, 0x00003010); | ||
267 | break; | ||
268 | case 0x41: | ||
269 | case 0x42: | ||
270 | case 0x43: | ||
271 | case 0x4c: | ||
272 | case 0x4e: | ||
273 | case 0x67: | ||
274 | default: | ||
275 | gr_def(ctx, 0x403440, 0x00001010); | ||
276 | break; | ||
277 | } | ||
278 | break; | ||
279 | } | ||
280 | } | ||
281 | |||
282 | static void | ||
283 | nv40_graph_construct_state3d(struct nouveau_grctx *ctx) | ||
284 | { | ||
285 | struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; | ||
286 | int i; | ||
287 | |||
288 | if (dev_priv->chipset == 0x40) { | ||
289 | cp_ctx(ctx, 0x401880, 51); | ||
290 | gr_def(ctx, 0x401940, 0x00000100); | ||
291 | } else | ||
292 | if (dev_priv->chipset == 0x46 || dev_priv->chipset == 0x47 || | ||
293 | dev_priv->chipset == 0x49 || dev_priv->chipset == 0x4b) { | ||
294 | cp_ctx(ctx, 0x401880, 32); | ||
295 | for (i = 0; i < 16; i++) | ||
296 | gr_def(ctx, 0x401880 + (i * 4), 0x00000111); | ||
297 | if (dev_priv->chipset == 0x46) | ||
298 | cp_ctx(ctx, 0x401900, 16); | ||
299 | cp_ctx(ctx, 0x401940, 3); | ||
300 | } | ||
301 | cp_ctx(ctx, 0x40194c, 18); | ||
302 | gr_def(ctx, 0x401954, 0x00000111); | ||
303 | gr_def(ctx, 0x401958, 0x00080060); | ||
304 | gr_def(ctx, 0x401974, 0x00000080); | ||
305 | gr_def(ctx, 0x401978, 0xffff0000); | ||
306 | gr_def(ctx, 0x40197c, 0x00000001); | ||
307 | gr_def(ctx, 0x401990, 0x46400000); | ||
308 | if (dev_priv->chipset == 0x40) { | ||
309 | cp_ctx(ctx, 0x4019a0, 2); | ||
310 | cp_ctx(ctx, 0x4019ac, 5); | ||
311 | } else { | ||
312 | cp_ctx(ctx, 0x4019a0, 1); | ||
313 | cp_ctx(ctx, 0x4019b4, 3); | ||
314 | } | ||
315 | gr_def(ctx, 0x4019bc, 0xffff0000); | ||
316 | switch (dev_priv->chipset) { | ||
317 | case 0x46: | ||
318 | case 0x47: | ||
319 | case 0x49: | ||
320 | case 0x4b: | ||
321 | cp_ctx(ctx, 0x4019c0, 18); | ||
322 | for (i = 0; i < 16; i++) | ||
323 | gr_def(ctx, 0x4019c0 + (i * 4), 0x88888888); | ||
324 | break; | ||
325 | } | ||
326 | cp_ctx(ctx, 0x401a08, 8); | ||
327 | gr_def(ctx, 0x401a10, 0x0fff0000); | ||
328 | gr_def(ctx, 0x401a14, 0x0fff0000); | ||
329 | gr_def(ctx, 0x401a1c, 0x00011100); | ||
330 | cp_ctx(ctx, 0x401a2c, 4); | ||
331 | cp_ctx(ctx, 0x401a44, 26); | ||
332 | for (i = 0; i < 16; i++) | ||
333 | gr_def(ctx, 0x401a44 + (i * 4), 0x07ff0000); | ||
334 | gr_def(ctx, 0x401a8c, 0x4b7fffff); | ||
335 | if (dev_priv->chipset == 0x40) { | ||
336 | cp_ctx(ctx, 0x401ab8, 3); | ||
337 | } else { | ||
338 | cp_ctx(ctx, 0x401ab8, 1); | ||
339 | cp_ctx(ctx, 0x401ac0, 1); | ||
340 | } | ||
341 | cp_ctx(ctx, 0x401ad0, 8); | ||
342 | gr_def(ctx, 0x401ad0, 0x30201000); | ||
343 | gr_def(ctx, 0x401ad4, 0x70605040); | ||
344 | gr_def(ctx, 0x401ad8, 0xb8a89888); | ||
345 | gr_def(ctx, 0x401adc, 0xf8e8d8c8); | ||
346 | cp_ctx(ctx, 0x401b10, dev_priv->chipset == 0x40 ? 2 : 1); | ||
347 | gr_def(ctx, 0x401b10, 0x40100000); | ||
348 | cp_ctx(ctx, 0x401b18, dev_priv->chipset == 0x40 ? 6 : 5); | ||
349 | gr_def(ctx, 0x401b28, dev_priv->chipset == 0x40 ? | ||
350 | 0x00000004 : 0x00000000); | ||
351 | cp_ctx(ctx, 0x401b30, 25); | ||
352 | gr_def(ctx, 0x401b34, 0x0000ffff); | ||
353 | gr_def(ctx, 0x401b68, 0x435185d6); | ||
354 | gr_def(ctx, 0x401b6c, 0x2155b699); | ||
355 | gr_def(ctx, 0x401b70, 0xfedcba98); | ||
356 | gr_def(ctx, 0x401b74, 0x00000098); | ||
357 | gr_def(ctx, 0x401b84, 0xffffffff); | ||
358 | gr_def(ctx, 0x401b88, 0x00ff7000); | ||
359 | gr_def(ctx, 0x401b8c, 0x0000ffff); | ||
360 | if (dev_priv->chipset != 0x44 && dev_priv->chipset != 0x4a && | ||
361 | dev_priv->chipset != 0x4e) | ||
362 | cp_ctx(ctx, 0x401b94, 1); | ||
363 | cp_ctx(ctx, 0x401b98, 8); | ||
364 | gr_def(ctx, 0x401b9c, 0x00ff0000); | ||
365 | cp_ctx(ctx, 0x401bc0, 9); | ||
366 | gr_def(ctx, 0x401be0, 0x00ffff00); | ||
367 | cp_ctx(ctx, 0x401c00, 192); | ||
368 | for (i = 0; i < 16; i++) { /* fragment texture units */ | ||
369 | gr_def(ctx, 0x401c40 + (i * 4), 0x00018488); | ||
370 | gr_def(ctx, 0x401c80 + (i * 4), 0x00028202); | ||
371 | gr_def(ctx, 0x401d00 + (i * 4), 0x0000aae4); | ||
372 | gr_def(ctx, 0x401d40 + (i * 4), 0x01012000); | ||
373 | gr_def(ctx, 0x401d80 + (i * 4), 0x00080008); | ||
374 | gr_def(ctx, 0x401e00 + (i * 4), 0x00100008); | ||
375 | } | ||
376 | for (i = 0; i < 4; i++) { /* vertex texture units */ | ||
377 | gr_def(ctx, 0x401e90 + (i * 4), 0x0001bc80); | ||
378 | gr_def(ctx, 0x401ea0 + (i * 4), 0x00000202); | ||
379 | gr_def(ctx, 0x401ec0 + (i * 4), 0x00000008); | ||
380 | gr_def(ctx, 0x401ee0 + (i * 4), 0x00080008); | ||
381 | } | ||
382 | cp_ctx(ctx, 0x400f5c, 3); | ||
383 | gr_def(ctx, 0x400f5c, 0x00000002); | ||
384 | cp_ctx(ctx, 0x400f84, 1); | ||
385 | } | ||
386 | |||
387 | static void | ||
388 | nv40_graph_construct_state3d_2(struct nouveau_grctx *ctx) | ||
389 | { | ||
390 | struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; | ||
391 | int i; | ||
392 | |||
393 | cp_ctx(ctx, 0x402000, 1); | ||
394 | cp_ctx(ctx, 0x402404, dev_priv->chipset == 0x40 ? 1 : 2); | ||
395 | switch (dev_priv->chipset) { | ||
396 | case 0x40: | ||
397 | gr_def(ctx, 0x402404, 0x00000001); | ||
398 | break; | ||
399 | case 0x4c: | ||
400 | case 0x4e: | ||
401 | case 0x67: | ||
402 | gr_def(ctx, 0x402404, 0x00000020); | ||
403 | break; | ||
404 | case 0x46: | ||
405 | case 0x49: | ||
406 | case 0x4b: | ||
407 | gr_def(ctx, 0x402404, 0x00000421); | ||
408 | break; | ||
409 | default: | ||
410 | gr_def(ctx, 0x402404, 0x00000021); | ||
411 | } | ||
412 | if (dev_priv->chipset != 0x40) | ||
413 | gr_def(ctx, 0x402408, 0x030c30c3); | ||
414 | switch (dev_priv->chipset) { | ||
415 | case 0x44: | ||
416 | case 0x46: | ||
417 | case 0x4a: | ||
418 | case 0x4c: | ||
419 | case 0x4e: | ||
420 | case 0x67: | ||
421 | cp_ctx(ctx, 0x402440, 1); | ||
422 | gr_def(ctx, 0x402440, 0x00011001); | ||
423 | break; | ||
424 | default: | ||
425 | break; | ||
426 | } | ||
427 | cp_ctx(ctx, 0x402480, dev_priv->chipset == 0x40 ? 8 : 9); | ||
428 | gr_def(ctx, 0x402488, 0x3e020200); | ||
429 | gr_def(ctx, 0x40248c, 0x00ffffff); | ||
430 | switch (dev_priv->chipset) { | ||
431 | case 0x40: | ||
432 | gr_def(ctx, 0x402490, 0x60103f00); | ||
433 | break; | ||
434 | case 0x47: | ||
435 | gr_def(ctx, 0x402490, 0x40103f00); | ||
436 | break; | ||
437 | case 0x41: | ||
438 | case 0x42: | ||
439 | case 0x49: | ||
440 | case 0x4b: | ||
441 | gr_def(ctx, 0x402490, 0x20103f00); | ||
442 | break; | ||
443 | default: | ||
444 | gr_def(ctx, 0x402490, 0x0c103f00); | ||
445 | break; | ||
446 | } | ||
447 | gr_def(ctx, 0x40249c, dev_priv->chipset <= 0x43 ? | ||
448 | 0x00020000 : 0x00040000); | ||
449 | cp_ctx(ctx, 0x402500, 31); | ||
450 | gr_def(ctx, 0x402530, 0x00008100); | ||
451 | if (dev_priv->chipset == 0x40) | ||
452 | cp_ctx(ctx, 0x40257c, 6); | ||
453 | cp_ctx(ctx, 0x402594, 16); | ||
454 | cp_ctx(ctx, 0x402800, 17); | ||
455 | gr_def(ctx, 0x402800, 0x00000001); | ||
456 | switch (dev_priv->chipset) { | ||
457 | case 0x47: | ||
458 | case 0x49: | ||
459 | case 0x4b: | ||
460 | cp_ctx(ctx, 0x402864, 1); | ||
461 | gr_def(ctx, 0x402864, 0x00001001); | ||
462 | cp_ctx(ctx, 0x402870, 3); | ||
463 | gr_def(ctx, 0x402878, 0x00000003); | ||
464 | if (dev_priv->chipset != 0x47) { /* belong at end!! */ | ||
465 | cp_ctx(ctx, 0x402900, 1); | ||
466 | cp_ctx(ctx, 0x402940, 1); | ||
467 | cp_ctx(ctx, 0x402980, 1); | ||
468 | cp_ctx(ctx, 0x4029c0, 1); | ||
469 | cp_ctx(ctx, 0x402a00, 1); | ||
470 | cp_ctx(ctx, 0x402a40, 1); | ||
471 | cp_ctx(ctx, 0x402a80, 1); | ||
472 | cp_ctx(ctx, 0x402ac0, 1); | ||
473 | } | ||
474 | break; | ||
475 | case 0x40: | ||
476 | cp_ctx(ctx, 0x402844, 1); | ||
477 | gr_def(ctx, 0x402844, 0x00000001); | ||
478 | cp_ctx(ctx, 0x402850, 1); | ||
479 | break; | ||
480 | default: | ||
481 | cp_ctx(ctx, 0x402844, 1); | ||
482 | gr_def(ctx, 0x402844, 0x00001001); | ||
483 | cp_ctx(ctx, 0x402850, 2); | ||
484 | gr_def(ctx, 0x402854, 0x00000003); | ||
485 | break; | ||
486 | } | ||
487 | |||
488 | cp_ctx(ctx, 0x402c00, 4); | ||
489 | gr_def(ctx, 0x402c00, dev_priv->chipset == 0x40 ? | ||
490 | 0x80800001 : 0x00888001); | ||
491 | switch (dev_priv->chipset) { | ||
492 | case 0x47: | ||
493 | case 0x49: | ||
494 | case 0x4b: | ||
495 | cp_ctx(ctx, 0x402c20, 40); | ||
496 | for (i = 0; i < 32; i++) | ||
497 | gr_def(ctx, 0x402c40 + (i * 4), 0xffffffff); | ||
498 | cp_ctx(ctx, 0x4030b8, 13); | ||
499 | gr_def(ctx, 0x4030dc, 0x00000005); | ||
500 | gr_def(ctx, 0x4030e8, 0x0000ffff); | ||
501 | break; | ||
502 | default: | ||
503 | cp_ctx(ctx, 0x402c10, 4); | ||
504 | if (dev_priv->chipset == 0x40) | ||
505 | cp_ctx(ctx, 0x402c20, 36); | ||
506 | else | ||
507 | if (dev_priv->chipset <= 0x42) | ||
508 | cp_ctx(ctx, 0x402c20, 24); | ||
509 | else | ||
510 | if (dev_priv->chipset <= 0x4a) | ||
511 | cp_ctx(ctx, 0x402c20, 16); | ||
512 | else | ||
513 | cp_ctx(ctx, 0x402c20, 8); | ||
514 | cp_ctx(ctx, 0x402cb0, dev_priv->chipset == 0x40 ? 12 : 13); | ||
515 | gr_def(ctx, 0x402cd4, 0x00000005); | ||
516 | if (dev_priv->chipset != 0x40) | ||
517 | gr_def(ctx, 0x402ce0, 0x0000ffff); | ||
518 | break; | ||
519 | } | ||
520 | |||
521 | cp_ctx(ctx, 0x403400, dev_priv->chipset == 0x40 ? 4 : 3); | ||
522 | cp_ctx(ctx, 0x403410, dev_priv->chipset == 0x40 ? 4 : 3); | ||
523 | cp_ctx(ctx, 0x403420, nv40_graph_vs_count(ctx->dev)); | ||
524 | for (i = 0; i < nv40_graph_vs_count(ctx->dev); i++) | ||
525 | gr_def(ctx, 0x403420 + (i * 4), 0x00005555); | ||
526 | |||
527 | if (dev_priv->chipset != 0x40) { | ||
528 | cp_ctx(ctx, 0x403600, 1); | ||
529 | gr_def(ctx, 0x403600, 0x00000001); | ||
530 | } | ||
531 | cp_ctx(ctx, 0x403800, 1); | ||
532 | |||
533 | cp_ctx(ctx, 0x403c18, 1); | ||
534 | gr_def(ctx, 0x403c18, 0x00000001); | ||
535 | switch (dev_priv->chipset) { | ||
536 | case 0x46: | ||
537 | case 0x47: | ||
538 | case 0x49: | ||
539 | case 0x4b: | ||
540 | cp_ctx(ctx, 0x405018, 1); | ||
541 | gr_def(ctx, 0x405018, 0x08e00001); | ||
542 | cp_ctx(ctx, 0x405c24, 1); | ||
543 | gr_def(ctx, 0x405c24, 0x000e3000); | ||
544 | break; | ||
545 | } | ||
546 | if (dev_priv->chipset != 0x4e) | ||
547 | cp_ctx(ctx, 0x405800, 11); | ||
548 | cp_ctx(ctx, 0x407000, 1); | ||
549 | } | ||
550 | |||
551 | static void | ||
552 | nv40_graph_construct_state3d_3(struct nouveau_grctx *ctx) | ||
553 | { | ||
554 | int len = nv40_graph_4097(ctx->dev) ? 0x0684 : 0x0084; | ||
555 | |||
556 | cp_out (ctx, 0x300000); | ||
557 | cp_lsr (ctx, len - 4); | ||
558 | cp_bra (ctx, SWAP_DIRECTION, SAVE, cp_swap_state3d_3_is_save); | ||
559 | cp_lsr (ctx, len); | ||
560 | cp_name(ctx, cp_swap_state3d_3_is_save); | ||
561 | cp_out (ctx, 0x800001); | ||
562 | |||
563 | ctx->ctxvals_pos += len; | ||
564 | } | ||
565 | |||
566 | static void | ||
567 | nv40_graph_construct_shader(struct nouveau_grctx *ctx) | ||
568 | { | ||
569 | struct drm_device *dev = ctx->dev; | ||
570 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
571 | struct nouveau_gpuobj *obj = ctx->data; | ||
572 | int vs, vs_nr, vs_len, vs_nr_b0, vs_nr_b1, b0_offset, b1_offset; | ||
573 | int offset, i; | ||
574 | |||
575 | vs_nr = nv40_graph_vs_count(ctx->dev); | ||
576 | vs_nr_b0 = 363; | ||
577 | vs_nr_b1 = dev_priv->chipset == 0x40 ? 128 : 64; | ||
578 | if (dev_priv->chipset == 0x40) { | ||
579 | b0_offset = 0x2200/4; /* 33a0 */ | ||
580 | b1_offset = 0x55a0/4; /* 1500 */ | ||
581 | vs_len = 0x6aa0/4; | ||
582 | } else | ||
583 | if (dev_priv->chipset == 0x41 || dev_priv->chipset == 0x42) { | ||
584 | b0_offset = 0x2200/4; /* 2200 */ | ||
585 | b1_offset = 0x4400/4; /* 0b00 */ | ||
586 | vs_len = 0x4f00/4; | ||
587 | } else { | ||
588 | b0_offset = 0x1d40/4; /* 2200 */ | ||
589 | b1_offset = 0x3f40/4; /* 0b00 : 0a40 */ | ||
590 | vs_len = nv40_graph_4097(dev) ? 0x4a40/4 : 0x4980/4; | ||
591 | } | ||
592 | |||
593 | cp_lsr(ctx, vs_len * vs_nr + 0x300/4); | ||
594 | cp_out(ctx, nv40_graph_4097(dev) ? 0x800041 : 0x800029); | ||
595 | |||
596 | offset = ctx->ctxvals_pos; | ||
597 | ctx->ctxvals_pos += (0x0300/4 + (vs_nr * vs_len)); | ||
598 | |||
599 | if (ctx->mode != NOUVEAU_GRCTX_VALS) | ||
600 | return; | ||
601 | |||
602 | offset += 0x0280/4; | ||
603 | for (i = 0; i < 16; i++, offset += 2) | ||
604 | nv_wo32(dev, obj, offset, 0x3f800000); | ||
605 | |||
606 | for (vs = 0; vs < vs_nr; vs++, offset += vs_len) { | ||
607 | for (i = 0; i < vs_nr_b0 * 6; i += 6) | ||
608 | nv_wo32(dev, obj, offset + b0_offset + i, 0x00000001); | ||
609 | for (i = 0; i < vs_nr_b1 * 4; i += 4) | ||
610 | nv_wo32(dev, obj, offset + b1_offset + i, 0x3f800000); | ||
611 | } | ||
612 | } | ||
613 | |||
614 | void | ||
615 | nv40_grctx_init(struct nouveau_grctx *ctx) | ||
616 | { | ||
617 | /* decide whether we're loading/unloading the context */ | ||
618 | cp_bra (ctx, AUTO_SAVE, PENDING, cp_setup_save); | ||
619 | cp_bra (ctx, USER_SAVE, PENDING, cp_setup_save); | ||
620 | |||
621 | cp_name(ctx, cp_check_load); | ||
622 | cp_bra (ctx, AUTO_LOAD, PENDING, cp_setup_auto_load); | ||
623 | cp_bra (ctx, USER_LOAD, PENDING, cp_setup_load); | ||
624 | cp_bra (ctx, ALWAYS, TRUE, cp_exit); | ||
625 | |||
626 | /* setup for context load */ | ||
627 | cp_name(ctx, cp_setup_auto_load); | ||
628 | cp_wait(ctx, STATUS, IDLE); | ||
629 | cp_out (ctx, CP_NEXT_TO_SWAP); | ||
630 | cp_name(ctx, cp_setup_load); | ||
631 | cp_wait(ctx, STATUS, IDLE); | ||
632 | cp_set (ctx, SWAP_DIRECTION, LOAD); | ||
633 | cp_out (ctx, 0x00910880); /* ?? */ | ||
634 | cp_out (ctx, 0x00901ffe); /* ?? */ | ||
635 | cp_out (ctx, 0x01940000); /* ?? */ | ||
636 | cp_lsr (ctx, 0x20); | ||
637 | cp_out (ctx, 0x0060000b); /* ?? */ | ||
638 | cp_wait(ctx, UNK57, CLEAR); | ||
639 | cp_out (ctx, 0x0060000c); /* ?? */ | ||
640 | cp_bra (ctx, ALWAYS, TRUE, cp_swap_state); | ||
641 | |||
642 | /* setup for context save */ | ||
643 | cp_name(ctx, cp_setup_save); | ||
644 | cp_set (ctx, SWAP_DIRECTION, SAVE); | ||
645 | |||
646 | /* general PGRAPH state */ | ||
647 | cp_name(ctx, cp_swap_state); | ||
648 | cp_pos (ctx, 0x00020/4); | ||
649 | nv40_graph_construct_general(ctx); | ||
650 | cp_wait(ctx, STATUS, IDLE); | ||
651 | |||
652 | /* 3D state, block 1 */ | ||
653 | cp_bra (ctx, UNK54, CLEAR, cp_prepare_exit); | ||
654 | nv40_graph_construct_state3d(ctx); | ||
655 | cp_wait(ctx, STATUS, IDLE); | ||
656 | |||
657 | /* 3D state, block 2 */ | ||
658 | nv40_graph_construct_state3d_2(ctx); | ||
659 | |||
660 | /* Some other block of "random" state */ | ||
661 | nv40_graph_construct_state3d_3(ctx); | ||
662 | |||
663 | /* Per-vertex shader state */ | ||
664 | cp_pos (ctx, ctx->ctxvals_pos); | ||
665 | nv40_graph_construct_shader(ctx); | ||
666 | |||
667 | /* pre-exit state updates */ | ||
668 | cp_name(ctx, cp_prepare_exit); | ||
669 | cp_bra (ctx, SWAP_DIRECTION, SAVE, cp_check_load); | ||
670 | cp_bra (ctx, USER_SAVE, PENDING, cp_exit); | ||
671 | cp_out (ctx, CP_NEXT_TO_CURRENT); | ||
672 | |||
673 | cp_name(ctx, cp_exit); | ||
674 | cp_set (ctx, USER_SAVE, NOT_PENDING); | ||
675 | cp_set (ctx, USER_LOAD, NOT_PENDING); | ||
676 | cp_out (ctx, CP_END); | ||
677 | } | ||
678 | |||
diff --git a/drivers/gpu/drm/nouveau/nv50_crtc.c b/drivers/gpu/drm/nouveau/nv50_crtc.c index f8e28a1e44e7..118d3285fd8c 100644 --- a/drivers/gpu/drm/nouveau/nv50_crtc.c +++ b/drivers/gpu/drm/nouveau/nv50_crtc.c | |||
@@ -45,7 +45,7 @@ nv50_crtc_lut_load(struct drm_crtc *crtc) | |||
45 | void __iomem *lut = nvbo_kmap_obj_iovirtual(nv_crtc->lut.nvbo); | 45 | void __iomem *lut = nvbo_kmap_obj_iovirtual(nv_crtc->lut.nvbo); |
46 | int i; | 46 | int i; |
47 | 47 | ||
48 | NV_DEBUG(crtc->dev, "\n"); | 48 | NV_DEBUG_KMS(crtc->dev, "\n"); |
49 | 49 | ||
50 | for (i = 0; i < 256; i++) { | 50 | for (i = 0; i < 256; i++) { |
51 | writew(nv_crtc->lut.r[i] >> 2, lut + 8*i + 0); | 51 | writew(nv_crtc->lut.r[i] >> 2, lut + 8*i + 0); |
@@ -68,8 +68,8 @@ nv50_crtc_blank(struct nouveau_crtc *nv_crtc, bool blanked) | |||
68 | struct nouveau_channel *evo = dev_priv->evo; | 68 | struct nouveau_channel *evo = dev_priv->evo; |
69 | int index = nv_crtc->index, ret; | 69 | int index = nv_crtc->index, ret; |
70 | 70 | ||
71 | NV_DEBUG(dev, "index %d\n", nv_crtc->index); | 71 | NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index); |
72 | NV_DEBUG(dev, "%s\n", blanked ? "blanked" : "unblanked"); | 72 | NV_DEBUG_KMS(dev, "%s\n", blanked ? "blanked" : "unblanked"); |
73 | 73 | ||
74 | if (blanked) { | 74 | if (blanked) { |
75 | nv_crtc->cursor.hide(nv_crtc, false); | 75 | nv_crtc->cursor.hide(nv_crtc, false); |
@@ -139,7 +139,7 @@ nv50_crtc_set_dither(struct nouveau_crtc *nv_crtc, bool on, bool update) | |||
139 | struct nouveau_channel *evo = dev_priv->evo; | 139 | struct nouveau_channel *evo = dev_priv->evo; |
140 | int ret; | 140 | int ret; |
141 | 141 | ||
142 | NV_DEBUG(dev, "\n"); | 142 | NV_DEBUG_KMS(dev, "\n"); |
143 | 143 | ||
144 | ret = RING_SPACE(evo, 2 + (update ? 2 : 0)); | 144 | ret = RING_SPACE(evo, 2 + (update ? 2 : 0)); |
145 | if (ret) { | 145 | if (ret) { |
@@ -193,7 +193,7 @@ nv50_crtc_set_scale(struct nouveau_crtc *nv_crtc, int scaling_mode, bool update) | |||
193 | uint32_t outX, outY, horiz, vert; | 193 | uint32_t outX, outY, horiz, vert; |
194 | int ret; | 194 | int ret; |
195 | 195 | ||
196 | NV_DEBUG(dev, "\n"); | 196 | NV_DEBUG_KMS(dev, "\n"); |
197 | 197 | ||
198 | switch (scaling_mode) { | 198 | switch (scaling_mode) { |
199 | case DRM_MODE_SCALE_NONE: | 199 | case DRM_MODE_SCALE_NONE: |
@@ -301,7 +301,7 @@ nv50_crtc_destroy(struct drm_crtc *crtc) | |||
301 | struct drm_device *dev = crtc->dev; | 301 | struct drm_device *dev = crtc->dev; |
302 | struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); | 302 | struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); |
303 | 303 | ||
304 | NV_DEBUG(dev, "\n"); | 304 | NV_DEBUG_KMS(dev, "\n"); |
305 | 305 | ||
306 | if (!crtc) | 306 | if (!crtc) |
307 | return; | 307 | return; |
@@ -433,7 +433,7 @@ nv50_crtc_prepare(struct drm_crtc *crtc) | |||
433 | struct drm_device *dev = crtc->dev; | 433 | struct drm_device *dev = crtc->dev; |
434 | struct drm_encoder *encoder; | 434 | struct drm_encoder *encoder; |
435 | 435 | ||
436 | NV_DEBUG(dev, "index %d\n", nv_crtc->index); | 436 | NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index); |
437 | 437 | ||
438 | /* Disconnect all unused encoders. */ | 438 | /* Disconnect all unused encoders. */ |
439 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 439 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
@@ -458,7 +458,7 @@ nv50_crtc_commit(struct drm_crtc *crtc) | |||
458 | struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); | 458 | struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); |
459 | int ret; | 459 | int ret; |
460 | 460 | ||
461 | NV_DEBUG(dev, "index %d\n", nv_crtc->index); | 461 | NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index); |
462 | 462 | ||
463 | nv50_crtc_blank(nv_crtc, false); | 463 | nv50_crtc_blank(nv_crtc, false); |
464 | 464 | ||
@@ -497,7 +497,7 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, int x, int y, | |||
497 | struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb); | 497 | struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb); |
498 | int ret, format; | 498 | int ret, format; |
499 | 499 | ||
500 | NV_DEBUG(dev, "index %d\n", nv_crtc->index); | 500 | NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index); |
501 | 501 | ||
502 | switch (drm_fb->depth) { | 502 | switch (drm_fb->depth) { |
503 | case 8: | 503 | case 8: |
@@ -612,7 +612,7 @@ nv50_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, | |||
612 | 612 | ||
613 | *nv_crtc->mode = *adjusted_mode; | 613 | *nv_crtc->mode = *adjusted_mode; |
614 | 614 | ||
615 | NV_DEBUG(dev, "index %d\n", nv_crtc->index); | 615 | NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index); |
616 | 616 | ||
617 | hsync_dur = adjusted_mode->hsync_end - adjusted_mode->hsync_start; | 617 | hsync_dur = adjusted_mode->hsync_end - adjusted_mode->hsync_start; |
618 | vsync_dur = adjusted_mode->vsync_end - adjusted_mode->vsync_start; | 618 | vsync_dur = adjusted_mode->vsync_end - adjusted_mode->vsync_start; |
@@ -706,7 +706,7 @@ nv50_crtc_create(struct drm_device *dev, int index) | |||
706 | struct nouveau_crtc *nv_crtc = NULL; | 706 | struct nouveau_crtc *nv_crtc = NULL; |
707 | int ret, i; | 707 | int ret, i; |
708 | 708 | ||
709 | NV_DEBUG(dev, "\n"); | 709 | NV_DEBUG_KMS(dev, "\n"); |
710 | 710 | ||
711 | nv_crtc = kzalloc(sizeof(*nv_crtc), GFP_KERNEL); | 711 | nv_crtc = kzalloc(sizeof(*nv_crtc), GFP_KERNEL); |
712 | if (!nv_crtc) | 712 | if (!nv_crtc) |
diff --git a/drivers/gpu/drm/nouveau/nv50_cursor.c b/drivers/gpu/drm/nouveau/nv50_cursor.c index e2e79a8f220d..753e723adb3a 100644 --- a/drivers/gpu/drm/nouveau/nv50_cursor.c +++ b/drivers/gpu/drm/nouveau/nv50_cursor.c | |||
@@ -41,7 +41,7 @@ nv50_cursor_show(struct nouveau_crtc *nv_crtc, bool update) | |||
41 | struct drm_device *dev = nv_crtc->base.dev; | 41 | struct drm_device *dev = nv_crtc->base.dev; |
42 | int ret; | 42 | int ret; |
43 | 43 | ||
44 | NV_DEBUG(dev, "\n"); | 44 | NV_DEBUG_KMS(dev, "\n"); |
45 | 45 | ||
46 | if (update && nv_crtc->cursor.visible) | 46 | if (update && nv_crtc->cursor.visible) |
47 | return; | 47 | return; |
@@ -76,7 +76,7 @@ nv50_cursor_hide(struct nouveau_crtc *nv_crtc, bool update) | |||
76 | struct drm_device *dev = nv_crtc->base.dev; | 76 | struct drm_device *dev = nv_crtc->base.dev; |
77 | int ret; | 77 | int ret; |
78 | 78 | ||
79 | NV_DEBUG(dev, "\n"); | 79 | NV_DEBUG_KMS(dev, "\n"); |
80 | 80 | ||
81 | if (update && !nv_crtc->cursor.visible) | 81 | if (update && !nv_crtc->cursor.visible) |
82 | return; | 82 | return; |
@@ -116,7 +116,7 @@ nv50_cursor_set_pos(struct nouveau_crtc *nv_crtc, int x, int y) | |||
116 | static void | 116 | static void |
117 | nv50_cursor_set_offset(struct nouveau_crtc *nv_crtc, uint32_t offset) | 117 | nv50_cursor_set_offset(struct nouveau_crtc *nv_crtc, uint32_t offset) |
118 | { | 118 | { |
119 | NV_DEBUG(nv_crtc->base.dev, "\n"); | 119 | NV_DEBUG_KMS(nv_crtc->base.dev, "\n"); |
120 | if (offset == nv_crtc->cursor.offset) | 120 | if (offset == nv_crtc->cursor.offset) |
121 | return; | 121 | return; |
122 | 122 | ||
@@ -143,7 +143,7 @@ nv50_cursor_fini(struct nouveau_crtc *nv_crtc) | |||
143 | struct drm_device *dev = nv_crtc->base.dev; | 143 | struct drm_device *dev = nv_crtc->base.dev; |
144 | int idx = nv_crtc->index; | 144 | int idx = nv_crtc->index; |
145 | 145 | ||
146 | NV_DEBUG(dev, "\n"); | 146 | NV_DEBUG_KMS(dev, "\n"); |
147 | 147 | ||
148 | nv_wr32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(idx), 0); | 148 | nv_wr32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(idx), 0); |
149 | if (!nv_wait(NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(idx), | 149 | if (!nv_wait(NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(idx), |
diff --git a/drivers/gpu/drm/nouveau/nv50_dac.c b/drivers/gpu/drm/nouveau/nv50_dac.c index fb5838e3be24..f08f042a8e10 100644 --- a/drivers/gpu/drm/nouveau/nv50_dac.c +++ b/drivers/gpu/drm/nouveau/nv50_dac.c | |||
@@ -44,7 +44,7 @@ nv50_dac_disconnect(struct nouveau_encoder *nv_encoder) | |||
44 | struct nouveau_channel *evo = dev_priv->evo; | 44 | struct nouveau_channel *evo = dev_priv->evo; |
45 | int ret; | 45 | int ret; |
46 | 46 | ||
47 | NV_DEBUG(dev, "Disconnecting DAC %d\n", nv_encoder->or); | 47 | NV_DEBUG_KMS(dev, "Disconnecting DAC %d\n", nv_encoder->or); |
48 | 48 | ||
49 | ret = RING_SPACE(evo, 2); | 49 | ret = RING_SPACE(evo, 2); |
50 | if (ret) { | 50 | if (ret) { |
@@ -81,11 +81,11 @@ nv50_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) | |||
81 | /* Use bios provided value if possible. */ | 81 | /* Use bios provided value if possible. */ |
82 | if (dev_priv->vbios->dactestval) { | 82 | if (dev_priv->vbios->dactestval) { |
83 | load_pattern = dev_priv->vbios->dactestval; | 83 | load_pattern = dev_priv->vbios->dactestval; |
84 | NV_DEBUG(dev, "Using bios provided load_pattern of %d\n", | 84 | NV_DEBUG_KMS(dev, "Using bios provided load_pattern of %d\n", |
85 | load_pattern); | 85 | load_pattern); |
86 | } else { | 86 | } else { |
87 | load_pattern = 340; | 87 | load_pattern = 340; |
88 | NV_DEBUG(dev, "Using default load_pattern of %d\n", | 88 | NV_DEBUG_KMS(dev, "Using default load_pattern of %d\n", |
89 | load_pattern); | 89 | load_pattern); |
90 | } | 90 | } |
91 | 91 | ||
@@ -103,9 +103,9 @@ nv50_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) | |||
103 | status = connector_status_connected; | 103 | status = connector_status_connected; |
104 | 104 | ||
105 | if (status == connector_status_connected) | 105 | if (status == connector_status_connected) |
106 | NV_DEBUG(dev, "Load was detected on output with or %d\n", or); | 106 | NV_DEBUG_KMS(dev, "Load was detected on output with or %d\n", or); |
107 | else | 107 | else |
108 | NV_DEBUG(dev, "Load was not detected on output with or %d\n", or); | 108 | NV_DEBUG_KMS(dev, "Load was not detected on output with or %d\n", or); |
109 | 109 | ||
110 | return status; | 110 | return status; |
111 | } | 111 | } |
@@ -118,7 +118,7 @@ nv50_dac_dpms(struct drm_encoder *encoder, int mode) | |||
118 | uint32_t val; | 118 | uint32_t val; |
119 | int or = nv_encoder->or; | 119 | int or = nv_encoder->or; |
120 | 120 | ||
121 | NV_DEBUG(dev, "or %d mode %d\n", or, mode); | 121 | NV_DEBUG_KMS(dev, "or %d mode %d\n", or, mode); |
122 | 122 | ||
123 | /* wait for it to be done */ | 123 | /* wait for it to be done */ |
124 | if (!nv_wait(NV50_PDISPLAY_DAC_DPMS_CTRL(or), | 124 | if (!nv_wait(NV50_PDISPLAY_DAC_DPMS_CTRL(or), |
@@ -173,7 +173,7 @@ nv50_dac_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
173 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | 173 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); |
174 | struct nouveau_connector *connector; | 174 | struct nouveau_connector *connector; |
175 | 175 | ||
176 | NV_DEBUG(encoder->dev, "or %d\n", nv_encoder->or); | 176 | NV_DEBUG_KMS(encoder->dev, "or %d\n", nv_encoder->or); |
177 | 177 | ||
178 | connector = nouveau_encoder_connector_get(nv_encoder); | 178 | connector = nouveau_encoder_connector_get(nv_encoder); |
179 | if (!connector) { | 179 | if (!connector) { |
@@ -213,7 +213,7 @@ nv50_dac_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
213 | uint32_t mode_ctl = 0, mode_ctl2 = 0; | 213 | uint32_t mode_ctl = 0, mode_ctl2 = 0; |
214 | int ret; | 214 | int ret; |
215 | 215 | ||
216 | NV_DEBUG(dev, "or %d\n", nv_encoder->or); | 216 | NV_DEBUG_KMS(dev, "or %d\n", nv_encoder->or); |
217 | 217 | ||
218 | nv50_dac_dpms(encoder, DRM_MODE_DPMS_ON); | 218 | nv50_dac_dpms(encoder, DRM_MODE_DPMS_ON); |
219 | 219 | ||
@@ -264,7 +264,7 @@ nv50_dac_destroy(struct drm_encoder *encoder) | |||
264 | if (!encoder) | 264 | if (!encoder) |
265 | return; | 265 | return; |
266 | 266 | ||
267 | NV_DEBUG(encoder->dev, "\n"); | 267 | NV_DEBUG_KMS(encoder->dev, "\n"); |
268 | 268 | ||
269 | drm_encoder_cleanup(encoder); | 269 | drm_encoder_cleanup(encoder); |
270 | kfree(nv_encoder); | 270 | kfree(nv_encoder); |
@@ -280,7 +280,7 @@ nv50_dac_create(struct drm_device *dev, struct dcb_entry *entry) | |||
280 | struct nouveau_encoder *nv_encoder; | 280 | struct nouveau_encoder *nv_encoder; |
281 | struct drm_encoder *encoder; | 281 | struct drm_encoder *encoder; |
282 | 282 | ||
283 | NV_DEBUG(dev, "\n"); | 283 | NV_DEBUG_KMS(dev, "\n"); |
284 | NV_INFO(dev, "Detected a DAC output\n"); | 284 | NV_INFO(dev, "Detected a DAC output\n"); |
285 | 285 | ||
286 | nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL); | 286 | nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL); |
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 12c5ee63495b..a9263d92a231 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c | |||
@@ -188,7 +188,7 @@ nv50_display_init(struct drm_device *dev) | |||
188 | uint64_t start; | 188 | uint64_t start; |
189 | int ret, i; | 189 | int ret, i; |
190 | 190 | ||
191 | NV_DEBUG(dev, "\n"); | 191 | NV_DEBUG_KMS(dev, "\n"); |
192 | 192 | ||
193 | nv_wr32(dev, 0x00610184, nv_rd32(dev, 0x00614004)); | 193 | nv_wr32(dev, 0x00610184, nv_rd32(dev, 0x00614004)); |
194 | /* | 194 | /* |
@@ -232,7 +232,7 @@ nv50_display_init(struct drm_device *dev) | |||
232 | nv_wr32(dev, NV50_PDISPLAY_UNK_380, 0); | 232 | nv_wr32(dev, NV50_PDISPLAY_UNK_380, 0); |
233 | /* RAM is clamped to 256 MiB. */ | 233 | /* RAM is clamped to 256 MiB. */ |
234 | ram_amount = nouveau_mem_fb_amount(dev); | 234 | ram_amount = nouveau_mem_fb_amount(dev); |
235 | NV_DEBUG(dev, "ram_amount %d\n", ram_amount); | 235 | NV_DEBUG_KMS(dev, "ram_amount %d\n", ram_amount); |
236 | if (ram_amount > 256*1024*1024) | 236 | if (ram_amount > 256*1024*1024) |
237 | ram_amount = 256*1024*1024; | 237 | ram_amount = 256*1024*1024; |
238 | nv_wr32(dev, NV50_PDISPLAY_RAM_AMOUNT, ram_amount - 1); | 238 | nv_wr32(dev, NV50_PDISPLAY_RAM_AMOUNT, ram_amount - 1); |
@@ -398,7 +398,7 @@ static int nv50_display_disable(struct drm_device *dev) | |||
398 | struct drm_crtc *drm_crtc; | 398 | struct drm_crtc *drm_crtc; |
399 | int ret, i; | 399 | int ret, i; |
400 | 400 | ||
401 | NV_DEBUG(dev, "\n"); | 401 | NV_DEBUG_KMS(dev, "\n"); |
402 | 402 | ||
403 | list_for_each_entry(drm_crtc, &dev->mode_config.crtc_list, head) { | 403 | list_for_each_entry(drm_crtc, &dev->mode_config.crtc_list, head) { |
404 | struct nouveau_crtc *crtc = nouveau_crtc(drm_crtc); | 404 | struct nouveau_crtc *crtc = nouveau_crtc(drm_crtc); |
@@ -469,7 +469,7 @@ int nv50_display_create(struct drm_device *dev) | |||
469 | uint32_t connector[16] = {}; | 469 | uint32_t connector[16] = {}; |
470 | int ret, i; | 470 | int ret, i; |
471 | 471 | ||
472 | NV_DEBUG(dev, "\n"); | 472 | NV_DEBUG_KMS(dev, "\n"); |
473 | 473 | ||
474 | /* init basic kernel modesetting */ | 474 | /* init basic kernel modesetting */ |
475 | drm_mode_config_init(dev); | 475 | drm_mode_config_init(dev); |
@@ -573,7 +573,7 @@ int nv50_display_destroy(struct drm_device *dev) | |||
573 | { | 573 | { |
574 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 574 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
575 | 575 | ||
576 | NV_DEBUG(dev, "\n"); | 576 | NV_DEBUG_KMS(dev, "\n"); |
577 | 577 | ||
578 | drm_mode_config_cleanup(dev); | 578 | drm_mode_config_cleanup(dev); |
579 | 579 | ||
@@ -617,7 +617,7 @@ nv50_display_irq_head(struct drm_device *dev, int *phead, | |||
617 | * CRTC separately, and submission will be blocked by the GPU | 617 | * CRTC separately, and submission will be blocked by the GPU |
618 | * until we handle each in turn. | 618 | * until we handle each in turn. |
619 | */ | 619 | */ |
620 | NV_DEBUG(dev, "0x610030: 0x%08x\n", unk30); | 620 | NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30); |
621 | head = ffs((unk30 >> 9) & 3) - 1; | 621 | head = ffs((unk30 >> 9) & 3) - 1; |
622 | if (head < 0) | 622 | if (head < 0) |
623 | return -EINVAL; | 623 | return -EINVAL; |
@@ -661,7 +661,7 @@ nv50_display_irq_head(struct drm_device *dev, int *phead, | |||
661 | or = i; | 661 | or = i; |
662 | } | 662 | } |
663 | 663 | ||
664 | NV_DEBUG(dev, "type %d, or %d\n", type, or); | 664 | NV_DEBUG_KMS(dev, "type %d, or %d\n", type, or); |
665 | if (type == OUTPUT_ANY) { | 665 | if (type == OUTPUT_ANY) { |
666 | NV_ERROR(dev, "unknown encoder!!\n"); | 666 | NV_ERROR(dev, "unknown encoder!!\n"); |
667 | return -1; | 667 | return -1; |
@@ -811,7 +811,7 @@ nv50_display_unk20_handler(struct drm_device *dev) | |||
811 | pclk = nv_rd32(dev, NV50_PDISPLAY_CRTC_P(head, CLOCK)) & 0x3fffff; | 811 | pclk = nv_rd32(dev, NV50_PDISPLAY_CRTC_P(head, CLOCK)) & 0x3fffff; |
812 | script = nv50_display_script_select(dev, dcbent, pclk); | 812 | script = nv50_display_script_select(dev, dcbent, pclk); |
813 | 813 | ||
814 | NV_DEBUG(dev, "head %d pxclk: %dKHz\n", head, pclk); | 814 | NV_DEBUG_KMS(dev, "head %d pxclk: %dKHz\n", head, pclk); |
815 | 815 | ||
816 | if (dcbent->type != OUTPUT_DP) | 816 | if (dcbent->type != OUTPUT_DP) |
817 | nouveau_bios_run_display_table(dev, dcbent, 0, -2); | 817 | nouveau_bios_run_display_table(dev, dcbent, 0, -2); |
@@ -870,7 +870,7 @@ nv50_display_irq_handler_bh(struct work_struct *work) | |||
870 | uint32_t intr0 = nv_rd32(dev, NV50_PDISPLAY_INTR_0); | 870 | uint32_t intr0 = nv_rd32(dev, NV50_PDISPLAY_INTR_0); |
871 | uint32_t intr1 = nv_rd32(dev, NV50_PDISPLAY_INTR_1); | 871 | uint32_t intr1 = nv_rd32(dev, NV50_PDISPLAY_INTR_1); |
872 | 872 | ||
873 | NV_DEBUG(dev, "PDISPLAY_INTR_BH 0x%08x 0x%08x\n", intr0, intr1); | 873 | NV_DEBUG_KMS(dev, "PDISPLAY_INTR_BH 0x%08x 0x%08x\n", intr0, intr1); |
874 | 874 | ||
875 | if (intr1 & NV50_PDISPLAY_INTR_1_CLK_UNK10) | 875 | if (intr1 & NV50_PDISPLAY_INTR_1_CLK_UNK10) |
876 | nv50_display_unk10_handler(dev); | 876 | nv50_display_unk10_handler(dev); |
@@ -974,7 +974,7 @@ nv50_display_irq_handler(struct drm_device *dev) | |||
974 | uint32_t intr1 = nv_rd32(dev, NV50_PDISPLAY_INTR_1); | 974 | uint32_t intr1 = nv_rd32(dev, NV50_PDISPLAY_INTR_1); |
975 | uint32_t clock; | 975 | uint32_t clock; |
976 | 976 | ||
977 | NV_DEBUG(dev, "PDISPLAY_INTR 0x%08x 0x%08x\n", intr0, intr1); | 977 | NV_DEBUG_KMS(dev, "PDISPLAY_INTR 0x%08x 0x%08x\n", intr0, intr1); |
978 | 978 | ||
979 | if (!intr0 && !(intr1 & ~delayed)) | 979 | if (!intr0 && !(intr1 & ~delayed)) |
980 | break; | 980 | break; |
diff --git a/drivers/gpu/drm/nouveau/nv50_fifo.c b/drivers/gpu/drm/nouveau/nv50_fifo.c index 77ae1aaa0bce..b7282284f080 100644 --- a/drivers/gpu/drm/nouveau/nv50_fifo.c +++ b/drivers/gpu/drm/nouveau/nv50_fifo.c | |||
@@ -416,7 +416,7 @@ nv50_fifo_unload_context(struct drm_device *dev) | |||
416 | NV_DEBUG(dev, "\n"); | 416 | NV_DEBUG(dev, "\n"); |
417 | 417 | ||
418 | chid = pfifo->channel_id(dev); | 418 | chid = pfifo->channel_id(dev); |
419 | if (chid < 0 || chid >= dev_priv->engine.fifo.channels) | 419 | if (chid < 1 || chid >= dev_priv->engine.fifo.channels - 1) |
420 | return 0; | 420 | return 0; |
421 | 421 | ||
422 | chan = dev_priv->fifos[chid]; | 422 | chan = dev_priv->fifos[chid]; |
diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c index 177d8229336f..ca79f32be44c 100644 --- a/drivers/gpu/drm/nouveau/nv50_graph.c +++ b/drivers/gpu/drm/nouveau/nv50_graph.c | |||
@@ -107,9 +107,13 @@ nv50_graph_init_regs(struct drm_device *dev) | |||
107 | static int | 107 | static int |
108 | nv50_graph_init_ctxctl(struct drm_device *dev) | 108 | nv50_graph_init_ctxctl(struct drm_device *dev) |
109 | { | 109 | { |
110 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
111 | |||
110 | NV_DEBUG(dev, "\n"); | 112 | NV_DEBUG(dev, "\n"); |
111 | 113 | ||
112 | nv40_grctx_init(dev); | 114 | nouveau_grctx_prog_load(dev); |
115 | if (!dev_priv->engine.graph.ctxprog) | ||
116 | dev_priv->engine.graph.accel_blocked = true; | ||
113 | 117 | ||
114 | nv_wr32(dev, 0x400320, 4); | 118 | nv_wr32(dev, 0x400320, 4); |
115 | nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, 0); | 119 | nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, 0); |
@@ -140,7 +144,7 @@ void | |||
140 | nv50_graph_takedown(struct drm_device *dev) | 144 | nv50_graph_takedown(struct drm_device *dev) |
141 | { | 145 | { |
142 | NV_DEBUG(dev, "\n"); | 146 | NV_DEBUG(dev, "\n"); |
143 | nv40_grctx_fini(dev); | 147 | nouveau_grctx_fini(dev); |
144 | } | 148 | } |
145 | 149 | ||
146 | void | 150 | void |
@@ -207,7 +211,7 @@ nv50_graph_create_context(struct nouveau_channel *chan) | |||
207 | dev_priv->engine.instmem.finish_access(dev); | 211 | dev_priv->engine.instmem.finish_access(dev); |
208 | 212 | ||
209 | dev_priv->engine.instmem.prepare_access(dev, true); | 213 | dev_priv->engine.instmem.prepare_access(dev, true); |
210 | nv40_grctx_vals_load(dev, ctx); | 214 | nouveau_grctx_vals_load(dev, ctx); |
211 | nv_wo32(dev, ctx, 0x00000/4, chan->ramin->instance >> 12); | 215 | nv_wo32(dev, ctx, 0x00000/4, chan->ramin->instance >> 12); |
212 | if ((dev_priv->chipset & 0xf0) == 0xa0) | 216 | if ((dev_priv->chipset & 0xf0) == 0xa0) |
213 | nv_wo32(dev, ctx, 0x00004/4, 0x00000000); | 217 | nv_wo32(dev, ctx, 0x00004/4, 0x00000000); |
diff --git a/drivers/gpu/drm/nouveau/nv50_sor.c b/drivers/gpu/drm/nouveau/nv50_sor.c index 8c280463a664..e395c16d30f5 100644 --- a/drivers/gpu/drm/nouveau/nv50_sor.c +++ b/drivers/gpu/drm/nouveau/nv50_sor.c | |||
@@ -44,7 +44,7 @@ nv50_sor_disconnect(struct nouveau_encoder *nv_encoder) | |||
44 | struct nouveau_channel *evo = dev_priv->evo; | 44 | struct nouveau_channel *evo = dev_priv->evo; |
45 | int ret; | 45 | int ret; |
46 | 46 | ||
47 | NV_DEBUG(dev, "Disconnecting SOR %d\n", nv_encoder->or); | 47 | NV_DEBUG_KMS(dev, "Disconnecting SOR %d\n", nv_encoder->or); |
48 | 48 | ||
49 | ret = RING_SPACE(evo, 2); | 49 | ret = RING_SPACE(evo, 2); |
50 | if (ret) { | 50 | if (ret) { |
@@ -70,7 +70,7 @@ nv50_sor_dp_link_train(struct drm_encoder *encoder) | |||
70 | } | 70 | } |
71 | 71 | ||
72 | if (dpe->script0) { | 72 | if (dpe->script0) { |
73 | NV_DEBUG(dev, "SOR-%d: running DP script 0\n", nv_encoder->or); | 73 | NV_DEBUG_KMS(dev, "SOR-%d: running DP script 0\n", nv_encoder->or); |
74 | nouveau_bios_run_init_table(dev, le16_to_cpu(dpe->script0), | 74 | nouveau_bios_run_init_table(dev, le16_to_cpu(dpe->script0), |
75 | nv_encoder->dcb); | 75 | nv_encoder->dcb); |
76 | } | 76 | } |
@@ -79,7 +79,7 @@ nv50_sor_dp_link_train(struct drm_encoder *encoder) | |||
79 | NV_ERROR(dev, "SOR-%d: link training failed\n", nv_encoder->or); | 79 | NV_ERROR(dev, "SOR-%d: link training failed\n", nv_encoder->or); |
80 | 80 | ||
81 | if (dpe->script1) { | 81 | if (dpe->script1) { |
82 | NV_DEBUG(dev, "SOR-%d: running DP script 1\n", nv_encoder->or); | 82 | NV_DEBUG_KMS(dev, "SOR-%d: running DP script 1\n", nv_encoder->or); |
83 | nouveau_bios_run_init_table(dev, le16_to_cpu(dpe->script1), | 83 | nouveau_bios_run_init_table(dev, le16_to_cpu(dpe->script1), |
84 | nv_encoder->dcb); | 84 | nv_encoder->dcb); |
85 | } | 85 | } |
@@ -93,7 +93,7 @@ nv50_sor_dpms(struct drm_encoder *encoder, int mode) | |||
93 | uint32_t val; | 93 | uint32_t val; |
94 | int or = nv_encoder->or; | 94 | int or = nv_encoder->or; |
95 | 95 | ||
96 | NV_DEBUG(dev, "or %d mode %d\n", or, mode); | 96 | NV_DEBUG_KMS(dev, "or %d mode %d\n", or, mode); |
97 | 97 | ||
98 | /* wait for it to be done */ | 98 | /* wait for it to be done */ |
99 | if (!nv_wait(NV50_PDISPLAY_SOR_DPMS_CTRL(or), | 99 | if (!nv_wait(NV50_PDISPLAY_SOR_DPMS_CTRL(or), |
@@ -142,7 +142,7 @@ nv50_sor_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
142 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | 142 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); |
143 | struct nouveau_connector *connector; | 143 | struct nouveau_connector *connector; |
144 | 144 | ||
145 | NV_DEBUG(encoder->dev, "or %d\n", nv_encoder->or); | 145 | NV_DEBUG_KMS(encoder->dev, "or %d\n", nv_encoder->or); |
146 | 146 | ||
147 | connector = nouveau_encoder_connector_get(nv_encoder); | 147 | connector = nouveau_encoder_connector_get(nv_encoder); |
148 | if (!connector) { | 148 | if (!connector) { |
@@ -182,7 +182,7 @@ nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
182 | uint32_t mode_ctl = 0; | 182 | uint32_t mode_ctl = 0; |
183 | int ret; | 183 | int ret; |
184 | 184 | ||
185 | NV_DEBUG(dev, "or %d\n", nv_encoder->or); | 185 | NV_DEBUG_KMS(dev, "or %d\n", nv_encoder->or); |
186 | 186 | ||
187 | nv50_sor_dpms(encoder, DRM_MODE_DPMS_ON); | 187 | nv50_sor_dpms(encoder, DRM_MODE_DPMS_ON); |
188 | 188 | ||
@@ -246,7 +246,7 @@ nv50_sor_destroy(struct drm_encoder *encoder) | |||
246 | if (!encoder) | 246 | if (!encoder) |
247 | return; | 247 | return; |
248 | 248 | ||
249 | NV_DEBUG(encoder->dev, "\n"); | 249 | NV_DEBUG_KMS(encoder->dev, "\n"); |
250 | 250 | ||
251 | drm_encoder_cleanup(encoder); | 251 | drm_encoder_cleanup(encoder); |
252 | 252 | ||
@@ -265,7 +265,7 @@ nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry) | |||
265 | bool dum; | 265 | bool dum; |
266 | int type; | 266 | int type; |
267 | 267 | ||
268 | NV_DEBUG(dev, "\n"); | 268 | NV_DEBUG_KMS(dev, "\n"); |
269 | 269 | ||
270 | switch (entry->type) { | 270 | switch (entry->type) { |
271 | case OUTPUT_TMDS: | 271 | case OUTPUT_TMDS: |
diff --git a/drivers/gpu/drm/r128/r128_drv.c b/drivers/gpu/drm/r128/r128_drv.c index 601f4c0e5da5..b806fdcc7170 100644 --- a/drivers/gpu/drm/r128/r128_drv.c +++ b/drivers/gpu/drm/r128/r128_drv.c | |||
@@ -64,7 +64,7 @@ static struct drm_driver driver = { | |||
64 | .owner = THIS_MODULE, | 64 | .owner = THIS_MODULE, |
65 | .open = drm_open, | 65 | .open = drm_open, |
66 | .release = drm_release, | 66 | .release = drm_release, |
67 | .ioctl = drm_ioctl, | 67 | .unlocked_ioctl = drm_ioctl, |
68 | .mmap = drm_mmap, | 68 | .mmap = drm_mmap, |
69 | .poll = drm_poll, | 69 | .poll = drm_poll, |
70 | .fasync = drm_fasync, | 70 | .fasync = drm_fasync, |
diff --git a/drivers/gpu/drm/r128/r128_ioc32.c b/drivers/gpu/drm/r128/r128_ioc32.c index d3cb676eee84..51c99fc4dd38 100644 --- a/drivers/gpu/drm/r128/r128_ioc32.c +++ b/drivers/gpu/drm/r128/r128_ioc32.c | |||
@@ -95,8 +95,7 @@ static int compat_r128_init(struct file *file, unsigned int cmd, | |||
95 | &init->agp_textures_offset)) | 95 | &init->agp_textures_offset)) |
96 | return -EFAULT; | 96 | return -EFAULT; |
97 | 97 | ||
98 | return drm_ioctl(file->f_path.dentry->d_inode, file, | 98 | return drm_ioctl(file, DRM_IOCTL_R128_INIT, (unsigned long)init); |
99 | DRM_IOCTL_R128_INIT, (unsigned long)init); | ||
100 | } | 99 | } |
101 | 100 | ||
102 | typedef struct drm_r128_depth32 { | 101 | typedef struct drm_r128_depth32 { |
@@ -129,8 +128,7 @@ static int compat_r128_depth(struct file *file, unsigned int cmd, | |||
129 | &depth->mask)) | 128 | &depth->mask)) |
130 | return -EFAULT; | 129 | return -EFAULT; |
131 | 130 | ||
132 | return drm_ioctl(file->f_path.dentry->d_inode, file, | 131 | return drm_ioctl(file, DRM_IOCTL_R128_DEPTH, (unsigned long)depth); |
133 | DRM_IOCTL_R128_DEPTH, (unsigned long)depth); | ||
134 | 132 | ||
135 | } | 133 | } |
136 | 134 | ||
@@ -153,8 +151,7 @@ static int compat_r128_stipple(struct file *file, unsigned int cmd, | |||
153 | &stipple->mask)) | 151 | &stipple->mask)) |
154 | return -EFAULT; | 152 | return -EFAULT; |
155 | 153 | ||
156 | return drm_ioctl(file->f_path.dentry->d_inode, file, | 154 | return drm_ioctl(file, DRM_IOCTL_R128_STIPPLE, (unsigned long)stipple); |
157 | DRM_IOCTL_R128_STIPPLE, (unsigned long)stipple); | ||
158 | } | 155 | } |
159 | 156 | ||
160 | typedef struct drm_r128_getparam32 { | 157 | typedef struct drm_r128_getparam32 { |
@@ -178,8 +175,7 @@ static int compat_r128_getparam(struct file *file, unsigned int cmd, | |||
178 | &getparam->value)) | 175 | &getparam->value)) |
179 | return -EFAULT; | 176 | return -EFAULT; |
180 | 177 | ||
181 | return drm_ioctl(file->f_path.dentry->d_inode, file, | 178 | return drm_ioctl(file, DRM_IOCTL_R128_GETPARAM, (unsigned long)getparam); |
182 | DRM_IOCTL_R128_GETPARAM, (unsigned long)getparam); | ||
183 | } | 179 | } |
184 | 180 | ||
185 | drm_ioctl_compat_t *r128_compat_ioctls[] = { | 181 | drm_ioctl_compat_t *r128_compat_ioctls[] = { |
@@ -210,12 +206,10 @@ long r128_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
210 | if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(r128_compat_ioctls)) | 206 | if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(r128_compat_ioctls)) |
211 | fn = r128_compat_ioctls[nr - DRM_COMMAND_BASE]; | 207 | fn = r128_compat_ioctls[nr - DRM_COMMAND_BASE]; |
212 | 208 | ||
213 | lock_kernel(); /* XXX for now */ | ||
214 | if (fn != NULL) | 209 | if (fn != NULL) |
215 | ret = (*fn) (filp, cmd, arg); | 210 | ret = (*fn) (filp, cmd, arg); |
216 | else | 211 | else |
217 | ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg); | 212 | ret = drm_ioctl(filp, cmd, arg); |
218 | unlock_kernel(); | ||
219 | 213 | ||
220 | return ret; | 214 | return ret; |
221 | } | 215 | } |
diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c index 6578d19dff93..388140a7e651 100644 --- a/drivers/gpu/drm/radeon/atom.c +++ b/drivers/gpu/drm/radeon/atom.c | |||
@@ -58,6 +58,7 @@ typedef struct { | |||
58 | } atom_exec_context; | 58 | } atom_exec_context; |
59 | 59 | ||
60 | int atom_debug = 0; | 60 | int atom_debug = 0; |
61 | static void atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params); | ||
61 | void atom_execute_table(struct atom_context *ctx, int index, uint32_t * params); | 62 | void atom_execute_table(struct atom_context *ctx, int index, uint32_t * params); |
62 | 63 | ||
63 | static uint32_t atom_arg_mask[8] = | 64 | static uint32_t atom_arg_mask[8] = |
@@ -573,7 +574,7 @@ static void atom_op_calltable(atom_exec_context *ctx, int *ptr, int arg) | |||
573 | else | 574 | else |
574 | SDEBUG(" table: %d\n", idx); | 575 | SDEBUG(" table: %d\n", idx); |
575 | if (U16(ctx->ctx->cmd_table + 4 + 2 * idx)) | 576 | if (U16(ctx->ctx->cmd_table + 4 + 2 * idx)) |
576 | atom_execute_table(ctx->ctx, idx, ctx->ps + ctx->ps_shift); | 577 | atom_execute_table_locked(ctx->ctx, idx, ctx->ps + ctx->ps_shift); |
577 | } | 578 | } |
578 | 579 | ||
579 | static void atom_op_clear(atom_exec_context *ctx, int *ptr, int arg) | 580 | static void atom_op_clear(atom_exec_context *ctx, int *ptr, int arg) |
@@ -1040,7 +1041,7 @@ static struct { | |||
1040 | atom_op_shr, ATOM_ARG_MC}, { | 1041 | atom_op_shr, ATOM_ARG_MC}, { |
1041 | atom_op_debug, 0},}; | 1042 | atom_op_debug, 0},}; |
1042 | 1043 | ||
1043 | void atom_execute_table(struct atom_context *ctx, int index, uint32_t * params) | 1044 | static void atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params) |
1044 | { | 1045 | { |
1045 | int base = CU16(ctx->cmd_table + 4 + 2 * index); | 1046 | int base = CU16(ctx->cmd_table + 4 + 2 * index); |
1046 | int len, ws, ps, ptr; | 1047 | int len, ws, ps, ptr; |
@@ -1092,6 +1093,13 @@ void atom_execute_table(struct atom_context *ctx, int index, uint32_t * params) | |||
1092 | kfree(ectx.ws); | 1093 | kfree(ectx.ws); |
1093 | } | 1094 | } |
1094 | 1095 | ||
1096 | void atom_execute_table(struct atom_context *ctx, int index, uint32_t * params) | ||
1097 | { | ||
1098 | mutex_lock(&ctx->mutex); | ||
1099 | atom_execute_table_locked(ctx, index, params); | ||
1100 | mutex_unlock(&ctx->mutex); | ||
1101 | } | ||
1102 | |||
1095 | static int atom_iio_len[] = { 1, 2, 3, 3, 3, 3, 4, 4, 4, 3 }; | 1103 | static int atom_iio_len[] = { 1, 2, 3, 3, 3, 3, 4, 4, 4, 3 }; |
1096 | 1104 | ||
1097 | static void atom_index_iio(struct atom_context *ctx, int base) | 1105 | static void atom_index_iio(struct atom_context *ctx, int base) |
diff --git a/drivers/gpu/drm/radeon/atom.h b/drivers/gpu/drm/radeon/atom.h index 6671848e5ea1..47fd943f6d14 100644 --- a/drivers/gpu/drm/radeon/atom.h +++ b/drivers/gpu/drm/radeon/atom.h | |||
@@ -120,6 +120,7 @@ struct card_info { | |||
120 | 120 | ||
121 | struct atom_context { | 121 | struct atom_context { |
122 | struct card_info *card; | 122 | struct card_info *card; |
123 | struct mutex mutex; | ||
123 | void *bios; | 124 | void *bios; |
124 | uint32_t cmd_table, data_table; | 125 | uint32_t cmd_table, data_table; |
125 | uint16_t *iio; | 126 | uint16_t *iio; |
diff --git a/drivers/gpu/drm/radeon/atombios.h b/drivers/gpu/drm/radeon/atombios.h index 5f48515c77a7..91ad0d1c1b17 100644 --- a/drivers/gpu/drm/radeon/atombios.h +++ b/drivers/gpu/drm/radeon/atombios.h | |||
@@ -4690,6 +4690,205 @@ typedef struct _ATOM_POWERPLAY_INFO_V3 { | |||
4690 | ATOM_POWERMODE_INFO_V3 asPowerPlayInfo[ATOM_MAX_NUMBEROF_POWER_BLOCK]; | 4690 | ATOM_POWERMODE_INFO_V3 asPowerPlayInfo[ATOM_MAX_NUMBEROF_POWER_BLOCK]; |
4691 | } ATOM_POWERPLAY_INFO_V3; | 4691 | } ATOM_POWERPLAY_INFO_V3; |
4692 | 4692 | ||
4693 | /* New PPlib */ | ||
4694 | /**************************************************************************/ | ||
4695 | typedef struct _ATOM_PPLIB_THERMALCONTROLLER | ||
4696 | |||
4697 | { | ||
4698 | UCHAR ucType; // one of ATOM_PP_THERMALCONTROLLER_* | ||
4699 | UCHAR ucI2cLine; // as interpreted by DAL I2C | ||
4700 | UCHAR ucI2cAddress; | ||
4701 | UCHAR ucFanParameters; // Fan Control Parameters. | ||
4702 | UCHAR ucFanMinRPM; // Fan Minimum RPM (hundreds) -- for display purposes only. | ||
4703 | UCHAR ucFanMaxRPM; // Fan Maximum RPM (hundreds) -- for display purposes only. | ||
4704 | UCHAR ucReserved; // ---- | ||
4705 | UCHAR ucFlags; // to be defined | ||
4706 | } ATOM_PPLIB_THERMALCONTROLLER; | ||
4707 | |||
4708 | #define ATOM_PP_FANPARAMETERS_TACHOMETER_PULSES_PER_REVOLUTION_MASK 0x0f | ||
4709 | #define ATOM_PP_FANPARAMETERS_NOFAN 0x80 // No fan is connected to this controller. | ||
4710 | |||
4711 | #define ATOM_PP_THERMALCONTROLLER_NONE 0 | ||
4712 | #define ATOM_PP_THERMALCONTROLLER_LM63 1 // Not used by PPLib | ||
4713 | #define ATOM_PP_THERMALCONTROLLER_ADM1032 2 // Not used by PPLib | ||
4714 | #define ATOM_PP_THERMALCONTROLLER_ADM1030 3 // Not used by PPLib | ||
4715 | #define ATOM_PP_THERMALCONTROLLER_MUA6649 4 // Not used by PPLib | ||
4716 | #define ATOM_PP_THERMALCONTROLLER_LM64 5 | ||
4717 | #define ATOM_PP_THERMALCONTROLLER_F75375 6 // Not used by PPLib | ||
4718 | #define ATOM_PP_THERMALCONTROLLER_RV6xx 7 | ||
4719 | #define ATOM_PP_THERMALCONTROLLER_RV770 8 | ||
4720 | #define ATOM_PP_THERMALCONTROLLER_ADT7473 9 | ||
4721 | |||
4722 | typedef struct _ATOM_PPLIB_STATE | ||
4723 | { | ||
4724 | UCHAR ucNonClockStateIndex; | ||
4725 | UCHAR ucClockStateIndices[1]; // variable-sized | ||
4726 | } ATOM_PPLIB_STATE; | ||
4727 | |||
4728 | //// ATOM_PPLIB_POWERPLAYTABLE::ulPlatformCaps | ||
4729 | #define ATOM_PP_PLATFORM_CAP_BACKBIAS 1 | ||
4730 | #define ATOM_PP_PLATFORM_CAP_POWERPLAY 2 | ||
4731 | #define ATOM_PP_PLATFORM_CAP_SBIOSPOWERSOURCE 4 | ||
4732 | #define ATOM_PP_PLATFORM_CAP_ASPM_L0s 8 | ||
4733 | #define ATOM_PP_PLATFORM_CAP_ASPM_L1 16 | ||
4734 | #define ATOM_PP_PLATFORM_CAP_HARDWAREDC 32 | ||
4735 | #define ATOM_PP_PLATFORM_CAP_GEMINIPRIMARY 64 | ||
4736 | #define ATOM_PP_PLATFORM_CAP_STEPVDDC 128 | ||
4737 | #define ATOM_PP_PLATFORM_CAP_VOLTAGECONTROL 256 | ||
4738 | #define ATOM_PP_PLATFORM_CAP_SIDEPORTCONTROL 512 | ||
4739 | #define ATOM_PP_PLATFORM_CAP_TURNOFFPLL_ASPML1 1024 | ||
4740 | #define ATOM_PP_PLATFORM_CAP_HTLINKCONTROL 2048 | ||
4741 | |||
4742 | typedef struct _ATOM_PPLIB_POWERPLAYTABLE | ||
4743 | { | ||
4744 | ATOM_COMMON_TABLE_HEADER sHeader; | ||
4745 | |||
4746 | UCHAR ucDataRevision; | ||
4747 | |||
4748 | UCHAR ucNumStates; | ||
4749 | UCHAR ucStateEntrySize; | ||
4750 | UCHAR ucClockInfoSize; | ||
4751 | UCHAR ucNonClockSize; | ||
4752 | |||
4753 | // offset from start of this table to array of ucNumStates ATOM_PPLIB_STATE structures | ||
4754 | USHORT usStateArrayOffset; | ||
4755 | |||
4756 | // offset from start of this table to array of ASIC-specific structures, | ||
4757 | // currently ATOM_PPLIB_CLOCK_INFO. | ||
4758 | USHORT usClockInfoArrayOffset; | ||
4759 | |||
4760 | // offset from start of this table to array of ATOM_PPLIB_NONCLOCK_INFO | ||
4761 | USHORT usNonClockInfoArrayOffset; | ||
4762 | |||
4763 | USHORT usBackbiasTime; // in microseconds | ||
4764 | USHORT usVoltageTime; // in microseconds | ||
4765 | USHORT usTableSize; //the size of this structure, or the extended structure | ||
4766 | |||
4767 | ULONG ulPlatformCaps; // See ATOM_PPLIB_CAPS_* | ||
4768 | |||
4769 | ATOM_PPLIB_THERMALCONTROLLER sThermalController; | ||
4770 | |||
4771 | USHORT usBootClockInfoOffset; | ||
4772 | USHORT usBootNonClockInfoOffset; | ||
4773 | |||
4774 | } ATOM_PPLIB_POWERPLAYTABLE; | ||
4775 | |||
4776 | //// ATOM_PPLIB_NONCLOCK_INFO::usClassification | ||
4777 | #define ATOM_PPLIB_CLASSIFICATION_UI_MASK 0x0007 | ||
4778 | #define ATOM_PPLIB_CLASSIFICATION_UI_SHIFT 0 | ||
4779 | #define ATOM_PPLIB_CLASSIFICATION_UI_NONE 0 | ||
4780 | #define ATOM_PPLIB_CLASSIFICATION_UI_BATTERY 1 | ||
4781 | #define ATOM_PPLIB_CLASSIFICATION_UI_BALANCED 3 | ||
4782 | #define ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE 5 | ||
4783 | // 2, 4, 6, 7 are reserved | ||
4784 | |||
4785 | #define ATOM_PPLIB_CLASSIFICATION_BOOT 0x0008 | ||
4786 | #define ATOM_PPLIB_CLASSIFICATION_THERMAL 0x0010 | ||
4787 | #define ATOM_PPLIB_CLASSIFICATION_LIMITEDPOWERSOURCE 0x0020 | ||
4788 | #define ATOM_PPLIB_CLASSIFICATION_REST 0x0040 | ||
4789 | #define ATOM_PPLIB_CLASSIFICATION_FORCED 0x0080 | ||
4790 | #define ATOM_PPLIB_CLASSIFICATION_3DPERFORMANCE 0x0100 | ||
4791 | #define ATOM_PPLIB_CLASSIFICATION_OVERDRIVETEMPLATE 0x0200 | ||
4792 | #define ATOM_PPLIB_CLASSIFICATION_UVDSTATE 0x0400 | ||
4793 | #define ATOM_PPLIB_CLASSIFICATION_3DLOW 0x0800 | ||
4794 | #define ATOM_PPLIB_CLASSIFICATION_ACPI 0x1000 | ||
4795 | // remaining 3 bits are reserved | ||
4796 | |||
4797 | //// ATOM_PPLIB_NONCLOCK_INFO::ulCapsAndSettings | ||
4798 | #define ATOM_PPLIB_SINGLE_DISPLAY_ONLY 0x00000001 | ||
4799 | #define ATOM_PPLIB_SUPPORTS_VIDEO_PLAYBACK 0x00000002 | ||
4800 | |||
4801 | // 0 is 2.5Gb/s, 1 is 5Gb/s | ||
4802 | #define ATOM_PPLIB_PCIE_LINK_SPEED_MASK 0x00000004 | ||
4803 | #define ATOM_PPLIB_PCIE_LINK_SPEED_SHIFT 2 | ||
4804 | |||
4805 | // lanes - 1: 1, 2, 4, 8, 12, 16 permitted by PCIE spec | ||
4806 | #define ATOM_PPLIB_PCIE_LINK_WIDTH_MASK 0x000000F8 | ||
4807 | #define ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT 3 | ||
4808 | |||
4809 | // lookup into reduced refresh-rate table | ||
4810 | #define ATOM_PPLIB_LIMITED_REFRESHRATE_VALUE_MASK 0x00000F00 | ||
4811 | #define ATOM_PPLIB_LIMITED_REFRESHRATE_VALUE_SHIFT 8 | ||
4812 | |||
4813 | #define ATOM_PPLIB_LIMITED_REFRESHRATE_UNLIMITED 0 | ||
4814 | #define ATOM_PPLIB_LIMITED_REFRESHRATE_50HZ 1 | ||
4815 | // 2-15 TBD as needed. | ||
4816 | |||
4817 | #define ATOM_PPLIB_SOFTWARE_DISABLE_LOADBALANCING 0x00001000 | ||
4818 | #define ATOM_PPLIB_SOFTWARE_ENABLE_SLEEP_FOR_TIMESTAMPS 0x00002000 | ||
4819 | #define ATOM_PPLIB_ENABLE_VARIBRIGHT 0x00008000 | ||
4820 | |||
4821 | #define ATOM_PPLIB_DISALLOW_ON_DC 0x00004000 | ||
4822 | |||
4823 | // Contained in an array starting at the offset | ||
4824 | // in ATOM_PPLIB_POWERPLAYTABLE::usNonClockInfoArrayOffset. | ||
4825 | // referenced from ATOM_PPLIB_STATE_INFO::ucNonClockStateIndex | ||
4826 | typedef struct _ATOM_PPLIB_NONCLOCK_INFO | ||
4827 | { | ||
4828 | USHORT usClassification; | ||
4829 | UCHAR ucMinTemperature; | ||
4830 | UCHAR ucMaxTemperature; | ||
4831 | ULONG ulCapsAndSettings; | ||
4832 | UCHAR ucRequiredPower; | ||
4833 | UCHAR ucUnused1[3]; | ||
4834 | } ATOM_PPLIB_NONCLOCK_INFO; | ||
4835 | |||
4836 | // Contained in an array starting at the offset | ||
4837 | // in ATOM_PPLIB_POWERPLAYTABLE::usClockInfoArrayOffset. | ||
4838 | // referenced from ATOM_PPLIB_STATE::ucClockStateIndices | ||
4839 | typedef struct _ATOM_PPLIB_R600_CLOCK_INFO | ||
4840 | { | ||
4841 | USHORT usEngineClockLow; | ||
4842 | UCHAR ucEngineClockHigh; | ||
4843 | |||
4844 | USHORT usMemoryClockLow; | ||
4845 | UCHAR ucMemoryClockHigh; | ||
4846 | |||
4847 | USHORT usVDDC; | ||
4848 | USHORT usUnused1; | ||
4849 | USHORT usUnused2; | ||
4850 | |||
4851 | ULONG ulFlags; // ATOM_PPLIB_R600_FLAGS_* | ||
4852 | |||
4853 | } ATOM_PPLIB_R600_CLOCK_INFO; | ||
4854 | |||
4855 | // ulFlags in ATOM_PPLIB_R600_CLOCK_INFO | ||
4856 | #define ATOM_PPLIB_R600_FLAGS_PCIEGEN2 1 | ||
4857 | #define ATOM_PPLIB_R600_FLAGS_UVDSAFE 2 | ||
4858 | #define ATOM_PPLIB_R600_FLAGS_BACKBIASENABLE 4 | ||
4859 | #define ATOM_PPLIB_R600_FLAGS_MEMORY_ODT_OFF 8 | ||
4860 | #define ATOM_PPLIB_R600_FLAGS_MEMORY_DLL_OFF 16 | ||
4861 | |||
4862 | typedef struct _ATOM_PPLIB_RS780_CLOCK_INFO | ||
4863 | |||
4864 | { | ||
4865 | USHORT usLowEngineClockLow; // Low Engine clock in MHz (the same way as on the R600). | ||
4866 | UCHAR ucLowEngineClockHigh; | ||
4867 | USHORT usHighEngineClockLow; // High Engine clock in MHz. | ||
4868 | UCHAR ucHighEngineClockHigh; | ||
4869 | USHORT usMemoryClockLow; // For now one of the ATOM_PPLIB_RS780_SPMCLK_XXXX constants. | ||
4870 | UCHAR ucMemoryClockHigh; // Currentyl unused. | ||
4871 | UCHAR ucPadding; // For proper alignment and size. | ||
4872 | USHORT usVDDC; // For the 780, use: None, Low, High, Variable | ||
4873 | UCHAR ucMaxHTLinkWidth; // From SBIOS - {2, 4, 8, 16} | ||
4874 | UCHAR ucMinHTLinkWidth; // From SBIOS - {2, 4, 8, 16}. Effective only if CDLW enabled. Minimum down stream width could be bigger as display BW requriement. | ||
4875 | USHORT usHTLinkFreq; // See definition ATOM_PPLIB_RS780_HTLINKFREQ_xxx or in MHz(>=200). | ||
4876 | ULONG ulFlags; | ||
4877 | } ATOM_PPLIB_RS780_CLOCK_INFO; | ||
4878 | |||
4879 | #define ATOM_PPLIB_RS780_VOLTAGE_NONE 0 | ||
4880 | #define ATOM_PPLIB_RS780_VOLTAGE_LOW 1 | ||
4881 | #define ATOM_PPLIB_RS780_VOLTAGE_HIGH 2 | ||
4882 | #define ATOM_PPLIB_RS780_VOLTAGE_VARIABLE 3 | ||
4883 | |||
4884 | #define ATOM_PPLIB_RS780_SPMCLK_NONE 0 // We cannot change the side port memory clock, leave it as it is. | ||
4885 | #define ATOM_PPLIB_RS780_SPMCLK_LOW 1 | ||
4886 | #define ATOM_PPLIB_RS780_SPMCLK_HIGH 2 | ||
4887 | |||
4888 | #define ATOM_PPLIB_RS780_HTLINKFREQ_NONE 0 | ||
4889 | #define ATOM_PPLIB_RS780_HTLINKFREQ_LOW 1 | ||
4890 | #define ATOM_PPLIB_RS780_HTLINKFREQ_HIGH 2 | ||
4891 | |||
4693 | /**************************************************************************/ | 4892 | /**************************************************************************/ |
4694 | 4893 | ||
4695 | /* Following definitions are for compatiblity issue in different SW components. */ | 4894 | /* Following definitions are for compatiblity issue in different SW components. */ |
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 84e5df766d3f..71727460968f 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
@@ -2881,6 +2881,10 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) | |||
2881 | 2881 | ||
2882 | for (i = 0; i < track->num_cb; i++) { | 2882 | for (i = 0; i < track->num_cb; i++) { |
2883 | if (track->cb[i].robj == NULL) { | 2883 | if (track->cb[i].robj == NULL) { |
2884 | if (!(track->fastfill || track->color_channel_mask || | ||
2885 | track->blend_read_enable)) { | ||
2886 | continue; | ||
2887 | } | ||
2884 | DRM_ERROR("[drm] No buffer for color buffer %d !\n", i); | 2888 | DRM_ERROR("[drm] No buffer for color buffer %d !\n", i); |
2885 | return -EINVAL; | 2889 | return -EINVAL; |
2886 | } | 2890 | } |
diff --git a/drivers/gpu/drm/radeon/r100_track.h b/drivers/gpu/drm/radeon/r100_track.h index 7188c3778ee2..b27a6999d219 100644 --- a/drivers/gpu/drm/radeon/r100_track.h +++ b/drivers/gpu/drm/radeon/r100_track.h | |||
@@ -67,13 +67,15 @@ struct r100_cs_track { | |||
67 | unsigned immd_dwords; | 67 | unsigned immd_dwords; |
68 | unsigned num_arrays; | 68 | unsigned num_arrays; |
69 | unsigned max_indx; | 69 | unsigned max_indx; |
70 | unsigned color_channel_mask; | ||
70 | struct r100_cs_track_array arrays[11]; | 71 | struct r100_cs_track_array arrays[11]; |
71 | struct r100_cs_track_cb cb[R300_MAX_CB]; | 72 | struct r100_cs_track_cb cb[R300_MAX_CB]; |
72 | struct r100_cs_track_cb zb; | 73 | struct r100_cs_track_cb zb; |
73 | struct r100_cs_track_texture textures[R300_TRACK_MAX_TEXTURE]; | 74 | struct r100_cs_track_texture textures[R300_TRACK_MAX_TEXTURE]; |
74 | bool z_enabled; | 75 | bool z_enabled; |
75 | bool separate_cube; | 76 | bool separate_cube; |
76 | 77 | bool fastfill; | |
78 | bool blend_read_enable; | ||
77 | }; | 79 | }; |
78 | 80 | ||
79 | int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track); | 81 | int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track); |
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 83490c2b5061..3f2cc9e2e8d9 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c | |||
@@ -887,6 +887,14 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
887 | track->textures[i].cpp = 1; | 887 | track->textures[i].cpp = 1; |
888 | track->textures[i].compress_format = R100_TRACK_COMP_DXT1; | 888 | track->textures[i].compress_format = R100_TRACK_COMP_DXT1; |
889 | break; | 889 | break; |
890 | case R300_TX_FORMAT_ATI2N: | ||
891 | if (p->rdev->family < CHIP_R420) { | ||
892 | DRM_ERROR("Invalid texture format %u\n", | ||
893 | (idx_value & 0x1F)); | ||
894 | return -EINVAL; | ||
895 | } | ||
896 | /* The same rules apply as for DXT3/5. */ | ||
897 | /* Pass through. */ | ||
890 | case R300_TX_FORMAT_DXT3: | 898 | case R300_TX_FORMAT_DXT3: |
891 | case R300_TX_FORMAT_DXT5: | 899 | case R300_TX_FORMAT_DXT5: |
892 | track->textures[i].cpp = 1; | 900 | track->textures[i].cpp = 1; |
@@ -951,6 +959,16 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
951 | track->textures[i].width_11 = tmp; | 959 | track->textures[i].width_11 = tmp; |
952 | tmp = ((idx_value >> 16) & 1) << 11; | 960 | tmp = ((idx_value >> 16) & 1) << 11; |
953 | track->textures[i].height_11 = tmp; | 961 | track->textures[i].height_11 = tmp; |
962 | |||
963 | /* ATI1N */ | ||
964 | if (idx_value & (1 << 14)) { | ||
965 | /* The same rules apply as for DXT1. */ | ||
966 | track->textures[i].compress_format = | ||
967 | R100_TRACK_COMP_DXT1; | ||
968 | } | ||
969 | } else if (idx_value & (1 << 14)) { | ||
970 | DRM_ERROR("Forbidden bit TXFORMAT_MSB\n"); | ||
971 | return -EINVAL; | ||
954 | } | 972 | } |
955 | break; | 973 | break; |
956 | case 0x4480: | 974 | case 0x4480: |
@@ -992,6 +1010,18 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
992 | } | 1010 | } |
993 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); | 1011 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
994 | break; | 1012 | break; |
1013 | case 0x4e0c: | ||
1014 | /* RB3D_COLOR_CHANNEL_MASK */ | ||
1015 | track->color_channel_mask = idx_value; | ||
1016 | break; | ||
1017 | case 0x4d1c: | ||
1018 | /* ZB_BW_CNTL */ | ||
1019 | track->fastfill = !!(idx_value & (1 << 2)); | ||
1020 | break; | ||
1021 | case 0x4e04: | ||
1022 | /* RB3D_BLENDCNTL */ | ||
1023 | track->blend_read_enable = !!(idx_value & (1 << 2)); | ||
1024 | break; | ||
995 | case 0x4be8: | 1025 | case 0x4be8: |
996 | /* valid register only on RV530 */ | 1026 | /* valid register only on RV530 */ |
997 | if (p->rdev->family == CHIP_RV530) | 1027 | if (p->rdev->family == CHIP_RV530) |
diff --git a/drivers/gpu/drm/radeon/r300_cmdbuf.c b/drivers/gpu/drm/radeon/r300_cmdbuf.c index cb2e470f97d4..34bffa0e4b73 100644 --- a/drivers/gpu/drm/radeon/r300_cmdbuf.c +++ b/drivers/gpu/drm/radeon/r300_cmdbuf.c | |||
@@ -990,7 +990,7 @@ static inline int r300_emit_r500fp(drm_radeon_private_t *dev_priv, | |||
990 | int sz; | 990 | int sz; |
991 | int addr; | 991 | int addr; |
992 | int type; | 992 | int type; |
993 | int clamp; | 993 | int isclamp; |
994 | int stride; | 994 | int stride; |
995 | RING_LOCALS; | 995 | RING_LOCALS; |
996 | 996 | ||
@@ -999,10 +999,10 @@ static inline int r300_emit_r500fp(drm_radeon_private_t *dev_priv, | |||
999 | addr = ((header.r500fp.adrhi_flags & 1) << 8) | header.r500fp.adrlo; | 999 | addr = ((header.r500fp.adrhi_flags & 1) << 8) | header.r500fp.adrlo; |
1000 | 1000 | ||
1001 | type = !!(header.r500fp.adrhi_flags & R500FP_CONSTANT_TYPE); | 1001 | type = !!(header.r500fp.adrhi_flags & R500FP_CONSTANT_TYPE); |
1002 | clamp = !!(header.r500fp.adrhi_flags & R500FP_CONSTANT_CLAMP); | 1002 | isclamp = !!(header.r500fp.adrhi_flags & R500FP_CONSTANT_CLAMP); |
1003 | 1003 | ||
1004 | addr |= (type << 16); | 1004 | addr |= (type << 16); |
1005 | addr |= (clamp << 17); | 1005 | addr |= (isclamp << 17); |
1006 | 1006 | ||
1007 | stride = type ? 4 : 6; | 1007 | stride = type ? 4 : 6; |
1008 | 1008 | ||
diff --git a/drivers/gpu/drm/radeon/r300_reg.h b/drivers/gpu/drm/radeon/r300_reg.h index 4b7afef35a65..1735a2b69580 100644 --- a/drivers/gpu/drm/radeon/r300_reg.h +++ b/drivers/gpu/drm/radeon/r300_reg.h | |||
@@ -900,6 +900,7 @@ | |||
900 | # define R300_TX_FORMAT_FL_I32 0x1B | 900 | # define R300_TX_FORMAT_FL_I32 0x1B |
901 | # define R300_TX_FORMAT_FL_I32A32 0x1C | 901 | # define R300_TX_FORMAT_FL_I32A32 0x1C |
902 | # define R300_TX_FORMAT_FL_R32G32B32A32 0x1D | 902 | # define R300_TX_FORMAT_FL_R32G32B32A32 0x1D |
903 | # define R300_TX_FORMAT_ATI2N 0x1F | ||
903 | /* alpha modes, convenience mostly */ | 904 | /* alpha modes, convenience mostly */ |
904 | /* if you have alpha, pick constant appropriate to the | 905 | /* if you have alpha, pick constant appropriate to the |
905 | number of channels (1 for I8, 2 for I8A8, 4 for R8G8B8A8, etc */ | 906 | number of channels (1 for I8, 2 for I8A8, 4 for R8G8B8A8, etc */ |
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index 0d820764f340..44060b92d9e6 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c | |||
@@ -170,7 +170,7 @@ static int r600_cs_packet_next_reloc_nomm(struct radeon_cs_parser *p, | |||
170 | idx, relocs_chunk->length_dw); | 170 | idx, relocs_chunk->length_dw); |
171 | return -EINVAL; | 171 | return -EINVAL; |
172 | } | 172 | } |
173 | *cs_reloc = &p->relocs[0]; | 173 | *cs_reloc = p->relocs; |
174 | (*cs_reloc)->lobj.gpu_offset = (u64)relocs_chunk->kdata[idx + 3] << 32; | 174 | (*cs_reloc)->lobj.gpu_offset = (u64)relocs_chunk->kdata[idx + 3] << 32; |
175 | (*cs_reloc)->lobj.gpu_offset |= relocs_chunk->kdata[idx + 0]; | 175 | (*cs_reloc)->lobj.gpu_offset |= relocs_chunk->kdata[idx + 0]; |
176 | return 0; | 176 | return 0; |
@@ -717,7 +717,7 @@ static int r600_cs_parser_relocs_legacy(struct radeon_cs_parser *p) | |||
717 | if (p->chunk_relocs_idx == -1) { | 717 | if (p->chunk_relocs_idx == -1) { |
718 | return 0; | 718 | return 0; |
719 | } | 719 | } |
720 | p->relocs = kcalloc(1, sizeof(struct radeon_cs_reloc), GFP_KERNEL); | 720 | p->relocs = kzalloc(sizeof(struct radeon_cs_reloc), GFP_KERNEL); |
721 | if (p->relocs == NULL) { | 721 | if (p->relocs == NULL) { |
722 | return -ENOMEM; | 722 | return -ENOMEM; |
723 | } | 723 | } |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index cd650fd3964e..53b55608102b 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -162,6 +162,7 @@ struct radeon_fence_driver { | |||
162 | struct list_head created; | 162 | struct list_head created; |
163 | struct list_head emited; | 163 | struct list_head emited; |
164 | struct list_head signaled; | 164 | struct list_head signaled; |
165 | bool initialized; | ||
165 | }; | 166 | }; |
166 | 167 | ||
167 | struct radeon_fence { | 168 | struct radeon_fence { |
@@ -202,8 +203,9 @@ struct radeon_surface_reg { | |||
202 | struct radeon_mman { | 203 | struct radeon_mman { |
203 | struct ttm_bo_global_ref bo_global_ref; | 204 | struct ttm_bo_global_ref bo_global_ref; |
204 | struct ttm_global_reference mem_global_ref; | 205 | struct ttm_global_reference mem_global_ref; |
205 | bool mem_global_referenced; | ||
206 | struct ttm_bo_device bdev; | 206 | struct ttm_bo_device bdev; |
207 | bool mem_global_referenced; | ||
208 | bool initialized; | ||
207 | }; | 209 | }; |
208 | 210 | ||
209 | struct radeon_bo { | 211 | struct radeon_bo { |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 636116bedcb4..eb29217bbf1d 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
@@ -33,6 +33,7 @@ | |||
33 | */ | 33 | */ |
34 | uint32_t radeon_legacy_get_engine_clock(struct radeon_device *rdev); | 34 | uint32_t radeon_legacy_get_engine_clock(struct radeon_device *rdev); |
35 | void radeon_legacy_set_engine_clock(struct radeon_device *rdev, uint32_t eng_clock); | 35 | void radeon_legacy_set_engine_clock(struct radeon_device *rdev, uint32_t eng_clock); |
36 | uint32_t radeon_legacy_get_memory_clock(struct radeon_device *rdev); | ||
36 | void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable); | 37 | void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable); |
37 | 38 | ||
38 | uint32_t radeon_atom_get_engine_clock(struct radeon_device *rdev); | 39 | uint32_t radeon_atom_get_engine_clock(struct radeon_device *rdev); |
@@ -106,7 +107,7 @@ static struct radeon_asic r100_asic = { | |||
106 | .copy = &r100_copy_blit, | 107 | .copy = &r100_copy_blit, |
107 | .get_engine_clock = &radeon_legacy_get_engine_clock, | 108 | .get_engine_clock = &radeon_legacy_get_engine_clock, |
108 | .set_engine_clock = &radeon_legacy_set_engine_clock, | 109 | .set_engine_clock = &radeon_legacy_set_engine_clock, |
109 | .get_memory_clock = NULL, | 110 | .get_memory_clock = &radeon_legacy_get_memory_clock, |
110 | .set_memory_clock = NULL, | 111 | .set_memory_clock = NULL, |
111 | .set_pcie_lanes = NULL, | 112 | .set_pcie_lanes = NULL, |
112 | .set_clock_gating = &radeon_legacy_set_clock_gating, | 113 | .set_clock_gating = &radeon_legacy_set_clock_gating, |
@@ -166,7 +167,7 @@ static struct radeon_asic r300_asic = { | |||
166 | .copy = &r100_copy_blit, | 167 | .copy = &r100_copy_blit, |
167 | .get_engine_clock = &radeon_legacy_get_engine_clock, | 168 | .get_engine_clock = &radeon_legacy_get_engine_clock, |
168 | .set_engine_clock = &radeon_legacy_set_engine_clock, | 169 | .set_engine_clock = &radeon_legacy_set_engine_clock, |
169 | .get_memory_clock = NULL, | 170 | .get_memory_clock = &radeon_legacy_get_memory_clock, |
170 | .set_memory_clock = NULL, | 171 | .set_memory_clock = NULL, |
171 | .set_pcie_lanes = &rv370_set_pcie_lanes, | 172 | .set_pcie_lanes = &rv370_set_pcie_lanes, |
172 | .set_clock_gating = &radeon_legacy_set_clock_gating, | 173 | .set_clock_gating = &radeon_legacy_set_clock_gating, |
@@ -259,7 +260,7 @@ static struct radeon_asic rs400_asic = { | |||
259 | .copy = &r100_copy_blit, | 260 | .copy = &r100_copy_blit, |
260 | .get_engine_clock = &radeon_legacy_get_engine_clock, | 261 | .get_engine_clock = &radeon_legacy_get_engine_clock, |
261 | .set_engine_clock = &radeon_legacy_set_engine_clock, | 262 | .set_engine_clock = &radeon_legacy_set_engine_clock, |
262 | .get_memory_clock = NULL, | 263 | .get_memory_clock = &radeon_legacy_get_memory_clock, |
263 | .set_memory_clock = NULL, | 264 | .set_memory_clock = NULL, |
264 | .set_pcie_lanes = NULL, | 265 | .set_pcie_lanes = NULL, |
265 | .set_clock_gating = &radeon_legacy_set_clock_gating, | 266 | .set_clock_gating = &radeon_legacy_set_clock_gating, |
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 12a0c760e7ff..321044bef71c 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
@@ -745,8 +745,7 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct | |||
745 | else | 745 | else |
746 | radeon_add_legacy_encoder(dev, | 746 | radeon_add_legacy_encoder(dev, |
747 | radeon_get_encoder_id(dev, | 747 | radeon_get_encoder_id(dev, |
748 | (1 << | 748 | (1 << i), |
749 | i), | ||
750 | dac), | 749 | dac), |
751 | (1 << i)); | 750 | (1 << i)); |
752 | } | 751 | } |
@@ -758,32 +757,30 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct | |||
758 | if (bios_connectors[j].valid && (i != j)) { | 757 | if (bios_connectors[j].valid && (i != j)) { |
759 | if (bios_connectors[i].line_mux == | 758 | if (bios_connectors[i].line_mux == |
760 | bios_connectors[j].line_mux) { | 759 | bios_connectors[j].line_mux) { |
761 | if (((bios_connectors[i]. | 760 | /* make sure not to combine LVDS */ |
762 | devices & | 761 | if (bios_connectors[i].devices & (ATOM_DEVICE_LCD_SUPPORT)) { |
763 | (ATOM_DEVICE_DFP_SUPPORT)) | 762 | bios_connectors[i].line_mux = 53; |
764 | && (bios_connectors[j]. | 763 | bios_connectors[i].ddc_bus.valid = false; |
765 | devices & | 764 | continue; |
766 | (ATOM_DEVICE_CRT_SUPPORT))) | 765 | } |
767 | || | 766 | if (bios_connectors[j].devices & (ATOM_DEVICE_LCD_SUPPORT)) { |
768 | ((bios_connectors[j]. | 767 | bios_connectors[j].line_mux = 53; |
769 | devices & | 768 | bios_connectors[j].ddc_bus.valid = false; |
770 | (ATOM_DEVICE_DFP_SUPPORT)) | 769 | continue; |
771 | && (bios_connectors[i]. | 770 | } |
772 | devices & | 771 | /* combine analog and digital for DVI-I */ |
773 | (ATOM_DEVICE_CRT_SUPPORT)))) { | 772 | if (((bios_connectors[i].devices & (ATOM_DEVICE_DFP_SUPPORT)) && |
774 | bios_connectors[i]. | 773 | (bios_connectors[j].devices & (ATOM_DEVICE_CRT_SUPPORT))) || |
775 | devices |= | 774 | ((bios_connectors[j].devices & (ATOM_DEVICE_DFP_SUPPORT)) && |
776 | bios_connectors[j]. | 775 | (bios_connectors[i].devices & (ATOM_DEVICE_CRT_SUPPORT)))) { |
777 | devices; | 776 | bios_connectors[i].devices |= |
778 | bios_connectors[i]. | 777 | bios_connectors[j].devices; |
779 | connector_type = | 778 | bios_connectors[i].connector_type = |
780 | DRM_MODE_CONNECTOR_DVII; | 779 | DRM_MODE_CONNECTOR_DVII; |
781 | if (bios_connectors[j].devices & | 780 | if (bios_connectors[j].devices & (ATOM_DEVICE_DFP_SUPPORT)) |
782 | (ATOM_DEVICE_DFP_SUPPORT)) | ||
783 | bios_connectors[i].hpd = | 781 | bios_connectors[i].hpd = |
784 | bios_connectors[j].hpd; | 782 | bios_connectors[j].hpd; |
785 | bios_connectors[j]. | 783 | bios_connectors[j].valid = false; |
786 | valid = false; | ||
787 | } | 784 | } |
788 | } | 785 | } |
789 | } | 786 | } |
@@ -1234,6 +1231,61 @@ bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index, | |||
1234 | return true; | 1231 | return true; |
1235 | } | 1232 | } |
1236 | 1233 | ||
1234 | enum radeon_tv_std | ||
1235 | radeon_atombios_get_tv_info(struct radeon_device *rdev) | ||
1236 | { | ||
1237 | struct radeon_mode_info *mode_info = &rdev->mode_info; | ||
1238 | int index = GetIndexIntoMasterTable(DATA, AnalogTV_Info); | ||
1239 | uint16_t data_offset; | ||
1240 | uint8_t frev, crev; | ||
1241 | struct _ATOM_ANALOG_TV_INFO *tv_info; | ||
1242 | enum radeon_tv_std tv_std = TV_STD_NTSC; | ||
1243 | |||
1244 | atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset); | ||
1245 | |||
1246 | tv_info = (struct _ATOM_ANALOG_TV_INFO *)(mode_info->atom_context->bios + data_offset); | ||
1247 | |||
1248 | switch (tv_info->ucTV_BootUpDefaultStandard) { | ||
1249 | case ATOM_TV_NTSC: | ||
1250 | tv_std = TV_STD_NTSC; | ||
1251 | DRM_INFO("Default TV standard: NTSC\n"); | ||
1252 | break; | ||
1253 | case ATOM_TV_NTSCJ: | ||
1254 | tv_std = TV_STD_NTSC_J; | ||
1255 | DRM_INFO("Default TV standard: NTSC-J\n"); | ||
1256 | break; | ||
1257 | case ATOM_TV_PAL: | ||
1258 | tv_std = TV_STD_PAL; | ||
1259 | DRM_INFO("Default TV standard: PAL\n"); | ||
1260 | break; | ||
1261 | case ATOM_TV_PALM: | ||
1262 | tv_std = TV_STD_PAL_M; | ||
1263 | DRM_INFO("Default TV standard: PAL-M\n"); | ||
1264 | break; | ||
1265 | case ATOM_TV_PALN: | ||
1266 | tv_std = TV_STD_PAL_N; | ||
1267 | DRM_INFO("Default TV standard: PAL-N\n"); | ||
1268 | break; | ||
1269 | case ATOM_TV_PALCN: | ||
1270 | tv_std = TV_STD_PAL_CN; | ||
1271 | DRM_INFO("Default TV standard: PAL-CN\n"); | ||
1272 | break; | ||
1273 | case ATOM_TV_PAL60: | ||
1274 | tv_std = TV_STD_PAL_60; | ||
1275 | DRM_INFO("Default TV standard: PAL-60\n"); | ||
1276 | break; | ||
1277 | case ATOM_TV_SECAM: | ||
1278 | tv_std = TV_STD_SECAM; | ||
1279 | DRM_INFO("Default TV standard: SECAM\n"); | ||
1280 | break; | ||
1281 | default: | ||
1282 | tv_std = TV_STD_NTSC; | ||
1283 | DRM_INFO("Unknown TV standard; defaulting to NTSC\n"); | ||
1284 | break; | ||
1285 | } | ||
1286 | return tv_std; | ||
1287 | } | ||
1288 | |||
1237 | struct radeon_encoder_tv_dac * | 1289 | struct radeon_encoder_tv_dac * |
1238 | radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder) | 1290 | radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder) |
1239 | { | 1291 | { |
@@ -1269,6 +1321,7 @@ radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder) | |||
1269 | dac = dac_info->ucDAC2_NTSC_DAC_Adjustment; | 1321 | dac = dac_info->ucDAC2_NTSC_DAC_Adjustment; |
1270 | tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20); | 1322 | tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20); |
1271 | 1323 | ||
1324 | tv_dac->tv_std = radeon_atombios_get_tv_info(rdev); | ||
1272 | } | 1325 | } |
1273 | return tv_dac; | 1326 | return tv_dac; |
1274 | } | 1327 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_clocks.c b/drivers/gpu/drm/radeon/radeon_clocks.c index b062109efbee..812f24dbc2a8 100644 --- a/drivers/gpu/drm/radeon/radeon_clocks.c +++ b/drivers/gpu/drm/radeon/radeon_clocks.c | |||
@@ -62,7 +62,7 @@ uint32_t radeon_legacy_get_engine_clock(struct radeon_device *rdev) | |||
62 | } | 62 | } |
63 | 63 | ||
64 | /* 10 khz */ | 64 | /* 10 khz */ |
65 | static uint32_t radeon_legacy_get_memory_clock(struct radeon_device *rdev) | 65 | uint32_t radeon_legacy_get_memory_clock(struct radeon_device *rdev) |
66 | { | 66 | { |
67 | struct radeon_pll *mpll = &rdev->clock.mpll; | 67 | struct radeon_pll *mpll = &rdev->clock.mpll; |
68 | uint32_t fb_div, ref_div, post_div, mclk; | 68 | uint32_t fb_div, ref_div, post_div, mclk; |
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index c5021a3445de..fd94dbca33ac 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c | |||
@@ -634,11 +634,10 @@ struct radeon_encoder_primary_dac *radeon_combios_get_primary_dac_info(struct | |||
634 | return p_dac; | 634 | return p_dac; |
635 | } | 635 | } |
636 | 636 | ||
637 | static enum radeon_tv_std | 637 | enum radeon_tv_std |
638 | radeon_combios_get_tv_info(struct radeon_encoder *encoder) | 638 | radeon_combios_get_tv_info(struct radeon_device *rdev) |
639 | { | 639 | { |
640 | struct drm_device *dev = encoder->base.dev; | 640 | struct drm_device *dev = rdev->ddev; |
641 | struct radeon_device *rdev = dev->dev_private; | ||
642 | uint16_t tv_info; | 641 | uint16_t tv_info; |
643 | enum radeon_tv_std tv_std = TV_STD_NTSC; | 642 | enum radeon_tv_std tv_std = TV_STD_NTSC; |
644 | 643 | ||
@@ -779,7 +778,7 @@ struct radeon_encoder_tv_dac *radeon_combios_get_tv_dac_info(struct | |||
779 | tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20); | 778 | tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20); |
780 | found = 1; | 779 | found = 1; |
781 | } | 780 | } |
782 | tv_dac->tv_std = radeon_combios_get_tv_info(encoder); | 781 | tv_dac->tv_std = radeon_combios_get_tv_info(rdev); |
783 | } | 782 | } |
784 | if (!found) { | 783 | if (!found) { |
785 | /* then check CRT table */ | 784 | /* then check CRT table */ |
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 5eece186e03c..20161567dbff 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
@@ -208,6 +208,18 @@ static struct drm_display_mode *radeon_fp_native_mode(struct drm_encoder *encode | |||
208 | drm_mode_set_name(mode); | 208 | drm_mode_set_name(mode); |
209 | 209 | ||
210 | DRM_DEBUG("Adding native panel mode %s\n", mode->name); | 210 | DRM_DEBUG("Adding native panel mode %s\n", mode->name); |
211 | } else if (native_mode->hdisplay != 0 && | ||
212 | native_mode->vdisplay != 0) { | ||
213 | /* mac laptops without an edid */ | ||
214 | /* Note that this is not necessarily the exact panel mode, | ||
215 | * but an approximation based on the cvt formula. For these | ||
216 | * systems we should ideally read the mode info out of the | ||
217 | * registers or add a mode table, but this works and is much | ||
218 | * simpler. | ||
219 | */ | ||
220 | mode = drm_cvt_mode(dev, native_mode->hdisplay, native_mode->vdisplay, 60, true, false, false); | ||
221 | mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER; | ||
222 | DRM_DEBUG("Adding cvt approximation of native panel mode %s\n", mode->name); | ||
211 | } | 223 | } |
212 | return mode; | 224 | return mode; |
213 | } | 225 | } |
@@ -1171,7 +1183,7 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1171 | 1); | 1183 | 1); |
1172 | drm_connector_attach_property(&radeon_connector->base, | 1184 | drm_connector_attach_property(&radeon_connector->base, |
1173 | rdev->mode_info.tv_std_property, | 1185 | rdev->mode_info.tv_std_property, |
1174 | 1); | 1186 | radeon_atombios_get_tv_info(rdev)); |
1175 | } | 1187 | } |
1176 | break; | 1188 | break; |
1177 | case DRM_MODE_CONNECTOR_LVDS: | 1189 | case DRM_MODE_CONNECTOR_LVDS: |
@@ -1315,7 +1327,7 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
1315 | 1); | 1327 | 1); |
1316 | drm_connector_attach_property(&radeon_connector->base, | 1328 | drm_connector_attach_property(&radeon_connector->base, |
1317 | rdev->mode_info.tv_std_property, | 1329 | rdev->mode_info.tv_std_property, |
1318 | 1); | 1330 | radeon_combios_get_tv_info(rdev)); |
1319 | } | 1331 | } |
1320 | break; | 1332 | break; |
1321 | case DRM_MODE_CONNECTOR_LVDS: | 1333 | case DRM_MODE_CONNECTOR_LVDS: |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 02bcdb1240c0..7c6848096bcd 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -391,6 +391,12 @@ int radeon_asic_init(struct radeon_device *rdev) | |||
391 | /* FIXME: not supported yet */ | 391 | /* FIXME: not supported yet */ |
392 | return -EINVAL; | 392 | return -EINVAL; |
393 | } | 393 | } |
394 | |||
395 | if (rdev->flags & RADEON_IS_IGP) { | ||
396 | rdev->asic->get_memory_clock = NULL; | ||
397 | rdev->asic->set_memory_clock = NULL; | ||
398 | } | ||
399 | |||
394 | return 0; | 400 | return 0; |
395 | } | 401 | } |
396 | 402 | ||
@@ -481,6 +487,7 @@ int radeon_atombios_init(struct radeon_device *rdev) | |||
481 | atom_card_info->pll_write = cail_pll_write; | 487 | atom_card_info->pll_write = cail_pll_write; |
482 | 488 | ||
483 | rdev->mode_info.atom_context = atom_parse(atom_card_info, rdev->bios); | 489 | rdev->mode_info.atom_context = atom_parse(atom_card_info, rdev->bios); |
490 | mutex_init(&rdev->mode_info.atom_context->mutex); | ||
484 | radeon_atom_initialize_bios_scratch_regs(rdev->ddev); | 491 | radeon_atom_initialize_bios_scratch_regs(rdev->ddev); |
485 | atom_allocate_fb_scratch(rdev->mode_info.atom_context); | 492 | atom_allocate_fb_scratch(rdev->mode_info.atom_context); |
486 | return 0; | 493 | return 0; |
@@ -539,9 +546,72 @@ void radeon_agp_disable(struct radeon_device *rdev) | |||
539 | } | 546 | } |
540 | } | 547 | } |
541 | 548 | ||
542 | /* | 549 | void radeon_check_arguments(struct radeon_device *rdev) |
543 | * Radeon device. | 550 | { |
544 | */ | 551 | /* vramlimit must be a power of two */ |
552 | switch (radeon_vram_limit) { | ||
553 | case 0: | ||
554 | case 4: | ||
555 | case 8: | ||
556 | case 16: | ||
557 | case 32: | ||
558 | case 64: | ||
559 | case 128: | ||
560 | case 256: | ||
561 | case 512: | ||
562 | case 1024: | ||
563 | case 2048: | ||
564 | case 4096: | ||
565 | break; | ||
566 | default: | ||
567 | dev_warn(rdev->dev, "vram limit (%d) must be a power of 2\n", | ||
568 | radeon_vram_limit); | ||
569 | radeon_vram_limit = 0; | ||
570 | break; | ||
571 | } | ||
572 | radeon_vram_limit = radeon_vram_limit << 20; | ||
573 | /* gtt size must be power of two and greater or equal to 32M */ | ||
574 | switch (radeon_gart_size) { | ||
575 | case 4: | ||
576 | case 8: | ||
577 | case 16: | ||
578 | dev_warn(rdev->dev, "gart size (%d) too small forcing to 512M\n", | ||
579 | radeon_gart_size); | ||
580 | radeon_gart_size = 512; | ||
581 | break; | ||
582 | case 32: | ||
583 | case 64: | ||
584 | case 128: | ||
585 | case 256: | ||
586 | case 512: | ||
587 | case 1024: | ||
588 | case 2048: | ||
589 | case 4096: | ||
590 | break; | ||
591 | default: | ||
592 | dev_warn(rdev->dev, "gart size (%d) must be a power of 2\n", | ||
593 | radeon_gart_size); | ||
594 | radeon_gart_size = 512; | ||
595 | break; | ||
596 | } | ||
597 | rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; | ||
598 | /* AGP mode can only be -1, 1, 2, 4, 8 */ | ||
599 | switch (radeon_agpmode) { | ||
600 | case -1: | ||
601 | case 0: | ||
602 | case 1: | ||
603 | case 2: | ||
604 | case 4: | ||
605 | case 8: | ||
606 | break; | ||
607 | default: | ||
608 | dev_warn(rdev->dev, "invalid AGP mode %d (valid mode: " | ||
609 | "-1, 0, 1, 2, 4, 8)\n", radeon_agpmode); | ||
610 | radeon_agpmode = 0; | ||
611 | break; | ||
612 | } | ||
613 | } | ||
614 | |||
545 | int radeon_device_init(struct radeon_device *rdev, | 615 | int radeon_device_init(struct radeon_device *rdev, |
546 | struct drm_device *ddev, | 616 | struct drm_device *ddev, |
547 | struct pci_dev *pdev, | 617 | struct pci_dev *pdev, |
@@ -580,9 +650,9 @@ int radeon_device_init(struct radeon_device *rdev, | |||
580 | 650 | ||
581 | /* Set asic functions */ | 651 | /* Set asic functions */ |
582 | r = radeon_asic_init(rdev); | 652 | r = radeon_asic_init(rdev); |
583 | if (r) { | 653 | if (r) |
584 | return r; | 654 | return r; |
585 | } | 655 | radeon_check_arguments(rdev); |
586 | 656 | ||
587 | if (rdev->flags & RADEON_IS_AGP && radeon_agpmode == -1) { | 657 | if (rdev->flags & RADEON_IS_AGP && radeon_agpmode == -1) { |
588 | radeon_agp_disable(rdev); | 658 | radeon_agp_disable(rdev); |
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index a133b833e45d..91d72b70abc9 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
@@ -739,7 +739,7 @@ static struct drm_prop_enum_list radeon_tv_std_enum_list[] = | |||
739 | { TV_STD_SECAM, "secam" }, | 739 | { TV_STD_SECAM, "secam" }, |
740 | }; | 740 | }; |
741 | 741 | ||
742 | int radeon_modeset_create_props(struct radeon_device *rdev) | 742 | static int radeon_modeset_create_props(struct radeon_device *rdev) |
743 | { | 743 | { |
744 | int i, sz; | 744 | int i, sz; |
745 | 745 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index dbd56ef82f9c..8ba3de7994d4 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c | |||
@@ -196,7 +196,7 @@ static struct drm_driver driver_old = { | |||
196 | .owner = THIS_MODULE, | 196 | .owner = THIS_MODULE, |
197 | .open = drm_open, | 197 | .open = drm_open, |
198 | .release = drm_release, | 198 | .release = drm_release, |
199 | .ioctl = drm_ioctl, | 199 | .unlocked_ioctl = drm_ioctl, |
200 | .mmap = drm_mmap, | 200 | .mmap = drm_mmap, |
201 | .poll = drm_poll, | 201 | .poll = drm_poll, |
202 | .fasync = drm_fasync, | 202 | .fasync = drm_fasync, |
@@ -284,7 +284,7 @@ static struct drm_driver kms_driver = { | |||
284 | .owner = THIS_MODULE, | 284 | .owner = THIS_MODULE, |
285 | .open = drm_open, | 285 | .open = drm_open, |
286 | .release = drm_release, | 286 | .release = drm_release, |
287 | .ioctl = drm_ioctl, | 287 | .unlocked_ioctl = drm_ioctl, |
288 | .mmap = radeon_mmap, | 288 | .mmap = radeon_mmap, |
289 | .poll = drm_poll, | 289 | .poll = drm_poll, |
290 | .fasync = drm_fasync, | 290 | .fasync = drm_fasync, |
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index 0d1d908e5225..ccba95f83d11 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c | |||
@@ -233,6 +233,8 @@ static bool radeon_atom_mode_fixup(struct drm_encoder *encoder, | |||
233 | if (!ASIC_IS_AVIVO(rdev)) { | 233 | if (!ASIC_IS_AVIVO(rdev)) { |
234 | adjusted_mode->hdisplay = mode->hdisplay; | 234 | adjusted_mode->hdisplay = mode->hdisplay; |
235 | adjusted_mode->vdisplay = mode->vdisplay; | 235 | adjusted_mode->vdisplay = mode->vdisplay; |
236 | adjusted_mode->crtc_hdisplay = mode->hdisplay; | ||
237 | adjusted_mode->crtc_vdisplay = mode->vdisplay; | ||
236 | } | 238 | } |
237 | adjusted_mode->base.id = mode_id; | 239 | adjusted_mode->base.id = mode_id; |
238 | } | 240 | } |
@@ -495,9 +497,9 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) | |||
495 | args.v1.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE; | 497 | args.v1.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE; |
496 | args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | 498 | args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); |
497 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | 499 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { |
498 | if (dig->lvds_misc & (1 << 0)) | 500 | if (dig->lvds_misc & ATOM_PANEL_MISC_DUAL) |
499 | args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL; | 501 | args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL; |
500 | if (dig->lvds_misc & (1 << 1)) | 502 | if (dig->lvds_misc & ATOM_PANEL_MISC_888RGB) |
501 | args.v1.ucMisc |= (1 << 1); | 503 | args.v1.ucMisc |= (1 << 1); |
502 | } else { | 504 | } else { |
503 | if (dig_connector->linkb) | 505 | if (dig_connector->linkb) |
@@ -524,18 +526,18 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) | |||
524 | args.v2.ucTemporal = 0; | 526 | args.v2.ucTemporal = 0; |
525 | args.v2.ucFRC = 0; | 527 | args.v2.ucFRC = 0; |
526 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | 528 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { |
527 | if (dig->lvds_misc & (1 << 0)) | 529 | if (dig->lvds_misc & ATOM_PANEL_MISC_DUAL) |
528 | args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL; | 530 | args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL; |
529 | if (dig->lvds_misc & (1 << 5)) { | 531 | if (dig->lvds_misc & ATOM_PANEL_MISC_SPATIAL) { |
530 | args.v2.ucSpatial = PANEL_ENCODER_SPATIAL_DITHER_EN; | 532 | args.v2.ucSpatial = PANEL_ENCODER_SPATIAL_DITHER_EN; |
531 | if (dig->lvds_misc & (1 << 1)) | 533 | if (dig->lvds_misc & ATOM_PANEL_MISC_888RGB) |
532 | args.v2.ucSpatial |= PANEL_ENCODER_SPATIAL_DITHER_DEPTH; | 534 | args.v2.ucSpatial |= PANEL_ENCODER_SPATIAL_DITHER_DEPTH; |
533 | } | 535 | } |
534 | if (dig->lvds_misc & (1 << 6)) { | 536 | if (dig->lvds_misc & ATOM_PANEL_MISC_TEMPORAL) { |
535 | args.v2.ucTemporal = PANEL_ENCODER_TEMPORAL_DITHER_EN; | 537 | args.v2.ucTemporal = PANEL_ENCODER_TEMPORAL_DITHER_EN; |
536 | if (dig->lvds_misc & (1 << 1)) | 538 | if (dig->lvds_misc & ATOM_PANEL_MISC_888RGB) |
537 | args.v2.ucTemporal |= PANEL_ENCODER_TEMPORAL_DITHER_DEPTH; | 539 | args.v2.ucTemporal |= PANEL_ENCODER_TEMPORAL_DITHER_DEPTH; |
538 | if (((dig->lvds_misc >> 2) & 0x3) == 2) | 540 | if (((dig->lvds_misc >> ATOM_PANEL_MISC_GREY_LEVEL_SHIFT) & 0x3) == 2) |
539 | args.v2.ucTemporal |= PANEL_ENCODER_TEMPORAL_LEVEL_4; | 541 | args.v2.ucTemporal |= PANEL_ENCODER_TEMPORAL_LEVEL_4; |
540 | } | 542 | } |
541 | } else { | 543 | } else { |
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index cb4cd97ae39f..4cdd8b4f7549 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c | |||
@@ -324,7 +324,7 @@ int radeon_fence_driver_init(struct radeon_device *rdev) | |||
324 | write_lock_irqsave(&rdev->fence_drv.lock, irq_flags); | 324 | write_lock_irqsave(&rdev->fence_drv.lock, irq_flags); |
325 | r = radeon_scratch_get(rdev, &rdev->fence_drv.scratch_reg); | 325 | r = radeon_scratch_get(rdev, &rdev->fence_drv.scratch_reg); |
326 | if (r) { | 326 | if (r) { |
327 | DRM_ERROR("Fence failed to get a scratch register."); | 327 | dev_err(rdev->dev, "fence failed to get scratch register\n"); |
328 | write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); | 328 | write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); |
329 | return r; | 329 | return r; |
330 | } | 330 | } |
@@ -335,9 +335,10 @@ int radeon_fence_driver_init(struct radeon_device *rdev) | |||
335 | INIT_LIST_HEAD(&rdev->fence_drv.signaled); | 335 | INIT_LIST_HEAD(&rdev->fence_drv.signaled); |
336 | rdev->fence_drv.count_timeout = 0; | 336 | rdev->fence_drv.count_timeout = 0; |
337 | init_waitqueue_head(&rdev->fence_drv.queue); | 337 | init_waitqueue_head(&rdev->fence_drv.queue); |
338 | rdev->fence_drv.initialized = true; | ||
338 | write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); | 339 | write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); |
339 | if (radeon_debugfs_fence_init(rdev)) { | 340 | if (radeon_debugfs_fence_init(rdev)) { |
340 | DRM_ERROR("Failed to register debugfs file for fence !\n"); | 341 | dev_err(rdev->dev, "fence debugfs file creation failed\n"); |
341 | } | 342 | } |
342 | return 0; | 343 | return 0; |
343 | } | 344 | } |
@@ -346,11 +347,13 @@ void radeon_fence_driver_fini(struct radeon_device *rdev) | |||
346 | { | 347 | { |
347 | unsigned long irq_flags; | 348 | unsigned long irq_flags; |
348 | 349 | ||
350 | if (!rdev->fence_drv.initialized) | ||
351 | return; | ||
349 | wake_up_all(&rdev->fence_drv.queue); | 352 | wake_up_all(&rdev->fence_drv.queue); |
350 | write_lock_irqsave(&rdev->fence_drv.lock, irq_flags); | 353 | write_lock_irqsave(&rdev->fence_drv.lock, irq_flags); |
351 | radeon_scratch_free(rdev, rdev->fence_drv.scratch_reg); | 354 | radeon_scratch_free(rdev, rdev->fence_drv.scratch_reg); |
352 | write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); | 355 | write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); |
353 | DRM_INFO("radeon: fence finalized\n"); | 356 | rdev->fence_drv.initialized = false; |
354 | } | 357 | } |
355 | 358 | ||
356 | 359 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_ioc32.c b/drivers/gpu/drm/radeon/radeon_ioc32.c index a1bf11de308a..48b7cea31e08 100644 --- a/drivers/gpu/drm/radeon/radeon_ioc32.c +++ b/drivers/gpu/drm/radeon/radeon_ioc32.c | |||
@@ -92,8 +92,7 @@ static int compat_radeon_cp_init(struct file *file, unsigned int cmd, | |||
92 | &init->gart_textures_offset)) | 92 | &init->gart_textures_offset)) |
93 | return -EFAULT; | 93 | return -EFAULT; |
94 | 94 | ||
95 | return drm_ioctl(file->f_path.dentry->d_inode, file, | 95 | return drm_ioctl(file, DRM_IOCTL_RADEON_CP_INIT, (unsigned long)init); |
96 | DRM_IOCTL_RADEON_CP_INIT, (unsigned long)init); | ||
97 | } | 96 | } |
98 | 97 | ||
99 | typedef struct drm_radeon_clear32 { | 98 | typedef struct drm_radeon_clear32 { |
@@ -125,8 +124,7 @@ static int compat_radeon_cp_clear(struct file *file, unsigned int cmd, | |||
125 | &clr->depth_boxes)) | 124 | &clr->depth_boxes)) |
126 | return -EFAULT; | 125 | return -EFAULT; |
127 | 126 | ||
128 | return drm_ioctl(file->f_path.dentry->d_inode, file, | 127 | return drm_ioctl(file, DRM_IOCTL_RADEON_CLEAR, (unsigned long)clr); |
129 | DRM_IOCTL_RADEON_CLEAR, (unsigned long)clr); | ||
130 | } | 128 | } |
131 | 129 | ||
132 | typedef struct drm_radeon_stipple32 { | 130 | typedef struct drm_radeon_stipple32 { |
@@ -149,8 +147,7 @@ static int compat_radeon_cp_stipple(struct file *file, unsigned int cmd, | |||
149 | &request->mask)) | 147 | &request->mask)) |
150 | return -EFAULT; | 148 | return -EFAULT; |
151 | 149 | ||
152 | return drm_ioctl(file->f_path.dentry->d_inode, file, | 150 | return drm_ioctl(file, DRM_IOCTL_RADEON_STIPPLE, (unsigned long)request); |
153 | DRM_IOCTL_RADEON_STIPPLE, (unsigned long)request); | ||
154 | } | 151 | } |
155 | 152 | ||
156 | typedef struct drm_radeon_tex_image32 { | 153 | typedef struct drm_radeon_tex_image32 { |
@@ -204,8 +201,7 @@ static int compat_radeon_cp_texture(struct file *file, unsigned int cmd, | |||
204 | &image->data)) | 201 | &image->data)) |
205 | return -EFAULT; | 202 | return -EFAULT; |
206 | 203 | ||
207 | return drm_ioctl(file->f_path.dentry->d_inode, file, | 204 | return drm_ioctl(file, DRM_IOCTL_RADEON_TEXTURE, (unsigned long)request); |
208 | DRM_IOCTL_RADEON_TEXTURE, (unsigned long)request); | ||
209 | } | 205 | } |
210 | 206 | ||
211 | typedef struct drm_radeon_vertex2_32 { | 207 | typedef struct drm_radeon_vertex2_32 { |
@@ -238,8 +234,7 @@ static int compat_radeon_cp_vertex2(struct file *file, unsigned int cmd, | |||
238 | &request->prim)) | 234 | &request->prim)) |
239 | return -EFAULT; | 235 | return -EFAULT; |
240 | 236 | ||
241 | return drm_ioctl(file->f_path.dentry->d_inode, file, | 237 | return drm_ioctl(file, DRM_IOCTL_RADEON_VERTEX2, (unsigned long)request); |
242 | DRM_IOCTL_RADEON_VERTEX2, (unsigned long)request); | ||
243 | } | 238 | } |
244 | 239 | ||
245 | typedef struct drm_radeon_cmd_buffer32 { | 240 | typedef struct drm_radeon_cmd_buffer32 { |
@@ -268,8 +263,7 @@ static int compat_radeon_cp_cmdbuf(struct file *file, unsigned int cmd, | |||
268 | &request->boxes)) | 263 | &request->boxes)) |
269 | return -EFAULT; | 264 | return -EFAULT; |
270 | 265 | ||
271 | return drm_ioctl(file->f_path.dentry->d_inode, file, | 266 | return drm_ioctl(file, DRM_IOCTL_RADEON_CMDBUF, (unsigned long)request); |
272 | DRM_IOCTL_RADEON_CMDBUF, (unsigned long)request); | ||
273 | } | 267 | } |
274 | 268 | ||
275 | typedef struct drm_radeon_getparam32 { | 269 | typedef struct drm_radeon_getparam32 { |
@@ -293,8 +287,7 @@ static int compat_radeon_cp_getparam(struct file *file, unsigned int cmd, | |||
293 | &request->value)) | 287 | &request->value)) |
294 | return -EFAULT; | 288 | return -EFAULT; |
295 | 289 | ||
296 | return drm_ioctl(file->f_path.dentry->d_inode, file, | 290 | return drm_ioctl(file, DRM_IOCTL_RADEON_GETPARAM, (unsigned long)request); |
297 | DRM_IOCTL_RADEON_GETPARAM, (unsigned long)request); | ||
298 | } | 291 | } |
299 | 292 | ||
300 | typedef struct drm_radeon_mem_alloc32 { | 293 | typedef struct drm_radeon_mem_alloc32 { |
@@ -322,8 +315,7 @@ static int compat_radeon_mem_alloc(struct file *file, unsigned int cmd, | |||
322 | &request->region_offset)) | 315 | &request->region_offset)) |
323 | return -EFAULT; | 316 | return -EFAULT; |
324 | 317 | ||
325 | return drm_ioctl(file->f_path.dentry->d_inode, file, | 318 | return drm_ioctl(file, DRM_IOCTL_RADEON_ALLOC, (unsigned long)request); |
326 | DRM_IOCTL_RADEON_ALLOC, (unsigned long)request); | ||
327 | } | 319 | } |
328 | 320 | ||
329 | typedef struct drm_radeon_irq_emit32 { | 321 | typedef struct drm_radeon_irq_emit32 { |
@@ -345,8 +337,7 @@ static int compat_radeon_irq_emit(struct file *file, unsigned int cmd, | |||
345 | &request->irq_seq)) | 337 | &request->irq_seq)) |
346 | return -EFAULT; | 338 | return -EFAULT; |
347 | 339 | ||
348 | return drm_ioctl(file->f_path.dentry->d_inode, file, | 340 | return drm_ioctl(file, DRM_IOCTL_RADEON_IRQ_EMIT, (unsigned long)request); |
349 | DRM_IOCTL_RADEON_IRQ_EMIT, (unsigned long)request); | ||
350 | } | 341 | } |
351 | 342 | ||
352 | /* The two 64-bit arches where alignof(u64)==4 in 32-bit code */ | 343 | /* The two 64-bit arches where alignof(u64)==4 in 32-bit code */ |
@@ -372,8 +363,7 @@ static int compat_radeon_cp_setparam(struct file *file, unsigned int cmd, | |||
372 | &request->value)) | 363 | &request->value)) |
373 | return -EFAULT; | 364 | return -EFAULT; |
374 | 365 | ||
375 | return drm_ioctl(file->f_dentry->d_inode, file, | 366 | return drm_ioctl(file, DRM_IOCTL_RADEON_SETPARAM, (unsigned long) request); |
376 | DRM_IOCTL_RADEON_SETPARAM, (unsigned long) request); | ||
377 | } | 367 | } |
378 | #else | 368 | #else |
379 | #define compat_radeon_cp_setparam NULL | 369 | #define compat_radeon_cp_setparam NULL |
@@ -413,12 +403,10 @@ long radeon_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
413 | if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(radeon_compat_ioctls)) | 403 | if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(radeon_compat_ioctls)) |
414 | fn = radeon_compat_ioctls[nr - DRM_COMMAND_BASE]; | 404 | fn = radeon_compat_ioctls[nr - DRM_COMMAND_BASE]; |
415 | 405 | ||
416 | lock_kernel(); /* XXX for now */ | ||
417 | if (fn != NULL) | 406 | if (fn != NULL) |
418 | ret = (*fn) (filp, cmd, arg); | 407 | ret = (*fn) (filp, cmd, arg); |
419 | else | 408 | else |
420 | ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg); | 409 | ret = drm_ioctl(filp, cmd, arg); |
421 | unlock_kernel(); | ||
422 | 410 | ||
423 | return ret; | 411 | return ret; |
424 | } | 412 | } |
@@ -431,9 +419,7 @@ long radeon_kms_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long | |||
431 | if (nr < DRM_COMMAND_BASE) | 419 | if (nr < DRM_COMMAND_BASE) |
432 | return drm_compat_ioctl(filp, cmd, arg); | 420 | return drm_compat_ioctl(filp, cmd, arg); |
433 | 421 | ||
434 | lock_kernel(); /* XXX for now */ | 422 | ret = drm_ioctl(filp, cmd, arg); |
435 | ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg); | ||
436 | unlock_kernel(); | ||
437 | 423 | ||
438 | return ret; | 424 | return ret; |
439 | } | 425 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index b82ede98e152..cc27485a07ad 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c | |||
@@ -43,8 +43,7 @@ static void radeon_overscan_setup(struct drm_crtc *crtc, | |||
43 | } | 43 | } |
44 | 44 | ||
45 | static void radeon_legacy_rmx_mode_set(struct drm_crtc *crtc, | 45 | static void radeon_legacy_rmx_mode_set(struct drm_crtc *crtc, |
46 | struct drm_display_mode *mode, | 46 | struct drm_display_mode *mode) |
47 | struct drm_display_mode *adjusted_mode) | ||
48 | { | 47 | { |
49 | struct drm_device *dev = crtc->dev; | 48 | struct drm_device *dev = crtc->dev; |
50 | struct radeon_device *rdev = dev->dev_private; | 49 | struct radeon_device *rdev = dev->dev_private; |
@@ -1059,7 +1058,7 @@ static int radeon_crtc_mode_set(struct drm_crtc *crtc, | |||
1059 | radeon_set_pll(crtc, adjusted_mode); | 1058 | radeon_set_pll(crtc, adjusted_mode); |
1060 | radeon_overscan_setup(crtc, adjusted_mode); | 1059 | radeon_overscan_setup(crtc, adjusted_mode); |
1061 | if (radeon_crtc->crtc_id == 0) { | 1060 | if (radeon_crtc->crtc_id == 0) { |
1062 | radeon_legacy_rmx_mode_set(crtc, mode, adjusted_mode); | 1061 | radeon_legacy_rmx_mode_set(crtc, adjusted_mode); |
1063 | } else { | 1062 | } else { |
1064 | if (radeon_crtc->rmx_type != RMX_OFF) { | 1063 | if (radeon_crtc->rmx_type != RMX_OFF) { |
1065 | /* FIXME: only first crtc has rmx what should we | 1064 | /* FIXME: only first crtc has rmx what should we |
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c index df00515e81fa..981508ff7037 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c | |||
@@ -207,6 +207,8 @@ static bool radeon_legacy_mode_fixup(struct drm_encoder *encoder, | |||
207 | *adjusted_mode = *native_mode; | 207 | *adjusted_mode = *native_mode; |
208 | adjusted_mode->hdisplay = mode->hdisplay; | 208 | adjusted_mode->hdisplay = mode->hdisplay; |
209 | adjusted_mode->vdisplay = mode->vdisplay; | 209 | adjusted_mode->vdisplay = mode->vdisplay; |
210 | adjusted_mode->crtc_hdisplay = mode->hdisplay; | ||
211 | adjusted_mode->crtc_vdisplay = mode->vdisplay; | ||
210 | adjusted_mode->base.id = mode_id; | 212 | adjusted_mode->base.id = mode_id; |
211 | } | 213 | } |
212 | 214 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 3dcbe130c422..402369db5ba0 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
@@ -88,6 +88,7 @@ enum radeon_tv_std { | |||
88 | TV_STD_SCART_PAL, | 88 | TV_STD_SCART_PAL, |
89 | TV_STD_SECAM, | 89 | TV_STD_SECAM, |
90 | TV_STD_PAL_CN, | 90 | TV_STD_PAL_CN, |
91 | TV_STD_PAL_N, | ||
91 | }; | 92 | }; |
92 | 93 | ||
93 | /* radeon gpio-based i2c | 94 | /* radeon gpio-based i2c |
@@ -395,6 +396,11 @@ struct radeon_framebuffer { | |||
395 | struct drm_gem_object *obj; | 396 | struct drm_gem_object *obj; |
396 | }; | 397 | }; |
397 | 398 | ||
399 | extern enum radeon_tv_std | ||
400 | radeon_combios_get_tv_info(struct radeon_device *rdev); | ||
401 | extern enum radeon_tv_std | ||
402 | radeon_atombios_get_tv_info(struct radeon_device *rdev); | ||
403 | |||
398 | extern void radeon_connector_hotplug(struct drm_connector *connector); | 404 | extern void radeon_connector_hotplug(struct drm_connector *connector); |
399 | extern bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector); | 405 | extern bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector); |
400 | extern int radeon_dp_mode_valid_helper(struct radeon_connector *radeon_connector, | 406 | extern int radeon_dp_mode_valid_helper(struct radeon_connector *radeon_connector, |
diff --git a/drivers/gpu/drm/radeon/radeon_test.c b/drivers/gpu/drm/radeon/radeon_test.c index 391c973ec4db..9f5e2f929da9 100644 --- a/drivers/gpu/drm/radeon/radeon_test.c +++ b/drivers/gpu/drm/radeon/radeon_test.c | |||
@@ -42,8 +42,8 @@ void radeon_test_moves(struct radeon_device *rdev) | |||
42 | /* Number of tests = | 42 | /* Number of tests = |
43 | * (Total GTT - IB pool - writeback page - ring buffer) / test size | 43 | * (Total GTT - IB pool - writeback page - ring buffer) / test size |
44 | */ | 44 | */ |
45 | n = (rdev->mc.gtt_size - RADEON_IB_POOL_SIZE*64*1024 - RADEON_GPU_PAGE_SIZE - | 45 | n = ((u32)(rdev->mc.gtt_size - RADEON_IB_POOL_SIZE*64*1024 - RADEON_GPU_PAGE_SIZE - |
46 | rdev->cp.ring_size) / size; | 46 | rdev->cp.ring_size)) / size; |
47 | 47 | ||
48 | gtt_obj = kzalloc(n * sizeof(*gtt_obj), GFP_KERNEL); | 48 | gtt_obj = kzalloc(n * sizeof(*gtt_obj), GFP_KERNEL); |
49 | if (!gtt_obj) { | 49 | if (!gtt_obj) { |
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index d7fd160cc671..3b0c07b444a2 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c | |||
@@ -494,6 +494,7 @@ int radeon_ttm_init(struct radeon_device *rdev) | |||
494 | DRM_ERROR("failed initializing buffer object driver(%d).\n", r); | 494 | DRM_ERROR("failed initializing buffer object driver(%d).\n", r); |
495 | return r; | 495 | return r; |
496 | } | 496 | } |
497 | rdev->mman.initialized = true; | ||
497 | r = ttm_bo_init_mm(&rdev->mman.bdev, TTM_PL_VRAM, | 498 | r = ttm_bo_init_mm(&rdev->mman.bdev, TTM_PL_VRAM, |
498 | rdev->mc.real_vram_size >> PAGE_SHIFT); | 499 | rdev->mc.real_vram_size >> PAGE_SHIFT); |
499 | if (r) { | 500 | if (r) { |
@@ -541,6 +542,8 @@ void radeon_ttm_fini(struct radeon_device *rdev) | |||
541 | { | 542 | { |
542 | int r; | 543 | int r; |
543 | 544 | ||
545 | if (!rdev->mman.initialized) | ||
546 | return; | ||
544 | if (rdev->stollen_vga_memory) { | 547 | if (rdev->stollen_vga_memory) { |
545 | r = radeon_bo_reserve(rdev->stollen_vga_memory, false); | 548 | r = radeon_bo_reserve(rdev->stollen_vga_memory, false); |
546 | if (r == 0) { | 549 | if (r == 0) { |
@@ -554,6 +557,7 @@ void radeon_ttm_fini(struct radeon_device *rdev) | |||
554 | ttm_bo_device_release(&rdev->mman.bdev); | 557 | ttm_bo_device_release(&rdev->mman.bdev); |
555 | radeon_gart_fini(rdev); | 558 | radeon_gart_fini(rdev); |
556 | radeon_ttm_global_fini(rdev); | 559 | radeon_ttm_global_fini(rdev); |
560 | rdev->mman.initialized = false; | ||
557 | DRM_INFO("radeon: ttm finalized\n"); | 561 | DRM_INFO("radeon: ttm finalized\n"); |
558 | } | 562 | } |
559 | 563 | ||
diff --git a/drivers/gpu/drm/savage/savage_drv.c b/drivers/gpu/drm/savage/savage_drv.c index eee52aa92a7c..021de44c15ab 100644 --- a/drivers/gpu/drm/savage/savage_drv.c +++ b/drivers/gpu/drm/savage/savage_drv.c | |||
@@ -50,7 +50,7 @@ static struct drm_driver driver = { | |||
50 | .owner = THIS_MODULE, | 50 | .owner = THIS_MODULE, |
51 | .open = drm_open, | 51 | .open = drm_open, |
52 | .release = drm_release, | 52 | .release = drm_release, |
53 | .ioctl = drm_ioctl, | 53 | .unlocked_ioctl = drm_ioctl, |
54 | .mmap = drm_mmap, | 54 | .mmap = drm_mmap, |
55 | .poll = drm_poll, | 55 | .poll = drm_poll, |
56 | .fasync = drm_fasync, | 56 | .fasync = drm_fasync, |
diff --git a/drivers/gpu/drm/sis/sis_drv.c b/drivers/gpu/drm/sis/sis_drv.c index e725cc0b1155..4fd1f067d380 100644 --- a/drivers/gpu/drm/sis/sis_drv.c +++ b/drivers/gpu/drm/sis/sis_drv.c | |||
@@ -80,7 +80,7 @@ static struct drm_driver driver = { | |||
80 | .owner = THIS_MODULE, | 80 | .owner = THIS_MODULE, |
81 | .open = drm_open, | 81 | .open = drm_open, |
82 | .release = drm_release, | 82 | .release = drm_release, |
83 | .ioctl = drm_ioctl, | 83 | .unlocked_ioctl = drm_ioctl, |
84 | .mmap = drm_mmap, | 84 | .mmap = drm_mmap, |
85 | .poll = drm_poll, | 85 | .poll = drm_poll, |
86 | .fasync = drm_fasync, | 86 | .fasync = drm_fasync, |
diff --git a/drivers/gpu/drm/tdfx/tdfx_drv.c b/drivers/gpu/drm/tdfx/tdfx_drv.c index 012ff2e356b2..ec5a43e65722 100644 --- a/drivers/gpu/drm/tdfx/tdfx_drv.c +++ b/drivers/gpu/drm/tdfx/tdfx_drv.c | |||
@@ -48,7 +48,7 @@ static struct drm_driver driver = { | |||
48 | .owner = THIS_MODULE, | 48 | .owner = THIS_MODULE, |
49 | .open = drm_open, | 49 | .open = drm_open, |
50 | .release = drm_release, | 50 | .release = drm_release, |
51 | .ioctl = drm_ioctl, | 51 | .unlocked_ioctl = drm_ioctl, |
52 | .mmap = drm_mmap, | 52 | .mmap = drm_mmap, |
53 | .poll = drm_poll, | 53 | .poll = drm_poll, |
54 | .fasync = drm_fasync, | 54 | .fasync = drm_fasync, |
diff --git a/drivers/gpu/drm/via/via_drv.c b/drivers/gpu/drm/via/via_drv.c index bc2f51843005..7a1b210401e0 100644 --- a/drivers/gpu/drm/via/via_drv.c +++ b/drivers/gpu/drm/via/via_drv.c | |||
@@ -58,7 +58,7 @@ static struct drm_driver driver = { | |||
58 | .owner = THIS_MODULE, | 58 | .owner = THIS_MODULE, |
59 | .open = drm_open, | 59 | .open = drm_open, |
60 | .release = drm_release, | 60 | .release = drm_release, |
61 | .ioctl = drm_ioctl, | 61 | .unlocked_ioctl = drm_ioctl, |
62 | .mmap = drm_mmap, | 62 | .mmap = drm_mmap, |
63 | .poll = drm_poll, | 63 | .poll = drm_poll, |
64 | .fasync = drm_fasync, | 64 | .fasync = drm_fasync, |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 7b48bb3b63b2..1db1ef30be2b 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | |||
@@ -103,37 +103,39 @@ | |||
103 | */ | 103 | */ |
104 | 104 | ||
105 | static struct drm_ioctl_desc vmw_ioctls[] = { | 105 | static struct drm_ioctl_desc vmw_ioctls[] = { |
106 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_GET_PARAM, vmw_getparam_ioctl, 0), | 106 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_GET_PARAM, vmw_getparam_ioctl, |
107 | DRM_AUTH | DRM_UNLOCKED), | ||
107 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_ALLOC_DMABUF, vmw_dmabuf_alloc_ioctl, | 108 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_ALLOC_DMABUF, vmw_dmabuf_alloc_ioctl, |
108 | 0), | 109 | DRM_AUTH | DRM_UNLOCKED), |
109 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_UNREF_DMABUF, vmw_dmabuf_unref_ioctl, | 110 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_UNREF_DMABUF, vmw_dmabuf_unref_ioctl, |
110 | 0), | 111 | DRM_AUTH | DRM_UNLOCKED), |
111 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_CURSOR_BYPASS, | 112 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_CURSOR_BYPASS, |
112 | vmw_kms_cursor_bypass_ioctl, 0), | 113 | vmw_kms_cursor_bypass_ioctl, |
114 | DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED), | ||
113 | 115 | ||
114 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_CONTROL_STREAM, vmw_overlay_ioctl, | 116 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_CONTROL_STREAM, vmw_overlay_ioctl, |
115 | 0), | 117 | DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED), |
116 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_CLAIM_STREAM, vmw_stream_claim_ioctl, | 118 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_CLAIM_STREAM, vmw_stream_claim_ioctl, |
117 | 0), | 119 | DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED), |
118 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_UNREF_STREAM, vmw_stream_unref_ioctl, | 120 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_UNREF_STREAM, vmw_stream_unref_ioctl, |
119 | 0), | 121 | DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED), |
120 | 122 | ||
121 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_CREATE_CONTEXT, vmw_context_define_ioctl, | 123 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_CREATE_CONTEXT, vmw_context_define_ioctl, |
122 | 0), | 124 | DRM_AUTH | DRM_UNLOCKED), |
123 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_UNREF_CONTEXT, vmw_context_destroy_ioctl, | 125 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_UNREF_CONTEXT, vmw_context_destroy_ioctl, |
124 | 0), | 126 | DRM_AUTH | DRM_UNLOCKED), |
125 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_CREATE_SURFACE, vmw_surface_define_ioctl, | 127 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_CREATE_SURFACE, vmw_surface_define_ioctl, |
126 | 0), | 128 | DRM_AUTH | DRM_UNLOCKED), |
127 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_UNREF_SURFACE, vmw_surface_destroy_ioctl, | 129 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_UNREF_SURFACE, vmw_surface_destroy_ioctl, |
128 | 0), | 130 | DRM_AUTH | DRM_UNLOCKED), |
129 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_REF_SURFACE, vmw_surface_reference_ioctl, | 131 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_REF_SURFACE, vmw_surface_reference_ioctl, |
130 | 0), | 132 | DRM_AUTH | DRM_UNLOCKED), |
131 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_EXECBUF, vmw_execbuf_ioctl, | 133 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_EXECBUF, vmw_execbuf_ioctl, |
132 | 0), | 134 | DRM_AUTH | DRM_UNLOCKED), |
133 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_FIFO_DEBUG, vmw_fifo_debug_ioctl, | 135 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_FIFO_DEBUG, vmw_fifo_debug_ioctl, |
134 | 0), | 136 | DRM_AUTH | DRM_ROOT_ONLY | DRM_MASTER | DRM_UNLOCKED), |
135 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_FENCE_WAIT, vmw_fence_wait_ioctl, | 137 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_FENCE_WAIT, vmw_fence_wait_ioctl, |
136 | 0) | 138 | DRM_AUTH | DRM_UNLOCKED) |
137 | }; | 139 | }; |
138 | 140 | ||
139 | static struct pci_device_id vmw_pci_id_list[] = { | 141 | static struct pci_device_id vmw_pci_id_list[] = { |
@@ -460,11 +462,9 @@ static long vmw_unlocked_ioctl(struct file *filp, unsigned int cmd, | |||
460 | struct drm_file *file_priv = filp->private_data; | 462 | struct drm_file *file_priv = filp->private_data; |
461 | struct drm_device *dev = file_priv->minor->dev; | 463 | struct drm_device *dev = file_priv->minor->dev; |
462 | unsigned int nr = DRM_IOCTL_NR(cmd); | 464 | unsigned int nr = DRM_IOCTL_NR(cmd); |
463 | long ret; | ||
464 | 465 | ||
465 | /* | 466 | /* |
466 | * The driver private ioctls and TTM ioctls should be | 467 | * Do extra checking on driver private ioctls. |
467 | * thread-safe. | ||
468 | */ | 468 | */ |
469 | 469 | ||
470 | if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END) | 470 | if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END) |
@@ -477,18 +477,9 @@ static long vmw_unlocked_ioctl(struct file *filp, unsigned int cmd, | |||
477 | nr - DRM_COMMAND_BASE); | 477 | nr - DRM_COMMAND_BASE); |
478 | return -EINVAL; | 478 | return -EINVAL; |
479 | } | 479 | } |
480 | return drm_ioctl(filp->f_path.dentry->d_inode, | ||
481 | filp, cmd, arg); | ||
482 | } | 480 | } |
483 | 481 | ||
484 | /* | 482 | return drm_ioctl(filp, cmd, arg); |
485 | * Not all old drm ioctls are thread-safe. | ||
486 | */ | ||
487 | |||
488 | lock_kernel(); | ||
489 | ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg); | ||
490 | unlock_kernel(); | ||
491 | return ret; | ||
492 | } | 483 | } |
493 | 484 | ||
494 | static int vmw_firstopen(struct drm_device *dev) | 485 | static int vmw_firstopen(struct drm_device *dev) |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index 43546d09d1b0..e61bd85b6975 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | |||
@@ -123,6 +123,7 @@ struct vmw_sw_context{ | |||
123 | uint32_t last_cid; | 123 | uint32_t last_cid; |
124 | bool cid_valid; | 124 | bool cid_valid; |
125 | uint32_t last_sid; | 125 | uint32_t last_sid; |
126 | uint32_t sid_translation; | ||
126 | bool sid_valid; | 127 | bool sid_valid; |
127 | struct ttm_object_file *tfile; | 128 | struct ttm_object_file *tfile; |
128 | struct list_head validate_nodes; | 129 | struct list_head validate_nodes; |
@@ -317,9 +318,10 @@ extern void vmw_surface_res_free(struct vmw_resource *res); | |||
317 | extern int vmw_surface_init(struct vmw_private *dev_priv, | 318 | extern int vmw_surface_init(struct vmw_private *dev_priv, |
318 | struct vmw_surface *srf, | 319 | struct vmw_surface *srf, |
319 | void (*res_free) (struct vmw_resource *res)); | 320 | void (*res_free) (struct vmw_resource *res)); |
320 | extern int vmw_user_surface_lookup(struct vmw_private *dev_priv, | 321 | extern int vmw_user_surface_lookup_handle(struct vmw_private *dev_priv, |
321 | struct ttm_object_file *tfile, | 322 | struct ttm_object_file *tfile, |
322 | int sid, struct vmw_surface **out); | 323 | uint32_t handle, |
324 | struct vmw_surface **out); | ||
323 | extern int vmw_surface_destroy_ioctl(struct drm_device *dev, void *data, | 325 | extern int vmw_surface_destroy_ioctl(struct drm_device *dev, void *data, |
324 | struct drm_file *file_priv); | 326 | struct drm_file *file_priv); |
325 | extern int vmw_surface_define_ioctl(struct drm_device *dev, void *data, | 327 | extern int vmw_surface_define_ioctl(struct drm_device *dev, void *data, |
@@ -328,7 +330,7 @@ extern int vmw_surface_reference_ioctl(struct drm_device *dev, void *data, | |||
328 | struct drm_file *file_priv); | 330 | struct drm_file *file_priv); |
329 | extern int vmw_surface_check(struct vmw_private *dev_priv, | 331 | extern int vmw_surface_check(struct vmw_private *dev_priv, |
330 | struct ttm_object_file *tfile, | 332 | struct ttm_object_file *tfile, |
331 | int id); | 333 | uint32_t handle, int *id); |
332 | extern void vmw_dmabuf_bo_free(struct ttm_buffer_object *bo); | 334 | extern void vmw_dmabuf_bo_free(struct ttm_buffer_object *bo); |
333 | extern int vmw_dmabuf_init(struct vmw_private *dev_priv, | 335 | extern int vmw_dmabuf_init(struct vmw_private *dev_priv, |
334 | struct vmw_dma_buffer *vmw_bo, | 336 | struct vmw_dma_buffer *vmw_bo, |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 7a39f3e6dc2c..2e92da567403 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | |||
@@ -73,21 +73,32 @@ static int vmw_cmd_cid_check(struct vmw_private *dev_priv, | |||
73 | 73 | ||
74 | static int vmw_cmd_sid_check(struct vmw_private *dev_priv, | 74 | static int vmw_cmd_sid_check(struct vmw_private *dev_priv, |
75 | struct vmw_sw_context *sw_context, | 75 | struct vmw_sw_context *sw_context, |
76 | uint32_t sid) | 76 | uint32_t *sid) |
77 | { | 77 | { |
78 | if (unlikely((!sw_context->sid_valid || sid != sw_context->last_sid) && | 78 | if (*sid == SVGA3D_INVALID_ID) |
79 | sid != SVGA3D_INVALID_ID)) { | 79 | return 0; |
80 | int ret = vmw_surface_check(dev_priv, sw_context->tfile, sid); | 80 | |
81 | if (unlikely((!sw_context->sid_valid || | ||
82 | *sid != sw_context->last_sid))) { | ||
83 | int real_id; | ||
84 | int ret = vmw_surface_check(dev_priv, sw_context->tfile, | ||
85 | *sid, &real_id); | ||
81 | 86 | ||
82 | if (unlikely(ret != 0)) { | 87 | if (unlikely(ret != 0)) { |
83 | DRM_ERROR("Could ot find or use surface %u\n", | 88 | DRM_ERROR("Could ot find or use surface 0x%08x " |
84 | (unsigned) sid); | 89 | "address 0x%08lx\n", |
90 | (unsigned int) *sid, | ||
91 | (unsigned long) sid); | ||
85 | return ret; | 92 | return ret; |
86 | } | 93 | } |
87 | 94 | ||
88 | sw_context->last_sid = sid; | 95 | sw_context->last_sid = *sid; |
89 | sw_context->sid_valid = true; | 96 | sw_context->sid_valid = true; |
90 | } | 97 | *sid = real_id; |
98 | sw_context->sid_translation = real_id; | ||
99 | } else | ||
100 | *sid = sw_context->sid_translation; | ||
101 | |||
91 | return 0; | 102 | return 0; |
92 | } | 103 | } |
93 | 104 | ||
@@ -107,7 +118,8 @@ static int vmw_cmd_set_render_target_check(struct vmw_private *dev_priv, | |||
107 | return ret; | 118 | return ret; |
108 | 119 | ||
109 | cmd = container_of(header, struct vmw_sid_cmd, header); | 120 | cmd = container_of(header, struct vmw_sid_cmd, header); |
110 | return vmw_cmd_sid_check(dev_priv, sw_context, cmd->body.target.sid); | 121 | ret = vmw_cmd_sid_check(dev_priv, sw_context, &cmd->body.target.sid); |
122 | return ret; | ||
111 | } | 123 | } |
112 | 124 | ||
113 | static int vmw_cmd_surface_copy_check(struct vmw_private *dev_priv, | 125 | static int vmw_cmd_surface_copy_check(struct vmw_private *dev_priv, |
@@ -121,10 +133,10 @@ static int vmw_cmd_surface_copy_check(struct vmw_private *dev_priv, | |||
121 | int ret; | 133 | int ret; |
122 | 134 | ||
123 | cmd = container_of(header, struct vmw_sid_cmd, header); | 135 | cmd = container_of(header, struct vmw_sid_cmd, header); |
124 | ret = vmw_cmd_sid_check(dev_priv, sw_context, cmd->body.src.sid); | 136 | ret = vmw_cmd_sid_check(dev_priv, sw_context, &cmd->body.src.sid); |
125 | if (unlikely(ret != 0)) | 137 | if (unlikely(ret != 0)) |
126 | return ret; | 138 | return ret; |
127 | return vmw_cmd_sid_check(dev_priv, sw_context, cmd->body.dest.sid); | 139 | return vmw_cmd_sid_check(dev_priv, sw_context, &cmd->body.dest.sid); |
128 | } | 140 | } |
129 | 141 | ||
130 | static int vmw_cmd_stretch_blt_check(struct vmw_private *dev_priv, | 142 | static int vmw_cmd_stretch_blt_check(struct vmw_private *dev_priv, |
@@ -138,10 +150,10 @@ static int vmw_cmd_stretch_blt_check(struct vmw_private *dev_priv, | |||
138 | int ret; | 150 | int ret; |
139 | 151 | ||
140 | cmd = container_of(header, struct vmw_sid_cmd, header); | 152 | cmd = container_of(header, struct vmw_sid_cmd, header); |
141 | ret = vmw_cmd_sid_check(dev_priv, sw_context, cmd->body.src.sid); | 153 | ret = vmw_cmd_sid_check(dev_priv, sw_context, &cmd->body.src.sid); |
142 | if (unlikely(ret != 0)) | 154 | if (unlikely(ret != 0)) |
143 | return ret; | 155 | return ret; |
144 | return vmw_cmd_sid_check(dev_priv, sw_context, cmd->body.dest.sid); | 156 | return vmw_cmd_sid_check(dev_priv, sw_context, &cmd->body.dest.sid); |
145 | } | 157 | } |
146 | 158 | ||
147 | static int vmw_cmd_blt_surf_screen_check(struct vmw_private *dev_priv, | 159 | static int vmw_cmd_blt_surf_screen_check(struct vmw_private *dev_priv, |
@@ -154,7 +166,7 @@ static int vmw_cmd_blt_surf_screen_check(struct vmw_private *dev_priv, | |||
154 | } *cmd; | 166 | } *cmd; |
155 | 167 | ||
156 | cmd = container_of(header, struct vmw_sid_cmd, header); | 168 | cmd = container_of(header, struct vmw_sid_cmd, header); |
157 | return vmw_cmd_sid_check(dev_priv, sw_context, cmd->body.srcImage.sid); | 169 | return vmw_cmd_sid_check(dev_priv, sw_context, &cmd->body.srcImage.sid); |
158 | } | 170 | } |
159 | 171 | ||
160 | static int vmw_cmd_present_check(struct vmw_private *dev_priv, | 172 | static int vmw_cmd_present_check(struct vmw_private *dev_priv, |
@@ -167,7 +179,7 @@ static int vmw_cmd_present_check(struct vmw_private *dev_priv, | |||
167 | } *cmd; | 179 | } *cmd; |
168 | 180 | ||
169 | cmd = container_of(header, struct vmw_sid_cmd, header); | 181 | cmd = container_of(header, struct vmw_sid_cmd, header); |
170 | return vmw_cmd_sid_check(dev_priv, sw_context, cmd->body.sid); | 182 | return vmw_cmd_sid_check(dev_priv, sw_context, &cmd->body.sid); |
171 | } | 183 | } |
172 | 184 | ||
173 | static int vmw_cmd_dma(struct vmw_private *dev_priv, | 185 | static int vmw_cmd_dma(struct vmw_private *dev_priv, |
@@ -187,12 +199,7 @@ static int vmw_cmd_dma(struct vmw_private *dev_priv, | |||
187 | uint32_t cur_validate_node; | 199 | uint32_t cur_validate_node; |
188 | struct ttm_validate_buffer *val_buf; | 200 | struct ttm_validate_buffer *val_buf; |
189 | 201 | ||
190 | |||
191 | cmd = container_of(header, struct vmw_dma_cmd, header); | 202 | cmd = container_of(header, struct vmw_dma_cmd, header); |
192 | ret = vmw_cmd_sid_check(dev_priv, sw_context, cmd->dma.host.sid); | ||
193 | if (unlikely(ret != 0)) | ||
194 | return ret; | ||
195 | |||
196 | handle = cmd->dma.guest.ptr.gmrId; | 203 | handle = cmd->dma.guest.ptr.gmrId; |
197 | ret = vmw_user_dmabuf_lookup(sw_context->tfile, handle, &vmw_bo); | 204 | ret = vmw_user_dmabuf_lookup(sw_context->tfile, handle, &vmw_bo); |
198 | if (unlikely(ret != 0)) { | 205 | if (unlikely(ret != 0)) { |
@@ -228,14 +235,23 @@ static int vmw_cmd_dma(struct vmw_private *dev_priv, | |||
228 | ++sw_context->cur_val_buf; | 235 | ++sw_context->cur_val_buf; |
229 | } | 236 | } |
230 | 237 | ||
231 | ret = vmw_user_surface_lookup(dev_priv, sw_context->tfile, | 238 | ret = vmw_user_surface_lookup_handle(dev_priv, sw_context->tfile, |
232 | cmd->dma.host.sid, &srf); | 239 | cmd->dma.host.sid, &srf); |
233 | if (ret) { | 240 | if (ret) { |
234 | DRM_ERROR("could not find surface\n"); | 241 | DRM_ERROR("could not find surface\n"); |
235 | goto out_no_reloc; | 242 | goto out_no_reloc; |
236 | } | 243 | } |
237 | 244 | ||
245 | /** | ||
246 | * Patch command stream with device SID. | ||
247 | */ | ||
248 | |||
249 | cmd->dma.host.sid = srf->res.id; | ||
238 | vmw_kms_cursor_snoop(srf, sw_context->tfile, bo, header); | 250 | vmw_kms_cursor_snoop(srf, sw_context->tfile, bo, header); |
251 | /** | ||
252 | * FIXME: May deadlock here when called from the | ||
253 | * command parsing code. | ||
254 | */ | ||
239 | vmw_surface_unreference(&srf); | 255 | vmw_surface_unreference(&srf); |
240 | 256 | ||
241 | out_no_reloc: | 257 | out_no_reloc: |
@@ -243,6 +259,90 @@ out_no_reloc: | |||
243 | return ret; | 259 | return ret; |
244 | } | 260 | } |
245 | 261 | ||
262 | static int vmw_cmd_draw(struct vmw_private *dev_priv, | ||
263 | struct vmw_sw_context *sw_context, | ||
264 | SVGA3dCmdHeader *header) | ||
265 | { | ||
266 | struct vmw_draw_cmd { | ||
267 | SVGA3dCmdHeader header; | ||
268 | SVGA3dCmdDrawPrimitives body; | ||
269 | } *cmd; | ||
270 | SVGA3dVertexDecl *decl = (SVGA3dVertexDecl *)( | ||
271 | (unsigned long)header + sizeof(*cmd)); | ||
272 | SVGA3dPrimitiveRange *range; | ||
273 | uint32_t i; | ||
274 | uint32_t maxnum; | ||
275 | int ret; | ||
276 | |||
277 | ret = vmw_cmd_cid_check(dev_priv, sw_context, header); | ||
278 | if (unlikely(ret != 0)) | ||
279 | return ret; | ||
280 | |||
281 | cmd = container_of(header, struct vmw_draw_cmd, header); | ||
282 | maxnum = (header->size - sizeof(cmd->body)) / sizeof(*decl); | ||
283 | |||
284 | if (unlikely(cmd->body.numVertexDecls > maxnum)) { | ||
285 | DRM_ERROR("Illegal number of vertex declarations.\n"); | ||
286 | return -EINVAL; | ||
287 | } | ||
288 | |||
289 | for (i = 0; i < cmd->body.numVertexDecls; ++i, ++decl) { | ||
290 | ret = vmw_cmd_sid_check(dev_priv, sw_context, | ||
291 | &decl->array.surfaceId); | ||
292 | if (unlikely(ret != 0)) | ||
293 | return ret; | ||
294 | } | ||
295 | |||
296 | maxnum = (header->size - sizeof(cmd->body) - | ||
297 | cmd->body.numVertexDecls * sizeof(*decl)) / sizeof(*range); | ||
298 | if (unlikely(cmd->body.numRanges > maxnum)) { | ||
299 | DRM_ERROR("Illegal number of index ranges.\n"); | ||
300 | return -EINVAL; | ||
301 | } | ||
302 | |||
303 | range = (SVGA3dPrimitiveRange *) decl; | ||
304 | for (i = 0; i < cmd->body.numRanges; ++i, ++range) { | ||
305 | ret = vmw_cmd_sid_check(dev_priv, sw_context, | ||
306 | &range->indexArray.surfaceId); | ||
307 | if (unlikely(ret != 0)) | ||
308 | return ret; | ||
309 | } | ||
310 | return 0; | ||
311 | } | ||
312 | |||
313 | |||
314 | static int vmw_cmd_tex_state(struct vmw_private *dev_priv, | ||
315 | struct vmw_sw_context *sw_context, | ||
316 | SVGA3dCmdHeader *header) | ||
317 | { | ||
318 | struct vmw_tex_state_cmd { | ||
319 | SVGA3dCmdHeader header; | ||
320 | SVGA3dCmdSetTextureState state; | ||
321 | }; | ||
322 | |||
323 | SVGA3dTextureState *last_state = (SVGA3dTextureState *) | ||
324 | ((unsigned long) header + header->size + sizeof(header)); | ||
325 | SVGA3dTextureState *cur_state = (SVGA3dTextureState *) | ||
326 | ((unsigned long) header + sizeof(struct vmw_tex_state_cmd)); | ||
327 | int ret; | ||
328 | |||
329 | ret = vmw_cmd_cid_check(dev_priv, sw_context, header); | ||
330 | if (unlikely(ret != 0)) | ||
331 | return ret; | ||
332 | |||
333 | for (; cur_state < last_state; ++cur_state) { | ||
334 | if (likely(cur_state->name != SVGA3D_TS_BIND_TEXTURE)) | ||
335 | continue; | ||
336 | |||
337 | ret = vmw_cmd_sid_check(dev_priv, sw_context, | ||
338 | &cur_state->value); | ||
339 | if (unlikely(ret != 0)) | ||
340 | return ret; | ||
341 | } | ||
342 | |||
343 | return 0; | ||
344 | } | ||
345 | |||
246 | 346 | ||
247 | typedef int (*vmw_cmd_func) (struct vmw_private *, | 347 | typedef int (*vmw_cmd_func) (struct vmw_private *, |
248 | struct vmw_sw_context *, | 348 | struct vmw_sw_context *, |
@@ -264,7 +364,7 @@ static vmw_cmd_func vmw_cmd_funcs[SVGA_3D_CMD_MAX] = { | |||
264 | VMW_CMD_DEF(SVGA_3D_CMD_SETRENDERSTATE, &vmw_cmd_cid_check), | 364 | VMW_CMD_DEF(SVGA_3D_CMD_SETRENDERSTATE, &vmw_cmd_cid_check), |
265 | VMW_CMD_DEF(SVGA_3D_CMD_SETRENDERTARGET, | 365 | VMW_CMD_DEF(SVGA_3D_CMD_SETRENDERTARGET, |
266 | &vmw_cmd_set_render_target_check), | 366 | &vmw_cmd_set_render_target_check), |
267 | VMW_CMD_DEF(SVGA_3D_CMD_SETTEXTURESTATE, &vmw_cmd_cid_check), | 367 | VMW_CMD_DEF(SVGA_3D_CMD_SETTEXTURESTATE, &vmw_cmd_tex_state), |
268 | VMW_CMD_DEF(SVGA_3D_CMD_SETMATERIAL, &vmw_cmd_cid_check), | 368 | VMW_CMD_DEF(SVGA_3D_CMD_SETMATERIAL, &vmw_cmd_cid_check), |
269 | VMW_CMD_DEF(SVGA_3D_CMD_SETLIGHTDATA, &vmw_cmd_cid_check), | 369 | VMW_CMD_DEF(SVGA_3D_CMD_SETLIGHTDATA, &vmw_cmd_cid_check), |
270 | VMW_CMD_DEF(SVGA_3D_CMD_SETLIGHTENABLED, &vmw_cmd_cid_check), | 370 | VMW_CMD_DEF(SVGA_3D_CMD_SETLIGHTENABLED, &vmw_cmd_cid_check), |
@@ -276,7 +376,7 @@ static vmw_cmd_func vmw_cmd_funcs[SVGA_3D_CMD_MAX] = { | |||
276 | VMW_CMD_DEF(SVGA_3D_CMD_SHADER_DESTROY, &vmw_cmd_cid_check), | 376 | VMW_CMD_DEF(SVGA_3D_CMD_SHADER_DESTROY, &vmw_cmd_cid_check), |
277 | VMW_CMD_DEF(SVGA_3D_CMD_SET_SHADER, &vmw_cmd_cid_check), | 377 | VMW_CMD_DEF(SVGA_3D_CMD_SET_SHADER, &vmw_cmd_cid_check), |
278 | VMW_CMD_DEF(SVGA_3D_CMD_SET_SHADER_CONST, &vmw_cmd_cid_check), | 378 | VMW_CMD_DEF(SVGA_3D_CMD_SET_SHADER_CONST, &vmw_cmd_cid_check), |
279 | VMW_CMD_DEF(SVGA_3D_CMD_DRAW_PRIMITIVES, &vmw_cmd_cid_check), | 379 | VMW_CMD_DEF(SVGA_3D_CMD_DRAW_PRIMITIVES, &vmw_cmd_draw), |
280 | VMW_CMD_DEF(SVGA_3D_CMD_SETSCISSORRECT, &vmw_cmd_cid_check), | 380 | VMW_CMD_DEF(SVGA_3D_CMD_SETSCISSORRECT, &vmw_cmd_cid_check), |
281 | VMW_CMD_DEF(SVGA_3D_CMD_BEGIN_QUERY, &vmw_cmd_cid_check), | 381 | VMW_CMD_DEF(SVGA_3D_CMD_BEGIN_QUERY, &vmw_cmd_cid_check), |
282 | VMW_CMD_DEF(SVGA_3D_CMD_END_QUERY, &vmw_cmd_cid_check), | 382 | VMW_CMD_DEF(SVGA_3D_CMD_END_QUERY, &vmw_cmd_cid_check), |
@@ -291,6 +391,7 @@ static int vmw_cmd_check(struct vmw_private *dev_priv, | |||
291 | void *buf, uint32_t *size) | 391 | void *buf, uint32_t *size) |
292 | { | 392 | { |
293 | uint32_t cmd_id; | 393 | uint32_t cmd_id; |
394 | uint32_t size_remaining = *size; | ||
294 | SVGA3dCmdHeader *header = (SVGA3dCmdHeader *) buf; | 395 | SVGA3dCmdHeader *header = (SVGA3dCmdHeader *) buf; |
295 | int ret; | 396 | int ret; |
296 | 397 | ||
@@ -304,6 +405,9 @@ static int vmw_cmd_check(struct vmw_private *dev_priv, | |||
304 | *size = le32_to_cpu(header->size) + sizeof(SVGA3dCmdHeader); | 405 | *size = le32_to_cpu(header->size) + sizeof(SVGA3dCmdHeader); |
305 | 406 | ||
306 | cmd_id -= SVGA_3D_CMD_BASE; | 407 | cmd_id -= SVGA_3D_CMD_BASE; |
408 | if (unlikely(*size > size_remaining)) | ||
409 | goto out_err; | ||
410 | |||
307 | if (unlikely(cmd_id >= SVGA_3D_CMD_MAX - SVGA_3D_CMD_BASE)) | 411 | if (unlikely(cmd_id >= SVGA_3D_CMD_MAX - SVGA_3D_CMD_BASE)) |
308 | goto out_err; | 412 | goto out_err; |
309 | 413 | ||
@@ -326,6 +430,7 @@ static int vmw_cmd_check_all(struct vmw_private *dev_priv, | |||
326 | int ret; | 430 | int ret; |
327 | 431 | ||
328 | while (cur_size > 0) { | 432 | while (cur_size > 0) { |
433 | size = cur_size; | ||
329 | ret = vmw_cmd_check(dev_priv, sw_context, buf, &size); | 434 | ret = vmw_cmd_check(dev_priv, sw_context, buf, &size); |
330 | if (unlikely(ret != 0)) | 435 | if (unlikely(ret != 0)) |
331 | return ret; | 436 | return ret; |
@@ -386,7 +491,7 @@ static int vmw_validate_single_buffer(struct vmw_private *dev_priv, | |||
386 | return 0; | 491 | return 0; |
387 | 492 | ||
388 | ret = vmw_gmr_bind(dev_priv, bo); | 493 | ret = vmw_gmr_bind(dev_priv, bo); |
389 | if (likely(ret == 0 || ret == -ERESTART)) | 494 | if (likely(ret == 0 || ret == -ERESTARTSYS)) |
390 | return ret; | 495 | return ret; |
391 | 496 | ||
392 | 497 | ||
@@ -429,7 +534,7 @@ int vmw_execbuf_ioctl(struct drm_device *dev, void *data, | |||
429 | 534 | ||
430 | ret = mutex_lock_interruptible(&dev_priv->cmdbuf_mutex); | 535 | ret = mutex_lock_interruptible(&dev_priv->cmdbuf_mutex); |
431 | if (unlikely(ret != 0)) { | 536 | if (unlikely(ret != 0)) { |
432 | ret = -ERESTART; | 537 | ret = -ERESTARTSYS; |
433 | goto out_no_cmd_mutex; | 538 | goto out_no_cmd_mutex; |
434 | } | 539 | } |
435 | 540 | ||
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c index 76b0693e2458..01feb48af333 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c | |||
@@ -191,7 +191,7 @@ static int vmw_fifo_wait_noirq(struct vmw_private *dev_priv, | |||
191 | } | 191 | } |
192 | schedule_timeout(1); | 192 | schedule_timeout(1); |
193 | if (interruptible && signal_pending(current)) { | 193 | if (interruptible && signal_pending(current)) { |
194 | ret = -ERESTART; | 194 | ret = -ERESTARTSYS; |
195 | break; | 195 | break; |
196 | } | 196 | } |
197 | } | 197 | } |
@@ -237,9 +237,7 @@ static int vmw_fifo_wait(struct vmw_private *dev_priv, | |||
237 | (dev_priv->fifo_queue, | 237 | (dev_priv->fifo_queue, |
238 | !vmw_fifo_is_full(dev_priv, bytes), timeout); | 238 | !vmw_fifo_is_full(dev_priv, bytes), timeout); |
239 | 239 | ||
240 | if (unlikely(ret == -ERESTARTSYS)) | 240 | if (unlikely(ret == 0)) |
241 | ret = -ERESTART; | ||
242 | else if (unlikely(ret == 0)) | ||
243 | ret = -EBUSY; | 241 | ret = -EBUSY; |
244 | else if (likely(ret > 0)) | 242 | else if (likely(ret > 0)) |
245 | ret = 0; | 243 | ret = 0; |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c b/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c index 9e0f0306eedb..d40086fc8647 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c | |||
@@ -155,7 +155,7 @@ int vmw_fallback_wait(struct vmw_private *dev_priv, | |||
155 | TASK_UNINTERRUPTIBLE); | 155 | TASK_UNINTERRUPTIBLE); |
156 | } | 156 | } |
157 | if (interruptible && signal_pending(current)) { | 157 | if (interruptible && signal_pending(current)) { |
158 | ret = -ERESTART; | 158 | ret = -ERESTARTSYS; |
159 | break; | 159 | break; |
160 | } | 160 | } |
161 | } | 161 | } |
@@ -218,9 +218,7 @@ int vmw_wait_fence(struct vmw_private *dev_priv, | |||
218 | vmw_fence_signaled(dev_priv, sequence), | 218 | vmw_fence_signaled(dev_priv, sequence), |
219 | timeout); | 219 | timeout); |
220 | 220 | ||
221 | if (unlikely(ret == -ERESTARTSYS)) | 221 | if (unlikely(ret == 0)) |
222 | ret = -ERESTART; | ||
223 | else if (unlikely(ret == 0)) | ||
224 | ret = -EBUSY; | 222 | ret = -EBUSY; |
225 | else if (likely(ret > 0)) | 223 | else if (likely(ret > 0)) |
226 | ret = 0; | 224 | ret = 0; |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index e9403be446fe..b1af76e371c3 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | |||
@@ -106,8 +106,8 @@ int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, | |||
106 | int ret; | 106 | int ret; |
107 | 107 | ||
108 | if (handle) { | 108 | if (handle) { |
109 | ret = vmw_user_surface_lookup(dev_priv, tfile, | 109 | ret = vmw_user_surface_lookup_handle(dev_priv, tfile, |
110 | handle, &surface); | 110 | handle, &surface); |
111 | if (!ret) { | 111 | if (!ret) { |
112 | if (!surface->snooper.image) { | 112 | if (!surface->snooper.image) { |
113 | DRM_ERROR("surface not suitable for cursor\n"); | 113 | DRM_ERROR("surface not suitable for cursor\n"); |
@@ -704,8 +704,8 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev, | |||
704 | struct vmw_dma_buffer *bo = NULL; | 704 | struct vmw_dma_buffer *bo = NULL; |
705 | int ret; | 705 | int ret; |
706 | 706 | ||
707 | ret = vmw_user_surface_lookup(dev_priv, tfile, | 707 | ret = vmw_user_surface_lookup_handle(dev_priv, tfile, |
708 | mode_cmd->handle, &surface); | 708 | mode_cmd->handle, &surface); |
709 | if (ret) | 709 | if (ret) |
710 | goto try_dmabuf; | 710 | goto try_dmabuf; |
711 | 711 | ||
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c index a1ceed0c8e07..c012d5927f65 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | |||
@@ -488,28 +488,44 @@ static void vmw_user_surface_free(struct vmw_resource *res) | |||
488 | kfree(user_srf); | 488 | kfree(user_srf); |
489 | } | 489 | } |
490 | 490 | ||
491 | int vmw_user_surface_lookup(struct vmw_private *dev_priv, | 491 | int vmw_user_surface_lookup_handle(struct vmw_private *dev_priv, |
492 | struct ttm_object_file *tfile, | 492 | struct ttm_object_file *tfile, |
493 | int sid, struct vmw_surface **out) | 493 | uint32_t handle, struct vmw_surface **out) |
494 | { | 494 | { |
495 | struct vmw_resource *res; | 495 | struct vmw_resource *res; |
496 | struct vmw_surface *srf; | 496 | struct vmw_surface *srf; |
497 | struct vmw_user_surface *user_srf; | 497 | struct vmw_user_surface *user_srf; |
498 | struct ttm_base_object *base; | ||
499 | int ret = -EINVAL; | ||
498 | 500 | ||
499 | res = vmw_resource_lookup(dev_priv, &dev_priv->surface_idr, sid); | 501 | base = ttm_base_object_lookup(tfile, handle); |
500 | if (unlikely(res == NULL)) | 502 | if (unlikely(base == NULL)) |
501 | return -EINVAL; | 503 | return -EINVAL; |
502 | 504 | ||
503 | if (res->res_free != &vmw_user_surface_free) | 505 | if (unlikely(base->object_type != VMW_RES_SURFACE)) |
504 | return -EINVAL; | 506 | goto out_bad_resource; |
505 | 507 | ||
506 | srf = container_of(res, struct vmw_surface, res); | 508 | user_srf = container_of(base, struct vmw_user_surface, base); |
507 | user_srf = container_of(srf, struct vmw_user_surface, srf); | 509 | srf = &user_srf->srf; |
508 | if (user_srf->base.tfile != tfile && !user_srf->base.shareable) | 510 | res = &srf->res; |
509 | return -EPERM; | 511 | |
512 | read_lock(&dev_priv->resource_lock); | ||
513 | |||
514 | if (!res->avail || res->res_free != &vmw_user_surface_free) { | ||
515 | read_unlock(&dev_priv->resource_lock); | ||
516 | goto out_bad_resource; | ||
517 | } | ||
518 | |||
519 | kref_get(&res->kref); | ||
520 | read_unlock(&dev_priv->resource_lock); | ||
510 | 521 | ||
511 | *out = srf; | 522 | *out = srf; |
512 | return 0; | 523 | ret = 0; |
524 | |||
525 | out_bad_resource: | ||
526 | ttm_base_object_unref(&base); | ||
527 | |||
528 | return ret; | ||
513 | } | 529 | } |
514 | 530 | ||
515 | static void vmw_user_surface_base_release(struct ttm_base_object **p_base) | 531 | static void vmw_user_surface_base_release(struct ttm_base_object **p_base) |
@@ -526,35 +542,10 @@ static void vmw_user_surface_base_release(struct ttm_base_object **p_base) | |||
526 | int vmw_surface_destroy_ioctl(struct drm_device *dev, void *data, | 542 | int vmw_surface_destroy_ioctl(struct drm_device *dev, void *data, |
527 | struct drm_file *file_priv) | 543 | struct drm_file *file_priv) |
528 | { | 544 | { |
529 | struct vmw_private *dev_priv = vmw_priv(dev); | ||
530 | struct vmw_resource *res; | ||
531 | struct vmw_surface *srf; | ||
532 | struct vmw_user_surface *user_srf; | ||
533 | struct drm_vmw_surface_arg *arg = (struct drm_vmw_surface_arg *)data; | 545 | struct drm_vmw_surface_arg *arg = (struct drm_vmw_surface_arg *)data; |
534 | struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; | 546 | struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; |
535 | int ret = 0; | ||
536 | |||
537 | res = vmw_resource_lookup(dev_priv, &dev_priv->surface_idr, arg->sid); | ||
538 | if (unlikely(res == NULL)) | ||
539 | return -EINVAL; | ||
540 | |||
541 | if (res->res_free != &vmw_user_surface_free) { | ||
542 | ret = -EINVAL; | ||
543 | goto out; | ||
544 | } | ||
545 | 547 | ||
546 | srf = container_of(res, struct vmw_surface, res); | 548 | return ttm_ref_object_base_unref(tfile, arg->sid, TTM_REF_USAGE); |
547 | user_srf = container_of(srf, struct vmw_user_surface, srf); | ||
548 | if (user_srf->base.tfile != tfile && !user_srf->base.shareable) { | ||
549 | ret = -EPERM; | ||
550 | goto out; | ||
551 | } | ||
552 | |||
553 | ttm_ref_object_base_unref(tfile, user_srf->base.hash.key, | ||
554 | TTM_REF_USAGE); | ||
555 | out: | ||
556 | vmw_resource_unreference(&res); | ||
557 | return ret; | ||
558 | } | 549 | } |
559 | 550 | ||
560 | int vmw_surface_define_ioctl(struct drm_device *dev, void *data, | 551 | int vmw_surface_define_ioctl(struct drm_device *dev, void *data, |
@@ -649,7 +640,10 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data, | |||
649 | } | 640 | } |
650 | srf->snooper.crtc = NULL; | 641 | srf->snooper.crtc = NULL; |
651 | 642 | ||
652 | rep->sid = res->id; | 643 | rep->sid = user_srf->base.hash.key; |
644 | if (rep->sid == SVGA3D_INVALID_ID) | ||
645 | DRM_ERROR("Created bad Surface ID.\n"); | ||
646 | |||
653 | vmw_resource_unreference(&res); | 647 | vmw_resource_unreference(&res); |
654 | return 0; | 648 | return 0; |
655 | out_err1: | 649 | out_err1: |
@@ -662,39 +656,33 @@ out_err0: | |||
662 | int vmw_surface_reference_ioctl(struct drm_device *dev, void *data, | 656 | int vmw_surface_reference_ioctl(struct drm_device *dev, void *data, |
663 | struct drm_file *file_priv) | 657 | struct drm_file *file_priv) |
664 | { | 658 | { |
665 | struct vmw_private *dev_priv = vmw_priv(dev); | ||
666 | union drm_vmw_surface_reference_arg *arg = | 659 | union drm_vmw_surface_reference_arg *arg = |
667 | (union drm_vmw_surface_reference_arg *)data; | 660 | (union drm_vmw_surface_reference_arg *)data; |
668 | struct drm_vmw_surface_arg *req = &arg->req; | 661 | struct drm_vmw_surface_arg *req = &arg->req; |
669 | struct drm_vmw_surface_create_req *rep = &arg->rep; | 662 | struct drm_vmw_surface_create_req *rep = &arg->rep; |
670 | struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; | 663 | struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; |
671 | struct vmw_resource *res; | ||
672 | struct vmw_surface *srf; | 664 | struct vmw_surface *srf; |
673 | struct vmw_user_surface *user_srf; | 665 | struct vmw_user_surface *user_srf; |
674 | struct drm_vmw_size __user *user_sizes; | 666 | struct drm_vmw_size __user *user_sizes; |
675 | int ret; | 667 | struct ttm_base_object *base; |
668 | int ret = -EINVAL; | ||
676 | 669 | ||
677 | res = vmw_resource_lookup(dev_priv, &dev_priv->surface_idr, req->sid); | 670 | base = ttm_base_object_lookup(tfile, req->sid); |
678 | if (unlikely(res == NULL)) | 671 | if (unlikely(base == NULL)) { |
672 | DRM_ERROR("Could not find surface to reference.\n"); | ||
679 | return -EINVAL; | 673 | return -EINVAL; |
680 | |||
681 | if (res->res_free != &vmw_user_surface_free) { | ||
682 | ret = -EINVAL; | ||
683 | goto out; | ||
684 | } | 674 | } |
685 | 675 | ||
686 | srf = container_of(res, struct vmw_surface, res); | 676 | if (unlikely(base->object_type != VMW_RES_SURFACE)) |
687 | user_srf = container_of(srf, struct vmw_user_surface, srf); | 677 | goto out_bad_resource; |
688 | if (user_srf->base.tfile != tfile && !user_srf->base.shareable) { | 678 | |
689 | DRM_ERROR("Tried to reference none shareable surface\n"); | 679 | user_srf = container_of(base, struct vmw_user_surface, base); |
690 | ret = -EPERM; | 680 | srf = &user_srf->srf; |
691 | goto out; | ||
692 | } | ||
693 | 681 | ||
694 | ret = ttm_ref_object_add(tfile, &user_srf->base, TTM_REF_USAGE, NULL); | 682 | ret = ttm_ref_object_add(tfile, &user_srf->base, TTM_REF_USAGE, NULL); |
695 | if (unlikely(ret != 0)) { | 683 | if (unlikely(ret != 0)) { |
696 | DRM_ERROR("Could not add a reference to a surface.\n"); | 684 | DRM_ERROR("Could not add a reference to a surface.\n"); |
697 | goto out; | 685 | goto out_no_reference; |
698 | } | 686 | } |
699 | 687 | ||
700 | rep->flags = srf->flags; | 688 | rep->flags = srf->flags; |
@@ -706,40 +694,43 @@ int vmw_surface_reference_ioctl(struct drm_device *dev, void *data, | |||
706 | if (user_sizes) | 694 | if (user_sizes) |
707 | ret = copy_to_user(user_sizes, srf->sizes, | 695 | ret = copy_to_user(user_sizes, srf->sizes, |
708 | srf->num_sizes * sizeof(*srf->sizes)); | 696 | srf->num_sizes * sizeof(*srf->sizes)); |
709 | if (unlikely(ret != 0)) { | 697 | if (unlikely(ret != 0)) |
710 | DRM_ERROR("copy_to_user failed %p %u\n", | 698 | DRM_ERROR("copy_to_user failed %p %u\n", |
711 | user_sizes, srf->num_sizes); | 699 | user_sizes, srf->num_sizes); |
712 | /** | 700 | out_bad_resource: |
713 | * FIXME: Unreference surface here? | 701 | out_no_reference: |
714 | */ | 702 | ttm_base_object_unref(&base); |
715 | goto out; | 703 | |
716 | } | ||
717 | out: | ||
718 | vmw_resource_unreference(&res); | ||
719 | return ret; | 704 | return ret; |
720 | } | 705 | } |
721 | 706 | ||
722 | int vmw_surface_check(struct vmw_private *dev_priv, | 707 | int vmw_surface_check(struct vmw_private *dev_priv, |
723 | struct ttm_object_file *tfile, | 708 | struct ttm_object_file *tfile, |
724 | int id) | 709 | uint32_t handle, int *id) |
725 | { | 710 | { |
726 | struct vmw_resource *res; | 711 | struct ttm_base_object *base; |
727 | int ret = 0; | 712 | struct vmw_user_surface *user_srf; |
728 | 713 | ||
729 | read_lock(&dev_priv->resource_lock); | 714 | int ret = -EPERM; |
730 | res = idr_find(&dev_priv->surface_idr, id); | ||
731 | if (res && res->avail) { | ||
732 | struct vmw_surface *srf = | ||
733 | container_of(res, struct vmw_surface, res); | ||
734 | struct vmw_user_surface *usrf = | ||
735 | container_of(srf, struct vmw_user_surface, srf); | ||
736 | 715 | ||
737 | if (usrf->base.tfile != tfile && !usrf->base.shareable) | 716 | base = ttm_base_object_lookup(tfile, handle); |
738 | ret = -EPERM; | 717 | if (unlikely(base == NULL)) |
739 | } else | 718 | return -EINVAL; |
740 | ret = -EINVAL; | 719 | |
741 | read_unlock(&dev_priv->resource_lock); | 720 | if (unlikely(base->object_type != VMW_RES_SURFACE)) |
721 | goto out_bad_surface; | ||
742 | 722 | ||
723 | user_srf = container_of(base, struct vmw_user_surface, base); | ||
724 | *id = user_srf->srf.res.id; | ||
725 | ret = 0; | ||
726 | |||
727 | out_bad_surface: | ||
728 | /** | ||
729 | * FIXME: May deadlock here when called from the | ||
730 | * command parsing code. | ||
731 | */ | ||
732 | |||
733 | ttm_base_object_unref(&base); | ||
743 | return ret; | 734 | return ret; |
744 | } | 735 | } |
745 | 736 | ||
diff --git a/drivers/i2c/busses/i2c-bfin-twi.c b/drivers/i2c/busses/i2c-bfin-twi.c index b309ac2c3d5c..fe3fb567317d 100644 --- a/drivers/i2c/busses/i2c-bfin-twi.c +++ b/drivers/i2c/busses/i2c-bfin-twi.c | |||
@@ -693,13 +693,13 @@ static int i2c_bfin_twi_probe(struct platform_device *pdev) | |||
693 | } | 693 | } |
694 | 694 | ||
695 | /* Set TWI internal clock as 10MHz */ | 695 | /* Set TWI internal clock as 10MHz */ |
696 | write_CONTROL(iface, ((get_sclk() / 1024 / 1024 + 5) / 10) & 0x7F); | 696 | write_CONTROL(iface, ((get_sclk() / 1000 / 1000 + 5) / 10) & 0x7F); |
697 | 697 | ||
698 | /* | 698 | /* |
699 | * We will not end up with a CLKDIV=0 because no one will specify | 699 | * We will not end up with a CLKDIV=0 because no one will specify |
700 | * 20kHz SCL or less in Kconfig now. (5 * 1024 / 20 = 0x100) | 700 | * 20kHz SCL or less in Kconfig now. (5 * 1000 / 20 = 250) |
701 | */ | 701 | */ |
702 | clkhilow = 5 * 1024 / CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ; | 702 | clkhilow = ((10 * 1000 / CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ) + 1) / 2; |
703 | 703 | ||
704 | /* Set Twi interface clock as specified */ | 704 | /* Set Twi interface clock as specified */ |
705 | write_CLKDIV(iface, (clkhilow << 8) | clkhilow); | 705 | write_CLKDIV(iface, (clkhilow << 8) | clkhilow); |
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 75bf3ad18099..0037e31076ba 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c | |||
@@ -247,7 +247,13 @@ static void omap_i2c_unidle(struct omap_i2c_dev *dev) | |||
247 | omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN); | 247 | omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN); |
248 | } | 248 | } |
249 | dev->idle = 0; | 249 | dev->idle = 0; |
250 | omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate); | 250 | |
251 | /* | ||
252 | * Don't write to this register if the IE state is 0 as it can | ||
253 | * cause deadlock. | ||
254 | */ | ||
255 | if (dev->iestate) | ||
256 | omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate); | ||
251 | } | 257 | } |
252 | 258 | ||
253 | static void omap_i2c_idle(struct omap_i2c_dev *dev) | 259 | static void omap_i2c_idle(struct omap_i2c_dev *dev) |
@@ -280,6 +286,11 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) | |||
280 | unsigned long internal_clk = 0; | 286 | unsigned long internal_clk = 0; |
281 | 287 | ||
282 | if (dev->rev >= OMAP_I2C_REV_2) { | 288 | if (dev->rev >= OMAP_I2C_REV_2) { |
289 | /* Disable I2C controller before soft reset */ | ||
290 | omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, | ||
291 | omap_i2c_read_reg(dev, OMAP_I2C_CON_REG) & | ||
292 | ~(OMAP_I2C_CON_EN)); | ||
293 | |||
283 | omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG, SYSC_SOFTRESET_MASK); | 294 | omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG, SYSC_SOFTRESET_MASK); |
284 | /* For some reason we need to set the EN bit before the | 295 | /* For some reason we need to set the EN bit before the |
285 | * reset done bit gets set. */ | 296 | * reset done bit gets set. */ |
diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.h b/drivers/infiniband/hw/cxgb3/cxio_hal.h index bfd03bf8be54..f3d440cc68f2 100644 --- a/drivers/infiniband/hw/cxgb3/cxio_hal.h +++ b/drivers/infiniband/hw/cxgb3/cxio_hal.h | |||
@@ -34,6 +34,7 @@ | |||
34 | 34 | ||
35 | #include <linux/list.h> | 35 | #include <linux/list.h> |
36 | #include <linux/mutex.h> | 36 | #include <linux/mutex.h> |
37 | #include <linux/kfifo.h> | ||
37 | 38 | ||
38 | #include "t3_cpl.h" | 39 | #include "t3_cpl.h" |
39 | #include "t3cdev.h" | 40 | #include "t3cdev.h" |
@@ -75,13 +76,13 @@ struct cxio_hal_ctrl_qp { | |||
75 | }; | 76 | }; |
76 | 77 | ||
77 | struct cxio_hal_resource { | 78 | struct cxio_hal_resource { |
78 | struct kfifo *tpt_fifo; | 79 | struct kfifo tpt_fifo; |
79 | spinlock_t tpt_fifo_lock; | 80 | spinlock_t tpt_fifo_lock; |
80 | struct kfifo *qpid_fifo; | 81 | struct kfifo qpid_fifo; |
81 | spinlock_t qpid_fifo_lock; | 82 | spinlock_t qpid_fifo_lock; |
82 | struct kfifo *cqid_fifo; | 83 | struct kfifo cqid_fifo; |
83 | spinlock_t cqid_fifo_lock; | 84 | spinlock_t cqid_fifo_lock; |
84 | struct kfifo *pdid_fifo; | 85 | struct kfifo pdid_fifo; |
85 | spinlock_t pdid_fifo_lock; | 86 | spinlock_t pdid_fifo_lock; |
86 | }; | 87 | }; |
87 | 88 | ||
diff --git a/drivers/infiniband/hw/cxgb3/cxio_resource.c b/drivers/infiniband/hw/cxgb3/cxio_resource.c index bd233c087653..31f9201b2980 100644 --- a/drivers/infiniband/hw/cxgb3/cxio_resource.c +++ b/drivers/infiniband/hw/cxgb3/cxio_resource.c | |||
@@ -39,12 +39,12 @@ | |||
39 | #include "cxio_resource.h" | 39 | #include "cxio_resource.h" |
40 | #include "cxio_hal.h" | 40 | #include "cxio_hal.h" |
41 | 41 | ||
42 | static struct kfifo *rhdl_fifo; | 42 | static struct kfifo rhdl_fifo; |
43 | static spinlock_t rhdl_fifo_lock; | 43 | static spinlock_t rhdl_fifo_lock; |
44 | 44 | ||
45 | #define RANDOM_SIZE 16 | 45 | #define RANDOM_SIZE 16 |
46 | 46 | ||
47 | static int __cxio_init_resource_fifo(struct kfifo **fifo, | 47 | static int __cxio_init_resource_fifo(struct kfifo *fifo, |
48 | spinlock_t *fifo_lock, | 48 | spinlock_t *fifo_lock, |
49 | u32 nr, u32 skip_low, | 49 | u32 nr, u32 skip_low, |
50 | u32 skip_high, | 50 | u32 skip_high, |
@@ -55,12 +55,11 @@ static int __cxio_init_resource_fifo(struct kfifo **fifo, | |||
55 | u32 rarray[16]; | 55 | u32 rarray[16]; |
56 | spin_lock_init(fifo_lock); | 56 | spin_lock_init(fifo_lock); |
57 | 57 | ||
58 | *fifo = kfifo_alloc(nr * sizeof(u32), GFP_KERNEL, fifo_lock); | 58 | if (kfifo_alloc(fifo, nr * sizeof(u32), GFP_KERNEL)) |
59 | if (IS_ERR(*fifo)) | ||
60 | return -ENOMEM; | 59 | return -ENOMEM; |
61 | 60 | ||
62 | for (i = 0; i < skip_low + skip_high; i++) | 61 | for (i = 0; i < skip_low + skip_high; i++) |
63 | __kfifo_put(*fifo, (unsigned char *) &entry, sizeof(u32)); | 62 | kfifo_in(fifo, (unsigned char *) &entry, sizeof(u32)); |
64 | if (random) { | 63 | if (random) { |
65 | j = 0; | 64 | j = 0; |
66 | random_bytes = random32(); | 65 | random_bytes = random32(); |
@@ -72,33 +71,35 @@ static int __cxio_init_resource_fifo(struct kfifo **fifo, | |||
72 | random_bytes = random32(); | 71 | random_bytes = random32(); |
73 | } | 72 | } |
74 | idx = (random_bytes >> (j * 2)) & 0xF; | 73 | idx = (random_bytes >> (j * 2)) & 0xF; |
75 | __kfifo_put(*fifo, | 74 | kfifo_in(fifo, |
76 | (unsigned char *) &rarray[idx], | 75 | (unsigned char *) &rarray[idx], |
77 | sizeof(u32)); | 76 | sizeof(u32)); |
78 | rarray[idx] = i; | 77 | rarray[idx] = i; |
79 | j++; | 78 | j++; |
80 | } | 79 | } |
81 | for (i = 0; i < RANDOM_SIZE; i++) | 80 | for (i = 0; i < RANDOM_SIZE; i++) |
82 | __kfifo_put(*fifo, | 81 | kfifo_in(fifo, |
83 | (unsigned char *) &rarray[i], | 82 | (unsigned char *) &rarray[i], |
84 | sizeof(u32)); | 83 | sizeof(u32)); |
85 | } else | 84 | } else |
86 | for (i = skip_low; i < nr - skip_high; i++) | 85 | for (i = skip_low; i < nr - skip_high; i++) |
87 | __kfifo_put(*fifo, (unsigned char *) &i, sizeof(u32)); | 86 | kfifo_in(fifo, (unsigned char *) &i, sizeof(u32)); |
88 | 87 | ||
89 | for (i = 0; i < skip_low + skip_high; i++) | 88 | for (i = 0; i < skip_low + skip_high; i++) |
90 | kfifo_get(*fifo, (unsigned char *) &entry, sizeof(u32)); | 89 | if (kfifo_out_locked(fifo, (unsigned char *) &entry, |
90 | sizeof(u32), fifo_lock) != sizeof(u32)) | ||
91 | break; | ||
91 | return 0; | 92 | return 0; |
92 | } | 93 | } |
93 | 94 | ||
94 | static int cxio_init_resource_fifo(struct kfifo **fifo, spinlock_t * fifo_lock, | 95 | static int cxio_init_resource_fifo(struct kfifo *fifo, spinlock_t * fifo_lock, |
95 | u32 nr, u32 skip_low, u32 skip_high) | 96 | u32 nr, u32 skip_low, u32 skip_high) |
96 | { | 97 | { |
97 | return (__cxio_init_resource_fifo(fifo, fifo_lock, nr, skip_low, | 98 | return (__cxio_init_resource_fifo(fifo, fifo_lock, nr, skip_low, |
98 | skip_high, 0)); | 99 | skip_high, 0)); |
99 | } | 100 | } |
100 | 101 | ||
101 | static int cxio_init_resource_fifo_random(struct kfifo **fifo, | 102 | static int cxio_init_resource_fifo_random(struct kfifo *fifo, |
102 | spinlock_t * fifo_lock, | 103 | spinlock_t * fifo_lock, |
103 | u32 nr, u32 skip_low, u32 skip_high) | 104 | u32 nr, u32 skip_low, u32 skip_high) |
104 | { | 105 | { |
@@ -113,15 +114,13 @@ static int cxio_init_qpid_fifo(struct cxio_rdev *rdev_p) | |||
113 | 114 | ||
114 | spin_lock_init(&rdev_p->rscp->qpid_fifo_lock); | 115 | spin_lock_init(&rdev_p->rscp->qpid_fifo_lock); |
115 | 116 | ||
116 | rdev_p->rscp->qpid_fifo = kfifo_alloc(T3_MAX_NUM_QP * sizeof(u32), | 117 | if (kfifo_alloc(&rdev_p->rscp->qpid_fifo, T3_MAX_NUM_QP * sizeof(u32), |
117 | GFP_KERNEL, | 118 | GFP_KERNEL)) |
118 | &rdev_p->rscp->qpid_fifo_lock); | ||
119 | if (IS_ERR(rdev_p->rscp->qpid_fifo)) | ||
120 | return -ENOMEM; | 119 | return -ENOMEM; |
121 | 120 | ||
122 | for (i = 16; i < T3_MAX_NUM_QP; i++) | 121 | for (i = 16; i < T3_MAX_NUM_QP; i++) |
123 | if (!(i & rdev_p->qpmask)) | 122 | if (!(i & rdev_p->qpmask)) |
124 | __kfifo_put(rdev_p->rscp->qpid_fifo, | 123 | kfifo_in(&rdev_p->rscp->qpid_fifo, |
125 | (unsigned char *) &i, sizeof(u32)); | 124 | (unsigned char *) &i, sizeof(u32)); |
126 | return 0; | 125 | return 0; |
127 | } | 126 | } |
@@ -134,7 +133,7 @@ int cxio_hal_init_rhdl_resource(u32 nr_rhdl) | |||
134 | 133 | ||
135 | void cxio_hal_destroy_rhdl_resource(void) | 134 | void cxio_hal_destroy_rhdl_resource(void) |
136 | { | 135 | { |
137 | kfifo_free(rhdl_fifo); | 136 | kfifo_free(&rhdl_fifo); |
138 | } | 137 | } |
139 | 138 | ||
140 | /* nr_* must be power of 2 */ | 139 | /* nr_* must be power of 2 */ |
@@ -167,11 +166,11 @@ int cxio_hal_init_resource(struct cxio_rdev *rdev_p, | |||
167 | goto pdid_err; | 166 | goto pdid_err; |
168 | return 0; | 167 | return 0; |
169 | pdid_err: | 168 | pdid_err: |
170 | kfifo_free(rscp->cqid_fifo); | 169 | kfifo_free(&rscp->cqid_fifo); |
171 | cqid_err: | 170 | cqid_err: |
172 | kfifo_free(rscp->qpid_fifo); | 171 | kfifo_free(&rscp->qpid_fifo); |
173 | qpid_err: | 172 | qpid_err: |
174 | kfifo_free(rscp->tpt_fifo); | 173 | kfifo_free(&rscp->tpt_fifo); |
175 | tpt_err: | 174 | tpt_err: |
176 | return -ENOMEM; | 175 | return -ENOMEM; |
177 | } | 176 | } |
@@ -179,33 +178,37 @@ tpt_err: | |||
179 | /* | 178 | /* |
180 | * returns 0 if no resource available | 179 | * returns 0 if no resource available |
181 | */ | 180 | */ |
182 | static u32 cxio_hal_get_resource(struct kfifo *fifo) | 181 | static u32 cxio_hal_get_resource(struct kfifo *fifo, spinlock_t * lock) |
183 | { | 182 | { |
184 | u32 entry; | 183 | u32 entry; |
185 | if (kfifo_get(fifo, (unsigned char *) &entry, sizeof(u32))) | 184 | if (kfifo_out_locked(fifo, (unsigned char *) &entry, sizeof(u32), lock)) |
186 | return entry; | 185 | return entry; |
187 | else | 186 | else |
188 | return 0; /* fifo emptry */ | 187 | return 0; /* fifo emptry */ |
189 | } | 188 | } |
190 | 189 | ||
191 | static void cxio_hal_put_resource(struct kfifo *fifo, u32 entry) | 190 | static void cxio_hal_put_resource(struct kfifo *fifo, spinlock_t * lock, |
191 | u32 entry) | ||
192 | { | 192 | { |
193 | BUG_ON(kfifo_put(fifo, (unsigned char *) &entry, sizeof(u32)) == 0); | 193 | BUG_ON( |
194 | kfifo_in_locked(fifo, (unsigned char *) &entry, sizeof(u32), lock) | ||
195 | == 0); | ||
194 | } | 196 | } |
195 | 197 | ||
196 | u32 cxio_hal_get_stag(struct cxio_hal_resource *rscp) | 198 | u32 cxio_hal_get_stag(struct cxio_hal_resource *rscp) |
197 | { | 199 | { |
198 | return cxio_hal_get_resource(rscp->tpt_fifo); | 200 | return cxio_hal_get_resource(&rscp->tpt_fifo, &rscp->tpt_fifo_lock); |
199 | } | 201 | } |
200 | 202 | ||
201 | void cxio_hal_put_stag(struct cxio_hal_resource *rscp, u32 stag) | 203 | void cxio_hal_put_stag(struct cxio_hal_resource *rscp, u32 stag) |
202 | { | 204 | { |
203 | cxio_hal_put_resource(rscp->tpt_fifo, stag); | 205 | cxio_hal_put_resource(&rscp->tpt_fifo, &rscp->tpt_fifo_lock, stag); |
204 | } | 206 | } |
205 | 207 | ||
206 | u32 cxio_hal_get_qpid(struct cxio_hal_resource *rscp) | 208 | u32 cxio_hal_get_qpid(struct cxio_hal_resource *rscp) |
207 | { | 209 | { |
208 | u32 qpid = cxio_hal_get_resource(rscp->qpid_fifo); | 210 | u32 qpid = cxio_hal_get_resource(&rscp->qpid_fifo, |
211 | &rscp->qpid_fifo_lock); | ||
209 | PDBG("%s qpid 0x%x\n", __func__, qpid); | 212 | PDBG("%s qpid 0x%x\n", __func__, qpid); |
210 | return qpid; | 213 | return qpid; |
211 | } | 214 | } |
@@ -213,35 +216,35 @@ u32 cxio_hal_get_qpid(struct cxio_hal_resource *rscp) | |||
213 | void cxio_hal_put_qpid(struct cxio_hal_resource *rscp, u32 qpid) | 216 | void cxio_hal_put_qpid(struct cxio_hal_resource *rscp, u32 qpid) |
214 | { | 217 | { |
215 | PDBG("%s qpid 0x%x\n", __func__, qpid); | 218 | PDBG("%s qpid 0x%x\n", __func__, qpid); |
216 | cxio_hal_put_resource(rscp->qpid_fifo, qpid); | 219 | cxio_hal_put_resource(&rscp->qpid_fifo, &rscp->qpid_fifo_lock, qpid); |
217 | } | 220 | } |
218 | 221 | ||
219 | u32 cxio_hal_get_cqid(struct cxio_hal_resource *rscp) | 222 | u32 cxio_hal_get_cqid(struct cxio_hal_resource *rscp) |
220 | { | 223 | { |
221 | return cxio_hal_get_resource(rscp->cqid_fifo); | 224 | return cxio_hal_get_resource(&rscp->cqid_fifo, &rscp->cqid_fifo_lock); |
222 | } | 225 | } |
223 | 226 | ||
224 | void cxio_hal_put_cqid(struct cxio_hal_resource *rscp, u32 cqid) | 227 | void cxio_hal_put_cqid(struct cxio_hal_resource *rscp, u32 cqid) |
225 | { | 228 | { |
226 | cxio_hal_put_resource(rscp->cqid_fifo, cqid); | 229 | cxio_hal_put_resource(&rscp->cqid_fifo, &rscp->cqid_fifo_lock, cqid); |
227 | } | 230 | } |
228 | 231 | ||
229 | u32 cxio_hal_get_pdid(struct cxio_hal_resource *rscp) | 232 | u32 cxio_hal_get_pdid(struct cxio_hal_resource *rscp) |
230 | { | 233 | { |
231 | return cxio_hal_get_resource(rscp->pdid_fifo); | 234 | return cxio_hal_get_resource(&rscp->pdid_fifo, &rscp->pdid_fifo_lock); |
232 | } | 235 | } |
233 | 236 | ||
234 | void cxio_hal_put_pdid(struct cxio_hal_resource *rscp, u32 pdid) | 237 | void cxio_hal_put_pdid(struct cxio_hal_resource *rscp, u32 pdid) |
235 | { | 238 | { |
236 | cxio_hal_put_resource(rscp->pdid_fifo, pdid); | 239 | cxio_hal_put_resource(&rscp->pdid_fifo, &rscp->pdid_fifo_lock, pdid); |
237 | } | 240 | } |
238 | 241 | ||
239 | void cxio_hal_destroy_resource(struct cxio_hal_resource *rscp) | 242 | void cxio_hal_destroy_resource(struct cxio_hal_resource *rscp) |
240 | { | 243 | { |
241 | kfifo_free(rscp->tpt_fifo); | 244 | kfifo_free(&rscp->tpt_fifo); |
242 | kfifo_free(rscp->cqid_fifo); | 245 | kfifo_free(&rscp->cqid_fifo); |
243 | kfifo_free(rscp->qpid_fifo); | 246 | kfifo_free(&rscp->qpid_fifo); |
244 | kfifo_free(rscp->pdid_fifo); | 247 | kfifo_free(&rscp->pdid_fifo); |
245 | kfree(rscp); | 248 | kfree(rscp); |
246 | } | 249 | } |
247 | 250 | ||
diff --git a/drivers/isdn/mISDN/l1oip_core.c b/drivers/isdn/mISDN/l1oip_core.c index 7e5f30dbc0a0..f1e8af54dff0 100644 --- a/drivers/isdn/mISDN/l1oip_core.c +++ b/drivers/isdn/mISDN/l1oip_core.c | |||
@@ -661,7 +661,7 @@ l1oip_socket_thread(void *data) | |||
661 | size_t recvbuf_size = 1500; | 661 | size_t recvbuf_size = 1500; |
662 | int recvlen; | 662 | int recvlen; |
663 | struct socket *socket = NULL; | 663 | struct socket *socket = NULL; |
664 | DECLARE_COMPLETION(wait); | 664 | DECLARE_COMPLETION_ONSTACK(wait); |
665 | 665 | ||
666 | /* allocate buffer memory */ | 666 | /* allocate buffer memory */ |
667 | recvbuf = kmalloc(recvbuf_size, GFP_KERNEL); | 667 | recvbuf = kmalloc(recvbuf_size, GFP_KERNEL); |
diff --git a/drivers/md/md.c b/drivers/md/md.c index f4f5f82f9f53..dd3dfe42d5a9 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -386,7 +386,9 @@ static void mddev_put(mddev_t *mddev) | |||
386 | if (!atomic_dec_and_lock(&mddev->active, &all_mddevs_lock)) | 386 | if (!atomic_dec_and_lock(&mddev->active, &all_mddevs_lock)) |
387 | return; | 387 | return; |
388 | if (!mddev->raid_disks && list_empty(&mddev->disks) && | 388 | if (!mddev->raid_disks && list_empty(&mddev->disks) && |
389 | !mddev->hold_active) { | 389 | mddev->ctime == 0 && !mddev->hold_active) { |
390 | /* Array is not configured at all, and not held active, | ||
391 | * so destroy it */ | ||
390 | list_del(&mddev->all_mddevs); | 392 | list_del(&mddev->all_mddevs); |
391 | if (mddev->gendisk) { | 393 | if (mddev->gendisk) { |
392 | /* we did a probe so need to clean up. | 394 | /* we did a probe so need to clean up. |
@@ -4355,7 +4357,7 @@ static int do_md_run(mddev_t * mddev) | |||
4355 | mddev->barriers_work = 1; | 4357 | mddev->barriers_work = 1; |
4356 | mddev->ok_start_degraded = start_dirty_degraded; | 4358 | mddev->ok_start_degraded = start_dirty_degraded; |
4357 | 4359 | ||
4358 | if (start_readonly) | 4360 | if (start_readonly && mddev->ro == 0) |
4359 | mddev->ro = 2; /* read-only, but switch on first write */ | 4361 | mddev->ro = 2; /* read-only, but switch on first write */ |
4360 | 4362 | ||
4361 | err = mddev->pers->run(mddev); | 4363 | err = mddev->pers->run(mddev); |
@@ -4419,33 +4421,6 @@ static int do_md_run(mddev_t * mddev) | |||
4419 | 4421 | ||
4420 | set_capacity(disk, mddev->array_sectors); | 4422 | set_capacity(disk, mddev->array_sectors); |
4421 | 4423 | ||
4422 | /* If there is a partially-recovered drive we need to | ||
4423 | * start recovery here. If we leave it to md_check_recovery, | ||
4424 | * it will remove the drives and not do the right thing | ||
4425 | */ | ||
4426 | if (mddev->degraded && !mddev->sync_thread) { | ||
4427 | int spares = 0; | ||
4428 | list_for_each_entry(rdev, &mddev->disks, same_set) | ||
4429 | if (rdev->raid_disk >= 0 && | ||
4430 | !test_bit(In_sync, &rdev->flags) && | ||
4431 | !test_bit(Faulty, &rdev->flags)) | ||
4432 | /* complete an interrupted recovery */ | ||
4433 | spares++; | ||
4434 | if (spares && mddev->pers->sync_request) { | ||
4435 | mddev->recovery = 0; | ||
4436 | set_bit(MD_RECOVERY_RUNNING, &mddev->recovery); | ||
4437 | mddev->sync_thread = md_register_thread(md_do_sync, | ||
4438 | mddev, | ||
4439 | "resync"); | ||
4440 | if (!mddev->sync_thread) { | ||
4441 | printk(KERN_ERR "%s: could not start resync" | ||
4442 | " thread...\n", | ||
4443 | mdname(mddev)); | ||
4444 | /* leave the spares where they are, it shouldn't hurt */ | ||
4445 | mddev->recovery = 0; | ||
4446 | } | ||
4447 | } | ||
4448 | } | ||
4449 | md_wakeup_thread(mddev->thread); | 4424 | md_wakeup_thread(mddev->thread); |
4450 | md_wakeup_thread(mddev->sync_thread); /* possibly kick off a reshape */ | 4425 | md_wakeup_thread(mddev->sync_thread); /* possibly kick off a reshape */ |
4451 | 4426 | ||
@@ -5262,6 +5237,10 @@ static int set_array_info(mddev_t * mddev, mdu_array_info_t *info) | |||
5262 | mddev->minor_version = info->minor_version; | 5237 | mddev->minor_version = info->minor_version; |
5263 | mddev->patch_version = info->patch_version; | 5238 | mddev->patch_version = info->patch_version; |
5264 | mddev->persistent = !info->not_persistent; | 5239 | mddev->persistent = !info->not_persistent; |
5240 | /* ensure mddev_put doesn't delete this now that there | ||
5241 | * is some minimal configuration. | ||
5242 | */ | ||
5243 | mddev->ctime = get_seconds(); | ||
5265 | return 0; | 5244 | return 0; |
5266 | } | 5245 | } |
5267 | mddev->major_version = MD_MAJOR_VERSION; | 5246 | mddev->major_version = MD_MAJOR_VERSION; |
@@ -6494,10 +6473,11 @@ void md_do_sync(mddev_t *mddev) | |||
6494 | mddev->curr_resync = 2; | 6473 | mddev->curr_resync = 2; |
6495 | 6474 | ||
6496 | try_again: | 6475 | try_again: |
6497 | if (kthread_should_stop()) { | 6476 | if (kthread_should_stop()) |
6498 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); | 6477 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); |
6478 | |||
6479 | if (test_bit(MD_RECOVERY_INTR, &mddev->recovery)) | ||
6499 | goto skip; | 6480 | goto skip; |
6500 | } | ||
6501 | for_each_mddev(mddev2, tmp) { | 6481 | for_each_mddev(mddev2, tmp) { |
6502 | if (mddev2 == mddev) | 6482 | if (mddev2 == mddev) |
6503 | continue; | 6483 | continue; |
diff --git a/drivers/media/video/cx23885/cx23888-ir.c b/drivers/media/video/cx23885/cx23888-ir.c index 3ccc8afeccf3..2bf57a4527d3 100644 --- a/drivers/media/video/cx23885/cx23888-ir.c +++ b/drivers/media/video/cx23885/cx23888-ir.c | |||
@@ -124,15 +124,12 @@ struct cx23888_ir_state { | |||
124 | atomic_t rxclk_divider; | 124 | atomic_t rxclk_divider; |
125 | atomic_t rx_invert; | 125 | atomic_t rx_invert; |
126 | 126 | ||
127 | struct kfifo *rx_kfifo; | 127 | struct kfifo rx_kfifo; |
128 | spinlock_t rx_kfifo_lock; | 128 | spinlock_t rx_kfifo_lock; |
129 | 129 | ||
130 | struct v4l2_subdev_ir_parameters tx_params; | 130 | struct v4l2_subdev_ir_parameters tx_params; |
131 | struct mutex tx_params_lock; | 131 | struct mutex tx_params_lock; |
132 | atomic_t txclk_divider; | 132 | atomic_t txclk_divider; |
133 | |||
134 | struct kfifo *tx_kfifo; | ||
135 | spinlock_t tx_kfifo_lock; | ||
136 | }; | 133 | }; |
137 | 134 | ||
138 | static inline struct cx23888_ir_state *to_state(struct v4l2_subdev *sd) | 135 | static inline struct cx23888_ir_state *to_state(struct v4l2_subdev *sd) |
@@ -522,6 +519,7 @@ static int cx23888_ir_irq_handler(struct v4l2_subdev *sd, u32 status, | |||
522 | { | 519 | { |
523 | struct cx23888_ir_state *state = to_state(sd); | 520 | struct cx23888_ir_state *state = to_state(sd); |
524 | struct cx23885_dev *dev = state->dev; | 521 | struct cx23885_dev *dev = state->dev; |
522 | unsigned long flags; | ||
525 | 523 | ||
526 | u32 cntrl = cx23888_ir_read4(dev, CX23888_IR_CNTRL_REG); | 524 | u32 cntrl = cx23888_ir_read4(dev, CX23888_IR_CNTRL_REG); |
527 | u32 irqen = cx23888_ir_read4(dev, CX23888_IR_IRQEN_REG); | 525 | u32 irqen = cx23888_ir_read4(dev, CX23888_IR_IRQEN_REG); |
@@ -594,8 +592,9 @@ static int cx23888_ir_irq_handler(struct v4l2_subdev *sd, u32 status, | |||
594 | if (i == 0) | 592 | if (i == 0) |
595 | break; | 593 | break; |
596 | j = i * sizeof(u32); | 594 | j = i * sizeof(u32); |
597 | k = kfifo_put(state->rx_kfifo, | 595 | k = kfifo_in_locked(&state->rx_kfifo, |
598 | (unsigned char *) rx_data, j); | 596 | (unsigned char *) rx_data, j, |
597 | &state->rx_kfifo_lock); | ||
599 | if (k != j) | 598 | if (k != j) |
600 | kror++; /* rx_kfifo over run */ | 599 | kror++; /* rx_kfifo over run */ |
601 | } | 600 | } |
@@ -631,8 +630,11 @@ static int cx23888_ir_irq_handler(struct v4l2_subdev *sd, u32 status, | |||
631 | cx23888_ir_write4(dev, CX23888_IR_CNTRL_REG, cntrl); | 630 | cx23888_ir_write4(dev, CX23888_IR_CNTRL_REG, cntrl); |
632 | *handled = true; | 631 | *handled = true; |
633 | } | 632 | } |
634 | if (kfifo_len(state->rx_kfifo) >= CX23888_IR_RX_KFIFO_SIZE / 2) | 633 | |
634 | spin_lock_irqsave(&state->rx_kfifo_lock, flags); | ||
635 | if (kfifo_len(&state->rx_kfifo) >= CX23888_IR_RX_KFIFO_SIZE / 2) | ||
635 | events |= V4L2_SUBDEV_IR_RX_FIFO_SERVICE_REQ; | 636 | events |= V4L2_SUBDEV_IR_RX_FIFO_SERVICE_REQ; |
637 | spin_unlock_irqrestore(&state->rx_kfifo_lock, flags); | ||
636 | 638 | ||
637 | if (events) | 639 | if (events) |
638 | v4l2_subdev_notify(sd, V4L2_SUBDEV_IR_RX_NOTIFY, &events); | 640 | v4l2_subdev_notify(sd, V4L2_SUBDEV_IR_RX_NOTIFY, &events); |
@@ -657,7 +659,7 @@ static int cx23888_ir_rx_read(struct v4l2_subdev *sd, u8 *buf, size_t count, | |||
657 | return 0; | 659 | return 0; |
658 | } | 660 | } |
659 | 661 | ||
660 | n = kfifo_get(state->rx_kfifo, buf, n); | 662 | n = kfifo_out_locked(&state->rx_kfifo, buf, n, &state->rx_kfifo_lock); |
661 | 663 | ||
662 | n /= sizeof(u32); | 664 | n /= sizeof(u32); |
663 | *num = n * sizeof(u32); | 665 | *num = n * sizeof(u32); |
@@ -785,7 +787,12 @@ static int cx23888_ir_rx_s_parameters(struct v4l2_subdev *sd, | |||
785 | o->interrupt_enable = p->interrupt_enable; | 787 | o->interrupt_enable = p->interrupt_enable; |
786 | o->enable = p->enable; | 788 | o->enable = p->enable; |
787 | if (p->enable) { | 789 | if (p->enable) { |
788 | kfifo_reset(state->rx_kfifo); | 790 | unsigned long flags; |
791 | |||
792 | spin_lock_irqsave(&state->rx_kfifo_lock, flags); | ||
793 | kfifo_reset(&state->rx_kfifo); | ||
794 | /* reset tx_fifo too if there is one... */ | ||
795 | spin_unlock_irqrestore(&state->rx_kfifo_lock, flags); | ||
789 | if (p->interrupt_enable) | 796 | if (p->interrupt_enable) |
790 | irqenable_rx(dev, IRQEN_RSE | IRQEN_RTE | IRQEN_ROE); | 797 | irqenable_rx(dev, IRQEN_RSE | IRQEN_RTE | IRQEN_ROE); |
791 | control_rx_enable(dev, p->enable); | 798 | control_rx_enable(dev, p->enable); |
@@ -892,7 +899,6 @@ static int cx23888_ir_tx_s_parameters(struct v4l2_subdev *sd, | |||
892 | o->interrupt_enable = p->interrupt_enable; | 899 | o->interrupt_enable = p->interrupt_enable; |
893 | o->enable = p->enable; | 900 | o->enable = p->enable; |
894 | if (p->enable) { | 901 | if (p->enable) { |
895 | kfifo_reset(state->tx_kfifo); | ||
896 | if (p->interrupt_enable) | 902 | if (p->interrupt_enable) |
897 | irqenable_tx(dev, IRQEN_TSE); | 903 | irqenable_tx(dev, IRQEN_TSE); |
898 | control_tx_enable(dev, p->enable); | 904 | control_tx_enable(dev, p->enable); |
@@ -1168,18 +1174,8 @@ int cx23888_ir_probe(struct cx23885_dev *dev) | |||
1168 | return -ENOMEM; | 1174 | return -ENOMEM; |
1169 | 1175 | ||
1170 | spin_lock_init(&state->rx_kfifo_lock); | 1176 | spin_lock_init(&state->rx_kfifo_lock); |
1171 | state->rx_kfifo = kfifo_alloc(CX23888_IR_RX_KFIFO_SIZE, GFP_KERNEL, | 1177 | if (kfifo_alloc(&state->rx_kfifo, CX23888_IR_RX_KFIFO_SIZE, GFP_KERNEL)) |
1172 | &state->rx_kfifo_lock); | ||
1173 | if (state->rx_kfifo == NULL) | ||
1174 | return -ENOMEM; | ||
1175 | |||
1176 | spin_lock_init(&state->tx_kfifo_lock); | ||
1177 | state->tx_kfifo = kfifo_alloc(CX23888_IR_TX_KFIFO_SIZE, GFP_KERNEL, | ||
1178 | &state->tx_kfifo_lock); | ||
1179 | if (state->tx_kfifo == NULL) { | ||
1180 | kfifo_free(state->rx_kfifo); | ||
1181 | return -ENOMEM; | 1178 | return -ENOMEM; |
1182 | } | ||
1183 | 1179 | ||
1184 | state->dev = dev; | 1180 | state->dev = dev; |
1185 | state->id = V4L2_IDENT_CX23888_IR; | 1181 | state->id = V4L2_IDENT_CX23888_IR; |
@@ -1211,8 +1207,7 @@ int cx23888_ir_probe(struct cx23885_dev *dev) | |||
1211 | sizeof(struct v4l2_subdev_ir_parameters)); | 1207 | sizeof(struct v4l2_subdev_ir_parameters)); |
1212 | v4l2_subdev_call(sd, ir, tx_s_parameters, &default_params); | 1208 | v4l2_subdev_call(sd, ir, tx_s_parameters, &default_params); |
1213 | } else { | 1209 | } else { |
1214 | kfifo_free(state->rx_kfifo); | 1210 | kfifo_free(&state->rx_kfifo); |
1215 | kfifo_free(state->tx_kfifo); | ||
1216 | } | 1211 | } |
1217 | return ret; | 1212 | return ret; |
1218 | } | 1213 | } |
@@ -1231,8 +1226,7 @@ int cx23888_ir_remove(struct cx23885_dev *dev) | |||
1231 | 1226 | ||
1232 | state = to_state(sd); | 1227 | state = to_state(sd); |
1233 | v4l2_device_unregister_subdev(sd); | 1228 | v4l2_device_unregister_subdev(sd); |
1234 | kfifo_free(state->rx_kfifo); | 1229 | kfifo_free(&state->rx_kfifo); |
1235 | kfifo_free(state->tx_kfifo); | ||
1236 | kfree(state); | 1230 | kfree(state); |
1237 | /* Nothing more to free() as state held the actual v4l2_subdev object */ | 1231 | /* Nothing more to free() as state held the actual v4l2_subdev object */ |
1238 | return 0; | 1232 | return 0; |
diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c index 6ffa64cd1c6d..b421858ccf90 100644 --- a/drivers/media/video/meye.c +++ b/drivers/media/video/meye.c | |||
@@ -800,8 +800,8 @@ again: | |||
800 | return IRQ_HANDLED; | 800 | return IRQ_HANDLED; |
801 | 801 | ||
802 | if (meye.mchip_mode == MCHIP_HIC_MODE_CONT_OUT) { | 802 | if (meye.mchip_mode == MCHIP_HIC_MODE_CONT_OUT) { |
803 | if (kfifo_get(meye.grabq, (unsigned char *)&reqnr, | 803 | if (kfifo_out_locked(&meye.grabq, (unsigned char *)&reqnr, |
804 | sizeof(int)) != sizeof(int)) { | 804 | sizeof(int), &meye.grabq_lock) != sizeof(int)) { |
805 | mchip_free_frame(); | 805 | mchip_free_frame(); |
806 | return IRQ_HANDLED; | 806 | return IRQ_HANDLED; |
807 | } | 807 | } |
@@ -811,7 +811,8 @@ again: | |||
811 | meye.grab_buffer[reqnr].state = MEYE_BUF_DONE; | 811 | meye.grab_buffer[reqnr].state = MEYE_BUF_DONE; |
812 | do_gettimeofday(&meye.grab_buffer[reqnr].timestamp); | 812 | do_gettimeofday(&meye.grab_buffer[reqnr].timestamp); |
813 | meye.grab_buffer[reqnr].sequence = sequence++; | 813 | meye.grab_buffer[reqnr].sequence = sequence++; |
814 | kfifo_put(meye.doneq, (unsigned char *)&reqnr, sizeof(int)); | 814 | kfifo_in_locked(&meye.doneq, (unsigned char *)&reqnr, |
815 | sizeof(int), &meye.doneq_lock); | ||
815 | wake_up_interruptible(&meye.proc_list); | 816 | wake_up_interruptible(&meye.proc_list); |
816 | } else { | 817 | } else { |
817 | int size; | 818 | int size; |
@@ -820,8 +821,8 @@ again: | |||
820 | mchip_free_frame(); | 821 | mchip_free_frame(); |
821 | goto again; | 822 | goto again; |
822 | } | 823 | } |
823 | if (kfifo_get(meye.grabq, (unsigned char *)&reqnr, | 824 | if (kfifo_out_locked(&meye.grabq, (unsigned char *)&reqnr, |
824 | sizeof(int)) != sizeof(int)) { | 825 | sizeof(int), &meye.grabq_lock) != sizeof(int)) { |
825 | mchip_free_frame(); | 826 | mchip_free_frame(); |
826 | goto again; | 827 | goto again; |
827 | } | 828 | } |
@@ -831,7 +832,8 @@ again: | |||
831 | meye.grab_buffer[reqnr].state = MEYE_BUF_DONE; | 832 | meye.grab_buffer[reqnr].state = MEYE_BUF_DONE; |
832 | do_gettimeofday(&meye.grab_buffer[reqnr].timestamp); | 833 | do_gettimeofday(&meye.grab_buffer[reqnr].timestamp); |
833 | meye.grab_buffer[reqnr].sequence = sequence++; | 834 | meye.grab_buffer[reqnr].sequence = sequence++; |
834 | kfifo_put(meye.doneq, (unsigned char *)&reqnr, sizeof(int)); | 835 | kfifo_in_locked(&meye.doneq, (unsigned char *)&reqnr, |
836 | sizeof(int), &meye.doneq_lock); | ||
835 | wake_up_interruptible(&meye.proc_list); | 837 | wake_up_interruptible(&meye.proc_list); |
836 | } | 838 | } |
837 | mchip_free_frame(); | 839 | mchip_free_frame(); |
@@ -859,8 +861,8 @@ static int meye_open(struct file *file) | |||
859 | 861 | ||
860 | for (i = 0; i < MEYE_MAX_BUFNBRS; i++) | 862 | for (i = 0; i < MEYE_MAX_BUFNBRS; i++) |
861 | meye.grab_buffer[i].state = MEYE_BUF_UNUSED; | 863 | meye.grab_buffer[i].state = MEYE_BUF_UNUSED; |
862 | kfifo_reset(meye.grabq); | 864 | kfifo_reset(&meye.grabq); |
863 | kfifo_reset(meye.doneq); | 865 | kfifo_reset(&meye.doneq); |
864 | return 0; | 866 | return 0; |
865 | } | 867 | } |
866 | 868 | ||
@@ -933,7 +935,8 @@ static int meyeioc_qbuf_capt(int *nb) | |||
933 | mchip_cont_compression_start(); | 935 | mchip_cont_compression_start(); |
934 | 936 | ||
935 | meye.grab_buffer[*nb].state = MEYE_BUF_USING; | 937 | meye.grab_buffer[*nb].state = MEYE_BUF_USING; |
936 | kfifo_put(meye.grabq, (unsigned char *)nb, sizeof(int)); | 938 | kfifo_in_locked(&meye.grabq, (unsigned char *)nb, sizeof(int), |
939 | &meye.grabq_lock); | ||
937 | mutex_unlock(&meye.lock); | 940 | mutex_unlock(&meye.lock); |
938 | 941 | ||
939 | return 0; | 942 | return 0; |
@@ -965,7 +968,9 @@ static int meyeioc_sync(struct file *file, void *fh, int *i) | |||
965 | /* fall through */ | 968 | /* fall through */ |
966 | case MEYE_BUF_DONE: | 969 | case MEYE_BUF_DONE: |
967 | meye.grab_buffer[*i].state = MEYE_BUF_UNUSED; | 970 | meye.grab_buffer[*i].state = MEYE_BUF_UNUSED; |
968 | kfifo_get(meye.doneq, (unsigned char *)&unused, sizeof(int)); | 971 | if (kfifo_out_locked(&meye.doneq, (unsigned char *)&unused, |
972 | sizeof(int), &meye.doneq_lock) != sizeof(int)) | ||
973 | break; | ||
969 | } | 974 | } |
970 | *i = meye.grab_buffer[*i].size; | 975 | *i = meye.grab_buffer[*i].size; |
971 | mutex_unlock(&meye.lock); | 976 | mutex_unlock(&meye.lock); |
@@ -1452,7 +1457,8 @@ static int vidioc_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf) | |||
1452 | buf->flags |= V4L2_BUF_FLAG_QUEUED; | 1457 | buf->flags |= V4L2_BUF_FLAG_QUEUED; |
1453 | buf->flags &= ~V4L2_BUF_FLAG_DONE; | 1458 | buf->flags &= ~V4L2_BUF_FLAG_DONE; |
1454 | meye.grab_buffer[buf->index].state = MEYE_BUF_USING; | 1459 | meye.grab_buffer[buf->index].state = MEYE_BUF_USING; |
1455 | kfifo_put(meye.grabq, (unsigned char *)&buf->index, sizeof(int)); | 1460 | kfifo_in_locked(&meye.grabq, (unsigned char *)&buf->index, |
1461 | sizeof(int), &meye.grabq_lock); | ||
1456 | mutex_unlock(&meye.lock); | 1462 | mutex_unlock(&meye.lock); |
1457 | 1463 | ||
1458 | return 0; | 1464 | return 0; |
@@ -1467,19 +1473,19 @@ static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf) | |||
1467 | 1473 | ||
1468 | mutex_lock(&meye.lock); | 1474 | mutex_lock(&meye.lock); |
1469 | 1475 | ||
1470 | if (kfifo_len(meye.doneq) == 0 && file->f_flags & O_NONBLOCK) { | 1476 | if (kfifo_len(&meye.doneq) == 0 && file->f_flags & O_NONBLOCK) { |
1471 | mutex_unlock(&meye.lock); | 1477 | mutex_unlock(&meye.lock); |
1472 | return -EAGAIN; | 1478 | return -EAGAIN; |
1473 | } | 1479 | } |
1474 | 1480 | ||
1475 | if (wait_event_interruptible(meye.proc_list, | 1481 | if (wait_event_interruptible(meye.proc_list, |
1476 | kfifo_len(meye.doneq) != 0) < 0) { | 1482 | kfifo_len(&meye.doneq) != 0) < 0) { |
1477 | mutex_unlock(&meye.lock); | 1483 | mutex_unlock(&meye.lock); |
1478 | return -EINTR; | 1484 | return -EINTR; |
1479 | } | 1485 | } |
1480 | 1486 | ||
1481 | if (!kfifo_get(meye.doneq, (unsigned char *)&reqnr, | 1487 | if (!kfifo_out_locked(&meye.doneq, (unsigned char *)&reqnr, |
1482 | sizeof(int))) { | 1488 | sizeof(int), &meye.doneq_lock)) { |
1483 | mutex_unlock(&meye.lock); | 1489 | mutex_unlock(&meye.lock); |
1484 | return -EBUSY; | 1490 | return -EBUSY; |
1485 | } | 1491 | } |
@@ -1529,8 +1535,8 @@ static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i) | |||
1529 | { | 1535 | { |
1530 | mutex_lock(&meye.lock); | 1536 | mutex_lock(&meye.lock); |
1531 | mchip_hic_stop(); | 1537 | mchip_hic_stop(); |
1532 | kfifo_reset(meye.grabq); | 1538 | kfifo_reset(&meye.grabq); |
1533 | kfifo_reset(meye.doneq); | 1539 | kfifo_reset(&meye.doneq); |
1534 | 1540 | ||
1535 | for (i = 0; i < MEYE_MAX_BUFNBRS; i++) | 1541 | for (i = 0; i < MEYE_MAX_BUFNBRS; i++) |
1536 | meye.grab_buffer[i].state = MEYE_BUF_UNUSED; | 1542 | meye.grab_buffer[i].state = MEYE_BUF_UNUSED; |
@@ -1572,7 +1578,7 @@ static unsigned int meye_poll(struct file *file, poll_table *wait) | |||
1572 | 1578 | ||
1573 | mutex_lock(&meye.lock); | 1579 | mutex_lock(&meye.lock); |
1574 | poll_wait(file, &meye.proc_list, wait); | 1580 | poll_wait(file, &meye.proc_list, wait); |
1575 | if (kfifo_len(meye.doneq)) | 1581 | if (kfifo_len(&meye.doneq)) |
1576 | res = POLLIN | POLLRDNORM; | 1582 | res = POLLIN | POLLRDNORM; |
1577 | mutex_unlock(&meye.lock); | 1583 | mutex_unlock(&meye.lock); |
1578 | return res; | 1584 | return res; |
@@ -1745,16 +1751,14 @@ static int __devinit meye_probe(struct pci_dev *pcidev, | |||
1745 | } | 1751 | } |
1746 | 1752 | ||
1747 | spin_lock_init(&meye.grabq_lock); | 1753 | spin_lock_init(&meye.grabq_lock); |
1748 | meye.grabq = kfifo_alloc(sizeof(int) * MEYE_MAX_BUFNBRS, GFP_KERNEL, | 1754 | if (kfifo_alloc(&meye.grabq, sizeof(int) * MEYE_MAX_BUFNBRS, |
1749 | &meye.grabq_lock); | 1755 | GFP_KERNEL)) { |
1750 | if (IS_ERR(meye.grabq)) { | ||
1751 | printk(KERN_ERR "meye: fifo allocation failed\n"); | 1756 | printk(KERN_ERR "meye: fifo allocation failed\n"); |
1752 | goto outkfifoalloc1; | 1757 | goto outkfifoalloc1; |
1753 | } | 1758 | } |
1754 | spin_lock_init(&meye.doneq_lock); | 1759 | spin_lock_init(&meye.doneq_lock); |
1755 | meye.doneq = kfifo_alloc(sizeof(int) * MEYE_MAX_BUFNBRS, GFP_KERNEL, | 1760 | if (kfifo_alloc(&meye.doneq, sizeof(int) * MEYE_MAX_BUFNBRS, |
1756 | &meye.doneq_lock); | 1761 | GFP_KERNEL)) { |
1757 | if (IS_ERR(meye.doneq)) { | ||
1758 | printk(KERN_ERR "meye: fifo allocation failed\n"); | 1762 | printk(KERN_ERR "meye: fifo allocation failed\n"); |
1759 | goto outkfifoalloc2; | 1763 | goto outkfifoalloc2; |
1760 | } | 1764 | } |
@@ -1868,9 +1872,9 @@ outregions: | |||
1868 | outenabledev: | 1872 | outenabledev: |
1869 | sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERA, 0); | 1873 | sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERA, 0); |
1870 | outsonypienable: | 1874 | outsonypienable: |
1871 | kfifo_free(meye.doneq); | 1875 | kfifo_free(&meye.doneq); |
1872 | outkfifoalloc2: | 1876 | outkfifoalloc2: |
1873 | kfifo_free(meye.grabq); | 1877 | kfifo_free(&meye.grabq); |
1874 | outkfifoalloc1: | 1878 | outkfifoalloc1: |
1875 | vfree(meye.grab_temp); | 1879 | vfree(meye.grab_temp); |
1876 | outvmalloc: | 1880 | outvmalloc: |
@@ -1901,8 +1905,8 @@ static void __devexit meye_remove(struct pci_dev *pcidev) | |||
1901 | 1905 | ||
1902 | sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERA, 0); | 1906 | sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERA, 0); |
1903 | 1907 | ||
1904 | kfifo_free(meye.doneq); | 1908 | kfifo_free(&meye.doneq); |
1905 | kfifo_free(meye.grabq); | 1909 | kfifo_free(&meye.grabq); |
1906 | 1910 | ||
1907 | vfree(meye.grab_temp); | 1911 | vfree(meye.grab_temp); |
1908 | 1912 | ||
diff --git a/drivers/media/video/meye.h b/drivers/media/video/meye.h index 5f70a106ba2b..1321ad5d6597 100644 --- a/drivers/media/video/meye.h +++ b/drivers/media/video/meye.h | |||
@@ -303,9 +303,9 @@ struct meye { | |||
303 | struct meye_grab_buffer grab_buffer[MEYE_MAX_BUFNBRS]; | 303 | struct meye_grab_buffer grab_buffer[MEYE_MAX_BUFNBRS]; |
304 | int vma_use_count[MEYE_MAX_BUFNBRS]; /* mmap count */ | 304 | int vma_use_count[MEYE_MAX_BUFNBRS]; /* mmap count */ |
305 | struct mutex lock; /* mutex for open/mmap... */ | 305 | struct mutex lock; /* mutex for open/mmap... */ |
306 | struct kfifo *grabq; /* queue for buffers to be grabbed */ | 306 | struct kfifo grabq; /* queue for buffers to be grabbed */ |
307 | spinlock_t grabq_lock; /* lock protecting the queue */ | 307 | spinlock_t grabq_lock; /* lock protecting the queue */ |
308 | struct kfifo *doneq; /* queue for grabbed buffers */ | 308 | struct kfifo doneq; /* queue for grabbed buffers */ |
309 | spinlock_t doneq_lock; /* lock protecting the queue */ | 309 | spinlock_t doneq_lock; /* lock protecting the queue */ |
310 | wait_queue_head_t proc_list; /* wait queue */ | 310 | wait_queue_head_t proc_list; /* wait queue */ |
311 | struct video_device *video_dev; /* video device parameters */ | 311 | struct video_device *video_dev; /* video device parameters */ |
diff --git a/drivers/net/3c507.c b/drivers/net/3c507.c index fbc231153e55..77cf0901a441 100644 --- a/drivers/net/3c507.c +++ b/drivers/net/3c507.c | |||
@@ -56,6 +56,7 @@ static const char version[] = | |||
56 | #include <linux/errno.h> | 56 | #include <linux/errno.h> |
57 | #include <linux/netdevice.h> | 57 | #include <linux/netdevice.h> |
58 | #include <linux/etherdevice.h> | 58 | #include <linux/etherdevice.h> |
59 | #include <linux/if_ether.h> | ||
59 | #include <linux/skbuff.h> | 60 | #include <linux/skbuff.h> |
60 | #include <linux/slab.h> | 61 | #include <linux/slab.h> |
61 | #include <linux/init.h> | 62 | #include <linux/init.h> |
@@ -734,8 +735,7 @@ static void init_82586_mem(struct net_device *dev) | |||
734 | memcpy_toio(lp->base, init_words + 5, sizeof(init_words) - 10); | 735 | memcpy_toio(lp->base, init_words + 5, sizeof(init_words) - 10); |
735 | 736 | ||
736 | /* Fill in the station address. */ | 737 | /* Fill in the station address. */ |
737 | memcpy_toio(lp->base+SA_OFFSET, dev->dev_addr, | 738 | memcpy_toio(lp->base+SA_OFFSET, dev->dev_addr, ETH_ALEN); |
738 | sizeof(dev->dev_addr)); | ||
739 | 739 | ||
740 | /* The Tx-block list is written as needed. We just set up the values. */ | 740 | /* The Tx-block list is written as needed. We just set up the values. */ |
741 | lp->tx_cmd_link = IDLELOOP + 4; | 741 | lp->tx_cmd_link = IDLELOOP + 4; |
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index e58a65391ad2..dd9a09c72dff 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
@@ -2346,6 +2346,7 @@ config GELIC_NET | |||
2346 | 2346 | ||
2347 | config GELIC_WIRELESS | 2347 | config GELIC_WIRELESS |
2348 | bool "PS3 Wireless support" | 2348 | bool "PS3 Wireless support" |
2349 | depends on WLAN | ||
2349 | depends on GELIC_NET | 2350 | depends on GELIC_NET |
2350 | select WIRELESS_EXT | 2351 | select WIRELESS_EXT |
2351 | help | 2352 | help |
@@ -2358,6 +2359,7 @@ config GELIC_WIRELESS | |||
2358 | config GELIC_WIRELESS_OLD_PSK_INTERFACE | 2359 | config GELIC_WIRELESS_OLD_PSK_INTERFACE |
2359 | bool "PS3 Wireless private PSK interface (OBSOLETE)" | 2360 | bool "PS3 Wireless private PSK interface (OBSOLETE)" |
2360 | depends on GELIC_WIRELESS | 2361 | depends on GELIC_WIRELESS |
2362 | select WEXT_PRIV | ||
2361 | help | 2363 | help |
2362 | This option retains the obsolete private interface to pass | 2364 | This option retains the obsolete private interface to pass |
2363 | the PSK from user space programs to the driver. The PSK | 2365 | the PSK from user space programs to the driver. The PSK |
diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index 9e56014d27ed..9fd8e5ecd5d7 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h | |||
@@ -275,6 +275,7 @@ struct be_adapter { | |||
275 | u32 tx_fc; /* Tx flow control */ | 275 | u32 tx_fc; /* Tx flow control */ |
276 | int link_speed; | 276 | int link_speed; |
277 | u8 port_type; | 277 | u8 port_type; |
278 | u8 transceiver; | ||
278 | }; | 279 | }; |
279 | 280 | ||
280 | extern const struct ethtool_ops be_ethtool_ops; | 281 | extern const struct ethtool_ops be_ethtool_ops; |
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index 1b68bd98dc0c..102ade134165 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c | |||
@@ -1479,6 +1479,41 @@ err: | |||
1479 | return status; | 1479 | return status; |
1480 | } | 1480 | } |
1481 | 1481 | ||
1482 | int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num, | ||
1483 | u8 loopback_type, u8 enable) | ||
1484 | { | ||
1485 | struct be_mcc_wrb *wrb; | ||
1486 | struct be_cmd_req_set_lmode *req; | ||
1487 | int status; | ||
1488 | |||
1489 | spin_lock_bh(&adapter->mcc_lock); | ||
1490 | |||
1491 | wrb = wrb_from_mccq(adapter); | ||
1492 | if (!wrb) { | ||
1493 | status = -EBUSY; | ||
1494 | goto err; | ||
1495 | } | ||
1496 | |||
1497 | req = embedded_payload(wrb); | ||
1498 | |||
1499 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0, | ||
1500 | OPCODE_LOWLEVEL_SET_LOOPBACK_MODE); | ||
1501 | |||
1502 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_LOWLEVEL, | ||
1503 | OPCODE_LOWLEVEL_SET_LOOPBACK_MODE, | ||
1504 | sizeof(*req)); | ||
1505 | |||
1506 | req->src_port = port_num; | ||
1507 | req->dest_port = port_num; | ||
1508 | req->loopback_type = loopback_type; | ||
1509 | req->loopback_state = enable; | ||
1510 | |||
1511 | status = be_mcc_notify_wait(adapter); | ||
1512 | err: | ||
1513 | spin_unlock_bh(&adapter->mcc_lock); | ||
1514 | return status; | ||
1515 | } | ||
1516 | |||
1482 | int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num, | 1517 | int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num, |
1483 | u32 loopback_type, u32 pkt_size, u32 num_pkts, u64 pattern) | 1518 | u32 loopback_type, u32 pkt_size, u32 num_pkts, u64 pattern) |
1484 | { | 1519 | { |
@@ -1501,6 +1536,7 @@ int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num, | |||
1501 | 1536 | ||
1502 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_LOWLEVEL, | 1537 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_LOWLEVEL, |
1503 | OPCODE_LOWLEVEL_LOOPBACK_TEST, sizeof(*req)); | 1538 | OPCODE_LOWLEVEL_LOOPBACK_TEST, sizeof(*req)); |
1539 | req->hdr.timeout = 4; | ||
1504 | 1540 | ||
1505 | req->pattern = cpu_to_le64(pattern); | 1541 | req->pattern = cpu_to_le64(pattern); |
1506 | req->src_port = cpu_to_le32(port_num); | 1542 | req->src_port = cpu_to_le32(port_num); |
diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h index 92b87ef156ed..c002b8391b4d 100644 --- a/drivers/net/benet/be_cmds.h +++ b/drivers/net/benet/be_cmds.h | |||
@@ -155,6 +155,7 @@ struct be_mcc_mailbox { | |||
155 | 155 | ||
156 | #define OPCODE_LOWLEVEL_HOST_DDR_DMA 17 | 156 | #define OPCODE_LOWLEVEL_HOST_DDR_DMA 17 |
157 | #define OPCODE_LOWLEVEL_LOOPBACK_TEST 18 | 157 | #define OPCODE_LOWLEVEL_LOOPBACK_TEST 18 |
158 | #define OPCODE_LOWLEVEL_SET_LOOPBACK_MODE 19 | ||
158 | 159 | ||
159 | struct be_cmd_req_hdr { | 160 | struct be_cmd_req_hdr { |
160 | u8 opcode; /* dword 0 */ | 161 | u8 opcode; /* dword 0 */ |
@@ -821,6 +822,19 @@ struct be_cmd_resp_loopback_test { | |||
821 | u32 ticks_compl; | 822 | u32 ticks_compl; |
822 | }; | 823 | }; |
823 | 824 | ||
825 | struct be_cmd_req_set_lmode { | ||
826 | struct be_cmd_req_hdr hdr; | ||
827 | u8 src_port; | ||
828 | u8 dest_port; | ||
829 | u8 loopback_type; | ||
830 | u8 loopback_state; | ||
831 | }; | ||
832 | |||
833 | struct be_cmd_resp_set_lmode { | ||
834 | struct be_cmd_resp_hdr resp_hdr; | ||
835 | u8 rsvd0[4]; | ||
836 | }; | ||
837 | |||
824 | /********************** DDR DMA test *********************/ | 838 | /********************** DDR DMA test *********************/ |
825 | struct be_cmd_req_ddrdma_test { | 839 | struct be_cmd_req_ddrdma_test { |
826 | struct be_cmd_req_hdr hdr; | 840 | struct be_cmd_req_hdr hdr; |
@@ -912,3 +926,5 @@ extern int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num, | |||
912 | u32 num_pkts, u64 pattern); | 926 | u32 num_pkts, u64 pattern); |
913 | extern int be_cmd_ddr_dma_test(struct be_adapter *adapter, u64 pattern, | 927 | extern int be_cmd_ddr_dma_test(struct be_adapter *adapter, u64 pattern, |
914 | u32 byte_cnt, struct be_dma_mem *cmd); | 928 | u32 byte_cnt, struct be_dma_mem *cmd); |
929 | extern int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num, | ||
930 | u8 loopback_type, u8 enable); | ||
diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c index 298b92cbd689..5d001c4deac1 100644 --- a/drivers/net/benet/be_ethtool.c +++ b/drivers/net/benet/be_ethtool.c | |||
@@ -118,6 +118,7 @@ static const char et_self_tests[][ETH_GSTRING_LEN] = { | |||
118 | #define BE_MAC_LOOPBACK 0x0 | 118 | #define BE_MAC_LOOPBACK 0x0 |
119 | #define BE_PHY_LOOPBACK 0x1 | 119 | #define BE_PHY_LOOPBACK 0x1 |
120 | #define BE_ONE_PORT_EXT_LOOPBACK 0x2 | 120 | #define BE_ONE_PORT_EXT_LOOPBACK 0x2 |
121 | #define BE_NO_LOOPBACK 0xff | ||
121 | 122 | ||
122 | static void | 123 | static void |
123 | be_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo) | 124 | be_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo) |
@@ -339,28 +340,50 @@ static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) | |||
339 | 340 | ||
340 | status = be_cmd_read_port_type(adapter, adapter->port_num, | 341 | status = be_cmd_read_port_type(adapter, adapter->port_num, |
341 | &connector); | 342 | &connector); |
342 | switch (connector) { | 343 | if (!status) { |
343 | case 7: | 344 | switch (connector) { |
344 | ecmd->port = PORT_FIBRE; | 345 | case 7: |
345 | break; | 346 | ecmd->port = PORT_FIBRE; |
346 | default: | 347 | ecmd->transceiver = XCVR_EXTERNAL; |
347 | ecmd->port = PORT_TP; | 348 | break; |
348 | break; | 349 | case 0: |
350 | ecmd->port = PORT_TP; | ||
351 | ecmd->transceiver = XCVR_EXTERNAL; | ||
352 | break; | ||
353 | default: | ||
354 | ecmd->port = PORT_TP; | ||
355 | ecmd->transceiver = XCVR_INTERNAL; | ||
356 | break; | ||
357 | } | ||
358 | } else { | ||
359 | ecmd->port = PORT_AUI; | ||
360 | ecmd->transceiver = XCVR_INTERNAL; | ||
349 | } | 361 | } |
350 | 362 | ||
351 | /* Save for future use */ | 363 | /* Save for future use */ |
352 | adapter->link_speed = ecmd->speed; | 364 | adapter->link_speed = ecmd->speed; |
353 | adapter->port_type = ecmd->port; | 365 | adapter->port_type = ecmd->port; |
366 | adapter->transceiver = ecmd->transceiver; | ||
354 | } else { | 367 | } else { |
355 | ecmd->speed = adapter->link_speed; | 368 | ecmd->speed = adapter->link_speed; |
356 | ecmd->port = adapter->port_type; | 369 | ecmd->port = adapter->port_type; |
370 | ecmd->transceiver = adapter->transceiver; | ||
357 | } | 371 | } |
358 | 372 | ||
359 | ecmd->duplex = DUPLEX_FULL; | 373 | ecmd->duplex = DUPLEX_FULL; |
360 | ecmd->autoneg = AUTONEG_DISABLE; | 374 | ecmd->autoneg = AUTONEG_DISABLE; |
361 | ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_TP); | ||
362 | ecmd->phy_address = adapter->port_num; | 375 | ecmd->phy_address = adapter->port_num; |
363 | ecmd->transceiver = XCVR_INTERNAL; | 376 | switch (ecmd->port) { |
377 | case PORT_FIBRE: | ||
378 | ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE); | ||
379 | break; | ||
380 | case PORT_TP: | ||
381 | ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_TP); | ||
382 | break; | ||
383 | case PORT_AUI: | ||
384 | ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_AUI); | ||
385 | break; | ||
386 | } | ||
364 | 387 | ||
365 | return 0; | 388 | return 0; |
366 | } | 389 | } |
@@ -489,6 +512,19 @@ err: | |||
489 | return ret; | 512 | return ret; |
490 | } | 513 | } |
491 | 514 | ||
515 | static u64 be_loopback_test(struct be_adapter *adapter, u8 loopback_type, | ||
516 | u64 *status) | ||
517 | { | ||
518 | be_cmd_set_loopback(adapter, adapter->port_num, | ||
519 | loopback_type, 1); | ||
520 | *status = be_cmd_loopback_test(adapter, adapter->port_num, | ||
521 | loopback_type, 1500, | ||
522 | 2, 0xabc); | ||
523 | be_cmd_set_loopback(adapter, adapter->port_num, | ||
524 | BE_NO_LOOPBACK, 1); | ||
525 | return *status; | ||
526 | } | ||
527 | |||
492 | static void | 528 | static void |
493 | be_self_test(struct net_device *netdev, struct ethtool_test *test, u64 *data) | 529 | be_self_test(struct net_device *netdev, struct ethtool_test *test, u64 *data) |
494 | { | 530 | { |
@@ -497,23 +533,18 @@ be_self_test(struct net_device *netdev, struct ethtool_test *test, u64 *data) | |||
497 | memset(data, 0, sizeof(u64) * ETHTOOL_TESTS_NUM); | 533 | memset(data, 0, sizeof(u64) * ETHTOOL_TESTS_NUM); |
498 | 534 | ||
499 | if (test->flags & ETH_TEST_FL_OFFLINE) { | 535 | if (test->flags & ETH_TEST_FL_OFFLINE) { |
500 | data[0] = be_cmd_loopback_test(adapter, adapter->port_num, | 536 | if (be_loopback_test(adapter, BE_MAC_LOOPBACK, |
501 | BE_MAC_LOOPBACK, 1500, | 537 | &data[0]) != 0) { |
502 | 2, 0xabc); | ||
503 | if (data[0] != 0) | ||
504 | test->flags |= ETH_TEST_FL_FAILED; | 538 | test->flags |= ETH_TEST_FL_FAILED; |
505 | 539 | } | |
506 | data[1] = be_cmd_loopback_test(adapter, adapter->port_num, | 540 | if (be_loopback_test(adapter, BE_PHY_LOOPBACK, |
507 | BE_PHY_LOOPBACK, 1500, | 541 | &data[1]) != 0) { |
508 | 2, 0xabc); | ||
509 | if (data[1] != 0) | ||
510 | test->flags |= ETH_TEST_FL_FAILED; | 542 | test->flags |= ETH_TEST_FL_FAILED; |
511 | 543 | } | |
512 | data[2] = be_cmd_loopback_test(adapter, adapter->port_num, | 544 | if (be_loopback_test(adapter, BE_ONE_PORT_EXT_LOOPBACK, |
513 | BE_ONE_PORT_EXT_LOOPBACK, | 545 | &data[2]) != 0) { |
514 | 1500, 2, 0xabc); | ||
515 | if (data[2] != 0) | ||
516 | test->flags |= ETH_TEST_FL_FAILED; | 546 | test->flags |= ETH_TEST_FL_FAILED; |
547 | } | ||
517 | 548 | ||
518 | data[3] = be_test_ddr_dma(adapter); | 549 | data[3] = be_test_ddr_dma(adapter); |
519 | if (data[3] != 0) | 550 | if (data[3] != 0) |
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 4bfc80812926..65df1de447e4 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c | |||
@@ -653,12 +653,20 @@ static void | |||
653 | bnx2_netif_stop(struct bnx2 *bp) | 653 | bnx2_netif_stop(struct bnx2 *bp) |
654 | { | 654 | { |
655 | bnx2_cnic_stop(bp); | 655 | bnx2_cnic_stop(bp); |
656 | bnx2_disable_int_sync(bp); | ||
657 | if (netif_running(bp->dev)) { | 656 | if (netif_running(bp->dev)) { |
657 | int i; | ||
658 | |||
658 | bnx2_napi_disable(bp); | 659 | bnx2_napi_disable(bp); |
659 | netif_tx_disable(bp->dev); | 660 | netif_tx_disable(bp->dev); |
660 | bp->dev->trans_start = jiffies; /* prevent tx timeout */ | 661 | /* prevent tx timeout */ |
662 | for (i = 0; i < bp->dev->num_tx_queues; i++) { | ||
663 | struct netdev_queue *txq; | ||
664 | |||
665 | txq = netdev_get_tx_queue(bp->dev, i); | ||
666 | txq->trans_start = jiffies; | ||
667 | } | ||
661 | } | 668 | } |
669 | bnx2_disable_int_sync(bp); | ||
662 | } | 670 | } |
663 | 671 | ||
664 | static void | 672 | static void |
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 77ba13520d87..306c2b8165e2 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c | |||
@@ -7593,6 +7593,8 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode) | |||
7593 | if (bp->cnic_eth_dev.drv_state & CNIC_DRV_STATE_REGD) { | 7593 | if (bp->cnic_eth_dev.drv_state & CNIC_DRV_STATE_REGD) { |
7594 | bnx2x_set_iscsi_eth_mac_addr(bp, 1); | 7594 | bnx2x_set_iscsi_eth_mac_addr(bp, 1); |
7595 | bp->cnic_flags |= BNX2X_CNIC_FLAG_MAC_SET; | 7595 | bp->cnic_flags |= BNX2X_CNIC_FLAG_MAC_SET; |
7596 | bnx2x_init_sb(bp, bp->cnic_sb, bp->cnic_sb_mapping, | ||
7597 | CNIC_SB_ID(bp)); | ||
7596 | } | 7598 | } |
7597 | mutex_unlock(&bp->cnic_mutex); | 7599 | mutex_unlock(&bp->cnic_mutex); |
7598 | #endif | 7600 | #endif |
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index 0fb7a4964e75..822f586d72af 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c | |||
@@ -1580,7 +1580,7 @@ static void ad_agg_selection_logic(struct aggregator *agg) | |||
1580 | // check if any partner replys | 1580 | // check if any partner replys |
1581 | if (best->is_individual) { | 1581 | if (best->is_individual) { |
1582 | pr_warning("%s: Warning: No 802.3ad response from the link partner for any adapters in the bond\n", | 1582 | pr_warning("%s: Warning: No 802.3ad response from the link partner for any adapters in the bond\n", |
1583 | best->slave->dev->master->name); | 1583 | best->slave ? best->slave->dev->master->name : "NULL"); |
1584 | } | 1584 | } |
1585 | 1585 | ||
1586 | best->is_active = 1; | 1586 | best->is_active = 1; |
diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c index d0ec17878ffc..166cc7e579c0 100644 --- a/drivers/net/can/at91_can.c +++ b/drivers/net/can/at91_can.c | |||
@@ -1037,7 +1037,7 @@ static int __init at91_can_probe(struct platform_device *pdev) | |||
1037 | 1037 | ||
1038 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1038 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1039 | irq = platform_get_irq(pdev, 0); | 1039 | irq = platform_get_irq(pdev, 0); |
1040 | if (!res || !irq) { | 1040 | if (!res || irq <= 0) { |
1041 | err = -ENODEV; | 1041 | err = -ENODEV; |
1042 | goto exit_put; | 1042 | goto exit_put; |
1043 | } | 1043 | } |
diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c index 8edac8915ea8..34e03104c3c1 100644 --- a/drivers/net/davinci_emac.c +++ b/drivers/net/davinci_emac.c | |||
@@ -2272,7 +2272,7 @@ static int emac_mii_reset(struct mii_bus *bus) | |||
2272 | unsigned int clk_div; | 2272 | unsigned int clk_div; |
2273 | int mdio_bus_freq = emac_bus_frequency; | 2273 | int mdio_bus_freq = emac_bus_frequency; |
2274 | 2274 | ||
2275 | if (mdio_max_freq & mdio_bus_freq) | 2275 | if (mdio_max_freq && mdio_bus_freq) |
2276 | clk_div = ((mdio_bus_freq / mdio_max_freq) - 1); | 2276 | clk_div = ((mdio_bus_freq / mdio_max_freq) - 1); |
2277 | else | 2277 | else |
2278 | clk_div = 0xFF; | 2278 | clk_div = 0xFF; |
diff --git a/drivers/net/e100.c b/drivers/net/e100.c index 929701ca07d3..839fb2b136d3 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c | |||
@@ -1829,6 +1829,7 @@ static int e100_alloc_cbs(struct nic *nic) | |||
1829 | &nic->cbs_dma_addr); | 1829 | &nic->cbs_dma_addr); |
1830 | if (!nic->cbs) | 1830 | if (!nic->cbs) |
1831 | return -ENOMEM; | 1831 | return -ENOMEM; |
1832 | memset(nic->cbs, 0, count * sizeof(struct cb)); | ||
1832 | 1833 | ||
1833 | for (cb = nic->cbs, i = 0; i < count; cb++, i++) { | 1834 | for (cb = nic->cbs, i = 0; i < count; cb++, i++) { |
1834 | cb->next = (i + 1 < count) ? cb + 1 : nic->cbs; | 1835 | cb->next = (i + 1 < count) ? cb + 1 : nic->cbs; |
@@ -1837,7 +1838,6 @@ static int e100_alloc_cbs(struct nic *nic) | |||
1837 | cb->dma_addr = nic->cbs_dma_addr + i * sizeof(struct cb); | 1838 | cb->dma_addr = nic->cbs_dma_addr + i * sizeof(struct cb); |
1838 | cb->link = cpu_to_le32(nic->cbs_dma_addr + | 1839 | cb->link = cpu_to_le32(nic->cbs_dma_addr + |
1839 | ((i+1) % count) * sizeof(struct cb)); | 1840 | ((i+1) % count) * sizeof(struct cb)); |
1840 | cb->skb = NULL; | ||
1841 | } | 1841 | } |
1842 | 1842 | ||
1843 | nic->cb_to_use = nic->cb_to_send = nic->cb_to_clean = nic->cbs; | 1843 | nic->cb_to_use = nic->cb_to_send = nic->cb_to_clean = nic->cbs; |
diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c index c1a42cfc80ba..b979464091bb 100644 --- a/drivers/net/e1000e/82571.c +++ b/drivers/net/e1000e/82571.c | |||
@@ -1290,7 +1290,6 @@ static s32 e1000_setup_link_82571(struct e1000_hw *hw) | |||
1290 | static s32 e1000_setup_copper_link_82571(struct e1000_hw *hw) | 1290 | static s32 e1000_setup_copper_link_82571(struct e1000_hw *hw) |
1291 | { | 1291 | { |
1292 | u32 ctrl; | 1292 | u32 ctrl; |
1293 | u32 led_ctrl; | ||
1294 | s32 ret_val; | 1293 | s32 ret_val; |
1295 | 1294 | ||
1296 | ctrl = er32(CTRL); | 1295 | ctrl = er32(CTRL); |
@@ -1305,11 +1304,6 @@ static s32 e1000_setup_copper_link_82571(struct e1000_hw *hw) | |||
1305 | break; | 1304 | break; |
1306 | case e1000_phy_igp_2: | 1305 | case e1000_phy_igp_2: |
1307 | ret_val = e1000e_copper_link_setup_igp(hw); | 1306 | ret_val = e1000e_copper_link_setup_igp(hw); |
1308 | /* Setup activity LED */ | ||
1309 | led_ctrl = er32(LEDCTL); | ||
1310 | led_ctrl &= IGP_ACTIVITY_LED_MASK; | ||
1311 | led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE); | ||
1312 | ew32(LEDCTL, led_ctrl); | ||
1313 | break; | 1307 | break; |
1314 | default: | 1308 | default: |
1315 | return -E1000_ERR_PHY; | 1309 | return -E1000_ERR_PHY; |
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 6850dc0a7b91..8bd3c9f17532 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c | |||
@@ -143,7 +143,6 @@ void gfar_start(struct net_device *dev); | |||
143 | static void gfar_clear_exact_match(struct net_device *dev); | 143 | static void gfar_clear_exact_match(struct net_device *dev); |
144 | static void gfar_set_mac_for_addr(struct net_device *dev, int num, u8 *addr); | 144 | static void gfar_set_mac_for_addr(struct net_device *dev, int num, u8 *addr); |
145 | static int gfar_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); | 145 | static int gfar_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); |
146 | u16 gfar_select_queue(struct net_device *dev, struct sk_buff *skb); | ||
147 | 146 | ||
148 | MODULE_AUTHOR("Freescale Semiconductor, Inc"); | 147 | MODULE_AUTHOR("Freescale Semiconductor, Inc"); |
149 | MODULE_DESCRIPTION("Gianfar Ethernet Driver"); | 148 | MODULE_DESCRIPTION("Gianfar Ethernet Driver"); |
@@ -357,8 +356,11 @@ static void gfar_init_mac(struct net_device *ndev) | |||
357 | /* Configure the coalescing support */ | 356 | /* Configure the coalescing support */ |
358 | gfar_configure_coalescing(priv, 0xFF, 0xFF); | 357 | gfar_configure_coalescing(priv, 0xFF, 0xFF); |
359 | 358 | ||
360 | if (priv->rx_filer_enable) | 359 | if (priv->rx_filer_enable) { |
361 | rctrl |= RCTRL_FILREN; | 360 | rctrl |= RCTRL_FILREN; |
361 | /* Program the RIR0 reg with the required distribution */ | ||
362 | gfar_write(®s->rir0, DEFAULT_RIR0); | ||
363 | } | ||
362 | 364 | ||
363 | if (priv->rx_csum_enable) | 365 | if (priv->rx_csum_enable) |
364 | rctrl |= RCTRL_CHECKSUMMING; | 366 | rctrl |= RCTRL_CHECKSUMMING; |
@@ -414,6 +416,36 @@ static void gfar_init_mac(struct net_device *ndev) | |||
414 | gfar_write(®s->fifo_tx_starve_shutoff, priv->fifo_starve_off); | 416 | gfar_write(®s->fifo_tx_starve_shutoff, priv->fifo_starve_off); |
415 | } | 417 | } |
416 | 418 | ||
419 | static struct net_device_stats *gfar_get_stats(struct net_device *dev) | ||
420 | { | ||
421 | struct gfar_private *priv = netdev_priv(dev); | ||
422 | struct netdev_queue *txq; | ||
423 | unsigned long rx_packets = 0, rx_bytes = 0, rx_dropped = 0; | ||
424 | unsigned long tx_packets = 0, tx_bytes = 0; | ||
425 | int i = 0; | ||
426 | |||
427 | for (i = 0; i < priv->num_rx_queues; i++) { | ||
428 | rx_packets += priv->rx_queue[i]->stats.rx_packets; | ||
429 | rx_bytes += priv->rx_queue[i]->stats.rx_bytes; | ||
430 | rx_dropped += priv->rx_queue[i]->stats.rx_dropped; | ||
431 | } | ||
432 | |||
433 | dev->stats.rx_packets = rx_packets; | ||
434 | dev->stats.rx_bytes = rx_bytes; | ||
435 | dev->stats.rx_dropped = rx_dropped; | ||
436 | |||
437 | for (i = 0; i < priv->num_tx_queues; i++) { | ||
438 | txq = netdev_get_tx_queue(dev, i); | ||
439 | tx_bytes += txq->tx_bytes; | ||
440 | tx_packets += txq->tx_packets; | ||
441 | } | ||
442 | |||
443 | dev->stats.tx_bytes = tx_bytes; | ||
444 | dev->stats.tx_packets = tx_packets; | ||
445 | |||
446 | return &dev->stats; | ||
447 | } | ||
448 | |||
417 | static const struct net_device_ops gfar_netdev_ops = { | 449 | static const struct net_device_ops gfar_netdev_ops = { |
418 | .ndo_open = gfar_enet_open, | 450 | .ndo_open = gfar_enet_open, |
419 | .ndo_start_xmit = gfar_start_xmit, | 451 | .ndo_start_xmit = gfar_start_xmit, |
@@ -422,7 +454,7 @@ static const struct net_device_ops gfar_netdev_ops = { | |||
422 | .ndo_set_multicast_list = gfar_set_multi, | 454 | .ndo_set_multicast_list = gfar_set_multi, |
423 | .ndo_tx_timeout = gfar_timeout, | 455 | .ndo_tx_timeout = gfar_timeout, |
424 | .ndo_do_ioctl = gfar_ioctl, | 456 | .ndo_do_ioctl = gfar_ioctl, |
425 | .ndo_select_queue = gfar_select_queue, | 457 | .ndo_get_stats = gfar_get_stats, |
426 | .ndo_vlan_rx_register = gfar_vlan_rx_register, | 458 | .ndo_vlan_rx_register = gfar_vlan_rx_register, |
427 | .ndo_set_mac_address = eth_mac_addr, | 459 | .ndo_set_mac_address = eth_mac_addr, |
428 | .ndo_validate_addr = eth_validate_addr, | 460 | .ndo_validate_addr = eth_validate_addr, |
@@ -472,10 +504,6 @@ static inline int gfar_uses_fcb(struct gfar_private *priv) | |||
472 | return priv->vlgrp || priv->rx_csum_enable; | 504 | return priv->vlgrp || priv->rx_csum_enable; |
473 | } | 505 | } |
474 | 506 | ||
475 | u16 gfar_select_queue(struct net_device *dev, struct sk_buff *skb) | ||
476 | { | ||
477 | return skb_get_queue_mapping(skb); | ||
478 | } | ||
479 | static void free_tx_pointers(struct gfar_private *priv) | 507 | static void free_tx_pointers(struct gfar_private *priv) |
480 | { | 508 | { |
481 | int i = 0; | 509 | int i = 0; |
@@ -1022,6 +1050,9 @@ static int gfar_probe(struct of_device *ofdev, | |||
1022 | priv->rx_queue[i]->rxic = DEFAULT_RXIC; | 1050 | priv->rx_queue[i]->rxic = DEFAULT_RXIC; |
1023 | } | 1051 | } |
1024 | 1052 | ||
1053 | /* enable filer if using multiple RX queues*/ | ||
1054 | if(priv->num_rx_queues > 1) | ||
1055 | priv->rx_filer_enable = 1; | ||
1025 | /* Enable most messages by default */ | 1056 | /* Enable most messages by default */ |
1026 | priv->msg_enable = (NETIF_MSG_IFUP << 1 ) - 1; | 1057 | priv->msg_enable = (NETIF_MSG_IFUP << 1 ) - 1; |
1027 | 1058 | ||
@@ -1937,7 +1968,8 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1937 | } | 1968 | } |
1938 | 1969 | ||
1939 | /* Update transmit stats */ | 1970 | /* Update transmit stats */ |
1940 | dev->stats.tx_bytes += skb->len; | 1971 | txq->tx_bytes += skb->len; |
1972 | txq->tx_packets ++; | ||
1941 | 1973 | ||
1942 | txbdp = txbdp_start = tx_queue->cur_tx; | 1974 | txbdp = txbdp_start = tx_queue->cur_tx; |
1943 | 1975 | ||
@@ -2295,8 +2327,6 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue) | |||
2295 | tx_queue->skb_dirtytx = skb_dirtytx; | 2327 | tx_queue->skb_dirtytx = skb_dirtytx; |
2296 | tx_queue->dirty_tx = bdp; | 2328 | tx_queue->dirty_tx = bdp; |
2297 | 2329 | ||
2298 | dev->stats.tx_packets += howmany; | ||
2299 | |||
2300 | return howmany; | 2330 | return howmany; |
2301 | } | 2331 | } |
2302 | 2332 | ||
@@ -2434,10 +2464,11 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, | |||
2434 | fcb = (struct rxfcb *)skb->data; | 2464 | fcb = (struct rxfcb *)skb->data; |
2435 | 2465 | ||
2436 | /* Remove the FCB from the skb */ | 2466 | /* Remove the FCB from the skb */ |
2437 | skb_set_queue_mapping(skb, fcb->rq); | ||
2438 | /* Remove the padded bytes, if there are any */ | 2467 | /* Remove the padded bytes, if there are any */ |
2439 | if (amount_pull) | 2468 | if (amount_pull) { |
2469 | skb_record_rx_queue(skb, fcb->rq); | ||
2440 | skb_pull(skb, amount_pull); | 2470 | skb_pull(skb, amount_pull); |
2471 | } | ||
2441 | 2472 | ||
2442 | if (priv->rx_csum_enable) | 2473 | if (priv->rx_csum_enable) |
2443 | gfar_rx_checksum(skb, fcb); | 2474 | gfar_rx_checksum(skb, fcb); |
@@ -2510,22 +2541,22 @@ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit) | |||
2510 | } | 2541 | } |
2511 | } else { | 2542 | } else { |
2512 | /* Increment the number of packets */ | 2543 | /* Increment the number of packets */ |
2513 | dev->stats.rx_packets++; | 2544 | rx_queue->stats.rx_packets++; |
2514 | howmany++; | 2545 | howmany++; |
2515 | 2546 | ||
2516 | if (likely(skb)) { | 2547 | if (likely(skb)) { |
2517 | pkt_len = bdp->length - ETH_FCS_LEN; | 2548 | pkt_len = bdp->length - ETH_FCS_LEN; |
2518 | /* Remove the FCS from the packet length */ | 2549 | /* Remove the FCS from the packet length */ |
2519 | skb_put(skb, pkt_len); | 2550 | skb_put(skb, pkt_len); |
2520 | dev->stats.rx_bytes += pkt_len; | 2551 | rx_queue->stats.rx_bytes += pkt_len; |
2521 | 2552 | skb_record_rx_queue(skb, rx_queue->qindex); | |
2522 | gfar_process_frame(dev, skb, amount_pull); | 2553 | gfar_process_frame(dev, skb, amount_pull); |
2523 | 2554 | ||
2524 | } else { | 2555 | } else { |
2525 | if (netif_msg_rx_err(priv)) | 2556 | if (netif_msg_rx_err(priv)) |
2526 | printk(KERN_WARNING | 2557 | printk(KERN_WARNING |
2527 | "%s: Missing skb!\n", dev->name); | 2558 | "%s: Missing skb!\n", dev->name); |
2528 | dev->stats.rx_dropped++; | 2559 | rx_queue->stats.rx_dropped++; |
2529 | priv->extra_stats.rx_skbmissing++; | 2560 | priv->extra_stats.rx_skbmissing++; |
2530 | } | 2561 | } |
2531 | 2562 | ||
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h index cbb451011cb5..3d72dc43dca5 100644 --- a/drivers/net/gianfar.h +++ b/drivers/net/gianfar.h | |||
@@ -333,7 +333,7 @@ extern const char gfar_driver_version[]; | |||
333 | #define IMASK_BSY 0x20000000 | 333 | #define IMASK_BSY 0x20000000 |
334 | #define IMASK_EBERR 0x10000000 | 334 | #define IMASK_EBERR 0x10000000 |
335 | #define IMASK_MSRO 0x04000000 | 335 | #define IMASK_MSRO 0x04000000 |
336 | #define IMASK_GRSC 0x02000000 | 336 | #define IMASK_GTSC 0x02000000 |
337 | #define IMASK_BABT 0x01000000 | 337 | #define IMASK_BABT 0x01000000 |
338 | #define IMASK_TXC 0x00800000 | 338 | #define IMASK_TXC 0x00800000 |
339 | #define IMASK_TXEEN 0x00400000 | 339 | #define IMASK_TXEEN 0x00400000 |
@@ -344,7 +344,7 @@ extern const char gfar_driver_version[]; | |||
344 | #define IMASK_XFUN 0x00010000 | 344 | #define IMASK_XFUN 0x00010000 |
345 | #define IMASK_RXB0 0x00008000 | 345 | #define IMASK_RXB0 0x00008000 |
346 | #define IMASK_MAG 0x00000800 | 346 | #define IMASK_MAG 0x00000800 |
347 | #define IMASK_GTSC 0x00000100 | 347 | #define IMASK_GRSC 0x00000100 |
348 | #define IMASK_RXFEN0 0x00000080 | 348 | #define IMASK_RXFEN0 0x00000080 |
349 | #define IMASK_FIR 0x00000008 | 349 | #define IMASK_FIR 0x00000008 |
350 | #define IMASK_FIQ 0x00000004 | 350 | #define IMASK_FIQ 0x00000004 |
@@ -401,6 +401,10 @@ extern const char gfar_driver_version[]; | |||
401 | #define FPR_FILER_MASK 0xFFFFFFFF | 401 | #define FPR_FILER_MASK 0xFFFFFFFF |
402 | #define MAX_FILER_IDX 0xFF | 402 | #define MAX_FILER_IDX 0xFF |
403 | 403 | ||
404 | /* This default RIR value directly corresponds | ||
405 | * to the 3-bit hash value generated */ | ||
406 | #define DEFAULT_RIR0 0x05397700 | ||
407 | |||
404 | /* RQFCR register bits */ | 408 | /* RQFCR register bits */ |
405 | #define RQFCR_GPI 0x80000000 | 409 | #define RQFCR_GPI 0x80000000 |
406 | #define RQFCR_HASHTBL_Q 0x00000000 | 410 | #define RQFCR_HASHTBL_Q 0x00000000 |
@@ -936,6 +940,15 @@ struct gfar_priv_tx_q { | |||
936 | unsigned short txtime; | 940 | unsigned short txtime; |
937 | }; | 941 | }; |
938 | 942 | ||
943 | /* | ||
944 | * Per RX queue stats | ||
945 | */ | ||
946 | struct rx_q_stats { | ||
947 | unsigned long rx_packets; | ||
948 | unsigned long rx_bytes; | ||
949 | unsigned long rx_dropped; | ||
950 | }; | ||
951 | |||
939 | /** | 952 | /** |
940 | * struct gfar_priv_rx_q - per rx queue structure | 953 | * struct gfar_priv_rx_q - per rx queue structure |
941 | * @rxlock: per queue rx spin lock | 954 | * @rxlock: per queue rx spin lock |
@@ -958,6 +971,7 @@ struct gfar_priv_rx_q { | |||
958 | struct rxbd8 *cur_rx; | 971 | struct rxbd8 *cur_rx; |
959 | struct net_device *dev; | 972 | struct net_device *dev; |
960 | struct gfar_priv_grp *grp; | 973 | struct gfar_priv_grp *grp; |
974 | struct rx_q_stats stats; | ||
961 | u16 skb_currx; | 975 | u16 skb_currx; |
962 | u16 qindex; | 976 | u16 qindex; |
963 | unsigned int rx_ring_size; | 977 | unsigned int rx_ring_size; |
diff --git a/drivers/net/ibmlana.c b/drivers/net/ibmlana.c index 090a6d3af112..052c74091d91 100644 --- a/drivers/net/ibmlana.c +++ b/drivers/net/ibmlana.c | |||
@@ -87,6 +87,7 @@ History: | |||
87 | #include <linux/module.h> | 87 | #include <linux/module.h> |
88 | #include <linux/netdevice.h> | 88 | #include <linux/netdevice.h> |
89 | #include <linux/etherdevice.h> | 89 | #include <linux/etherdevice.h> |
90 | #include <linux/if_ether.h> | ||
90 | #include <linux/skbuff.h> | 91 | #include <linux/skbuff.h> |
91 | #include <linux/bitops.h> | 92 | #include <linux/bitops.h> |
92 | 93 | ||
@@ -988,7 +989,7 @@ static int __devinit ibmlana_init_one(struct device *kdev) | |||
988 | 989 | ||
989 | /* copy out MAC address */ | 990 | /* copy out MAC address */ |
990 | 991 | ||
991 | for (z = 0; z < sizeof(dev->dev_addr); z++) | 992 | for (z = 0; z < ETH_ALEN; z++) |
992 | dev->dev_addr[z] = inb(dev->base_addr + MACADDRPROM + z); | 993 | dev->dev_addr[z] = inb(dev->base_addr + MACADDRPROM + z); |
993 | 994 | ||
994 | /* print config */ | 995 | /* print config */ |
diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c index e8e9e9194a88..c505b50d1fa3 100644 --- a/drivers/net/igb/e1000_82575.c +++ b/drivers/net/igb/e1000_82575.c | |||
@@ -1096,9 +1096,7 @@ static s32 igb_setup_serdes_link_82575(struct e1000_hw *hw) | |||
1096 | hw_dbg("Configuring Autoneg:PCS_LCTL=0x%08X\n", reg); | 1096 | hw_dbg("Configuring Autoneg:PCS_LCTL=0x%08X\n", reg); |
1097 | } else { | 1097 | } else { |
1098 | /* Set PCS register for forced link */ | 1098 | /* Set PCS register for forced link */ |
1099 | reg |= E1000_PCS_LCTL_FSD | /* Force Speed */ | 1099 | reg |= E1000_PCS_LCTL_FSD; /* Force Speed */ |
1100 | E1000_PCS_LCTL_FORCE_LINK | /* Force Link */ | ||
1101 | E1000_PCS_LCTL_FLV_LINK_UP; /* Force link value up */ | ||
1102 | 1100 | ||
1103 | hw_dbg("Configuring Forced Link:PCS_LCTL=0x%08X\n", reg); | 1101 | hw_dbg("Configuring Forced Link:PCS_LCTL=0x%08X\n", reg); |
1104 | } | 1102 | } |
diff --git a/drivers/net/igb/e1000_phy.c b/drivers/net/igb/e1000_phy.c index 5c9d73e9bb8d..3670a66401b8 100644 --- a/drivers/net/igb/e1000_phy.c +++ b/drivers/net/igb/e1000_phy.c | |||
@@ -457,15 +457,6 @@ s32 igb_copper_link_setup_82580(struct e1000_hw *hw) | |||
457 | phy_data |= I82580_CFG_ENABLE_DOWNSHIFT; | 457 | phy_data |= I82580_CFG_ENABLE_DOWNSHIFT; |
458 | 458 | ||
459 | ret_val = phy->ops.write_reg(hw, I82580_CFG_REG, phy_data); | 459 | ret_val = phy->ops.write_reg(hw, I82580_CFG_REG, phy_data); |
460 | if (ret_val) | ||
461 | goto out; | ||
462 | |||
463 | /* Set number of link attempts before downshift */ | ||
464 | ret_val = phy->ops.read_reg(hw, I82580_CTRL_REG, &phy_data); | ||
465 | if (ret_val) | ||
466 | goto out; | ||
467 | phy_data &= ~I82580_CTRL_DOWNSHIFT_MASK; | ||
468 | ret_val = phy->ops.write_reg(hw, I82580_CTRL_REG, phy_data); | ||
469 | 460 | ||
470 | out: | 461 | out: |
471 | return ret_val; | 462 | return ret_val; |
diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c index ac9d5272650d..f771a6c08777 100644 --- a/drivers/net/igb/igb_ethtool.c +++ b/drivers/net/igb/igb_ethtool.c | |||
@@ -1795,7 +1795,7 @@ static int igb_wol_exclusion(struct igb_adapter *adapter, | |||
1795 | /* dual port cards only support WoL on port A from now on | 1795 | /* dual port cards only support WoL on port A from now on |
1796 | * unless it was enabled in the eeprom for port B | 1796 | * unless it was enabled in the eeprom for port B |
1797 | * so exclude FUNC_1 ports from having WoL enabled */ | 1797 | * so exclude FUNC_1 ports from having WoL enabled */ |
1798 | if (rd32(E1000_STATUS) & E1000_STATUS_FUNC_1 && | 1798 | if ((rd32(E1000_STATUS) & E1000_STATUS_FUNC_MASK) && |
1799 | !adapter->eeprom_wol) { | 1799 | !adapter->eeprom_wol) { |
1800 | wol->supported = 0; | 1800 | wol->supported = 0; |
1801 | break; | 1801 | break; |
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 78963a0e128d..933c64ff2465 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c | |||
@@ -1306,13 +1306,8 @@ void igb_reset(struct igb_adapter *adapter) | |||
1306 | hwm = min(((pba << 10) * 9 / 10), | 1306 | hwm = min(((pba << 10) * 9 / 10), |
1307 | ((pba << 10) - 2 * adapter->max_frame_size)); | 1307 | ((pba << 10) - 2 * adapter->max_frame_size)); |
1308 | 1308 | ||
1309 | if (mac->type < e1000_82576) { | 1309 | fc->high_water = hwm & 0xFFF0; /* 16-byte granularity */ |
1310 | fc->high_water = hwm & 0xFFF8; /* 8-byte granularity */ | 1310 | fc->low_water = fc->high_water - 16; |
1311 | fc->low_water = fc->high_water - 8; | ||
1312 | } else { | ||
1313 | fc->high_water = hwm & 0xFFF0; /* 16-byte granularity */ | ||
1314 | fc->low_water = fc->high_water - 16; | ||
1315 | } | ||
1316 | fc->pause_time = 0xFFFF; | 1311 | fc->pause_time = 0xFFFF; |
1317 | fc->send_xon = 1; | 1312 | fc->send_xon = 1; |
1318 | fc->current_mode = fc->requested_mode; | 1313 | fc->current_mode = fc->requested_mode; |
diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c index e9dd95f136aa..0dbd0320023a 100644 --- a/drivers/net/igbvf/netdev.c +++ b/drivers/net/igbvf/netdev.c | |||
@@ -2763,7 +2763,8 @@ static int __devinit igbvf_probe(struct pci_dev *pdev, | |||
2763 | err = hw->mac.ops.reset_hw(hw); | 2763 | err = hw->mac.ops.reset_hw(hw); |
2764 | if (err) { | 2764 | if (err) { |
2765 | dev_info(&pdev->dev, | 2765 | dev_info(&pdev->dev, |
2766 | "PF still in reset state, assigning new address\n"); | 2766 | "PF still in reset state, assigning new address." |
2767 | " Is the PF interface up?\n"); | ||
2767 | random_ether_addr(hw->mac.addr); | 2768 | random_ether_addr(hw->mac.addr); |
2768 | } else { | 2769 | } else { |
2769 | err = hw->mac.ops.read_mac_addr(hw); | 2770 | err = hw->mac.ops.read_mac_addr(hw); |
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index bd64387563f0..1a2ea621e371 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c | |||
@@ -4373,6 +4373,11 @@ static int ixgbe_resume(struct pci_dev *pdev) | |||
4373 | 4373 | ||
4374 | pci_set_power_state(pdev, PCI_D0); | 4374 | pci_set_power_state(pdev, PCI_D0); |
4375 | pci_restore_state(pdev); | 4375 | pci_restore_state(pdev); |
4376 | /* | ||
4377 | * pci_restore_state clears dev->state_saved so call | ||
4378 | * pci_save_state to restore it. | ||
4379 | */ | ||
4380 | pci_save_state(pdev); | ||
4376 | 4381 | ||
4377 | err = pci_enable_device_mem(pdev); | 4382 | err = pci_enable_device_mem(pdev); |
4378 | if (err) { | 4383 | if (err) { |
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index f4996846a234..6cae26a5bd67 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c | |||
@@ -57,7 +57,9 @@ static int use_msi = 1; | |||
57 | 57 | ||
58 | static int use_msi_x = 1; | 58 | static int use_msi_x = 1; |
59 | 59 | ||
60 | static unsigned long auto_fw_reset = AUTO_FW_RESET_ENABLED; | 60 | static int auto_fw_reset = AUTO_FW_RESET_ENABLED; |
61 | module_param(auto_fw_reset, int, 0644); | ||
62 | MODULE_PARM_DESC(auto_fw_reset,"Auto firmware reset (0=disabled, 1=enabled"); | ||
61 | 63 | ||
62 | static int __devinit netxen_nic_probe(struct pci_dev *pdev, | 64 | static int __devinit netxen_nic_probe(struct pci_dev *pdev, |
63 | const struct pci_device_id *ent); | 65 | const struct pci_device_id *ent); |
@@ -2534,42 +2536,6 @@ static struct bin_attribute bin_attr_mem = { | |||
2534 | .write = netxen_sysfs_write_mem, | 2536 | .write = netxen_sysfs_write_mem, |
2535 | }; | 2537 | }; |
2536 | 2538 | ||
2537 | #ifdef CONFIG_MODULES | ||
2538 | static ssize_t | ||
2539 | netxen_store_auto_fw_reset(struct module_attribute *mattr, | ||
2540 | struct module *mod, const char *buf, size_t count) | ||
2541 | |||
2542 | { | ||
2543 | unsigned long new; | ||
2544 | |||
2545 | if (strict_strtoul(buf, 16, &new)) | ||
2546 | return -EINVAL; | ||
2547 | |||
2548 | if ((new == AUTO_FW_RESET_ENABLED) || (new == AUTO_FW_RESET_DISABLED)) { | ||
2549 | auto_fw_reset = new; | ||
2550 | return count; | ||
2551 | } | ||
2552 | |||
2553 | return -EINVAL; | ||
2554 | } | ||
2555 | |||
2556 | static ssize_t | ||
2557 | netxen_show_auto_fw_reset(struct module_attribute *mattr, | ||
2558 | struct module *mod, char *buf) | ||
2559 | |||
2560 | { | ||
2561 | if (auto_fw_reset == AUTO_FW_RESET_ENABLED) | ||
2562 | return sprintf(buf, "enabled\n"); | ||
2563 | else | ||
2564 | return sprintf(buf, "disabled\n"); | ||
2565 | } | ||
2566 | |||
2567 | static struct module_attribute mod_attr_fw_reset = { | ||
2568 | .attr = {.name = "auto_fw_reset", .mode = (S_IRUGO | S_IWUSR)}, | ||
2569 | .show = netxen_show_auto_fw_reset, | ||
2570 | .store = netxen_store_auto_fw_reset, | ||
2571 | }; | ||
2572 | #endif | ||
2573 | 2539 | ||
2574 | static void | 2540 | static void |
2575 | netxen_create_sysfs_entries(struct netxen_adapter *adapter) | 2541 | netxen_create_sysfs_entries(struct netxen_adapter *adapter) |
@@ -2775,23 +2741,12 @@ static struct pci_driver netxen_driver = { | |||
2775 | 2741 | ||
2776 | static int __init netxen_init_module(void) | 2742 | static int __init netxen_init_module(void) |
2777 | { | 2743 | { |
2778 | #ifdef CONFIG_MODULES | ||
2779 | struct module *mod = THIS_MODULE; | ||
2780 | #endif | ||
2781 | |||
2782 | printk(KERN_INFO "%s\n", netxen_nic_driver_string); | 2744 | printk(KERN_INFO "%s\n", netxen_nic_driver_string); |
2783 | 2745 | ||
2784 | #ifdef CONFIG_INET | 2746 | #ifdef CONFIG_INET |
2785 | register_netdevice_notifier(&netxen_netdev_cb); | 2747 | register_netdevice_notifier(&netxen_netdev_cb); |
2786 | register_inetaddr_notifier(&netxen_inetaddr_cb); | 2748 | register_inetaddr_notifier(&netxen_inetaddr_cb); |
2787 | #endif | 2749 | #endif |
2788 | |||
2789 | #ifdef CONFIG_MODULES | ||
2790 | if (sysfs_create_file(&mod->mkobj.kobj, &mod_attr_fw_reset.attr)) | ||
2791 | printk(KERN_ERR "%s: Failed to create auto_fw_reset " | ||
2792 | "sysfs entry.", netxen_nic_driver_name); | ||
2793 | #endif | ||
2794 | |||
2795 | return pci_register_driver(&netxen_driver); | 2750 | return pci_register_driver(&netxen_driver); |
2796 | } | 2751 | } |
2797 | 2752 | ||
@@ -2799,12 +2754,6 @@ module_init(netxen_init_module); | |||
2799 | 2754 | ||
2800 | static void __exit netxen_exit_module(void) | 2755 | static void __exit netxen_exit_module(void) |
2801 | { | 2756 | { |
2802 | #ifdef CONFIG_MODULES | ||
2803 | struct module *mod = THIS_MODULE; | ||
2804 | |||
2805 | sysfs_remove_file(&mod->mkobj.kobj, &mod_attr_fw_reset.attr); | ||
2806 | #endif | ||
2807 | |||
2808 | pci_unregister_driver(&netxen_driver); | 2757 | pci_unregister_driver(&netxen_driver); |
2809 | 2758 | ||
2810 | #ifdef CONFIG_INET | 2759 | #ifdef CONFIG_INET |
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c index dcc67a35e8f2..e154677ff706 100644 --- a/drivers/net/pcnet32.c +++ b/drivers/net/pcnet32.c | |||
@@ -45,6 +45,7 @@ static const char *const version = | |||
45 | #include <linux/crc32.h> | 45 | #include <linux/crc32.h> |
46 | #include <linux/netdevice.h> | 46 | #include <linux/netdevice.h> |
47 | #include <linux/etherdevice.h> | 47 | #include <linux/etherdevice.h> |
48 | #include <linux/if_ether.h> | ||
48 | #include <linux/skbuff.h> | 49 | #include <linux/skbuff.h> |
49 | #include <linux/spinlock.h> | 50 | #include <linux/spinlock.h> |
50 | #include <linux/moduleparam.h> | 51 | #include <linux/moduleparam.h> |
@@ -1765,7 +1766,7 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev) | |||
1765 | 1766 | ||
1766 | /* if the ethernet address is not valid, force to 00:00:00:00:00:00 */ | 1767 | /* if the ethernet address is not valid, force to 00:00:00:00:00:00 */ |
1767 | if (!is_valid_ether_addr(dev->perm_addr)) | 1768 | if (!is_valid_ether_addr(dev->perm_addr)) |
1768 | memset(dev->dev_addr, 0, sizeof(dev->dev_addr)); | 1769 | memset(dev->dev_addr, 0, ETH_ALEN); |
1769 | 1770 | ||
1770 | if (pcnet32_debug & NETIF_MSG_PROBE) { | 1771 | if (pcnet32_debug & NETIF_MSG_PROBE) { |
1771 | printk(" %pM", dev->dev_addr); | 1772 | printk(" %pM", dev->dev_addr); |
diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c index f63c96a4ecb4..c13cf64095b6 100644 --- a/drivers/net/phy/broadcom.c +++ b/drivers/net/phy/broadcom.c | |||
@@ -326,7 +326,8 @@ error: | |||
326 | 326 | ||
327 | static void bcm54xx_adjust_rxrefclk(struct phy_device *phydev) | 327 | static void bcm54xx_adjust_rxrefclk(struct phy_device *phydev) |
328 | { | 328 | { |
329 | u32 val, orig; | 329 | u32 orig; |
330 | int val; | ||
330 | bool clk125en = true; | 331 | bool clk125en = true; |
331 | 332 | ||
332 | /* Abort if we are using an untested phy. */ | 333 | /* Abort if we are using an untested phy. */ |
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index f983e3b507cc..103e8b0e2a0d 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c | |||
@@ -741,14 +741,14 @@ static int efx_probe_port(struct efx_nic *efx) | |||
741 | 741 | ||
742 | EFX_LOG(efx, "create port\n"); | 742 | EFX_LOG(efx, "create port\n"); |
743 | 743 | ||
744 | if (phy_flash_cfg) | ||
745 | efx->phy_mode = PHY_MODE_SPECIAL; | ||
746 | |||
744 | /* Connect up MAC/PHY operations table */ | 747 | /* Connect up MAC/PHY operations table */ |
745 | rc = efx->type->probe_port(efx); | 748 | rc = efx->type->probe_port(efx); |
746 | if (rc) | 749 | if (rc) |
747 | goto err; | 750 | goto err; |
748 | 751 | ||
749 | if (phy_flash_cfg) | ||
750 | efx->phy_mode = PHY_MODE_SPECIAL; | ||
751 | |||
752 | /* Sanity check MAC address */ | 752 | /* Sanity check MAC address */ |
753 | if (is_valid_ether_addr(efx->mac_address)) { | 753 | if (is_valid_ether_addr(efx->mac_address)) { |
754 | memcpy(efx->net_dev->dev_addr, efx->mac_address, ETH_ALEN); | 754 | memcpy(efx->net_dev->dev_addr, efx->mac_address, ETH_ALEN); |
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 17afcd26e870..9d009c46e962 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c | |||
@@ -925,6 +925,7 @@ static int falcon_probe_port(struct efx_nic *efx) | |||
925 | 925 | ||
926 | static void falcon_remove_port(struct efx_nic *efx) | 926 | static void falcon_remove_port(struct efx_nic *efx) |
927 | { | 927 | { |
928 | efx->phy_op->remove(efx); | ||
928 | efx_nic_free_buffer(efx, &efx->stats_buffer); | 929 | efx_nic_free_buffer(efx, &efx->stats_buffer); |
929 | } | 930 | } |
930 | 931 | ||
diff --git a/drivers/net/sfc/falcon_xmac.c b/drivers/net/sfc/falcon_xmac.c index 3da933f8f079..8ccab2c67a20 100644 --- a/drivers/net/sfc/falcon_xmac.c +++ b/drivers/net/sfc/falcon_xmac.c | |||
@@ -111,16 +111,12 @@ static void falcon_mask_status_intr(struct efx_nic *efx, bool enable) | |||
111 | efx_writeo(efx, ®, FR_AB_XM_MGT_INT_MASK); | 111 | efx_writeo(efx, ®, FR_AB_XM_MGT_INT_MASK); |
112 | } | 112 | } |
113 | 113 | ||
114 | /* Get status of XAUI link */ | 114 | static bool falcon_xgxs_link_ok(struct efx_nic *efx) |
115 | static bool falcon_xaui_link_ok(struct efx_nic *efx) | ||
116 | { | 115 | { |
117 | efx_oword_t reg; | 116 | efx_oword_t reg; |
118 | bool align_done, link_ok = false; | 117 | bool align_done, link_ok = false; |
119 | int sync_status; | 118 | int sync_status; |
120 | 119 | ||
121 | if (LOOPBACK_INTERNAL(efx)) | ||
122 | return true; | ||
123 | |||
124 | /* Read link status */ | 120 | /* Read link status */ |
125 | efx_reado(efx, ®, FR_AB_XX_CORE_STAT); | 121 | efx_reado(efx, ®, FR_AB_XX_CORE_STAT); |
126 | 122 | ||
@@ -135,14 +131,24 @@ static bool falcon_xaui_link_ok(struct efx_nic *efx) | |||
135 | EFX_SET_OWORD_FIELD(reg, FRF_AB_XX_DISPERR, FFE_AB_XX_STAT_ALL_LANES); | 131 | EFX_SET_OWORD_FIELD(reg, FRF_AB_XX_DISPERR, FFE_AB_XX_STAT_ALL_LANES); |
136 | efx_writeo(efx, ®, FR_AB_XX_CORE_STAT); | 132 | efx_writeo(efx, ®, FR_AB_XX_CORE_STAT); |
137 | 133 | ||
138 | /* If the link is up, then check the phy side of the xaui link */ | ||
139 | if (efx->link_state.up && link_ok) | ||
140 | if (efx->mdio.mmds & (1 << MDIO_MMD_PHYXS)) | ||
141 | link_ok = efx_mdio_phyxgxs_lane_sync(efx); | ||
142 | |||
143 | return link_ok; | 134 | return link_ok; |
144 | } | 135 | } |
145 | 136 | ||
137 | static bool falcon_xmac_link_ok(struct efx_nic *efx) | ||
138 | { | ||
139 | /* | ||
140 | * Check MAC's XGXS link status except when using XGMII loopback | ||
141 | * which bypasses the XGXS block. | ||
142 | * If possible, check PHY's XGXS link status except when using | ||
143 | * MAC loopback. | ||
144 | */ | ||
145 | return (efx->loopback_mode == LOOPBACK_XGMII || | ||
146 | falcon_xgxs_link_ok(efx)) && | ||
147 | (!(efx->mdio.mmds & (1 << MDIO_MMD_PHYXS)) || | ||
148 | LOOPBACK_INTERNAL(efx) || | ||
149 | efx_mdio_phyxgxs_lane_sync(efx)); | ||
150 | } | ||
151 | |||
146 | void falcon_reconfigure_xmac_core(struct efx_nic *efx) | 152 | void falcon_reconfigure_xmac_core(struct efx_nic *efx) |
147 | { | 153 | { |
148 | unsigned int max_frame_len; | 154 | unsigned int max_frame_len; |
@@ -245,9 +251,9 @@ static void falcon_reconfigure_xgxs_core(struct efx_nic *efx) | |||
245 | 251 | ||
246 | 252 | ||
247 | /* Try to bring up the Falcon side of the Falcon-Phy XAUI link */ | 253 | /* Try to bring up the Falcon side of the Falcon-Phy XAUI link */ |
248 | static bool falcon_check_xaui_link_up(struct efx_nic *efx, int tries) | 254 | static bool falcon_xmac_link_ok_retry(struct efx_nic *efx, int tries) |
249 | { | 255 | { |
250 | bool mac_up = falcon_xaui_link_ok(efx); | 256 | bool mac_up = falcon_xmac_link_ok(efx); |
251 | 257 | ||
252 | if (LOOPBACK_MASK(efx) & LOOPBACKS_EXTERNAL(efx) & LOOPBACKS_WS || | 258 | if (LOOPBACK_MASK(efx) & LOOPBACKS_EXTERNAL(efx) & LOOPBACKS_WS || |
253 | efx_phy_mode_disabled(efx->phy_mode)) | 259 | efx_phy_mode_disabled(efx->phy_mode)) |
@@ -261,7 +267,7 @@ static bool falcon_check_xaui_link_up(struct efx_nic *efx, int tries) | |||
261 | falcon_reset_xaui(efx); | 267 | falcon_reset_xaui(efx); |
262 | udelay(200); | 268 | udelay(200); |
263 | 269 | ||
264 | mac_up = falcon_xaui_link_ok(efx); | 270 | mac_up = falcon_xmac_link_ok(efx); |
265 | --tries; | 271 | --tries; |
266 | } | 272 | } |
267 | 273 | ||
@@ -272,7 +278,7 @@ static bool falcon_check_xaui_link_up(struct efx_nic *efx, int tries) | |||
272 | 278 | ||
273 | static bool falcon_xmac_check_fault(struct efx_nic *efx) | 279 | static bool falcon_xmac_check_fault(struct efx_nic *efx) |
274 | { | 280 | { |
275 | return !falcon_check_xaui_link_up(efx, 5); | 281 | return !falcon_xmac_link_ok_retry(efx, 5); |
276 | } | 282 | } |
277 | 283 | ||
278 | static int falcon_reconfigure_xmac(struct efx_nic *efx) | 284 | static int falcon_reconfigure_xmac(struct efx_nic *efx) |
@@ -284,7 +290,7 @@ static int falcon_reconfigure_xmac(struct efx_nic *efx) | |||
284 | 290 | ||
285 | falcon_reconfigure_mac_wrapper(efx); | 291 | falcon_reconfigure_mac_wrapper(efx); |
286 | 292 | ||
287 | efx->xmac_poll_required = !falcon_check_xaui_link_up(efx, 5); | 293 | efx->xmac_poll_required = !falcon_xmac_link_ok_retry(efx, 5); |
288 | falcon_mask_status_intr(efx, true); | 294 | falcon_mask_status_intr(efx, true); |
289 | 295 | ||
290 | return 0; | 296 | return 0; |
@@ -357,7 +363,7 @@ void falcon_poll_xmac(struct efx_nic *efx) | |||
357 | return; | 363 | return; |
358 | 364 | ||
359 | falcon_mask_status_intr(efx, false); | 365 | falcon_mask_status_intr(efx, false); |
360 | efx->xmac_poll_required = !falcon_check_xaui_link_up(efx, 1); | 366 | efx->xmac_poll_required = !falcon_xmac_link_ok_retry(efx, 1); |
361 | falcon_mask_status_intr(efx, true); | 367 | falcon_mask_status_intr(efx, true); |
362 | } | 368 | } |
363 | 369 | ||
diff --git a/drivers/net/sfc/mcdi_phy.c b/drivers/net/sfc/mcdi_phy.c index 0e1bcc5a0d52..eb694af7a473 100644 --- a/drivers/net/sfc/mcdi_phy.c +++ b/drivers/net/sfc/mcdi_phy.c | |||
@@ -304,31 +304,47 @@ static u32 mcdi_to_ethtool_media(u32 media) | |||
304 | 304 | ||
305 | static int efx_mcdi_phy_probe(struct efx_nic *efx) | 305 | static int efx_mcdi_phy_probe(struct efx_nic *efx) |
306 | { | 306 | { |
307 | struct efx_mcdi_phy_cfg *phy_cfg; | 307 | struct efx_mcdi_phy_cfg *phy_data; |
308 | u8 outbuf[MC_CMD_GET_LINK_OUT_LEN]; | ||
309 | u32 caps; | ||
308 | int rc; | 310 | int rc; |
309 | 311 | ||
310 | /* TODO: Move phy_data initialisation to | 312 | /* Initialise and populate phy_data */ |
311 | * phy_op->probe/remove, rather than init/fini */ | 313 | phy_data = kzalloc(sizeof(*phy_data), GFP_KERNEL); |
312 | phy_cfg = kzalloc(sizeof(*phy_cfg), GFP_KERNEL); | 314 | if (phy_data == NULL) |
313 | if (phy_cfg == NULL) { | 315 | return -ENOMEM; |
314 | rc = -ENOMEM; | 316 | |
315 | goto fail_alloc; | 317 | rc = efx_mcdi_get_phy_cfg(efx, phy_data); |
316 | } | ||
317 | rc = efx_mcdi_get_phy_cfg(efx, phy_cfg); | ||
318 | if (rc != 0) | 318 | if (rc != 0) |
319 | goto fail; | 319 | goto fail; |
320 | 320 | ||
321 | efx->phy_type = phy_cfg->type; | 321 | /* Read initial link advertisement */ |
322 | BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0); | ||
323 | rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0, | ||
324 | outbuf, sizeof(outbuf), NULL); | ||
325 | if (rc) | ||
326 | goto fail; | ||
327 | |||
328 | /* Fill out nic state */ | ||
329 | efx->phy_data = phy_data; | ||
330 | efx->phy_type = phy_data->type; | ||
322 | 331 | ||
323 | efx->mdio_bus = phy_cfg->channel; | 332 | efx->mdio_bus = phy_data->channel; |
324 | efx->mdio.prtad = phy_cfg->port; | 333 | efx->mdio.prtad = phy_data->port; |
325 | efx->mdio.mmds = phy_cfg->mmd_mask & ~(1 << MC_CMD_MMD_CLAUSE22); | 334 | efx->mdio.mmds = phy_data->mmd_mask & ~(1 << MC_CMD_MMD_CLAUSE22); |
326 | efx->mdio.mode_support = 0; | 335 | efx->mdio.mode_support = 0; |
327 | if (phy_cfg->mmd_mask & (1 << MC_CMD_MMD_CLAUSE22)) | 336 | if (phy_data->mmd_mask & (1 << MC_CMD_MMD_CLAUSE22)) |
328 | efx->mdio.mode_support |= MDIO_SUPPORTS_C22; | 337 | efx->mdio.mode_support |= MDIO_SUPPORTS_C22; |
329 | if (phy_cfg->mmd_mask & ~(1 << MC_CMD_MMD_CLAUSE22)) | 338 | if (phy_data->mmd_mask & ~(1 << MC_CMD_MMD_CLAUSE22)) |
330 | efx->mdio.mode_support |= MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22; | 339 | efx->mdio.mode_support |= MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22; |
331 | 340 | ||
341 | caps = MCDI_DWORD(outbuf, GET_LINK_OUT_CAP); | ||
342 | if (caps & (1 << MC_CMD_PHY_CAP_AN_LBN)) | ||
343 | efx->link_advertising = | ||
344 | mcdi_to_ethtool_cap(phy_data->media, caps); | ||
345 | else | ||
346 | phy_data->forced_cap = caps; | ||
347 | |||
332 | /* Assert that we can map efx -> mcdi loopback modes */ | 348 | /* Assert that we can map efx -> mcdi loopback modes */ |
333 | BUILD_BUG_ON(LOOPBACK_NONE != MC_CMD_LOOPBACK_NONE); | 349 | BUILD_BUG_ON(LOOPBACK_NONE != MC_CMD_LOOPBACK_NONE); |
334 | BUILD_BUG_ON(LOOPBACK_DATA != MC_CMD_LOOPBACK_DATA); | 350 | BUILD_BUG_ON(LOOPBACK_DATA != MC_CMD_LOOPBACK_DATA); |
@@ -365,46 +381,6 @@ static int efx_mcdi_phy_probe(struct efx_nic *efx) | |||
365 | * but by convention we don't */ | 381 | * but by convention we don't */ |
366 | efx->loopback_modes &= ~(1 << LOOPBACK_NONE); | 382 | efx->loopback_modes &= ~(1 << LOOPBACK_NONE); |
367 | 383 | ||
368 | kfree(phy_cfg); | ||
369 | |||
370 | return 0; | ||
371 | |||
372 | fail: | ||
373 | kfree(phy_cfg); | ||
374 | fail_alloc: | ||
375 | return rc; | ||
376 | } | ||
377 | |||
378 | static int efx_mcdi_phy_init(struct efx_nic *efx) | ||
379 | { | ||
380 | struct efx_mcdi_phy_cfg *phy_data; | ||
381 | u8 outbuf[MC_CMD_GET_LINK_OUT_LEN]; | ||
382 | u32 caps; | ||
383 | int rc; | ||
384 | |||
385 | phy_data = kzalloc(sizeof(*phy_data), GFP_KERNEL); | ||
386 | if (phy_data == NULL) | ||
387 | return -ENOMEM; | ||
388 | |||
389 | rc = efx_mcdi_get_phy_cfg(efx, phy_data); | ||
390 | if (rc != 0) | ||
391 | goto fail; | ||
392 | |||
393 | efx->phy_data = phy_data; | ||
394 | |||
395 | BUILD_BUG_ON(MC_CMD_GET_LINK_IN_LEN != 0); | ||
396 | rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0, | ||
397 | outbuf, sizeof(outbuf), NULL); | ||
398 | if (rc) | ||
399 | goto fail; | ||
400 | |||
401 | caps = MCDI_DWORD(outbuf, GET_LINK_OUT_CAP); | ||
402 | if (caps & (1 << MC_CMD_PHY_CAP_AN_LBN)) | ||
403 | efx->link_advertising = | ||
404 | mcdi_to_ethtool_cap(phy_data->media, caps); | ||
405 | else | ||
406 | phy_data->forced_cap = caps; | ||
407 | |||
408 | return 0; | 384 | return 0; |
409 | 385 | ||
410 | fail: | 386 | fail: |
@@ -504,7 +480,7 @@ static bool efx_mcdi_phy_poll(struct efx_nic *efx) | |||
504 | return !efx_link_state_equal(&efx->link_state, &old_state); | 480 | return !efx_link_state_equal(&efx->link_state, &old_state); |
505 | } | 481 | } |
506 | 482 | ||
507 | static void efx_mcdi_phy_fini(struct efx_nic *efx) | 483 | static void efx_mcdi_phy_remove(struct efx_nic *efx) |
508 | { | 484 | { |
509 | struct efx_mcdi_phy_data *phy_data = efx->phy_data; | 485 | struct efx_mcdi_phy_data *phy_data = efx->phy_data; |
510 | 486 | ||
@@ -586,10 +562,11 @@ static int efx_mcdi_phy_set_settings(struct efx_nic *efx, struct ethtool_cmd *ec | |||
586 | 562 | ||
587 | struct efx_phy_operations efx_mcdi_phy_ops = { | 563 | struct efx_phy_operations efx_mcdi_phy_ops = { |
588 | .probe = efx_mcdi_phy_probe, | 564 | .probe = efx_mcdi_phy_probe, |
589 | .init = efx_mcdi_phy_init, | 565 | .init = efx_port_dummy_op_int, |
590 | .reconfigure = efx_mcdi_phy_reconfigure, | 566 | .reconfigure = efx_mcdi_phy_reconfigure, |
591 | .poll = efx_mcdi_phy_poll, | 567 | .poll = efx_mcdi_phy_poll, |
592 | .fini = efx_mcdi_phy_fini, | 568 | .fini = efx_port_dummy_op_void, |
569 | .remove = efx_mcdi_phy_remove, | ||
593 | .get_settings = efx_mcdi_phy_get_settings, | 570 | .get_settings = efx_mcdi_phy_get_settings, |
594 | .set_settings = efx_mcdi_phy_set_settings, | 571 | .set_settings = efx_mcdi_phy_set_settings, |
595 | .run_tests = NULL, | 572 | .run_tests = NULL, |
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 34c381f009b7..d5aab5b3fa06 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h | |||
@@ -524,6 +524,7 @@ struct efx_phy_operations { | |||
524 | int (*probe) (struct efx_nic *efx); | 524 | int (*probe) (struct efx_nic *efx); |
525 | int (*init) (struct efx_nic *efx); | 525 | int (*init) (struct efx_nic *efx); |
526 | void (*fini) (struct efx_nic *efx); | 526 | void (*fini) (struct efx_nic *efx); |
527 | void (*remove) (struct efx_nic *efx); | ||
527 | int (*reconfigure) (struct efx_nic *efx); | 528 | int (*reconfigure) (struct efx_nic *efx); |
528 | bool (*poll) (struct efx_nic *efx); | 529 | bool (*poll) (struct efx_nic *efx); |
529 | void (*get_settings) (struct efx_nic *efx, | 530 | void (*get_settings) (struct efx_nic *efx, |
diff --git a/drivers/net/sfc/nic.c b/drivers/net/sfc/nic.c index a577be227862..db44224ed2ca 100644 --- a/drivers/net/sfc/nic.c +++ b/drivers/net/sfc/nic.c | |||
@@ -1576,6 +1576,8 @@ void efx_nic_init_common(struct efx_nic *efx) | |||
1576 | EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_SOFT_EVT_EN, 1); | 1576 | EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_SOFT_EVT_EN, 1); |
1577 | /* Prefetch threshold 2 => fetch when descriptor cache half empty */ | 1577 | /* Prefetch threshold 2 => fetch when descriptor cache half empty */ |
1578 | EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_PREF_THRESHOLD, 2); | 1578 | EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_PREF_THRESHOLD, 2); |
1579 | /* Disable hardware watchdog which can misfire */ | ||
1580 | EFX_SET_OWORD_FIELD(temp, FRF_AZ_TX_PREF_WD_TMR, 0x3fffff); | ||
1579 | /* Squash TX of packets of 16 bytes or less */ | 1581 | /* Squash TX of packets of 16 bytes or less */ |
1580 | if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) | 1582 | if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) |
1581 | EFX_SET_OWORD_FIELD(temp, FRF_BZ_TX_FLUSH_MIN_LEN_EN, 1); | 1583 | EFX_SET_OWORD_FIELD(temp, FRF_BZ_TX_FLUSH_MIN_LEN_EN, 1); |
diff --git a/drivers/net/sfc/qt202x_phy.c b/drivers/net/sfc/qt202x_phy.c index 3800fc791b2f..ff8f0a417fa3 100644 --- a/drivers/net/sfc/qt202x_phy.c +++ b/drivers/net/sfc/qt202x_phy.c | |||
@@ -33,6 +33,9 @@ | |||
33 | #define PCS_FW_HEARTBEAT_REG 0xd7ee | 33 | #define PCS_FW_HEARTBEAT_REG 0xd7ee |
34 | #define PCS_FW_HEARTB_LBN 0 | 34 | #define PCS_FW_HEARTB_LBN 0 |
35 | #define PCS_FW_HEARTB_WIDTH 8 | 35 | #define PCS_FW_HEARTB_WIDTH 8 |
36 | #define PCS_FW_PRODUCT_CODE_1 0xd7f0 | ||
37 | #define PCS_FW_VERSION_1 0xd7f3 | ||
38 | #define PCS_FW_BUILD_1 0xd7f6 | ||
36 | #define PCS_UC8051_STATUS_REG 0xd7fd | 39 | #define PCS_UC8051_STATUS_REG 0xd7fd |
37 | #define PCS_UC_STATUS_LBN 0 | 40 | #define PCS_UC_STATUS_LBN 0 |
38 | #define PCS_UC_STATUS_WIDTH 8 | 41 | #define PCS_UC_STATUS_WIDTH 8 |
@@ -52,14 +55,24 @@ void falcon_qt202x_set_led(struct efx_nic *p, int led, int mode) | |||
52 | 55 | ||
53 | struct qt202x_phy_data { | 56 | struct qt202x_phy_data { |
54 | enum efx_phy_mode phy_mode; | 57 | enum efx_phy_mode phy_mode; |
58 | bool bug17190_in_bad_state; | ||
59 | unsigned long bug17190_timer; | ||
60 | u32 firmware_ver; | ||
55 | }; | 61 | }; |
56 | 62 | ||
57 | #define QT2022C2_MAX_RESET_TIME 500 | 63 | #define QT2022C2_MAX_RESET_TIME 500 |
58 | #define QT2022C2_RESET_WAIT 10 | 64 | #define QT2022C2_RESET_WAIT 10 |
59 | 65 | ||
60 | static int qt2025c_wait_reset(struct efx_nic *efx) | 66 | #define QT2025C_MAX_HEARTB_TIME (5 * HZ) |
67 | #define QT2025C_HEARTB_WAIT 100 | ||
68 | #define QT2025C_MAX_FWSTART_TIME (25 * HZ / 10) | ||
69 | #define QT2025C_FWSTART_WAIT 100 | ||
70 | |||
71 | #define BUG17190_INTERVAL (2 * HZ) | ||
72 | |||
73 | static int qt2025c_wait_heartbeat(struct efx_nic *efx) | ||
61 | { | 74 | { |
62 | unsigned long timeout = jiffies + 10 * HZ; | 75 | unsigned long timeout = jiffies + QT2025C_MAX_HEARTB_TIME; |
63 | int reg, old_counter = 0; | 76 | int reg, old_counter = 0; |
64 | 77 | ||
65 | /* Wait for firmware heartbeat to start */ | 78 | /* Wait for firmware heartbeat to start */ |
@@ -74,11 +87,25 @@ static int qt2025c_wait_reset(struct efx_nic *efx) | |||
74 | old_counter = counter; | 87 | old_counter = counter; |
75 | else if (counter != old_counter) | 88 | else if (counter != old_counter) |
76 | break; | 89 | break; |
77 | if (time_after(jiffies, timeout)) | 90 | if (time_after(jiffies, timeout)) { |
91 | /* Some cables have EEPROMs that conflict with the | ||
92 | * PHY's on-board EEPROM so it cannot load firmware */ | ||
93 | EFX_ERR(efx, "If an SFP+ direct attach cable is" | ||
94 | " connected, please check that it complies" | ||
95 | " with the SFP+ specification\n"); | ||
78 | return -ETIMEDOUT; | 96 | return -ETIMEDOUT; |
79 | msleep(10); | 97 | } |
98 | msleep(QT2025C_HEARTB_WAIT); | ||
80 | } | 99 | } |
81 | 100 | ||
101 | return 0; | ||
102 | } | ||
103 | |||
104 | static int qt2025c_wait_fw_status_good(struct efx_nic *efx) | ||
105 | { | ||
106 | unsigned long timeout = jiffies + QT2025C_MAX_FWSTART_TIME; | ||
107 | int reg; | ||
108 | |||
82 | /* Wait for firmware status to look good */ | 109 | /* Wait for firmware status to look good */ |
83 | for (;;) { | 110 | for (;;) { |
84 | reg = efx_mdio_read(efx, MDIO_MMD_PCS, PCS_UC8051_STATUS_REG); | 111 | reg = efx_mdio_read(efx, MDIO_MMD_PCS, PCS_UC8051_STATUS_REG); |
@@ -90,7 +117,178 @@ static int qt2025c_wait_reset(struct efx_nic *efx) | |||
90 | break; | 117 | break; |
91 | if (time_after(jiffies, timeout)) | 118 | if (time_after(jiffies, timeout)) |
92 | return -ETIMEDOUT; | 119 | return -ETIMEDOUT; |
120 | msleep(QT2025C_FWSTART_WAIT); | ||
121 | } | ||
122 | |||
123 | return 0; | ||
124 | } | ||
125 | |||
126 | static void qt2025c_restart_firmware(struct efx_nic *efx) | ||
127 | { | ||
128 | /* Restart microcontroller execution of firmware from RAM */ | ||
129 | efx_mdio_write(efx, 3, 0xe854, 0x00c0); | ||
130 | efx_mdio_write(efx, 3, 0xe854, 0x0040); | ||
131 | msleep(50); | ||
132 | } | ||
133 | |||
134 | static int qt2025c_wait_reset(struct efx_nic *efx) | ||
135 | { | ||
136 | int rc; | ||
137 | |||
138 | rc = qt2025c_wait_heartbeat(efx); | ||
139 | if (rc != 0) | ||
140 | return rc; | ||
141 | |||
142 | rc = qt2025c_wait_fw_status_good(efx); | ||
143 | if (rc == -ETIMEDOUT) { | ||
144 | /* Bug 17689: occasionally heartbeat starts but firmware status | ||
145 | * code never progresses beyond 0x00. Try again, once, after | ||
146 | * restarting execution of the firmware image. */ | ||
147 | EFX_LOG(efx, "bashing QT2025C microcontroller\n"); | ||
148 | qt2025c_restart_firmware(efx); | ||
149 | rc = qt2025c_wait_heartbeat(efx); | ||
150 | if (rc != 0) | ||
151 | return rc; | ||
152 | rc = qt2025c_wait_fw_status_good(efx); | ||
153 | } | ||
154 | |||
155 | return rc; | ||
156 | } | ||
157 | |||
158 | static void qt2025c_firmware_id(struct efx_nic *efx) | ||
159 | { | ||
160 | struct qt202x_phy_data *phy_data = efx->phy_data; | ||
161 | u8 firmware_id[9]; | ||
162 | size_t i; | ||
163 | |||
164 | for (i = 0; i < sizeof(firmware_id); i++) | ||
165 | firmware_id[i] = efx_mdio_read(efx, MDIO_MMD_PCS, | ||
166 | PCS_FW_PRODUCT_CODE_1 + i); | ||
167 | EFX_INFO(efx, "QT2025C firmware %xr%d v%d.%d.%d.%d [20%02d-%02d-%02d]\n", | ||
168 | (firmware_id[0] << 8) | firmware_id[1], firmware_id[2], | ||
169 | firmware_id[3] >> 4, firmware_id[3] & 0xf, | ||
170 | firmware_id[4], firmware_id[5], | ||
171 | firmware_id[6], firmware_id[7], firmware_id[8]); | ||
172 | phy_data->firmware_ver = ((firmware_id[3] & 0xf0) << 20) | | ||
173 | ((firmware_id[3] & 0x0f) << 16) | | ||
174 | (firmware_id[4] << 8) | firmware_id[5]; | ||
175 | } | ||
176 | |||
177 | static void qt2025c_bug17190_workaround(struct efx_nic *efx) | ||
178 | { | ||
179 | struct qt202x_phy_data *phy_data = efx->phy_data; | ||
180 | |||
181 | /* The PHY can get stuck in a state where it reports PHY_XS and PMA/PMD | ||
182 | * layers up, but PCS down (no block_lock). If we notice this state | ||
183 | * persisting for a couple of seconds, we switch PMA/PMD loopback | ||
184 | * briefly on and then off again, which is normally sufficient to | ||
185 | * recover it. | ||
186 | */ | ||
187 | if (efx->link_state.up || | ||
188 | !efx_mdio_links_ok(efx, MDIO_DEVS_PMAPMD | MDIO_DEVS_PHYXS)) { | ||
189 | phy_data->bug17190_in_bad_state = false; | ||
190 | return; | ||
191 | } | ||
192 | |||
193 | if (!phy_data->bug17190_in_bad_state) { | ||
194 | phy_data->bug17190_in_bad_state = true; | ||
195 | phy_data->bug17190_timer = jiffies + BUG17190_INTERVAL; | ||
196 | return; | ||
197 | } | ||
198 | |||
199 | if (time_after_eq(jiffies, phy_data->bug17190_timer)) { | ||
200 | EFX_LOG(efx, "bashing QT2025C PMA/PMD\n"); | ||
201 | efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, MDIO_CTRL1, | ||
202 | MDIO_PMA_CTRL1_LOOPBACK, true); | ||
93 | msleep(100); | 203 | msleep(100); |
204 | efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, MDIO_CTRL1, | ||
205 | MDIO_PMA_CTRL1_LOOPBACK, false); | ||
206 | phy_data->bug17190_timer = jiffies + BUG17190_INTERVAL; | ||
207 | } | ||
208 | } | ||
209 | |||
210 | static int qt2025c_select_phy_mode(struct efx_nic *efx) | ||
211 | { | ||
212 | struct qt202x_phy_data *phy_data = efx->phy_data; | ||
213 | struct falcon_board *board = falcon_board(efx); | ||
214 | int reg, rc, i; | ||
215 | uint16_t phy_op_mode; | ||
216 | |||
217 | /* Only 2.0.1.0+ PHY firmware supports the more optimal SFP+ | ||
218 | * Self-Configure mode. Don't attempt any switching if we encounter | ||
219 | * older firmware. */ | ||
220 | if (phy_data->firmware_ver < 0x02000100) | ||
221 | return 0; | ||
222 | |||
223 | /* In general we will get optimal behaviour in "SFP+ Self-Configure" | ||
224 | * mode; however, that powers down most of the PHY when no module is | ||
225 | * present, so we must use a different mode (any fixed mode will do) | ||
226 | * to be sure that loopbacks will work. */ | ||
227 | phy_op_mode = (efx->loopback_mode == LOOPBACK_NONE) ? 0x0038 : 0x0020; | ||
228 | |||
229 | /* Only change mode if really necessary */ | ||
230 | reg = efx_mdio_read(efx, 1, 0xc319); | ||
231 | if ((reg & 0x0038) == phy_op_mode) | ||
232 | return 0; | ||
233 | EFX_LOG(efx, "Switching PHY to mode 0x%04x\n", phy_op_mode); | ||
234 | |||
235 | /* This sequence replicates the register writes configured in the boot | ||
236 | * EEPROM (including the differences between board revisions), except | ||
237 | * that the operating mode is changed, and the PHY is prevented from | ||
238 | * unnecessarily reloading the main firmware image again. */ | ||
239 | efx_mdio_write(efx, 1, 0xc300, 0x0000); | ||
240 | /* (Note: this portion of the boot EEPROM sequence, which bit-bashes 9 | ||
241 | * STOPs onto the firmware/module I2C bus to reset it, varies across | ||
242 | * board revisions, as the bus is connected to different GPIO/LED | ||
243 | * outputs on the PHY.) */ | ||
244 | if (board->major == 0 && board->minor < 2) { | ||
245 | efx_mdio_write(efx, 1, 0xc303, 0x4498); | ||
246 | for (i = 0; i < 9; i++) { | ||
247 | efx_mdio_write(efx, 1, 0xc303, 0x4488); | ||
248 | efx_mdio_write(efx, 1, 0xc303, 0x4480); | ||
249 | efx_mdio_write(efx, 1, 0xc303, 0x4490); | ||
250 | efx_mdio_write(efx, 1, 0xc303, 0x4498); | ||
251 | } | ||
252 | } else { | ||
253 | efx_mdio_write(efx, 1, 0xc303, 0x0920); | ||
254 | efx_mdio_write(efx, 1, 0xd008, 0x0004); | ||
255 | for (i = 0; i < 9; i++) { | ||
256 | efx_mdio_write(efx, 1, 0xc303, 0x0900); | ||
257 | efx_mdio_write(efx, 1, 0xd008, 0x0005); | ||
258 | efx_mdio_write(efx, 1, 0xc303, 0x0920); | ||
259 | efx_mdio_write(efx, 1, 0xd008, 0x0004); | ||
260 | } | ||
261 | efx_mdio_write(efx, 1, 0xc303, 0x4900); | ||
262 | } | ||
263 | efx_mdio_write(efx, 1, 0xc303, 0x4900); | ||
264 | efx_mdio_write(efx, 1, 0xc302, 0x0004); | ||
265 | efx_mdio_write(efx, 1, 0xc316, 0x0013); | ||
266 | efx_mdio_write(efx, 1, 0xc318, 0x0054); | ||
267 | efx_mdio_write(efx, 1, 0xc319, phy_op_mode); | ||
268 | efx_mdio_write(efx, 1, 0xc31a, 0x0098); | ||
269 | efx_mdio_write(efx, 3, 0x0026, 0x0e00); | ||
270 | efx_mdio_write(efx, 3, 0x0027, 0x0013); | ||
271 | efx_mdio_write(efx, 3, 0x0028, 0xa528); | ||
272 | efx_mdio_write(efx, 1, 0xd006, 0x000a); | ||
273 | efx_mdio_write(efx, 1, 0xd007, 0x0009); | ||
274 | efx_mdio_write(efx, 1, 0xd008, 0x0004); | ||
275 | /* This additional write is not present in the boot EEPROM. It | ||
276 | * prevents the PHY's internal boot ROM doing another pointless (and | ||
277 | * slow) reload of the firmware image (the microcontroller's code | ||
278 | * memory is not affected by the microcontroller reset). */ | ||
279 | efx_mdio_write(efx, 1, 0xc317, 0x00ff); | ||
280 | efx_mdio_write(efx, 1, 0xc300, 0x0002); | ||
281 | msleep(20); | ||
282 | |||
283 | /* Restart microcontroller execution of firmware from RAM */ | ||
284 | qt2025c_restart_firmware(efx); | ||
285 | |||
286 | /* Wait for the microcontroller to be ready again */ | ||
287 | rc = qt2025c_wait_reset(efx); | ||
288 | if (rc < 0) { | ||
289 | EFX_ERR(efx, "PHY microcontroller reset during mode switch " | ||
290 | "timed out\n"); | ||
291 | return rc; | ||
94 | } | 292 | } |
95 | 293 | ||
96 | return 0; | 294 | return 0; |
@@ -137,6 +335,16 @@ static int qt202x_reset_phy(struct efx_nic *efx) | |||
137 | 335 | ||
138 | static int qt202x_phy_probe(struct efx_nic *efx) | 336 | static int qt202x_phy_probe(struct efx_nic *efx) |
139 | { | 337 | { |
338 | struct qt202x_phy_data *phy_data; | ||
339 | |||
340 | phy_data = kzalloc(sizeof(struct qt202x_phy_data), GFP_KERNEL); | ||
341 | if (!phy_data) | ||
342 | return -ENOMEM; | ||
343 | efx->phy_data = phy_data; | ||
344 | phy_data->phy_mode = efx->phy_mode; | ||
345 | phy_data->bug17190_in_bad_state = false; | ||
346 | phy_data->bug17190_timer = 0; | ||
347 | |||
140 | efx->mdio.mmds = QT202X_REQUIRED_DEVS; | 348 | efx->mdio.mmds = QT202X_REQUIRED_DEVS; |
141 | efx->mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22; | 349 | efx->mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22; |
142 | efx->loopback_modes = QT202X_LOOPBACKS | FALCON_XMAC_LOOPBACKS; | 350 | efx->loopback_modes = QT202X_LOOPBACKS | FALCON_XMAC_LOOPBACKS; |
@@ -145,7 +353,6 @@ static int qt202x_phy_probe(struct efx_nic *efx) | |||
145 | 353 | ||
146 | static int qt202x_phy_init(struct efx_nic *efx) | 354 | static int qt202x_phy_init(struct efx_nic *efx) |
147 | { | 355 | { |
148 | struct qt202x_phy_data *phy_data; | ||
149 | u32 devid; | 356 | u32 devid; |
150 | int rc; | 357 | int rc; |
151 | 358 | ||
@@ -155,17 +362,14 @@ static int qt202x_phy_init(struct efx_nic *efx) | |||
155 | return rc; | 362 | return rc; |
156 | } | 363 | } |
157 | 364 | ||
158 | phy_data = kzalloc(sizeof(struct qt202x_phy_data), GFP_KERNEL); | ||
159 | if (!phy_data) | ||
160 | return -ENOMEM; | ||
161 | efx->phy_data = phy_data; | ||
162 | |||
163 | devid = efx_mdio_read_id(efx, MDIO_MMD_PHYXS); | 365 | devid = efx_mdio_read_id(efx, MDIO_MMD_PHYXS); |
164 | EFX_INFO(efx, "PHY ID reg %x (OUI %06x model %02x revision %x)\n", | 366 | EFX_INFO(efx, "PHY ID reg %x (OUI %06x model %02x revision %x)\n", |
165 | devid, efx_mdio_id_oui(devid), efx_mdio_id_model(devid), | 367 | devid, efx_mdio_id_oui(devid), efx_mdio_id_model(devid), |
166 | efx_mdio_id_rev(devid)); | 368 | efx_mdio_id_rev(devid)); |
167 | 369 | ||
168 | phy_data->phy_mode = efx->phy_mode; | 370 | if (efx->phy_type == PHY_TYPE_QT2025C) |
371 | qt2025c_firmware_id(efx); | ||
372 | |||
169 | return 0; | 373 | return 0; |
170 | } | 374 | } |
171 | 375 | ||
@@ -183,6 +387,9 @@ static bool qt202x_phy_poll(struct efx_nic *efx) | |||
183 | efx->link_state.fd = true; | 387 | efx->link_state.fd = true; |
184 | efx->link_state.fc = efx->wanted_fc; | 388 | efx->link_state.fc = efx->wanted_fc; |
185 | 389 | ||
390 | if (efx->phy_type == PHY_TYPE_QT2025C) | ||
391 | qt2025c_bug17190_workaround(efx); | ||
392 | |||
186 | return efx->link_state.up != was_up; | 393 | return efx->link_state.up != was_up; |
187 | } | 394 | } |
188 | 395 | ||
@@ -191,6 +398,10 @@ static int qt202x_phy_reconfigure(struct efx_nic *efx) | |||
191 | struct qt202x_phy_data *phy_data = efx->phy_data; | 398 | struct qt202x_phy_data *phy_data = efx->phy_data; |
192 | 399 | ||
193 | if (efx->phy_type == PHY_TYPE_QT2025C) { | 400 | if (efx->phy_type == PHY_TYPE_QT2025C) { |
401 | int rc = qt2025c_select_phy_mode(efx); | ||
402 | if (rc) | ||
403 | return rc; | ||
404 | |||
194 | /* There are several different register bits which can | 405 | /* There are several different register bits which can |
195 | * disable TX (and save power) on direct-attach cables | 406 | * disable TX (and save power) on direct-attach cables |
196 | * or optical transceivers, varying somewhat between | 407 | * or optical transceivers, varying somewhat between |
@@ -224,7 +435,7 @@ static void qt202x_phy_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecm | |||
224 | mdio45_ethtool_gset(&efx->mdio, ecmd); | 435 | mdio45_ethtool_gset(&efx->mdio, ecmd); |
225 | } | 436 | } |
226 | 437 | ||
227 | static void qt202x_phy_fini(struct efx_nic *efx) | 438 | static void qt202x_phy_remove(struct efx_nic *efx) |
228 | { | 439 | { |
229 | /* Free the context block */ | 440 | /* Free the context block */ |
230 | kfree(efx->phy_data); | 441 | kfree(efx->phy_data); |
@@ -236,7 +447,8 @@ struct efx_phy_operations falcon_qt202x_phy_ops = { | |||
236 | .init = qt202x_phy_init, | 447 | .init = qt202x_phy_init, |
237 | .reconfigure = qt202x_phy_reconfigure, | 448 | .reconfigure = qt202x_phy_reconfigure, |
238 | .poll = qt202x_phy_poll, | 449 | .poll = qt202x_phy_poll, |
239 | .fini = qt202x_phy_fini, | 450 | .fini = efx_port_dummy_op_void, |
451 | .remove = qt202x_phy_remove, | ||
240 | .get_settings = qt202x_phy_get_settings, | 452 | .get_settings = qt202x_phy_get_settings, |
241 | .set_settings = efx_mdio_set_settings, | 453 | .set_settings = efx_mdio_set_settings, |
242 | }; | 454 | }; |
diff --git a/drivers/net/sfc/siena.c b/drivers/net/sfc/siena.c index de07a4f031b2..f8c6771e66d8 100644 --- a/drivers/net/sfc/siena.c +++ b/drivers/net/sfc/siena.c | |||
@@ -133,6 +133,7 @@ static int siena_probe_port(struct efx_nic *efx) | |||
133 | 133 | ||
134 | void siena_remove_port(struct efx_nic *efx) | 134 | void siena_remove_port(struct efx_nic *efx) |
135 | { | 135 | { |
136 | efx->phy_op->remove(efx); | ||
136 | efx_nic_free_buffer(efx, &efx->stats_buffer); | 137 | efx_nic_free_buffer(efx, &efx->stats_buffer); |
137 | } | 138 | } |
138 | 139 | ||
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c index ca11572a49a9..3009c297c135 100644 --- a/drivers/net/sfc/tenxpress.c +++ b/drivers/net/sfc/tenxpress.c | |||
@@ -202,10 +202,14 @@ static ssize_t set_phy_short_reach(struct device *dev, | |||
202 | int rc; | 202 | int rc; |
203 | 203 | ||
204 | rtnl_lock(); | 204 | rtnl_lock(); |
205 | efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, MDIO_PMA_10GBT_TXPWR, | 205 | if (efx->state != STATE_RUNNING) { |
206 | MDIO_PMA_10GBT_TXPWR_SHORT, | 206 | rc = -EBUSY; |
207 | count != 0 && *buf != '0'); | 207 | } else { |
208 | rc = efx_reconfigure_port(efx); | 208 | efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, MDIO_PMA_10GBT_TXPWR, |
209 | MDIO_PMA_10GBT_TXPWR_SHORT, | ||
210 | count != 0 && *buf != '0'); | ||
211 | rc = efx_reconfigure_port(efx); | ||
212 | } | ||
209 | rtnl_unlock(); | 213 | rtnl_unlock(); |
210 | 214 | ||
211 | return rc < 0 ? rc : (ssize_t)count; | 215 | return rc < 0 ? rc : (ssize_t)count; |
@@ -298,36 +302,62 @@ static int tenxpress_init(struct efx_nic *efx) | |||
298 | return 0; | 302 | return 0; |
299 | } | 303 | } |
300 | 304 | ||
301 | static int sfx7101_phy_probe(struct efx_nic *efx) | 305 | static int tenxpress_phy_probe(struct efx_nic *efx) |
302 | { | 306 | { |
303 | efx->mdio.mmds = TENXPRESS_REQUIRED_DEVS; | 307 | struct tenxpress_phy_data *phy_data; |
304 | efx->mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22; | 308 | int rc; |
305 | efx->loopback_modes = SFX7101_LOOPBACKS | FALCON_XMAC_LOOPBACKS; | 309 | |
306 | return 0; | 310 | /* Allocate phy private storage */ |
307 | } | 311 | phy_data = kzalloc(sizeof(*phy_data), GFP_KERNEL); |
312 | if (!phy_data) | ||
313 | return -ENOMEM; | ||
314 | efx->phy_data = phy_data; | ||
315 | phy_data->phy_mode = efx->phy_mode; | ||
316 | |||
317 | /* Create any special files */ | ||
318 | if (efx->phy_type == PHY_TYPE_SFT9001B) { | ||
319 | rc = device_create_file(&efx->pci_dev->dev, | ||
320 | &dev_attr_phy_short_reach); | ||
321 | if (rc) | ||
322 | goto fail; | ||
323 | } | ||
324 | |||
325 | if (efx->phy_type == PHY_TYPE_SFX7101) { | ||
326 | efx->mdio.mmds = TENXPRESS_REQUIRED_DEVS; | ||
327 | efx->mdio.mode_support = MDIO_SUPPORTS_C45; | ||
328 | |||
329 | efx->loopback_modes = SFX7101_LOOPBACKS | FALCON_XMAC_LOOPBACKS; | ||
330 | |||
331 | efx->link_advertising = (ADVERTISED_TP | ADVERTISED_Autoneg | | ||
332 | ADVERTISED_10000baseT_Full); | ||
333 | } else { | ||
334 | efx->mdio.mmds = TENXPRESS_REQUIRED_DEVS; | ||
335 | efx->mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22; | ||
336 | |||
337 | efx->loopback_modes = (SFT9001_LOOPBACKS | | ||
338 | FALCON_XMAC_LOOPBACKS | | ||
339 | FALCON_GMAC_LOOPBACKS); | ||
340 | |||
341 | efx->link_advertising = (ADVERTISED_TP | ADVERTISED_Autoneg | | ||
342 | ADVERTISED_10000baseT_Full | | ||
343 | ADVERTISED_1000baseT_Full | | ||
344 | ADVERTISED_100baseT_Full); | ||
345 | } | ||
308 | 346 | ||
309 | static int sft9001_phy_probe(struct efx_nic *efx) | ||
310 | { | ||
311 | efx->mdio.mmds = TENXPRESS_REQUIRED_DEVS; | ||
312 | efx->mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22; | ||
313 | efx->loopback_modes = (SFT9001_LOOPBACKS | FALCON_XMAC_LOOPBACKS | | ||
314 | FALCON_GMAC_LOOPBACKS); | ||
315 | return 0; | 347 | return 0; |
348 | |||
349 | fail: | ||
350 | kfree(efx->phy_data); | ||
351 | efx->phy_data = NULL; | ||
352 | return rc; | ||
316 | } | 353 | } |
317 | 354 | ||
318 | static int tenxpress_phy_init(struct efx_nic *efx) | 355 | static int tenxpress_phy_init(struct efx_nic *efx) |
319 | { | 356 | { |
320 | struct tenxpress_phy_data *phy_data; | 357 | int rc; |
321 | int rc = 0; | ||
322 | 358 | ||
323 | falcon_board(efx)->type->init_phy(efx); | 359 | falcon_board(efx)->type->init_phy(efx); |
324 | 360 | ||
325 | phy_data = kzalloc(sizeof(*phy_data), GFP_KERNEL); | ||
326 | if (!phy_data) | ||
327 | return -ENOMEM; | ||
328 | efx->phy_data = phy_data; | ||
329 | phy_data->phy_mode = efx->phy_mode; | ||
330 | |||
331 | if (!(efx->phy_mode & PHY_MODE_SPECIAL)) { | 361 | if (!(efx->phy_mode & PHY_MODE_SPECIAL)) { |
332 | if (efx->phy_type == PHY_TYPE_SFT9001A) { | 362 | if (efx->phy_type == PHY_TYPE_SFT9001A) { |
333 | int reg; | 363 | int reg; |
@@ -341,44 +371,27 @@ static int tenxpress_phy_init(struct efx_nic *efx) | |||
341 | 371 | ||
342 | rc = efx_mdio_wait_reset_mmds(efx, TENXPRESS_REQUIRED_DEVS); | 372 | rc = efx_mdio_wait_reset_mmds(efx, TENXPRESS_REQUIRED_DEVS); |
343 | if (rc < 0) | 373 | if (rc < 0) |
344 | goto fail; | 374 | return rc; |
345 | 375 | ||
346 | rc = efx_mdio_check_mmds(efx, TENXPRESS_REQUIRED_DEVS, 0); | 376 | rc = efx_mdio_check_mmds(efx, TENXPRESS_REQUIRED_DEVS, 0); |
347 | if (rc < 0) | 377 | if (rc < 0) |
348 | goto fail; | 378 | return rc; |
349 | } | 379 | } |
350 | 380 | ||
351 | rc = tenxpress_init(efx); | 381 | rc = tenxpress_init(efx); |
352 | if (rc < 0) | 382 | if (rc < 0) |
353 | goto fail; | 383 | return rc; |
354 | 384 | ||
355 | /* Initialise advertising flags */ | 385 | /* Reinitialise flow control settings */ |
356 | efx->link_advertising = (ADVERTISED_TP | ADVERTISED_Autoneg | | ||
357 | ADVERTISED_10000baseT_Full); | ||
358 | if (efx->phy_type != PHY_TYPE_SFX7101) | ||
359 | efx->link_advertising |= (ADVERTISED_1000baseT_Full | | ||
360 | ADVERTISED_100baseT_Full); | ||
361 | efx_link_set_wanted_fc(efx, efx->wanted_fc); | 386 | efx_link_set_wanted_fc(efx, efx->wanted_fc); |
362 | efx_mdio_an_reconfigure(efx); | 387 | efx_mdio_an_reconfigure(efx); |
363 | 388 | ||
364 | if (efx->phy_type == PHY_TYPE_SFT9001B) { | ||
365 | rc = device_create_file(&efx->pci_dev->dev, | ||
366 | &dev_attr_phy_short_reach); | ||
367 | if (rc) | ||
368 | goto fail; | ||
369 | } | ||
370 | |||
371 | schedule_timeout_uninterruptible(HZ / 5); /* 200ms */ | 389 | schedule_timeout_uninterruptible(HZ / 5); /* 200ms */ |
372 | 390 | ||
373 | /* Let XGXS and SerDes out of reset */ | 391 | /* Let XGXS and SerDes out of reset */ |
374 | falcon_reset_xaui(efx); | 392 | falcon_reset_xaui(efx); |
375 | 393 | ||
376 | return 0; | 394 | return 0; |
377 | |||
378 | fail: | ||
379 | kfree(efx->phy_data); | ||
380 | efx->phy_data = NULL; | ||
381 | return rc; | ||
382 | } | 395 | } |
383 | 396 | ||
384 | /* Perform a "special software reset" on the PHY. The caller is | 397 | /* Perform a "special software reset" on the PHY. The caller is |
@@ -589,25 +602,26 @@ static bool tenxpress_phy_poll(struct efx_nic *efx) | |||
589 | return !efx_link_state_equal(&efx->link_state, &old_state); | 602 | return !efx_link_state_equal(&efx->link_state, &old_state); |
590 | } | 603 | } |
591 | 604 | ||
592 | static void tenxpress_phy_fini(struct efx_nic *efx) | 605 | static void sfx7101_phy_fini(struct efx_nic *efx) |
593 | { | 606 | { |
594 | int reg; | 607 | int reg; |
595 | 608 | ||
609 | /* Power down the LNPGA */ | ||
610 | reg = (1 << PMA_PMD_LNPGA_POWERDOWN_LBN); | ||
611 | efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG, reg); | ||
612 | |||
613 | /* Waiting here ensures that the board fini, which can turn | ||
614 | * off the power to the PHY, won't get run until the LNPGA | ||
615 | * powerdown has been given long enough to complete. */ | ||
616 | schedule_timeout_uninterruptible(LNPGA_PDOWN_WAIT); /* 200 ms */ | ||
617 | } | ||
618 | |||
619 | static void tenxpress_phy_remove(struct efx_nic *efx) | ||
620 | { | ||
596 | if (efx->phy_type == PHY_TYPE_SFT9001B) | 621 | if (efx->phy_type == PHY_TYPE_SFT9001B) |
597 | device_remove_file(&efx->pci_dev->dev, | 622 | device_remove_file(&efx->pci_dev->dev, |
598 | &dev_attr_phy_short_reach); | 623 | &dev_attr_phy_short_reach); |
599 | 624 | ||
600 | if (efx->phy_type == PHY_TYPE_SFX7101) { | ||
601 | /* Power down the LNPGA */ | ||
602 | reg = (1 << PMA_PMD_LNPGA_POWERDOWN_LBN); | ||
603 | efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG, reg); | ||
604 | |||
605 | /* Waiting here ensures that the board fini, which can turn | ||
606 | * off the power to the PHY, won't get run until the LNPGA | ||
607 | * powerdown has been given long enough to complete. */ | ||
608 | schedule_timeout_uninterruptible(LNPGA_PDOWN_WAIT); /* 200 ms */ | ||
609 | } | ||
610 | |||
611 | kfree(efx->phy_data); | 625 | kfree(efx->phy_data); |
612 | efx->phy_data = NULL; | 626 | efx->phy_data = NULL; |
613 | } | 627 | } |
@@ -819,11 +833,12 @@ static void sft9001_set_npage_adv(struct efx_nic *efx, u32 advertising) | |||
819 | } | 833 | } |
820 | 834 | ||
821 | struct efx_phy_operations falcon_sfx7101_phy_ops = { | 835 | struct efx_phy_operations falcon_sfx7101_phy_ops = { |
822 | .probe = sfx7101_phy_probe, | 836 | .probe = tenxpress_phy_probe, |
823 | .init = tenxpress_phy_init, | 837 | .init = tenxpress_phy_init, |
824 | .reconfigure = tenxpress_phy_reconfigure, | 838 | .reconfigure = tenxpress_phy_reconfigure, |
825 | .poll = tenxpress_phy_poll, | 839 | .poll = tenxpress_phy_poll, |
826 | .fini = tenxpress_phy_fini, | 840 | .fini = sfx7101_phy_fini, |
841 | .remove = tenxpress_phy_remove, | ||
827 | .get_settings = tenxpress_get_settings, | 842 | .get_settings = tenxpress_get_settings, |
828 | .set_settings = tenxpress_set_settings, | 843 | .set_settings = tenxpress_set_settings, |
829 | .set_npage_adv = sfx7101_set_npage_adv, | 844 | .set_npage_adv = sfx7101_set_npage_adv, |
@@ -832,11 +847,12 @@ struct efx_phy_operations falcon_sfx7101_phy_ops = { | |||
832 | }; | 847 | }; |
833 | 848 | ||
834 | struct efx_phy_operations falcon_sft9001_phy_ops = { | 849 | struct efx_phy_operations falcon_sft9001_phy_ops = { |
835 | .probe = sft9001_phy_probe, | 850 | .probe = tenxpress_phy_probe, |
836 | .init = tenxpress_phy_init, | 851 | .init = tenxpress_phy_init, |
837 | .reconfigure = tenxpress_phy_reconfigure, | 852 | .reconfigure = tenxpress_phy_reconfigure, |
838 | .poll = tenxpress_phy_poll, | 853 | .poll = tenxpress_phy_poll, |
839 | .fini = tenxpress_phy_fini, | 854 | .fini = efx_port_dummy_op_void, |
855 | .remove = tenxpress_phy_remove, | ||
840 | .get_settings = tenxpress_get_settings, | 856 | .get_settings = tenxpress_get_settings, |
841 | .set_settings = tenxpress_set_settings, | 857 | .set_settings = tenxpress_set_settings, |
842 | .set_npage_adv = sft9001_set_npage_adv, | 858 | .set_npage_adv = sft9001_set_npage_adv, |
diff --git a/drivers/net/sfc/tx.c b/drivers/net/sfc/tx.c index e669f94e821b..a8b70ef6d817 100644 --- a/drivers/net/sfc/tx.c +++ b/drivers/net/sfc/tx.c | |||
@@ -821,8 +821,6 @@ static void efx_enqueue_unwind(struct efx_tx_queue *tx_queue) | |||
821 | EFX_TXQ_MASK]; | 821 | EFX_TXQ_MASK]; |
822 | efx_tsoh_free(tx_queue, buffer); | 822 | efx_tsoh_free(tx_queue, buffer); |
823 | EFX_BUG_ON_PARANOID(buffer->skb); | 823 | EFX_BUG_ON_PARANOID(buffer->skb); |
824 | buffer->len = 0; | ||
825 | buffer->continuation = true; | ||
826 | if (buffer->unmap_len) { | 824 | if (buffer->unmap_len) { |
827 | unmap_addr = (buffer->dma_addr + buffer->len - | 825 | unmap_addr = (buffer->dma_addr + buffer->len - |
828 | buffer->unmap_len); | 826 | buffer->unmap_len); |
@@ -836,6 +834,8 @@ static void efx_enqueue_unwind(struct efx_tx_queue *tx_queue) | |||
836 | PCI_DMA_TODEVICE); | 834 | PCI_DMA_TODEVICE); |
837 | buffer->unmap_len = 0; | 835 | buffer->unmap_len = 0; |
838 | } | 836 | } |
837 | buffer->len = 0; | ||
838 | buffer->continuation = true; | ||
839 | } | 839 | } |
840 | } | 840 | } |
841 | 841 | ||
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 01e99f22210e..2834a01bae24 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
@@ -849,13 +849,13 @@ static void tun_sock_write_space(struct sock *sk) | |||
849 | if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) | 849 | if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) |
850 | wake_up_interruptible_sync(sk->sk_sleep); | 850 | wake_up_interruptible_sync(sk->sk_sleep); |
851 | 851 | ||
852 | tun = container_of(sk, struct tun_sock, sk)->tun; | 852 | tun = tun_sk(sk)->tun; |
853 | kill_fasync(&tun->fasync, SIGIO, POLL_OUT); | 853 | kill_fasync(&tun->fasync, SIGIO, POLL_OUT); |
854 | } | 854 | } |
855 | 855 | ||
856 | static void tun_sock_destruct(struct sock *sk) | 856 | static void tun_sock_destruct(struct sock *sk) |
857 | { | 857 | { |
858 | free_netdev(container_of(sk, struct tun_sock, sk)->tun->dev); | 858 | free_netdev(tun_sk(sk)->tun->dev); |
859 | } | 859 | } |
860 | 860 | ||
861 | static struct proto tun_proto = { | 861 | static struct proto tun_proto = { |
@@ -990,7 +990,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) | |||
990 | sk->sk_write_space = tun_sock_write_space; | 990 | sk->sk_write_space = tun_sock_write_space; |
991 | sk->sk_sndbuf = INT_MAX; | 991 | sk->sk_sndbuf = INT_MAX; |
992 | 992 | ||
993 | container_of(sk, struct tun_sock, sk)->tun = tun; | 993 | tun_sk(sk)->tun = tun; |
994 | 994 | ||
995 | security_tun_dev_post_create(sk); | 995 | security_tun_dev_post_create(sk); |
996 | 996 | ||
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index afaf088b72ea..41ad2f3697c7 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c | |||
@@ -1563,7 +1563,10 @@ static int ugeth_disable(struct ucc_geth_private *ugeth, enum comm_dir mode) | |||
1563 | 1563 | ||
1564 | static void ugeth_quiesce(struct ucc_geth_private *ugeth) | 1564 | static void ugeth_quiesce(struct ucc_geth_private *ugeth) |
1565 | { | 1565 | { |
1566 | /* Wait for and prevent any further xmits. */ | 1566 | /* Prevent any further xmits, plus detach the device. */ |
1567 | netif_device_detach(ugeth->ndev); | ||
1568 | |||
1569 | /* Wait for any current xmits to finish. */ | ||
1567 | netif_tx_disable(ugeth->ndev); | 1570 | netif_tx_disable(ugeth->ndev); |
1568 | 1571 | ||
1569 | /* Disable the interrupt to avoid NAPI rescheduling. */ | 1572 | /* Disable the interrupt to avoid NAPI rescheduling. */ |
@@ -1577,7 +1580,7 @@ static void ugeth_activate(struct ucc_geth_private *ugeth) | |||
1577 | { | 1580 | { |
1578 | napi_enable(&ugeth->napi); | 1581 | napi_enable(&ugeth->napi); |
1579 | enable_irq(ugeth->ug_info->uf_info.irq); | 1582 | enable_irq(ugeth->ug_info->uf_info.irq); |
1580 | netif_tx_wake_all_queues(ugeth->ndev); | 1583 | netif_device_attach(ugeth->ndev); |
1581 | } | 1584 | } |
1582 | 1585 | ||
1583 | /* Called every time the controller might need to be made | 1586 | /* Called every time the controller might need to be made |
@@ -1648,25 +1651,28 @@ static void adjust_link(struct net_device *dev) | |||
1648 | ugeth->oldspeed = phydev->speed; | 1651 | ugeth->oldspeed = phydev->speed; |
1649 | } | 1652 | } |
1650 | 1653 | ||
1651 | /* | ||
1652 | * To change the MAC configuration we need to disable the | ||
1653 | * controller. To do so, we have to either grab ugeth->lock, | ||
1654 | * which is a bad idea since 'graceful stop' commands might | ||
1655 | * take quite a while, or we can quiesce driver's activity. | ||
1656 | */ | ||
1657 | ugeth_quiesce(ugeth); | ||
1658 | ugeth_disable(ugeth, COMM_DIR_RX_AND_TX); | ||
1659 | |||
1660 | out_be32(&ug_regs->maccfg2, tempval); | ||
1661 | out_be32(&uf_regs->upsmr, upsmr); | ||
1662 | |||
1663 | ugeth_enable(ugeth, COMM_DIR_RX_AND_TX); | ||
1664 | ugeth_activate(ugeth); | ||
1665 | |||
1666 | if (!ugeth->oldlink) { | 1654 | if (!ugeth->oldlink) { |
1667 | new_state = 1; | 1655 | new_state = 1; |
1668 | ugeth->oldlink = 1; | 1656 | ugeth->oldlink = 1; |
1669 | } | 1657 | } |
1658 | |||
1659 | if (new_state) { | ||
1660 | /* | ||
1661 | * To change the MAC configuration we need to disable | ||
1662 | * the controller. To do so, we have to either grab | ||
1663 | * ugeth->lock, which is a bad idea since 'graceful | ||
1664 | * stop' commands might take quite a while, or we can | ||
1665 | * quiesce driver's activity. | ||
1666 | */ | ||
1667 | ugeth_quiesce(ugeth); | ||
1668 | ugeth_disable(ugeth, COMM_DIR_RX_AND_TX); | ||
1669 | |||
1670 | out_be32(&ug_regs->maccfg2, tempval); | ||
1671 | out_be32(&uf_regs->upsmr, upsmr); | ||
1672 | |||
1673 | ugeth_enable(ugeth, COMM_DIR_RX_AND_TX); | ||
1674 | ugeth_activate(ugeth); | ||
1675 | } | ||
1670 | } else if (ugeth->oldlink) { | 1676 | } else if (ugeth->oldlink) { |
1671 | new_state = 1; | 1677 | new_state = 1; |
1672 | ugeth->oldlink = 0; | 1678 | ugeth->oldlink = 0; |
@@ -3273,7 +3279,7 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ) | |||
3273 | /* Handle the transmitted buffer and release */ | 3279 | /* Handle the transmitted buffer and release */ |
3274 | /* the BD to be used with the current frame */ | 3280 | /* the BD to be used with the current frame */ |
3275 | 3281 | ||
3276 | if ((bd == ugeth->txBd[txQ]) && (netif_queue_stopped(dev) == 0)) | 3282 | if (bd == ugeth->txBd[txQ]) /* queue empty? */ |
3277 | break; | 3283 | break; |
3278 | 3284 | ||
3279 | dev->stats.tx_packets++; | 3285 | dev->stats.tx_packets++; |
diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c index 593e01f64e9b..611b80435955 100644 --- a/drivers/net/via-rhine.c +++ b/drivers/net/via-rhine.c | |||
@@ -102,6 +102,7 @@ static const int multicast_filter_limit = 32; | |||
102 | #include <linux/ethtool.h> | 102 | #include <linux/ethtool.h> |
103 | #include <linux/crc32.h> | 103 | #include <linux/crc32.h> |
104 | #include <linux/bitops.h> | 104 | #include <linux/bitops.h> |
105 | #include <linux/workqueue.h> | ||
105 | #include <asm/processor.h> /* Processor type for cache alignment. */ | 106 | #include <asm/processor.h> /* Processor type for cache alignment. */ |
106 | #include <asm/io.h> | 107 | #include <asm/io.h> |
107 | #include <asm/irq.h> | 108 | #include <asm/irq.h> |
@@ -389,6 +390,7 @@ struct rhine_private { | |||
389 | struct net_device *dev; | 390 | struct net_device *dev; |
390 | struct napi_struct napi; | 391 | struct napi_struct napi; |
391 | spinlock_t lock; | 392 | spinlock_t lock; |
393 | struct work_struct reset_task; | ||
392 | 394 | ||
393 | /* Frequently used values: keep some adjacent for cache effect. */ | 395 | /* Frequently used values: keep some adjacent for cache effect. */ |
394 | u32 quirks; | 396 | u32 quirks; |
@@ -407,6 +409,7 @@ struct rhine_private { | |||
407 | static int mdio_read(struct net_device *dev, int phy_id, int location); | 409 | static int mdio_read(struct net_device *dev, int phy_id, int location); |
408 | static void mdio_write(struct net_device *dev, int phy_id, int location, int value); | 410 | static void mdio_write(struct net_device *dev, int phy_id, int location, int value); |
409 | static int rhine_open(struct net_device *dev); | 411 | static int rhine_open(struct net_device *dev); |
412 | static void rhine_reset_task(struct work_struct *work); | ||
410 | static void rhine_tx_timeout(struct net_device *dev); | 413 | static void rhine_tx_timeout(struct net_device *dev); |
411 | static netdev_tx_t rhine_start_tx(struct sk_buff *skb, | 414 | static netdev_tx_t rhine_start_tx(struct sk_buff *skb, |
412 | struct net_device *dev); | 415 | struct net_device *dev); |
@@ -775,6 +778,8 @@ static int __devinit rhine_init_one(struct pci_dev *pdev, | |||
775 | dev->irq = pdev->irq; | 778 | dev->irq = pdev->irq; |
776 | 779 | ||
777 | spin_lock_init(&rp->lock); | 780 | spin_lock_init(&rp->lock); |
781 | INIT_WORK(&rp->reset_task, rhine_reset_task); | ||
782 | |||
778 | rp->mii_if.dev = dev; | 783 | rp->mii_if.dev = dev; |
779 | rp->mii_if.mdio_read = mdio_read; | 784 | rp->mii_if.mdio_read = mdio_read; |
780 | rp->mii_if.mdio_write = mdio_write; | 785 | rp->mii_if.mdio_write = mdio_write; |
@@ -1179,22 +1184,18 @@ static int rhine_open(struct net_device *dev) | |||
1179 | return 0; | 1184 | return 0; |
1180 | } | 1185 | } |
1181 | 1186 | ||
1182 | static void rhine_tx_timeout(struct net_device *dev) | 1187 | static void rhine_reset_task(struct work_struct *work) |
1183 | { | 1188 | { |
1184 | struct rhine_private *rp = netdev_priv(dev); | 1189 | struct rhine_private *rp = container_of(work, struct rhine_private, |
1185 | void __iomem *ioaddr = rp->base; | 1190 | reset_task); |
1186 | 1191 | struct net_device *dev = rp->dev; | |
1187 | printk(KERN_WARNING "%s: Transmit timed out, status %4.4x, PHY status " | ||
1188 | "%4.4x, resetting...\n", | ||
1189 | dev->name, ioread16(ioaddr + IntrStatus), | ||
1190 | mdio_read(dev, rp->mii_if.phy_id, MII_BMSR)); | ||
1191 | 1192 | ||
1192 | /* protect against concurrent rx interrupts */ | 1193 | /* protect against concurrent rx interrupts */ |
1193 | disable_irq(rp->pdev->irq); | 1194 | disable_irq(rp->pdev->irq); |
1194 | 1195 | ||
1195 | napi_disable(&rp->napi); | 1196 | napi_disable(&rp->napi); |
1196 | 1197 | ||
1197 | spin_lock(&rp->lock); | 1198 | spin_lock_bh(&rp->lock); |
1198 | 1199 | ||
1199 | /* clear all descriptors */ | 1200 | /* clear all descriptors */ |
1200 | free_tbufs(dev); | 1201 | free_tbufs(dev); |
@@ -1206,7 +1207,7 @@ static void rhine_tx_timeout(struct net_device *dev) | |||
1206 | rhine_chip_reset(dev); | 1207 | rhine_chip_reset(dev); |
1207 | init_registers(dev); | 1208 | init_registers(dev); |
1208 | 1209 | ||
1209 | spin_unlock(&rp->lock); | 1210 | spin_unlock_bh(&rp->lock); |
1210 | enable_irq(rp->pdev->irq); | 1211 | enable_irq(rp->pdev->irq); |
1211 | 1212 | ||
1212 | dev->trans_start = jiffies; | 1213 | dev->trans_start = jiffies; |
@@ -1214,6 +1215,19 @@ static void rhine_tx_timeout(struct net_device *dev) | |||
1214 | netif_wake_queue(dev); | 1215 | netif_wake_queue(dev); |
1215 | } | 1216 | } |
1216 | 1217 | ||
1218 | static void rhine_tx_timeout(struct net_device *dev) | ||
1219 | { | ||
1220 | struct rhine_private *rp = netdev_priv(dev); | ||
1221 | void __iomem *ioaddr = rp->base; | ||
1222 | |||
1223 | printk(KERN_WARNING "%s: Transmit timed out, status %4.4x, PHY status " | ||
1224 | "%4.4x, resetting...\n", | ||
1225 | dev->name, ioread16(ioaddr + IntrStatus), | ||
1226 | mdio_read(dev, rp->mii_if.phy_id, MII_BMSR)); | ||
1227 | |||
1228 | schedule_work(&rp->reset_task); | ||
1229 | } | ||
1230 | |||
1217 | static netdev_tx_t rhine_start_tx(struct sk_buff *skb, | 1231 | static netdev_tx_t rhine_start_tx(struct sk_buff *skb, |
1218 | struct net_device *dev) | 1232 | struct net_device *dev) |
1219 | { | 1233 | { |
@@ -1830,10 +1844,11 @@ static int rhine_close(struct net_device *dev) | |||
1830 | struct rhine_private *rp = netdev_priv(dev); | 1844 | struct rhine_private *rp = netdev_priv(dev); |
1831 | void __iomem *ioaddr = rp->base; | 1845 | void __iomem *ioaddr = rp->base; |
1832 | 1846 | ||
1833 | spin_lock_irq(&rp->lock); | ||
1834 | |||
1835 | netif_stop_queue(dev); | ||
1836 | napi_disable(&rp->napi); | 1847 | napi_disable(&rp->napi); |
1848 | cancel_work_sync(&rp->reset_task); | ||
1849 | netif_stop_queue(dev); | ||
1850 | |||
1851 | spin_lock_irq(&rp->lock); | ||
1837 | 1852 | ||
1838 | if (debug > 1) | 1853 | if (debug > 1) |
1839 | printk(KERN_DEBUG "%s: Shutting down ethercard, " | 1854 | printk(KERN_DEBUG "%s: Shutting down ethercard, " |
diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index f1c4b2a1e867..0fdfd58a35a1 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c | |||
@@ -4087,21 +4087,21 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
4087 | goto _exit0; | 4087 | goto _exit0; |
4088 | } | 4088 | } |
4089 | 4089 | ||
4090 | if (!pci_set_dma_mask(pdev, 0xffffffffffffffffULL)) { | 4090 | if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { |
4091 | vxge_debug_ll_config(VXGE_TRACE, | 4091 | vxge_debug_ll_config(VXGE_TRACE, |
4092 | "%s : using 64bit DMA", __func__); | 4092 | "%s : using 64bit DMA", __func__); |
4093 | 4093 | ||
4094 | high_dma = 1; | 4094 | high_dma = 1; |
4095 | 4095 | ||
4096 | if (pci_set_consistent_dma_mask(pdev, | 4096 | if (pci_set_consistent_dma_mask(pdev, |
4097 | 0xffffffffffffffffULL)) { | 4097 | DMA_BIT_MASK(64))) { |
4098 | vxge_debug_init(VXGE_ERR, | 4098 | vxge_debug_init(VXGE_ERR, |
4099 | "%s : unable to obtain 64bit DMA for " | 4099 | "%s : unable to obtain 64bit DMA for " |
4100 | "consistent allocations", __func__); | 4100 | "consistent allocations", __func__); |
4101 | ret = -ENOMEM; | 4101 | ret = -ENOMEM; |
4102 | goto _exit1; | 4102 | goto _exit1; |
4103 | } | 4103 | } |
4104 | } else if (!pci_set_dma_mask(pdev, 0xffffffffUL)) { | 4104 | } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) { |
4105 | vxge_debug_ll_config(VXGE_TRACE, | 4105 | vxge_debug_ll_config(VXGE_TRACE, |
4106 | "%s : using 32bit DMA", __func__); | 4106 | "%s : using 32bit DMA", __func__); |
4107 | } else { | 4107 | } else { |
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index a4c086f069b1..e63b7c40d0ee 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
@@ -1903,17 +1903,6 @@ accept: | |||
1903 | rxs->noise = sc->ah->ah_noise_floor; | 1903 | rxs->noise = sc->ah->ah_noise_floor; |
1904 | rxs->signal = rxs->noise + rs.rs_rssi; | 1904 | rxs->signal = rxs->noise + rs.rs_rssi; |
1905 | 1905 | ||
1906 | /* An rssi of 35 indicates you should be able use | ||
1907 | * 54 Mbps reliably. A more elaborate scheme can be used | ||
1908 | * here but it requires a map of SNR/throughput for each | ||
1909 | * possible mode used */ | ||
1910 | rxs->qual = rs.rs_rssi * 100 / 35; | ||
1911 | |||
1912 | /* rssi can be more than 35 though, anything above that | ||
1913 | * should be considered at 100% */ | ||
1914 | if (rxs->qual > 100) | ||
1915 | rxs->qual = 100; | ||
1916 | |||
1917 | rxs->antenna = rs.rs_antenna; | 1906 | rxs->antenna = rs.rs_antenna; |
1918 | rxs->rate_idx = ath5k_hw_to_driver_rix(sc, rs.rs_rate); | 1907 | rxs->rate_idx = ath5k_hw_to_driver_rix(sc, rs.rs_rate); |
1919 | rxs->flag |= ath5k_rx_decrypted(sc, ds, skb, &rs); | 1908 | rxs->flag |= ath5k_rx_decrypted(sc, ds, skb, &rs); |
@@ -2381,6 +2370,9 @@ ath5k_init(struct ath5k_softc *sc) | |||
2381 | */ | 2370 | */ |
2382 | ath5k_stop_locked(sc); | 2371 | ath5k_stop_locked(sc); |
2383 | 2372 | ||
2373 | /* Set PHY calibration interval */ | ||
2374 | ah->ah_cal_intval = ath5k_calinterval; | ||
2375 | |||
2384 | /* | 2376 | /* |
2385 | * The basic interface to setting the hardware in a good | 2377 | * The basic interface to setting the hardware in a good |
2386 | * state is ``reset''. On return the hardware is known to | 2378 | * state is ``reset''. On return the hardware is known to |
@@ -2408,10 +2400,6 @@ ath5k_init(struct ath5k_softc *sc) | |||
2408 | 2400 | ||
2409 | /* Set ack to be sent at low bit-rates */ | 2401 | /* Set ack to be sent at low bit-rates */ |
2410 | ath5k_hw_set_ack_bitrate_high(ah, false); | 2402 | ath5k_hw_set_ack_bitrate_high(ah, false); |
2411 | |||
2412 | /* Set PHY calibration inteval */ | ||
2413 | ah->ah_cal_intval = ath5k_calinterval; | ||
2414 | |||
2415 | ret = 0; | 2403 | ret = 0; |
2416 | done: | 2404 | done: |
2417 | mmiowb(); | 2405 | mmiowb(); |
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index 71b84d91dcff..efc420cd42bf 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c | |||
@@ -186,7 +186,7 @@ bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q) | |||
186 | wait = wait_time; | 186 | wait = wait_time; |
187 | while (ath9k_hw_numtxpending(ah, q)) { | 187 | while (ath9k_hw_numtxpending(ah, q)) { |
188 | if ((--wait) == 0) { | 188 | if ((--wait) == 0) { |
189 | ath_print(common, ATH_DBG_QUEUE, | 189 | ath_print(common, ATH_DBG_FATAL, |
190 | "Failed to stop TX DMA in 100 " | 190 | "Failed to stop TX DMA in 100 " |
191 | "msec after killing last frame\n"); | 191 | "msec after killing last frame\n"); |
192 | break; | 192 | break; |
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h index 0c87771383f0..e185479e295e 100644 --- a/drivers/net/wireless/ath/ath9k/mac.h +++ b/drivers/net/wireless/ath/ath9k/mac.h | |||
@@ -77,6 +77,9 @@ | |||
77 | #define ATH9K_TXERR_XTXOP 0x08 | 77 | #define ATH9K_TXERR_XTXOP 0x08 |
78 | #define ATH9K_TXERR_TIMER_EXPIRED 0x10 | 78 | #define ATH9K_TXERR_TIMER_EXPIRED 0x10 |
79 | #define ATH9K_TX_ACKED 0x20 | 79 | #define ATH9K_TX_ACKED 0x20 |
80 | #define ATH9K_TXERR_MASK \ | ||
81 | (ATH9K_TXERR_XRETRY | ATH9K_TXERR_FILT | ATH9K_TXERR_FIFO | \ | ||
82 | ATH9K_TXERR_XTXOP | ATH9K_TXERR_TIMER_EXPIRED) | ||
80 | 83 | ||
81 | #define ATH9K_TX_BA 0x01 | 84 | #define ATH9K_TX_BA 0x01 |
82 | #define ATH9K_TX_PWRMGMT 0x02 | 85 | #define ATH9K_TX_PWRMGMT 0x02 |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index c48743452515..996eb90263cc 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -1973,6 +1973,9 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) | |||
1973 | struct ieee80211_hw *hw = sc->hw; | 1973 | struct ieee80211_hw *hw = sc->hw; |
1974 | int r; | 1974 | int r; |
1975 | 1975 | ||
1976 | /* Stop ANI */ | ||
1977 | del_timer_sync(&common->ani.timer); | ||
1978 | |||
1976 | ath9k_hw_set_interrupts(ah, 0); | 1979 | ath9k_hw_set_interrupts(ah, 0); |
1977 | ath_drain_all_txq(sc, retry_tx); | 1980 | ath_drain_all_txq(sc, retry_tx); |
1978 | ath_stoprecv(sc); | 1981 | ath_stoprecv(sc); |
@@ -2014,6 +2017,9 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) | |||
2014 | } | 2017 | } |
2015 | } | 2018 | } |
2016 | 2019 | ||
2020 | /* Start ANI */ | ||
2021 | ath_start_ani(common); | ||
2022 | |||
2017 | return r; | 2023 | return r; |
2018 | } | 2024 | } |
2019 | 2025 | ||
@@ -2508,6 +2514,9 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
2508 | return; /* another wiphy still in use */ | 2514 | return; /* another wiphy still in use */ |
2509 | } | 2515 | } |
2510 | 2516 | ||
2517 | /* Ensure HW is awake when we try to shut it down. */ | ||
2518 | ath9k_ps_wakeup(sc); | ||
2519 | |||
2511 | if (ah->btcoex_hw.enabled) { | 2520 | if (ah->btcoex_hw.enabled) { |
2512 | ath9k_hw_btcoex_disable(ah); | 2521 | ath9k_hw_btcoex_disable(ah); |
2513 | if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) | 2522 | if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) |
@@ -2528,6 +2537,9 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
2528 | /* disable HAL and put h/w to sleep */ | 2537 | /* disable HAL and put h/w to sleep */ |
2529 | ath9k_hw_disable(ah); | 2538 | ath9k_hw_disable(ah); |
2530 | ath9k_hw_configpcipowersave(ah, 1, 1); | 2539 | ath9k_hw_configpcipowersave(ah, 1, 1); |
2540 | ath9k_ps_restore(sc); | ||
2541 | |||
2542 | /* Finally, put the chip in FULL SLEEP mode */ | ||
2531 | ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP); | 2543 | ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP); |
2532 | 2544 | ||
2533 | sc->sc_flags |= SC_OP_INVALID; | 2545 | sc->sc_flags |= SC_OP_INVALID; |
@@ -2641,8 +2653,10 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, | |||
2641 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) || | 2653 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) || |
2642 | (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) || | 2654 | (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) || |
2643 | (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) { | 2655 | (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) { |
2656 | ath9k_ps_wakeup(sc); | ||
2644 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); | 2657 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); |
2645 | ath_beacon_return(sc, avp); | 2658 | ath_beacon_return(sc, avp); |
2659 | ath9k_ps_restore(sc); | ||
2646 | } | 2660 | } |
2647 | 2661 | ||
2648 | sc->sc_flags &= ~SC_OP_BEACONS; | 2662 | sc->sc_flags &= ~SC_OP_BEACONS; |
@@ -3091,15 +3105,21 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, | |||
3091 | case IEEE80211_AMPDU_RX_STOP: | 3105 | case IEEE80211_AMPDU_RX_STOP: |
3092 | break; | 3106 | break; |
3093 | case IEEE80211_AMPDU_TX_START: | 3107 | case IEEE80211_AMPDU_TX_START: |
3108 | ath9k_ps_wakeup(sc); | ||
3094 | ath_tx_aggr_start(sc, sta, tid, ssn); | 3109 | ath_tx_aggr_start(sc, sta, tid, ssn); |
3095 | ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); | 3110 | ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); |
3111 | ath9k_ps_restore(sc); | ||
3096 | break; | 3112 | break; |
3097 | case IEEE80211_AMPDU_TX_STOP: | 3113 | case IEEE80211_AMPDU_TX_STOP: |
3114 | ath9k_ps_wakeup(sc); | ||
3098 | ath_tx_aggr_stop(sc, sta, tid); | 3115 | ath_tx_aggr_stop(sc, sta, tid); |
3099 | ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); | 3116 | ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); |
3117 | ath9k_ps_restore(sc); | ||
3100 | break; | 3118 | break; |
3101 | case IEEE80211_AMPDU_TX_OPERATIONAL: | 3119 | case IEEE80211_AMPDU_TX_OPERATIONAL: |
3120 | ath9k_ps_wakeup(sc); | ||
3102 | ath_tx_aggr_resume(sc, sta, tid); | 3121 | ath_tx_aggr_resume(sc, sta, tid); |
3122 | ath9k_ps_restore(sc); | ||
3103 | break; | 3123 | break; |
3104 | default: | 3124 | default: |
3105 | ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, | 3125 | ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, |
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index 5321f735e5a0..f7af5ea54753 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c | |||
@@ -96,7 +96,7 @@ static void ath_pci_bt_coex_prep(struct ath_common *common) | |||
96 | pci_write_config_byte(pdev, ATH_PCIE_CAP_LINK_CTRL, aspm); | 96 | pci_write_config_byte(pdev, ATH_PCIE_CAP_LINK_CTRL, aspm); |
97 | } | 97 | } |
98 | 98 | ||
99 | const static struct ath_bus_ops ath_pci_bus_ops = { | 99 | static const struct ath_bus_ops ath_pci_bus_ops = { |
100 | .read_cachesize = ath_pci_read_cachesize, | 100 | .read_cachesize = ath_pci_read_cachesize, |
101 | .cleanup = ath_pci_cleanup, | 101 | .cleanup = ath_pci_cleanup, |
102 | .eeprom_read = ath_pci_eeprom_read, | 102 | .eeprom_read = ath_pci_eeprom_read, |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 2a11cc57ceea..fa12b9060b0b 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -1108,11 +1108,11 @@ void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) | |||
1108 | if (npend) { | 1108 | if (npend) { |
1109 | int r; | 1109 | int r; |
1110 | 1110 | ||
1111 | ath_print(common, ATH_DBG_XMIT, | 1111 | ath_print(common, ATH_DBG_FATAL, |
1112 | "Unable to stop TxDMA. Reset HAL!\n"); | 1112 | "Unable to stop TxDMA. Reset HAL!\n"); |
1113 | 1113 | ||
1114 | spin_lock_bh(&sc->sc_resetlock); | 1114 | spin_lock_bh(&sc->sc_resetlock); |
1115 | r = ath9k_hw_reset(ah, sc->sc_ah->curchan, true); | 1115 | r = ath9k_hw_reset(ah, sc->sc_ah->curchan, false); |
1116 | if (r) | 1116 | if (r) |
1117 | ath_print(common, ATH_DBG_FATAL, | 1117 | ath_print(common, ATH_DBG_FATAL, |
1118 | "Unable to reset hardware; reset status %d\n", | 1118 | "Unable to reset hardware; reset status %d\n", |
@@ -1414,17 +1414,9 @@ static void assign_aggr_tid_seqno(struct sk_buff *skb, | |||
1414 | * For HT capable stations, we save tidno for later use. | 1414 | * For HT capable stations, we save tidno for later use. |
1415 | * We also override seqno set by upper layer with the one | 1415 | * We also override seqno set by upper layer with the one |
1416 | * in tx aggregation state. | 1416 | * in tx aggregation state. |
1417 | * | ||
1418 | * If fragmentation is on, the sequence number is | ||
1419 | * not overridden, since it has been | ||
1420 | * incremented by the fragmentation routine. | ||
1421 | * | ||
1422 | * FIXME: check if the fragmentation threshold exceeds | ||
1423 | * IEEE80211 max. | ||
1424 | */ | 1417 | */ |
1425 | tid = ATH_AN_2_TID(an, bf->bf_tidno); | 1418 | tid = ATH_AN_2_TID(an, bf->bf_tidno); |
1426 | hdr->seq_ctrl = cpu_to_le16(tid->seq_next << | 1419 | hdr->seq_ctrl = cpu_to_le16(tid->seq_next << IEEE80211_SEQ_SEQ_SHIFT); |
1427 | IEEE80211_SEQ_SEQ_SHIFT); | ||
1428 | bf->bf_seqno = tid->seq_next; | 1420 | bf->bf_seqno = tid->seq_next; |
1429 | INCR(tid->seq_next, IEEE80211_SEQ_MAX); | 1421 | INCR(tid->seq_next, IEEE80211_SEQ_MAX); |
1430 | } | 1422 | } |
@@ -1636,7 +1628,8 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf, | |||
1636 | bf->bf_keyix = ATH9K_TXKEYIX_INVALID; | 1628 | bf->bf_keyix = ATH9K_TXKEYIX_INVALID; |
1637 | } | 1629 | } |
1638 | 1630 | ||
1639 | if (ieee80211_is_data_qos(fc) && (sc->sc_flags & SC_OP_TXAGGR)) | 1631 | if (ieee80211_is_data_qos(fc) && bf_isht(bf) && |
1632 | (sc->sc_flags & SC_OP_TXAGGR)) | ||
1640 | assign_aggr_tid_seqno(skb, bf); | 1633 | assign_aggr_tid_seqno(skb, bf); |
1641 | 1634 | ||
1642 | bf->bf_mpdu = skb; | 1635 | bf->bf_mpdu = skb; |
@@ -1780,7 +1773,8 @@ void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1780 | struct ath_wiphy *aphy = hw->priv; | 1773 | struct ath_wiphy *aphy = hw->priv; |
1781 | struct ath_softc *sc = aphy->sc; | 1774 | struct ath_softc *sc = aphy->sc; |
1782 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1775 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
1783 | int hdrlen, padsize; | 1776 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
1777 | int padpos, padsize; | ||
1784 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 1778 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
1785 | struct ath_tx_control txctl; | 1779 | struct ath_tx_control txctl; |
1786 | 1780 | ||
@@ -1792,7 +1786,6 @@ void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1792 | * BSSes. | 1786 | * BSSes. |
1793 | */ | 1787 | */ |
1794 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { | 1788 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { |
1795 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | ||
1796 | if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) | 1789 | if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) |
1797 | sc->tx.seq_no += 0x10; | 1790 | sc->tx.seq_no += 0x10; |
1798 | hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); | 1791 | hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); |
@@ -1800,9 +1793,9 @@ void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1800 | } | 1793 | } |
1801 | 1794 | ||
1802 | /* Add the padding after the header if this is not already done */ | 1795 | /* Add the padding after the header if this is not already done */ |
1803 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | 1796 | padpos = ath9k_cmn_padpos(hdr->frame_control); |
1804 | if (hdrlen & 3) { | 1797 | padsize = padpos & 3; |
1805 | padsize = hdrlen % 4; | 1798 | if (padsize && skb->len>padpos) { |
1806 | if (skb_headroom(skb) < padsize) { | 1799 | if (skb_headroom(skb) < padsize) { |
1807 | ath_print(common, ATH_DBG_XMIT, | 1800 | ath_print(common, ATH_DBG_XMIT, |
1808 | "TX CABQ padding failed\n"); | 1801 | "TX CABQ padding failed\n"); |
@@ -1810,7 +1803,7 @@ void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1810 | return; | 1803 | return; |
1811 | } | 1804 | } |
1812 | skb_push(skb, padsize); | 1805 | skb_push(skb, padsize); |
1813 | memmove(skb->data, skb->data + padsize, hdrlen); | 1806 | memmove(skb->data, skb->data + padsize, padpos); |
1814 | } | 1807 | } |
1815 | 1808 | ||
1816 | txctl.txq = sc->beacon.cabq; | 1809 | txctl.txq = sc->beacon.cabq; |
@@ -1838,7 +1831,8 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | |||
1838 | struct ieee80211_hw *hw = sc->hw; | 1831 | struct ieee80211_hw *hw = sc->hw; |
1839 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 1832 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
1840 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1833 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
1841 | int hdrlen, padsize; | 1834 | struct ieee80211_hdr * hdr = (struct ieee80211_hdr *)skb->data; |
1835 | int padpos, padsize; | ||
1842 | 1836 | ||
1843 | ath_print(common, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb); | 1837 | ath_print(common, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb); |
1844 | 1838 | ||
@@ -1853,14 +1847,14 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | |||
1853 | tx_info->flags |= IEEE80211_TX_STAT_ACK; | 1847 | tx_info->flags |= IEEE80211_TX_STAT_ACK; |
1854 | } | 1848 | } |
1855 | 1849 | ||
1856 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | 1850 | padpos = ath9k_cmn_padpos(hdr->frame_control); |
1857 | padsize = hdrlen & 3; | 1851 | padsize = padpos & 3; |
1858 | if (padsize && hdrlen >= 24) { | 1852 | if (padsize && skb->len>padpos+padsize) { |
1859 | /* | 1853 | /* |
1860 | * Remove MAC header padding before giving the frame back to | 1854 | * Remove MAC header padding before giving the frame back to |
1861 | * mac80211. | 1855 | * mac80211. |
1862 | */ | 1856 | */ |
1863 | memmove(skb->data + padsize, skb->data, hdrlen); | 1857 | memmove(skb->data + padsize, skb->data, padpos); |
1864 | skb_pull(skb, padsize); | 1858 | skb_pull(skb, padsize); |
1865 | } | 1859 | } |
1866 | 1860 | ||
@@ -2078,7 +2072,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | |||
2078 | &txq->axq_q, lastbf->list.prev); | 2072 | &txq->axq_q, lastbf->list.prev); |
2079 | 2073 | ||
2080 | txq->axq_depth--; | 2074 | txq->axq_depth--; |
2081 | txok = !(ds->ds_txstat.ts_status & ATH9K_TXERR_FILT); | 2075 | txok = !(ds->ds_txstat.ts_status & ATH9K_TXERR_MASK); |
2082 | txq->axq_tx_inprogress = false; | 2076 | txq->axq_tx_inprogress = false; |
2083 | spin_unlock_bh(&txq->axq_lock); | 2077 | spin_unlock_bh(&txq->axq_lock); |
2084 | 2078 | ||
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c index 027be275e035..88d1fd02d40a 100644 --- a/drivers/net/wireless/b43/dma.c +++ b/drivers/net/wireless/b43/dma.c | |||
@@ -383,160 +383,44 @@ static inline | |||
383 | } | 383 | } |
384 | } | 384 | } |
385 | 385 | ||
386 | /* Check if a DMA region fits the device constraints. | ||
387 | * Returns true, if the region is OK for usage with this device. */ | ||
388 | static inline bool b43_dma_address_ok(struct b43_dmaring *ring, | ||
389 | dma_addr_t addr, size_t size) | ||
390 | { | ||
391 | switch (ring->type) { | ||
392 | case B43_DMA_30BIT: | ||
393 | if ((u64)addr + size > (1ULL << 30)) | ||
394 | return 0; | ||
395 | break; | ||
396 | case B43_DMA_32BIT: | ||
397 | if ((u64)addr + size > (1ULL << 32)) | ||
398 | return 0; | ||
399 | break; | ||
400 | case B43_DMA_64BIT: | ||
401 | /* Currently we can't have addresses beyond | ||
402 | * 64bit in the kernel. */ | ||
403 | break; | ||
404 | } | ||
405 | return 1; | ||
406 | } | ||
407 | |||
408 | #define is_4k_aligned(addr) (((u64)(addr) & 0x0FFFull) == 0) | ||
409 | #define is_8k_aligned(addr) (((u64)(addr) & 0x1FFFull) == 0) | ||
410 | |||
411 | static void b43_unmap_and_free_ringmem(struct b43_dmaring *ring, void *base, | ||
412 | dma_addr_t dmaaddr, size_t size) | ||
413 | { | ||
414 | ssb_dma_unmap_single(ring->dev->dev, dmaaddr, size, DMA_TO_DEVICE); | ||
415 | free_pages((unsigned long)base, get_order(size)); | ||
416 | } | ||
417 | |||
418 | static void * __b43_get_and_map_ringmem(struct b43_dmaring *ring, | ||
419 | dma_addr_t *dmaaddr, size_t size, | ||
420 | gfp_t gfp_flags) | ||
421 | { | ||
422 | void *base; | ||
423 | |||
424 | base = (void *)__get_free_pages(gfp_flags, get_order(size)); | ||
425 | if (!base) | ||
426 | return NULL; | ||
427 | memset(base, 0, size); | ||
428 | *dmaaddr = ssb_dma_map_single(ring->dev->dev, base, size, | ||
429 | DMA_TO_DEVICE); | ||
430 | if (ssb_dma_mapping_error(ring->dev->dev, *dmaaddr)) { | ||
431 | free_pages((unsigned long)base, get_order(size)); | ||
432 | return NULL; | ||
433 | } | ||
434 | |||
435 | return base; | ||
436 | } | ||
437 | |||
438 | static void * b43_get_and_map_ringmem(struct b43_dmaring *ring, | ||
439 | dma_addr_t *dmaaddr, size_t size) | ||
440 | { | ||
441 | void *base; | ||
442 | |||
443 | base = __b43_get_and_map_ringmem(ring, dmaaddr, size, | ||
444 | GFP_KERNEL); | ||
445 | if (!base) { | ||
446 | b43err(ring->dev->wl, "Failed to allocate or map pages " | ||
447 | "for DMA ringmemory\n"); | ||
448 | return NULL; | ||
449 | } | ||
450 | if (!b43_dma_address_ok(ring, *dmaaddr, size)) { | ||
451 | /* The memory does not fit our device constraints. | ||
452 | * Retry with GFP_DMA set to get lower memory. */ | ||
453 | b43_unmap_and_free_ringmem(ring, base, *dmaaddr, size); | ||
454 | base = __b43_get_and_map_ringmem(ring, dmaaddr, size, | ||
455 | GFP_KERNEL | GFP_DMA); | ||
456 | if (!base) { | ||
457 | b43err(ring->dev->wl, "Failed to allocate or map pages " | ||
458 | "in the GFP_DMA region for DMA ringmemory\n"); | ||
459 | return NULL; | ||
460 | } | ||
461 | if (!b43_dma_address_ok(ring, *dmaaddr, size)) { | ||
462 | b43_unmap_and_free_ringmem(ring, base, *dmaaddr, size); | ||
463 | b43err(ring->dev->wl, "Failed to allocate DMA " | ||
464 | "ringmemory that fits device constraints\n"); | ||
465 | return NULL; | ||
466 | } | ||
467 | } | ||
468 | /* We expect the memory to be 4k aligned, at least. */ | ||
469 | if (B43_WARN_ON(!is_4k_aligned(*dmaaddr))) { | ||
470 | b43_unmap_and_free_ringmem(ring, base, *dmaaddr, size); | ||
471 | return NULL; | ||
472 | } | ||
473 | |||
474 | return base; | ||
475 | } | ||
476 | |||
477 | static int alloc_ringmemory(struct b43_dmaring *ring) | 386 | static int alloc_ringmemory(struct b43_dmaring *ring) |
478 | { | 387 | { |
479 | unsigned int required; | 388 | gfp_t flags = GFP_KERNEL; |
480 | void *base; | 389 | |
481 | dma_addr_t dmaaddr; | 390 | /* The specs call for 4K buffers for 30- and 32-bit DMA with 4K |
482 | 391 | * alignment and 8K buffers for 64-bit DMA with 8K alignment. Testing | |
483 | /* There are several requirements to the descriptor ring memory: | 392 | * has shown that 4K is sufficient for the latter as long as the buffer |
484 | * - The memory region needs to fit the address constraints for the | 393 | * does not cross an 8K boundary. |
485 | * device (same as for frame buffers). | 394 | * |
486 | * - For 30/32bit DMA devices, the descriptor ring must be 4k aligned. | 395 | * For unknown reasons - possibly a hardware error - the BCM4311 rev |
487 | * - For 64bit DMA devices, the descriptor ring must be 8k aligned. | 396 | * 02, which uses 64-bit DMA, needs the ring buffer in very low memory, |
397 | * which accounts for the GFP_DMA flag below. | ||
398 | * | ||
399 | * The flags here must match the flags in free_ringmemory below! | ||
488 | */ | 400 | */ |
489 | |||
490 | if (ring->type == B43_DMA_64BIT) | 401 | if (ring->type == B43_DMA_64BIT) |
491 | required = ring->nr_slots * sizeof(struct b43_dmadesc64); | 402 | flags |= GFP_DMA; |
492 | else | 403 | ring->descbase = ssb_dma_alloc_consistent(ring->dev->dev, |
493 | required = ring->nr_slots * sizeof(struct b43_dmadesc32); | 404 | B43_DMA_RINGMEMSIZE, |
494 | if (B43_WARN_ON(required > 0x1000)) | 405 | &(ring->dmabase), flags); |
406 | if (!ring->descbase) { | ||
407 | b43err(ring->dev->wl, "DMA ringmemory allocation failed\n"); | ||
495 | return -ENOMEM; | 408 | return -ENOMEM; |
496 | |||
497 | ring->alloc_descsize = 0x1000; | ||
498 | base = b43_get_and_map_ringmem(ring, &dmaaddr, ring->alloc_descsize); | ||
499 | if (!base) | ||
500 | return -ENOMEM; | ||
501 | ring->alloc_descbase = base; | ||
502 | ring->alloc_dmabase = dmaaddr; | ||
503 | |||
504 | if ((ring->type != B43_DMA_64BIT) || is_8k_aligned(dmaaddr)) { | ||
505 | /* We're on <=32bit DMA, or we already got 8k aligned memory. | ||
506 | * That's all we need, so we're fine. */ | ||
507 | ring->descbase = base; | ||
508 | ring->dmabase = dmaaddr; | ||
509 | return 0; | ||
510 | } | ||
511 | b43_unmap_and_free_ringmem(ring, base, dmaaddr, ring->alloc_descsize); | ||
512 | |||
513 | /* Ok, we failed at the 8k alignment requirement. | ||
514 | * Try to force-align the memory region now. */ | ||
515 | ring->alloc_descsize = 0x2000; | ||
516 | base = b43_get_and_map_ringmem(ring, &dmaaddr, ring->alloc_descsize); | ||
517 | if (!base) | ||
518 | return -ENOMEM; | ||
519 | ring->alloc_descbase = base; | ||
520 | ring->alloc_dmabase = dmaaddr; | ||
521 | |||
522 | if (is_8k_aligned(dmaaddr)) { | ||
523 | /* We're already 8k aligned. That Ok, too. */ | ||
524 | ring->descbase = base; | ||
525 | ring->dmabase = dmaaddr; | ||
526 | return 0; | ||
527 | } | 409 | } |
528 | /* Force-align it to 8k */ | 410 | memset(ring->descbase, 0, B43_DMA_RINGMEMSIZE); |
529 | ring->descbase = (void *)((u8 *)base + 0x1000); | ||
530 | ring->dmabase = dmaaddr + 0x1000; | ||
531 | B43_WARN_ON(!is_8k_aligned(ring->dmabase)); | ||
532 | 411 | ||
533 | return 0; | 412 | return 0; |
534 | } | 413 | } |
535 | 414 | ||
536 | static void free_ringmemory(struct b43_dmaring *ring) | 415 | static void free_ringmemory(struct b43_dmaring *ring) |
537 | { | 416 | { |
538 | b43_unmap_and_free_ringmem(ring, ring->alloc_descbase, | 417 | gfp_t flags = GFP_KERNEL; |
539 | ring->alloc_dmabase, ring->alloc_descsize); | 418 | |
419 | if (ring->type == B43_DMA_64BIT) | ||
420 | flags |= GFP_DMA; | ||
421 | |||
422 | ssb_dma_free_consistent(ring->dev->dev, B43_DMA_RINGMEMSIZE, | ||
423 | ring->descbase, ring->dmabase, flags); | ||
540 | } | 424 | } |
541 | 425 | ||
542 | /* Reset the RX DMA channel */ | 426 | /* Reset the RX DMA channel */ |
@@ -646,14 +530,29 @@ static bool b43_dma_mapping_error(struct b43_dmaring *ring, | |||
646 | if (unlikely(ssb_dma_mapping_error(ring->dev->dev, addr))) | 530 | if (unlikely(ssb_dma_mapping_error(ring->dev->dev, addr))) |
647 | return 1; | 531 | return 1; |
648 | 532 | ||
649 | if (!b43_dma_address_ok(ring, addr, buffersize)) { | 533 | switch (ring->type) { |
650 | /* We can't support this address. Unmap it again. */ | 534 | case B43_DMA_30BIT: |
651 | unmap_descbuffer(ring, addr, buffersize, dma_to_device); | 535 | if ((u64)addr + buffersize > (1ULL << 30)) |
652 | return 1; | 536 | goto address_error; |
537 | break; | ||
538 | case B43_DMA_32BIT: | ||
539 | if ((u64)addr + buffersize > (1ULL << 32)) | ||
540 | goto address_error; | ||
541 | break; | ||
542 | case B43_DMA_64BIT: | ||
543 | /* Currently we can't have addresses beyond | ||
544 | * 64bit in the kernel. */ | ||
545 | break; | ||
653 | } | 546 | } |
654 | 547 | ||
655 | /* The address is OK. */ | 548 | /* The address is OK. */ |
656 | return 0; | 549 | return 0; |
550 | |||
551 | address_error: | ||
552 | /* We can't support this address. Unmap it again. */ | ||
553 | unmap_descbuffer(ring, addr, buffersize, dma_to_device); | ||
554 | |||
555 | return 1; | ||
657 | } | 556 | } |
658 | 557 | ||
659 | static bool b43_rx_buffer_is_poisoned(struct b43_dmaring *ring, struct sk_buff *skb) | 558 | static bool b43_rx_buffer_is_poisoned(struct b43_dmaring *ring, struct sk_buff *skb) |
@@ -715,9 +614,6 @@ static int setup_rx_descbuffer(struct b43_dmaring *ring, | |||
715 | meta->dmaaddr = dmaaddr; | 614 | meta->dmaaddr = dmaaddr; |
716 | ring->ops->fill_descriptor(ring, desc, dmaaddr, | 615 | ring->ops->fill_descriptor(ring, desc, dmaaddr, |
717 | ring->rx_buffersize, 0, 0, 0); | 616 | ring->rx_buffersize, 0, 0, 0); |
718 | ssb_dma_sync_single_for_device(ring->dev->dev, | ||
719 | ring->alloc_dmabase, | ||
720 | ring->alloc_descsize, DMA_TO_DEVICE); | ||
721 | 617 | ||
722 | return 0; | 618 | return 0; |
723 | } | 619 | } |
@@ -1354,9 +1250,6 @@ static int dma_tx_fragment(struct b43_dmaring *ring, | |||
1354 | } | 1250 | } |
1355 | /* Now transfer the whole frame. */ | 1251 | /* Now transfer the whole frame. */ |
1356 | wmb(); | 1252 | wmb(); |
1357 | ssb_dma_sync_single_for_device(ring->dev->dev, | ||
1358 | ring->alloc_dmabase, | ||
1359 | ring->alloc_descsize, DMA_TO_DEVICE); | ||
1360 | ops->poke_tx(ring, next_slot(ring, slot)); | 1253 | ops->poke_tx(ring, next_slot(ring, slot)); |
1361 | return 0; | 1254 | return 0; |
1362 | 1255 | ||
diff --git a/drivers/net/wireless/b43/dma.h b/drivers/net/wireless/b43/dma.h index e607b392314c..f7ab37c4cdbc 100644 --- a/drivers/net/wireless/b43/dma.h +++ b/drivers/net/wireless/b43/dma.h | |||
@@ -157,6 +157,7 @@ struct b43_dmadesc_generic { | |||
157 | } __attribute__ ((__packed__)); | 157 | } __attribute__ ((__packed__)); |
158 | 158 | ||
159 | /* Misc DMA constants */ | 159 | /* Misc DMA constants */ |
160 | #define B43_DMA_RINGMEMSIZE PAGE_SIZE | ||
160 | #define B43_DMA0_RX_FRAMEOFFSET 30 | 161 | #define B43_DMA0_RX_FRAMEOFFSET 30 |
161 | 162 | ||
162 | /* DMA engine tuning knobs */ | 163 | /* DMA engine tuning knobs */ |
@@ -246,12 +247,6 @@ struct b43_dmaring { | |||
246 | /* The QOS priority assigned to this ring. Only used for TX rings. | 247 | /* The QOS priority assigned to this ring. Only used for TX rings. |
247 | * This is the mac80211 "queue" value. */ | 248 | * This is the mac80211 "queue" value. */ |
248 | u8 queue_prio; | 249 | u8 queue_prio; |
249 | /* Pointers and size of the originally allocated and mapped memory | ||
250 | * region for the descriptor ring. */ | ||
251 | void *alloc_descbase; | ||
252 | dma_addr_t alloc_dmabase; | ||
253 | unsigned int alloc_descsize; | ||
254 | /* Pointer to our wireless device. */ | ||
255 | struct b43_wldev *dev; | 250 | struct b43_wldev *dev; |
256 | #ifdef CONFIG_B43_DEBUG | 251 | #ifdef CONFIG_B43_DEBUG |
257 | /* Maximum number of used slots. */ | 252 | /* Maximum number of used slots. */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 7da1dab933d9..234891d8cc10 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c | |||
@@ -681,19 +681,13 @@ static void iwl3945_rx_reply_rx(struct iwl_priv *priv, | |||
681 | snr = rx_stats_sig_avg / rx_stats_noise_diff; | 681 | snr = rx_stats_sig_avg / rx_stats_noise_diff; |
682 | rx_status.noise = rx_status.signal - | 682 | rx_status.noise = rx_status.signal - |
683 | iwl3945_calc_db_from_ratio(snr); | 683 | iwl3945_calc_db_from_ratio(snr); |
684 | rx_status.qual = iwl3945_calc_sig_qual(rx_status.signal, | ||
685 | rx_status.noise); | ||
686 | |||
687 | /* If noise info not available, calculate signal quality indicator (%) | ||
688 | * using just the dBm signal level. */ | ||
689 | } else { | 684 | } else { |
690 | rx_status.noise = priv->last_rx_noise; | 685 | rx_status.noise = priv->last_rx_noise; |
691 | rx_status.qual = iwl3945_calc_sig_qual(rx_status.signal, 0); | ||
692 | } | 686 | } |
693 | 687 | ||
694 | 688 | ||
695 | IWL_DEBUG_STATS(priv, "Rssi %d noise %d qual %d sig_avg %d noise_diff %d\n", | 689 | IWL_DEBUG_STATS(priv, "Rssi %d noise %d sig_avg %d noise_diff %d\n", |
696 | rx_status.signal, rx_status.noise, rx_status.qual, | 690 | rx_status.signal, rx_status.noise, |
697 | rx_stats_sig_avg, rx_stats_noise_diff); | 691 | rx_stats_sig_avg, rx_stats_noise_diff); |
698 | 692 | ||
699 | header = (struct ieee80211_hdr *)IWL_RX_DATA(pkt); | 693 | header = (struct ieee80211_hdr *)IWL_RX_DATA(pkt); |
@@ -1835,8 +1829,7 @@ static int iwl3945_send_rxon_assoc(struct iwl_priv *priv) | |||
1835 | rc = -EIO; | 1829 | rc = -EIO; |
1836 | } | 1830 | } |
1837 | 1831 | ||
1838 | priv->alloc_rxb_page--; | 1832 | iwl_free_pages(priv, cmd.reply_page); |
1839 | free_pages(cmd.reply_page, priv->hw_params.rx_page_order); | ||
1840 | 1833 | ||
1841 | return rc; | 1834 | return rc; |
1842 | } | 1835 | } |
@@ -2836,6 +2829,7 @@ static struct iwl_cfg iwl3945_bg_cfg = { | |||
2836 | .use_isr_legacy = true, | 2829 | .use_isr_legacy = true, |
2837 | .ht_greenfield_support = false, | 2830 | .ht_greenfield_support = false, |
2838 | .led_compensation = 64, | 2831 | .led_compensation = 64, |
2832 | .broken_powersave = true, | ||
2839 | }; | 2833 | }; |
2840 | 2834 | ||
2841 | static struct iwl_cfg iwl3945_abg_cfg = { | 2835 | static struct iwl_cfg iwl3945_abg_cfg = { |
@@ -2852,6 +2846,7 @@ static struct iwl_cfg iwl3945_abg_cfg = { | |||
2852 | .use_isr_legacy = true, | 2846 | .use_isr_legacy = true, |
2853 | .ht_greenfield_support = false, | 2847 | .ht_greenfield_support = false, |
2854 | .led_compensation = 64, | 2848 | .led_compensation = 64, |
2849 | .broken_powersave = true, | ||
2855 | }; | 2850 | }; |
2856 | 2851 | ||
2857 | struct pci_device_id iwl3945_hw_card_ids[] = { | 2852 | struct pci_device_id iwl3945_hw_card_ids[] = { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h index ecc23ec1f6a4..531fa125f5a6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945.h | |||
@@ -222,7 +222,6 @@ struct iwl3945_ibss_seq { | |||
222 | * | 222 | * |
223 | *****************************************************************************/ | 223 | *****************************************************************************/ |
224 | extern int iwl3945_calc_db_from_ratio(int sig_ratio); | 224 | extern int iwl3945_calc_db_from_ratio(int sig_ratio); |
225 | extern int iwl3945_calc_sig_qual(int rssi_dbm, int noise_dbm); | ||
226 | extern void iwl3945_rx_replenish(void *data); | 225 | extern void iwl3945_rx_replenish(void *data); |
227 | extern void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq); | 226 | extern void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq); |
228 | extern unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv, | 227 | extern unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 386513b601f5..484c5fdf7c2a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c | |||
@@ -1204,7 +1204,7 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel, | |||
1204 | iwl4965_interpolate_chan(priv, channel, &ch_eeprom_info); | 1204 | iwl4965_interpolate_chan(priv, channel, &ch_eeprom_info); |
1205 | 1205 | ||
1206 | /* calculate tx gain adjustment based on power supply voltage */ | 1206 | /* calculate tx gain adjustment based on power supply voltage */ |
1207 | voltage = priv->calib_info->voltage; | 1207 | voltage = le16_to_cpu(priv->calib_info->voltage); |
1208 | init_voltage = (s32)le32_to_cpu(priv->card_alive_init.voltage); | 1208 | init_voltage = (s32)le32_to_cpu(priv->card_alive_init.voltage); |
1209 | voltage_compensation = | 1209 | voltage_compensation = |
1210 | iwl4965_get_voltage_compensation(voltage, init_voltage); | 1210 | iwl4965_get_voltage_compensation(voltage, init_voltage); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h index 4ef6804a455a..bc056e9ab85f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h | |||
@@ -92,11 +92,15 @@ | |||
92 | 92 | ||
93 | static inline s32 iwl_temp_calib_to_offset(struct iwl_priv *priv) | 93 | static inline s32 iwl_temp_calib_to_offset(struct iwl_priv *priv) |
94 | { | 94 | { |
95 | u16 *temp_calib = (u16 *)iwl_eeprom_query_addr(priv, | 95 | u16 temperature, voltage; |
96 | EEPROM_5000_TEMPERATURE); | 96 | __le16 *temp_calib = |
97 | /* offset = temperature - voltage / coef */ | 97 | (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_5000_TEMPERATURE); |
98 | s32 offset = (s32)(temp_calib[0] - temp_calib[1] / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF); | 98 | |
99 | return offset; | 99 | temperature = le16_to_cpu(temp_calib[0]); |
100 | voltage = le16_to_cpu(temp_calib[1]); | ||
101 | |||
102 | /* offset = temp - volt / coeff */ | ||
103 | return (s32)(temperature - voltage / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF); | ||
100 | } | 104 | } |
101 | 105 | ||
102 | /* Fixed (non-configurable) rx data from phy */ | 106 | /* Fixed (non-configurable) rx data from phy */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index e2f8615c8c9b..33a5866538e7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c | |||
@@ -333,14 +333,15 @@ static void iwl5000_set_ct_threshold(struct iwl_priv *priv) | |||
333 | static int iwl5000_set_Xtal_calib(struct iwl_priv *priv) | 333 | static int iwl5000_set_Xtal_calib(struct iwl_priv *priv) |
334 | { | 334 | { |
335 | struct iwl_calib_xtal_freq_cmd cmd; | 335 | struct iwl_calib_xtal_freq_cmd cmd; |
336 | u16 *xtal_calib = (u16 *)iwl_eeprom_query_addr(priv, EEPROM_5000_XTAL); | 336 | __le16 *xtal_calib = |
337 | (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_5000_XTAL); | ||
337 | 338 | ||
338 | cmd.hdr.op_code = IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD; | 339 | cmd.hdr.op_code = IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD; |
339 | cmd.hdr.first_group = 0; | 340 | cmd.hdr.first_group = 0; |
340 | cmd.hdr.groups_num = 1; | 341 | cmd.hdr.groups_num = 1; |
341 | cmd.hdr.data_valid = 1; | 342 | cmd.hdr.data_valid = 1; |
342 | cmd.cap_pin1 = (u8)xtal_calib[0]; | 343 | cmd.cap_pin1 = le16_to_cpu(xtal_calib[0]); |
343 | cmd.cap_pin2 = (u8)xtal_calib[1]; | 344 | cmd.cap_pin2 = le16_to_cpu(xtal_calib[1]); |
344 | return iwl_calib_set(&priv->calib_results[IWL_CALIB_XTAL], | 345 | return iwl_calib_set(&priv->calib_results[IWL_CALIB_XTAL], |
345 | (u8 *)&cmd, sizeof(cmd)); | 346 | (u8 *)&cmd, sizeof(cmd)); |
346 | } | 347 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index fe511cbf012e..b93e49158196 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c | |||
@@ -150,7 +150,7 @@ static s32 expected_tpt_mimo3_40MHz[4][IWL_RATE_COUNT] = { | |||
150 | }; | 150 | }; |
151 | 151 | ||
152 | /* mbps, mcs */ | 152 | /* mbps, mcs */ |
153 | const static struct iwl_rate_mcs_info iwl_rate_mcs[IWL_RATE_COUNT] = { | 153 | static const struct iwl_rate_mcs_info iwl_rate_mcs[IWL_RATE_COUNT] = { |
154 | { "1", "BPSK DSSS"}, | 154 | { "1", "BPSK DSSS"}, |
155 | { "2", "QPSK DSSS"}, | 155 | { "2", "QPSK DSSS"}, |
156 | {"5.5", "BPSK CCK"}, | 156 | {"5.5", "BPSK CCK"}, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index b8377efb3ba7..1c9866daf815 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -1842,7 +1842,7 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log) | |||
1842 | } | 1842 | } |
1843 | 1843 | ||
1844 | #ifdef CONFIG_IWLWIFI_DEBUG | 1844 | #ifdef CONFIG_IWLWIFI_DEBUG |
1845 | if (!(iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS)) | 1845 | if (!(iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) && !full_log) |
1846 | size = (size > DEFAULT_DUMP_EVENT_LOG_ENTRIES) | 1846 | size = (size > DEFAULT_DUMP_EVENT_LOG_ENTRIES) |
1847 | ? DEFAULT_DUMP_EVENT_LOG_ENTRIES : size; | 1847 | ? DEFAULT_DUMP_EVENT_LOG_ENTRIES : size; |
1848 | #else | 1848 | #else |
@@ -3173,7 +3173,6 @@ static int iwl_init_drv(struct iwl_priv *priv) | |||
3173 | 3173 | ||
3174 | priv->ibss_beacon = NULL; | 3174 | priv->ibss_beacon = NULL; |
3175 | 3175 | ||
3176 | spin_lock_init(&priv->lock); | ||
3177 | spin_lock_init(&priv->sta_lock); | 3176 | spin_lock_init(&priv->sta_lock); |
3178 | spin_lock_init(&priv->hcmd_lock); | 3177 | spin_lock_init(&priv->hcmd_lock); |
3179 | 3178 | ||
@@ -3361,10 +3360,11 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3361 | (unsigned long long) pci_resource_len(pdev, 0)); | 3360 | (unsigned long long) pci_resource_len(pdev, 0)); |
3362 | IWL_DEBUG_INFO(priv, "pci_resource_base = %p\n", priv->hw_base); | 3361 | IWL_DEBUG_INFO(priv, "pci_resource_base = %p\n", priv->hw_base); |
3363 | 3362 | ||
3364 | /* this spin lock will be used in apm_ops.init and EEPROM access | 3363 | /* these spin locks will be used in apm_ops.init and EEPROM access |
3365 | * we should init now | 3364 | * we should init now |
3366 | */ | 3365 | */ |
3367 | spin_lock_init(&priv->reg_lock); | 3366 | spin_lock_init(&priv->reg_lock); |
3367 | spin_lock_init(&priv->lock); | ||
3368 | iwl_hw_detect(priv); | 3368 | iwl_hw_detect(priv); |
3369 | IWL_INFO(priv, "Detected Intel Wireless WiFi Link %s REV=0x%X\n", | 3369 | IWL_INFO(priv, "Detected Intel Wireless WiFi Link %s REV=0x%X\n", |
3370 | priv->cfg->name, priv->hw_rev); | 3370 | priv->cfg->name, priv->hw_rev); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h index a7bfae01f19b..1ec8cb4d5eae 100644 --- a/drivers/net/wireless/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/iwlwifi/iwl-csr.h | |||
@@ -77,8 +77,7 @@ | |||
77 | * The MAC (uCode processor, etc.) does not need to be powered up for accessing | 77 | * The MAC (uCode processor, etc.) does not need to be powered up for accessing |
78 | * the CSR registers. | 78 | * the CSR registers. |
79 | * | 79 | * |
80 | * NOTE: Newer devices using one-time-programmable (OTP) memory | 80 | * NOTE: Device does need to be awake in order to read this memory |
81 | * require device to be awake in order to read this memory | ||
82 | * via CSR_EEPROM and CSR_OTP registers | 81 | * via CSR_EEPROM and CSR_OTP registers |
83 | */ | 82 | */ |
84 | #define CSR_BASE (0x000) | 83 | #define CSR_BASE (0x000) |
@@ -111,9 +110,8 @@ | |||
111 | /* | 110 | /* |
112 | * EEPROM and OTP (one-time-programmable) memory reads | 111 | * EEPROM and OTP (one-time-programmable) memory reads |
113 | * | 112 | * |
114 | * NOTE: For (newer) devices using OTP, device must be awake, initialized via | 113 | * NOTE: Device must be awake, initialized via apm_ops.init(), |
115 | * apm_ops.init() in order to read. Older devices (3945/4965/5000) | 114 | * in order to read. |
116 | * use EEPROM and do not require this. | ||
117 | */ | 115 | */ |
118 | #define CSR_EEPROM_REG (CSR_BASE+0x02c) | 116 | #define CSR_EEPROM_REG (CSR_BASE+0x02c) |
119 | #define CSR_EEPROM_GP (CSR_BASE+0x030) | 117 | #define CSR_EEPROM_GP (CSR_BASE+0x030) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 2673e9a4db92..165d1f6e2dd9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -1168,7 +1168,7 @@ struct iwl_priv { | |||
1168 | u32 last_beacon_time; | 1168 | u32 last_beacon_time; |
1169 | u64 last_tsf; | 1169 | u64 last_tsf; |
1170 | 1170 | ||
1171 | /* eeprom */ | 1171 | /* eeprom -- this is in the card's little endian byte order */ |
1172 | u8 *eeprom; | 1172 | u8 *eeprom; |
1173 | int nvm_device_type; | 1173 | int nvm_device_type; |
1174 | struct iwl_eeprom_calib_info *calib_info; | 1174 | struct iwl_eeprom_calib_info *calib_info; |
@@ -1353,4 +1353,15 @@ static inline int is_channel_ibss(const struct iwl_channel_info *ch) | |||
1353 | return ((ch->flags & EEPROM_CHANNEL_IBSS)) ? 1 : 0; | 1353 | return ((ch->flags & EEPROM_CHANNEL_IBSS)) ? 1 : 0; |
1354 | } | 1354 | } |
1355 | 1355 | ||
1356 | static inline void __iwl_free_pages(struct iwl_priv *priv, struct page *page) | ||
1357 | { | ||
1358 | __free_pages(page, priv->hw_params.rx_page_order); | ||
1359 | priv->alloc_rxb_page--; | ||
1360 | } | ||
1361 | |||
1362 | static inline void iwl_free_pages(struct iwl_priv *priv, unsigned long page) | ||
1363 | { | ||
1364 | free_pages(page, priv->hw_params.rx_page_order); | ||
1365 | priv->alloc_rxb_page--; | ||
1366 | } | ||
1356 | #endif /* __iwl_dev_h__ */ | 1367 | #endif /* __iwl_dev_h__ */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index 3946e5c03f81..4a30969689ff 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c | |||
@@ -370,7 +370,7 @@ static int iwl_init_otp_access(struct iwl_priv *priv) | |||
370 | return ret; | 370 | return ret; |
371 | } | 371 | } |
372 | 372 | ||
373 | static int iwl_read_otp_word(struct iwl_priv *priv, u16 addr, u16 *eeprom_data) | 373 | static int iwl_read_otp_word(struct iwl_priv *priv, u16 addr, __le16 *eeprom_data) |
374 | { | 374 | { |
375 | int ret = 0; | 375 | int ret = 0; |
376 | u32 r; | 376 | u32 r; |
@@ -404,7 +404,7 @@ static int iwl_read_otp_word(struct iwl_priv *priv, u16 addr, u16 *eeprom_data) | |||
404 | CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK); | 404 | CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK); |
405 | IWL_ERR(priv, "Correctable OTP ECC error, continue read\n"); | 405 | IWL_ERR(priv, "Correctable OTP ECC error, continue read\n"); |
406 | } | 406 | } |
407 | *eeprom_data = le16_to_cpu((__force __le16)(r >> 16)); | 407 | *eeprom_data = cpu_to_le16(r >> 16); |
408 | return 0; | 408 | return 0; |
409 | } | 409 | } |
410 | 410 | ||
@@ -413,7 +413,8 @@ static int iwl_read_otp_word(struct iwl_priv *priv, u16 addr, u16 *eeprom_data) | |||
413 | */ | 413 | */ |
414 | static bool iwl_is_otp_empty(struct iwl_priv *priv) | 414 | static bool iwl_is_otp_empty(struct iwl_priv *priv) |
415 | { | 415 | { |
416 | u16 next_link_addr = 0, link_value; | 416 | u16 next_link_addr = 0; |
417 | __le16 link_value; | ||
417 | bool is_empty = false; | 418 | bool is_empty = false; |
418 | 419 | ||
419 | /* locate the beginning of OTP link list */ | 420 | /* locate the beginning of OTP link list */ |
@@ -443,7 +444,8 @@ static bool iwl_is_otp_empty(struct iwl_priv *priv) | |||
443 | static int iwl_find_otp_image(struct iwl_priv *priv, | 444 | static int iwl_find_otp_image(struct iwl_priv *priv, |
444 | u16 *validblockaddr) | 445 | u16 *validblockaddr) |
445 | { | 446 | { |
446 | u16 next_link_addr = 0, link_value = 0, valid_addr; | 447 | u16 next_link_addr = 0, valid_addr; |
448 | __le16 link_value = 0; | ||
447 | int usedblocks = 0; | 449 | int usedblocks = 0; |
448 | 450 | ||
449 | /* set addressing mode to absolute to traverse the link list */ | 451 | /* set addressing mode to absolute to traverse the link list */ |
@@ -463,7 +465,7 @@ static int iwl_find_otp_image(struct iwl_priv *priv, | |||
463 | * check for more block on the link list | 465 | * check for more block on the link list |
464 | */ | 466 | */ |
465 | valid_addr = next_link_addr; | 467 | valid_addr = next_link_addr; |
466 | next_link_addr = link_value * sizeof(u16); | 468 | next_link_addr = le16_to_cpu(link_value) * sizeof(u16); |
467 | IWL_DEBUG_INFO(priv, "OTP blocks %d addr 0x%x\n", | 469 | IWL_DEBUG_INFO(priv, "OTP blocks %d addr 0x%x\n", |
468 | usedblocks, next_link_addr); | 470 | usedblocks, next_link_addr); |
469 | if (iwl_read_otp_word(priv, next_link_addr, &link_value)) | 471 | if (iwl_read_otp_word(priv, next_link_addr, &link_value)) |
@@ -497,7 +499,7 @@ static int iwl_find_otp_image(struct iwl_priv *priv, | |||
497 | */ | 499 | */ |
498 | int iwl_eeprom_init(struct iwl_priv *priv) | 500 | int iwl_eeprom_init(struct iwl_priv *priv) |
499 | { | 501 | { |
500 | u16 *e; | 502 | __le16 *e; |
501 | u32 gp = iwl_read32(priv, CSR_EEPROM_GP); | 503 | u32 gp = iwl_read32(priv, CSR_EEPROM_GP); |
502 | int sz; | 504 | int sz; |
503 | int ret; | 505 | int ret; |
@@ -516,12 +518,9 @@ int iwl_eeprom_init(struct iwl_priv *priv) | |||
516 | ret = -ENOMEM; | 518 | ret = -ENOMEM; |
517 | goto alloc_err; | 519 | goto alloc_err; |
518 | } | 520 | } |
519 | e = (u16 *)priv->eeprom; | 521 | e = (__le16 *)priv->eeprom; |
520 | 522 | ||
521 | if (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) { | 523 | priv->cfg->ops->lib->apm_ops.init(priv); |
522 | /* OTP reads require powered-up chip */ | ||
523 | priv->cfg->ops->lib->apm_ops.init(priv); | ||
524 | } | ||
525 | 524 | ||
526 | ret = priv->cfg->ops->lib->eeprom_ops.verify_signature(priv); | 525 | ret = priv->cfg->ops->lib->eeprom_ops.verify_signature(priv); |
527 | if (ret < 0) { | 526 | if (ret < 0) { |
@@ -562,7 +561,7 @@ int iwl_eeprom_init(struct iwl_priv *priv) | |||
562 | } | 561 | } |
563 | for (addr = validblockaddr; addr < validblockaddr + sz; | 562 | for (addr = validblockaddr; addr < validblockaddr + sz; |
564 | addr += sizeof(u16)) { | 563 | addr += sizeof(u16)) { |
565 | u16 eeprom_data; | 564 | __le16 eeprom_data; |
566 | 565 | ||
567 | ret = iwl_read_otp_word(priv, addr, &eeprom_data); | 566 | ret = iwl_read_otp_word(priv, addr, &eeprom_data); |
568 | if (ret) | 567 | if (ret) |
@@ -570,13 +569,6 @@ int iwl_eeprom_init(struct iwl_priv *priv) | |||
570 | e[cache_addr / 2] = eeprom_data; | 569 | e[cache_addr / 2] = eeprom_data; |
571 | cache_addr += sizeof(u16); | 570 | cache_addr += sizeof(u16); |
572 | } | 571 | } |
573 | |||
574 | /* | ||
575 | * Now that OTP reads are complete, reset chip to save | ||
576 | * power until we load uCode during "up". | ||
577 | */ | ||
578 | priv->cfg->ops->lib->apm_ops.stop(priv); | ||
579 | |||
580 | } else { | 572 | } else { |
581 | /* eeprom is an array of 16bit values */ | 573 | /* eeprom is an array of 16bit values */ |
582 | for (addr = 0; addr < sz; addr += sizeof(u16)) { | 574 | for (addr = 0; addr < sz; addr += sizeof(u16)) { |
@@ -594,7 +586,7 @@ int iwl_eeprom_init(struct iwl_priv *priv) | |||
594 | goto done; | 586 | goto done; |
595 | } | 587 | } |
596 | r = _iwl_read_direct32(priv, CSR_EEPROM_REG); | 588 | r = _iwl_read_direct32(priv, CSR_EEPROM_REG); |
597 | e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16)); | 589 | e[addr / 2] = cpu_to_le16(r >> 16); |
598 | } | 590 | } |
599 | } | 591 | } |
600 | ret = 0; | 592 | ret = 0; |
@@ -603,6 +595,8 @@ done: | |||
603 | err: | 595 | err: |
604 | if (ret) | 596 | if (ret) |
605 | iwl_eeprom_free(priv); | 597 | iwl_eeprom_free(priv); |
598 | /* Reset chip to save power until we load uCode during "up". */ | ||
599 | priv->cfg->ops->lib->apm_ops.stop(priv); | ||
606 | alloc_err: | 600 | alloc_err: |
607 | return ret; | 601 | return ret; |
608 | } | 602 | } |
@@ -755,7 +749,8 @@ static int iwl_mod_ht40_chan_info(struct iwl_priv *priv, | |||
755 | ch_info->ht40_eeprom = *eeprom_ch; | 749 | ch_info->ht40_eeprom = *eeprom_ch; |
756 | ch_info->ht40_max_power_avg = eeprom_ch->max_power_avg; | 750 | ch_info->ht40_max_power_avg = eeprom_ch->max_power_avg; |
757 | ch_info->ht40_flags = eeprom_ch->flags; | 751 | ch_info->ht40_flags = eeprom_ch->flags; |
758 | ch_info->ht40_extension_channel &= ~clear_ht40_extension_channel; | 752 | if (eeprom_ch->flags & EEPROM_CHANNEL_VALID) |
753 | ch_info->ht40_extension_channel &= ~clear_ht40_extension_channel; | ||
759 | 754 | ||
760 | return 0; | 755 | return 0; |
761 | } | 756 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index 5cd2b66bbe45..0cd9c02ee044 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h | |||
@@ -137,7 +137,7 @@ struct iwl_eeprom_channel { | |||
137 | * | 137 | * |
138 | */ | 138 | */ |
139 | struct iwl_eeprom_enhanced_txpwr { | 139 | struct iwl_eeprom_enhanced_txpwr { |
140 | u16 common; | 140 | __le16 common; |
141 | s8 chain_a_max; | 141 | s8 chain_a_max; |
142 | s8 chain_b_max; | 142 | s8 chain_b_max; |
143 | s8 chain_c_max; | 143 | s8 chain_c_max; |
@@ -360,7 +360,7 @@ struct iwl_eeprom_calib_subband_info { | |||
360 | struct iwl_eeprom_calib_info { | 360 | struct iwl_eeprom_calib_info { |
361 | u8 saturation_power24; /* half-dBm (e.g. "34" = 17 dBm) */ | 361 | u8 saturation_power24; /* half-dBm (e.g. "34" = 17 dBm) */ |
362 | u8 saturation_power52; /* half-dBm */ | 362 | u8 saturation_power52; /* half-dBm */ |
363 | s16 voltage; /* signed */ | 363 | __le16 voltage; /* signed */ |
364 | struct iwl_eeprom_calib_subband_info | 364 | struct iwl_eeprom_calib_subband_info |
365 | band_info[EEPROM_TX_POWER_BANDS]; | 365 | band_info[EEPROM_TX_POWER_BANDS]; |
366 | } __attribute__ ((packed)); | 366 | } __attribute__ ((packed)); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c index a23165948202..30e9ea6d54ec 100644 --- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c | |||
@@ -234,7 +234,7 @@ cancel: | |||
234 | } | 234 | } |
235 | fail: | 235 | fail: |
236 | if (cmd->reply_page) { | 236 | if (cmd->reply_page) { |
237 | free_pages(cmd->reply_page, priv->hw_params.rx_page_order); | 237 | iwl_free_pages(priv, cmd->reply_page); |
238 | cmd->reply_page = 0; | 238 | cmd->reply_page = 0; |
239 | } | 239 | } |
240 | out: | 240 | out: |
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index 6090bc15a6d5..6f36b6e79f5e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c | |||
@@ -345,10 +345,8 @@ void iwl_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq) | |||
345 | pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma, | 345 | pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma, |
346 | PAGE_SIZE << priv->hw_params.rx_page_order, | 346 | PAGE_SIZE << priv->hw_params.rx_page_order, |
347 | PCI_DMA_FROMDEVICE); | 347 | PCI_DMA_FROMDEVICE); |
348 | __free_pages(rxq->pool[i].page, | 348 | __iwl_free_pages(priv, rxq->pool[i].page); |
349 | priv->hw_params.rx_page_order); | ||
350 | rxq->pool[i].page = NULL; | 349 | rxq->pool[i].page = NULL; |
351 | priv->alloc_rxb_page--; | ||
352 | } | 350 | } |
353 | } | 351 | } |
354 | 352 | ||
@@ -416,9 +414,7 @@ void iwl_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq) | |||
416 | pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma, | 414 | pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma, |
417 | PAGE_SIZE << priv->hw_params.rx_page_order, | 415 | PAGE_SIZE << priv->hw_params.rx_page_order, |
418 | PCI_DMA_FROMDEVICE); | 416 | PCI_DMA_FROMDEVICE); |
419 | priv->alloc_rxb_page--; | 417 | __iwl_free_pages(priv, rxq->pool[i].page); |
420 | __free_pages(rxq->pool[i].page, | ||
421 | priv->hw_params.rx_page_order); | ||
422 | rxq->pool[i].page = NULL; | 418 | rxq->pool[i].page = NULL; |
423 | } | 419 | } |
424 | list_add_tail(&rxq->pool[i].list, &rxq->rx_used); | 420 | list_add_tail(&rxq->pool[i].list, &rxq->rx_used); |
@@ -654,47 +650,6 @@ void iwl_reply_statistics(struct iwl_priv *priv, | |||
654 | } | 650 | } |
655 | EXPORT_SYMBOL(iwl_reply_statistics); | 651 | EXPORT_SYMBOL(iwl_reply_statistics); |
656 | 652 | ||
657 | #define PERFECT_RSSI (-20) /* dBm */ | ||
658 | #define WORST_RSSI (-95) /* dBm */ | ||
659 | #define RSSI_RANGE (PERFECT_RSSI - WORST_RSSI) | ||
660 | |||
661 | /* Calculate an indication of rx signal quality (a percentage, not dBm!). | ||
662 | * See http://www.ces.clemson.edu/linux/signal_quality.shtml for info | ||
663 | * about formulas used below. */ | ||
664 | static int iwl_calc_sig_qual(int rssi_dbm, int noise_dbm) | ||
665 | { | ||
666 | int sig_qual; | ||
667 | int degradation = PERFECT_RSSI - rssi_dbm; | ||
668 | |||
669 | /* If we get a noise measurement, use signal-to-noise ratio (SNR) | ||
670 | * as indicator; formula is (signal dbm - noise dbm). | ||
671 | * SNR at or above 40 is a great signal (100%). | ||
672 | * Below that, scale to fit SNR of 0 - 40 dB within 0 - 100% indicator. | ||
673 | * Weakest usable signal is usually 10 - 15 dB SNR. */ | ||
674 | if (noise_dbm) { | ||
675 | if (rssi_dbm - noise_dbm >= 40) | ||
676 | return 100; | ||
677 | else if (rssi_dbm < noise_dbm) | ||
678 | return 0; | ||
679 | sig_qual = ((rssi_dbm - noise_dbm) * 5) / 2; | ||
680 | |||
681 | /* Else use just the signal level. | ||
682 | * This formula is a least squares fit of data points collected and | ||
683 | * compared with a reference system that had a percentage (%) display | ||
684 | * for signal quality. */ | ||
685 | } else | ||
686 | sig_qual = (100 * (RSSI_RANGE * RSSI_RANGE) - degradation * | ||
687 | (15 * RSSI_RANGE + 62 * degradation)) / | ||
688 | (RSSI_RANGE * RSSI_RANGE); | ||
689 | |||
690 | if (sig_qual > 100) | ||
691 | sig_qual = 100; | ||
692 | else if (sig_qual < 1) | ||
693 | sig_qual = 0; | ||
694 | |||
695 | return sig_qual; | ||
696 | } | ||
697 | |||
698 | /* Calc max signal level (dBm) among 3 possible receivers */ | 653 | /* Calc max signal level (dBm) among 3 possible receivers */ |
699 | static inline int iwl_calc_rssi(struct iwl_priv *priv, | 654 | static inline int iwl_calc_rssi(struct iwl_priv *priv, |
700 | struct iwl_rx_phy_res *rx_resp) | 655 | struct iwl_rx_phy_res *rx_resp) |
@@ -1105,11 +1060,8 @@ void iwl_rx_reply_rx(struct iwl_priv *priv, | |||
1105 | if (iwl_is_associated(priv) && | 1060 | if (iwl_is_associated(priv) && |
1106 | !test_bit(STATUS_SCANNING, &priv->status)) { | 1061 | !test_bit(STATUS_SCANNING, &priv->status)) { |
1107 | rx_status.noise = priv->last_rx_noise; | 1062 | rx_status.noise = priv->last_rx_noise; |
1108 | rx_status.qual = iwl_calc_sig_qual(rx_status.signal, | ||
1109 | rx_status.noise); | ||
1110 | } else { | 1063 | } else { |
1111 | rx_status.noise = IWL_NOISE_MEAS_NOT_AVAILABLE; | 1064 | rx_status.noise = IWL_NOISE_MEAS_NOT_AVAILABLE; |
1112 | rx_status.qual = iwl_calc_sig_qual(rx_status.signal, 0); | ||
1113 | } | 1065 | } |
1114 | 1066 | ||
1115 | /* Reset beacon noise level if not associated. */ | 1067 | /* Reset beacon noise level if not associated. */ |
@@ -1122,8 +1074,8 @@ void iwl_rx_reply_rx(struct iwl_priv *priv, | |||
1122 | iwl_dbg_report_frame(priv, phy_res, len, header, 1); | 1074 | iwl_dbg_report_frame(priv, phy_res, len, header, 1); |
1123 | #endif | 1075 | #endif |
1124 | iwl_dbg_log_rx_data_frame(priv, len, header); | 1076 | iwl_dbg_log_rx_data_frame(priv, len, header); |
1125 | IWL_DEBUG_STATS_LIMIT(priv, "Rssi %d, noise %d, qual %d, TSF %llu\n", | 1077 | IWL_DEBUG_STATS_LIMIT(priv, "Rssi %d, noise %d, TSF %llu\n", |
1126 | rx_status.signal, rx_status.noise, rx_status.qual, | 1078 | rx_status.signal, rx_status.noise, |
1127 | (unsigned long long)rx_status.mactime); | 1079 | (unsigned long long)rx_status.mactime); |
1128 | 1080 | ||
1129 | /* | 1081 | /* |
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index a2b2b8315ff9..fa1c89ba6459 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c | |||
@@ -144,8 +144,7 @@ static int iwl_send_scan_abort(struct iwl_priv *priv) | |||
144 | clear_bit(STATUS_SCAN_HW, &priv->status); | 144 | clear_bit(STATUS_SCAN_HW, &priv->status); |
145 | } | 145 | } |
146 | 146 | ||
147 | priv->alloc_rxb_page--; | 147 | iwl_free_pages(priv, cmd.reply_page); |
148 | free_pages(cmd.reply_page, priv->hw_params.rx_page_order); | ||
149 | 148 | ||
150 | return ret; | 149 | return ret; |
151 | } | 150 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index cd6a6901216e..cde09a890b73 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c | |||
@@ -164,9 +164,7 @@ int iwl_send_add_sta(struct iwl_priv *priv, | |||
164 | break; | 164 | break; |
165 | } | 165 | } |
166 | } | 166 | } |
167 | 167 | iwl_free_pages(priv, cmd.reply_page); | |
168 | priv->alloc_rxb_page--; | ||
169 | free_pages(cmd.reply_page, priv->hw_params.rx_page_order); | ||
170 | 168 | ||
171 | return ret; | 169 | return ret; |
172 | } | 170 | } |
@@ -391,9 +389,7 @@ static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr, | |||
391 | break; | 389 | break; |
392 | } | 390 | } |
393 | } | 391 | } |
394 | 392 | iwl_free_pages(priv, cmd.reply_page); | |
395 | priv->alloc_rxb_page--; | ||
396 | free_pages(cmd.reply_page, priv->hw_params.rx_page_order); | ||
397 | 393 | ||
398 | return ret; | 394 | return ret; |
399 | } | 395 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 00da5e152d46..87ce2bd292c7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c | |||
@@ -407,13 +407,14 @@ void iwl_hw_txq_ctx_free(struct iwl_priv *priv) | |||
407 | int txq_id; | 407 | int txq_id; |
408 | 408 | ||
409 | /* Tx queues */ | 409 | /* Tx queues */ |
410 | if (priv->txq) | 410 | if (priv->txq) { |
411 | for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; | 411 | for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; |
412 | txq_id++) | 412 | txq_id++) |
413 | if (txq_id == IWL_CMD_QUEUE_NUM) | 413 | if (txq_id == IWL_CMD_QUEUE_NUM) |
414 | iwl_cmd_queue_free(priv); | 414 | iwl_cmd_queue_free(priv); |
415 | else | 415 | else |
416 | iwl_tx_queue_free(priv, txq_id); | 416 | iwl_tx_queue_free(priv, txq_id); |
417 | } | ||
417 | iwl_free_dma_ptr(priv, &priv->kw); | 418 | iwl_free_dma_ptr(priv, &priv->kw); |
418 | 419 | ||
419 | iwl_free_dma_ptr(priv, &priv->scd_bc_tbls); | 420 | iwl_free_dma_ptr(priv, &priv->scd_bc_tbls); |
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 2a28a1f8b1fe..f8e4e4b18d02 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -548,6 +548,9 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
548 | txq = &priv->txq[txq_id]; | 548 | txq = &priv->txq[txq_id]; |
549 | q = &txq->q; | 549 | q = &txq->q; |
550 | 550 | ||
551 | if ((iwl_queue_space(q) < q->high_mark)) | ||
552 | goto drop; | ||
553 | |||
551 | spin_lock_irqsave(&priv->lock, flags); | 554 | spin_lock_irqsave(&priv->lock, flags); |
552 | 555 | ||
553 | idx = get_cmd_index(q, q->write_ptr, 0); | 556 | idx = get_cmd_index(q, q->write_ptr, 0); |
@@ -812,7 +815,7 @@ static int iwl3945_get_measurement(struct iwl_priv *priv, | |||
812 | break; | 815 | break; |
813 | } | 816 | } |
814 | 817 | ||
815 | free_pages(cmd.reply_page, priv->hw_params.rx_page_order); | 818 | iwl_free_pages(priv, cmd.reply_page); |
816 | 819 | ||
817 | return rc; | 820 | return rc; |
818 | } | 821 | } |
@@ -1198,9 +1201,7 @@ void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq) | |||
1198 | pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma, | 1201 | pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma, |
1199 | PAGE_SIZE << priv->hw_params.rx_page_order, | 1202 | PAGE_SIZE << priv->hw_params.rx_page_order, |
1200 | PCI_DMA_FROMDEVICE); | 1203 | PCI_DMA_FROMDEVICE); |
1201 | priv->alloc_rxb_page--; | 1204 | __iwl_free_pages(priv, rxq->pool[i].page); |
1202 | __free_pages(rxq->pool[i].page, | ||
1203 | priv->hw_params.rx_page_order); | ||
1204 | rxq->pool[i].page = NULL; | 1205 | rxq->pool[i].page = NULL; |
1205 | } | 1206 | } |
1206 | list_add_tail(&rxq->pool[i].list, &rxq->rx_used); | 1207 | list_add_tail(&rxq->pool[i].list, &rxq->rx_used); |
@@ -1247,10 +1248,8 @@ static void iwl3945_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rx | |||
1247 | pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma, | 1248 | pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma, |
1248 | PAGE_SIZE << priv->hw_params.rx_page_order, | 1249 | PAGE_SIZE << priv->hw_params.rx_page_order, |
1249 | PCI_DMA_FROMDEVICE); | 1250 | PCI_DMA_FROMDEVICE); |
1250 | __free_pages(rxq->pool[i].page, | 1251 | __iwl_free_pages(priv, rxq->pool[i].page); |
1251 | priv->hw_params.rx_page_order); | ||
1252 | rxq->pool[i].page = NULL; | 1252 | rxq->pool[i].page = NULL; |
1253 | priv->alloc_rxb_page--; | ||
1254 | } | 1253 | } |
1255 | } | 1254 | } |
1256 | 1255 | ||
@@ -1300,47 +1299,6 @@ int iwl3945_calc_db_from_ratio(int sig_ratio) | |||
1300 | return (int)ratio2dB[sig_ratio]; | 1299 | return (int)ratio2dB[sig_ratio]; |
1301 | } | 1300 | } |
1302 | 1301 | ||
1303 | #define PERFECT_RSSI (-20) /* dBm */ | ||
1304 | #define WORST_RSSI (-95) /* dBm */ | ||
1305 | #define RSSI_RANGE (PERFECT_RSSI - WORST_RSSI) | ||
1306 | |||
1307 | /* Calculate an indication of rx signal quality (a percentage, not dBm!). | ||
1308 | * See http://www.ces.clemson.edu/linux/signal_quality.shtml for info | ||
1309 | * about formulas used below. */ | ||
1310 | int iwl3945_calc_sig_qual(int rssi_dbm, int noise_dbm) | ||
1311 | { | ||
1312 | int sig_qual; | ||
1313 | int degradation = PERFECT_RSSI - rssi_dbm; | ||
1314 | |||
1315 | /* If we get a noise measurement, use signal-to-noise ratio (SNR) | ||
1316 | * as indicator; formula is (signal dbm - noise dbm). | ||
1317 | * SNR at or above 40 is a great signal (100%). | ||
1318 | * Below that, scale to fit SNR of 0 - 40 dB within 0 - 100% indicator. | ||
1319 | * Weakest usable signal is usually 10 - 15 dB SNR. */ | ||
1320 | if (noise_dbm) { | ||
1321 | if (rssi_dbm - noise_dbm >= 40) | ||
1322 | return 100; | ||
1323 | else if (rssi_dbm < noise_dbm) | ||
1324 | return 0; | ||
1325 | sig_qual = ((rssi_dbm - noise_dbm) * 5) / 2; | ||
1326 | |||
1327 | /* Else use just the signal level. | ||
1328 | * This formula is a least squares fit of data points collected and | ||
1329 | * compared with a reference system that had a percentage (%) display | ||
1330 | * for signal quality. */ | ||
1331 | } else | ||
1332 | sig_qual = (100 * (RSSI_RANGE * RSSI_RANGE) - degradation * | ||
1333 | (15 * RSSI_RANGE + 62 * degradation)) / | ||
1334 | (RSSI_RANGE * RSSI_RANGE); | ||
1335 | |||
1336 | if (sig_qual > 100) | ||
1337 | sig_qual = 100; | ||
1338 | else if (sig_qual < 1) | ||
1339 | sig_qual = 0; | ||
1340 | |||
1341 | return sig_qual; | ||
1342 | } | ||
1343 | |||
1344 | /** | 1302 | /** |
1345 | * iwl3945_rx_handle - Main entry function for receiving responses from uCode | 1303 | * iwl3945_rx_handle - Main entry function for receiving responses from uCode |
1346 | * | 1304 | * |
@@ -1688,7 +1646,7 @@ void iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log) | |||
1688 | } | 1646 | } |
1689 | 1647 | ||
1690 | #ifdef CONFIG_IWLWIFI_DEBUG | 1648 | #ifdef CONFIG_IWLWIFI_DEBUG |
1691 | if (!(iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS)) | 1649 | if (!(iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) && !full_log) |
1692 | size = (size > DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES) | 1650 | size = (size > DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES) |
1693 | ? DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES : size; | 1651 | ? DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES : size; |
1694 | #else | 1652 | #else |
@@ -3867,7 +3825,6 @@ static int iwl3945_init_drv(struct iwl_priv *priv) | |||
3867 | priv->retry_rate = 1; | 3825 | priv->retry_rate = 1; |
3868 | priv->ibss_beacon = NULL; | 3826 | priv->ibss_beacon = NULL; |
3869 | 3827 | ||
3870 | spin_lock_init(&priv->lock); | ||
3871 | spin_lock_init(&priv->sta_lock); | 3828 | spin_lock_init(&priv->sta_lock); |
3872 | spin_lock_init(&priv->hcmd_lock); | 3829 | spin_lock_init(&priv->hcmd_lock); |
3873 | 3830 | ||
@@ -3936,9 +3893,11 @@ static int iwl3945_setup_mac(struct iwl_priv *priv) | |||
3936 | /* Tell mac80211 our characteristics */ | 3893 | /* Tell mac80211 our characteristics */ |
3937 | hw->flags = IEEE80211_HW_SIGNAL_DBM | | 3894 | hw->flags = IEEE80211_HW_SIGNAL_DBM | |
3938 | IEEE80211_HW_NOISE_DBM | | 3895 | IEEE80211_HW_NOISE_DBM | |
3939 | IEEE80211_HW_SPECTRUM_MGMT | | 3896 | IEEE80211_HW_SPECTRUM_MGMT; |
3940 | IEEE80211_HW_SUPPORTS_PS | | 3897 | |
3941 | IEEE80211_HW_SUPPORTS_DYNAMIC_PS; | 3898 | if (!priv->cfg->broken_powersave) |
3899 | hw->flags |= IEEE80211_HW_SUPPORTS_PS | | ||
3900 | IEEE80211_HW_SUPPORTS_DYNAMIC_PS; | ||
3942 | 3901 | ||
3943 | hw->wiphy->interface_modes = | 3902 | hw->wiphy->interface_modes = |
3944 | BIT(NL80211_IFTYPE_STATION) | | 3903 | BIT(NL80211_IFTYPE_STATION) | |
@@ -4057,10 +4016,11 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
4057 | * PCI Tx retries from interfering with C3 CPU state */ | 4016 | * PCI Tx retries from interfering with C3 CPU state */ |
4058 | pci_write_config_byte(pdev, 0x41, 0x00); | 4017 | pci_write_config_byte(pdev, 0x41, 0x00); |
4059 | 4018 | ||
4060 | /* this spin lock will be used in apm_ops.init and EEPROM access | 4019 | /* these spin locks will be used in apm_ops.init and EEPROM access |
4061 | * we should init now | 4020 | * we should init now |
4062 | */ | 4021 | */ |
4063 | spin_lock_init(&priv->reg_lock); | 4022 | spin_lock_init(&priv->reg_lock); |
4023 | spin_lock_init(&priv->lock); | ||
4064 | 4024 | ||
4065 | /*********************** | 4025 | /*********************** |
4066 | * 4. Read EEPROM | 4026 | * 4. Read EEPROM |
diff --git a/drivers/net/wireless/iwmc3200wifi/iwm.h b/drivers/net/wireless/iwmc3200wifi/iwm.h index 5a26bb05a33a..842811142bef 100644 --- a/drivers/net/wireless/iwmc3200wifi/iwm.h +++ b/drivers/net/wireless/iwmc3200wifi/iwm.h | |||
@@ -268,7 +268,7 @@ struct iwm_priv { | |||
268 | 268 | ||
269 | struct sk_buff_head rx_list; | 269 | struct sk_buff_head rx_list; |
270 | struct list_head rx_tickets; | 270 | struct list_head rx_tickets; |
271 | struct list_head rx_packets[IWM_RX_ID_HASH]; | 271 | struct list_head rx_packets[IWM_RX_ID_HASH + 1]; |
272 | struct workqueue_struct *rx_wq; | 272 | struct workqueue_struct *rx_wq; |
273 | struct work_struct rx_worker; | 273 | struct work_struct rx_worker; |
274 | 274 | ||
@@ -349,7 +349,7 @@ int iwm_up(struct iwm_priv *iwm); | |||
349 | int iwm_down(struct iwm_priv *iwm); | 349 | int iwm_down(struct iwm_priv *iwm); |
350 | 350 | ||
351 | /* TX API */ | 351 | /* TX API */ |
352 | u16 iwm_tid_to_queue(u16 tid); | 352 | int iwm_tid_to_queue(u16 tid); |
353 | void iwm_tx_credit_inc(struct iwm_priv *iwm, int id, int total_freed_pages); | 353 | void iwm_tx_credit_inc(struct iwm_priv *iwm, int id, int total_freed_pages); |
354 | void iwm_tx_worker(struct work_struct *work); | 354 | void iwm_tx_worker(struct work_struct *work); |
355 | int iwm_xmit_frame(struct sk_buff *skb, struct net_device *netdev); | 355 | int iwm_xmit_frame(struct sk_buff *skb, struct net_device *netdev); |
diff --git a/drivers/net/wireless/iwmc3200wifi/netdev.c b/drivers/net/wireless/iwmc3200wifi/netdev.c index e4f0f8705f65..c4c0d23c63ec 100644 --- a/drivers/net/wireless/iwmc3200wifi/netdev.c +++ b/drivers/net/wireless/iwmc3200wifi/netdev.c | |||
@@ -76,7 +76,7 @@ static int iwm_stop(struct net_device *ndev) | |||
76 | */ | 76 | */ |
77 | static const u16 iwm_1d_to_queue[8] = { 1, 0, 0, 1, 2, 2, 3, 3 }; | 77 | static const u16 iwm_1d_to_queue[8] = { 1, 0, 0, 1, 2, 2, 3, 3 }; |
78 | 78 | ||
79 | u16 iwm_tid_to_queue(u16 tid) | 79 | int iwm_tid_to_queue(u16 tid) |
80 | { | 80 | { |
81 | if (tid > IWM_UMAC_TID_NR - 2) | 81 | if (tid > IWM_UMAC_TID_NR - 2) |
82 | return -EINVAL; | 82 | return -EINVAL; |
diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c index 1c57c1f72cba..6d6ed7485175 100644 --- a/drivers/net/wireless/iwmc3200wifi/rx.c +++ b/drivers/net/wireless/iwmc3200wifi/rx.c | |||
@@ -1126,7 +1126,7 @@ static int iwm_ntf_stop_resume_tx(struct iwm_priv *iwm, u8 *buf, | |||
1126 | 1126 | ||
1127 | if (!stop) { | 1127 | if (!stop) { |
1128 | struct iwm_tx_queue *txq; | 1128 | struct iwm_tx_queue *txq; |
1129 | u16 queue = iwm_tid_to_queue(bit); | 1129 | int queue = iwm_tid_to_queue(bit); |
1130 | 1130 | ||
1131 | if (queue < 0) | 1131 | if (queue < 0) |
1132 | continue; | 1132 | continue; |
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index b9b371bfa30f..42611bea76a3 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c | |||
@@ -1365,7 +1365,7 @@ static void lbs_send_confirmsleep(struct lbs_private *priv) | |||
1365 | priv->dnld_sent = DNLD_RES_RECEIVED; | 1365 | priv->dnld_sent = DNLD_RES_RECEIVED; |
1366 | 1366 | ||
1367 | /* If nothing to do, go back to sleep (?) */ | 1367 | /* If nothing to do, go back to sleep (?) */ |
1368 | if (!__kfifo_len(priv->event_fifo) && !priv->resp_len[priv->resp_idx]) | 1368 | if (!kfifo_len(&priv->event_fifo) && !priv->resp_len[priv->resp_idx]) |
1369 | priv->psstate = PS_STATE_SLEEP; | 1369 | priv->psstate = PS_STATE_SLEEP; |
1370 | 1370 | ||
1371 | spin_unlock_irqrestore(&priv->driver_lock, flags); | 1371 | spin_unlock_irqrestore(&priv->driver_lock, flags); |
@@ -1439,7 +1439,7 @@ void lbs_ps_confirm_sleep(struct lbs_private *priv) | |||
1439 | } | 1439 | } |
1440 | 1440 | ||
1441 | /* Pending events or command responses? */ | 1441 | /* Pending events or command responses? */ |
1442 | if (__kfifo_len(priv->event_fifo) || priv->resp_len[priv->resp_idx]) { | 1442 | if (kfifo_len(&priv->event_fifo) || priv->resp_len[priv->resp_idx]) { |
1443 | allowed = 0; | 1443 | allowed = 0; |
1444 | lbs_deb_host("pending events or command responses\n"); | 1444 | lbs_deb_host("pending events or command responses\n"); |
1445 | } | 1445 | } |
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h index 6a8d2b291d8c..05bb298dfae9 100644 --- a/drivers/net/wireless/libertas/dev.h +++ b/drivers/net/wireless/libertas/dev.h | |||
@@ -10,7 +10,7 @@ | |||
10 | #include "scan.h" | 10 | #include "scan.h" |
11 | #include "assoc.h" | 11 | #include "assoc.h" |
12 | 12 | ||
13 | 13 | #include <linux/kfifo.h> | |
14 | 14 | ||
15 | /** sleep_params */ | 15 | /** sleep_params */ |
16 | struct sleep_params { | 16 | struct sleep_params { |
@@ -120,7 +120,7 @@ struct lbs_private { | |||
120 | u32 resp_len[2]; | 120 | u32 resp_len[2]; |
121 | 121 | ||
122 | /* Events sent from hardware to driver */ | 122 | /* Events sent from hardware to driver */ |
123 | struct kfifo *event_fifo; | 123 | struct kfifo event_fifo; |
124 | 124 | ||
125 | /** thread to service interrupts */ | 125 | /** thread to service interrupts */ |
126 | struct task_struct *main_thread; | 126 | struct task_struct *main_thread; |
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index db38a5a719fa..c2975c8e2f21 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c | |||
@@ -459,7 +459,7 @@ static int lbs_thread(void *data) | |||
459 | else if (!list_empty(&priv->cmdpendingq) && | 459 | else if (!list_empty(&priv->cmdpendingq) && |
460 | !(priv->wakeup_dev_required)) | 460 | !(priv->wakeup_dev_required)) |
461 | shouldsleep = 0; /* We have a command to send */ | 461 | shouldsleep = 0; /* We have a command to send */ |
462 | else if (__kfifo_len(priv->event_fifo)) | 462 | else if (kfifo_len(&priv->event_fifo)) |
463 | shouldsleep = 0; /* We have an event to process */ | 463 | shouldsleep = 0; /* We have an event to process */ |
464 | else | 464 | else |
465 | shouldsleep = 1; /* No command */ | 465 | shouldsleep = 1; /* No command */ |
@@ -511,10 +511,13 @@ static int lbs_thread(void *data) | |||
511 | 511 | ||
512 | /* Process hardware events, e.g. card removed, link lost */ | 512 | /* Process hardware events, e.g. card removed, link lost */ |
513 | spin_lock_irq(&priv->driver_lock); | 513 | spin_lock_irq(&priv->driver_lock); |
514 | while (__kfifo_len(priv->event_fifo)) { | 514 | while (kfifo_len(&priv->event_fifo)) { |
515 | u32 event; | 515 | u32 event; |
516 | __kfifo_get(priv->event_fifo, (unsigned char *) &event, | 516 | |
517 | sizeof(event)); | 517 | if (kfifo_out(&priv->event_fifo, |
518 | (unsigned char *) &event, sizeof(event)) != | ||
519 | sizeof(event)) | ||
520 | break; | ||
518 | spin_unlock_irq(&priv->driver_lock); | 521 | spin_unlock_irq(&priv->driver_lock); |
519 | lbs_process_event(priv, event); | 522 | lbs_process_event(priv, event); |
520 | spin_lock_irq(&priv->driver_lock); | 523 | spin_lock_irq(&priv->driver_lock); |
@@ -883,10 +886,9 @@ static int lbs_init_adapter(struct lbs_private *priv) | |||
883 | priv->resp_len[0] = priv->resp_len[1] = 0; | 886 | priv->resp_len[0] = priv->resp_len[1] = 0; |
884 | 887 | ||
885 | /* Create the event FIFO */ | 888 | /* Create the event FIFO */ |
886 | priv->event_fifo = kfifo_alloc(sizeof(u32) * 16, GFP_KERNEL, NULL); | 889 | ret = kfifo_alloc(&priv->event_fifo, sizeof(u32) * 16, GFP_KERNEL); |
887 | if (IS_ERR(priv->event_fifo)) { | 890 | if (ret) { |
888 | lbs_pr_err("Out of memory allocating event FIFO buffer\n"); | 891 | lbs_pr_err("Out of memory allocating event FIFO buffer\n"); |
889 | ret = -ENOMEM; | ||
890 | goto out; | 892 | goto out; |
891 | } | 893 | } |
892 | 894 | ||
@@ -901,8 +903,7 @@ static void lbs_free_adapter(struct lbs_private *priv) | |||
901 | lbs_deb_enter(LBS_DEB_MAIN); | 903 | lbs_deb_enter(LBS_DEB_MAIN); |
902 | 904 | ||
903 | lbs_free_cmd_buffer(priv); | 905 | lbs_free_cmd_buffer(priv); |
904 | if (priv->event_fifo) | 906 | kfifo_free(&priv->event_fifo); |
905 | kfifo_free(priv->event_fifo); | ||
906 | del_timer(&priv->command_timer); | 907 | del_timer(&priv->command_timer); |
907 | del_timer(&priv->auto_deepsleep_timer); | 908 | del_timer(&priv->auto_deepsleep_timer); |
908 | kfree(priv->networks); | 909 | kfree(priv->networks); |
@@ -1177,7 +1178,7 @@ void lbs_queue_event(struct lbs_private *priv, u32 event) | |||
1177 | if (priv->psstate == PS_STATE_SLEEP) | 1178 | if (priv->psstate == PS_STATE_SLEEP) |
1178 | priv->psstate = PS_STATE_AWAKE; | 1179 | priv->psstate = PS_STATE_AWAKE; |
1179 | 1180 | ||
1180 | __kfifo_put(priv->event_fifo, (unsigned char *) &event, sizeof(u32)); | 1181 | kfifo_in(&priv->event_fifo, (unsigned char *) &event, sizeof(u32)); |
1181 | 1182 | ||
1182 | wake_up_interruptible(&priv->waitq); | 1183 | wake_up_interruptible(&priv->waitq); |
1183 | 1184 | ||
diff --git a/drivers/net/wireless/libertas/mesh.c b/drivers/net/wireless/libertas/mesh.c index 2f91c9b808af..92b7a357a5e4 100644 --- a/drivers/net/wireless/libertas/mesh.c +++ b/drivers/net/wireless/libertas/mesh.c | |||
@@ -2,6 +2,7 @@ | |||
2 | #include <linux/delay.h> | 2 | #include <linux/delay.h> |
3 | #include <linux/etherdevice.h> | 3 | #include <linux/etherdevice.h> |
4 | #include <linux/netdevice.h> | 4 | #include <linux/netdevice.h> |
5 | #include <linux/if_ether.h> | ||
5 | #include <linux/if_arp.h> | 6 | #include <linux/if_arp.h> |
6 | #include <linux/kthread.h> | 7 | #include <linux/kthread.h> |
7 | #include <linux/kfifo.h> | 8 | #include <linux/kfifo.h> |
@@ -351,8 +352,7 @@ int lbs_add_mesh(struct lbs_private *priv) | |||
351 | 352 | ||
352 | mesh_dev->netdev_ops = &mesh_netdev_ops; | 353 | mesh_dev->netdev_ops = &mesh_netdev_ops; |
353 | mesh_dev->ethtool_ops = &lbs_ethtool_ops; | 354 | mesh_dev->ethtool_ops = &lbs_ethtool_ops; |
354 | memcpy(mesh_dev->dev_addr, priv->dev->dev_addr, | 355 | memcpy(mesh_dev->dev_addr, priv->dev->dev_addr, ETH_ALEN); |
355 | sizeof(priv->dev->dev_addr)); | ||
356 | 356 | ||
357 | SET_NETDEV_DEV(priv->mesh_dev, priv->dev->dev.parent); | 357 | SET_NETDEV_DEV(priv->mesh_dev, priv->dev->dev.parent); |
358 | 358 | ||
diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c index c6a6c042b82f..b0b1c7841500 100644 --- a/drivers/net/wireless/libertas/scan.c +++ b/drivers/net/wireless/libertas/scan.c | |||
@@ -567,11 +567,8 @@ int lbs_scan_networks(struct lbs_private *priv, int full_scan) | |||
567 | chan_count = lbs_scan_create_channel_list(priv, chan_list); | 567 | chan_count = lbs_scan_create_channel_list(priv, chan_list); |
568 | 568 | ||
569 | netif_stop_queue(priv->dev); | 569 | netif_stop_queue(priv->dev); |
570 | netif_carrier_off(priv->dev); | 570 | if (priv->mesh_dev) |
571 | if (priv->mesh_dev) { | ||
572 | netif_stop_queue(priv->mesh_dev); | 571 | netif_stop_queue(priv->mesh_dev); |
573 | netif_carrier_off(priv->mesh_dev); | ||
574 | } | ||
575 | 572 | ||
576 | /* Prepare to continue an interrupted scan */ | 573 | /* Prepare to continue an interrupted scan */ |
577 | lbs_deb_scan("chan_count %d, scan_channel %d\n", | 574 | lbs_deb_scan("chan_count %d, scan_channel %d\n", |
@@ -635,16 +632,13 @@ out2: | |||
635 | priv->scan_channel = 0; | 632 | priv->scan_channel = 0; |
636 | 633 | ||
637 | out: | 634 | out: |
638 | if (priv->connect_status == LBS_CONNECTED) { | 635 | if (priv->connect_status == LBS_CONNECTED && !priv->tx_pending_len) |
639 | netif_carrier_on(priv->dev); | 636 | netif_wake_queue(priv->dev); |
640 | if (!priv->tx_pending_len) | 637 | |
641 | netif_wake_queue(priv->dev); | 638 | if (priv->mesh_dev && (priv->mesh_connect_status == LBS_CONNECTED) && |
642 | } | 639 | !priv->tx_pending_len) |
643 | if (priv->mesh_dev && (priv->mesh_connect_status == LBS_CONNECTED)) { | 640 | netif_wake_queue(priv->mesh_dev); |
644 | netif_carrier_on(priv->mesh_dev); | 641 | |
645 | if (!priv->tx_pending_len) | ||
646 | netif_wake_queue(priv->mesh_dev); | ||
647 | } | ||
648 | kfree(chan_list); | 642 | kfree(chan_list); |
649 | 643 | ||
650 | lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret); | 644 | lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret); |
diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c index a8eb9e1fcf36..4b1aab593a84 100644 --- a/drivers/net/wireless/libertas/wext.c +++ b/drivers/net/wireless/libertas/wext.c | |||
@@ -2025,10 +2025,8 @@ static int lbs_get_essid(struct net_device *dev, struct iw_request_info *info, | |||
2025 | if (priv->connect_status == LBS_CONNECTED) { | 2025 | if (priv->connect_status == LBS_CONNECTED) { |
2026 | memcpy(extra, priv->curbssparams.ssid, | 2026 | memcpy(extra, priv->curbssparams.ssid, |
2027 | priv->curbssparams.ssid_len); | 2027 | priv->curbssparams.ssid_len); |
2028 | extra[priv->curbssparams.ssid_len] = '\0'; | ||
2029 | } else { | 2028 | } else { |
2030 | memset(extra, 0, 32); | 2029 | memset(extra, 0, 32); |
2031 | extra[priv->curbssparams.ssid_len] = '\0'; | ||
2032 | } | 2030 | } |
2033 | /* | 2031 | /* |
2034 | * If none, we may want to get the one that was set | 2032 | * If none, we may want to get the one that was set |
diff --git a/drivers/net/wireless/libertas_tf/main.c b/drivers/net/wireless/libertas_tf/main.c index 019431d2f8a9..26a1abd5bb03 100644 --- a/drivers/net/wireless/libertas_tf/main.c +++ b/drivers/net/wireless/libertas_tf/main.c | |||
@@ -495,7 +495,6 @@ int lbtf_rx(struct lbtf_private *priv, struct sk_buff *skb) | |||
495 | stats.band = IEEE80211_BAND_2GHZ; | 495 | stats.band = IEEE80211_BAND_2GHZ; |
496 | stats.signal = prxpd->snr; | 496 | stats.signal = prxpd->snr; |
497 | stats.noise = prxpd->nf; | 497 | stats.noise = prxpd->nf; |
498 | stats.qual = prxpd->snr - prxpd->nf; | ||
499 | /* Marvell rate index has a hole at value 4 */ | 498 | /* Marvell rate index has a hole at value 4 */ |
500 | if (prxpd->rx_rate > 4) | 499 | if (prxpd->rx_rate > 4) |
501 | --prxpd->rx_rate; | 500 | --prxpd->rx_rate; |
diff --git a/drivers/net/wireless/orinoco/wext.c b/drivers/net/wireless/orinoco/wext.c index 7698fdd6a3a2..31ca241f7753 100644 --- a/drivers/net/wireless/orinoco/wext.c +++ b/drivers/net/wireless/orinoco/wext.c | |||
@@ -23,7 +23,7 @@ | |||
23 | #define MAX_RID_LEN 1024 | 23 | #define MAX_RID_LEN 1024 |
24 | 24 | ||
25 | /* Helper routine to record keys | 25 | /* Helper routine to record keys |
26 | * Do not call from interrupt context */ | 26 | * It is called under orinoco_lock so it may not sleep */ |
27 | static int orinoco_set_key(struct orinoco_private *priv, int index, | 27 | static int orinoco_set_key(struct orinoco_private *priv, int index, |
28 | enum orinoco_alg alg, const u8 *key, int key_len, | 28 | enum orinoco_alg alg, const u8 *key, int key_len, |
29 | const u8 *seq, int seq_len) | 29 | const u8 *seq, int seq_len) |
@@ -32,14 +32,14 @@ static int orinoco_set_key(struct orinoco_private *priv, int index, | |||
32 | kzfree(priv->keys[index].seq); | 32 | kzfree(priv->keys[index].seq); |
33 | 33 | ||
34 | if (key_len) { | 34 | if (key_len) { |
35 | priv->keys[index].key = kzalloc(key_len, GFP_KERNEL); | 35 | priv->keys[index].key = kzalloc(key_len, GFP_ATOMIC); |
36 | if (!priv->keys[index].key) | 36 | if (!priv->keys[index].key) |
37 | goto nomem; | 37 | goto nomem; |
38 | } else | 38 | } else |
39 | priv->keys[index].key = NULL; | 39 | priv->keys[index].key = NULL; |
40 | 40 | ||
41 | if (seq_len) { | 41 | if (seq_len) { |
42 | priv->keys[index].seq = kzalloc(seq_len, GFP_KERNEL); | 42 | priv->keys[index].seq = kzalloc(seq_len, GFP_ATOMIC); |
43 | if (!priv->keys[index].seq) | 43 | if (!priv->keys[index].seq) |
44 | goto free_key; | 44 | goto free_key; |
45 | } else | 45 | } else |
diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index c5fe867665e6..1a7eae357fef 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h | |||
@@ -1323,7 +1323,7 @@ | |||
1323 | #define PAIRWISE_KEY_ENTRY(__idx) \ | 1323 | #define PAIRWISE_KEY_ENTRY(__idx) \ |
1324 | ( PAIRWISE_KEY_TABLE_BASE + ((__idx) * sizeof(struct hw_key_entry)) ) | 1324 | ( PAIRWISE_KEY_TABLE_BASE + ((__idx) * sizeof(struct hw_key_entry)) ) |
1325 | #define MAC_IVEIV_ENTRY(__idx) \ | 1325 | #define MAC_IVEIV_ENTRY(__idx) \ |
1326 | ( MAC_IVEIV_TABLE_BASE + ((__idx) & sizeof(struct mac_iveiv_entry)) ) | 1326 | ( MAC_IVEIV_TABLE_BASE + ((__idx) * sizeof(struct mac_iveiv_entry)) ) |
1327 | #define MAC_WCID_ATTR_ENTRY(__idx) \ | 1327 | #define MAC_WCID_ATTR_ENTRY(__idx) \ |
1328 | ( MAC_WCID_ATTRIBUTE_BASE + ((__idx) * sizeof(u32)) ) | 1328 | ( MAC_WCID_ATTRIBUTE_BASE + ((__idx) * sizeof(u32)) ) |
1329 | #define SHARED_KEY_ENTRY(__idx) \ | 1329 | #define SHARED_KEY_ENTRY(__idx) \ |
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index eb1e1d00bec3..27bf887f1453 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c | |||
@@ -37,7 +37,7 @@ | |||
37 | #include <linux/module.h> | 37 | #include <linux/module.h> |
38 | 38 | ||
39 | #include "rt2x00.h" | 39 | #include "rt2x00.h" |
40 | #ifdef CONFIG_RT2800USB | 40 | #if defined(CONFIG_RT2800USB) || defined(CONFIG_RT2800USB_MODULE) |
41 | #include "rt2x00usb.h" | 41 | #include "rt2x00usb.h" |
42 | #endif | 42 | #endif |
43 | #include "rt2800lib.h" | 43 | #include "rt2800lib.h" |
@@ -1121,7 +1121,7 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) | |||
1121 | 1121 | ||
1122 | if (rt2x00_intf_is_usb(rt2x00dev)) { | 1122 | if (rt2x00_intf_is_usb(rt2x00dev)) { |
1123 | rt2800_register_write(rt2x00dev, USB_DMA_CFG, 0x00000000); | 1123 | rt2800_register_write(rt2x00dev, USB_DMA_CFG, 0x00000000); |
1124 | #ifdef CONFIG_RT2800USB | 1124 | #if defined(CONFIG_RT2800USB) || defined(CONFIG_RT2800USB_MODULE) |
1125 | rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0, | 1125 | rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0, |
1126 | USB_MODE_RESET, REGISTER_TIMEOUT); | 1126 | USB_MODE_RESET, REGISTER_TIMEOUT); |
1127 | #endif | 1127 | #endif |
@@ -2022,6 +2022,12 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2022 | u16 eeprom; | 2022 | u16 eeprom; |
2023 | 2023 | ||
2024 | /* | 2024 | /* |
2025 | * Disable powersaving as default on PCI devices. | ||
2026 | */ | ||
2027 | if (rt2x00_intf_is_pci(rt2x00dev)) | ||
2028 | rt2x00dev->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | ||
2029 | |||
2030 | /* | ||
2025 | * Initialize all hw fields. | 2031 | * Initialize all hw fields. |
2026 | */ | 2032 | */ |
2027 | rt2x00dev->hw->flags = | 2033 | rt2x00dev->hw->flags = |
@@ -2074,8 +2080,7 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2074 | IEEE80211_HT_CAP_SGI_20 | | 2080 | IEEE80211_HT_CAP_SGI_20 | |
2075 | IEEE80211_HT_CAP_SGI_40 | | 2081 | IEEE80211_HT_CAP_SGI_40 | |
2076 | IEEE80211_HT_CAP_TX_STBC | | 2082 | IEEE80211_HT_CAP_TX_STBC | |
2077 | IEEE80211_HT_CAP_RX_STBC | | 2083 | IEEE80211_HT_CAP_RX_STBC; |
2078 | IEEE80211_HT_CAP_PSMP_SUPPORT; | ||
2079 | spec->ht.ampdu_factor = 3; | 2084 | spec->ht.ampdu_factor = 3; |
2080 | spec->ht.ampdu_density = 4; | 2085 | spec->ht.ampdu_density = 4; |
2081 | spec->ht.mcs.tx_params = | 2086 | spec->ht.mcs.tx_params = |
@@ -2140,8 +2145,8 @@ static void rt2800_get_tkip_seq(struct ieee80211_hw *hw, u8 hw_key_idx, | |||
2140 | rt2800_register_multiread(rt2x00dev, offset, | 2145 | rt2800_register_multiread(rt2x00dev, offset, |
2141 | &iveiv_entry, sizeof(iveiv_entry)); | 2146 | &iveiv_entry, sizeof(iveiv_entry)); |
2142 | 2147 | ||
2143 | memcpy(&iveiv_entry.iv[0], iv16, sizeof(iv16)); | 2148 | memcpy(iv16, &iveiv_entry.iv[0], sizeof(*iv16)); |
2144 | memcpy(&iveiv_entry.iv[4], iv32, sizeof(iv32)); | 2149 | memcpy(iv32, &iveiv_entry.iv[4], sizeof(*iv32)); |
2145 | } | 2150 | } |
2146 | 2151 | ||
2147 | static int rt2800_set_rts_threshold(struct ieee80211_hw *hw, u32 value) | 2152 | static int rt2800_set_rts_threshold(struct ieee80211_hw *hw, u32 value) |
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index af85d18cdbe7..ab95346cf6a3 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c | |||
@@ -922,6 +922,7 @@ static struct usb_device_id rt2800usb_device_table[] = { | |||
922 | { USB_DEVICE(0x1737, 0x0070), USB_DEVICE_DATA(&rt2800usb_ops) }, | 922 | { USB_DEVICE(0x1737, 0x0070), USB_DEVICE_DATA(&rt2800usb_ops) }, |
923 | { USB_DEVICE(0x1737, 0x0071), USB_DEVICE_DATA(&rt2800usb_ops) }, | 923 | { USB_DEVICE(0x1737, 0x0071), USB_DEVICE_DATA(&rt2800usb_ops) }, |
924 | { USB_DEVICE(0x1737, 0x0077), USB_DEVICE_DATA(&rt2800usb_ops) }, | 924 | { USB_DEVICE(0x1737, 0x0077), USB_DEVICE_DATA(&rt2800usb_ops) }, |
925 | { USB_DEVICE(0x1737, 0x0079), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
925 | /* Logitec */ | 926 | /* Logitec */ |
926 | { USB_DEVICE(0x0789, 0x0162), USB_DEVICE_DATA(&rt2800usb_ops) }, | 927 | { USB_DEVICE(0x0789, 0x0162), USB_DEVICE_DATA(&rt2800usb_ops) }, |
927 | { USB_DEVICE(0x0789, 0x0163), USB_DEVICE_DATA(&rt2800usb_ops) }, | 928 | { USB_DEVICE(0x0789, 0x0163), USB_DEVICE_DATA(&rt2800usb_ops) }, |
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 687e17dc2e9f..0ca589306d71 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c | |||
@@ -2539,6 +2539,11 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2539 | unsigned int i; | 2539 | unsigned int i; |
2540 | 2540 | ||
2541 | /* | 2541 | /* |
2542 | * Disable powersaving as default. | ||
2543 | */ | ||
2544 | rt2x00dev->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | ||
2545 | |||
2546 | /* | ||
2542 | * Initialize all hw fields. | 2547 | * Initialize all hw fields. |
2543 | */ | 2548 | */ |
2544 | rt2x00dev->hw->flags = | 2549 | rt2x00dev->hw->flags = |
diff --git a/drivers/net/wireless/rtl818x/rtl8180_dev.c b/drivers/net/wireless/rtl818x/rtl8180_dev.c index a1a3dd15c664..8a40a1439984 100644 --- a/drivers/net/wireless/rtl818x/rtl8180_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8180_dev.c | |||
@@ -132,7 +132,6 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev) | |||
132 | 132 | ||
133 | rx_status.antenna = (flags2 >> 15) & 1; | 133 | rx_status.antenna = (flags2 >> 15) & 1; |
134 | /* TODO: improve signal/rssi reporting */ | 134 | /* TODO: improve signal/rssi reporting */ |
135 | rx_status.qual = flags2 & 0xFF; | ||
136 | rx_status.signal = (flags2 >> 8) & 0x7F; | 135 | rx_status.signal = (flags2 >> 8) & 0x7F; |
137 | /* XXX: is this correct? */ | 136 | /* XXX: is this correct? */ |
138 | rx_status.rate_idx = (flags >> 20) & 0xF; | 137 | rx_status.rate_idx = (flags >> 20) & 0xF; |
diff --git a/drivers/net/wireless/wl12xx/wl1251_boot.c b/drivers/net/wireless/wl12xx/wl1251_boot.c index 2e733e7bdfd4..28a808674080 100644 --- a/drivers/net/wireless/wl12xx/wl1251_boot.c +++ b/drivers/net/wireless/wl12xx/wl1251_boot.c | |||
@@ -256,7 +256,7 @@ int wl1251_boot_run_firmware(struct wl1251 *wl) | |||
256 | } | 256 | } |
257 | } | 257 | } |
258 | 258 | ||
259 | if (loop >= INIT_LOOP) { | 259 | if (loop > INIT_LOOP) { |
260 | wl1251_error("timeout waiting for the hardware to " | 260 | wl1251_error("timeout waiting for the hardware to " |
261 | "complete initialization"); | 261 | "complete initialization"); |
262 | return -EIO; | 262 | return -EIO; |
diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.c b/drivers/net/wireless/wl12xx/wl1271_cmd.c index 886a9bc39cc1..c3385b3d246c 100644 --- a/drivers/net/wireless/wl12xx/wl1271_cmd.c +++ b/drivers/net/wireless/wl12xx/wl1271_cmd.c | |||
@@ -777,7 +777,7 @@ out: | |||
777 | return ret; | 777 | return ret; |
778 | } | 778 | } |
779 | 779 | ||
780 | static int wl1271_build_basic_rates(char *rates, u8 band) | 780 | static int wl1271_build_basic_rates(u8 *rates, u8 band) |
781 | { | 781 | { |
782 | u8 index = 0; | 782 | u8 index = 0; |
783 | 783 | ||
@@ -804,7 +804,7 @@ static int wl1271_build_basic_rates(char *rates, u8 band) | |||
804 | return index; | 804 | return index; |
805 | } | 805 | } |
806 | 806 | ||
807 | static int wl1271_build_extended_rates(char *rates, u8 band) | 807 | static int wl1271_build_extended_rates(u8 *rates, u8 band) |
808 | { | 808 | { |
809 | u8 index = 0; | 809 | u8 index = 0; |
810 | 810 | ||
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c index dfa1b9bc22c8..7ca95c414fa8 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.c +++ b/drivers/net/wireless/zd1211rw/zd_chip.c | |||
@@ -1325,151 +1325,11 @@ int zd_chip_set_basic_rates(struct zd_chip *chip, u16 cr_rates) | |||
1325 | return r; | 1325 | return r; |
1326 | } | 1326 | } |
1327 | 1327 | ||
1328 | static int ofdm_qual_db(u8 status_quality, u8 zd_rate, unsigned int size) | ||
1329 | { | ||
1330 | static const u16 constants[] = { | ||
1331 | 715, 655, 585, 540, 470, 410, 360, 315, | ||
1332 | 270, 235, 205, 175, 150, 125, 105, 85, | ||
1333 | 65, 50, 40, 25, 15 | ||
1334 | }; | ||
1335 | |||
1336 | int i; | ||
1337 | u32 x; | ||
1338 | |||
1339 | /* It seems that their quality parameter is somehow per signal | ||
1340 | * and is now transferred per bit. | ||
1341 | */ | ||
1342 | switch (zd_rate) { | ||
1343 | case ZD_OFDM_RATE_6M: | ||
1344 | case ZD_OFDM_RATE_12M: | ||
1345 | case ZD_OFDM_RATE_24M: | ||
1346 | size *= 2; | ||
1347 | break; | ||
1348 | case ZD_OFDM_RATE_9M: | ||
1349 | case ZD_OFDM_RATE_18M: | ||
1350 | case ZD_OFDM_RATE_36M: | ||
1351 | case ZD_OFDM_RATE_54M: | ||
1352 | size *= 4; | ||
1353 | size /= 3; | ||
1354 | break; | ||
1355 | case ZD_OFDM_RATE_48M: | ||
1356 | size *= 3; | ||
1357 | size /= 2; | ||
1358 | break; | ||
1359 | default: | ||
1360 | return -EINVAL; | ||
1361 | } | ||
1362 | |||
1363 | x = (10000 * status_quality)/size; | ||
1364 | for (i = 0; i < ARRAY_SIZE(constants); i++) { | ||
1365 | if (x > constants[i]) | ||
1366 | break; | ||
1367 | } | ||
1368 | |||
1369 | switch (zd_rate) { | ||
1370 | case ZD_OFDM_RATE_6M: | ||
1371 | case ZD_OFDM_RATE_9M: | ||
1372 | i += 3; | ||
1373 | break; | ||
1374 | case ZD_OFDM_RATE_12M: | ||
1375 | case ZD_OFDM_RATE_18M: | ||
1376 | i += 5; | ||
1377 | break; | ||
1378 | case ZD_OFDM_RATE_24M: | ||
1379 | case ZD_OFDM_RATE_36M: | ||
1380 | i += 9; | ||
1381 | break; | ||
1382 | case ZD_OFDM_RATE_48M: | ||
1383 | case ZD_OFDM_RATE_54M: | ||
1384 | i += 15; | ||
1385 | break; | ||
1386 | default: | ||
1387 | return -EINVAL; | ||
1388 | } | ||
1389 | |||
1390 | return i; | ||
1391 | } | ||
1392 | |||
1393 | static int ofdm_qual_percent(u8 status_quality, u8 zd_rate, unsigned int size) | ||
1394 | { | ||
1395 | int r; | ||
1396 | |||
1397 | r = ofdm_qual_db(status_quality, zd_rate, size); | ||
1398 | ZD_ASSERT(r >= 0); | ||
1399 | if (r < 0) | ||
1400 | r = 0; | ||
1401 | |||
1402 | r = (r * 100)/29; | ||
1403 | return r <= 100 ? r : 100; | ||
1404 | } | ||
1405 | |||
1406 | static unsigned int log10times100(unsigned int x) | ||
1407 | { | ||
1408 | static const u8 log10[] = { | ||
1409 | 0, | ||
1410 | 0, 30, 47, 60, 69, 77, 84, 90, 95, 100, | ||
1411 | 104, 107, 111, 114, 117, 120, 123, 125, 127, 130, | ||
1412 | 132, 134, 136, 138, 139, 141, 143, 144, 146, 147, | ||
1413 | 149, 150, 151, 153, 154, 155, 156, 157, 159, 160, | ||
1414 | 161, 162, 163, 164, 165, 166, 167, 168, 169, 169, | ||
1415 | 170, 171, 172, 173, 174, 174, 175, 176, 177, 177, | ||
1416 | 178, 179, 179, 180, 181, 181, 182, 183, 183, 184, | ||
1417 | 185, 185, 186, 186, 187, 188, 188, 189, 189, 190, | ||
1418 | 190, 191, 191, 192, 192, 193, 193, 194, 194, 195, | ||
1419 | 195, 196, 196, 197, 197, 198, 198, 199, 199, 200, | ||
1420 | 200, 200, 201, 201, 202, 202, 202, 203, 203, 204, | ||
1421 | 204, 204, 205, 205, 206, 206, 206, 207, 207, 207, | ||
1422 | 208, 208, 208, 209, 209, 210, 210, 210, 211, 211, | ||
1423 | 211, 212, 212, 212, 213, 213, 213, 213, 214, 214, | ||
1424 | 214, 215, 215, 215, 216, 216, 216, 217, 217, 217, | ||
1425 | 217, 218, 218, 218, 219, 219, 219, 219, 220, 220, | ||
1426 | 220, 220, 221, 221, 221, 222, 222, 222, 222, 223, | ||
1427 | 223, 223, 223, 224, 224, 224, 224, | ||
1428 | }; | ||
1429 | |||
1430 | return x < ARRAY_SIZE(log10) ? log10[x] : 225; | ||
1431 | } | ||
1432 | |||
1433 | enum { | ||
1434 | MAX_CCK_EVM_DB = 45, | ||
1435 | }; | ||
1436 | |||
1437 | static int cck_evm_db(u8 status_quality) | ||
1438 | { | ||
1439 | return (20 * log10times100(status_quality)) / 100; | ||
1440 | } | ||
1441 | |||
1442 | static int cck_snr_db(u8 status_quality) | ||
1443 | { | ||
1444 | int r = MAX_CCK_EVM_DB - cck_evm_db(status_quality); | ||
1445 | ZD_ASSERT(r >= 0); | ||
1446 | return r; | ||
1447 | } | ||
1448 | |||
1449 | static int cck_qual_percent(u8 status_quality) | ||
1450 | { | ||
1451 | int r; | ||
1452 | |||
1453 | r = cck_snr_db(status_quality); | ||
1454 | r = (100*r)/17; | ||
1455 | return r <= 100 ? r : 100; | ||
1456 | } | ||
1457 | |||
1458 | static inline u8 zd_rate_from_ofdm_plcp_header(const void *rx_frame) | 1328 | static inline u8 zd_rate_from_ofdm_plcp_header(const void *rx_frame) |
1459 | { | 1329 | { |
1460 | return ZD_OFDM | zd_ofdm_plcp_header_rate(rx_frame); | 1330 | return ZD_OFDM | zd_ofdm_plcp_header_rate(rx_frame); |
1461 | } | 1331 | } |
1462 | 1332 | ||
1463 | u8 zd_rx_qual_percent(const void *rx_frame, unsigned int size, | ||
1464 | const struct rx_status *status) | ||
1465 | { | ||
1466 | return (status->frame_status&ZD_RX_OFDM) ? | ||
1467 | ofdm_qual_percent(status->signal_quality_ofdm, | ||
1468 | zd_rate_from_ofdm_plcp_header(rx_frame), | ||
1469 | size) : | ||
1470 | cck_qual_percent(status->signal_quality_cck); | ||
1471 | } | ||
1472 | |||
1473 | /** | 1333 | /** |
1474 | * zd_rx_rate - report zd-rate | 1334 | * zd_rx_rate - report zd-rate |
1475 | * @rx_frame - received frame | 1335 | * @rx_frame - received frame |
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.h b/drivers/net/wireless/zd1211rw/zd_chip.h index 9fd8f3508d66..f8bbf7d302ae 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.h +++ b/drivers/net/wireless/zd1211rw/zd_chip.h | |||
@@ -929,9 +929,6 @@ static inline int zd_get_beacon_interval(struct zd_chip *chip, u32 *interval) | |||
929 | 929 | ||
930 | struct rx_status; | 930 | struct rx_status; |
931 | 931 | ||
932 | u8 zd_rx_qual_percent(const void *rx_frame, unsigned int size, | ||
933 | const struct rx_status *status); | ||
934 | |||
935 | u8 zd_rx_rate(const void *rx_frame, const struct rx_status *status); | 932 | u8 zd_rx_rate(const void *rx_frame, const struct rx_status *status); |
936 | 933 | ||
937 | struct zd_mc_hash { | 934 | struct zd_mc_hash { |
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index cf51e8f8174b..8ebf5c33955d 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c | |||
@@ -828,9 +828,6 @@ int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length) | |||
828 | stats.freq = zd_channels[_zd_chip_get_channel(&mac->chip) - 1].center_freq; | 828 | stats.freq = zd_channels[_zd_chip_get_channel(&mac->chip) - 1].center_freq; |
829 | stats.band = IEEE80211_BAND_2GHZ; | 829 | stats.band = IEEE80211_BAND_2GHZ; |
830 | stats.signal = status->signal_strength; | 830 | stats.signal = status->signal_strength; |
831 | stats.qual = zd_rx_qual_percent(buffer, | ||
832 | length - sizeof(struct rx_status), | ||
833 | status); | ||
834 | 831 | ||
835 | rate = zd_rx_rate(buffer, status); | 832 | rate = zd_rx_rate(buffer, status); |
836 | 833 | ||
diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h index bd588eb8e922..8e210cd76e55 100644 --- a/drivers/pci/hotplug/shpchp.h +++ b/drivers/pci/hotplug/shpchp.h | |||
@@ -121,7 +121,7 @@ struct controller { | |||
121 | #define PCI_DEVICE_ID_AMD_GOLAM_7450 0x7450 | 121 | #define PCI_DEVICE_ID_AMD_GOLAM_7450 0x7450 |
122 | #define PCI_DEVICE_ID_AMD_POGO_7458 0x7458 | 122 | #define PCI_DEVICE_ID_AMD_POGO_7458 0x7458 |
123 | 123 | ||
124 | /* AMD PCIX bridge registers */ | 124 | /* AMD PCI-X bridge registers */ |
125 | #define PCIX_MEM_BASE_LIMIT_OFFSET 0x1C | 125 | #define PCIX_MEM_BASE_LIMIT_OFFSET 0x1C |
126 | #define PCIX_MISCII_OFFSET 0x48 | 126 | #define PCIX_MISCII_OFFSET 0x48 |
127 | #define PCIX_MISC_BRIDGE_ERRORS_OFFSET 0x80 | 127 | #define PCIX_MISC_BRIDGE_ERRORS_OFFSET 0x80 |
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index e56f9bed6f2b..417312528ddf 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c | |||
@@ -305,7 +305,7 @@ struct device_domain_info { | |||
305 | int segment; /* PCI domain */ | 305 | int segment; /* PCI domain */ |
306 | u8 bus; /* PCI bus number */ | 306 | u8 bus; /* PCI bus number */ |
307 | u8 devfn; /* PCI devfn number */ | 307 | u8 devfn; /* PCI devfn number */ |
308 | struct pci_dev *dev; /* it's NULL for PCIE-to-PCI bridge */ | 308 | struct pci_dev *dev; /* it's NULL for PCIe-to-PCI bridge */ |
309 | struct intel_iommu *iommu; /* IOMMU used by this device */ | 309 | struct intel_iommu *iommu; /* IOMMU used by this device */ |
310 | struct dmar_domain *domain; /* pointer to domain */ | 310 | struct dmar_domain *domain; /* pointer to domain */ |
311 | }; | 311 | }; |
@@ -1604,7 +1604,7 @@ domain_context_mapping(struct dmar_domain *domain, struct pci_dev *pdev, | |||
1604 | return ret; | 1604 | return ret; |
1605 | parent = parent->bus->self; | 1605 | parent = parent->bus->self; |
1606 | } | 1606 | } |
1607 | if (pci_is_pcie(tmp)) /* this is a PCIE-to-PCI bridge */ | 1607 | if (pci_is_pcie(tmp)) /* this is a PCIe-to-PCI bridge */ |
1608 | return domain_context_mapping_one(domain, | 1608 | return domain_context_mapping_one(domain, |
1609 | pci_domain_nr(tmp->subordinate), | 1609 | pci_domain_nr(tmp->subordinate), |
1610 | tmp->subordinate->number, 0, | 1610 | tmp->subordinate->number, 0, |
@@ -3325,7 +3325,7 @@ static void iommu_detach_dependent_devices(struct intel_iommu *iommu, | |||
3325 | parent->devfn); | 3325 | parent->devfn); |
3326 | parent = parent->bus->self; | 3326 | parent = parent->bus->self; |
3327 | } | 3327 | } |
3328 | if (pci_is_pcie(tmp)) /* this is a PCIE-to-PCI bridge */ | 3328 | if (pci_is_pcie(tmp)) /* this is a PCIe-to-PCI bridge */ |
3329 | iommu_detach_dev(iommu, | 3329 | iommu_detach_dev(iommu, |
3330 | tmp->subordinate->number, 0); | 3330 | tmp->subordinate->number, 0); |
3331 | else /* this is a legacy PCI bridge */ | 3331 | else /* this is a legacy PCI bridge */ |
diff --git a/drivers/pci/intr_remapping.c b/drivers/pci/intr_remapping.c index 8b65a489581b..95b849130ad4 100644 --- a/drivers/pci/intr_remapping.c +++ b/drivers/pci/intr_remapping.c | |||
@@ -528,7 +528,7 @@ int set_msi_sid(struct irte *irte, struct pci_dev *dev) | |||
528 | 528 | ||
529 | bridge = pci_find_upstream_pcie_bridge(dev); | 529 | bridge = pci_find_upstream_pcie_bridge(dev); |
530 | if (bridge) { | 530 | if (bridge) { |
531 | if (pci_is_pcie(bridge))/* this is a PCIE-to-PCI/PCIX bridge */ | 531 | if (pci_is_pcie(bridge))/* this is a PCIe-to-PCI/PCIX bridge */ |
532 | set_irte_sid(irte, SVT_VERIFY_BUS, SQ_ALL_16, | 532 | set_irte_sid(irte, SVT_VERIFY_BUS, SQ_ALL_16, |
533 | (bridge->bus->number << 8) | dev->bus->number); | 533 | (bridge->bus->number << 8) | dev->bus->number); |
534 | else /* this is a legacy PCI bridge */ | 534 | else /* this is a legacy PCI bridge */ |
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index cc617ddd33d0..7e2829538a4c 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c | |||
@@ -112,11 +112,7 @@ static bool acpi_pci_can_wakeup(struct pci_dev *dev) | |||
112 | static void acpi_pci_propagate_wakeup_enable(struct pci_bus *bus, bool enable) | 112 | static void acpi_pci_propagate_wakeup_enable(struct pci_bus *bus, bool enable) |
113 | { | 113 | { |
114 | while (bus->parent) { | 114 | while (bus->parent) { |
115 | struct pci_dev *bridge = bus->self; | 115 | if (!acpi_pm_device_sleep_wake(&bus->self->dev, enable)) |
116 | int ret; | ||
117 | |||
118 | ret = acpi_pm_device_sleep_wake(&bridge->dev, enable); | ||
119 | if (!ret || pci_is_pcie(bridge)) | ||
120 | return; | 116 | return; |
121 | bus = bus->parent; | 117 | bus = bus->parent; |
122 | } | 118 | } |
@@ -131,9 +127,7 @@ static int acpi_pci_sleep_wake(struct pci_dev *dev, bool enable) | |||
131 | if (acpi_pci_can_wakeup(dev)) | 127 | if (acpi_pci_can_wakeup(dev)) |
132 | return acpi_pm_device_sleep_wake(&dev->dev, enable); | 128 | return acpi_pm_device_sleep_wake(&dev->dev, enable); |
133 | 129 | ||
134 | if (!pci_is_pcie(dev)) | 130 | acpi_pci_propagate_wakeup_enable(dev->bus, enable); |
135 | acpi_pci_propagate_wakeup_enable(dev->bus, enable); | ||
136 | |||
137 | return 0; | 131 | return 0; |
138 | } | 132 | } |
139 | 133 | ||
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 0bc27e059019..864e703cf737 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -1153,11 +1153,11 @@ pci_disable_device(struct pci_dev *dev) | |||
1153 | 1153 | ||
1154 | /** | 1154 | /** |
1155 | * pcibios_set_pcie_reset_state - set reset state for device dev | 1155 | * pcibios_set_pcie_reset_state - set reset state for device dev |
1156 | * @dev: the PCI-E device reset | 1156 | * @dev: the PCIe device reset |
1157 | * @state: Reset state to enter into | 1157 | * @state: Reset state to enter into |
1158 | * | 1158 | * |
1159 | * | 1159 | * |
1160 | * Sets the PCI-E reset state for the device. This is the default | 1160 | * Sets the PCIe reset state for the device. This is the default |
1161 | * implementation. Architecture implementations can override this. | 1161 | * implementation. Architecture implementations can override this. |
1162 | */ | 1162 | */ |
1163 | int __attribute__ ((weak)) pcibios_set_pcie_reset_state(struct pci_dev *dev, | 1163 | int __attribute__ ((weak)) pcibios_set_pcie_reset_state(struct pci_dev *dev, |
@@ -1168,7 +1168,7 @@ int __attribute__ ((weak)) pcibios_set_pcie_reset_state(struct pci_dev *dev, | |||
1168 | 1168 | ||
1169 | /** | 1169 | /** |
1170 | * pci_set_pcie_reset_state - set reset state for device dev | 1170 | * pci_set_pcie_reset_state - set reset state for device dev |
1171 | * @dev: the PCI-E device reset | 1171 | * @dev: the PCIe device reset |
1172 | * @state: Reset state to enter into | 1172 | * @state: Reset state to enter into |
1173 | * | 1173 | * |
1174 | * | 1174 | * |
@@ -2284,6 +2284,21 @@ static int pci_parent_bus_reset(struct pci_dev *dev, int probe) | |||
2284 | return 0; | 2284 | return 0; |
2285 | } | 2285 | } |
2286 | 2286 | ||
2287 | static int pci_dev_specific_reset(struct pci_dev *dev, int probe) | ||
2288 | { | ||
2289 | struct pci_dev_reset_methods *i; | ||
2290 | |||
2291 | for (i = pci_dev_reset_methods; i->reset; i++) { | ||
2292 | if ((i->vendor == dev->vendor || | ||
2293 | i->vendor == (u16)PCI_ANY_ID) && | ||
2294 | (i->device == dev->device || | ||
2295 | i->device == (u16)PCI_ANY_ID)) | ||
2296 | return i->reset(dev, probe); | ||
2297 | } | ||
2298 | |||
2299 | return -ENOTTY; | ||
2300 | } | ||
2301 | |||
2287 | static int pci_dev_reset(struct pci_dev *dev, int probe) | 2302 | static int pci_dev_reset(struct pci_dev *dev, int probe) |
2288 | { | 2303 | { |
2289 | int rc; | 2304 | int rc; |
@@ -2296,6 +2311,10 @@ static int pci_dev_reset(struct pci_dev *dev, int probe) | |||
2296 | down(&dev->dev.sem); | 2311 | down(&dev->dev.sem); |
2297 | } | 2312 | } |
2298 | 2313 | ||
2314 | rc = pci_dev_specific_reset(dev, probe); | ||
2315 | if (rc != -ENOTTY) | ||
2316 | goto done; | ||
2317 | |||
2299 | rc = pcie_flr(dev, probe); | 2318 | rc = pcie_flr(dev, probe); |
2300 | if (rc != -ENOTTY) | 2319 | if (rc != -ENOTTY) |
2301 | goto done; | 2320 | goto done; |
@@ -2779,6 +2798,11 @@ int __attribute__ ((weak)) pci_ext_cfg_avail(struct pci_dev *dev) | |||
2779 | return 1; | 2798 | return 1; |
2780 | } | 2799 | } |
2781 | 2800 | ||
2801 | void __weak pci_fixup_cardbus(struct pci_bus *bus) | ||
2802 | { | ||
2803 | } | ||
2804 | EXPORT_SYMBOL(pci_fixup_cardbus); | ||
2805 | |||
2782 | static int __init pci_setup(char *str) | 2806 | static int __init pci_setup(char *str) |
2783 | { | 2807 | { |
2784 | while (str) { | 2808 | while (str) { |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 33ed8e0aba1e..709eaa4fee51 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -313,4 +313,12 @@ static inline int pci_resource_alignment(struct pci_dev *dev, | |||
313 | 313 | ||
314 | extern void pci_enable_acs(struct pci_dev *dev); | 314 | extern void pci_enable_acs(struct pci_dev *dev); |
315 | 315 | ||
316 | struct pci_dev_reset_methods { | ||
317 | u16 vendor; | ||
318 | u16 device; | ||
319 | int (*reset)(struct pci_dev *dev, int probe); | ||
320 | }; | ||
321 | |||
322 | extern struct pci_dev_reset_methods pci_dev_reset_methods[]; | ||
323 | |||
316 | #endif /* DRIVERS_PCI_H */ | 324 | #endif /* DRIVERS_PCI_H */ |
diff --git a/drivers/pci/pcie/aer/Kconfig.debug b/drivers/pci/pcie/aer/Kconfig.debug index b8c925c1f6aa..9142949734f5 100644 --- a/drivers/pci/pcie/aer/Kconfig.debug +++ b/drivers/pci/pcie/aer/Kconfig.debug | |||
@@ -3,14 +3,14 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | config PCIEAER_INJECT | 5 | config PCIEAER_INJECT |
6 | tristate "PCIE AER error injector support" | 6 | tristate "PCIe AER error injector support" |
7 | depends on PCIEAER | 7 | depends on PCIEAER |
8 | default n | 8 | default n |
9 | help | 9 | help |
10 | This enables PCI Express Root Port Advanced Error Reporting | 10 | This enables PCI Express Root Port Advanced Error Reporting |
11 | (AER) software error injector. | 11 | (AER) software error injector. |
12 | 12 | ||
13 | Debuging PCIE AER code is quite difficult because it is hard | 13 | Debugging PCIe AER code is quite difficult because it is hard |
14 | to trigger various real hardware errors. Software based | 14 | to trigger various real hardware errors. Software based |
15 | error injection can fake almost all kinds of errors with the | 15 | error injection can fake almost all kinds of errors with the |
16 | help of a user space helper tool aer-inject, which can be | 16 | help of a user space helper tool aer-inject, which can be |
diff --git a/drivers/pci/pcie/aer/aer_inject.c b/drivers/pci/pcie/aer/aer_inject.c index 7fcd5331b14c..797d47809f7a 100644 --- a/drivers/pci/pcie/aer/aer_inject.c +++ b/drivers/pci/pcie/aer/aer_inject.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * PCIE AER software error injection support. | 2 | * PCIe AER software error injection support. |
3 | * | 3 | * |
4 | * Debuging PCIE AER code is quite difficult because it is hard to | 4 | * Debuging PCIe AER code is quite difficult because it is hard to |
5 | * trigger various real hardware errors. Software based error | 5 | * trigger various real hardware errors. Software based error |
6 | * injection can fake almost all kinds of errors with the help of a | 6 | * injection can fake almost all kinds of errors with the help of a |
7 | * user space helper tool aer-inject, which can be gotten from: | 7 | * user space helper tool aer-inject, which can be gotten from: |
@@ -484,5 +484,5 @@ static void __exit aer_inject_exit(void) | |||
484 | module_init(aer_inject_init); | 484 | module_init(aer_inject_init); |
485 | module_exit(aer_inject_exit); | 485 | module_exit(aer_inject_exit); |
486 | 486 | ||
487 | MODULE_DESCRIPTION("PCIE AER software error injector"); | 487 | MODULE_DESCRIPTION("PCIe AER software error injector"); |
488 | MODULE_LICENSE("GPL"); | 488 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c index 97a345927b55..21f215f4daa3 100644 --- a/drivers/pci/pcie/aer/aerdrv.c +++ b/drivers/pci/pcie/aer/aerdrv.c | |||
@@ -155,7 +155,7 @@ static struct aer_rpc *aer_alloc_rpc(struct pcie_device *dev) | |||
155 | mutex_init(&rpc->rpc_mutex); | 155 | mutex_init(&rpc->rpc_mutex); |
156 | init_waitqueue_head(&rpc->wait_release); | 156 | init_waitqueue_head(&rpc->wait_release); |
157 | 157 | ||
158 | /* Use PCIE bus function to store rpc into PCIE device */ | 158 | /* Use PCIe bus function to store rpc into PCIe device */ |
159 | set_service_data(dev, rpc); | 159 | set_service_data(dev, rpc); |
160 | 160 | ||
161 | return rpc; | 161 | return rpc; |
diff --git a/drivers/pci/pcie/aer/aerdrv_acpi.c b/drivers/pci/pcie/aer/aerdrv_acpi.c index 8edb2f300e8f..04814087658d 100644 --- a/drivers/pci/pcie/aer/aerdrv_acpi.c +++ b/drivers/pci/pcie/aer/aerdrv_acpi.c | |||
@@ -24,7 +24,7 @@ | |||
24 | * | 24 | * |
25 | * @return: Zero on success. Nonzero otherwise. | 25 | * @return: Zero on success. Nonzero otherwise. |
26 | * | 26 | * |
27 | * Invoked when PCIE bus loads AER service driver. To avoid conflict with | 27 | * Invoked when PCIe bus loads AER service driver. To avoid conflict with |
28 | * BIOS AER support requires BIOS to yield AER control to OS native driver. | 28 | * BIOS AER support requires BIOS to yield AER control to OS native driver. |
29 | **/ | 29 | **/ |
30 | int aer_osc_setup(struct pcie_device *pciedev) | 30 | int aer_osc_setup(struct pcie_device *pciedev) |
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c index ae672ca80333..c843a799814d 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c | |||
@@ -587,7 +587,7 @@ static void handle_error_source(struct pcie_device *aerdev, | |||
587 | * aer_enable_rootport - enable Root Port's interrupts when receiving messages | 587 | * aer_enable_rootport - enable Root Port's interrupts when receiving messages |
588 | * @rpc: pointer to a Root Port data structure | 588 | * @rpc: pointer to a Root Port data structure |
589 | * | 589 | * |
590 | * Invoked when PCIE bus loads AER service driver. | 590 | * Invoked when PCIe bus loads AER service driver. |
591 | */ | 591 | */ |
592 | void aer_enable_rootport(struct aer_rpc *rpc) | 592 | void aer_enable_rootport(struct aer_rpc *rpc) |
593 | { | 593 | { |
@@ -597,7 +597,7 @@ void aer_enable_rootport(struct aer_rpc *rpc) | |||
597 | u32 reg32; | 597 | u32 reg32; |
598 | 598 | ||
599 | pos = pci_pcie_cap(pdev); | 599 | pos = pci_pcie_cap(pdev); |
600 | /* Clear PCIE Capability's Device Status */ | 600 | /* Clear PCIe Capability's Device Status */ |
601 | pci_read_config_word(pdev, pos+PCI_EXP_DEVSTA, ®16); | 601 | pci_read_config_word(pdev, pos+PCI_EXP_DEVSTA, ®16); |
602 | pci_write_config_word(pdev, pos+PCI_EXP_DEVSTA, reg16); | 602 | pci_write_config_word(pdev, pos+PCI_EXP_DEVSTA, reg16); |
603 | 603 | ||
@@ -631,7 +631,7 @@ void aer_enable_rootport(struct aer_rpc *rpc) | |||
631 | * disable_root_aer - disable Root Port's interrupts when receiving messages | 631 | * disable_root_aer - disable Root Port's interrupts when receiving messages |
632 | * @rpc: pointer to a Root Port data structure | 632 | * @rpc: pointer to a Root Port data structure |
633 | * | 633 | * |
634 | * Invoked when PCIE bus unloads AER service driver. | 634 | * Invoked when PCIe bus unloads AER service driver. |
635 | */ | 635 | */ |
636 | static void disable_root_aer(struct aer_rpc *rpc) | 636 | static void disable_root_aer(struct aer_rpc *rpc) |
637 | { | 637 | { |
diff --git a/drivers/pci/pcie/aer/aerdrv_errprint.c b/drivers/pci/pcie/aer/aerdrv_errprint.c index 44acde72294f..9d3e4c8d0184 100644 --- a/drivers/pci/pcie/aer/aerdrv_errprint.c +++ b/drivers/pci/pcie/aer/aerdrv_errprint.c | |||
@@ -184,7 +184,7 @@ void aer_print_error(struct pci_dev *dev, struct aer_err_info *info) | |||
184 | 184 | ||
185 | if (info->status == 0) { | 185 | if (info->status == 0) { |
186 | AER_PR(info, dev, | 186 | AER_PR(info, dev, |
187 | "PCIE Bus Error: severity=%s, type=Unaccessible, " | 187 | "PCIe Bus Error: severity=%s, type=Unaccessible, " |
188 | "id=%04x(Unregistered Agent ID)\n", | 188 | "id=%04x(Unregistered Agent ID)\n", |
189 | aer_error_severity_string[info->severity], id); | 189 | aer_error_severity_string[info->severity], id); |
190 | } else { | 190 | } else { |
@@ -194,7 +194,7 @@ void aer_print_error(struct pci_dev *dev, struct aer_err_info *info) | |||
194 | agent = AER_GET_AGENT(info->severity, info->status); | 194 | agent = AER_GET_AGENT(info->severity, info->status); |
195 | 195 | ||
196 | AER_PR(info, dev, | 196 | AER_PR(info, dev, |
197 | "PCIE Bus Error: severity=%s, type=%s, id=%04x(%s)\n", | 197 | "PCIe Bus Error: severity=%s, type=%s, id=%04x(%s)\n", |
198 | aer_error_severity_string[info->severity], | 198 | aer_error_severity_string[info->severity], |
199 | aer_error_layer[layer], id, aer_agent_string[agent]); | 199 | aer_error_layer[layer], id, aer_agent_string[agent]); |
200 | 200 | ||
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index 5a01fc7fbf05..be53d98fa384 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * File: drivers/pci/pcie/aspm.c | 2 | * File: drivers/pci/pcie/aspm.c |
3 | * Enabling PCIE link L0s/L1 state and Clock Power Management | 3 | * Enabling PCIe link L0s/L1 state and Clock Power Management |
4 | * | 4 | * |
5 | * Copyright (C) 2007 Intel | 5 | * Copyright (C) 2007 Intel |
6 | * Copyright (C) Zhang Yanmin (yanmin.zhang@intel.com) | 6 | * Copyright (C) Zhang Yanmin (yanmin.zhang@intel.com) |
@@ -499,7 +499,7 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev) | |||
499 | int pos; | 499 | int pos; |
500 | u32 reg32; | 500 | u32 reg32; |
501 | /* | 501 | /* |
502 | * Some functions in a slot might not all be PCIE functions, | 502 | * Some functions in a slot might not all be PCIe functions, |
503 | * very strange. Disable ASPM for the whole slot | 503 | * very strange. Disable ASPM for the whole slot |
504 | */ | 504 | */ |
505 | list_for_each_entry(child, &pdev->subordinate->devices, bus_list) { | 505 | list_for_each_entry(child, &pdev->subordinate->devices, bus_list) { |
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index a49452e2aed9..34d65172a4d7 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c | |||
@@ -24,7 +24,7 @@ | |||
24 | */ | 24 | */ |
25 | #define DRIVER_VERSION "v1.0" | 25 | #define DRIVER_VERSION "v1.0" |
26 | #define DRIVER_AUTHOR "tom.l.nguyen@intel.com" | 26 | #define DRIVER_AUTHOR "tom.l.nguyen@intel.com" |
27 | #define DRIVER_DESC "PCIE Port Bus Driver" | 27 | #define DRIVER_DESC "PCIe Port Bus Driver" |
28 | MODULE_AUTHOR(DRIVER_AUTHOR); | 28 | MODULE_AUTHOR(DRIVER_AUTHOR); |
29 | MODULE_DESCRIPTION(DRIVER_DESC); | 29 | MODULE_DESCRIPTION(DRIVER_DESC); |
30 | MODULE_LICENSE("GPL"); | 30 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 7cfa7c38d318..8726698866b1 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -2629,13 +2629,68 @@ static int __init pci_apply_final_quirks(void) | |||
2629 | if (!pci_cache_line_size) { | 2629 | if (!pci_cache_line_size) { |
2630 | printk(KERN_DEBUG "PCI: CLS %u bytes, default %u\n", | 2630 | printk(KERN_DEBUG "PCI: CLS %u bytes, default %u\n", |
2631 | cls << 2, pci_dfl_cache_line_size << 2); | 2631 | cls << 2, pci_dfl_cache_line_size << 2); |
2632 | pci_cache_line_size = cls; | 2632 | pci_cache_line_size = cls ? cls : pci_dfl_cache_line_size; |
2633 | } | 2633 | } |
2634 | 2634 | ||
2635 | return 0; | 2635 | return 0; |
2636 | } | 2636 | } |
2637 | 2637 | ||
2638 | fs_initcall_sync(pci_apply_final_quirks); | 2638 | fs_initcall_sync(pci_apply_final_quirks); |
2639 | |||
2640 | /* | ||
2641 | * Followings are device-specific reset methods which can be used to | ||
2642 | * reset a single function if other methods (e.g. FLR, PM D0->D3) are | ||
2643 | * not available. | ||
2644 | */ | ||
2645 | static int reset_intel_generic_dev(struct pci_dev *dev, int probe) | ||
2646 | { | ||
2647 | int pos; | ||
2648 | |||
2649 | /* only implement PCI_CLASS_SERIAL_USB at present */ | ||
2650 | if (dev->class == PCI_CLASS_SERIAL_USB) { | ||
2651 | pos = pci_find_capability(dev, PCI_CAP_ID_VNDR); | ||
2652 | if (!pos) | ||
2653 | return -ENOTTY; | ||
2654 | |||
2655 | if (probe) | ||
2656 | return 0; | ||
2657 | |||
2658 | pci_write_config_byte(dev, pos + 0x4, 1); | ||
2659 | msleep(100); | ||
2660 | |||
2661 | return 0; | ||
2662 | } else { | ||
2663 | return -ENOTTY; | ||
2664 | } | ||
2665 | } | ||
2666 | |||
2667 | static int reset_intel_82599_sfp_virtfn(struct pci_dev *dev, int probe) | ||
2668 | { | ||
2669 | int pos; | ||
2670 | |||
2671 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); | ||
2672 | if (!pos) | ||
2673 | return -ENOTTY; | ||
2674 | |||
2675 | if (probe) | ||
2676 | return 0; | ||
2677 | |||
2678 | pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, | ||
2679 | PCI_EXP_DEVCTL_BCR_FLR); | ||
2680 | msleep(100); | ||
2681 | |||
2682 | return 0; | ||
2683 | } | ||
2684 | |||
2685 | #define PCI_DEVICE_ID_INTEL_82599_SFP_VF 0x10ed | ||
2686 | |||
2687 | struct pci_dev_reset_methods pci_dev_reset_methods[] = { | ||
2688 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82599_SFP_VF, | ||
2689 | reset_intel_82599_sfp_virtfn }, | ||
2690 | { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, | ||
2691 | reset_intel_generic_dev }, | ||
2692 | { 0 } | ||
2693 | }; | ||
2639 | #else | 2694 | #else |
2640 | void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev) {} | 2695 | void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev) {} |
2641 | #endif | 2696 | #endif |
diff --git a/drivers/pci/search.c b/drivers/pci/search.c index 6dae87143258..4a471dc4f4b9 100644 --- a/drivers/pci/search.c +++ b/drivers/pci/search.c | |||
@@ -15,9 +15,9 @@ | |||
15 | 15 | ||
16 | DECLARE_RWSEM(pci_bus_sem); | 16 | DECLARE_RWSEM(pci_bus_sem); |
17 | /* | 17 | /* |
18 | * find the upstream PCIE-to-PCI bridge of a PCI device | 18 | * find the upstream PCIe-to-PCI bridge of a PCI device |
19 | * if the device is PCIE, return NULL | 19 | * if the device is PCIE, return NULL |
20 | * if the device isn't connected to a PCIE bridge (that is its parent is a | 20 | * if the device isn't connected to a PCIe bridge (that is its parent is a |
21 | * legacy PCI bridge and the bridge is directly connected to bus 0), return its | 21 | * legacy PCI bridge and the bridge is directly connected to bus 0), return its |
22 | * parent | 22 | * parent |
23 | */ | 23 | */ |
@@ -37,7 +37,7 @@ pci_find_upstream_pcie_bridge(struct pci_dev *pdev) | |||
37 | tmp = pdev; | 37 | tmp = pdev; |
38 | continue; | 38 | continue; |
39 | } | 39 | } |
40 | /* PCI device should connect to a PCIE bridge */ | 40 | /* PCI device should connect to a PCIe bridge */ |
41 | if (pdev->pcie_type != PCI_EXP_TYPE_PCI_BRIDGE) { | 41 | if (pdev->pcie_type != PCI_EXP_TYPE_PCI_BRIDGE) { |
42 | /* Busted hardware? */ | 42 | /* Busted hardware? */ |
43 | WARN_ON_ONCE(1); | 43 | WARN_ON_ONCE(1); |
diff --git a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c index cdf50f3bc2df..d99f846451a3 100644 --- a/drivers/pcmcia/cardbus.c +++ b/drivers/pcmcia/cardbus.c | |||
@@ -222,7 +222,7 @@ int __ref cb_alloc(struct pcmcia_socket *s) | |||
222 | unsigned int max, pass; | 222 | unsigned int max, pass; |
223 | 223 | ||
224 | s->functions = pci_scan_slot(bus, PCI_DEVFN(0, 0)); | 224 | s->functions = pci_scan_slot(bus, PCI_DEVFN(0, 0)); |
225 | /* pcibios_fixup_bus(bus); */ | 225 | pci_fixup_cardbus(bus); |
226 | 226 | ||
227 | max = bus->secondary; | 227 | max = bus->secondary; |
228 | for (pass = 0; pass < 2; pass++) | 228 | for (pass = 0; pass < 2; pass++) |
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index fc5bf9d2a3f3..db32c25e3605 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig | |||
@@ -231,8 +231,36 @@ config THINKPAD_ACPI | |||
231 | 231 | ||
232 | This driver was formerly known as ibm-acpi. | 232 | This driver was formerly known as ibm-acpi. |
233 | 233 | ||
234 | Extra functionality will be available if the rfkill (CONFIG_RFKILL) | ||
235 | and/or ALSA (CONFIG_SND) subsystems are available in the kernel. | ||
236 | Note that if you want ThinkPad-ACPI to be built-in instead of | ||
237 | modular, ALSA and rfkill will also have to be built-in. | ||
238 | |||
234 | If you have an IBM or Lenovo ThinkPad laptop, say Y or M here. | 239 | If you have an IBM or Lenovo ThinkPad laptop, say Y or M here. |
235 | 240 | ||
241 | config THINKPAD_ACPI_ALSA_SUPPORT | ||
242 | bool "Console audio control ALSA interface" | ||
243 | depends on THINKPAD_ACPI | ||
244 | depends on SND | ||
245 | depends on SND = y || THINKPAD_ACPI = SND | ||
246 | default y | ||
247 | ---help--- | ||
248 | Enables monitoring of the built-in console audio output control | ||
249 | (headphone and speakers), which is operated by the mute and (in | ||
250 | some ThinkPad models) volume hotkeys. | ||
251 | |||
252 | If this option is enabled, ThinkPad-ACPI will export an ALSA card | ||
253 | with a single read-only mixer control, which should be used for | ||
254 | on-screen-display feedback purposes by the Desktop Environment. | ||
255 | |||
256 | Optionally, the driver will also allow software control (the | ||
257 | ALSA mixer will be made read-write). Please refer to the driver | ||
258 | documentation for details. | ||
259 | |||
260 | All IBM models have both volume and mute control. Newer Lenovo | ||
261 | models only have mute control (the volume hotkeys are just normal | ||
262 | keys and volume control is done through the main HDA mixer). | ||
263 | |||
236 | config THINKPAD_ACPI_DEBUGFACILITIES | 264 | config THINKPAD_ACPI_DEBUGFACILITIES |
237 | bool "Maintainer debug facilities" | 265 | bool "Maintainer debug facilities" |
238 | depends on THINKPAD_ACPI | 266 | depends on THINKPAD_ACPI |
@@ -464,4 +492,16 @@ config TOSHIBA_BT_RFKILL | |||
464 | 492 | ||
465 | If you have a modern Toshiba laptop with a Bluetooth and an | 493 | If you have a modern Toshiba laptop with a Bluetooth and an |
466 | RFKill switch (such as the Portege R500), say Y. | 494 | RFKill switch (such as the Portege R500), say Y. |
495 | |||
496 | config ACPI_CMPC | ||
497 | tristate "CMPC Laptop Extras" | ||
498 | depends on X86 && ACPI | ||
499 | select INPUT | ||
500 | select BACKLIGHT_CLASS_DEVICE | ||
501 | default n | ||
502 | help | ||
503 | Support for Intel Classmate PC ACPI devices, including some | ||
504 | keys as input device, backlight device, tablet and accelerometer | ||
505 | devices. | ||
506 | |||
467 | endif # X86_PLATFORM_DEVICES | 507 | endif # X86_PLATFORM_DEVICES |
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile index b7474b6a8bf1..9cd9fa0a27e6 100644 --- a/drivers/platform/x86/Makefile +++ b/drivers/platform/x86/Makefile | |||
@@ -5,6 +5,7 @@ | |||
5 | obj-$(CONFIG_ASUS_LAPTOP) += asus-laptop.o | 5 | obj-$(CONFIG_ASUS_LAPTOP) += asus-laptop.o |
6 | obj-$(CONFIG_EEEPC_LAPTOP) += eeepc-laptop.o | 6 | obj-$(CONFIG_EEEPC_LAPTOP) += eeepc-laptop.o |
7 | obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o | 7 | obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o |
8 | obj-$(CONFIG_ACPI_CMPC) += classmate-laptop.o | ||
8 | obj-$(CONFIG_COMPAL_LAPTOP) += compal-laptop.o | 9 | obj-$(CONFIG_COMPAL_LAPTOP) += compal-laptop.o |
9 | obj-$(CONFIG_DELL_LAPTOP) += dell-laptop.o | 10 | obj-$(CONFIG_DELL_LAPTOP) += dell-laptop.o |
10 | obj-$(CONFIG_DELL_WMI) += dell-wmi.o | 11 | obj-$(CONFIG_DELL_WMI) += dell-wmi.o |
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index 454970d2d701..07d14dfdf0b4 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c | |||
@@ -96,9 +96,6 @@ struct acer_quirks { | |||
96 | MODULE_ALIAS("wmi:67C3371D-95A3-4C37-BB61-DD47B491DAAB"); | 96 | MODULE_ALIAS("wmi:67C3371D-95A3-4C37-BB61-DD47B491DAAB"); |
97 | MODULE_ALIAS("wmi:6AF4F258-B401-42fd-BE91-3D4AC2D7C0D3"); | 97 | MODULE_ALIAS("wmi:6AF4F258-B401-42fd-BE91-3D4AC2D7C0D3"); |
98 | 98 | ||
99 | /* Temporary workaround until the WMI sysfs interface goes in */ | ||
100 | MODULE_ALIAS("dmi:*:*Acer*:*:"); | ||
101 | |||
102 | /* | 99 | /* |
103 | * Interface capability flags | 100 | * Interface capability flags |
104 | */ | 101 | */ |
diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c index 79b15b9d9cf0..7b2384d674d0 100644 --- a/drivers/platform/x86/acerhdf.c +++ b/drivers/platform/x86/acerhdf.c | |||
@@ -52,7 +52,7 @@ | |||
52 | */ | 52 | */ |
53 | #undef START_IN_KERNEL_MODE | 53 | #undef START_IN_KERNEL_MODE |
54 | 54 | ||
55 | #define DRV_VER "0.5.20" | 55 | #define DRV_VER "0.5.22" |
56 | 56 | ||
57 | /* | 57 | /* |
58 | * According to the Atom N270 datasheet, | 58 | * According to the Atom N270 datasheet, |
@@ -156,19 +156,25 @@ static const struct bios_settings_t bios_tbl[] = { | |||
156 | {"Acer", "AOA150", "v0.3310", 0x55, 0x58, {0x20, 0x20, 0x00} }, | 156 | {"Acer", "AOA150", "v0.3310", 0x55, 0x58, {0x20, 0x20, 0x00} }, |
157 | /* Acer 1410 */ | 157 | /* Acer 1410 */ |
158 | {"Acer", "Aspire 1410", "v0.3120", 0x55, 0x58, {0x9e, 0x9e, 0x00} }, | 158 | {"Acer", "Aspire 1410", "v0.3120", 0x55, 0x58, {0x9e, 0x9e, 0x00} }, |
159 | /* special BIOS / other */ | 159 | {"Acer", "Aspire 1410", "v1.3303", 0x55, 0x58, {0x9e, 0x9e, 0x00} }, |
160 | /* Acer 1810xx */ | ||
161 | {"Acer", "Aspire 1810TZ", "v0.3120", 0x55, 0x58, {0x9e, 0x9e, 0x00} }, | ||
162 | {"Acer", "Aspire 1810T", "v0.3120", 0x55, 0x58, {0x9e, 0x9e, 0x00} }, | ||
163 | {"Acer", "Aspire 1810T", "v1.3303", 0x55, 0x58, {0x9e, 0x9e, 0x00} }, | ||
164 | {"Acer", "Aspire 1810TZ", "v1.3303", 0x55, 0x58, {0x9e, 0x9e, 0x00} }, | ||
165 | /* Gateway */ | ||
160 | {"Gateway", "AOA110", "v0.3103", 0x55, 0x58, {0x21, 0x21, 0x00} }, | 166 | {"Gateway", "AOA110", "v0.3103", 0x55, 0x58, {0x21, 0x21, 0x00} }, |
161 | {"Gateway", "AOA150", "v0.3103", 0x55, 0x58, {0x20, 0x20, 0x00} }, | 167 | {"Gateway", "AOA150", "v0.3103", 0x55, 0x58, {0x20, 0x20, 0x00} }, |
162 | {"Gateway ", "LT31 ", "v1.3103 ", 0x55, 0x58, | 168 | {"Gateway", "LT31", "v1.3103", 0x55, 0x58, {0x10, 0x0f, 0x00} }, |
163 | {0x10, 0x0f, 0x00} }, | 169 | {"Gateway", "LT31", "v1.3201", 0x55, 0x58, {0x10, 0x0f, 0x00} }, |
164 | {"Gateway ", "LT31 ", "v1.3201 ", 0x55, 0x58, | 170 | {"Gateway", "LT31", "v1.3302", 0x55, 0x58, {0x10, 0x0f, 0x00} }, |
165 | {0x10, 0x0f, 0x00} }, | 171 | /* Packard Bell */ |
166 | {"Gateway ", "LT31 ", "v1.3302 ", 0x55, 0x58, | ||
167 | {0x10, 0x0f, 0x00} }, | ||
168 | {"Packard Bell", "DOA150", "v0.3104", 0x55, 0x58, {0x21, 0x21, 0x00} }, | 172 | {"Packard Bell", "DOA150", "v0.3104", 0x55, 0x58, {0x21, 0x21, 0x00} }, |
169 | {"Packard Bell", "DOA150", "v0.3105", 0x55, 0x58, {0x20, 0x20, 0x00} }, | 173 | {"Packard Bell", "DOA150", "v0.3105", 0x55, 0x58, {0x20, 0x20, 0x00} }, |
170 | {"Packard Bell", "AOA110", "v0.3105", 0x55, 0x58, {0x21, 0x21, 0x00} }, | 174 | {"Packard Bell", "AOA110", "v0.3105", 0x55, 0x58, {0x21, 0x21, 0x00} }, |
171 | {"Packard Bell", "AOA150", "v0.3105", 0x55, 0x58, {0x20, 0x20, 0x00} }, | 175 | {"Packard Bell", "AOA150", "v0.3105", 0x55, 0x58, {0x20, 0x20, 0x00} }, |
176 | {"Packard Bell", "DOTMU", "v1.3303", 0x55, 0x58, {0x9e, 0x9e, 0x00} }, | ||
177 | {"Packard Bell", "DOTMU", "v0.3120", 0x55, 0x58, {0x9e, 0x9e, 0x00} }, | ||
172 | /* pewpew-terminator */ | 178 | /* pewpew-terminator */ |
173 | {"", "", "", 0, 0, {0, 0, 0} } | 179 | {"", "", "", 0, 0, {0, 0, 0} } |
174 | }; | 180 | }; |
@@ -486,13 +492,26 @@ static struct platform_driver acerhdf_driver = { | |||
486 | .remove = acerhdf_remove, | 492 | .remove = acerhdf_remove, |
487 | }; | 493 | }; |
488 | 494 | ||
495 | /* checks if str begins with start */ | ||
496 | static int str_starts_with(const char *str, const char *start) | ||
497 | { | ||
498 | unsigned long str_len = 0, start_len = 0; | ||
499 | |||
500 | str_len = strlen(str); | ||
501 | start_len = strlen(start); | ||
502 | |||
503 | if (str_len >= start_len && | ||
504 | !strncmp(str, start, start_len)) | ||
505 | return 1; | ||
506 | |||
507 | return 0; | ||
508 | } | ||
489 | 509 | ||
490 | /* check hardware */ | 510 | /* check hardware */ |
491 | static int acerhdf_check_hardware(void) | 511 | static int acerhdf_check_hardware(void) |
492 | { | 512 | { |
493 | char const *vendor, *version, *product; | 513 | char const *vendor, *version, *product; |
494 | int i; | 514 | const struct bios_settings_t *bt = NULL; |
495 | unsigned long prod_len = 0; | ||
496 | 515 | ||
497 | /* get BIOS data */ | 516 | /* get BIOS data */ |
498 | vendor = dmi_get_system_info(DMI_SYS_VENDOR); | 517 | vendor = dmi_get_system_info(DMI_SYS_VENDOR); |
@@ -514,20 +533,20 @@ static int acerhdf_check_hardware(void) | |||
514 | kernelmode = 0; | 533 | kernelmode = 0; |
515 | } | 534 | } |
516 | 535 | ||
517 | prod_len = strlen(product); | ||
518 | |||
519 | if (verbose) | 536 | if (verbose) |
520 | pr_info("BIOS info: %s %s, product: %s\n", | 537 | pr_info("BIOS info: %s %s, product: %s\n", |
521 | vendor, version, product); | 538 | vendor, version, product); |
522 | 539 | ||
523 | /* search BIOS version and vendor in BIOS settings table */ | 540 | /* search BIOS version and vendor in BIOS settings table */ |
524 | for (i = 0; bios_tbl[i].version[0]; i++) { | 541 | for (bt = bios_tbl; bt->vendor[0]; bt++) { |
525 | if (strlen(bios_tbl[i].product) >= prod_len && | 542 | /* |
526 | !strncmp(bios_tbl[i].product, product, | 543 | * check if actual hardware BIOS vendor, product and version |
527 | strlen(bios_tbl[i].product)) && | 544 | * IDs start with the strings of BIOS table entry |
528 | !strcmp(bios_tbl[i].vendor, vendor) && | 545 | */ |
529 | !strcmp(bios_tbl[i].version, version)) { | 546 | if (str_starts_with(vendor, bt->vendor) && |
530 | bios_cfg = &bios_tbl[i]; | 547 | str_starts_with(product, bt->product) && |
548 | str_starts_with(version, bt->version)) { | ||
549 | bios_cfg = bt; | ||
531 | break; | 550 | break; |
532 | } | 551 | } |
533 | } | 552 | } |
@@ -640,9 +659,14 @@ static void __exit acerhdf_exit(void) | |||
640 | MODULE_LICENSE("GPL"); | 659 | MODULE_LICENSE("GPL"); |
641 | MODULE_AUTHOR("Peter Feuerer"); | 660 | MODULE_AUTHOR("Peter Feuerer"); |
642 | MODULE_DESCRIPTION("Aspire One temperature and fan driver"); | 661 | MODULE_DESCRIPTION("Aspire One temperature and fan driver"); |
643 | MODULE_ALIAS("dmi:*:*Acer*:*:"); | 662 | MODULE_ALIAS("dmi:*:*Acer*:pnAOA*:"); |
644 | MODULE_ALIAS("dmi:*:*Gateway*:*:"); | 663 | MODULE_ALIAS("dmi:*:*Acer*:pnAspire 1410*:"); |
645 | MODULE_ALIAS("dmi:*:*Packard Bell*:*:"); | 664 | MODULE_ALIAS("dmi:*:*Acer*:pnAspire 1810*:"); |
665 | MODULE_ALIAS("dmi:*:*Gateway*:pnAOA*:"); | ||
666 | MODULE_ALIAS("dmi:*:*Gateway*:pnLT31*:"); | ||
667 | MODULE_ALIAS("dmi:*:*Packard Bell*:pnAOA*:"); | ||
668 | MODULE_ALIAS("dmi:*:*Packard Bell*:pnDOA*:"); | ||
669 | MODULE_ALIAS("dmi:*:*Packard Bell*:pnDOTMU*:"); | ||
646 | 670 | ||
647 | module_init(acerhdf_init); | 671 | module_init(acerhdf_init); |
648 | module_exit(acerhdf_exit); | 672 | module_exit(acerhdf_exit); |
diff --git a/drivers/platform/x86/asus_acpi.c b/drivers/platform/x86/asus_acpi.c index 0c9c53111a22..c1d2aeeea948 100644 --- a/drivers/platform/x86/asus_acpi.c +++ b/drivers/platform/x86/asus_acpi.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/init.h> | 35 | #include <linux/init.h> |
36 | #include <linux/types.h> | 36 | #include <linux/types.h> |
37 | #include <linux/proc_fs.h> | 37 | #include <linux/proc_fs.h> |
38 | #include <linux/seq_file.h> | ||
38 | #include <linux/backlight.h> | 39 | #include <linux/backlight.h> |
39 | #include <acpi/acpi_drivers.h> | 40 | #include <acpi/acpi_drivers.h> |
40 | #include <acpi/acpi_bus.h> | 41 | #include <acpi/acpi_bus.h> |
@@ -513,26 +514,12 @@ static int read_acpi_int(acpi_handle handle, const char *method, int *val) | |||
513 | return (status == AE_OK) && (out_obj.type == ACPI_TYPE_INTEGER); | 514 | return (status == AE_OK) && (out_obj.type == ACPI_TYPE_INTEGER); |
514 | } | 515 | } |
515 | 516 | ||
516 | /* | 517 | static int asus_info_proc_show(struct seq_file *m, void *v) |
517 | * We write our info in page, we begin at offset off and cannot write more | ||
518 | * than count bytes. We set eof to 1 if we handle those 2 values. We return the | ||
519 | * number of bytes written in page | ||
520 | */ | ||
521 | static int | ||
522 | proc_read_info(char *page, char **start, off_t off, int count, int *eof, | ||
523 | void *data) | ||
524 | { | 518 | { |
525 | int len = 0; | ||
526 | int temp; | 519 | int temp; |
527 | char buf[16]; /* enough for all info */ | ||
528 | /* | ||
529 | * We use the easy way, we don't care of off and count, | ||
530 | * so we don't set eof to 1 | ||
531 | */ | ||
532 | 520 | ||
533 | len += sprintf(page, ACPI_HOTK_NAME " " ASUS_ACPI_VERSION "\n"); | 521 | seq_printf(m, ACPI_HOTK_NAME " " ASUS_ACPI_VERSION "\n"); |
534 | len += sprintf(page + len, "Model reference : %s\n", | 522 | seq_printf(m, "Model reference : %s\n", hotk->methods->name); |
535 | hotk->methods->name); | ||
536 | /* | 523 | /* |
537 | * The SFUN method probably allows the original driver to get the list | 524 | * The SFUN method probably allows the original driver to get the list |
538 | * of features supported by a given model. For now, 0x0100 or 0x0800 | 525 | * of features supported by a given model. For now, 0x0100 or 0x0800 |
@@ -540,8 +527,7 @@ proc_read_info(char *page, char **start, off_t off, int count, int *eof, | |||
540 | * The significance of others is yet to be found. | 527 | * The significance of others is yet to be found. |
541 | */ | 528 | */ |
542 | if (read_acpi_int(hotk->handle, "SFUN", &temp)) | 529 | if (read_acpi_int(hotk->handle, "SFUN", &temp)) |
543 | len += | 530 | seq_printf(m, "SFUN value : 0x%04x\n", temp); |
544 | sprintf(page + len, "SFUN value : 0x%04x\n", temp); | ||
545 | /* | 531 | /* |
546 | * Another value for userspace: the ASYM method returns 0x02 for | 532 | * Another value for userspace: the ASYM method returns 0x02 for |
547 | * battery low and 0x04 for battery critical, its readings tend to be | 533 | * battery low and 0x04 for battery critical, its readings tend to be |
@@ -550,30 +536,34 @@ proc_read_info(char *page, char **start, off_t off, int count, int *eof, | |||
550 | * silently ignored. | 536 | * silently ignored. |
551 | */ | 537 | */ |
552 | if (read_acpi_int(hotk->handle, "ASYM", &temp)) | 538 | if (read_acpi_int(hotk->handle, "ASYM", &temp)) |
553 | len += | 539 | seq_printf(m, "ASYM value : 0x%04x\n", temp); |
554 | sprintf(page + len, "ASYM value : 0x%04x\n", temp); | ||
555 | if (asus_info) { | 540 | if (asus_info) { |
556 | snprintf(buf, 16, "%d", asus_info->length); | 541 | seq_printf(m, "DSDT length : %d\n", asus_info->length); |
557 | len += sprintf(page + len, "DSDT length : %s\n", buf); | 542 | seq_printf(m, "DSDT checksum : %d\n", asus_info->checksum); |
558 | snprintf(buf, 16, "%d", asus_info->checksum); | 543 | seq_printf(m, "DSDT revision : %d\n", asus_info->revision); |
559 | len += sprintf(page + len, "DSDT checksum : %s\n", buf); | 544 | seq_printf(m, "OEM id : %.*s\n", ACPI_OEM_ID_SIZE, asus_info->oem_id); |
560 | snprintf(buf, 16, "%d", asus_info->revision); | 545 | seq_printf(m, "OEM table id : %.*s\n", ACPI_OEM_TABLE_ID_SIZE, asus_info->oem_table_id); |
561 | len += sprintf(page + len, "DSDT revision : %s\n", buf); | 546 | seq_printf(m, "OEM revision : 0x%x\n", asus_info->oem_revision); |
562 | snprintf(buf, 7, "%s", asus_info->oem_id); | 547 | seq_printf(m, "ASL comp vendor id : %.*s\n", ACPI_NAME_SIZE, asus_info->asl_compiler_id); |
563 | len += sprintf(page + len, "OEM id : %s\n", buf); | 548 | seq_printf(m, "ASL comp revision : 0x%x\n", asus_info->asl_compiler_revision); |
564 | snprintf(buf, 9, "%s", asus_info->oem_table_id); | ||
565 | len += sprintf(page + len, "OEM table id : %s\n", buf); | ||
566 | snprintf(buf, 16, "%x", asus_info->oem_revision); | ||
567 | len += sprintf(page + len, "OEM revision : 0x%s\n", buf); | ||
568 | snprintf(buf, 5, "%s", asus_info->asl_compiler_id); | ||
569 | len += sprintf(page + len, "ASL comp vendor id : %s\n", buf); | ||
570 | snprintf(buf, 16, "%x", asus_info->asl_compiler_revision); | ||
571 | len += sprintf(page + len, "ASL comp revision : 0x%s\n", buf); | ||
572 | } | 549 | } |
573 | 550 | ||
574 | return len; | 551 | return 0; |
552 | } | ||
553 | |||
554 | static int asus_info_proc_open(struct inode *inode, struct file *file) | ||
555 | { | ||
556 | return single_open(file, asus_info_proc_show, NULL); | ||
575 | } | 557 | } |
576 | 558 | ||
559 | static const struct file_operations asus_info_proc_fops = { | ||
560 | .owner = THIS_MODULE, | ||
561 | .open = asus_info_proc_open, | ||
562 | .read = seq_read, | ||
563 | .llseek = seq_lseek, | ||
564 | .release = single_release, | ||
565 | }; | ||
566 | |||
577 | /* | 567 | /* |
578 | * /proc handlers | 568 | * /proc handlers |
579 | * We write our info in page, we begin at offset off and cannot write more | 569 | * We write our info in page, we begin at offset off and cannot write more |
@@ -639,34 +629,48 @@ write_led(const char __user *buffer, unsigned long count, | |||
639 | /* | 629 | /* |
640 | * Proc handlers for MLED | 630 | * Proc handlers for MLED |
641 | */ | 631 | */ |
642 | static int | 632 | static int mled_proc_show(struct seq_file *m, void *v) |
643 | proc_read_mled(char *page, char **start, off_t off, int count, int *eof, | ||
644 | void *data) | ||
645 | { | 633 | { |
646 | return sprintf(page, "%d\n", | 634 | seq_printf(m, "%d\n", read_led(hotk->methods->mled_status, MLED_ON)); |
647 | read_led(hotk->methods->mled_status, MLED_ON)); | 635 | return 0; |
648 | } | 636 | } |
649 | 637 | ||
650 | static int | 638 | static int mled_proc_open(struct inode *inode, struct file *file) |
651 | proc_write_mled(struct file *file, const char __user *buffer, | 639 | { |
652 | unsigned long count, void *data) | 640 | return single_open(file, mled_proc_show, NULL); |
641 | } | ||
642 | |||
643 | static ssize_t mled_proc_write(struct file *file, const char __user *buffer, | ||
644 | size_t count, loff_t *pos) | ||
653 | { | 645 | { |
654 | return write_led(buffer, count, hotk->methods->mt_mled, MLED_ON, 1); | 646 | return write_led(buffer, count, hotk->methods->mt_mled, MLED_ON, 1); |
655 | } | 647 | } |
656 | 648 | ||
649 | static const struct file_operations mled_proc_fops = { | ||
650 | .owner = THIS_MODULE, | ||
651 | .open = mled_proc_open, | ||
652 | .read = seq_read, | ||
653 | .llseek = seq_lseek, | ||
654 | .release = single_release, | ||
655 | .write = mled_proc_write, | ||
656 | }; | ||
657 | |||
657 | /* | 658 | /* |
658 | * Proc handlers for LED display | 659 | * Proc handlers for LED display |
659 | */ | 660 | */ |
660 | static int | 661 | static int ledd_proc_show(struct seq_file *m, void *v) |
661 | proc_read_ledd(char *page, char **start, off_t off, int count, int *eof, | ||
662 | void *data) | ||
663 | { | 662 | { |
664 | return sprintf(page, "0x%08x\n", hotk->ledd_status); | 663 | seq_printf(m, "0x%08x\n", hotk->ledd_status); |
664 | return 0; | ||
665 | } | 665 | } |
666 | 666 | ||
667 | static int | 667 | static int ledd_proc_open(struct inode *inode, struct file *file) |
668 | proc_write_ledd(struct file *file, const char __user *buffer, | 668 | { |
669 | unsigned long count, void *data) | 669 | return single_open(file, ledd_proc_show, NULL); |
670 | } | ||
671 | |||
672 | static ssize_t ledd_proc_write(struct file *file, const char __user *buffer, | ||
673 | size_t count, loff_t *pos) | ||
670 | { | 674 | { |
671 | int rv, value; | 675 | int rv, value; |
672 | 676 | ||
@@ -682,61 +686,104 @@ proc_write_ledd(struct file *file, const char __user *buffer, | |||
682 | return rv; | 686 | return rv; |
683 | } | 687 | } |
684 | 688 | ||
689 | static const struct file_operations ledd_proc_fops = { | ||
690 | .owner = THIS_MODULE, | ||
691 | .open = ledd_proc_open, | ||
692 | .read = seq_read, | ||
693 | .llseek = seq_lseek, | ||
694 | .release = single_release, | ||
695 | .write = ledd_proc_write, | ||
696 | }; | ||
697 | |||
685 | /* | 698 | /* |
686 | * Proc handlers for WLED | 699 | * Proc handlers for WLED |
687 | */ | 700 | */ |
688 | static int | 701 | static int wled_proc_show(struct seq_file *m, void *v) |
689 | proc_read_wled(char *page, char **start, off_t off, int count, int *eof, | ||
690 | void *data) | ||
691 | { | 702 | { |
692 | return sprintf(page, "%d\n", | 703 | seq_printf(m, "%d\n", read_led(hotk->methods->wled_status, WLED_ON)); |
693 | read_led(hotk->methods->wled_status, WLED_ON)); | 704 | return 0; |
694 | } | 705 | } |
695 | 706 | ||
696 | static int | 707 | static int wled_proc_open(struct inode *inode, struct file *file) |
697 | proc_write_wled(struct file *file, const char __user *buffer, | 708 | { |
698 | unsigned long count, void *data) | 709 | return single_open(file, wled_proc_show, NULL); |
710 | } | ||
711 | |||
712 | static ssize_t wled_proc_write(struct file *file, const char __user *buffer, | ||
713 | size_t count, loff_t *pos) | ||
699 | { | 714 | { |
700 | return write_led(buffer, count, hotk->methods->mt_wled, WLED_ON, 0); | 715 | return write_led(buffer, count, hotk->methods->mt_wled, WLED_ON, 0); |
701 | } | 716 | } |
702 | 717 | ||
718 | static const struct file_operations wled_proc_fops = { | ||
719 | .owner = THIS_MODULE, | ||
720 | .open = wled_proc_open, | ||
721 | .read = seq_read, | ||
722 | .llseek = seq_lseek, | ||
723 | .release = single_release, | ||
724 | .write = wled_proc_write, | ||
725 | }; | ||
726 | |||
703 | /* | 727 | /* |
704 | * Proc handlers for Bluetooth | 728 | * Proc handlers for Bluetooth |
705 | */ | 729 | */ |
706 | static int | 730 | static int bluetooth_proc_show(struct seq_file *m, void *v) |
707 | proc_read_bluetooth(char *page, char **start, off_t off, int count, int *eof, | ||
708 | void *data) | ||
709 | { | 731 | { |
710 | return sprintf(page, "%d\n", read_led(hotk->methods->bt_status, BT_ON)); | 732 | seq_printf(m, "%d\n", read_led(hotk->methods->bt_status, BT_ON)); |
733 | return 0; | ||
711 | } | 734 | } |
712 | 735 | ||
713 | static int | 736 | static int bluetooth_proc_open(struct inode *inode, struct file *file) |
714 | proc_write_bluetooth(struct file *file, const char __user *buffer, | 737 | { |
715 | unsigned long count, void *data) | 738 | return single_open(file, bluetooth_proc_show, NULL); |
739 | } | ||
740 | |||
741 | static ssize_t bluetooth_proc_write(struct file *file, | ||
742 | const char __user *buffer, size_t count, loff_t *pos) | ||
716 | { | 743 | { |
717 | /* Note: mt_bt_switch controls both internal Bluetooth adapter's | 744 | /* Note: mt_bt_switch controls both internal Bluetooth adapter's |
718 | presence and its LED */ | 745 | presence and its LED */ |
719 | return write_led(buffer, count, hotk->methods->mt_bt_switch, BT_ON, 0); | 746 | return write_led(buffer, count, hotk->methods->mt_bt_switch, BT_ON, 0); |
720 | } | 747 | } |
721 | 748 | ||
749 | static const struct file_operations bluetooth_proc_fops = { | ||
750 | .owner = THIS_MODULE, | ||
751 | .open = bluetooth_proc_open, | ||
752 | .read = seq_read, | ||
753 | .llseek = seq_lseek, | ||
754 | .release = single_release, | ||
755 | .write = bluetooth_proc_write, | ||
756 | }; | ||
757 | |||
722 | /* | 758 | /* |
723 | * Proc handlers for TLED | 759 | * Proc handlers for TLED |
724 | */ | 760 | */ |
725 | static int | 761 | static int tled_proc_show(struct seq_file *m, void *v) |
726 | proc_read_tled(char *page, char **start, off_t off, int count, int *eof, | ||
727 | void *data) | ||
728 | { | 762 | { |
729 | return sprintf(page, "%d\n", | 763 | seq_printf(m, "%d\n", read_led(hotk->methods->tled_status, TLED_ON)); |
730 | read_led(hotk->methods->tled_status, TLED_ON)); | 764 | return 0; |
731 | } | 765 | } |
732 | 766 | ||
733 | static int | 767 | static int tled_proc_open(struct inode *inode, struct file *file) |
734 | proc_write_tled(struct file *file, const char __user *buffer, | 768 | { |
735 | unsigned long count, void *data) | 769 | return single_open(file, tled_proc_show, NULL); |
770 | } | ||
771 | |||
772 | static ssize_t tled_proc_write(struct file *file, const char __user *buffer, | ||
773 | size_t count, loff_t *pos) | ||
736 | { | 774 | { |
737 | return write_led(buffer, count, hotk->methods->mt_tled, TLED_ON, 0); | 775 | return write_led(buffer, count, hotk->methods->mt_tled, TLED_ON, 0); |
738 | } | 776 | } |
739 | 777 | ||
778 | static const struct file_operations tled_proc_fops = { | ||
779 | .owner = THIS_MODULE, | ||
780 | .open = tled_proc_open, | ||
781 | .read = seq_read, | ||
782 | .llseek = seq_lseek, | ||
783 | .release = single_release, | ||
784 | .write = tled_proc_write, | ||
785 | }; | ||
786 | |||
740 | static int get_lcd_state(void) | 787 | static int get_lcd_state(void) |
741 | { | 788 | { |
742 | int lcd = 0; | 789 | int lcd = 0; |
@@ -829,16 +876,19 @@ static int set_lcd_state(int value) | |||
829 | 876 | ||
830 | } | 877 | } |
831 | 878 | ||
832 | static int | 879 | static int lcd_proc_show(struct seq_file *m, void *v) |
833 | proc_read_lcd(char *page, char **start, off_t off, int count, int *eof, | ||
834 | void *data) | ||
835 | { | 880 | { |
836 | return sprintf(page, "%d\n", get_lcd_state()); | 881 | seq_printf(m, "%d\n", get_lcd_state()); |
882 | return 0; | ||
837 | } | 883 | } |
838 | 884 | ||
839 | static int | 885 | static int lcd_proc_open(struct inode *inode, struct file *file) |
840 | proc_write_lcd(struct file *file, const char __user *buffer, | 886 | { |
841 | unsigned long count, void *data) | 887 | return single_open(file, lcd_proc_show, NULL); |
888 | } | ||
889 | |||
890 | static ssize_t lcd_proc_write(struct file *file, const char __user *buffer, | ||
891 | size_t count, loff_t *pos) | ||
842 | { | 892 | { |
843 | int rv, value; | 893 | int rv, value; |
844 | 894 | ||
@@ -848,6 +898,15 @@ proc_write_lcd(struct file *file, const char __user *buffer, | |||
848 | return rv; | 898 | return rv; |
849 | } | 899 | } |
850 | 900 | ||
901 | static const struct file_operations lcd_proc_fops = { | ||
902 | .owner = THIS_MODULE, | ||
903 | .open = lcd_proc_open, | ||
904 | .read = seq_read, | ||
905 | .llseek = seq_lseek, | ||
906 | .release = single_release, | ||
907 | .write = lcd_proc_write, | ||
908 | }; | ||
909 | |||
851 | static int read_brightness(struct backlight_device *bd) | 910 | static int read_brightness(struct backlight_device *bd) |
852 | { | 911 | { |
853 | int value; | 912 | int value; |
@@ -907,16 +966,19 @@ static int set_brightness_status(struct backlight_device *bd) | |||
907 | return set_brightness(bd->props.brightness); | 966 | return set_brightness(bd->props.brightness); |
908 | } | 967 | } |
909 | 968 | ||
910 | static int | 969 | static int brn_proc_show(struct seq_file *m, void *v) |
911 | proc_read_brn(char *page, char **start, off_t off, int count, int *eof, | ||
912 | void *data) | ||
913 | { | 970 | { |
914 | return sprintf(page, "%d\n", read_brightness(NULL)); | 971 | seq_printf(m, "%d\n", read_brightness(NULL)); |
972 | return 0; | ||
915 | } | 973 | } |
916 | 974 | ||
917 | static int | 975 | static int brn_proc_open(struct inode *inode, struct file *file) |
918 | proc_write_brn(struct file *file, const char __user *buffer, | 976 | { |
919 | unsigned long count, void *data) | 977 | return single_open(file, brn_proc_show, NULL); |
978 | } | ||
979 | |||
980 | static ssize_t brn_proc_write(struct file *file, const char __user *buffer, | ||
981 | size_t count, loff_t *pos) | ||
920 | { | 982 | { |
921 | int rv, value; | 983 | int rv, value; |
922 | 984 | ||
@@ -929,6 +991,15 @@ proc_write_brn(struct file *file, const char __user *buffer, | |||
929 | return rv; | 991 | return rv; |
930 | } | 992 | } |
931 | 993 | ||
994 | static const struct file_operations brn_proc_fops = { | ||
995 | .owner = THIS_MODULE, | ||
996 | .open = brn_proc_open, | ||
997 | .read = seq_read, | ||
998 | .llseek = seq_lseek, | ||
999 | .release = single_release, | ||
1000 | .write = brn_proc_write, | ||
1001 | }; | ||
1002 | |||
932 | static void set_display(int value) | 1003 | static void set_display(int value) |
933 | { | 1004 | { |
934 | /* no sanity check needed for now */ | 1005 | /* no sanity check needed for now */ |
@@ -942,9 +1013,7 @@ static void set_display(int value) | |||
942 | * Now, *this* one could be more user-friendly, but so far, no-one has | 1013 | * Now, *this* one could be more user-friendly, but so far, no-one has |
943 | * complained. The significance of bits is the same as in proc_write_disp() | 1014 | * complained. The significance of bits is the same as in proc_write_disp() |
944 | */ | 1015 | */ |
945 | static int | 1016 | static int disp_proc_show(struct seq_file *m, void *v) |
946 | proc_read_disp(char *page, char **start, off_t off, int count, int *eof, | ||
947 | void *data) | ||
948 | { | 1017 | { |
949 | int value = 0; | 1018 | int value = 0; |
950 | 1019 | ||
@@ -952,7 +1021,13 @@ proc_read_disp(char *page, char **start, off_t off, int count, int *eof, | |||
952 | printk(KERN_WARNING | 1021 | printk(KERN_WARNING |
953 | "Asus ACPI: Error reading display status\n"); | 1022 | "Asus ACPI: Error reading display status\n"); |
954 | value &= 0x07; /* needed for some models, shouldn't hurt others */ | 1023 | value &= 0x07; /* needed for some models, shouldn't hurt others */ |
955 | return sprintf(page, "%d\n", value); | 1024 | seq_printf(m, "%d\n", value); |
1025 | return 0; | ||
1026 | } | ||
1027 | |||
1028 | static int disp_proc_open(struct inode *inode, struct file *file) | ||
1029 | { | ||
1030 | return single_open(file, disp_proc_show, NULL); | ||
956 | } | 1031 | } |
957 | 1032 | ||
958 | /* | 1033 | /* |
@@ -961,9 +1036,8 @@ proc_read_disp(char *page, char **start, off_t off, int count, int *eof, | |||
961 | * (bitwise) of these will suffice. I never actually tested 3 displays hooked | 1036 | * (bitwise) of these will suffice. I never actually tested 3 displays hooked |
962 | * up simultaneously, so be warned. See the acpi4asus README for more info. | 1037 | * up simultaneously, so be warned. See the acpi4asus README for more info. |
963 | */ | 1038 | */ |
964 | static int | 1039 | static ssize_t disp_proc_write(struct file *file, const char __user *buffer, |
965 | proc_write_disp(struct file *file, const char __user *buffer, | 1040 | size_t count, loff_t *pos) |
966 | unsigned long count, void *data) | ||
967 | { | 1041 | { |
968 | int rv, value; | 1042 | int rv, value; |
969 | 1043 | ||
@@ -973,25 +1047,27 @@ proc_write_disp(struct file *file, const char __user *buffer, | |||
973 | return rv; | 1047 | return rv; |
974 | } | 1048 | } |
975 | 1049 | ||
976 | typedef int (proc_readfunc) (char *page, char **start, off_t off, int count, | 1050 | static const struct file_operations disp_proc_fops = { |
977 | int *eof, void *data); | 1051 | .owner = THIS_MODULE, |
978 | typedef int (proc_writefunc) (struct file *file, const char __user *buffer, | 1052 | .open = disp_proc_open, |
979 | unsigned long count, void *data); | 1053 | .read = seq_read, |
1054 | .llseek = seq_lseek, | ||
1055 | .release = single_release, | ||
1056 | .write = disp_proc_write, | ||
1057 | }; | ||
980 | 1058 | ||
981 | static int | 1059 | static int |
982 | asus_proc_add(char *name, proc_writefunc *writefunc, | 1060 | asus_proc_add(char *name, const struct file_operations *proc_fops, mode_t mode, |
983 | proc_readfunc *readfunc, mode_t mode, | ||
984 | struct acpi_device *device) | 1061 | struct acpi_device *device) |
985 | { | 1062 | { |
986 | struct proc_dir_entry *proc = | 1063 | struct proc_dir_entry *proc; |
987 | create_proc_entry(name, mode, acpi_device_dir(device)); | 1064 | |
1065 | proc = proc_create_data(name, mode, acpi_device_dir(device), | ||
1066 | proc_fops, acpi_driver_data(device)); | ||
988 | if (!proc) { | 1067 | if (!proc) { |
989 | printk(KERN_WARNING " Unable to create %s fs entry\n", name); | 1068 | printk(KERN_WARNING " Unable to create %s fs entry\n", name); |
990 | return -1; | 1069 | return -1; |
991 | } | 1070 | } |
992 | proc->write_proc = writefunc; | ||
993 | proc->read_proc = readfunc; | ||
994 | proc->data = acpi_driver_data(device); | ||
995 | proc->uid = asus_uid; | 1071 | proc->uid = asus_uid; |
996 | proc->gid = asus_gid; | 1072 | proc->gid = asus_gid; |
997 | return 0; | 1073 | return 0; |
@@ -1020,10 +1096,9 @@ static int asus_hotk_add_fs(struct acpi_device *device) | |||
1020 | if (!acpi_device_dir(device)) | 1096 | if (!acpi_device_dir(device)) |
1021 | return -ENODEV; | 1097 | return -ENODEV; |
1022 | 1098 | ||
1023 | proc = create_proc_entry(PROC_INFO, mode, acpi_device_dir(device)); | 1099 | proc = proc_create(PROC_INFO, mode, acpi_device_dir(device), |
1100 | &asus_info_proc_fops); | ||
1024 | if (proc) { | 1101 | if (proc) { |
1025 | proc->read_proc = proc_read_info; | ||
1026 | proc->data = acpi_driver_data(device); | ||
1027 | proc->uid = asus_uid; | 1102 | proc->uid = asus_uid; |
1028 | proc->gid = asus_gid; | 1103 | proc->gid = asus_gid; |
1029 | } else { | 1104 | } else { |
@@ -1032,28 +1107,23 @@ static int asus_hotk_add_fs(struct acpi_device *device) | |||
1032 | } | 1107 | } |
1033 | 1108 | ||
1034 | if (hotk->methods->mt_wled) { | 1109 | if (hotk->methods->mt_wled) { |
1035 | asus_proc_add(PROC_WLED, &proc_write_wled, &proc_read_wled, | 1110 | asus_proc_add(PROC_WLED, &wled_proc_fops, mode, device); |
1036 | mode, device); | ||
1037 | } | 1111 | } |
1038 | 1112 | ||
1039 | if (hotk->methods->mt_ledd) { | 1113 | if (hotk->methods->mt_ledd) { |
1040 | asus_proc_add(PROC_LEDD, &proc_write_ledd, &proc_read_ledd, | 1114 | asus_proc_add(PROC_LEDD, &ledd_proc_fops, mode, device); |
1041 | mode, device); | ||
1042 | } | 1115 | } |
1043 | 1116 | ||
1044 | if (hotk->methods->mt_mled) { | 1117 | if (hotk->methods->mt_mled) { |
1045 | asus_proc_add(PROC_MLED, &proc_write_mled, &proc_read_mled, | 1118 | asus_proc_add(PROC_MLED, &mled_proc_fops, mode, device); |
1046 | mode, device); | ||
1047 | } | 1119 | } |
1048 | 1120 | ||
1049 | if (hotk->methods->mt_tled) { | 1121 | if (hotk->methods->mt_tled) { |
1050 | asus_proc_add(PROC_TLED, &proc_write_tled, &proc_read_tled, | 1122 | asus_proc_add(PROC_TLED, &tled_proc_fops, mode, device); |
1051 | mode, device); | ||
1052 | } | 1123 | } |
1053 | 1124 | ||
1054 | if (hotk->methods->mt_bt_switch) { | 1125 | if (hotk->methods->mt_bt_switch) { |
1055 | asus_proc_add(PROC_BT, &proc_write_bluetooth, | 1126 | asus_proc_add(PROC_BT, &bluetooth_proc_fops, mode, device); |
1056 | &proc_read_bluetooth, mode, device); | ||
1057 | } | 1127 | } |
1058 | 1128 | ||
1059 | /* | 1129 | /* |
@@ -1061,19 +1131,16 @@ static int asus_hotk_add_fs(struct acpi_device *device) | |||
1061 | * accessible from the keyboard | 1131 | * accessible from the keyboard |
1062 | */ | 1132 | */ |
1063 | if (hotk->methods->mt_lcd_switch && hotk->methods->lcd_status) { | 1133 | if (hotk->methods->mt_lcd_switch && hotk->methods->lcd_status) { |
1064 | asus_proc_add(PROC_LCD, &proc_write_lcd, &proc_read_lcd, mode, | 1134 | asus_proc_add(PROC_LCD, &lcd_proc_fops, mode, device); |
1065 | device); | ||
1066 | } | 1135 | } |
1067 | 1136 | ||
1068 | if ((hotk->methods->brightness_up && hotk->methods->brightness_down) || | 1137 | if ((hotk->methods->brightness_up && hotk->methods->brightness_down) || |
1069 | (hotk->methods->brightness_get && hotk->methods->brightness_set)) { | 1138 | (hotk->methods->brightness_get && hotk->methods->brightness_set)) { |
1070 | asus_proc_add(PROC_BRN, &proc_write_brn, &proc_read_brn, mode, | 1139 | asus_proc_add(PROC_BRN, &brn_proc_fops, mode, device); |
1071 | device); | ||
1072 | } | 1140 | } |
1073 | 1141 | ||
1074 | if (hotk->methods->display_set) { | 1142 | if (hotk->methods->display_set) { |
1075 | asus_proc_add(PROC_DISP, &proc_write_disp, &proc_read_disp, | 1143 | asus_proc_add(PROC_DISP, &disp_proc_fops, mode, device); |
1076 | mode, device); | ||
1077 | } | 1144 | } |
1078 | 1145 | ||
1079 | return 0; | 1146 | return 0; |
diff --git a/drivers/platform/x86/classmate-laptop.c b/drivers/platform/x86/classmate-laptop.c new file mode 100644 index 000000000000..ed90082cdf1d --- /dev/null +++ b/drivers/platform/x86/classmate-laptop.c | |||
@@ -0,0 +1,609 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2009 Thadeu Lima de Souza Cascardo <cascardo@holoscopio.com> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
17 | */ | ||
18 | |||
19 | |||
20 | #include <linux/init.h> | ||
21 | #include <linux/module.h> | ||
22 | #include <linux/workqueue.h> | ||
23 | #include <acpi/acpi_drivers.h> | ||
24 | #include <linux/backlight.h> | ||
25 | #include <linux/input.h> | ||
26 | |||
27 | MODULE_LICENSE("GPL"); | ||
28 | |||
29 | |||
30 | struct cmpc_accel { | ||
31 | int sensitivity; | ||
32 | }; | ||
33 | |||
34 | #define CMPC_ACCEL_SENSITIVITY_DEFAULT 5 | ||
35 | |||
36 | |||
37 | /* | ||
38 | * Generic input device code. | ||
39 | */ | ||
40 | |||
41 | typedef void (*input_device_init)(struct input_dev *dev); | ||
42 | |||
43 | static int cmpc_add_acpi_notify_device(struct acpi_device *acpi, char *name, | ||
44 | input_device_init idev_init) | ||
45 | { | ||
46 | struct input_dev *inputdev; | ||
47 | int error; | ||
48 | |||
49 | inputdev = input_allocate_device(); | ||
50 | if (!inputdev) | ||
51 | return -ENOMEM; | ||
52 | inputdev->name = name; | ||
53 | inputdev->dev.parent = &acpi->dev; | ||
54 | idev_init(inputdev); | ||
55 | error = input_register_device(inputdev); | ||
56 | if (error) { | ||
57 | input_free_device(inputdev); | ||
58 | return error; | ||
59 | } | ||
60 | dev_set_drvdata(&acpi->dev, inputdev); | ||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | static int cmpc_remove_acpi_notify_device(struct acpi_device *acpi) | ||
65 | { | ||
66 | struct input_dev *inputdev = dev_get_drvdata(&acpi->dev); | ||
67 | input_unregister_device(inputdev); | ||
68 | return 0; | ||
69 | } | ||
70 | |||
71 | /* | ||
72 | * Accelerometer code. | ||
73 | */ | ||
74 | static acpi_status cmpc_start_accel(acpi_handle handle) | ||
75 | { | ||
76 | union acpi_object param[2]; | ||
77 | struct acpi_object_list input; | ||
78 | acpi_status status; | ||
79 | |||
80 | param[0].type = ACPI_TYPE_INTEGER; | ||
81 | param[0].integer.value = 0x3; | ||
82 | param[1].type = ACPI_TYPE_INTEGER; | ||
83 | input.count = 2; | ||
84 | input.pointer = param; | ||
85 | status = acpi_evaluate_object(handle, "ACMD", &input, NULL); | ||
86 | return status; | ||
87 | } | ||
88 | |||
89 | static acpi_status cmpc_stop_accel(acpi_handle handle) | ||
90 | { | ||
91 | union acpi_object param[2]; | ||
92 | struct acpi_object_list input; | ||
93 | acpi_status status; | ||
94 | |||
95 | param[0].type = ACPI_TYPE_INTEGER; | ||
96 | param[0].integer.value = 0x4; | ||
97 | param[1].type = ACPI_TYPE_INTEGER; | ||
98 | input.count = 2; | ||
99 | input.pointer = param; | ||
100 | status = acpi_evaluate_object(handle, "ACMD", &input, NULL); | ||
101 | return status; | ||
102 | } | ||
103 | |||
104 | static acpi_status cmpc_accel_set_sensitivity(acpi_handle handle, int val) | ||
105 | { | ||
106 | union acpi_object param[2]; | ||
107 | struct acpi_object_list input; | ||
108 | |||
109 | param[0].type = ACPI_TYPE_INTEGER; | ||
110 | param[0].integer.value = 0x02; | ||
111 | param[1].type = ACPI_TYPE_INTEGER; | ||
112 | param[1].integer.value = val; | ||
113 | input.count = 2; | ||
114 | input.pointer = param; | ||
115 | return acpi_evaluate_object(handle, "ACMD", &input, NULL); | ||
116 | } | ||
117 | |||
118 | static acpi_status cmpc_get_accel(acpi_handle handle, | ||
119 | unsigned char *x, | ||
120 | unsigned char *y, | ||
121 | unsigned char *z) | ||
122 | { | ||
123 | union acpi_object param[2]; | ||
124 | struct acpi_object_list input; | ||
125 | struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, 0 }; | ||
126 | unsigned char *locs; | ||
127 | acpi_status status; | ||
128 | |||
129 | param[0].type = ACPI_TYPE_INTEGER; | ||
130 | param[0].integer.value = 0x01; | ||
131 | param[1].type = ACPI_TYPE_INTEGER; | ||
132 | input.count = 2; | ||
133 | input.pointer = param; | ||
134 | status = acpi_evaluate_object(handle, "ACMD", &input, &output); | ||
135 | if (ACPI_SUCCESS(status)) { | ||
136 | union acpi_object *obj; | ||
137 | obj = output.pointer; | ||
138 | locs = obj->buffer.pointer; | ||
139 | *x = locs[0]; | ||
140 | *y = locs[1]; | ||
141 | *z = locs[2]; | ||
142 | kfree(output.pointer); | ||
143 | } | ||
144 | return status; | ||
145 | } | ||
146 | |||
147 | static void cmpc_accel_handler(struct acpi_device *dev, u32 event) | ||
148 | { | ||
149 | if (event == 0x81) { | ||
150 | unsigned char x, y, z; | ||
151 | acpi_status status; | ||
152 | |||
153 | status = cmpc_get_accel(dev->handle, &x, &y, &z); | ||
154 | if (ACPI_SUCCESS(status)) { | ||
155 | struct input_dev *inputdev = dev_get_drvdata(&dev->dev); | ||
156 | |||
157 | input_report_abs(inputdev, ABS_X, x); | ||
158 | input_report_abs(inputdev, ABS_Y, y); | ||
159 | input_report_abs(inputdev, ABS_Z, z); | ||
160 | input_sync(inputdev); | ||
161 | } | ||
162 | } | ||
163 | } | ||
164 | |||
165 | static ssize_t cmpc_accel_sensitivity_show(struct device *dev, | ||
166 | struct device_attribute *attr, | ||
167 | char *buf) | ||
168 | { | ||
169 | struct acpi_device *acpi; | ||
170 | struct input_dev *inputdev; | ||
171 | struct cmpc_accel *accel; | ||
172 | |||
173 | acpi = to_acpi_device(dev); | ||
174 | inputdev = dev_get_drvdata(&acpi->dev); | ||
175 | accel = dev_get_drvdata(&inputdev->dev); | ||
176 | |||
177 | return sprintf(buf, "%d\n", accel->sensitivity); | ||
178 | } | ||
179 | |||
180 | static ssize_t cmpc_accel_sensitivity_store(struct device *dev, | ||
181 | struct device_attribute *attr, | ||
182 | const char *buf, size_t count) | ||
183 | { | ||
184 | struct acpi_device *acpi; | ||
185 | struct input_dev *inputdev; | ||
186 | struct cmpc_accel *accel; | ||
187 | unsigned long sensitivity; | ||
188 | int r; | ||
189 | |||
190 | acpi = to_acpi_device(dev); | ||
191 | inputdev = dev_get_drvdata(&acpi->dev); | ||
192 | accel = dev_get_drvdata(&inputdev->dev); | ||
193 | |||
194 | r = strict_strtoul(buf, 0, &sensitivity); | ||
195 | if (r) | ||
196 | return r; | ||
197 | |||
198 | accel->sensitivity = sensitivity; | ||
199 | cmpc_accel_set_sensitivity(acpi->handle, sensitivity); | ||
200 | |||
201 | return strnlen(buf, count); | ||
202 | } | ||
203 | |||
204 | struct device_attribute cmpc_accel_sensitivity_attr = { | ||
205 | .attr = { .name = "sensitivity", .mode = 0660 }, | ||
206 | .show = cmpc_accel_sensitivity_show, | ||
207 | .store = cmpc_accel_sensitivity_store | ||
208 | }; | ||
209 | |||
210 | static int cmpc_accel_open(struct input_dev *input) | ||
211 | { | ||
212 | struct acpi_device *acpi; | ||
213 | |||
214 | acpi = to_acpi_device(input->dev.parent); | ||
215 | if (ACPI_SUCCESS(cmpc_start_accel(acpi->handle))) | ||
216 | return 0; | ||
217 | return -EIO; | ||
218 | } | ||
219 | |||
220 | static void cmpc_accel_close(struct input_dev *input) | ||
221 | { | ||
222 | struct acpi_device *acpi; | ||
223 | |||
224 | acpi = to_acpi_device(input->dev.parent); | ||
225 | cmpc_stop_accel(acpi->handle); | ||
226 | } | ||
227 | |||
228 | static void cmpc_accel_idev_init(struct input_dev *inputdev) | ||
229 | { | ||
230 | set_bit(EV_ABS, inputdev->evbit); | ||
231 | input_set_abs_params(inputdev, ABS_X, 0, 255, 8, 0); | ||
232 | input_set_abs_params(inputdev, ABS_Y, 0, 255, 8, 0); | ||
233 | input_set_abs_params(inputdev, ABS_Z, 0, 255, 8, 0); | ||
234 | inputdev->open = cmpc_accel_open; | ||
235 | inputdev->close = cmpc_accel_close; | ||
236 | } | ||
237 | |||
238 | static int cmpc_accel_add(struct acpi_device *acpi) | ||
239 | { | ||
240 | int error; | ||
241 | struct input_dev *inputdev; | ||
242 | struct cmpc_accel *accel; | ||
243 | |||
244 | accel = kmalloc(sizeof(*accel), GFP_KERNEL); | ||
245 | if (!accel) | ||
246 | return -ENOMEM; | ||
247 | |||
248 | accel->sensitivity = CMPC_ACCEL_SENSITIVITY_DEFAULT; | ||
249 | cmpc_accel_set_sensitivity(acpi->handle, accel->sensitivity); | ||
250 | |||
251 | error = device_create_file(&acpi->dev, &cmpc_accel_sensitivity_attr); | ||
252 | if (error) | ||
253 | goto failed_file; | ||
254 | |||
255 | error = cmpc_add_acpi_notify_device(acpi, "cmpc_accel", | ||
256 | cmpc_accel_idev_init); | ||
257 | if (error) | ||
258 | goto failed_input; | ||
259 | |||
260 | inputdev = dev_get_drvdata(&acpi->dev); | ||
261 | dev_set_drvdata(&inputdev->dev, accel); | ||
262 | |||
263 | return 0; | ||
264 | |||
265 | failed_input: | ||
266 | device_remove_file(&acpi->dev, &cmpc_accel_sensitivity_attr); | ||
267 | failed_file: | ||
268 | kfree(accel); | ||
269 | return error; | ||
270 | } | ||
271 | |||
272 | static int cmpc_accel_remove(struct acpi_device *acpi, int type) | ||
273 | { | ||
274 | struct input_dev *inputdev; | ||
275 | struct cmpc_accel *accel; | ||
276 | |||
277 | inputdev = dev_get_drvdata(&acpi->dev); | ||
278 | accel = dev_get_drvdata(&inputdev->dev); | ||
279 | |||
280 | device_remove_file(&acpi->dev, &cmpc_accel_sensitivity_attr); | ||
281 | return cmpc_remove_acpi_notify_device(acpi); | ||
282 | } | ||
283 | |||
284 | static const struct acpi_device_id cmpc_accel_device_ids[] = { | ||
285 | {"ACCE0000", 0}, | ||
286 | {"", 0} | ||
287 | }; | ||
288 | MODULE_DEVICE_TABLE(acpi, cmpc_accel_device_ids); | ||
289 | |||
290 | static struct acpi_driver cmpc_accel_acpi_driver = { | ||
291 | .owner = THIS_MODULE, | ||
292 | .name = "cmpc_accel", | ||
293 | .class = "cmpc_accel", | ||
294 | .ids = cmpc_accel_device_ids, | ||
295 | .ops = { | ||
296 | .add = cmpc_accel_add, | ||
297 | .remove = cmpc_accel_remove, | ||
298 | .notify = cmpc_accel_handler, | ||
299 | } | ||
300 | }; | ||
301 | |||
302 | |||
303 | /* | ||
304 | * Tablet mode code. | ||
305 | */ | ||
306 | static acpi_status cmpc_get_tablet(acpi_handle handle, | ||
307 | unsigned long long *value) | ||
308 | { | ||
309 | union acpi_object param; | ||
310 | struct acpi_object_list input; | ||
311 | unsigned long long output; | ||
312 | acpi_status status; | ||
313 | |||
314 | param.type = ACPI_TYPE_INTEGER; | ||
315 | param.integer.value = 0x01; | ||
316 | input.count = 1; | ||
317 | input.pointer = ¶m; | ||
318 | status = acpi_evaluate_integer(handle, "TCMD", &input, &output); | ||
319 | if (ACPI_SUCCESS(status)) | ||
320 | *value = output; | ||
321 | return status; | ||
322 | } | ||
323 | |||
324 | static void cmpc_tablet_handler(struct acpi_device *dev, u32 event) | ||
325 | { | ||
326 | unsigned long long val = 0; | ||
327 | struct input_dev *inputdev = dev_get_drvdata(&dev->dev); | ||
328 | |||
329 | if (event == 0x81) { | ||
330 | if (ACPI_SUCCESS(cmpc_get_tablet(dev->handle, &val))) | ||
331 | input_report_switch(inputdev, SW_TABLET_MODE, !val); | ||
332 | } | ||
333 | } | ||
334 | |||
335 | static void cmpc_tablet_idev_init(struct input_dev *inputdev) | ||
336 | { | ||
337 | unsigned long long val = 0; | ||
338 | struct acpi_device *acpi; | ||
339 | |||
340 | set_bit(EV_SW, inputdev->evbit); | ||
341 | set_bit(SW_TABLET_MODE, inputdev->swbit); | ||
342 | |||
343 | acpi = to_acpi_device(inputdev->dev.parent); | ||
344 | if (ACPI_SUCCESS(cmpc_get_tablet(acpi->handle, &val))) | ||
345 | input_report_switch(inputdev, SW_TABLET_MODE, !val); | ||
346 | } | ||
347 | |||
348 | static int cmpc_tablet_add(struct acpi_device *acpi) | ||
349 | { | ||
350 | return cmpc_add_acpi_notify_device(acpi, "cmpc_tablet", | ||
351 | cmpc_tablet_idev_init); | ||
352 | } | ||
353 | |||
354 | static int cmpc_tablet_remove(struct acpi_device *acpi, int type) | ||
355 | { | ||
356 | return cmpc_remove_acpi_notify_device(acpi); | ||
357 | } | ||
358 | |||
359 | static int cmpc_tablet_resume(struct acpi_device *acpi) | ||
360 | { | ||
361 | struct input_dev *inputdev = dev_get_drvdata(&acpi->dev); | ||
362 | unsigned long long val = 0; | ||
363 | if (ACPI_SUCCESS(cmpc_get_tablet(acpi->handle, &val))) | ||
364 | input_report_switch(inputdev, SW_TABLET_MODE, !val); | ||
365 | return 0; | ||
366 | } | ||
367 | |||
368 | static const struct acpi_device_id cmpc_tablet_device_ids[] = { | ||
369 | {"TBLT0000", 0}, | ||
370 | {"", 0} | ||
371 | }; | ||
372 | MODULE_DEVICE_TABLE(acpi, cmpc_tablet_device_ids); | ||
373 | |||
374 | static struct acpi_driver cmpc_tablet_acpi_driver = { | ||
375 | .owner = THIS_MODULE, | ||
376 | .name = "cmpc_tablet", | ||
377 | .class = "cmpc_tablet", | ||
378 | .ids = cmpc_tablet_device_ids, | ||
379 | .ops = { | ||
380 | .add = cmpc_tablet_add, | ||
381 | .remove = cmpc_tablet_remove, | ||
382 | .resume = cmpc_tablet_resume, | ||
383 | .notify = cmpc_tablet_handler, | ||
384 | } | ||
385 | }; | ||
386 | |||
387 | |||
388 | /* | ||
389 | * Backlight code. | ||
390 | */ | ||
391 | |||
392 | static acpi_status cmpc_get_brightness(acpi_handle handle, | ||
393 | unsigned long long *value) | ||
394 | { | ||
395 | union acpi_object param; | ||
396 | struct acpi_object_list input; | ||
397 | unsigned long long output; | ||
398 | acpi_status status; | ||
399 | |||
400 | param.type = ACPI_TYPE_INTEGER; | ||
401 | param.integer.value = 0xC0; | ||
402 | input.count = 1; | ||
403 | input.pointer = ¶m; | ||
404 | status = acpi_evaluate_integer(handle, "GRDI", &input, &output); | ||
405 | if (ACPI_SUCCESS(status)) | ||
406 | *value = output; | ||
407 | return status; | ||
408 | } | ||
409 | |||
410 | static acpi_status cmpc_set_brightness(acpi_handle handle, | ||
411 | unsigned long long value) | ||
412 | { | ||
413 | union acpi_object param[2]; | ||
414 | struct acpi_object_list input; | ||
415 | acpi_status status; | ||
416 | unsigned long long output; | ||
417 | |||
418 | param[0].type = ACPI_TYPE_INTEGER; | ||
419 | param[0].integer.value = 0xC0; | ||
420 | param[1].type = ACPI_TYPE_INTEGER; | ||
421 | param[1].integer.value = value; | ||
422 | input.count = 2; | ||
423 | input.pointer = param; | ||
424 | status = acpi_evaluate_integer(handle, "GWRI", &input, &output); | ||
425 | return status; | ||
426 | } | ||
427 | |||
428 | static int cmpc_bl_get_brightness(struct backlight_device *bd) | ||
429 | { | ||
430 | acpi_status status; | ||
431 | acpi_handle handle; | ||
432 | unsigned long long brightness; | ||
433 | |||
434 | handle = bl_get_data(bd); | ||
435 | status = cmpc_get_brightness(handle, &brightness); | ||
436 | if (ACPI_SUCCESS(status)) | ||
437 | return brightness; | ||
438 | else | ||
439 | return -1; | ||
440 | } | ||
441 | |||
442 | static int cmpc_bl_update_status(struct backlight_device *bd) | ||
443 | { | ||
444 | acpi_status status; | ||
445 | acpi_handle handle; | ||
446 | |||
447 | handle = bl_get_data(bd); | ||
448 | status = cmpc_set_brightness(handle, bd->props.brightness); | ||
449 | if (ACPI_SUCCESS(status)) | ||
450 | return 0; | ||
451 | else | ||
452 | return -1; | ||
453 | } | ||
454 | |||
455 | static struct backlight_ops cmpc_bl_ops = { | ||
456 | .get_brightness = cmpc_bl_get_brightness, | ||
457 | .update_status = cmpc_bl_update_status | ||
458 | }; | ||
459 | |||
460 | static int cmpc_bl_add(struct acpi_device *acpi) | ||
461 | { | ||
462 | struct backlight_device *bd; | ||
463 | |||
464 | bd = backlight_device_register("cmpc_bl", &acpi->dev, | ||
465 | acpi->handle, &cmpc_bl_ops); | ||
466 | bd->props.max_brightness = 7; | ||
467 | dev_set_drvdata(&acpi->dev, bd); | ||
468 | return 0; | ||
469 | } | ||
470 | |||
471 | static int cmpc_bl_remove(struct acpi_device *acpi, int type) | ||
472 | { | ||
473 | struct backlight_device *bd; | ||
474 | |||
475 | bd = dev_get_drvdata(&acpi->dev); | ||
476 | backlight_device_unregister(bd); | ||
477 | return 0; | ||
478 | } | ||
479 | |||
480 | static const struct acpi_device_id cmpc_device_ids[] = { | ||
481 | {"IPML200", 0}, | ||
482 | {"", 0} | ||
483 | }; | ||
484 | MODULE_DEVICE_TABLE(acpi, cmpc_device_ids); | ||
485 | |||
486 | static struct acpi_driver cmpc_bl_acpi_driver = { | ||
487 | .owner = THIS_MODULE, | ||
488 | .name = "cmpc", | ||
489 | .class = "cmpc", | ||
490 | .ids = cmpc_device_ids, | ||
491 | .ops = { | ||
492 | .add = cmpc_bl_add, | ||
493 | .remove = cmpc_bl_remove | ||
494 | } | ||
495 | }; | ||
496 | |||
497 | |||
498 | /* | ||
499 | * Extra keys code. | ||
500 | */ | ||
501 | static int cmpc_keys_codes[] = { | ||
502 | KEY_UNKNOWN, | ||
503 | KEY_WLAN, | ||
504 | KEY_SWITCHVIDEOMODE, | ||
505 | KEY_BRIGHTNESSDOWN, | ||
506 | KEY_BRIGHTNESSUP, | ||
507 | KEY_VENDOR, | ||
508 | KEY_MAX | ||
509 | }; | ||
510 | |||
511 | static void cmpc_keys_handler(struct acpi_device *dev, u32 event) | ||
512 | { | ||
513 | struct input_dev *inputdev; | ||
514 | int code = KEY_MAX; | ||
515 | |||
516 | if ((event & 0x0F) < ARRAY_SIZE(cmpc_keys_codes)) | ||
517 | code = cmpc_keys_codes[event & 0x0F]; | ||
518 | inputdev = dev_get_drvdata(&dev->dev);; | ||
519 | input_report_key(inputdev, code, !(event & 0x10)); | ||
520 | } | ||
521 | |||
522 | static void cmpc_keys_idev_init(struct input_dev *inputdev) | ||
523 | { | ||
524 | int i; | ||
525 | |||
526 | set_bit(EV_KEY, inputdev->evbit); | ||
527 | for (i = 0; cmpc_keys_codes[i] != KEY_MAX; i++) | ||
528 | set_bit(cmpc_keys_codes[i], inputdev->keybit); | ||
529 | } | ||
530 | |||
531 | static int cmpc_keys_add(struct acpi_device *acpi) | ||
532 | { | ||
533 | return cmpc_add_acpi_notify_device(acpi, "cmpc_keys", | ||
534 | cmpc_keys_idev_init); | ||
535 | } | ||
536 | |||
537 | static int cmpc_keys_remove(struct acpi_device *acpi, int type) | ||
538 | { | ||
539 | return cmpc_remove_acpi_notify_device(acpi); | ||
540 | } | ||
541 | |||
542 | static const struct acpi_device_id cmpc_keys_device_ids[] = { | ||
543 | {"FnBT0000", 0}, | ||
544 | {"", 0} | ||
545 | }; | ||
546 | MODULE_DEVICE_TABLE(acpi, cmpc_keys_device_ids); | ||
547 | |||
548 | static struct acpi_driver cmpc_keys_acpi_driver = { | ||
549 | .owner = THIS_MODULE, | ||
550 | .name = "cmpc_keys", | ||
551 | .class = "cmpc_keys", | ||
552 | .ids = cmpc_keys_device_ids, | ||
553 | .ops = { | ||
554 | .add = cmpc_keys_add, | ||
555 | .remove = cmpc_keys_remove, | ||
556 | .notify = cmpc_keys_handler, | ||
557 | } | ||
558 | }; | ||
559 | |||
560 | |||
561 | /* | ||
562 | * General init/exit code. | ||
563 | */ | ||
564 | |||
565 | static int cmpc_init(void) | ||
566 | { | ||
567 | int r; | ||
568 | |||
569 | r = acpi_bus_register_driver(&cmpc_keys_acpi_driver); | ||
570 | if (r) | ||
571 | goto failed_keys; | ||
572 | |||
573 | r = acpi_bus_register_driver(&cmpc_bl_acpi_driver); | ||
574 | if (r) | ||
575 | goto failed_bl; | ||
576 | |||
577 | r = acpi_bus_register_driver(&cmpc_tablet_acpi_driver); | ||
578 | if (r) | ||
579 | goto failed_tablet; | ||
580 | |||
581 | r = acpi_bus_register_driver(&cmpc_accel_acpi_driver); | ||
582 | if (r) | ||
583 | goto failed_accel; | ||
584 | |||
585 | return r; | ||
586 | |||
587 | failed_accel: | ||
588 | acpi_bus_unregister_driver(&cmpc_tablet_acpi_driver); | ||
589 | |||
590 | failed_tablet: | ||
591 | acpi_bus_unregister_driver(&cmpc_bl_acpi_driver); | ||
592 | |||
593 | failed_bl: | ||
594 | acpi_bus_unregister_driver(&cmpc_keys_acpi_driver); | ||
595 | |||
596 | failed_keys: | ||
597 | return r; | ||
598 | } | ||
599 | |||
600 | static void cmpc_exit(void) | ||
601 | { | ||
602 | acpi_bus_unregister_driver(&cmpc_accel_acpi_driver); | ||
603 | acpi_bus_unregister_driver(&cmpc_tablet_acpi_driver); | ||
604 | acpi_bus_unregister_driver(&cmpc_bl_acpi_driver); | ||
605 | acpi_bus_unregister_driver(&cmpc_keys_acpi_driver); | ||
606 | } | ||
607 | |||
608 | module_init(cmpc_init); | ||
609 | module_exit(cmpc_exit); | ||
diff --git a/drivers/platform/x86/dell-wmi.c b/drivers/platform/x86/dell-wmi.c index 67f3fe71c509..1b1dddbd5744 100644 --- a/drivers/platform/x86/dell-wmi.c +++ b/drivers/platform/x86/dell-wmi.c | |||
@@ -202,8 +202,13 @@ static void dell_wmi_notify(u32 value, void *context) | |||
202 | struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL }; | 202 | struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL }; |
203 | static struct key_entry *key; | 203 | static struct key_entry *key; |
204 | union acpi_object *obj; | 204 | union acpi_object *obj; |
205 | acpi_status status; | ||
205 | 206 | ||
206 | wmi_get_event_data(value, &response); | 207 | status = wmi_get_event_data(value, &response); |
208 | if (status != AE_OK) { | ||
209 | printk(KERN_INFO "dell-wmi: bad event status 0x%x\n", status); | ||
210 | return; | ||
211 | } | ||
207 | 212 | ||
208 | obj = (union acpi_object *)response.pointer; | 213 | obj = (union acpi_object *)response.pointer; |
209 | 214 | ||
@@ -238,6 +243,7 @@ static void dell_wmi_notify(u32 value, void *context) | |||
238 | input_sync(dell_wmi_input_dev); | 243 | input_sync(dell_wmi_input_dev); |
239 | } | 244 | } |
240 | } | 245 | } |
246 | kfree(obj); | ||
241 | } | 247 | } |
242 | 248 | ||
243 | 249 | ||
@@ -322,39 +328,37 @@ static int __init dell_wmi_input_setup(void) | |||
322 | static int __init dell_wmi_init(void) | 328 | static int __init dell_wmi_init(void) |
323 | { | 329 | { |
324 | int err; | 330 | int err; |
331 | acpi_status status; | ||
325 | 332 | ||
326 | if (wmi_has_guid(DELL_EVENT_GUID)) { | 333 | if (!wmi_has_guid(DELL_EVENT_GUID)) { |
327 | 334 | printk(KERN_WARNING "dell-wmi: No known WMI GUID found\n"); | |
328 | dmi_walk(find_hk_type, NULL); | 335 | return -ENODEV; |
329 | 336 | } | |
330 | err = dell_wmi_input_setup(); | ||
331 | |||
332 | if (err) | ||
333 | return err; | ||
334 | 337 | ||
335 | err = wmi_install_notify_handler(DELL_EVENT_GUID, | 338 | dmi_walk(find_hk_type, NULL); |
336 | dell_wmi_notify, NULL); | 339 | acpi_video = acpi_video_backlight_support(); |
337 | if (err) { | ||
338 | input_unregister_device(dell_wmi_input_dev); | ||
339 | printk(KERN_ERR "dell-wmi: Unable to register" | ||
340 | " notify handler - %d\n", err); | ||
341 | return err; | ||
342 | } | ||
343 | 340 | ||
344 | acpi_video = acpi_video_backlight_support(); | 341 | err = dell_wmi_input_setup(); |
342 | if (err) | ||
343 | return err; | ||
345 | 344 | ||
346 | } else | 345 | status = wmi_install_notify_handler(DELL_EVENT_GUID, |
347 | printk(KERN_WARNING "dell-wmi: No known WMI GUID found\n"); | 346 | dell_wmi_notify, NULL); |
347 | if (ACPI_FAILURE(status)) { | ||
348 | input_unregister_device(dell_wmi_input_dev); | ||
349 | printk(KERN_ERR | ||
350 | "dell-wmi: Unable to register notify handler - %d\n", | ||
351 | status); | ||
352 | return -ENODEV; | ||
353 | } | ||
348 | 354 | ||
349 | return 0; | 355 | return 0; |
350 | } | 356 | } |
351 | 357 | ||
352 | static void __exit dell_wmi_exit(void) | 358 | static void __exit dell_wmi_exit(void) |
353 | { | 359 | { |
354 | if (wmi_has_guid(DELL_EVENT_GUID)) { | 360 | wmi_remove_notify_handler(DELL_EVENT_GUID); |
355 | wmi_remove_notify_handler(DELL_EVENT_GUID); | 361 | input_unregister_device(dell_wmi_input_dev); |
356 | input_unregister_device(dell_wmi_input_dev); | ||
357 | } | ||
358 | } | 362 | } |
359 | 363 | ||
360 | module_init(dell_wmi_init); | 364 | module_init(dell_wmi_init); |
diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c index bcd4ba8be7db..5f3320d468f6 100644 --- a/drivers/platform/x86/fujitsu-laptop.c +++ b/drivers/platform/x86/fujitsu-laptop.c | |||
@@ -164,7 +164,7 @@ struct fujitsu_hotkey_t { | |||
164 | struct input_dev *input; | 164 | struct input_dev *input; |
165 | char phys[32]; | 165 | char phys[32]; |
166 | struct platform_device *pf_device; | 166 | struct platform_device *pf_device; |
167 | struct kfifo *fifo; | 167 | struct kfifo fifo; |
168 | spinlock_t fifo_lock; | 168 | spinlock_t fifo_lock; |
169 | int rfkill_supported; | 169 | int rfkill_supported; |
170 | int rfkill_state; | 170 | int rfkill_state; |
@@ -376,8 +376,8 @@ static int get_lcd_level(void) | |||
376 | 376 | ||
377 | status = | 377 | status = |
378 | acpi_evaluate_integer(fujitsu->acpi_handle, "GBLL", NULL, &state); | 378 | acpi_evaluate_integer(fujitsu->acpi_handle, "GBLL", NULL, &state); |
379 | if (status < 0) | 379 | if (ACPI_FAILURE(status)) |
380 | return status; | 380 | return 0; |
381 | 381 | ||
382 | fujitsu->brightness_level = state & 0x0fffffff; | 382 | fujitsu->brightness_level = state & 0x0fffffff; |
383 | 383 | ||
@@ -398,8 +398,8 @@ static int get_max_brightness(void) | |||
398 | 398 | ||
399 | status = | 399 | status = |
400 | acpi_evaluate_integer(fujitsu->acpi_handle, "RBLL", NULL, &state); | 400 | acpi_evaluate_integer(fujitsu->acpi_handle, "RBLL", NULL, &state); |
401 | if (status < 0) | 401 | if (ACPI_FAILURE(status)) |
402 | return status; | 402 | return -1; |
403 | 403 | ||
404 | fujitsu->max_brightness = state; | 404 | fujitsu->max_brightness = state; |
405 | 405 | ||
@@ -824,12 +824,10 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device) | |||
824 | 824 | ||
825 | /* kfifo */ | 825 | /* kfifo */ |
826 | spin_lock_init(&fujitsu_hotkey->fifo_lock); | 826 | spin_lock_init(&fujitsu_hotkey->fifo_lock); |
827 | fujitsu_hotkey->fifo = | 827 | error = kfifo_alloc(&fujitsu_hotkey->fifo, RINGBUFFERSIZE * sizeof(int), |
828 | kfifo_alloc(RINGBUFFERSIZE * sizeof(int), GFP_KERNEL, | 828 | GFP_KERNEL); |
829 | &fujitsu_hotkey->fifo_lock); | 829 | if (error) { |
830 | if (IS_ERR(fujitsu_hotkey->fifo)) { | ||
831 | printk(KERN_ERR "kfifo_alloc failed\n"); | 830 | printk(KERN_ERR "kfifo_alloc failed\n"); |
832 | error = PTR_ERR(fujitsu_hotkey->fifo); | ||
833 | goto err_stop; | 831 | goto err_stop; |
834 | } | 832 | } |
835 | 833 | ||
@@ -934,7 +932,7 @@ err_unregister_input_dev: | |||
934 | err_free_input_dev: | 932 | err_free_input_dev: |
935 | input_free_device(input); | 933 | input_free_device(input); |
936 | err_free_fifo: | 934 | err_free_fifo: |
937 | kfifo_free(fujitsu_hotkey->fifo); | 935 | kfifo_free(&fujitsu_hotkey->fifo); |
938 | err_stop: | 936 | err_stop: |
939 | return result; | 937 | return result; |
940 | } | 938 | } |
@@ -956,7 +954,7 @@ static int acpi_fujitsu_hotkey_remove(struct acpi_device *device, int type) | |||
956 | 954 | ||
957 | input_free_device(input); | 955 | input_free_device(input); |
958 | 956 | ||
959 | kfifo_free(fujitsu_hotkey->fifo); | 957 | kfifo_free(&fujitsu_hotkey->fifo); |
960 | 958 | ||
961 | fujitsu_hotkey->acpi_handle = NULL; | 959 | fujitsu_hotkey->acpi_handle = NULL; |
962 | 960 | ||
@@ -1008,9 +1006,10 @@ static void acpi_fujitsu_hotkey_notify(struct acpi_device *device, u32 event) | |||
1008 | vdbg_printk(FUJLAPTOP_DBG_TRACE, | 1006 | vdbg_printk(FUJLAPTOP_DBG_TRACE, |
1009 | "Push keycode into ringbuffer [%d]\n", | 1007 | "Push keycode into ringbuffer [%d]\n", |
1010 | keycode); | 1008 | keycode); |
1011 | status = kfifo_put(fujitsu_hotkey->fifo, | 1009 | status = kfifo_in_locked(&fujitsu_hotkey->fifo, |
1012 | (unsigned char *)&keycode, | 1010 | (unsigned char *)&keycode, |
1013 | sizeof(keycode)); | 1011 | sizeof(keycode), |
1012 | &fujitsu_hotkey->fifo_lock); | ||
1014 | if (status != sizeof(keycode)) { | 1013 | if (status != sizeof(keycode)) { |
1015 | vdbg_printk(FUJLAPTOP_DBG_WARN, | 1014 | vdbg_printk(FUJLAPTOP_DBG_WARN, |
1016 | "Could not push keycode [0x%x]\n", | 1015 | "Could not push keycode [0x%x]\n", |
@@ -1021,11 +1020,12 @@ static void acpi_fujitsu_hotkey_notify(struct acpi_device *device, u32 event) | |||
1021 | } | 1020 | } |
1022 | } else if (keycode == 0) { | 1021 | } else if (keycode == 0) { |
1023 | while ((status = | 1022 | while ((status = |
1024 | kfifo_get | 1023 | kfifo_out_locked( |
1025 | (fujitsu_hotkey->fifo, (unsigned char *) | 1024 | &fujitsu_hotkey->fifo, |
1026 | &keycode_r, | 1025 | (unsigned char *) &keycode_r, |
1027 | sizeof | 1026 | sizeof(keycode_r), |
1028 | (keycode_r))) == sizeof(keycode_r)) { | 1027 | &fujitsu_hotkey->fifo_lock)) |
1028 | == sizeof(keycode_r)) { | ||
1029 | input_report_key(input, keycode_r, 0); | 1029 | input_report_key(input, keycode_r, 0); |
1030 | input_sync(input); | 1030 | input_sync(input); |
1031 | vdbg_printk(FUJLAPTOP_DBG_TRACE, | 1031 | vdbg_printk(FUJLAPTOP_DBG_TRACE, |
diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c index 63c3e658a884..5b648f0c6075 100644 --- a/drivers/platform/x86/hp-wmi.c +++ b/drivers/platform/x86/hp-wmi.c | |||
@@ -134,10 +134,15 @@ static int hp_wmi_perform_query(int query, int write, int value) | |||
134 | 134 | ||
135 | obj = output.pointer; | 135 | obj = output.pointer; |
136 | 136 | ||
137 | if (!obj || obj->type != ACPI_TYPE_BUFFER) | 137 | if (!obj) |
138 | return -EINVAL; | 138 | return -EINVAL; |
139 | else if (obj->type != ACPI_TYPE_BUFFER) { | ||
140 | kfree(obj); | ||
141 | return -EINVAL; | ||
142 | } | ||
139 | 143 | ||
140 | bios_return = *((struct bios_return *)obj->buffer.pointer); | 144 | bios_return = *((struct bios_return *)obj->buffer.pointer); |
145 | kfree(obj); | ||
141 | if (bios_return.return_code > 0) | 146 | if (bios_return.return_code > 0) |
142 | return bios_return.return_code * -1; | 147 | return bios_return.return_code * -1; |
143 | else | 148 | else |
@@ -333,17 +338,24 @@ static void hp_wmi_notify(u32 value, void *context) | |||
333 | static struct key_entry *key; | 338 | static struct key_entry *key; |
334 | union acpi_object *obj; | 339 | union acpi_object *obj; |
335 | int eventcode; | 340 | int eventcode; |
341 | acpi_status status; | ||
336 | 342 | ||
337 | wmi_get_event_data(value, &response); | 343 | status = wmi_get_event_data(value, &response); |
344 | if (status != AE_OK) { | ||
345 | printk(KERN_INFO "hp-wmi: bad event status 0x%x\n", status); | ||
346 | return; | ||
347 | } | ||
338 | 348 | ||
339 | obj = (union acpi_object *)response.pointer; | 349 | obj = (union acpi_object *)response.pointer; |
340 | 350 | ||
341 | if (!obj || obj->type != ACPI_TYPE_BUFFER || obj->buffer.length != 8) { | 351 | if (!obj || obj->type != ACPI_TYPE_BUFFER || obj->buffer.length != 8) { |
342 | printk(KERN_INFO "HP WMI: Unknown response received\n"); | 352 | printk(KERN_INFO "HP WMI: Unknown response received\n"); |
353 | kfree(obj); | ||
343 | return; | 354 | return; |
344 | } | 355 | } |
345 | 356 | ||
346 | eventcode = *((u8 *) obj->buffer.pointer); | 357 | eventcode = *((u8 *) obj->buffer.pointer); |
358 | kfree(obj); | ||
347 | if (eventcode == 0x4) | 359 | if (eventcode == 0x4) |
348 | eventcode = hp_wmi_perform_query(HPWMI_HOTKEY_QUERY, 0, | 360 | eventcode = hp_wmi_perform_query(HPWMI_HOTKEY_QUERY, 0, |
349 | 0); | 361 | 0); |
@@ -381,6 +393,8 @@ static void hp_wmi_notify(u32 value, void *context) | |||
381 | } else | 393 | } else |
382 | printk(KERN_INFO "HP WMI: Unknown key pressed - %x\n", | 394 | printk(KERN_INFO "HP WMI: Unknown key pressed - %x\n", |
383 | eventcode); | 395 | eventcode); |
396 | |||
397 | kfree(obj); | ||
384 | } | 398 | } |
385 | 399 | ||
386 | static int __init hp_wmi_input_setup(void) | 400 | static int __init hp_wmi_input_setup(void) |
@@ -572,7 +586,7 @@ static int __init hp_wmi_init(void) | |||
572 | if (wmi_has_guid(HPWMI_EVENT_GUID)) { | 586 | if (wmi_has_guid(HPWMI_EVENT_GUID)) { |
573 | err = wmi_install_notify_handler(HPWMI_EVENT_GUID, | 587 | err = wmi_install_notify_handler(HPWMI_EVENT_GUID, |
574 | hp_wmi_notify, NULL); | 588 | hp_wmi_notify, NULL); |
575 | if (!err) | 589 | if (ACPI_SUCCESS(err)) |
576 | hp_wmi_input_setup(); | 590 | hp_wmi_input_setup(); |
577 | } | 591 | } |
578 | 592 | ||
diff --git a/drivers/platform/x86/msi-wmi.c b/drivers/platform/x86/msi-wmi.c index 0c8fe145c4af..f5f70d4c6913 100644 --- a/drivers/platform/x86/msi-wmi.c +++ b/drivers/platform/x86/msi-wmi.c | |||
@@ -34,16 +34,6 @@ MODULE_LICENSE("GPL"); | |||
34 | MODULE_ALIAS("wmi:551A1F84-FBDD-4125-91DB-3EA8F44F1D45"); | 34 | MODULE_ALIAS("wmi:551A1F84-FBDD-4125-91DB-3EA8F44F1D45"); |
35 | MODULE_ALIAS("wmi:B6F3EEF2-3D2F-49DC-9DE3-85BCE18C62F2"); | 35 | MODULE_ALIAS("wmi:B6F3EEF2-3D2F-49DC-9DE3-85BCE18C62F2"); |
36 | 36 | ||
37 | /* Temporary workaround until the WMI sysfs interface goes in | ||
38 | { "svn", DMI_SYS_VENDOR }, | ||
39 | { "pn", DMI_PRODUCT_NAME }, | ||
40 | { "pvr", DMI_PRODUCT_VERSION }, | ||
41 | { "rvn", DMI_BOARD_VENDOR }, | ||
42 | { "rn", DMI_BOARD_NAME }, | ||
43 | */ | ||
44 | |||
45 | MODULE_ALIAS("dmi:*:svnMICRO-STARINTERNATIONAL*:pnMS-6638:*"); | ||
46 | |||
47 | #define DRV_NAME "msi-wmi" | 37 | #define DRV_NAME "msi-wmi" |
48 | #define DRV_PFX DRV_NAME ": " | 38 | #define DRV_PFX DRV_NAME ": " |
49 | 39 | ||
@@ -159,8 +149,13 @@ static void msi_wmi_notify(u32 value, void *context) | |||
159 | static struct key_entry *key; | 149 | static struct key_entry *key; |
160 | union acpi_object *obj; | 150 | union acpi_object *obj; |
161 | ktime_t cur; | 151 | ktime_t cur; |
152 | acpi_status status; | ||
162 | 153 | ||
163 | wmi_get_event_data(value, &response); | 154 | status = wmi_get_event_data(value, &response); |
155 | if (status != AE_OK) { | ||
156 | printk(KERN_INFO DRV_PFX "bad event status 0x%x\n", status); | ||
157 | return; | ||
158 | } | ||
164 | 159 | ||
165 | obj = (union acpi_object *)response.pointer; | 160 | obj = (union acpi_object *)response.pointer; |
166 | 161 | ||
@@ -246,7 +241,7 @@ static int __init msi_wmi_init(void) | |||
246 | } | 241 | } |
247 | err = wmi_install_notify_handler(MSIWMI_EVENT_GUID, | 242 | err = wmi_install_notify_handler(MSIWMI_EVENT_GUID, |
248 | msi_wmi_notify, NULL); | 243 | msi_wmi_notify, NULL); |
249 | if (err) | 244 | if (ACPI_FAILURE(err)) |
250 | return -EINVAL; | 245 | return -EINVAL; |
251 | 246 | ||
252 | err = msi_wmi_input_setup(); | 247 | err = msi_wmi_input_setup(); |
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index 7a2cc8a5c975..5af53340da6f 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c | |||
@@ -131,6 +131,7 @@ enum sony_nc_rfkill { | |||
131 | N_SONY_RFKILL, | 131 | N_SONY_RFKILL, |
132 | }; | 132 | }; |
133 | 133 | ||
134 | static int sony_rfkill_handle; | ||
134 | static struct rfkill *sony_rfkill_devices[N_SONY_RFKILL]; | 135 | static struct rfkill *sony_rfkill_devices[N_SONY_RFKILL]; |
135 | static int sony_rfkill_address[N_SONY_RFKILL] = {0x300, 0x500, 0x700, 0x900}; | 136 | static int sony_rfkill_address[N_SONY_RFKILL] = {0x300, 0x500, 0x700, 0x900}; |
136 | static void sony_nc_rfkill_update(void); | 137 | static void sony_nc_rfkill_update(void); |
@@ -142,7 +143,7 @@ struct sony_laptop_input_s { | |||
142 | atomic_t users; | 143 | atomic_t users; |
143 | struct input_dev *jog_dev; | 144 | struct input_dev *jog_dev; |
144 | struct input_dev *key_dev; | 145 | struct input_dev *key_dev; |
145 | struct kfifo *fifo; | 146 | struct kfifo fifo; |
146 | spinlock_t fifo_lock; | 147 | spinlock_t fifo_lock; |
147 | struct workqueue_struct *wq; | 148 | struct workqueue_struct *wq; |
148 | }; | 149 | }; |
@@ -232,6 +233,7 @@ static int sony_laptop_input_index[] = { | |||
232 | 56, /* 69 SONYPI_EVENT_VOLUME_INC_PRESSED */ | 233 | 56, /* 69 SONYPI_EVENT_VOLUME_INC_PRESSED */ |
233 | 57, /* 70 SONYPI_EVENT_VOLUME_DEC_PRESSED */ | 234 | 57, /* 70 SONYPI_EVENT_VOLUME_DEC_PRESSED */ |
234 | -1, /* 71 SONYPI_EVENT_BRIGHTNESS_PRESSED */ | 235 | -1, /* 71 SONYPI_EVENT_BRIGHTNESS_PRESSED */ |
236 | 58, /* 72 SONYPI_EVENT_MEDIA_PRESSED */ | ||
235 | }; | 237 | }; |
236 | 238 | ||
237 | static int sony_laptop_input_keycode_map[] = { | 239 | static int sony_laptop_input_keycode_map[] = { |
@@ -293,6 +295,7 @@ static int sony_laptop_input_keycode_map[] = { | |||
293 | KEY_F15, /* 55 SONYPI_EVENT_SETTINGKEY_PRESSED */ | 295 | KEY_F15, /* 55 SONYPI_EVENT_SETTINGKEY_PRESSED */ |
294 | KEY_VOLUMEUP, /* 56 SONYPI_EVENT_VOLUME_INC_PRESSED */ | 296 | KEY_VOLUMEUP, /* 56 SONYPI_EVENT_VOLUME_INC_PRESSED */ |
295 | KEY_VOLUMEDOWN, /* 57 SONYPI_EVENT_VOLUME_DEC_PRESSED */ | 297 | KEY_VOLUMEDOWN, /* 57 SONYPI_EVENT_VOLUME_DEC_PRESSED */ |
298 | KEY_MEDIA, /* 58 SONYPI_EVENT_MEDIA_PRESSED */ | ||
296 | }; | 299 | }; |
297 | 300 | ||
298 | /* release buttons after a short delay if pressed */ | 301 | /* release buttons after a short delay if pressed */ |
@@ -300,8 +303,9 @@ static void do_sony_laptop_release_key(struct work_struct *work) | |||
300 | { | 303 | { |
301 | struct sony_laptop_keypress kp; | 304 | struct sony_laptop_keypress kp; |
302 | 305 | ||
303 | while (kfifo_get(sony_laptop_input.fifo, (unsigned char *)&kp, | 306 | while (kfifo_out_locked(&sony_laptop_input.fifo, (unsigned char *)&kp, |
304 | sizeof(kp)) == sizeof(kp)) { | 307 | sizeof(kp), &sony_laptop_input.fifo_lock) |
308 | == sizeof(kp)) { | ||
305 | msleep(10); | 309 | msleep(10); |
306 | input_report_key(kp.dev, kp.key, 0); | 310 | input_report_key(kp.dev, kp.key, 0); |
307 | input_sync(kp.dev); | 311 | input_sync(kp.dev); |
@@ -362,8 +366,9 @@ static void sony_laptop_report_input_event(u8 event) | |||
362 | /* we emit the scancode so we can always remap the key */ | 366 | /* we emit the scancode so we can always remap the key */ |
363 | input_event(kp.dev, EV_MSC, MSC_SCAN, event); | 367 | input_event(kp.dev, EV_MSC, MSC_SCAN, event); |
364 | input_sync(kp.dev); | 368 | input_sync(kp.dev); |
365 | kfifo_put(sony_laptop_input.fifo, | 369 | kfifo_in_locked(&sony_laptop_input.fifo, |
366 | (unsigned char *)&kp, sizeof(kp)); | 370 | (unsigned char *)&kp, sizeof(kp), |
371 | &sony_laptop_input.fifo_lock); | ||
367 | 372 | ||
368 | if (!work_pending(&sony_laptop_release_key_work)) | 373 | if (!work_pending(&sony_laptop_release_key_work)) |
369 | queue_work(sony_laptop_input.wq, | 374 | queue_work(sony_laptop_input.wq, |
@@ -385,12 +390,10 @@ static int sony_laptop_setup_input(struct acpi_device *acpi_device) | |||
385 | 390 | ||
386 | /* kfifo */ | 391 | /* kfifo */ |
387 | spin_lock_init(&sony_laptop_input.fifo_lock); | 392 | spin_lock_init(&sony_laptop_input.fifo_lock); |
388 | sony_laptop_input.fifo = | 393 | error = |
389 | kfifo_alloc(SONY_LAPTOP_BUF_SIZE, GFP_KERNEL, | 394 | kfifo_alloc(&sony_laptop_input.fifo, SONY_LAPTOP_BUF_SIZE, GFP_KERNEL); |
390 | &sony_laptop_input.fifo_lock); | 395 | if (error) { |
391 | if (IS_ERR(sony_laptop_input.fifo)) { | ||
392 | printk(KERN_ERR DRV_PFX "kfifo_alloc failed\n"); | 396 | printk(KERN_ERR DRV_PFX "kfifo_alloc failed\n"); |
393 | error = PTR_ERR(sony_laptop_input.fifo); | ||
394 | goto err_dec_users; | 397 | goto err_dec_users; |
395 | } | 398 | } |
396 | 399 | ||
@@ -474,7 +477,7 @@ err_destroy_wq: | |||
474 | destroy_workqueue(sony_laptop_input.wq); | 477 | destroy_workqueue(sony_laptop_input.wq); |
475 | 478 | ||
476 | err_free_kfifo: | 479 | err_free_kfifo: |
477 | kfifo_free(sony_laptop_input.fifo); | 480 | kfifo_free(&sony_laptop_input.fifo); |
478 | 481 | ||
479 | err_dec_users: | 482 | err_dec_users: |
480 | atomic_dec(&sony_laptop_input.users); | 483 | atomic_dec(&sony_laptop_input.users); |
@@ -500,7 +503,7 @@ static void sony_laptop_remove_input(void) | |||
500 | } | 503 | } |
501 | 504 | ||
502 | destroy_workqueue(sony_laptop_input.wq); | 505 | destroy_workqueue(sony_laptop_input.wq); |
503 | kfifo_free(sony_laptop_input.fifo); | 506 | kfifo_free(&sony_laptop_input.fifo); |
504 | } | 507 | } |
505 | 508 | ||
506 | /*********** Platform Device ***********/ | 509 | /*********** Platform Device ***********/ |
@@ -890,6 +893,8 @@ static struct sony_nc_event sony_100_events[] = { | |||
890 | { 0x0C, SONYPI_EVENT_FNKEY_RELEASED }, | 893 | { 0x0C, SONYPI_EVENT_FNKEY_RELEASED }, |
891 | { 0x9f, SONYPI_EVENT_CD_EJECT_PRESSED }, | 894 | { 0x9f, SONYPI_EVENT_CD_EJECT_PRESSED }, |
892 | { 0x1f, SONYPI_EVENT_ANYBUTTON_RELEASED }, | 895 | { 0x1f, SONYPI_EVENT_ANYBUTTON_RELEASED }, |
896 | { 0xa1, SONYPI_EVENT_MEDIA_PRESSED }, | ||
897 | { 0x21, SONYPI_EVENT_ANYBUTTON_RELEASED }, | ||
893 | { 0, 0 }, | 898 | { 0, 0 }, |
894 | }; | 899 | }; |
895 | 900 | ||
@@ -961,7 +966,7 @@ static void sony_nc_notify(struct acpi_device *device, u32 event) | |||
961 | else | 966 | else |
962 | sony_laptop_report_input_event(ev); | 967 | sony_laptop_report_input_event(ev); |
963 | } | 968 | } |
964 | } else if (sony_find_snc_handle(0x124) == ev) { | 969 | } else if (sony_find_snc_handle(sony_rfkill_handle) == ev) { |
965 | sony_nc_rfkill_update(); | 970 | sony_nc_rfkill_update(); |
966 | return; | 971 | return; |
967 | } | 972 | } |
@@ -1067,7 +1072,7 @@ static int sony_nc_rfkill_set(void *data, bool blocked) | |||
1067 | if (!blocked) | 1072 | if (!blocked) |
1068 | argument |= 0xff0000; | 1073 | argument |= 0xff0000; |
1069 | 1074 | ||
1070 | return sony_call_snc_handle(0x124, argument, &result); | 1075 | return sony_call_snc_handle(sony_rfkill_handle, argument, &result); |
1071 | } | 1076 | } |
1072 | 1077 | ||
1073 | static const struct rfkill_ops sony_rfkill_ops = { | 1078 | static const struct rfkill_ops sony_rfkill_ops = { |
@@ -1110,7 +1115,7 @@ static int sony_nc_setup_rfkill(struct acpi_device *device, | |||
1110 | if (!rfk) | 1115 | if (!rfk) |
1111 | return -ENOMEM; | 1116 | return -ENOMEM; |
1112 | 1117 | ||
1113 | sony_call_snc_handle(0x124, 0x200, &result); | 1118 | sony_call_snc_handle(sony_rfkill_handle, 0x200, &result); |
1114 | hwblock = !(result & 0x1); | 1119 | hwblock = !(result & 0x1); |
1115 | rfkill_set_hw_state(rfk, hwblock); | 1120 | rfkill_set_hw_state(rfk, hwblock); |
1116 | 1121 | ||
@@ -1129,7 +1134,7 @@ static void sony_nc_rfkill_update() | |||
1129 | int result; | 1134 | int result; |
1130 | bool hwblock; | 1135 | bool hwblock; |
1131 | 1136 | ||
1132 | sony_call_snc_handle(0x124, 0x200, &result); | 1137 | sony_call_snc_handle(sony_rfkill_handle, 0x200, &result); |
1133 | hwblock = !(result & 0x1); | 1138 | hwblock = !(result & 0x1); |
1134 | 1139 | ||
1135 | for (i = 0; i < N_SONY_RFKILL; i++) { | 1140 | for (i = 0; i < N_SONY_RFKILL; i++) { |
@@ -1145,36 +1150,79 @@ static void sony_nc_rfkill_update() | |||
1145 | continue; | 1150 | continue; |
1146 | } | 1151 | } |
1147 | 1152 | ||
1148 | sony_call_snc_handle(0x124, argument, &result); | 1153 | sony_call_snc_handle(sony_rfkill_handle, argument, &result); |
1149 | rfkill_set_states(sony_rfkill_devices[i], | 1154 | rfkill_set_states(sony_rfkill_devices[i], |
1150 | !(result & 0xf), false); | 1155 | !(result & 0xf), false); |
1151 | } | 1156 | } |
1152 | } | 1157 | } |
1153 | 1158 | ||
1154 | static int sony_nc_rfkill_setup(struct acpi_device *device) | 1159 | static void sony_nc_rfkill_setup(struct acpi_device *device) |
1155 | { | 1160 | { |
1156 | int result, ret; | 1161 | int offset; |
1162 | u8 dev_code, i; | ||
1163 | acpi_status status; | ||
1164 | struct acpi_object_list params; | ||
1165 | union acpi_object in_obj; | ||
1166 | union acpi_object *device_enum; | ||
1167 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
1157 | 1168 | ||
1158 | if (sony_find_snc_handle(0x124) == -1) | 1169 | offset = sony_find_snc_handle(0x124); |
1159 | return -1; | 1170 | if (offset == -1) { |
1171 | offset = sony_find_snc_handle(0x135); | ||
1172 | if (offset == -1) | ||
1173 | return; | ||
1174 | else | ||
1175 | sony_rfkill_handle = 0x135; | ||
1176 | } else | ||
1177 | sony_rfkill_handle = 0x124; | ||
1178 | dprintk("Found rkfill handle: 0x%.4x\n", sony_rfkill_handle); | ||
1160 | 1179 | ||
1161 | ret = sony_call_snc_handle(0x124, 0xb00, &result); | 1180 | /* need to read the whole buffer returned by the acpi call to SN06 |
1162 | if (ret) { | 1181 | * here otherwise we may miss some features |
1163 | printk(KERN_INFO DRV_PFX | 1182 | */ |
1164 | "Unable to enumerate rfkill devices: %x\n", ret); | 1183 | params.count = 1; |
1165 | return ret; | 1184 | params.pointer = &in_obj; |
1185 | in_obj.type = ACPI_TYPE_INTEGER; | ||
1186 | in_obj.integer.value = offset; | ||
1187 | status = acpi_evaluate_object(sony_nc_acpi_handle, "SN06", ¶ms, | ||
1188 | &buffer); | ||
1189 | if (ACPI_FAILURE(status)) { | ||
1190 | dprintk("Radio device enumeration failed\n"); | ||
1191 | return; | ||
1192 | } | ||
1193 | |||
1194 | device_enum = (union acpi_object *) buffer.pointer; | ||
1195 | if (!device_enum || device_enum->type != ACPI_TYPE_BUFFER) { | ||
1196 | printk(KERN_ERR "Invalid SN06 return object 0x%.2x\n", | ||
1197 | device_enum->type); | ||
1198 | goto out_no_enum; | ||
1166 | } | 1199 | } |
1167 | 1200 | ||
1168 | if (result & 0x1) | 1201 | /* the buffer is filled with magic numbers describing the devices |
1169 | sony_nc_setup_rfkill(device, SONY_WIFI); | 1202 | * available, 0xff terminates the enumeration |
1170 | if (result & 0x2) | 1203 | */ |
1171 | sony_nc_setup_rfkill(device, SONY_BLUETOOTH); | 1204 | while ((dev_code = *(device_enum->buffer.pointer + i)) != 0xff && |
1172 | if (result & 0x1c) | 1205 | i < device_enum->buffer.length) { |
1173 | sony_nc_setup_rfkill(device, SONY_WWAN); | 1206 | i++; |
1174 | if (result & 0x20) | 1207 | dprintk("Radio devices, looking at 0x%.2x\n", dev_code); |
1175 | sony_nc_setup_rfkill(device, SONY_WIMAX); | ||
1176 | 1208 | ||
1177 | return 0; | 1209 | if (dev_code == 0 && !sony_rfkill_devices[SONY_WIFI]) |
1210 | sony_nc_setup_rfkill(device, SONY_WIFI); | ||
1211 | |||
1212 | if (dev_code == 0x10 && !sony_rfkill_devices[SONY_BLUETOOTH]) | ||
1213 | sony_nc_setup_rfkill(device, SONY_BLUETOOTH); | ||
1214 | |||
1215 | if ((0xf0 & dev_code) == 0x20 && | ||
1216 | !sony_rfkill_devices[SONY_WWAN]) | ||
1217 | sony_nc_setup_rfkill(device, SONY_WWAN); | ||
1218 | |||
1219 | if (dev_code == 0x30 && !sony_rfkill_devices[SONY_WIMAX]) | ||
1220 | sony_nc_setup_rfkill(device, SONY_WIMAX); | ||
1221 | } | ||
1222 | |||
1223 | out_no_enum: | ||
1224 | kfree(buffer.pointer); | ||
1225 | return; | ||
1178 | } | 1226 | } |
1179 | 1227 | ||
1180 | static int sony_nc_add(struct acpi_device *device) | 1228 | static int sony_nc_add(struct acpi_device *device) |
@@ -2079,7 +2127,7 @@ static struct attribute_group spic_attribute_group = { | |||
2079 | 2127 | ||
2080 | struct sonypi_compat_s { | 2128 | struct sonypi_compat_s { |
2081 | struct fasync_struct *fifo_async; | 2129 | struct fasync_struct *fifo_async; |
2082 | struct kfifo *fifo; | 2130 | struct kfifo fifo; |
2083 | spinlock_t fifo_lock; | 2131 | spinlock_t fifo_lock; |
2084 | wait_queue_head_t fifo_proc_list; | 2132 | wait_queue_head_t fifo_proc_list; |
2085 | atomic_t open_count; | 2133 | atomic_t open_count; |
@@ -2104,12 +2152,12 @@ static int sonypi_misc_open(struct inode *inode, struct file *file) | |||
2104 | /* Flush input queue on first open */ | 2152 | /* Flush input queue on first open */ |
2105 | unsigned long flags; | 2153 | unsigned long flags; |
2106 | 2154 | ||
2107 | spin_lock_irqsave(sonypi_compat.fifo->lock, flags); | 2155 | spin_lock_irqsave(&sonypi_compat.fifo_lock, flags); |
2108 | 2156 | ||
2109 | if (atomic_inc_return(&sonypi_compat.open_count) == 1) | 2157 | if (atomic_inc_return(&sonypi_compat.open_count) == 1) |
2110 | __kfifo_reset(sonypi_compat.fifo); | 2158 | kfifo_reset(&sonypi_compat.fifo); |
2111 | 2159 | ||
2112 | spin_unlock_irqrestore(sonypi_compat.fifo->lock, flags); | 2160 | spin_unlock_irqrestore(&sonypi_compat.fifo_lock, flags); |
2113 | 2161 | ||
2114 | return 0; | 2162 | return 0; |
2115 | } | 2163 | } |
@@ -2120,17 +2168,18 @@ static ssize_t sonypi_misc_read(struct file *file, char __user *buf, | |||
2120 | ssize_t ret; | 2168 | ssize_t ret; |
2121 | unsigned char c; | 2169 | unsigned char c; |
2122 | 2170 | ||
2123 | if ((kfifo_len(sonypi_compat.fifo) == 0) && | 2171 | if ((kfifo_len(&sonypi_compat.fifo) == 0) && |
2124 | (file->f_flags & O_NONBLOCK)) | 2172 | (file->f_flags & O_NONBLOCK)) |
2125 | return -EAGAIN; | 2173 | return -EAGAIN; |
2126 | 2174 | ||
2127 | ret = wait_event_interruptible(sonypi_compat.fifo_proc_list, | 2175 | ret = wait_event_interruptible(sonypi_compat.fifo_proc_list, |
2128 | kfifo_len(sonypi_compat.fifo) != 0); | 2176 | kfifo_len(&sonypi_compat.fifo) != 0); |
2129 | if (ret) | 2177 | if (ret) |
2130 | return ret; | 2178 | return ret; |
2131 | 2179 | ||
2132 | while (ret < count && | 2180 | while (ret < count && |
2133 | (kfifo_get(sonypi_compat.fifo, &c, sizeof(c)) == sizeof(c))) { | 2181 | (kfifo_out_locked(&sonypi_compat.fifo, &c, sizeof(c), |
2182 | &sonypi_compat.fifo_lock) == sizeof(c))) { | ||
2134 | if (put_user(c, buf++)) | 2183 | if (put_user(c, buf++)) |
2135 | return -EFAULT; | 2184 | return -EFAULT; |
2136 | ret++; | 2185 | ret++; |
@@ -2147,7 +2196,7 @@ static ssize_t sonypi_misc_read(struct file *file, char __user *buf, | |||
2147 | static unsigned int sonypi_misc_poll(struct file *file, poll_table *wait) | 2196 | static unsigned int sonypi_misc_poll(struct file *file, poll_table *wait) |
2148 | { | 2197 | { |
2149 | poll_wait(file, &sonypi_compat.fifo_proc_list, wait); | 2198 | poll_wait(file, &sonypi_compat.fifo_proc_list, wait); |
2150 | if (kfifo_len(sonypi_compat.fifo)) | 2199 | if (kfifo_len(&sonypi_compat.fifo)) |
2151 | return POLLIN | POLLRDNORM; | 2200 | return POLLIN | POLLRDNORM; |
2152 | return 0; | 2201 | return 0; |
2153 | } | 2202 | } |
@@ -2309,7 +2358,8 @@ static struct miscdevice sonypi_misc_device = { | |||
2309 | 2358 | ||
2310 | static void sonypi_compat_report_event(u8 event) | 2359 | static void sonypi_compat_report_event(u8 event) |
2311 | { | 2360 | { |
2312 | kfifo_put(sonypi_compat.fifo, (unsigned char *)&event, sizeof(event)); | 2361 | kfifo_in_locked(&sonypi_compat.fifo, (unsigned char *)&event, |
2362 | sizeof(event), &sonypi_compat.fifo_lock); | ||
2313 | kill_fasync(&sonypi_compat.fifo_async, SIGIO, POLL_IN); | 2363 | kill_fasync(&sonypi_compat.fifo_async, SIGIO, POLL_IN); |
2314 | wake_up_interruptible(&sonypi_compat.fifo_proc_list); | 2364 | wake_up_interruptible(&sonypi_compat.fifo_proc_list); |
2315 | } | 2365 | } |
@@ -2319,11 +2369,11 @@ static int sonypi_compat_init(void) | |||
2319 | int error; | 2369 | int error; |
2320 | 2370 | ||
2321 | spin_lock_init(&sonypi_compat.fifo_lock); | 2371 | spin_lock_init(&sonypi_compat.fifo_lock); |
2322 | sonypi_compat.fifo = kfifo_alloc(SONY_LAPTOP_BUF_SIZE, GFP_KERNEL, | 2372 | error = |
2323 | &sonypi_compat.fifo_lock); | 2373 | kfifo_alloc(&sonypi_compat.fifo, SONY_LAPTOP_BUF_SIZE, GFP_KERNEL); |
2324 | if (IS_ERR(sonypi_compat.fifo)) { | 2374 | if (error) { |
2325 | printk(KERN_ERR DRV_PFX "kfifo_alloc failed\n"); | 2375 | printk(KERN_ERR DRV_PFX "kfifo_alloc failed\n"); |
2326 | return PTR_ERR(sonypi_compat.fifo); | 2376 | return error; |
2327 | } | 2377 | } |
2328 | 2378 | ||
2329 | init_waitqueue_head(&sonypi_compat.fifo_proc_list); | 2379 | init_waitqueue_head(&sonypi_compat.fifo_proc_list); |
@@ -2342,14 +2392,14 @@ static int sonypi_compat_init(void) | |||
2342 | return 0; | 2392 | return 0; |
2343 | 2393 | ||
2344 | err_free_kfifo: | 2394 | err_free_kfifo: |
2345 | kfifo_free(sonypi_compat.fifo); | 2395 | kfifo_free(&sonypi_compat.fifo); |
2346 | return error; | 2396 | return error; |
2347 | } | 2397 | } |
2348 | 2398 | ||
2349 | static void sonypi_compat_exit(void) | 2399 | static void sonypi_compat_exit(void) |
2350 | { | 2400 | { |
2351 | misc_deregister(&sonypi_misc_device); | 2401 | misc_deregister(&sonypi_misc_device); |
2352 | kfifo_free(sonypi_compat.fifo); | 2402 | kfifo_free(&sonypi_compat.fifo); |
2353 | } | 2403 | } |
2354 | #else | 2404 | #else |
2355 | static int sonypi_compat_init(void) { return 0; } | 2405 | static int sonypi_compat_init(void) { return 0; } |
diff --git a/drivers/platform/x86/tc1100-wmi.c b/drivers/platform/x86/tc1100-wmi.c index 44166003d4ef..dd33b51c3486 100644 --- a/drivers/platform/x86/tc1100-wmi.c +++ b/drivers/platform/x86/tc1100-wmi.c | |||
@@ -47,22 +47,6 @@ MODULE_DESCRIPTION("HP Compaq TC1100 Tablet WMI Extras"); | |||
47 | MODULE_LICENSE("GPL"); | 47 | MODULE_LICENSE("GPL"); |
48 | MODULE_ALIAS("wmi:C364AC71-36DB-495A-8494-B439D472A505"); | 48 | MODULE_ALIAS("wmi:C364AC71-36DB-495A-8494-B439D472A505"); |
49 | 49 | ||
50 | static int tc1100_probe(struct platform_device *device); | ||
51 | static int tc1100_remove(struct platform_device *device); | ||
52 | static int tc1100_suspend(struct platform_device *device, pm_message_t state); | ||
53 | static int tc1100_resume(struct platform_device *device); | ||
54 | |||
55 | static struct platform_driver tc1100_driver = { | ||
56 | .driver = { | ||
57 | .name = "tc1100-wmi", | ||
58 | .owner = THIS_MODULE, | ||
59 | }, | ||
60 | .probe = tc1100_probe, | ||
61 | .remove = tc1100_remove, | ||
62 | .suspend = tc1100_suspend, | ||
63 | .resume = tc1100_resume, | ||
64 | }; | ||
65 | |||
66 | static struct platform_device *tc1100_device; | 50 | static struct platform_device *tc1100_device; |
67 | 51 | ||
68 | struct tc1100_data { | 52 | struct tc1100_data { |
@@ -183,51 +167,35 @@ static DEVICE_ATTR(value, S_IWUGO | S_IRUGO | S_IWUSR, \ | |||
183 | show_set_bool(wireless, TC1100_INSTANCE_WIRELESS); | 167 | show_set_bool(wireless, TC1100_INSTANCE_WIRELESS); |
184 | show_set_bool(jogdial, TC1100_INSTANCE_JOGDIAL); | 168 | show_set_bool(jogdial, TC1100_INSTANCE_JOGDIAL); |
185 | 169 | ||
186 | static void remove_fs(void) | 170 | static struct attribute *tc1100_attributes[] = { |
187 | { | 171 | &dev_attr_wireless.attr, |
188 | device_remove_file(&tc1100_device->dev, &dev_attr_wireless); | 172 | &dev_attr_jogdial.attr, |
189 | device_remove_file(&tc1100_device->dev, &dev_attr_jogdial); | 173 | NULL |
190 | } | 174 | }; |
191 | |||
192 | static int add_fs(void) | ||
193 | { | ||
194 | int ret; | ||
195 | |||
196 | ret = device_create_file(&tc1100_device->dev, &dev_attr_wireless); | ||
197 | if (ret) | ||
198 | goto add_sysfs_error; | ||
199 | |||
200 | ret = device_create_file(&tc1100_device->dev, &dev_attr_jogdial); | ||
201 | if (ret) | ||
202 | goto add_sysfs_error; | ||
203 | |||
204 | return ret; | ||
205 | 175 | ||
206 | add_sysfs_error: | 176 | static struct attribute_group tc1100_attribute_group = { |
207 | remove_fs(); | 177 | .attrs = tc1100_attributes, |
208 | return ret; | 178 | }; |
209 | } | ||
210 | 179 | ||
211 | /* -------------------------------------------------------------------------- | 180 | /* -------------------------------------------------------------------------- |
212 | Driver Model | 181 | Driver Model |
213 | -------------------------------------------------------------------------- */ | 182 | -------------------------------------------------------------------------- */ |
214 | 183 | ||
215 | static int tc1100_probe(struct platform_device *device) | 184 | static int __init tc1100_probe(struct platform_device *device) |
216 | { | 185 | { |
217 | int result = 0; | 186 | return sysfs_create_group(&device->dev.kobj, &tc1100_attribute_group); |
218 | |||
219 | result = add_fs(); | ||
220 | return result; | ||
221 | } | 187 | } |
222 | 188 | ||
223 | 189 | ||
224 | static int tc1100_remove(struct platform_device *device) | 190 | static int __devexit tc1100_remove(struct platform_device *device) |
225 | { | 191 | { |
226 | remove_fs(); | 192 | sysfs_remove_group(&device->dev.kobj, &tc1100_attribute_group); |
193 | |||
227 | return 0; | 194 | return 0; |
228 | } | 195 | } |
229 | 196 | ||
230 | static int tc1100_suspend(struct platform_device *dev, pm_message_t state) | 197 | #ifdef CONFIG_PM |
198 | static int tc1100_suspend(struct device *dev) | ||
231 | { | 199 | { |
232 | int ret; | 200 | int ret; |
233 | 201 | ||
@@ -239,10 +207,10 @@ static int tc1100_suspend(struct platform_device *dev, pm_message_t state) | |||
239 | if (ret) | 207 | if (ret) |
240 | return ret; | 208 | return ret; |
241 | 209 | ||
242 | return ret; | 210 | return 0; |
243 | } | 211 | } |
244 | 212 | ||
245 | static int tc1100_resume(struct platform_device *dev) | 213 | static int tc1100_resume(struct device *dev) |
246 | { | 214 | { |
247 | int ret; | 215 | int ret; |
248 | 216 | ||
@@ -254,34 +222,61 @@ static int tc1100_resume(struct platform_device *dev) | |||
254 | if (ret) | 222 | if (ret) |
255 | return ret; | 223 | return ret; |
256 | 224 | ||
257 | return ret; | 225 | return 0; |
258 | } | 226 | } |
259 | 227 | ||
228 | static const struct dev_pm_ops tc1100_pm_ops = { | ||
229 | .suspend = tc1100_suspend, | ||
230 | .resume = tc1100_resume, | ||
231 | .freeze = tc1100_suspend, | ||
232 | .restore = tc1100_resume, | ||
233 | }; | ||
234 | #endif | ||
235 | |||
236 | static struct platform_driver tc1100_driver = { | ||
237 | .driver = { | ||
238 | .name = "tc1100-wmi", | ||
239 | .owner = THIS_MODULE, | ||
240 | #ifdef CONFIG_PM | ||
241 | .pm = &tc1100_pm_ops, | ||
242 | #endif | ||
243 | }, | ||
244 | .remove = __devexit_p(tc1100_remove), | ||
245 | }; | ||
246 | |||
260 | static int __init tc1100_init(void) | 247 | static int __init tc1100_init(void) |
261 | { | 248 | { |
262 | int result = 0; | 249 | int error; |
263 | 250 | ||
264 | if (!wmi_has_guid(GUID)) | 251 | if (!wmi_has_guid(GUID)) |
265 | return -ENODEV; | 252 | return -ENODEV; |
266 | 253 | ||
267 | result = platform_driver_register(&tc1100_driver); | ||
268 | if (result) | ||
269 | return result; | ||
270 | |||
271 | tc1100_device = platform_device_alloc("tc1100-wmi", -1); | 254 | tc1100_device = platform_device_alloc("tc1100-wmi", -1); |
272 | platform_device_add(tc1100_device); | 255 | if (!tc1100_device) |
256 | return -ENOMEM; | ||
257 | |||
258 | error = platform_device_add(tc1100_device); | ||
259 | if (error) | ||
260 | goto err_device_put; | ||
261 | |||
262 | error = platform_driver_probe(&tc1100_driver, tc1100_probe); | ||
263 | if (error) | ||
264 | goto err_device_del; | ||
273 | 265 | ||
274 | printk(TC1100_INFO "HP Compaq TC1100 Tablet WMI Extras loaded\n"); | 266 | printk(TC1100_INFO "HP Compaq TC1100 Tablet WMI Extras loaded\n"); |
267 | return 0; | ||
275 | 268 | ||
276 | return result; | 269 | err_device_del: |
270 | platform_device_del(tc1100_device); | ||
271 | err_device_put: | ||
272 | platform_device_put(tc1100_device); | ||
273 | return error; | ||
277 | } | 274 | } |
278 | 275 | ||
279 | static void __exit tc1100_exit(void) | 276 | static void __exit tc1100_exit(void) |
280 | { | 277 | { |
281 | platform_device_del(tc1100_device); | 278 | platform_device_unregister(tc1100_device); |
282 | platform_driver_unregister(&tc1100_driver); | 279 | platform_driver_unregister(&tc1100_driver); |
283 | |||
284 | printk(TC1100_INFO "HP Compaq TC1100 Tablet WMI Extras unloaded\n"); | ||
285 | } | 280 | } |
286 | 281 | ||
287 | module_init(tc1100_init); | 282 | module_init(tc1100_init); |
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 448c8aeb166b..e67e4feb35cb 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c | |||
@@ -6384,11 +6384,13 @@ static struct ibm_struct brightness_driver_data = { | |||
6384 | * and we leave them unchanged. | 6384 | * and we leave them unchanged. |
6385 | */ | 6385 | */ |
6386 | 6386 | ||
6387 | #ifdef CONFIG_THINKPAD_ACPI_ALSA_SUPPORT | ||
6388 | |||
6387 | #define TPACPI_ALSA_DRVNAME "ThinkPad EC" | 6389 | #define TPACPI_ALSA_DRVNAME "ThinkPad EC" |
6388 | #define TPACPI_ALSA_SHRTNAME "ThinkPad Console Audio Control" | 6390 | #define TPACPI_ALSA_SHRTNAME "ThinkPad Console Audio Control" |
6389 | #define TPACPI_ALSA_MIXERNAME TPACPI_ALSA_SHRTNAME | 6391 | #define TPACPI_ALSA_MIXERNAME TPACPI_ALSA_SHRTNAME |
6390 | 6392 | ||
6391 | static int alsa_index = SNDRV_DEFAULT_IDX1; | 6393 | static int alsa_index = ~((1 << (SNDRV_CARDS - 3)) - 1); /* last three slots */ |
6392 | static char *alsa_id = "ThinkPadEC"; | 6394 | static char *alsa_id = "ThinkPadEC"; |
6393 | static int alsa_enable = SNDRV_DEFAULT_ENABLE1; | 6395 | static int alsa_enable = SNDRV_DEFAULT_ENABLE1; |
6394 | 6396 | ||
@@ -6705,10 +6707,11 @@ static int __init volume_create_alsa_mixer(void) | |||
6705 | 6707 | ||
6706 | rc = snd_card_create(alsa_index, alsa_id, THIS_MODULE, | 6708 | rc = snd_card_create(alsa_index, alsa_id, THIS_MODULE, |
6707 | sizeof(struct tpacpi_alsa_data), &card); | 6709 | sizeof(struct tpacpi_alsa_data), &card); |
6708 | if (rc < 0) | 6710 | if (rc < 0 || !card) { |
6709 | return rc; | 6711 | printk(TPACPI_ERR |
6710 | if (!card) | 6712 | "Failed to create ALSA card structures: %d\n", rc); |
6711 | return -ENOMEM; | 6713 | return 1; |
6714 | } | ||
6712 | 6715 | ||
6713 | BUG_ON(!card->private_data); | 6716 | BUG_ON(!card->private_data); |
6714 | data = card->private_data; | 6717 | data = card->private_data; |
@@ -6741,8 +6744,9 @@ static int __init volume_create_alsa_mixer(void) | |||
6741 | rc = snd_ctl_add(card, ctl_vol); | 6744 | rc = snd_ctl_add(card, ctl_vol); |
6742 | if (rc < 0) { | 6745 | if (rc < 0) { |
6743 | printk(TPACPI_ERR | 6746 | printk(TPACPI_ERR |
6744 | "Failed to create ALSA volume control\n"); | 6747 | "Failed to create ALSA volume control: %d\n", |
6745 | goto err_out; | 6748 | rc); |
6749 | goto err_exit; | ||
6746 | } | 6750 | } |
6747 | data->ctl_vol_id = &ctl_vol->id; | 6751 | data->ctl_vol_id = &ctl_vol->id; |
6748 | } | 6752 | } |
@@ -6750,22 +6754,25 @@ static int __init volume_create_alsa_mixer(void) | |||
6750 | ctl_mute = snd_ctl_new1(&volume_alsa_control_mute, NULL); | 6754 | ctl_mute = snd_ctl_new1(&volume_alsa_control_mute, NULL); |
6751 | rc = snd_ctl_add(card, ctl_mute); | 6755 | rc = snd_ctl_add(card, ctl_mute); |
6752 | if (rc < 0) { | 6756 | if (rc < 0) { |
6753 | printk(TPACPI_ERR "Failed to create ALSA mute control\n"); | 6757 | printk(TPACPI_ERR "Failed to create ALSA mute control: %d\n", |
6754 | goto err_out; | 6758 | rc); |
6759 | goto err_exit; | ||
6755 | } | 6760 | } |
6756 | data->ctl_mute_id = &ctl_mute->id; | 6761 | data->ctl_mute_id = &ctl_mute->id; |
6757 | 6762 | ||
6758 | snd_card_set_dev(card, &tpacpi_pdev->dev); | 6763 | snd_card_set_dev(card, &tpacpi_pdev->dev); |
6759 | rc = snd_card_register(card); | 6764 | rc = snd_card_register(card); |
6760 | |||
6761 | err_out: | ||
6762 | if (rc < 0) { | 6765 | if (rc < 0) { |
6763 | snd_card_free(card); | 6766 | printk(TPACPI_ERR "Failed to register ALSA card: %d\n", rc); |
6764 | card = NULL; | 6767 | goto err_exit; |
6765 | } | 6768 | } |
6766 | 6769 | ||
6767 | alsa_card = card; | 6770 | alsa_card = card; |
6768 | return rc; | 6771 | return 0; |
6772 | |||
6773 | err_exit: | ||
6774 | snd_card_free(card); | ||
6775 | return 1; | ||
6769 | } | 6776 | } |
6770 | 6777 | ||
6771 | #define TPACPI_VOL_Q_MUTEONLY 0x0001 /* Mute-only control available */ | 6778 | #define TPACPI_VOL_Q_MUTEONLY 0x0001 /* Mute-only control available */ |
@@ -7016,6 +7023,28 @@ static struct ibm_struct volume_driver_data = { | |||
7016 | .shutdown = volume_shutdown, | 7023 | .shutdown = volume_shutdown, |
7017 | }; | 7024 | }; |
7018 | 7025 | ||
7026 | #else /* !CONFIG_THINKPAD_ACPI_ALSA_SUPPORT */ | ||
7027 | |||
7028 | #define alsa_card NULL | ||
7029 | |||
7030 | static void inline volume_alsa_notify_change(void) | ||
7031 | { | ||
7032 | } | ||
7033 | |||
7034 | static int __init volume_init(struct ibm_init_struct *iibm) | ||
7035 | { | ||
7036 | printk(TPACPI_INFO | ||
7037 | "volume: disabled as there is no ALSA support in this kernel\n"); | ||
7038 | |||
7039 | return 1; | ||
7040 | } | ||
7041 | |||
7042 | static struct ibm_struct volume_driver_data = { | ||
7043 | .name = "volume", | ||
7044 | }; | ||
7045 | |||
7046 | #endif /* CONFIG_THINKPAD_ACPI_ALSA_SUPPORT */ | ||
7047 | |||
7019 | /************************************************************************* | 7048 | /************************************************************************* |
7020 | * Fan subdriver | 7049 | * Fan subdriver |
7021 | */ | 7050 | */ |
@@ -8738,6 +8767,7 @@ MODULE_PARM_DESC(hotkey_report_mode, | |||
8738 | "used for backwards compatibility with userspace, " | 8767 | "used for backwards compatibility with userspace, " |
8739 | "see documentation"); | 8768 | "see documentation"); |
8740 | 8769 | ||
8770 | #ifdef CONFIG_THINKPAD_ACPI_ALSA_SUPPORT | ||
8741 | module_param_named(volume_mode, volume_mode, uint, 0444); | 8771 | module_param_named(volume_mode, volume_mode, uint, 0444); |
8742 | MODULE_PARM_DESC(volume_mode, | 8772 | MODULE_PARM_DESC(volume_mode, |
8743 | "Selects volume control strategy: " | 8773 | "Selects volume control strategy: " |
@@ -8760,6 +8790,7 @@ module_param_named(id, alsa_id, charp, 0444); | |||
8760 | MODULE_PARM_DESC(id, "ALSA id for the ACPI EC Mixer"); | 8790 | MODULE_PARM_DESC(id, "ALSA id for the ACPI EC Mixer"); |
8761 | module_param_named(enable, alsa_enable, bool, 0444); | 8791 | module_param_named(enable, alsa_enable, bool, 0444); |
8762 | MODULE_PARM_DESC(enable, "Enable the ALSA interface for the ACPI EC Mixer"); | 8792 | MODULE_PARM_DESC(enable, "Enable the ALSA interface for the ACPI EC Mixer"); |
8793 | #endif /* CONFIG_THINKPAD_ACPI_ALSA_SUPPORT */ | ||
8763 | 8794 | ||
8764 | #define TPACPI_PARAM(feature) \ | 8795 | #define TPACPI_PARAM(feature) \ |
8765 | module_param_call(feature, set_ibm_param, NULL, NULL, 0); \ | 8796 | module_param_call(feature, set_ibm_param, NULL, NULL, 0); \ |
diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index 51c0a8bee414..77bf5d8f893a 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <linux/init.h> | 42 | #include <linux/init.h> |
43 | #include <linux/types.h> | 43 | #include <linux/types.h> |
44 | #include <linux/proc_fs.h> | 44 | #include <linux/proc_fs.h> |
45 | #include <linux/seq_file.h> | ||
45 | #include <linux/backlight.h> | 46 | #include <linux/backlight.h> |
46 | #include <linux/platform_device.h> | 47 | #include <linux/platform_device.h> |
47 | #include <linux/rfkill.h> | 48 | #include <linux/rfkill.h> |
@@ -357,63 +358,6 @@ static int force_fan; | |||
357 | static int last_key_event; | 358 | static int last_key_event; |
358 | static int key_event_valid; | 359 | static int key_event_valid; |
359 | 360 | ||
360 | typedef struct _ProcItem { | ||
361 | const char *name; | ||
362 | char *(*read_func) (char *); | ||
363 | unsigned long (*write_func) (const char *, unsigned long); | ||
364 | } ProcItem; | ||
365 | |||
366 | /* proc file handlers | ||
367 | */ | ||
368 | |||
369 | static int | ||
370 | dispatch_read(char *page, char **start, off_t off, int count, int *eof, | ||
371 | ProcItem * item) | ||
372 | { | ||
373 | char *p = page; | ||
374 | int len; | ||
375 | |||
376 | if (off == 0) | ||
377 | p = item->read_func(p); | ||
378 | |||
379 | /* ISSUE: I don't understand this code */ | ||
380 | len = (p - page); | ||
381 | if (len <= off + count) | ||
382 | *eof = 1; | ||
383 | *start = page + off; | ||
384 | len -= off; | ||
385 | if (len > count) | ||
386 | len = count; | ||
387 | if (len < 0) | ||
388 | len = 0; | ||
389 | return len; | ||
390 | } | ||
391 | |||
392 | static int | ||
393 | dispatch_write(struct file *file, const char __user * buffer, | ||
394 | unsigned long count, ProcItem * item) | ||
395 | { | ||
396 | int result; | ||
397 | char *tmp_buffer; | ||
398 | |||
399 | /* Arg buffer points to userspace memory, which can't be accessed | ||
400 | * directly. Since we're making a copy, zero-terminate the | ||
401 | * destination so that sscanf can be used on it safely. | ||
402 | */ | ||
403 | tmp_buffer = kmalloc(count + 1, GFP_KERNEL); | ||
404 | if (!tmp_buffer) | ||
405 | return -ENOMEM; | ||
406 | |||
407 | if (copy_from_user(tmp_buffer, buffer, count)) { | ||
408 | result = -EFAULT; | ||
409 | } else { | ||
410 | tmp_buffer[count] = 0; | ||
411 | result = item->write_func(tmp_buffer, count); | ||
412 | } | ||
413 | kfree(tmp_buffer); | ||
414 | return result; | ||
415 | } | ||
416 | |||
417 | static int get_lcd(struct backlight_device *bd) | 361 | static int get_lcd(struct backlight_device *bd) |
418 | { | 362 | { |
419 | u32 hci_result; | 363 | u32 hci_result; |
@@ -426,19 +370,24 @@ static int get_lcd(struct backlight_device *bd) | |||
426 | return -EFAULT; | 370 | return -EFAULT; |
427 | } | 371 | } |
428 | 372 | ||
429 | static char *read_lcd(char *p) | 373 | static int lcd_proc_show(struct seq_file *m, void *v) |
430 | { | 374 | { |
431 | int value = get_lcd(NULL); | 375 | int value = get_lcd(NULL); |
432 | 376 | ||
433 | if (value >= 0) { | 377 | if (value >= 0) { |
434 | p += sprintf(p, "brightness: %d\n", value); | 378 | seq_printf(m, "brightness: %d\n", value); |
435 | p += sprintf(p, "brightness_levels: %d\n", | 379 | seq_printf(m, "brightness_levels: %d\n", |
436 | HCI_LCD_BRIGHTNESS_LEVELS); | 380 | HCI_LCD_BRIGHTNESS_LEVELS); |
437 | } else { | 381 | } else { |
438 | printk(MY_ERR "Error reading LCD brightness\n"); | 382 | printk(MY_ERR "Error reading LCD brightness\n"); |
439 | } | 383 | } |
440 | 384 | ||
441 | return p; | 385 | return 0; |
386 | } | ||
387 | |||
388 | static int lcd_proc_open(struct inode *inode, struct file *file) | ||
389 | { | ||
390 | return single_open(file, lcd_proc_show, NULL); | ||
442 | } | 391 | } |
443 | 392 | ||
444 | static int set_lcd(int value) | 393 | static int set_lcd(int value) |
@@ -458,12 +407,20 @@ static int set_lcd_status(struct backlight_device *bd) | |||
458 | return set_lcd(bd->props.brightness); | 407 | return set_lcd(bd->props.brightness); |
459 | } | 408 | } |
460 | 409 | ||
461 | static unsigned long write_lcd(const char *buffer, unsigned long count) | 410 | static ssize_t lcd_proc_write(struct file *file, const char __user *buf, |
411 | size_t count, loff_t *pos) | ||
462 | { | 412 | { |
413 | char cmd[42]; | ||
414 | size_t len; | ||
463 | int value; | 415 | int value; |
464 | int ret; | 416 | int ret; |
465 | 417 | ||
466 | if (sscanf(buffer, " brightness : %i", &value) == 1 && | 418 | len = min(count, sizeof(cmd) - 1); |
419 | if (copy_from_user(cmd, buf, len)) | ||
420 | return -EFAULT; | ||
421 | cmd[len] = '\0'; | ||
422 | |||
423 | if (sscanf(cmd, " brightness : %i", &value) == 1 && | ||
467 | value >= 0 && value < HCI_LCD_BRIGHTNESS_LEVELS) { | 424 | value >= 0 && value < HCI_LCD_BRIGHTNESS_LEVELS) { |
468 | ret = set_lcd(value); | 425 | ret = set_lcd(value); |
469 | if (ret == 0) | 426 | if (ret == 0) |
@@ -474,7 +431,16 @@ static unsigned long write_lcd(const char *buffer, unsigned long count) | |||
474 | return ret; | 431 | return ret; |
475 | } | 432 | } |
476 | 433 | ||
477 | static char *read_video(char *p) | 434 | static const struct file_operations lcd_proc_fops = { |
435 | .owner = THIS_MODULE, | ||
436 | .open = lcd_proc_open, | ||
437 | .read = seq_read, | ||
438 | .llseek = seq_lseek, | ||
439 | .release = single_release, | ||
440 | .write = lcd_proc_write, | ||
441 | }; | ||
442 | |||
443 | static int video_proc_show(struct seq_file *m, void *v) | ||
478 | { | 444 | { |
479 | u32 hci_result; | 445 | u32 hci_result; |
480 | u32 value; | 446 | u32 value; |
@@ -484,18 +450,25 @@ static char *read_video(char *p) | |||
484 | int is_lcd = (value & HCI_VIDEO_OUT_LCD) ? 1 : 0; | 450 | int is_lcd = (value & HCI_VIDEO_OUT_LCD) ? 1 : 0; |
485 | int is_crt = (value & HCI_VIDEO_OUT_CRT) ? 1 : 0; | 451 | int is_crt = (value & HCI_VIDEO_OUT_CRT) ? 1 : 0; |
486 | int is_tv = (value & HCI_VIDEO_OUT_TV) ? 1 : 0; | 452 | int is_tv = (value & HCI_VIDEO_OUT_TV) ? 1 : 0; |
487 | p += sprintf(p, "lcd_out: %d\n", is_lcd); | 453 | seq_printf(m, "lcd_out: %d\n", is_lcd); |
488 | p += sprintf(p, "crt_out: %d\n", is_crt); | 454 | seq_printf(m, "crt_out: %d\n", is_crt); |
489 | p += sprintf(p, "tv_out: %d\n", is_tv); | 455 | seq_printf(m, "tv_out: %d\n", is_tv); |
490 | } else { | 456 | } else { |
491 | printk(MY_ERR "Error reading video out status\n"); | 457 | printk(MY_ERR "Error reading video out status\n"); |
492 | } | 458 | } |
493 | 459 | ||
494 | return p; | 460 | return 0; |
495 | } | 461 | } |
496 | 462 | ||
497 | static unsigned long write_video(const char *buffer, unsigned long count) | 463 | static int video_proc_open(struct inode *inode, struct file *file) |
498 | { | 464 | { |
465 | return single_open(file, video_proc_show, NULL); | ||
466 | } | ||
467 | |||
468 | static ssize_t video_proc_write(struct file *file, const char __user *buf, | ||
469 | size_t count, loff_t *pos) | ||
470 | { | ||
471 | char *cmd, *buffer; | ||
499 | int value; | 472 | int value; |
500 | int remain = count; | 473 | int remain = count; |
501 | int lcd_out = -1; | 474 | int lcd_out = -1; |
@@ -504,6 +477,17 @@ static unsigned long write_video(const char *buffer, unsigned long count) | |||
504 | u32 hci_result; | 477 | u32 hci_result; |
505 | u32 video_out; | 478 | u32 video_out; |
506 | 479 | ||
480 | cmd = kmalloc(count + 1, GFP_KERNEL); | ||
481 | if (!cmd) | ||
482 | return -ENOMEM; | ||
483 | if (copy_from_user(cmd, buf, count)) { | ||
484 | kfree(cmd); | ||
485 | return -EFAULT; | ||
486 | } | ||
487 | cmd[count] = '\0'; | ||
488 | |||
489 | buffer = cmd; | ||
490 | |||
507 | /* scan expression. Multiple expressions may be delimited with ; | 491 | /* scan expression. Multiple expressions may be delimited with ; |
508 | * | 492 | * |
509 | * NOTE: to keep scanning simple, invalid fields are ignored | 493 | * NOTE: to keep scanning simple, invalid fields are ignored |
@@ -523,6 +507,8 @@ static unsigned long write_video(const char *buffer, unsigned long count) | |||
523 | while (remain && *(buffer - 1) != ';'); | 507 | while (remain && *(buffer - 1) != ';'); |
524 | } | 508 | } |
525 | 509 | ||
510 | kfree(cmd); | ||
511 | |||
526 | hci_read1(HCI_VIDEO_OUT, &video_out, &hci_result); | 512 | hci_read1(HCI_VIDEO_OUT, &video_out, &hci_result); |
527 | if (hci_result == HCI_SUCCESS) { | 513 | if (hci_result == HCI_SUCCESS) { |
528 | unsigned int new_video_out = video_out; | 514 | unsigned int new_video_out = video_out; |
@@ -543,28 +529,50 @@ static unsigned long write_video(const char *buffer, unsigned long count) | |||
543 | return count; | 529 | return count; |
544 | } | 530 | } |
545 | 531 | ||
546 | static char *read_fan(char *p) | 532 | static const struct file_operations video_proc_fops = { |
533 | .owner = THIS_MODULE, | ||
534 | .open = video_proc_open, | ||
535 | .read = seq_read, | ||
536 | .llseek = seq_lseek, | ||
537 | .release = single_release, | ||
538 | .write = video_proc_write, | ||
539 | }; | ||
540 | |||
541 | static int fan_proc_show(struct seq_file *m, void *v) | ||
547 | { | 542 | { |
548 | u32 hci_result; | 543 | u32 hci_result; |
549 | u32 value; | 544 | u32 value; |
550 | 545 | ||
551 | hci_read1(HCI_FAN, &value, &hci_result); | 546 | hci_read1(HCI_FAN, &value, &hci_result); |
552 | if (hci_result == HCI_SUCCESS) { | 547 | if (hci_result == HCI_SUCCESS) { |
553 | p += sprintf(p, "running: %d\n", (value > 0)); | 548 | seq_printf(m, "running: %d\n", (value > 0)); |
554 | p += sprintf(p, "force_on: %d\n", force_fan); | 549 | seq_printf(m, "force_on: %d\n", force_fan); |
555 | } else { | 550 | } else { |
556 | printk(MY_ERR "Error reading fan status\n"); | 551 | printk(MY_ERR "Error reading fan status\n"); |
557 | } | 552 | } |
558 | 553 | ||
559 | return p; | 554 | return 0; |
555 | } | ||
556 | |||
557 | static int fan_proc_open(struct inode *inode, struct file *file) | ||
558 | { | ||
559 | return single_open(file, fan_proc_show, NULL); | ||
560 | } | 560 | } |
561 | 561 | ||
562 | static unsigned long write_fan(const char *buffer, unsigned long count) | 562 | static ssize_t fan_proc_write(struct file *file, const char __user *buf, |
563 | size_t count, loff_t *pos) | ||
563 | { | 564 | { |
565 | char cmd[42]; | ||
566 | size_t len; | ||
564 | int value; | 567 | int value; |
565 | u32 hci_result; | 568 | u32 hci_result; |
566 | 569 | ||
567 | if (sscanf(buffer, " force_on : %i", &value) == 1 && | 570 | len = min(count, sizeof(cmd) - 1); |
571 | if (copy_from_user(cmd, buf, len)) | ||
572 | return -EFAULT; | ||
573 | cmd[len] = '\0'; | ||
574 | |||
575 | if (sscanf(cmd, " force_on : %i", &value) == 1 && | ||
568 | value >= 0 && value <= 1) { | 576 | value >= 0 && value <= 1) { |
569 | hci_write1(HCI_FAN, value, &hci_result); | 577 | hci_write1(HCI_FAN, value, &hci_result); |
570 | if (hci_result != HCI_SUCCESS) | 578 | if (hci_result != HCI_SUCCESS) |
@@ -578,7 +586,16 @@ static unsigned long write_fan(const char *buffer, unsigned long count) | |||
578 | return count; | 586 | return count; |
579 | } | 587 | } |
580 | 588 | ||
581 | static char *read_keys(char *p) | 589 | static const struct file_operations fan_proc_fops = { |
590 | .owner = THIS_MODULE, | ||
591 | .open = fan_proc_open, | ||
592 | .read = seq_read, | ||
593 | .llseek = seq_lseek, | ||
594 | .release = single_release, | ||
595 | .write = fan_proc_write, | ||
596 | }; | ||
597 | |||
598 | static int keys_proc_show(struct seq_file *m, void *v) | ||
582 | { | 599 | { |
583 | u32 hci_result; | 600 | u32 hci_result; |
584 | u32 value; | 601 | u32 value; |
@@ -602,18 +619,30 @@ static char *read_keys(char *p) | |||
602 | } | 619 | } |
603 | } | 620 | } |
604 | 621 | ||
605 | p += sprintf(p, "hotkey_ready: %d\n", key_event_valid); | 622 | seq_printf(m, "hotkey_ready: %d\n", key_event_valid); |
606 | p += sprintf(p, "hotkey: 0x%04x\n", last_key_event); | 623 | seq_printf(m, "hotkey: 0x%04x\n", last_key_event); |
624 | end: | ||
625 | return 0; | ||
626 | } | ||
607 | 627 | ||
608 | end: | 628 | static int keys_proc_open(struct inode *inode, struct file *file) |
609 | return p; | 629 | { |
630 | return single_open(file, keys_proc_show, NULL); | ||
610 | } | 631 | } |
611 | 632 | ||
612 | static unsigned long write_keys(const char *buffer, unsigned long count) | 633 | static ssize_t keys_proc_write(struct file *file, const char __user *buf, |
634 | size_t count, loff_t *pos) | ||
613 | { | 635 | { |
636 | char cmd[42]; | ||
637 | size_t len; | ||
614 | int value; | 638 | int value; |
615 | 639 | ||
616 | if (sscanf(buffer, " hotkey_ready : %i", &value) == 1 && value == 0) { | 640 | len = min(count, sizeof(cmd) - 1); |
641 | if (copy_from_user(cmd, buf, len)) | ||
642 | return -EFAULT; | ||
643 | cmd[len] = '\0'; | ||
644 | |||
645 | if (sscanf(cmd, " hotkey_ready : %i", &value) == 1 && value == 0) { | ||
617 | key_event_valid = 0; | 646 | key_event_valid = 0; |
618 | } else { | 647 | } else { |
619 | return -EINVAL; | 648 | return -EINVAL; |
@@ -622,52 +651,58 @@ static unsigned long write_keys(const char *buffer, unsigned long count) | |||
622 | return count; | 651 | return count; |
623 | } | 652 | } |
624 | 653 | ||
625 | static char *read_version(char *p) | 654 | static const struct file_operations keys_proc_fops = { |
655 | .owner = THIS_MODULE, | ||
656 | .open = keys_proc_open, | ||
657 | .read = seq_read, | ||
658 | .llseek = seq_lseek, | ||
659 | .release = single_release, | ||
660 | .write = keys_proc_write, | ||
661 | }; | ||
662 | |||
663 | static int version_proc_show(struct seq_file *m, void *v) | ||
626 | { | 664 | { |
627 | p += sprintf(p, "driver: %s\n", TOSHIBA_ACPI_VERSION); | 665 | seq_printf(m, "driver: %s\n", TOSHIBA_ACPI_VERSION); |
628 | p += sprintf(p, "proc_interface: %d\n", | 666 | seq_printf(m, "proc_interface: %d\n", PROC_INTERFACE_VERSION); |
629 | PROC_INTERFACE_VERSION); | 667 | return 0; |
630 | return p; | ||
631 | } | 668 | } |
632 | 669 | ||
670 | static int version_proc_open(struct inode *inode, struct file *file) | ||
671 | { | ||
672 | return single_open(file, version_proc_show, PDE(inode)->data); | ||
673 | } | ||
674 | |||
675 | static const struct file_operations version_proc_fops = { | ||
676 | .owner = THIS_MODULE, | ||
677 | .open = version_proc_open, | ||
678 | .read = seq_read, | ||
679 | .llseek = seq_lseek, | ||
680 | .release = single_release, | ||
681 | }; | ||
682 | |||
633 | /* proc and module init | 683 | /* proc and module init |
634 | */ | 684 | */ |
635 | 685 | ||
636 | #define PROC_TOSHIBA "toshiba" | 686 | #define PROC_TOSHIBA "toshiba" |
637 | 687 | ||
638 | static ProcItem proc_items[] = { | ||
639 | {"lcd", read_lcd, write_lcd}, | ||
640 | {"video", read_video, write_video}, | ||
641 | {"fan", read_fan, write_fan}, | ||
642 | {"keys", read_keys, write_keys}, | ||
643 | {"version", read_version, NULL}, | ||
644 | {NULL} | ||
645 | }; | ||
646 | |||
647 | static acpi_status __init add_device(void) | 688 | static acpi_status __init add_device(void) |
648 | { | 689 | { |
649 | struct proc_dir_entry *proc; | 690 | proc_create("lcd", S_IRUGO | S_IWUSR, toshiba_proc_dir, &lcd_proc_fops); |
650 | ProcItem *item; | 691 | proc_create("video", S_IRUGO | S_IWUSR, toshiba_proc_dir, &video_proc_fops); |
651 | 692 | proc_create("fan", S_IRUGO | S_IWUSR, toshiba_proc_dir, &fan_proc_fops); | |
652 | for (item = proc_items; item->name; ++item) { | 693 | proc_create("keys", S_IRUGO | S_IWUSR, toshiba_proc_dir, &keys_proc_fops); |
653 | proc = create_proc_read_entry(item->name, | 694 | proc_create("version", S_IRUGO, toshiba_proc_dir, &version_proc_fops); |
654 | S_IFREG | S_IRUGO | S_IWUSR, | ||
655 | toshiba_proc_dir, | ||
656 | (read_proc_t *) dispatch_read, | ||
657 | item); | ||
658 | if (proc && item->write_func) | ||
659 | proc->write_proc = (write_proc_t *) dispatch_write; | ||
660 | } | ||
661 | 695 | ||
662 | return AE_OK; | 696 | return AE_OK; |
663 | } | 697 | } |
664 | 698 | ||
665 | static acpi_status remove_device(void) | 699 | static acpi_status remove_device(void) |
666 | { | 700 | { |
667 | ProcItem *item; | 701 | remove_proc_entry("lcd", toshiba_proc_dir); |
668 | 702 | remove_proc_entry("video", toshiba_proc_dir); | |
669 | for (item = proc_items; item->name; ++item) | 703 | remove_proc_entry("fan", toshiba_proc_dir); |
670 | remove_proc_entry(item->name, toshiba_proc_dir); | 704 | remove_proc_entry("keys", toshiba_proc_dir); |
705 | remove_proc_entry("version", toshiba_proc_dir); | ||
671 | return AE_OK; | 706 | return AE_OK; |
672 | } | 707 | } |
673 | 708 | ||
diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c index e425a868cd3a..b104302fea0a 100644 --- a/drivers/platform/x86/wmi.c +++ b/drivers/platform/x86/wmi.c | |||
@@ -492,8 +492,7 @@ wmi_notify_handler handler, void *data) | |||
492 | if (!guid || !handler) | 492 | if (!guid || !handler) |
493 | return AE_BAD_PARAMETER; | 493 | return AE_BAD_PARAMETER; |
494 | 494 | ||
495 | find_guid(guid, &block); | 495 | if (!find_guid(guid, &block)) |
496 | if (!block) | ||
497 | return AE_NOT_EXIST; | 496 | return AE_NOT_EXIST; |
498 | 497 | ||
499 | if (block->handler) | 498 | if (block->handler) |
@@ -521,8 +520,7 @@ acpi_status wmi_remove_notify_handler(const char *guid) | |||
521 | if (!guid) | 520 | if (!guid) |
522 | return AE_BAD_PARAMETER; | 521 | return AE_BAD_PARAMETER; |
523 | 522 | ||
524 | find_guid(guid, &block); | 523 | if (!find_guid(guid, &block)) |
525 | if (!block) | ||
526 | return AE_NOT_EXIST; | 524 | return AE_NOT_EXIST; |
527 | 525 | ||
528 | if (!block->handler) | 526 | if (!block->handler) |
@@ -540,8 +538,8 @@ EXPORT_SYMBOL_GPL(wmi_remove_notify_handler); | |||
540 | /** | 538 | /** |
541 | * wmi_get_event_data - Get WMI data associated with an event | 539 | * wmi_get_event_data - Get WMI data associated with an event |
542 | * | 540 | * |
543 | * @event - Event to find | 541 | * @event: Event to find |
544 | * &out - Buffer to hold event data | 542 | * @out: Buffer to hold event data. out->pointer should be freed with kfree() |
545 | * | 543 | * |
546 | * Returns extra data associated with an event in WMI. | 544 | * Returns extra data associated with an event in WMI. |
547 | */ | 545 | */ |
@@ -716,6 +714,22 @@ static int wmi_class_init(void) | |||
716 | return ret; | 714 | return ret; |
717 | } | 715 | } |
718 | 716 | ||
717 | static bool guid_already_parsed(const char *guid_string) | ||
718 | { | ||
719 | struct guid_block *gblock; | ||
720 | struct wmi_block *wblock; | ||
721 | struct list_head *p; | ||
722 | |||
723 | list_for_each(p, &wmi_blocks.list) { | ||
724 | wblock = list_entry(p, struct wmi_block, list); | ||
725 | gblock = &wblock->gblock; | ||
726 | |||
727 | if (strncmp(gblock->guid, guid_string, 16) == 0) | ||
728 | return true; | ||
729 | } | ||
730 | return false; | ||
731 | } | ||
732 | |||
719 | /* | 733 | /* |
720 | * Parse the _WDG method for the GUID data blocks | 734 | * Parse the _WDG method for the GUID data blocks |
721 | */ | 735 | */ |
@@ -725,6 +739,7 @@ static __init acpi_status parse_wdg(acpi_handle handle) | |||
725 | union acpi_object *obj; | 739 | union acpi_object *obj; |
726 | struct guid_block *gblock; | 740 | struct guid_block *gblock; |
727 | struct wmi_block *wblock; | 741 | struct wmi_block *wblock; |
742 | char guid_string[37]; | ||
728 | acpi_status status; | 743 | acpi_status status; |
729 | u32 i, total; | 744 | u32 i, total; |
730 | 745 | ||
@@ -747,6 +762,19 @@ static __init acpi_status parse_wdg(acpi_handle handle) | |||
747 | memcpy(gblock, obj->buffer.pointer, obj->buffer.length); | 762 | memcpy(gblock, obj->buffer.pointer, obj->buffer.length); |
748 | 763 | ||
749 | for (i = 0; i < total; i++) { | 764 | for (i = 0; i < total; i++) { |
765 | /* | ||
766 | Some WMI devices, like those for nVidia hooks, have a | ||
767 | duplicate GUID. It's not clear what we should do in this | ||
768 | case yet, so for now, we'll just ignore the duplicate. | ||
769 | Anyone who wants to add support for that device can come | ||
770 | up with a better workaround for the mess then. | ||
771 | */ | ||
772 | if (guid_already_parsed(gblock[i].guid) == true) { | ||
773 | wmi_gtoa(gblock[i].guid, guid_string); | ||
774 | printk(KERN_INFO PREFIX "Skipping duplicate GUID %s\n", | ||
775 | guid_string); | ||
776 | continue; | ||
777 | } | ||
750 | wblock = kzalloc(sizeof(struct wmi_block), GFP_KERNEL); | 778 | wblock = kzalloc(sizeof(struct wmi_block), GFP_KERNEL); |
751 | if (!wblock) | 779 | if (!wblock) |
752 | return AE_NO_MEMORY; | 780 | return AE_NO_MEMORY; |
diff --git a/drivers/s390/block/dasd_alias.c b/drivers/s390/block/dasd_alias.c index fd1231738ef4..148b1dd24070 100644 --- a/drivers/s390/block/dasd_alias.c +++ b/drivers/s390/block/dasd_alias.c | |||
@@ -218,7 +218,7 @@ int dasd_alias_make_device_known_to_lcu(struct dasd_device *device) | |||
218 | spin_unlock_irqrestore(&aliastree.lock, flags); | 218 | spin_unlock_irqrestore(&aliastree.lock, flags); |
219 | newlcu = _allocate_lcu(uid); | 219 | newlcu = _allocate_lcu(uid); |
220 | if (IS_ERR(newlcu)) | 220 | if (IS_ERR(newlcu)) |
221 | return PTR_ERR(lcu); | 221 | return PTR_ERR(newlcu); |
222 | spin_lock_irqsave(&aliastree.lock, flags); | 222 | spin_lock_irqsave(&aliastree.lock, flags); |
223 | lcu = _find_lcu(server, uid); | 223 | lcu = _find_lcu(server, uid); |
224 | if (!lcu) { | 224 | if (!lcu) { |
diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c index f64d0db881b4..6e14863f5c70 100644 --- a/drivers/s390/block/dasd_diag.c +++ b/drivers/s390/block/dasd_diag.c | |||
@@ -8,7 +8,7 @@ | |||
8 | * | 8 | * |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #define KMSG_COMPONENT "dasd-diag" | 11 | #define KMSG_COMPONENT "dasd" |
12 | 12 | ||
13 | #include <linux/stddef.h> | 13 | #include <linux/stddef.h> |
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
@@ -146,16 +146,16 @@ dasd_diag_erp(struct dasd_device *device) | |||
146 | rc = mdsk_init_io(device, device->block->bp_block, 0, NULL); | 146 | rc = mdsk_init_io(device, device->block->bp_block, 0, NULL); |
147 | if (rc == 4) { | 147 | if (rc == 4) { |
148 | if (!(device->features & DASD_FEATURE_READONLY)) { | 148 | if (!(device->features & DASD_FEATURE_READONLY)) { |
149 | dev_warn(&device->cdev->dev, | 149 | pr_warning("%s: The access mode of a DIAG device " |
150 | "The access mode of a DIAG device changed" | 150 | "changed to read-only\n", |
151 | " to read-only"); | 151 | dev_name(&device->cdev->dev)); |
152 | device->features |= DASD_FEATURE_READONLY; | 152 | device->features |= DASD_FEATURE_READONLY; |
153 | } | 153 | } |
154 | rc = 0; | 154 | rc = 0; |
155 | } | 155 | } |
156 | if (rc) | 156 | if (rc) |
157 | dev_warn(&device->cdev->dev, "DIAG ERP failed with " | 157 | pr_warning("%s: DIAG ERP failed with " |
158 | "rc=%d\n", rc); | 158 | "rc=%d\n", dev_name(&device->cdev->dev), rc); |
159 | } | 159 | } |
160 | 160 | ||
161 | /* Start a given request at the device. Return zero on success, non-zero | 161 | /* Start a given request at the device. Return zero on success, non-zero |
@@ -371,8 +371,9 @@ dasd_diag_check_device(struct dasd_device *device) | |||
371 | private->pt_block = 2; | 371 | private->pt_block = 2; |
372 | break; | 372 | break; |
373 | default: | 373 | default: |
374 | dev_warn(&device->cdev->dev, "Device type %d is not supported " | 374 | pr_warning("%s: Device type %d is not supported " |
375 | "in DIAG mode\n", private->rdc_data.vdev_class); | 375 | "in DIAG mode\n", dev_name(&device->cdev->dev), |
376 | private->rdc_data.vdev_class); | ||
376 | rc = -EOPNOTSUPP; | 377 | rc = -EOPNOTSUPP; |
377 | goto out; | 378 | goto out; |
378 | } | 379 | } |
@@ -413,8 +414,8 @@ dasd_diag_check_device(struct dasd_device *device) | |||
413 | private->iob.flaga = DASD_DIAG_FLAGA_DEFAULT; | 414 | private->iob.flaga = DASD_DIAG_FLAGA_DEFAULT; |
414 | rc = dia250(&private->iob, RW_BIO); | 415 | rc = dia250(&private->iob, RW_BIO); |
415 | if (rc == 3) { | 416 | if (rc == 3) { |
416 | dev_warn(&device->cdev->dev, | 417 | pr_warning("%s: A 64-bit DIAG call failed\n", |
417 | "A 64-bit DIAG call failed\n"); | 418 | dev_name(&device->cdev->dev)); |
418 | rc = -EOPNOTSUPP; | 419 | rc = -EOPNOTSUPP; |
419 | goto out_label; | 420 | goto out_label; |
420 | } | 421 | } |
@@ -423,8 +424,9 @@ dasd_diag_check_device(struct dasd_device *device) | |||
423 | break; | 424 | break; |
424 | } | 425 | } |
425 | if (bsize > PAGE_SIZE) { | 426 | if (bsize > PAGE_SIZE) { |
426 | dev_warn(&device->cdev->dev, "Accessing the DASD failed because" | 427 | pr_warning("%s: Accessing the DASD failed because of an " |
427 | " of an incorrect format (rc=%d)\n", rc); | 428 | "incorrect format (rc=%d)\n", |
429 | dev_name(&device->cdev->dev), rc); | ||
428 | rc = -EIO; | 430 | rc = -EIO; |
429 | goto out_label; | 431 | goto out_label; |
430 | } | 432 | } |
@@ -442,18 +444,18 @@ dasd_diag_check_device(struct dasd_device *device) | |||
442 | block->s2b_shift++; | 444 | block->s2b_shift++; |
443 | rc = mdsk_init_io(device, block->bp_block, 0, NULL); | 445 | rc = mdsk_init_io(device, block->bp_block, 0, NULL); |
444 | if (rc && (rc != 4)) { | 446 | if (rc && (rc != 4)) { |
445 | dev_warn(&device->cdev->dev, "DIAG initialization " | 447 | pr_warning("%s: DIAG initialization failed with rc=%d\n", |
446 | "failed with rc=%d\n", rc); | 448 | dev_name(&device->cdev->dev), rc); |
447 | rc = -EIO; | 449 | rc = -EIO; |
448 | } else { | 450 | } else { |
449 | if (rc == 4) | 451 | if (rc == 4) |
450 | device->features |= DASD_FEATURE_READONLY; | 452 | device->features |= DASD_FEATURE_READONLY; |
451 | dev_info(&device->cdev->dev, | 453 | pr_info("%s: New DASD with %ld byte/block, total size %ld " |
452 | "New DASD with %ld byte/block, total size %ld KB%s\n", | 454 | "KB%s\n", dev_name(&device->cdev->dev), |
453 | (unsigned long) block->bp_block, | 455 | (unsigned long) block->bp_block, |
454 | (unsigned long) (block->blocks << | 456 | (unsigned long) (block->blocks << |
455 | block->s2b_shift) >> 1, | 457 | block->s2b_shift) >> 1, |
456 | (rc == 4) ? ", read-only device" : ""); | 458 | (rc == 4) ? ", read-only device" : ""); |
457 | rc = 0; | 459 | rc = 0; |
458 | } | 460 | } |
459 | out_label: | 461 | out_label: |
diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c index 28e4649fa9e4..247b2b934728 100644 --- a/drivers/s390/char/fs3270.c +++ b/drivers/s390/char/fs3270.c | |||
@@ -467,7 +467,7 @@ fs3270_open(struct inode *inode, struct file *filp) | |||
467 | if (IS_ERR(ib)) { | 467 | if (IS_ERR(ib)) { |
468 | raw3270_put_view(&fp->view); | 468 | raw3270_put_view(&fp->view); |
469 | raw3270_del_view(&fp->view); | 469 | raw3270_del_view(&fp->view); |
470 | rc = PTR_ERR(fp); | 470 | rc = PTR_ERR(ib); |
471 | goto out; | 471 | goto out; |
472 | } | 472 | } |
473 | fp->rdbuf = ib; | 473 | fp->rdbuf = ib; |
diff --git a/drivers/s390/char/tape_34xx.c b/drivers/s390/char/tape_34xx.c index 3657fe103c27..cb70fa1cf539 100644 --- a/drivers/s390/char/tape_34xx.c +++ b/drivers/s390/char/tape_34xx.c | |||
@@ -9,6 +9,7 @@ | |||
9 | */ | 9 | */ |
10 | 10 | ||
11 | #define KMSG_COMPONENT "tape_34xx" | 11 | #define KMSG_COMPONENT "tape_34xx" |
12 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt | ||
12 | 13 | ||
13 | #include <linux/module.h> | 14 | #include <linux/module.h> |
14 | #include <linux/init.h> | 15 | #include <linux/init.h> |
diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c index 0c72aadb8391..9821c5886613 100644 --- a/drivers/s390/char/tape_3590.c +++ b/drivers/s390/char/tape_3590.c | |||
@@ -9,6 +9,7 @@ | |||
9 | */ | 9 | */ |
10 | 10 | ||
11 | #define KMSG_COMPONENT "tape_3590" | 11 | #define KMSG_COMPONENT "tape_3590" |
12 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt | ||
12 | 13 | ||
13 | #include <linux/module.h> | 14 | #include <linux/module.h> |
14 | #include <linux/init.h> | 15 | #include <linux/init.h> |
@@ -136,7 +137,7 @@ static void int_to_ext_kekl(struct tape3592_kekl *in, | |||
136 | out->type_on_tape = TAPE390_KEKL_TYPE_LABEL; | 137 | out->type_on_tape = TAPE390_KEKL_TYPE_LABEL; |
137 | memcpy(out->label, in->label, sizeof(in->label)); | 138 | memcpy(out->label, in->label, sizeof(in->label)); |
138 | EBCASC(out->label, sizeof(in->label)); | 139 | EBCASC(out->label, sizeof(in->label)); |
139 | strstrip(out->label); | 140 | strim(out->label); |
140 | } | 141 | } |
141 | 142 | ||
142 | static void int_to_ext_kekl_pair(struct tape3592_kekl_pair *in, | 143 | static void int_to_ext_kekl_pair(struct tape3592_kekl_pair *in, |
diff --git a/drivers/s390/char/tape_block.c b/drivers/s390/char/tape_block.c index 4799cc2f73c3..96816149368a 100644 --- a/drivers/s390/char/tape_block.c +++ b/drivers/s390/char/tape_block.c | |||
@@ -11,6 +11,7 @@ | |||
11 | */ | 11 | */ |
12 | 12 | ||
13 | #define KMSG_COMPONENT "tape" | 13 | #define KMSG_COMPONENT "tape" |
14 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt | ||
14 | 15 | ||
15 | #include <linux/fs.h> | 16 | #include <linux/fs.h> |
16 | #include <linux/module.h> | 17 | #include <linux/module.h> |
diff --git a/drivers/s390/char/tape_char.c b/drivers/s390/char/tape_char.c index 23d773a0d113..2125ec7d95f0 100644 --- a/drivers/s390/char/tape_char.c +++ b/drivers/s390/char/tape_char.c | |||
@@ -10,6 +10,9 @@ | |||
10 | * Martin Schwidefsky <schwidefsky@de.ibm.com> | 10 | * Martin Schwidefsky <schwidefsky@de.ibm.com> |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #define KMSG_COMPONENT "tape" | ||
14 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt | ||
15 | |||
13 | #include <linux/module.h> | 16 | #include <linux/module.h> |
14 | #include <linux/types.h> | 17 | #include <linux/types.h> |
15 | #include <linux/proc_fs.h> | 18 | #include <linux/proc_fs.h> |
diff --git a/drivers/s390/char/tape_class.c b/drivers/s390/char/tape_class.c index ddc914ccea8f..b2864e3edb6d 100644 --- a/drivers/s390/char/tape_class.c +++ b/drivers/s390/char/tape_class.c | |||
@@ -7,6 +7,10 @@ | |||
7 | * Author: Stefan Bader <shbader@de.ibm.com> | 7 | * Author: Stefan Bader <shbader@de.ibm.com> |
8 | * Based on simple class device code by Greg K-H | 8 | * Based on simple class device code by Greg K-H |
9 | */ | 9 | */ |
10 | |||
11 | #define KMSG_COMPONENT "tape" | ||
12 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt | ||
13 | |||
10 | #include "tape_class.h" | 14 | #include "tape_class.h" |
11 | 15 | ||
12 | MODULE_AUTHOR("Stefan Bader <shbader@de.ibm.com>"); | 16 | MODULE_AUTHOR("Stefan Bader <shbader@de.ibm.com>"); |
diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c index f5d6802dc5da..81b094e480e6 100644 --- a/drivers/s390/char/tape_core.c +++ b/drivers/s390/char/tape_core.c | |||
@@ -12,6 +12,8 @@ | |||
12 | */ | 12 | */ |
13 | 13 | ||
14 | #define KMSG_COMPONENT "tape" | 14 | #define KMSG_COMPONENT "tape" |
15 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt | ||
16 | |||
15 | #include <linux/module.h> | 17 | #include <linux/module.h> |
16 | #include <linux/init.h> // for kernel parameters | 18 | #include <linux/init.h> // for kernel parameters |
17 | #include <linux/kmod.h> // for requesting modules | 19 | #include <linux/kmod.h> // for requesting modules |
diff --git a/drivers/s390/char/tape_proc.c b/drivers/s390/char/tape_proc.c index ebd820ccfb24..0ceb37984f77 100644 --- a/drivers/s390/char/tape_proc.c +++ b/drivers/s390/char/tape_proc.c | |||
@@ -11,6 +11,9 @@ | |||
11 | * PROCFS Functions | 11 | * PROCFS Functions |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #define KMSG_COMPONENT "tape" | ||
15 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt | ||
16 | |||
14 | #include <linux/module.h> | 17 | #include <linux/module.h> |
15 | #include <linux/vmalloc.h> | 18 | #include <linux/vmalloc.h> |
16 | #include <linux/seq_file.h> | 19 | #include <linux/seq_file.h> |
diff --git a/drivers/s390/char/tape_std.c b/drivers/s390/char/tape_std.c index 750354ad16e5..03f07e5dd6e9 100644 --- a/drivers/s390/char/tape_std.c +++ b/drivers/s390/char/tape_std.c | |||
@@ -11,6 +11,9 @@ | |||
11 | * Stefan Bader <shbader@de.ibm.com> | 11 | * Stefan Bader <shbader@de.ibm.com> |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #define KMSG_COMPONENT "tape" | ||
15 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt | ||
16 | |||
14 | #include <linux/stddef.h> | 17 | #include <linux/stddef.h> |
15 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
16 | #include <linux/bio.h> | 19 | #include <linux/bio.h> |
diff --git a/drivers/s390/cio/ccwreq.c b/drivers/s390/cio/ccwreq.c index 9509e3860934..7a28a3029a3f 100644 --- a/drivers/s390/cio/ccwreq.c +++ b/drivers/s390/cio/ccwreq.c | |||
@@ -49,7 +49,6 @@ static u16 ccwreq_next_path(struct ccw_device *cdev) | |||
49 | */ | 49 | */ |
50 | static void ccwreq_stop(struct ccw_device *cdev, int rc) | 50 | static void ccwreq_stop(struct ccw_device *cdev, int rc) |
51 | { | 51 | { |
52 | struct subchannel *sch = to_subchannel(cdev->dev.parent); | ||
53 | struct ccw_request *req = &cdev->private->req; | 52 | struct ccw_request *req = &cdev->private->req; |
54 | 53 | ||
55 | if (req->done) | 54 | if (req->done) |
@@ -57,7 +56,6 @@ static void ccwreq_stop(struct ccw_device *cdev, int rc) | |||
57 | req->done = 1; | 56 | req->done = 1; |
58 | ccw_device_set_timeout(cdev, 0); | 57 | ccw_device_set_timeout(cdev, 0); |
59 | memset(&cdev->private->irb, 0, sizeof(struct irb)); | 58 | memset(&cdev->private->irb, 0, sizeof(struct irb)); |
60 | sch->lpm = sch->schib.pmcw.pam; | ||
61 | if (rc && rc != -ENODEV && req->drc) | 59 | if (rc && rc != -ENODEV && req->drc) |
62 | rc = req->drc; | 60 | rc = req->drc; |
63 | req->callback(cdev, req->data, rc); | 61 | req->callback(cdev, req->data, rc); |
@@ -80,7 +78,6 @@ static void ccwreq_do(struct ccw_device *cdev) | |||
80 | continue; | 78 | continue; |
81 | } | 79 | } |
82 | /* Perform start function. */ | 80 | /* Perform start function. */ |
83 | sch->lpm = 0xff; | ||
84 | memset(&cdev->private->irb, 0, sizeof(struct irb)); | 81 | memset(&cdev->private->irb, 0, sizeof(struct irb)); |
85 | rc = cio_start(sch, cp, (u8) req->mask); | 82 | rc = cio_start(sch, cp, (u8) req->mask); |
86 | if (rc == 0) { | 83 | if (rc == 0) { |
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index 73901c9e260f..a6c7d5426fb2 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c | |||
@@ -1519,6 +1519,7 @@ static int ccw_device_console_enable(struct ccw_device *cdev, | |||
1519 | sch->driver = &io_subchannel_driver; | 1519 | sch->driver = &io_subchannel_driver; |
1520 | /* Initialize the ccw_device structure. */ | 1520 | /* Initialize the ccw_device structure. */ |
1521 | cdev->dev.parent= &sch->dev; | 1521 | cdev->dev.parent= &sch->dev; |
1522 | sch_set_cdev(sch, cdev); | ||
1522 | io_subchannel_recog(cdev, sch); | 1523 | io_subchannel_recog(cdev, sch); |
1523 | /* Now wait for the async. recognition to come to an end. */ | 1524 | /* Now wait for the async. recognition to come to an end. */ |
1524 | spin_lock_irq(cdev->ccwlock); | 1525 | spin_lock_irq(cdev->ccwlock); |
diff --git a/drivers/s390/cio/device_pgid.c b/drivers/s390/cio/device_pgid.c index aad188e43b4f..6facb5499a65 100644 --- a/drivers/s390/cio/device_pgid.c +++ b/drivers/s390/cio/device_pgid.c | |||
@@ -142,7 +142,7 @@ static void spid_do(struct ccw_device *cdev) | |||
142 | u8 fn; | 142 | u8 fn; |
143 | 143 | ||
144 | /* Use next available path that is not already in correct state. */ | 144 | /* Use next available path that is not already in correct state. */ |
145 | req->lpm = lpm_adjust(req->lpm, sch->schib.pmcw.pam & ~sch->vpm); | 145 | req->lpm = lpm_adjust(req->lpm, cdev->private->pgid_todo_mask); |
146 | if (!req->lpm) | 146 | if (!req->lpm) |
147 | goto out_nopath; | 147 | goto out_nopath; |
148 | /* Channel program setup. */ | 148 | /* Channel program setup. */ |
@@ -254,15 +254,15 @@ static void pgid_analyze(struct ccw_device *cdev, struct pgid **p, | |||
254 | *p = first; | 254 | *p = first; |
255 | } | 255 | } |
256 | 256 | ||
257 | static u8 pgid_to_vpm(struct ccw_device *cdev) | 257 | static u8 pgid_to_donepm(struct ccw_device *cdev) |
258 | { | 258 | { |
259 | struct subchannel *sch = to_subchannel(cdev->dev.parent); | 259 | struct subchannel *sch = to_subchannel(cdev->dev.parent); |
260 | struct pgid *pgid; | 260 | struct pgid *pgid; |
261 | int i; | 261 | int i; |
262 | int lpm; | 262 | int lpm; |
263 | u8 vpm = 0; | 263 | u8 donepm = 0; |
264 | 264 | ||
265 | /* Set VPM bits for paths which are already in the target state. */ | 265 | /* Set bits for paths which are already in the target state. */ |
266 | for (i = 0; i < 8; i++) { | 266 | for (i = 0; i < 8; i++) { |
267 | lpm = 0x80 >> i; | 267 | lpm = 0x80 >> i; |
268 | if ((cdev->private->pgid_valid_mask & lpm) == 0) | 268 | if ((cdev->private->pgid_valid_mask & lpm) == 0) |
@@ -282,10 +282,10 @@ static u8 pgid_to_vpm(struct ccw_device *cdev) | |||
282 | if (pgid->inf.ps.state3 != SNID_STATE3_SINGLE_PATH) | 282 | if (pgid->inf.ps.state3 != SNID_STATE3_SINGLE_PATH) |
283 | continue; | 283 | continue; |
284 | } | 284 | } |
285 | vpm |= lpm; | 285 | donepm |= lpm; |
286 | } | 286 | } |
287 | 287 | ||
288 | return vpm; | 288 | return donepm; |
289 | } | 289 | } |
290 | 290 | ||
291 | static void pgid_fill(struct ccw_device *cdev, struct pgid *pgid) | 291 | static void pgid_fill(struct ccw_device *cdev, struct pgid *pgid) |
@@ -307,6 +307,7 @@ static void snid_done(struct ccw_device *cdev, int rc) | |||
307 | int mismatch = 0; | 307 | int mismatch = 0; |
308 | int reserved = 0; | 308 | int reserved = 0; |
309 | int reset = 0; | 309 | int reset = 0; |
310 | u8 donepm; | ||
310 | 311 | ||
311 | if (rc) | 312 | if (rc) |
312 | goto out; | 313 | goto out; |
@@ -316,18 +317,20 @@ static void snid_done(struct ccw_device *cdev, int rc) | |||
316 | else if (mismatch) | 317 | else if (mismatch) |
317 | rc = -EOPNOTSUPP; | 318 | rc = -EOPNOTSUPP; |
318 | else { | 319 | else { |
319 | sch->vpm = pgid_to_vpm(cdev); | 320 | donepm = pgid_to_donepm(cdev); |
321 | sch->vpm = donepm & sch->opm; | ||
322 | cdev->private->pgid_todo_mask &= ~donepm; | ||
320 | pgid_fill(cdev, pgid); | 323 | pgid_fill(cdev, pgid); |
321 | } | 324 | } |
322 | out: | 325 | out: |
323 | CIO_MSG_EVENT(2, "snid: device 0.%x.%04x: rc=%d pvm=%02x vpm=%02x " | 326 | CIO_MSG_EVENT(2, "snid: device 0.%x.%04x: rc=%d pvm=%02x vpm=%02x " |
324 | "mism=%d rsvd=%d reset=%d\n", id->ssid, id->devno, rc, | 327 | "todo=%02x mism=%d rsvd=%d reset=%d\n", id->ssid, |
325 | cdev->private->pgid_valid_mask, sch->vpm, mismatch, | 328 | id->devno, rc, cdev->private->pgid_valid_mask, sch->vpm, |
326 | reserved, reset); | 329 | cdev->private->pgid_todo_mask, mismatch, reserved, reset); |
327 | switch (rc) { | 330 | switch (rc) { |
328 | case 0: | 331 | case 0: |
329 | /* Anything left to do? */ | 332 | /* Anything left to do? */ |
330 | if (sch->vpm == sch->schib.pmcw.pam) { | 333 | if (cdev->private->pgid_todo_mask == 0) { |
331 | verify_done(cdev, sch->vpm == 0 ? -EACCES : 0); | 334 | verify_done(cdev, sch->vpm == 0 ? -EACCES : 0); |
332 | return; | 335 | return; |
333 | } | 336 | } |
@@ -411,6 +414,7 @@ static void verify_start(struct ccw_device *cdev) | |||
411 | struct ccw_dev_id *devid = &cdev->private->dev_id; | 414 | struct ccw_dev_id *devid = &cdev->private->dev_id; |
412 | 415 | ||
413 | sch->vpm = 0; | 416 | sch->vpm = 0; |
417 | sch->lpm = sch->schib.pmcw.pam; | ||
414 | /* Initialize request data. */ | 418 | /* Initialize request data. */ |
415 | memset(req, 0, sizeof(*req)); | 419 | memset(req, 0, sizeof(*req)); |
416 | req->timeout = PGID_TIMEOUT; | 420 | req->timeout = PGID_TIMEOUT; |
@@ -442,11 +446,14 @@ static void verify_start(struct ccw_device *cdev) | |||
442 | */ | 446 | */ |
443 | void ccw_device_verify_start(struct ccw_device *cdev) | 447 | void ccw_device_verify_start(struct ccw_device *cdev) |
444 | { | 448 | { |
449 | struct subchannel *sch = to_subchannel(cdev->dev.parent); | ||
450 | |||
445 | CIO_TRACE_EVENT(4, "vrfy"); | 451 | CIO_TRACE_EVENT(4, "vrfy"); |
446 | CIO_HEX_EVENT(4, &cdev->private->dev_id, sizeof(cdev->private->dev_id)); | 452 | CIO_HEX_EVENT(4, &cdev->private->dev_id, sizeof(cdev->private->dev_id)); |
447 | /* Initialize PGID data. */ | 453 | /* Initialize PGID data. */ |
448 | memset(cdev->private->pgid, 0, sizeof(cdev->private->pgid)); | 454 | memset(cdev->private->pgid, 0, sizeof(cdev->private->pgid)); |
449 | cdev->private->pgid_valid_mask = 0; | 455 | cdev->private->pgid_valid_mask = 0; |
456 | cdev->private->pgid_todo_mask = sch->schib.pmcw.pam; | ||
450 | /* | 457 | /* |
451 | * Initialize pathgroup and multipath state with target values. | 458 | * Initialize pathgroup and multipath state with target values. |
452 | * They may change in the course of path verification. | 459 | * They may change in the course of path verification. |
diff --git a/drivers/s390/cio/fcx.c b/drivers/s390/cio/fcx.c index 61677dfbdc9b..ca5e9bb9d458 100644 --- a/drivers/s390/cio/fcx.c +++ b/drivers/s390/cio/fcx.c | |||
@@ -163,7 +163,7 @@ void tcw_finalize(struct tcw *tcw, int num_tidaws) | |||
163 | /* Add tcat to tccb. */ | 163 | /* Add tcat to tccb. */ |
164 | tccb = tcw_get_tccb(tcw); | 164 | tccb = tcw_get_tccb(tcw); |
165 | tcat = (struct tccb_tcat *) &tccb->tca[tca_size(tccb)]; | 165 | tcat = (struct tccb_tcat *) &tccb->tca[tca_size(tccb)]; |
166 | memset(tcat, 0, sizeof(tcat)); | 166 | memset(tcat, 0, sizeof(*tcat)); |
167 | /* Calculate tcw input/output count and tcat transport count. */ | 167 | /* Calculate tcw input/output count and tcat transport count. */ |
168 | count = calc_dcw_count(tccb); | 168 | count = calc_dcw_count(tccb); |
169 | if (tcw->w && (tcw->flags & TCW_FLAGS_OUTPUT_TIDA)) | 169 | if (tcw->w && (tcw->flags & TCW_FLAGS_OUTPUT_TIDA)) |
@@ -269,7 +269,7 @@ EXPORT_SYMBOL(tccb_init); | |||
269 | */ | 269 | */ |
270 | void tsb_init(struct tsb *tsb) | 270 | void tsb_init(struct tsb *tsb) |
271 | { | 271 | { |
272 | memset(tsb, 0, sizeof(tsb)); | 272 | memset(tsb, 0, sizeof(*tsb)); |
273 | } | 273 | } |
274 | EXPORT_SYMBOL(tsb_init); | 274 | EXPORT_SYMBOL(tsb_init); |
275 | 275 | ||
diff --git a/drivers/s390/cio/io_sch.h b/drivers/s390/cio/io_sch.h index d72ae4c93af9..b9ce712a7f25 100644 --- a/drivers/s390/cio/io_sch.h +++ b/drivers/s390/cio/io_sch.h | |||
@@ -150,6 +150,7 @@ struct ccw_device_private { | |||
150 | struct ccw_request req; /* internal I/O request */ | 150 | struct ccw_request req; /* internal I/O request */ |
151 | int iretry; | 151 | int iretry; |
152 | u8 pgid_valid_mask; /* mask of valid PGIDs */ | 152 | u8 pgid_valid_mask; /* mask of valid PGIDs */ |
153 | u8 pgid_todo_mask; /* mask of PGIDs to be adjusted */ | ||
153 | struct { | 154 | struct { |
154 | unsigned int fast:1; /* post with "channel end" */ | 155 | unsigned int fast:1; /* post with "channel end" */ |
155 | unsigned int repall:1; /* report every interrupt status */ | 156 | unsigned int repall:1; /* report every interrupt status */ |
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c index 4be6e84b9599..b2275c5000e7 100644 --- a/drivers/s390/cio/qdio_main.c +++ b/drivers/s390/cio/qdio_main.c | |||
@@ -486,7 +486,8 @@ static int get_inbound_buffer_frontier(struct qdio_q *q) | |||
486 | case SLSB_P_INPUT_PRIMED: | 486 | case SLSB_P_INPUT_PRIMED: |
487 | inbound_primed(q, count); | 487 | inbound_primed(q, count); |
488 | q->first_to_check = add_buf(q->first_to_check, count); | 488 | q->first_to_check = add_buf(q->first_to_check, count); |
489 | atomic_sub(count, &q->nr_buf_used); | 489 | if (atomic_sub(count, &q->nr_buf_used) == 0) |
490 | qdio_perf_stat_inc(&perf_stats.inbound_queue_full); | ||
490 | break; | 491 | break; |
491 | case SLSB_P_INPUT_ERROR: | 492 | case SLSB_P_INPUT_ERROR: |
492 | announce_buffer_error(q, count); | 493 | announce_buffer_error(q, count); |
diff --git a/drivers/s390/cio/qdio_perf.c b/drivers/s390/cio/qdio_perf.c index 968e3c7c2632..54f7c325a3e6 100644 --- a/drivers/s390/cio/qdio_perf.c +++ b/drivers/s390/cio/qdio_perf.c | |||
@@ -64,6 +64,8 @@ static int qdio_perf_proc_show(struct seq_file *m, void *v) | |||
64 | (long)atomic_long_read(&perf_stats.fast_requeue)); | 64 | (long)atomic_long_read(&perf_stats.fast_requeue)); |
65 | seq_printf(m, "Number of outbound target full condition\t: %li\n", | 65 | seq_printf(m, "Number of outbound target full condition\t: %li\n", |
66 | (long)atomic_long_read(&perf_stats.outbound_target_full)); | 66 | (long)atomic_long_read(&perf_stats.outbound_target_full)); |
67 | seq_printf(m, "Number of inbound queue full condition\t\t: %li\n", | ||
68 | (long)atomic_long_read(&perf_stats.inbound_queue_full)); | ||
67 | seq_printf(m, "Number of outbound tasklet mod_timer calls\t: %li\n", | 69 | seq_printf(m, "Number of outbound tasklet mod_timer calls\t: %li\n", |
68 | (long)atomic_long_read(&perf_stats.debug_tl_out_timer)); | 70 | (long)atomic_long_read(&perf_stats.debug_tl_out_timer)); |
69 | seq_printf(m, "Number of stop polling calls\t\t\t: %li\n", | 71 | seq_printf(m, "Number of stop polling calls\t\t\t: %li\n", |
diff --git a/drivers/s390/cio/qdio_perf.h b/drivers/s390/cio/qdio_perf.h index ff4504ce1e3c..12454231dc8b 100644 --- a/drivers/s390/cio/qdio_perf.h +++ b/drivers/s390/cio/qdio_perf.h | |||
@@ -36,6 +36,7 @@ struct qdio_perf_stats { | |||
36 | atomic_long_t outbound_handler; | 36 | atomic_long_t outbound_handler; |
37 | atomic_long_t fast_requeue; | 37 | atomic_long_t fast_requeue; |
38 | atomic_long_t outbound_target_full; | 38 | atomic_long_t outbound_target_full; |
39 | atomic_long_t inbound_queue_full; | ||
39 | 40 | ||
40 | /* for debugging */ | 41 | /* for debugging */ |
41 | atomic_long_t debug_tl_out_timer; | 42 | atomic_long_t debug_tl_out_timer; |
diff --git a/drivers/s390/cio/qdio_setup.c b/drivers/s390/cio/qdio_setup.c index 18d54fc21ce9..8c2dea5fa2b4 100644 --- a/drivers/s390/cio/qdio_setup.c +++ b/drivers/s390/cio/qdio_setup.c | |||
@@ -48,7 +48,6 @@ static void set_impl_params(struct qdio_irq *irq_ptr, | |||
48 | if (!irq_ptr) | 48 | if (!irq_ptr) |
49 | return; | 49 | return; |
50 | 50 | ||
51 | WARN_ON((unsigned long)&irq_ptr->qib & 0xff); | ||
52 | irq_ptr->qib.pfmt = qib_param_field_format; | 51 | irq_ptr->qib.pfmt = qib_param_field_format; |
53 | if (qib_param_field) | 52 | if (qib_param_field) |
54 | memcpy(irq_ptr->qib.parm, qib_param_field, | 53 | memcpy(irq_ptr->qib.parm, qib_param_field, |
@@ -82,14 +81,12 @@ static int __qdio_allocate_qs(struct qdio_q **irq_ptr_qs, int nr_queues) | |||
82 | q = kmem_cache_alloc(qdio_q_cache, GFP_KERNEL); | 81 | q = kmem_cache_alloc(qdio_q_cache, GFP_KERNEL); |
83 | if (!q) | 82 | if (!q) |
84 | return -ENOMEM; | 83 | return -ENOMEM; |
85 | WARN_ON((unsigned long)q & 0xff); | ||
86 | 84 | ||
87 | q->slib = (struct slib *) __get_free_page(GFP_KERNEL); | 85 | q->slib = (struct slib *) __get_free_page(GFP_KERNEL); |
88 | if (!q->slib) { | 86 | if (!q->slib) { |
89 | kmem_cache_free(qdio_q_cache, q); | 87 | kmem_cache_free(qdio_q_cache, q); |
90 | return -ENOMEM; | 88 | return -ENOMEM; |
91 | } | 89 | } |
92 | WARN_ON((unsigned long)q->slib & 0x7ff); | ||
93 | irq_ptr_qs[i] = q; | 90 | irq_ptr_qs[i] = q; |
94 | } | 91 | } |
95 | return 0; | 92 | return 0; |
@@ -131,7 +128,7 @@ static void setup_storage_lists(struct qdio_q *q, struct qdio_irq *irq_ptr, | |||
131 | /* fill in sbal */ | 128 | /* fill in sbal */ |
132 | for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; j++) { | 129 | for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; j++) { |
133 | q->sbal[j] = *sbals_array++; | 130 | q->sbal[j] = *sbals_array++; |
134 | WARN_ON((unsigned long)q->sbal[j] & 0xff); | 131 | BUG_ON((unsigned long)q->sbal[j] & 0xff); |
135 | } | 132 | } |
136 | 133 | ||
137 | /* fill in slib */ | 134 | /* fill in slib */ |
@@ -147,11 +144,6 @@ static void setup_storage_lists(struct qdio_q *q, struct qdio_irq *irq_ptr, | |||
147 | /* fill in sl */ | 144 | /* fill in sl */ |
148 | for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; j++) | 145 | for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; j++) |
149 | q->sl->element[j].sbal = (unsigned long)q->sbal[j]; | 146 | q->sl->element[j].sbal = (unsigned long)q->sbal[j]; |
150 | |||
151 | DBF_EVENT("sl-slsb-sbal"); | ||
152 | DBF_HEX(q->sl, sizeof(void *)); | ||
153 | DBF_HEX(&q->slsb, sizeof(void *)); | ||
154 | DBF_HEX(q->sbal, sizeof(void *)); | ||
155 | } | 147 | } |
156 | 148 | ||
157 | static void setup_queues(struct qdio_irq *irq_ptr, | 149 | static void setup_queues(struct qdio_irq *irq_ptr, |
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index b7689f3d05f5..c28a712fd4db 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c | |||
@@ -517,7 +517,7 @@ static void iscsi_free_task(struct iscsi_task *task) | |||
517 | if (conn->login_task == task) | 517 | if (conn->login_task == task) |
518 | return; | 518 | return; |
519 | 519 | ||
520 | __kfifo_put(session->cmdpool.queue, (void*)&task, sizeof(void*)); | 520 | kfifo_in(&session->cmdpool.queue, (void*)&task, sizeof(void*)); |
521 | 521 | ||
522 | if (sc) { | 522 | if (sc) { |
523 | task->sc = NULL; | 523 | task->sc = NULL; |
@@ -737,7 +737,7 @@ __iscsi_conn_send_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, | |||
737 | BUG_ON(conn->c_stage == ISCSI_CONN_INITIAL_STAGE); | 737 | BUG_ON(conn->c_stage == ISCSI_CONN_INITIAL_STAGE); |
738 | BUG_ON(conn->c_stage == ISCSI_CONN_STOPPED); | 738 | BUG_ON(conn->c_stage == ISCSI_CONN_STOPPED); |
739 | 739 | ||
740 | if (!__kfifo_get(session->cmdpool.queue, | 740 | if (!kfifo_out(&session->cmdpool.queue, |
741 | (void*)&task, sizeof(void*))) | 741 | (void*)&task, sizeof(void*))) |
742 | return NULL; | 742 | return NULL; |
743 | } | 743 | } |
@@ -1567,7 +1567,7 @@ static inline struct iscsi_task *iscsi_alloc_task(struct iscsi_conn *conn, | |||
1567 | { | 1567 | { |
1568 | struct iscsi_task *task; | 1568 | struct iscsi_task *task; |
1569 | 1569 | ||
1570 | if (!__kfifo_get(conn->session->cmdpool.queue, | 1570 | if (!kfifo_out(&conn->session->cmdpool.queue, |
1571 | (void *) &task, sizeof(void *))) | 1571 | (void *) &task, sizeof(void *))) |
1572 | return NULL; | 1572 | return NULL; |
1573 | 1573 | ||
@@ -2461,12 +2461,7 @@ iscsi_pool_init(struct iscsi_pool *q, int max, void ***items, int item_size) | |||
2461 | if (q->pool == NULL) | 2461 | if (q->pool == NULL) |
2462 | return -ENOMEM; | 2462 | return -ENOMEM; |
2463 | 2463 | ||
2464 | q->queue = kfifo_init((void*)q->pool, max * sizeof(void*), | 2464 | kfifo_init(&q->queue, (void*)q->pool, max * sizeof(void*)); |
2465 | GFP_KERNEL, NULL); | ||
2466 | if (IS_ERR(q->queue)) { | ||
2467 | q->queue = NULL; | ||
2468 | goto enomem; | ||
2469 | } | ||
2470 | 2465 | ||
2471 | for (i = 0; i < max; i++) { | 2466 | for (i = 0; i < max; i++) { |
2472 | q->pool[i] = kzalloc(item_size, GFP_KERNEL); | 2467 | q->pool[i] = kzalloc(item_size, GFP_KERNEL); |
@@ -2474,7 +2469,7 @@ iscsi_pool_init(struct iscsi_pool *q, int max, void ***items, int item_size) | |||
2474 | q->max = i; | 2469 | q->max = i; |
2475 | goto enomem; | 2470 | goto enomem; |
2476 | } | 2471 | } |
2477 | __kfifo_put(q->queue, (void*)&q->pool[i], sizeof(void*)); | 2472 | kfifo_in(&q->queue, (void*)&q->pool[i], sizeof(void*)); |
2478 | } | 2473 | } |
2479 | 2474 | ||
2480 | if (items) { | 2475 | if (items) { |
@@ -2497,7 +2492,6 @@ void iscsi_pool_free(struct iscsi_pool *q) | |||
2497 | for (i = 0; i < q->max; i++) | 2492 | for (i = 0; i < q->max; i++) |
2498 | kfree(q->pool[i]); | 2493 | kfree(q->pool[i]); |
2499 | kfree(q->pool); | 2494 | kfree(q->pool); |
2500 | kfree(q->queue); | ||
2501 | } | 2495 | } |
2502 | EXPORT_SYMBOL_GPL(iscsi_pool_free); | 2496 | EXPORT_SYMBOL_GPL(iscsi_pool_free); |
2503 | 2497 | ||
@@ -2825,7 +2819,7 @@ iscsi_conn_setup(struct iscsi_cls_session *cls_session, int dd_size, | |||
2825 | 2819 | ||
2826 | /* allocate login_task used for the login/text sequences */ | 2820 | /* allocate login_task used for the login/text sequences */ |
2827 | spin_lock_bh(&session->lock); | 2821 | spin_lock_bh(&session->lock); |
2828 | if (!__kfifo_get(session->cmdpool.queue, | 2822 | if (!kfifo_out(&session->cmdpool.queue, |
2829 | (void*)&conn->login_task, | 2823 | (void*)&conn->login_task, |
2830 | sizeof(void*))) { | 2824 | sizeof(void*))) { |
2831 | spin_unlock_bh(&session->lock); | 2825 | spin_unlock_bh(&session->lock); |
@@ -2845,7 +2839,7 @@ iscsi_conn_setup(struct iscsi_cls_session *cls_session, int dd_size, | |||
2845 | return cls_conn; | 2839 | return cls_conn; |
2846 | 2840 | ||
2847 | login_task_data_alloc_fail: | 2841 | login_task_data_alloc_fail: |
2848 | __kfifo_put(session->cmdpool.queue, (void*)&conn->login_task, | 2842 | kfifo_in(&session->cmdpool.queue, (void*)&conn->login_task, |
2849 | sizeof(void*)); | 2843 | sizeof(void*)); |
2850 | login_task_alloc_fail: | 2844 | login_task_alloc_fail: |
2851 | iscsi_destroy_conn(cls_conn); | 2845 | iscsi_destroy_conn(cls_conn); |
@@ -2908,7 +2902,7 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn) | |||
2908 | free_pages((unsigned long) conn->data, | 2902 | free_pages((unsigned long) conn->data, |
2909 | get_order(ISCSI_DEF_MAX_RECV_SEG_LEN)); | 2903 | get_order(ISCSI_DEF_MAX_RECV_SEG_LEN)); |
2910 | kfree(conn->persistent_address); | 2904 | kfree(conn->persistent_address); |
2911 | __kfifo_put(session->cmdpool.queue, (void*)&conn->login_task, | 2905 | kfifo_in(&session->cmdpool.queue, (void*)&conn->login_task, |
2912 | sizeof(void*)); | 2906 | sizeof(void*)); |
2913 | if (session->leadconn == conn) | 2907 | if (session->leadconn == conn) |
2914 | session->leadconn = NULL; | 2908 | session->leadconn = NULL; |
diff --git a/drivers/scsi/libiscsi_tcp.c b/drivers/scsi/libiscsi_tcp.c index ca25ee5190b0..db6856c138fc 100644 --- a/drivers/scsi/libiscsi_tcp.c +++ b/drivers/scsi/libiscsi_tcp.c | |||
@@ -445,15 +445,15 @@ void iscsi_tcp_cleanup_task(struct iscsi_task *task) | |||
445 | return; | 445 | return; |
446 | 446 | ||
447 | /* flush task's r2t queues */ | 447 | /* flush task's r2t queues */ |
448 | while (__kfifo_get(tcp_task->r2tqueue, (void*)&r2t, sizeof(void*))) { | 448 | while (kfifo_out(&tcp_task->r2tqueue, (void*)&r2t, sizeof(void*))) { |
449 | __kfifo_put(tcp_task->r2tpool.queue, (void*)&r2t, | 449 | kfifo_in(&tcp_task->r2tpool.queue, (void*)&r2t, |
450 | sizeof(void*)); | 450 | sizeof(void*)); |
451 | ISCSI_DBG_TCP(task->conn, "pending r2t dropped\n"); | 451 | ISCSI_DBG_TCP(task->conn, "pending r2t dropped\n"); |
452 | } | 452 | } |
453 | 453 | ||
454 | r2t = tcp_task->r2t; | 454 | r2t = tcp_task->r2t; |
455 | if (r2t != NULL) { | 455 | if (r2t != NULL) { |
456 | __kfifo_put(tcp_task->r2tpool.queue, (void*)&r2t, | 456 | kfifo_in(&tcp_task->r2tpool.queue, (void*)&r2t, |
457 | sizeof(void*)); | 457 | sizeof(void*)); |
458 | tcp_task->r2t = NULL; | 458 | tcp_task->r2t = NULL; |
459 | } | 459 | } |
@@ -541,7 +541,7 @@ static int iscsi_tcp_r2t_rsp(struct iscsi_conn *conn, struct iscsi_task *task) | |||
541 | return 0; | 541 | return 0; |
542 | } | 542 | } |
543 | 543 | ||
544 | rc = __kfifo_get(tcp_task->r2tpool.queue, (void*)&r2t, sizeof(void*)); | 544 | rc = kfifo_out(&tcp_task->r2tpool.queue, (void*)&r2t, sizeof(void*)); |
545 | if (!rc) { | 545 | if (!rc) { |
546 | iscsi_conn_printk(KERN_ERR, conn, "Could not allocate R2T. " | 546 | iscsi_conn_printk(KERN_ERR, conn, "Could not allocate R2T. " |
547 | "Target has sent more R2Ts than it " | 547 | "Target has sent more R2Ts than it " |
@@ -554,7 +554,7 @@ static int iscsi_tcp_r2t_rsp(struct iscsi_conn *conn, struct iscsi_task *task) | |||
554 | if (r2t->data_length == 0) { | 554 | if (r2t->data_length == 0) { |
555 | iscsi_conn_printk(KERN_ERR, conn, | 555 | iscsi_conn_printk(KERN_ERR, conn, |
556 | "invalid R2T with zero data len\n"); | 556 | "invalid R2T with zero data len\n"); |
557 | __kfifo_put(tcp_task->r2tpool.queue, (void*)&r2t, | 557 | kfifo_in(&tcp_task->r2tpool.queue, (void*)&r2t, |
558 | sizeof(void*)); | 558 | sizeof(void*)); |
559 | return ISCSI_ERR_DATALEN; | 559 | return ISCSI_ERR_DATALEN; |
560 | } | 560 | } |
@@ -570,7 +570,7 @@ static int iscsi_tcp_r2t_rsp(struct iscsi_conn *conn, struct iscsi_task *task) | |||
570 | "invalid R2T with data len %u at offset %u " | 570 | "invalid R2T with data len %u at offset %u " |
571 | "and total length %d\n", r2t->data_length, | 571 | "and total length %d\n", r2t->data_length, |
572 | r2t->data_offset, scsi_out(task->sc)->length); | 572 | r2t->data_offset, scsi_out(task->sc)->length); |
573 | __kfifo_put(tcp_task->r2tpool.queue, (void*)&r2t, | 573 | kfifo_in(&tcp_task->r2tpool.queue, (void*)&r2t, |
574 | sizeof(void*)); | 574 | sizeof(void*)); |
575 | return ISCSI_ERR_DATALEN; | 575 | return ISCSI_ERR_DATALEN; |
576 | } | 576 | } |
@@ -580,7 +580,7 @@ static int iscsi_tcp_r2t_rsp(struct iscsi_conn *conn, struct iscsi_task *task) | |||
580 | r2t->sent = 0; | 580 | r2t->sent = 0; |
581 | 581 | ||
582 | tcp_task->exp_datasn = r2tsn + 1; | 582 | tcp_task->exp_datasn = r2tsn + 1; |
583 | __kfifo_put(tcp_task->r2tqueue, (void*)&r2t, sizeof(void*)); | 583 | kfifo_in(&tcp_task->r2tqueue, (void*)&r2t, sizeof(void*)); |
584 | conn->r2t_pdus_cnt++; | 584 | conn->r2t_pdus_cnt++; |
585 | 585 | ||
586 | iscsi_requeue_task(task); | 586 | iscsi_requeue_task(task); |
@@ -951,7 +951,7 @@ int iscsi_tcp_task_init(struct iscsi_task *task) | |||
951 | return conn->session->tt->init_pdu(task, 0, task->data_count); | 951 | return conn->session->tt->init_pdu(task, 0, task->data_count); |
952 | } | 952 | } |
953 | 953 | ||
954 | BUG_ON(__kfifo_len(tcp_task->r2tqueue)); | 954 | BUG_ON(kfifo_len(&tcp_task->r2tqueue)); |
955 | tcp_task->exp_datasn = 0; | 955 | tcp_task->exp_datasn = 0; |
956 | 956 | ||
957 | /* Prepare PDU, optionally w/ immediate data */ | 957 | /* Prepare PDU, optionally w/ immediate data */ |
@@ -982,7 +982,7 @@ static struct iscsi_r2t_info *iscsi_tcp_get_curr_r2t(struct iscsi_task *task) | |||
982 | if (r2t->data_length <= r2t->sent) { | 982 | if (r2t->data_length <= r2t->sent) { |
983 | ISCSI_DBG_TCP(task->conn, | 983 | ISCSI_DBG_TCP(task->conn, |
984 | " done with r2t %p\n", r2t); | 984 | " done with r2t %p\n", r2t); |
985 | __kfifo_put(tcp_task->r2tpool.queue, | 985 | kfifo_in(&tcp_task->r2tpool.queue, |
986 | (void *)&tcp_task->r2t, | 986 | (void *)&tcp_task->r2t, |
987 | sizeof(void *)); | 987 | sizeof(void *)); |
988 | tcp_task->r2t = r2t = NULL; | 988 | tcp_task->r2t = r2t = NULL; |
@@ -990,8 +990,13 @@ static struct iscsi_r2t_info *iscsi_tcp_get_curr_r2t(struct iscsi_task *task) | |||
990 | } | 990 | } |
991 | 991 | ||
992 | if (r2t == NULL) { | 992 | if (r2t == NULL) { |
993 | __kfifo_get(tcp_task->r2tqueue, | 993 | if (kfifo_out(&tcp_task->r2tqueue, |
994 | (void *)&tcp_task->r2t, sizeof(void *)); | 994 | (void *)&tcp_task->r2t, sizeof(void *)) != |
995 | sizeof(void *)) { | ||
996 | WARN_ONCE(1, "unexpected fifo state"); | ||
997 | r2t = NULL; | ||
998 | } | ||
999 | |||
995 | r2t = tcp_task->r2t; | 1000 | r2t = tcp_task->r2t; |
996 | } | 1001 | } |
997 | spin_unlock_bh(&session->lock); | 1002 | spin_unlock_bh(&session->lock); |
@@ -1127,9 +1132,8 @@ int iscsi_tcp_r2tpool_alloc(struct iscsi_session *session) | |||
1127 | } | 1132 | } |
1128 | 1133 | ||
1129 | /* R2T xmit queue */ | 1134 | /* R2T xmit queue */ |
1130 | tcp_task->r2tqueue = kfifo_alloc( | 1135 | if (kfifo_alloc(&tcp_task->r2tqueue, |
1131 | session->max_r2t * 4 * sizeof(void*), GFP_KERNEL, NULL); | 1136 | session->max_r2t * 4 * sizeof(void*), GFP_KERNEL)) { |
1132 | if (tcp_task->r2tqueue == ERR_PTR(-ENOMEM)) { | ||
1133 | iscsi_pool_free(&tcp_task->r2tpool); | 1137 | iscsi_pool_free(&tcp_task->r2tpool); |
1134 | goto r2t_alloc_fail; | 1138 | goto r2t_alloc_fail; |
1135 | } | 1139 | } |
@@ -1142,7 +1146,7 @@ r2t_alloc_fail: | |||
1142 | struct iscsi_task *task = session->cmds[i]; | 1146 | struct iscsi_task *task = session->cmds[i]; |
1143 | struct iscsi_tcp_task *tcp_task = task->dd_data; | 1147 | struct iscsi_tcp_task *tcp_task = task->dd_data; |
1144 | 1148 | ||
1145 | kfifo_free(tcp_task->r2tqueue); | 1149 | kfifo_free(&tcp_task->r2tqueue); |
1146 | iscsi_pool_free(&tcp_task->r2tpool); | 1150 | iscsi_pool_free(&tcp_task->r2tpool); |
1147 | } | 1151 | } |
1148 | return -ENOMEM; | 1152 | return -ENOMEM; |
@@ -1157,7 +1161,7 @@ void iscsi_tcp_r2tpool_free(struct iscsi_session *session) | |||
1157 | struct iscsi_task *task = session->cmds[i]; | 1161 | struct iscsi_task *task = session->cmds[i]; |
1158 | struct iscsi_tcp_task *tcp_task = task->dd_data; | 1162 | struct iscsi_tcp_task *tcp_task = task->dd_data; |
1159 | 1163 | ||
1160 | kfifo_free(tcp_task->r2tqueue); | 1164 | kfifo_free(&tcp_task->r2tqueue); |
1161 | iscsi_pool_free(&tcp_task->r2tpool); | 1165 | iscsi_pool_free(&tcp_task->r2tpool); |
1162 | } | 1166 | } |
1163 | } | 1167 | } |
diff --git a/drivers/scsi/libsrp.c b/drivers/scsi/libsrp.c index 9ad38e81e343..ab19b3b4be52 100644 --- a/drivers/scsi/libsrp.c +++ b/drivers/scsi/libsrp.c | |||
@@ -58,19 +58,15 @@ static int srp_iu_pool_alloc(struct srp_queue *q, size_t max, | |||
58 | goto free_pool; | 58 | goto free_pool; |
59 | 59 | ||
60 | spin_lock_init(&q->lock); | 60 | spin_lock_init(&q->lock); |
61 | q->queue = kfifo_init((void *) q->pool, max * sizeof(void *), | 61 | kfifo_init(&q->queue, (void *) q->pool, max * sizeof(void *)); |
62 | GFP_KERNEL, &q->lock); | ||
63 | if (IS_ERR(q->queue)) | ||
64 | goto free_item; | ||
65 | 62 | ||
66 | for (i = 0, iue = q->items; i < max; i++) { | 63 | for (i = 0, iue = q->items; i < max; i++) { |
67 | __kfifo_put(q->queue, (void *) &iue, sizeof(void *)); | 64 | kfifo_in(&q->queue, (void *) &iue, sizeof(void *)); |
68 | iue->sbuf = ring[i]; | 65 | iue->sbuf = ring[i]; |
69 | iue++; | 66 | iue++; |
70 | } | 67 | } |
71 | return 0; | 68 | return 0; |
72 | 69 | ||
73 | free_item: | ||
74 | kfree(q->items); | 70 | kfree(q->items); |
75 | free_pool: | 71 | free_pool: |
76 | kfree(q->pool); | 72 | kfree(q->pool); |
@@ -167,7 +163,11 @@ struct iu_entry *srp_iu_get(struct srp_target *target) | |||
167 | { | 163 | { |
168 | struct iu_entry *iue = NULL; | 164 | struct iu_entry *iue = NULL; |
169 | 165 | ||
170 | kfifo_get(target->iu_queue.queue, (void *) &iue, sizeof(void *)); | 166 | if (kfifo_out_locked(&target->iu_queue.queue, (void *) &iue, |
167 | sizeof(void *), &target->iu_queue.lock) != sizeof(void *)) { | ||
168 | WARN_ONCE(1, "unexpected fifo state"); | ||
169 | return NULL; | ||
170 | } | ||
171 | if (!iue) | 171 | if (!iue) |
172 | return iue; | 172 | return iue; |
173 | iue->target = target; | 173 | iue->target = target; |
@@ -179,7 +179,8 @@ EXPORT_SYMBOL_GPL(srp_iu_get); | |||
179 | 179 | ||
180 | void srp_iu_put(struct iu_entry *iue) | 180 | void srp_iu_put(struct iu_entry *iue) |
181 | { | 181 | { |
182 | kfifo_put(iue->target->iu_queue.queue, (void *) &iue, sizeof(void *)); | 182 | kfifo_in_locked(&iue->target->iu_queue.queue, (void *) &iue, |
183 | sizeof(void *), &iue->target->iu_queue.lock); | ||
183 | } | 184 | } |
184 | EXPORT_SYMBOL_GPL(srp_iu_put); | 185 | EXPORT_SYMBOL_GPL(srp_iu_put); |
185 | 186 | ||
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 68c7f6cfd728..37f0de9dd9ce 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c | |||
@@ -222,9 +222,9 @@ static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) | |||
222 | Set SCP6MD1,0 = {01} (output) */ | 222 | Set SCP6MD1,0 = {01} (output) */ |
223 | __raw_writew((data & 0x0fcf) | 0x1000, SCPCR); | 223 | __raw_writew((data & 0x0fcf) | 0x1000, SCPCR); |
224 | 224 | ||
225 | data = ctrl_inb(SCPDR); | 225 | data = __raw_readb(SCPDR); |
226 | /* Set /RTS2 (bit6) = 0 */ | 226 | /* Set /RTS2 (bit6) = 0 */ |
227 | ctrl_outb(data & 0xbf, SCPDR); | 227 | __raw_writeb(data & 0xbf, SCPDR); |
228 | } | 228 | } |
229 | } | 229 | } |
230 | #elif defined(CONFIG_CPU_SUBTYPE_SH7722) | 230 | #elif defined(CONFIG_CPU_SUBTYPE_SH7722) |
@@ -897,11 +897,21 @@ static void sci_shutdown(struct uart_port *port) | |||
897 | static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | 897 | static void sci_set_termios(struct uart_port *port, struct ktermios *termios, |
898 | struct ktermios *old) | 898 | struct ktermios *old) |
899 | { | 899 | { |
900 | unsigned int status, baud, smr_val; | 900 | unsigned int status, baud, smr_val, max_baud; |
901 | int t = -1; | 901 | int t = -1; |
902 | 902 | ||
903 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); | 903 | /* |
904 | if (likely(baud)) | 904 | * earlyprintk comes here early on with port->uartclk set to zero. |
905 | * the clock framework is not up and running at this point so here | ||
906 | * we assume that 115200 is the maximum baud rate. please note that | ||
907 | * the baud rate is not programmed during earlyprintk - it is assumed | ||
908 | * that the previous boot loader has enabled required clocks and | ||
909 | * setup the baud rate generator hardware for us already. | ||
910 | */ | ||
911 | max_baud = port->uartclk ? port->uartclk / 16 : 115200; | ||
912 | |||
913 | baud = uart_get_baud_rate(port, termios, old, 0, max_baud); | ||
914 | if (likely(baud && port->uartclk)) | ||
905 | t = SCBRR_VALUE(baud, port->uartclk); | 915 | t = SCBRR_VALUE(baud, port->uartclk); |
906 | 916 | ||
907 | do { | 917 | do { |
diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h index a32094eeb42b..0efcded59ae6 100644 --- a/drivers/serial/sh-sci.h +++ b/drivers/serial/sh-sci.h | |||
@@ -517,20 +517,20 @@ static const struct __attribute__((packed)) { | |||
517 | static inline int sci_rxd_in(struct uart_port *port) | 517 | static inline int sci_rxd_in(struct uart_port *port) |
518 | { | 518 | { |
519 | if (port->mapbase == 0xfffffe80) | 519 | if (port->mapbase == 0xfffffe80) |
520 | return ctrl_inb(SCPDR)&0x01 ? 1 : 0; /* SCI */ | 520 | return __raw_readb(SCPDR)&0x01 ? 1 : 0; /* SCI */ |
521 | if (port->mapbase == 0xa4000150) | 521 | if (port->mapbase == 0xa4000150) |
522 | return ctrl_inb(SCPDR)&0x10 ? 1 : 0; /* SCIF */ | 522 | return __raw_readb(SCPDR)&0x10 ? 1 : 0; /* SCIF */ |
523 | if (port->mapbase == 0xa4000140) | 523 | if (port->mapbase == 0xa4000140) |
524 | return ctrl_inb(SCPDR)&0x04 ? 1 : 0; /* IRDA */ | 524 | return __raw_readb(SCPDR)&0x04 ? 1 : 0; /* IRDA */ |
525 | return 1; | 525 | return 1; |
526 | } | 526 | } |
527 | #elif defined(CONFIG_CPU_SUBTYPE_SH7705) | 527 | #elif defined(CONFIG_CPU_SUBTYPE_SH7705) |
528 | static inline int sci_rxd_in(struct uart_port *port) | 528 | static inline int sci_rxd_in(struct uart_port *port) |
529 | { | 529 | { |
530 | if (port->mapbase == SCIF0) | 530 | if (port->mapbase == SCIF0) |
531 | return ctrl_inb(SCPDR)&0x04 ? 1 : 0; /* IRDA */ | 531 | return __raw_readb(SCPDR)&0x04 ? 1 : 0; /* IRDA */ |
532 | if (port->mapbase == SCIF2) | 532 | if (port->mapbase == SCIF2) |
533 | return ctrl_inb(SCPDR)&0x10 ? 1 : 0; /* SCIF */ | 533 | return __raw_readb(SCPDR)&0x10 ? 1 : 0; /* SCIF */ |
534 | return 1; | 534 | return 1; |
535 | } | 535 | } |
536 | #elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) | 536 | #elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) |
@@ -557,68 +557,68 @@ static inline int sci_rxd_in(struct uart_port *port) | |||
557 | static inline int sci_rxd_in(struct uart_port *port) | 557 | static inline int sci_rxd_in(struct uart_port *port) |
558 | { | 558 | { |
559 | if (port->mapbase == 0xffe00000) | 559 | if (port->mapbase == 0xffe00000) |
560 | return ctrl_inb(SCSPTR1)&0x01 ? 1 : 0; /* SCI */ | 560 | return __raw_readb(SCSPTR1)&0x01 ? 1 : 0; /* SCI */ |
561 | if (port->mapbase == 0xffe80000) | 561 | if (port->mapbase == 0xffe80000) |
562 | return ctrl_inw(SCSPTR2)&0x0001 ? 1 : 0; /* SCIF */ | 562 | return __raw_readw(SCSPTR2)&0x0001 ? 1 : 0; /* SCIF */ |
563 | return 1; | 563 | return 1; |
564 | } | 564 | } |
565 | #elif defined(CONFIG_CPU_SUBTYPE_SH4_202) | 565 | #elif defined(CONFIG_CPU_SUBTYPE_SH4_202) |
566 | static inline int sci_rxd_in(struct uart_port *port) | 566 | static inline int sci_rxd_in(struct uart_port *port) |
567 | { | 567 | { |
568 | if (port->mapbase == 0xffe80000) | 568 | if (port->mapbase == 0xffe80000) |
569 | return ctrl_inw(SCSPTR2)&0x0001 ? 1 : 0; /* SCIF */ | 569 | return __raw_readw(SCSPTR2)&0x0001 ? 1 : 0; /* SCIF */ |
570 | return 1; | 570 | return 1; |
571 | } | 571 | } |
572 | #elif defined(CONFIG_CPU_SUBTYPE_SH7757) | 572 | #elif defined(CONFIG_CPU_SUBTYPE_SH7757) |
573 | static inline int sci_rxd_in(struct uart_port *port) | 573 | static inline int sci_rxd_in(struct uart_port *port) |
574 | { | 574 | { |
575 | if (port->mapbase == 0xfe4b0000) | 575 | if (port->mapbase == 0xfe4b0000) |
576 | return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; | 576 | return __raw_readw(SCSPTR0) & 0x0001 ? 1 : 0; |
577 | if (port->mapbase == 0xfe4c0000) | 577 | if (port->mapbase == 0xfe4c0000) |
578 | return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; | 578 | return __raw_readw(SCSPTR1) & 0x0001 ? 1 : 0; |
579 | if (port->mapbase == 0xfe4d0000) | 579 | if (port->mapbase == 0xfe4d0000) |
580 | return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; | 580 | return __raw_readw(SCSPTR2) & 0x0001 ? 1 : 0; |
581 | } | 581 | } |
582 | #elif defined(CONFIG_CPU_SUBTYPE_SH7760) | 582 | #elif defined(CONFIG_CPU_SUBTYPE_SH7760) |
583 | static inline int sci_rxd_in(struct uart_port *port) | 583 | static inline int sci_rxd_in(struct uart_port *port) |
584 | { | 584 | { |
585 | if (port->mapbase == 0xfe600000) | 585 | if (port->mapbase == 0xfe600000) |
586 | return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ | 586 | return __raw_readw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ |
587 | if (port->mapbase == 0xfe610000) | 587 | if (port->mapbase == 0xfe610000) |
588 | return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ | 588 | return __raw_readw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ |
589 | if (port->mapbase == 0xfe620000) | 589 | if (port->mapbase == 0xfe620000) |
590 | return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ | 590 | return __raw_readw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ |
591 | return 1; | 591 | return 1; |
592 | } | 592 | } |
593 | #elif defined(CONFIG_CPU_SUBTYPE_SH7343) | 593 | #elif defined(CONFIG_CPU_SUBTYPE_SH7343) |
594 | static inline int sci_rxd_in(struct uart_port *port) | 594 | static inline int sci_rxd_in(struct uart_port *port) |
595 | { | 595 | { |
596 | if (port->mapbase == 0xffe00000) | 596 | if (port->mapbase == 0xffe00000) |
597 | return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ | 597 | return __raw_readw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ |
598 | if (port->mapbase == 0xffe10000) | 598 | if (port->mapbase == 0xffe10000) |
599 | return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ | 599 | return __raw_readw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ |
600 | if (port->mapbase == 0xffe20000) | 600 | if (port->mapbase == 0xffe20000) |
601 | return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ | 601 | return __raw_readw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ |
602 | if (port->mapbase == 0xffe30000) | 602 | if (port->mapbase == 0xffe30000) |
603 | return ctrl_inw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */ | 603 | return __raw_readw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */ |
604 | return 1; | 604 | return 1; |
605 | } | 605 | } |
606 | #elif defined(CONFIG_CPU_SUBTYPE_SH7366) | 606 | #elif defined(CONFIG_CPU_SUBTYPE_SH7366) |
607 | static inline int sci_rxd_in(struct uart_port *port) | 607 | static inline int sci_rxd_in(struct uart_port *port) |
608 | { | 608 | { |
609 | if (port->mapbase == 0xffe00000) | 609 | if (port->mapbase == 0xffe00000) |
610 | return ctrl_inb(SCPDR0) & 0x0001 ? 1 : 0; /* SCIF0 */ | 610 | return __raw_readb(SCPDR0) & 0x0001 ? 1 : 0; /* SCIF0 */ |
611 | return 1; | 611 | return 1; |
612 | } | 612 | } |
613 | #elif defined(CONFIG_CPU_SUBTYPE_SH7722) | 613 | #elif defined(CONFIG_CPU_SUBTYPE_SH7722) |
614 | static inline int sci_rxd_in(struct uart_port *port) | 614 | static inline int sci_rxd_in(struct uart_port *port) |
615 | { | 615 | { |
616 | if (port->mapbase == 0xffe00000) | 616 | if (port->mapbase == 0xffe00000) |
617 | return ctrl_inb(PSDR) & 0x02 ? 1 : 0; /* SCIF0 */ | 617 | return __raw_readb(PSDR) & 0x02 ? 1 : 0; /* SCIF0 */ |
618 | if (port->mapbase == 0xffe10000) | 618 | if (port->mapbase == 0xffe10000) |
619 | return ctrl_inb(PADR) & 0x40 ? 1 : 0; /* SCIF1 */ | 619 | return __raw_readb(PADR) & 0x40 ? 1 : 0; /* SCIF1 */ |
620 | if (port->mapbase == 0xffe20000) | 620 | if (port->mapbase == 0xffe20000) |
621 | return ctrl_inb(PWDR) & 0x04 ? 1 : 0; /* SCIF2 */ | 621 | return __raw_readb(PWDR) & 0x04 ? 1 : 0; /* SCIF2 */ |
622 | 622 | ||
623 | return 1; | 623 | return 1; |
624 | } | 624 | } |
@@ -626,17 +626,17 @@ static inline int sci_rxd_in(struct uart_port *port) | |||
626 | static inline int sci_rxd_in(struct uart_port *port) | 626 | static inline int sci_rxd_in(struct uart_port *port) |
627 | { | 627 | { |
628 | if (port->mapbase == 0xffe00000) | 628 | if (port->mapbase == 0xffe00000) |
629 | return ctrl_inb(SCSPTR0) & 0x0008 ? 1 : 0; /* SCIF0 */ | 629 | return __raw_readb(SCSPTR0) & 0x0008 ? 1 : 0; /* SCIF0 */ |
630 | if (port->mapbase == 0xffe10000) | 630 | if (port->mapbase == 0xffe10000) |
631 | return ctrl_inb(SCSPTR1) & 0x0020 ? 1 : 0; /* SCIF1 */ | 631 | return __raw_readb(SCSPTR1) & 0x0020 ? 1 : 0; /* SCIF1 */ |
632 | if (port->mapbase == 0xffe20000) | 632 | if (port->mapbase == 0xffe20000) |
633 | return ctrl_inb(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF2 */ | 633 | return __raw_readb(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF2 */ |
634 | if (port->mapbase == 0xa4e30000) | 634 | if (port->mapbase == 0xa4e30000) |
635 | return ctrl_inb(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF3 */ | 635 | return __raw_readb(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF3 */ |
636 | if (port->mapbase == 0xa4e40000) | 636 | if (port->mapbase == 0xa4e40000) |
637 | return ctrl_inb(SCSPTR4) & 0x0001 ? 1 : 0; /* SCIF4 */ | 637 | return __raw_readb(SCSPTR4) & 0x0001 ? 1 : 0; /* SCIF4 */ |
638 | if (port->mapbase == 0xa4e50000) | 638 | if (port->mapbase == 0xa4e50000) |
639 | return ctrl_inb(SCSPTR5) & 0x0008 ? 1 : 0; /* SCIF5 */ | 639 | return __raw_readb(SCSPTR5) & 0x0008 ? 1 : 0; /* SCIF5 */ |
640 | return 1; | 640 | return 1; |
641 | } | 641 | } |
642 | #elif defined(CONFIG_CPU_SUBTYPE_SH7724) | 642 | #elif defined(CONFIG_CPU_SUBTYPE_SH7724) |
@@ -645,9 +645,9 @@ static inline int sci_rxd_in(struct uart_port *port) | |||
645 | static inline int sci_rxd_in(struct uart_port *port) | 645 | static inline int sci_rxd_in(struct uart_port *port) |
646 | { | 646 | { |
647 | if (port->type == PORT_SCIF) | 647 | if (port->type == PORT_SCIF) |
648 | return ctrl_inw((port->mapbase + SCFSR)) & SCIF_BRK ? 1 : 0; | 648 | return __raw_readw((port->mapbase + SCFSR)) & SCIF_BRK ? 1 : 0; |
649 | if (port->type == PORT_SCIFA) | 649 | if (port->type == PORT_SCIFA) |
650 | return ctrl_inw((port->mapbase + SCASSR)) & SCIF_BRK ? 1 : 0; | 650 | return __raw_readw((port->mapbase + SCASSR)) & SCIF_BRK ? 1 : 0; |
651 | return 1; | 651 | return 1; |
652 | } | 652 | } |
653 | #elif defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103) | 653 | #elif defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103) |
@@ -665,11 +665,11 @@ static inline int sci_rxd_in(struct uart_port *port) | |||
665 | static inline int sci_rxd_in(struct uart_port *port) | 665 | static inline int sci_rxd_in(struct uart_port *port) |
666 | { | 666 | { |
667 | if (port->mapbase == 0xffe00000) | 667 | if (port->mapbase == 0xffe00000) |
668 | return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ | 668 | return __raw_readw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ |
669 | if (port->mapbase == 0xffe08000) | 669 | if (port->mapbase == 0xffe08000) |
670 | return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ | 670 | return __raw_readw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ |
671 | if (port->mapbase == 0xffe10000) | 671 | if (port->mapbase == 0xffe10000) |
672 | return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF/IRDA */ | 672 | return __raw_readw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF/IRDA */ |
673 | 673 | ||
674 | return 1; | 674 | return 1; |
675 | } | 675 | } |
@@ -677,20 +677,20 @@ static inline int sci_rxd_in(struct uart_port *port) | |||
677 | static inline int sci_rxd_in(struct uart_port *port) | 677 | static inline int sci_rxd_in(struct uart_port *port) |
678 | { | 678 | { |
679 | if (port->mapbase == 0xff923000) | 679 | if (port->mapbase == 0xff923000) |
680 | return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ | 680 | return __raw_readw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ |
681 | if (port->mapbase == 0xff924000) | 681 | if (port->mapbase == 0xff924000) |
682 | return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ | 682 | return __raw_readw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ |
683 | if (port->mapbase == 0xff925000) | 683 | if (port->mapbase == 0xff925000) |
684 | return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ | 684 | return __raw_readw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ |
685 | return 1; | 685 | return 1; |
686 | } | 686 | } |
687 | #elif defined(CONFIG_CPU_SUBTYPE_SH7780) | 687 | #elif defined(CONFIG_CPU_SUBTYPE_SH7780) |
688 | static inline int sci_rxd_in(struct uart_port *port) | 688 | static inline int sci_rxd_in(struct uart_port *port) |
689 | { | 689 | { |
690 | if (port->mapbase == 0xffe00000) | 690 | if (port->mapbase == 0xffe00000) |
691 | return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ | 691 | return __raw_readw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ |
692 | if (port->mapbase == 0xffe10000) | 692 | if (port->mapbase == 0xffe10000) |
693 | return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ | 693 | return __raw_readw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ |
694 | return 1; | 694 | return 1; |
695 | } | 695 | } |
696 | #elif defined(CONFIG_CPU_SUBTYPE_SH7785) || \ | 696 | #elif defined(CONFIG_CPU_SUBTYPE_SH7785) || \ |
@@ -698,17 +698,17 @@ static inline int sci_rxd_in(struct uart_port *port) | |||
698 | static inline int sci_rxd_in(struct uart_port *port) | 698 | static inline int sci_rxd_in(struct uart_port *port) |
699 | { | 699 | { |
700 | if (port->mapbase == 0xffea0000) | 700 | if (port->mapbase == 0xffea0000) |
701 | return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ | 701 | return __raw_readw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ |
702 | if (port->mapbase == 0xffeb0000) | 702 | if (port->mapbase == 0xffeb0000) |
703 | return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ | 703 | return __raw_readw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ |
704 | if (port->mapbase == 0xffec0000) | 704 | if (port->mapbase == 0xffec0000) |
705 | return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ | 705 | return __raw_readw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ |
706 | if (port->mapbase == 0xffed0000) | 706 | if (port->mapbase == 0xffed0000) |
707 | return ctrl_inw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */ | 707 | return __raw_readw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */ |
708 | if (port->mapbase == 0xffee0000) | 708 | if (port->mapbase == 0xffee0000) |
709 | return ctrl_inw(SCSPTR4) & 0x0001 ? 1 : 0; /* SCIF */ | 709 | return __raw_readw(SCSPTR4) & 0x0001 ? 1 : 0; /* SCIF */ |
710 | if (port->mapbase == 0xffef0000) | 710 | if (port->mapbase == 0xffef0000) |
711 | return ctrl_inw(SCSPTR5) & 0x0001 ? 1 : 0; /* SCIF */ | 711 | return __raw_readw(SCSPTR5) & 0x0001 ? 1 : 0; /* SCIF */ |
712 | return 1; | 712 | return 1; |
713 | } | 713 | } |
714 | #elif defined(CONFIG_CPU_SUBTYPE_SH7201) || \ | 714 | #elif defined(CONFIG_CPU_SUBTYPE_SH7201) || \ |
@@ -718,22 +718,22 @@ static inline int sci_rxd_in(struct uart_port *port) | |||
718 | static inline int sci_rxd_in(struct uart_port *port) | 718 | static inline int sci_rxd_in(struct uart_port *port) |
719 | { | 719 | { |
720 | if (port->mapbase == 0xfffe8000) | 720 | if (port->mapbase == 0xfffe8000) |
721 | return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ | 721 | return __raw_readw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ |
722 | if (port->mapbase == 0xfffe8800) | 722 | if (port->mapbase == 0xfffe8800) |
723 | return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ | 723 | return __raw_readw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ |
724 | if (port->mapbase == 0xfffe9000) | 724 | if (port->mapbase == 0xfffe9000) |
725 | return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ | 725 | return __raw_readw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ |
726 | if (port->mapbase == 0xfffe9800) | 726 | if (port->mapbase == 0xfffe9800) |
727 | return ctrl_inw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */ | 727 | return __raw_readw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */ |
728 | #if defined(CONFIG_CPU_SUBTYPE_SH7201) | 728 | #if defined(CONFIG_CPU_SUBTYPE_SH7201) |
729 | if (port->mapbase == 0xfffeA000) | 729 | if (port->mapbase == 0xfffeA000) |
730 | return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ | 730 | return __raw_readw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ |
731 | if (port->mapbase == 0xfffeA800) | 731 | if (port->mapbase == 0xfffeA800) |
732 | return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ | 732 | return __raw_readw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ |
733 | if (port->mapbase == 0xfffeB000) | 733 | if (port->mapbase == 0xfffeB000) |
734 | return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ | 734 | return __raw_readw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ |
735 | if (port->mapbase == 0xfffeB800) | 735 | if (port->mapbase == 0xfffeB800) |
736 | return ctrl_inw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */ | 736 | return __raw_readw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */ |
737 | #endif | 737 | #endif |
738 | return 1; | 738 | return 1; |
739 | } | 739 | } |
@@ -741,24 +741,24 @@ static inline int sci_rxd_in(struct uart_port *port) | |||
741 | static inline int sci_rxd_in(struct uart_port *port) | 741 | static inline int sci_rxd_in(struct uart_port *port) |
742 | { | 742 | { |
743 | if (port->mapbase == 0xf8400000) | 743 | if (port->mapbase == 0xf8400000) |
744 | return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ | 744 | return __raw_readw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ |
745 | if (port->mapbase == 0xf8410000) | 745 | if (port->mapbase == 0xf8410000) |
746 | return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ | 746 | return __raw_readw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ |
747 | if (port->mapbase == 0xf8420000) | 747 | if (port->mapbase == 0xf8420000) |
748 | return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ | 748 | return __raw_readw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ |
749 | return 1; | 749 | return 1; |
750 | } | 750 | } |
751 | #elif defined(CONFIG_CPU_SUBTYPE_SHX3) | 751 | #elif defined(CONFIG_CPU_SUBTYPE_SHX3) |
752 | static inline int sci_rxd_in(struct uart_port *port) | 752 | static inline int sci_rxd_in(struct uart_port *port) |
753 | { | 753 | { |
754 | if (port->mapbase == 0xffc30000) | 754 | if (port->mapbase == 0xffc30000) |
755 | return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ | 755 | return __raw_readw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ |
756 | if (port->mapbase == 0xffc40000) | 756 | if (port->mapbase == 0xffc40000) |
757 | return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ | 757 | return __raw_readw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ |
758 | if (port->mapbase == 0xffc50000) | 758 | if (port->mapbase == 0xffc50000) |
759 | return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ | 759 | return __raw_readw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ |
760 | if (port->mapbase == 0xffc60000) | 760 | if (port->mapbase == 0xffc60000) |
761 | return ctrl_inw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */ | 761 | return __raw_readw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */ |
762 | return 1; | 762 | return 1; |
763 | } | 763 | } |
764 | #endif | 764 | #endif |
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 093f57af32d3..94eb86319ff3 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig | |||
@@ -87,8 +87,6 @@ source "drivers/staging/frontier/Kconfig" | |||
87 | 87 | ||
88 | source "drivers/staging/dream/Kconfig" | 88 | source "drivers/staging/dream/Kconfig" |
89 | 89 | ||
90 | source "drivers/staging/dst/Kconfig" | ||
91 | |||
92 | source "drivers/staging/pohmelfs/Kconfig" | 90 | source "drivers/staging/pohmelfs/Kconfig" |
93 | 91 | ||
94 | source "drivers/staging/b3dfg/Kconfig" | 92 | source "drivers/staging/b3dfg/Kconfig" |
@@ -145,5 +143,7 @@ source "drivers/staging/wavelan/Kconfig" | |||
145 | 143 | ||
146 | source "drivers/staging/netwave/Kconfig" | 144 | source "drivers/staging/netwave/Kconfig" |
147 | 145 | ||
146 | source "drivers/staging/sm7xx/Kconfig" | ||
147 | |||
148 | endif # !STAGING_EXCLUDE_BUILD | 148 | endif # !STAGING_EXCLUDE_BUILD |
149 | endif # STAGING | 149 | endif # STAGING |
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 069864f4391e..b5e67b889f60 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile | |||
@@ -26,7 +26,6 @@ obj-$(CONFIG_RTL8192E) += rtl8192e/ | |||
26 | obj-$(CONFIG_INPUT_MIMIO) += mimio/ | 26 | obj-$(CONFIG_INPUT_MIMIO) += mimio/ |
27 | obj-$(CONFIG_TRANZPORT) += frontier/ | 27 | obj-$(CONFIG_TRANZPORT) += frontier/ |
28 | obj-$(CONFIG_DREAM) += dream/ | 28 | obj-$(CONFIG_DREAM) += dream/ |
29 | obj-$(CONFIG_DST) += dst/ | ||
30 | obj-$(CONFIG_POHMELFS) += pohmelfs/ | 29 | obj-$(CONFIG_POHMELFS) += pohmelfs/ |
31 | obj-$(CONFIG_B3DFG) += b3dfg/ | 30 | obj-$(CONFIG_B3DFG) += b3dfg/ |
32 | obj-$(CONFIG_IDE_PHISON) += phison/ | 31 | obj-$(CONFIG_IDE_PHISON) += phison/ |
@@ -53,3 +52,4 @@ obj-$(CONFIG_ARLAN) += arlan/ | |||
53 | obj-$(CONFIG_WAVELAN) += wavelan/ | 52 | obj-$(CONFIG_WAVELAN) += wavelan/ |
54 | obj-$(CONFIG_PCMCIA_WAVELAN) += wavelan/ | 53 | obj-$(CONFIG_PCMCIA_WAVELAN) += wavelan/ |
55 | obj-$(CONFIG_PCMCIA_NETWAVE) += netwave/ | 54 | obj-$(CONFIG_PCMCIA_NETWAVE) += netwave/ |
55 | obj-$(CONFIG_FB_SM7XX) += sm7xx/ | ||
diff --git a/drivers/staging/batman-adv/Kconfig b/drivers/staging/batman-adv/Kconfig index 7632f5760060..1d74dabf9511 100644 --- a/drivers/staging/batman-adv/Kconfig +++ b/drivers/staging/batman-adv/Kconfig | |||
@@ -4,6 +4,7 @@ | |||
4 | 4 | ||
5 | config BATMAN_ADV | 5 | config BATMAN_ADV |
6 | tristate "B.A.T.M.A.N. Advanced Meshing Protocol" | 6 | tristate "B.A.T.M.A.N. Advanced Meshing Protocol" |
7 | depends on PROC_FS && PACKET | ||
7 | default n | 8 | default n |
8 | ---help--- | 9 | ---help--- |
9 | 10 | ||
diff --git a/drivers/staging/batman-adv/send.c b/drivers/staging/batman-adv/send.c index d724798278d6..eb617508cca4 100644 --- a/drivers/staging/batman-adv/send.c +++ b/drivers/staging/batman-adv/send.c | |||
@@ -363,8 +363,10 @@ void add_bcast_packet_to_list(unsigned char *packet_buff, int packet_len) | |||
363 | return; | 363 | return; |
364 | 364 | ||
365 | forw_packet->packet_buff = kmalloc(packet_len, GFP_ATOMIC); | 365 | forw_packet->packet_buff = kmalloc(packet_len, GFP_ATOMIC); |
366 | if (!forw_packet->packet_buff) | 366 | if (!forw_packet->packet_buff) { |
367 | kfree(forw_packet); | ||
367 | return; | 368 | return; |
369 | } | ||
368 | 370 | ||
369 | forw_packet->packet_len = packet_len; | 371 | forw_packet->packet_len = packet_len; |
370 | memcpy(forw_packet->packet_buff, packet_buff, forw_packet->packet_len); | 372 | memcpy(forw_packet->packet_buff, packet_buff, forw_packet->packet_len); |
diff --git a/drivers/staging/comedi/comedi.h b/drivers/staging/comedi/comedi.h index ccc5cdc008c6..b559a9c2f857 100644 --- a/drivers/staging/comedi/comedi.h +++ b/drivers/staging/comedi/comedi.h | |||
@@ -451,7 +451,7 @@ | |||
451 | 451 | ||
452 | #define COMEDI_CB_EOS 1 /* end of scan */ | 452 | #define COMEDI_CB_EOS 1 /* end of scan */ |
453 | #define COMEDI_CB_EOA 2 /* end of acquisition */ | 453 | #define COMEDI_CB_EOA 2 /* end of acquisition */ |
454 | #define COMEDI_CB_BLOCK 4 /* DEPRECATED: convenient block size */ | 454 | #define COMEDI_CB_BLOCK 4 /* data has arrived: wakes up read() / write() */ |
455 | #define COMEDI_CB_EOBUF 8 /* DEPRECATED: end of buffer */ | 455 | #define COMEDI_CB_EOBUF 8 /* DEPRECATED: end of buffer */ |
456 | #define COMEDI_CB_ERROR 16 /* card error during acquisition */ | 456 | #define COMEDI_CB_ERROR 16 /* card error during acquisition */ |
457 | #define COMEDI_CB_OVERFLOW 32 /* buffer overflow/underflow */ | 457 | #define COMEDI_CB_OVERFLOW 32 /* buffer overflow/underflow */ |
diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c index 0d2c2eb23b23..bd397840dcba 100644 --- a/drivers/staging/comedi/drivers/jr3_pci.c +++ b/drivers/staging/comedi/drivers/jr3_pci.c | |||
@@ -849,8 +849,11 @@ static int jr3_pci_attach(struct comedi_device *dev, | |||
849 | } | 849 | } |
850 | 850 | ||
851 | devpriv->pci_enabled = 1; | 851 | devpriv->pci_enabled = 1; |
852 | devpriv->iobase = | 852 | devpriv->iobase = ioremap(pci_resource_start(card, 0), |
853 | ioremap(pci_resource_start(card, 0), sizeof(struct jr3_t)); | 853 | offsetof(struct jr3_t, channel[devpriv->n_channels])); |
854 | if (!devpriv->iobase) | ||
855 | return -ENOMEM; | ||
856 | |||
854 | result = alloc_subdevices(dev, devpriv->n_channels); | 857 | result = alloc_subdevices(dev, devpriv->n_channels); |
855 | if (result < 0) | 858 | if (result < 0) |
856 | goto out; | 859 | goto out; |
diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index 06c020466298..9a1b559c4b0d 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c | |||
@@ -1,4 +1,4 @@ | |||
1 | #define DRIVER_VERSION "v2.3" | 1 | #define DRIVER_VERSION "v2.4" |
2 | #define DRIVER_AUTHOR "Bernd Porr, BerndPorr@f2s.com" | 2 | #define DRIVER_AUTHOR "Bernd Porr, BerndPorr@f2s.com" |
3 | #define DRIVER_DESC "Stirling/ITL USB-DUX -- Bernd.Porr@f2s.com" | 3 | #define DRIVER_DESC "Stirling/ITL USB-DUX -- Bernd.Porr@f2s.com" |
4 | /* | 4 | /* |
@@ -81,6 +81,8 @@ sampling rate. If you sample two channels you get 4kHz and so on. | |||
81 | * 2.1: changed PWM API | 81 | * 2.1: changed PWM API |
82 | * 2.2: added firmware kernel request to fix an udev problem | 82 | * 2.2: added firmware kernel request to fix an udev problem |
83 | * 2.3: corrected a bug in bulk timeouts which were far too short | 83 | * 2.3: corrected a bug in bulk timeouts which were far too short |
84 | * 2.4: fixed a bug which causes the driver to hang when it ran out of data. | ||
85 | * Thanks to Jan-Matthias Braun and Ian to spot the bug and fix it. | ||
84 | * | 86 | * |
85 | */ | 87 | */ |
86 | 88 | ||
@@ -532,6 +534,7 @@ static void usbduxsub_ai_IsocIrq(struct urb *urb) | |||
532 | } | 534 | } |
533 | } | 535 | } |
534 | /* tell comedi that data is there */ | 536 | /* tell comedi that data is there */ |
537 | s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS; | ||
535 | comedi_event(this_usbduxsub->comedidev, s); | 538 | comedi_event(this_usbduxsub->comedidev, s); |
536 | } | 539 | } |
537 | 540 | ||
diff --git a/drivers/staging/dst/Kconfig b/drivers/staging/dst/Kconfig deleted file mode 100644 index 448d342ac2a2..000000000000 --- a/drivers/staging/dst/Kconfig +++ /dev/null | |||
@@ -1,67 +0,0 @@ | |||
1 | config DST | ||
2 | tristate "Distributed storage" | ||
3 | depends on NET && CRYPTO && SYSFS && BLK_DEV | ||
4 | select CONNECTOR | ||
5 | ---help--- | ||
6 | DST is a network block device storage, which can be used to organize | ||
7 | exported storage on the remote nodes into the local block device. | ||
8 | |||
9 | DST works on top of any network media and protocol; it is just a matter | ||
10 | of configuration utility to understand the correct addresses. The most | ||
11 | common example is TCP over IP, which allows to pass through firewalls and | ||
12 | create remote backup storage in a different datacenter. DST requires | ||
13 | single port to be enabled on the exporting node and outgoing connections | ||
14 | on the local node. | ||
15 | |||
16 | DST works with in-kernel client and server, which improves performance by | ||
17 | eliminating unneded data copies and by not depending on the version | ||
18 | of the external IO components. It requires userspace configuration utility | ||
19 | though. | ||
20 | |||
21 | DST uses transaction model, when each store has to be explicitly acked | ||
22 | from the remote node to be considered as successfully written. There | ||
23 | may be lots of in-flight transactions. When remote host does not ack | ||
24 | the transaction it will be resent predefined number of times with specified | ||
25 | timeouts between them. All those parameters are configurable. Transactions | ||
26 | are marked as failed after all resends complete unsuccessfully; having | ||
27 | long enough resend timeout and/or large number of resends allows not to | ||
28 | return error to the higher (FS usually) layer in case of short network | ||
29 | problems or remote node outages. In case of network RAID setup this means | ||
30 | that storage will not degrade until transactions are marked as failed, and | ||
31 | thus will not force checksum recalculation and data rebuild. In case of | ||
32 | connection failure DST will try to reconnect to the remote node automatically. | ||
33 | DST sends ping commands at idle time to detect if remote node is alive. | ||
34 | |||
35 | Because of transactional model it is possible to use zero-copy sending | ||
36 | without worry of data corruption (which in turn could be detected by the | ||
37 | strong checksums though). | ||
38 | |||
39 | DST may fully encrypt the data channel in case of untrusted channel and implement | ||
40 | strong checksum of the transferred data. It is possible to configure algorithms | ||
41 | and crypto keys; they should match on both sides of the network channel. | ||
42 | Crypto processing does not introduce noticeble performance overhead, since DST | ||
43 | uses configurable pool of threads to perform crypto processing. | ||
44 | |||
45 | DST utilizes memory pool model of all its transaction allocations (it is the | ||
46 | only additional allocation on the client) and server allocations (bio pools, | ||
47 | while pages are allocated from the slab). | ||
48 | |||
49 | At startup DST performs a simple negotiation with the export node to determine | ||
50 | access permissions and size of the exported storage. It can be extended if | ||
51 | new parameters should be autonegotiated. | ||
52 | |||
53 | DST carries block IO flags in the protocol, which allows to transparently implement | ||
54 | barriers and sync/flush operations. Those flags are used in the export node where | ||
55 | IO against the local storage is performed, which means that sync write will be sync | ||
56 | on the remote node too, which in turn improves data integrity and improved resistance | ||
57 | to errors and data corruption during power outages or storage damages. | ||
58 | |||
59 | Homepage: http://www.ioremap.net/projects/dst | ||
60 | Userspace configuration utility and the latest releases: http://www.ioremap.net/archive/dst/ | ||
61 | |||
62 | config DST_DEBUG | ||
63 | bool "DST debug" | ||
64 | depends on DST | ||
65 | ---help--- | ||
66 | This option will enable HEAVY debugging of the DST. | ||
67 | Turn it on ONLY if you have to debug some really obscure problem. | ||
diff --git a/drivers/staging/dst/Makefile b/drivers/staging/dst/Makefile deleted file mode 100644 index 3a8b0cf9643e..000000000000 --- a/drivers/staging/dst/Makefile +++ /dev/null | |||
@@ -1,3 +0,0 @@ | |||
1 | obj-$(CONFIG_DST) += nst.o | ||
2 | |||
3 | nst-y := dcore.o state.o export.o thread_pool.o crypto.o trans.o | ||
diff --git a/drivers/staging/dst/crypto.c b/drivers/staging/dst/crypto.c deleted file mode 100644 index 351295c97a4b..000000000000 --- a/drivers/staging/dst/crypto.c +++ /dev/null | |||
@@ -1,733 +0,0 @@ | |||
1 | /* | ||
2 | * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net> | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | */ | ||
15 | |||
16 | #include <linux/bio.h> | ||
17 | #include <linux/crypto.h> | ||
18 | #include <linux/dst.h> | ||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/scatterlist.h> | ||
21 | #include <linux/slab.h> | ||
22 | |||
23 | /* | ||
24 | * Tricky bastard, but IV can be more complex with time... | ||
25 | */ | ||
26 | static inline u64 dst_gen_iv(struct dst_trans *t) | ||
27 | { | ||
28 | return t->gen; | ||
29 | } | ||
30 | |||
31 | /* | ||
32 | * Crypto machinery: hash/cipher support for the given crypto controls. | ||
33 | */ | ||
34 | static struct crypto_hash *dst_init_hash(struct dst_crypto_ctl *ctl, u8 *key) | ||
35 | { | ||
36 | int err; | ||
37 | struct crypto_hash *hash; | ||
38 | |||
39 | hash = crypto_alloc_hash(ctl->hash_algo, 0, CRYPTO_ALG_ASYNC); | ||
40 | if (IS_ERR(hash)) { | ||
41 | err = PTR_ERR(hash); | ||
42 | dprintk("%s: failed to allocate hash '%s', err: %d.\n", | ||
43 | __func__, ctl->hash_algo, err); | ||
44 | goto err_out_exit; | ||
45 | } | ||
46 | |||
47 | ctl->crypto_attached_size = crypto_hash_digestsize(hash); | ||
48 | |||
49 | if (!ctl->hash_keysize) | ||
50 | return hash; | ||
51 | |||
52 | err = crypto_hash_setkey(hash, key, ctl->hash_keysize); | ||
53 | if (err) { | ||
54 | dprintk("%s: failed to set key for hash '%s', err: %d.\n", | ||
55 | __func__, ctl->hash_algo, err); | ||
56 | goto err_out_free; | ||
57 | } | ||
58 | |||
59 | return hash; | ||
60 | |||
61 | err_out_free: | ||
62 | crypto_free_hash(hash); | ||
63 | err_out_exit: | ||
64 | return ERR_PTR(err); | ||
65 | } | ||
66 | |||
67 | static struct crypto_ablkcipher *dst_init_cipher(struct dst_crypto_ctl *ctl, | ||
68 | u8 *key) | ||
69 | { | ||
70 | int err = -EINVAL; | ||
71 | struct crypto_ablkcipher *cipher; | ||
72 | |||
73 | if (!ctl->cipher_keysize) | ||
74 | goto err_out_exit; | ||
75 | |||
76 | cipher = crypto_alloc_ablkcipher(ctl->cipher_algo, 0, 0); | ||
77 | if (IS_ERR(cipher)) { | ||
78 | err = PTR_ERR(cipher); | ||
79 | dprintk("%s: failed to allocate cipher '%s', err: %d.\n", | ||
80 | __func__, ctl->cipher_algo, err); | ||
81 | goto err_out_exit; | ||
82 | } | ||
83 | |||
84 | crypto_ablkcipher_clear_flags(cipher, ~0); | ||
85 | |||
86 | err = crypto_ablkcipher_setkey(cipher, key, ctl->cipher_keysize); | ||
87 | if (err) { | ||
88 | dprintk("%s: failed to set key for cipher '%s', err: %d.\n", | ||
89 | __func__, ctl->cipher_algo, err); | ||
90 | goto err_out_free; | ||
91 | } | ||
92 | |||
93 | return cipher; | ||
94 | |||
95 | err_out_free: | ||
96 | crypto_free_ablkcipher(cipher); | ||
97 | err_out_exit: | ||
98 | return ERR_PTR(err); | ||
99 | } | ||
100 | |||
101 | /* | ||
102 | * Crypto engine has a pool of pages to encrypt data into before sending | ||
103 | * it over the network. This pool is freed/allocated here. | ||
104 | */ | ||
105 | static void dst_crypto_pages_free(struct dst_crypto_engine *e) | ||
106 | { | ||
107 | unsigned int i; | ||
108 | |||
109 | for (i = 0; i < e->page_num; ++i) | ||
110 | __free_page(e->pages[i]); | ||
111 | kfree(e->pages); | ||
112 | } | ||
113 | |||
114 | static int dst_crypto_pages_alloc(struct dst_crypto_engine *e, int num) | ||
115 | { | ||
116 | int i; | ||
117 | |||
118 | e->pages = kmalloc(num * sizeof(struct page **), GFP_KERNEL); | ||
119 | if (!e->pages) | ||
120 | return -ENOMEM; | ||
121 | |||
122 | for (i = 0; i < num; ++i) { | ||
123 | e->pages[i] = alloc_page(GFP_KERNEL); | ||
124 | if (!e->pages[i]) | ||
125 | goto err_out_free_pages; | ||
126 | } | ||
127 | |||
128 | e->page_num = num; | ||
129 | return 0; | ||
130 | |||
131 | err_out_free_pages: | ||
132 | while (--i >= 0) | ||
133 | __free_page(e->pages[i]); | ||
134 | |||
135 | kfree(e->pages); | ||
136 | return -ENOMEM; | ||
137 | } | ||
138 | |||
139 | /* | ||
140 | * Initialize crypto engine for given node. | ||
141 | * Setup cipher/hash, keys, pool of threads and private data. | ||
142 | */ | ||
143 | static int dst_crypto_engine_init(struct dst_crypto_engine *e, | ||
144 | struct dst_node *n) | ||
145 | { | ||
146 | int err; | ||
147 | struct dst_crypto_ctl *ctl = &n->crypto; | ||
148 | |||
149 | err = dst_crypto_pages_alloc(e, n->max_pages); | ||
150 | if (err) | ||
151 | goto err_out_exit; | ||
152 | |||
153 | e->size = PAGE_SIZE; | ||
154 | e->data = kmalloc(e->size, GFP_KERNEL); | ||
155 | if (!e->data) { | ||
156 | err = -ENOMEM; | ||
157 | goto err_out_free_pages; | ||
158 | } | ||
159 | |||
160 | if (ctl->hash_algo[0]) { | ||
161 | e->hash = dst_init_hash(ctl, n->hash_key); | ||
162 | if (IS_ERR(e->hash)) { | ||
163 | err = PTR_ERR(e->hash); | ||
164 | e->hash = NULL; | ||
165 | goto err_out_free; | ||
166 | } | ||
167 | } | ||
168 | |||
169 | if (ctl->cipher_algo[0]) { | ||
170 | e->cipher = dst_init_cipher(ctl, n->cipher_key); | ||
171 | if (IS_ERR(e->cipher)) { | ||
172 | err = PTR_ERR(e->cipher); | ||
173 | e->cipher = NULL; | ||
174 | goto err_out_free_hash; | ||
175 | } | ||
176 | } | ||
177 | |||
178 | return 0; | ||
179 | |||
180 | err_out_free_hash: | ||
181 | crypto_free_hash(e->hash); | ||
182 | err_out_free: | ||
183 | kfree(e->data); | ||
184 | err_out_free_pages: | ||
185 | dst_crypto_pages_free(e); | ||
186 | err_out_exit: | ||
187 | return err; | ||
188 | } | ||
189 | |||
190 | static void dst_crypto_engine_exit(struct dst_crypto_engine *e) | ||
191 | { | ||
192 | if (e->hash) | ||
193 | crypto_free_hash(e->hash); | ||
194 | if (e->cipher) | ||
195 | crypto_free_ablkcipher(e->cipher); | ||
196 | dst_crypto_pages_free(e); | ||
197 | kfree(e->data); | ||
198 | } | ||
199 | |||
200 | /* | ||
201 | * Waiting for cipher processing to be completed. | ||
202 | */ | ||
203 | struct dst_crypto_completion { | ||
204 | struct completion complete; | ||
205 | int error; | ||
206 | }; | ||
207 | |||
208 | static void dst_crypto_complete(struct crypto_async_request *req, int err) | ||
209 | { | ||
210 | struct dst_crypto_completion *c = req->data; | ||
211 | |||
212 | if (err == -EINPROGRESS) | ||
213 | return; | ||
214 | |||
215 | dprintk("%s: req: %p, err: %d.\n", __func__, req, err); | ||
216 | c->error = err; | ||
217 | complete(&c->complete); | ||
218 | } | ||
219 | |||
220 | static int dst_crypto_process(struct ablkcipher_request *req, | ||
221 | struct scatterlist *sg_dst, struct scatterlist *sg_src, | ||
222 | void *iv, int enc, unsigned long timeout) | ||
223 | { | ||
224 | struct dst_crypto_completion c; | ||
225 | int err; | ||
226 | |||
227 | init_completion(&c.complete); | ||
228 | c.error = -EINPROGRESS; | ||
229 | |||
230 | ablkcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, | ||
231 | dst_crypto_complete, &c); | ||
232 | |||
233 | ablkcipher_request_set_crypt(req, sg_src, sg_dst, sg_src->length, iv); | ||
234 | |||
235 | if (enc) | ||
236 | err = crypto_ablkcipher_encrypt(req); | ||
237 | else | ||
238 | err = crypto_ablkcipher_decrypt(req); | ||
239 | |||
240 | switch (err) { | ||
241 | case -EINPROGRESS: | ||
242 | case -EBUSY: | ||
243 | err = wait_for_completion_interruptible_timeout(&c.complete, | ||
244 | timeout); | ||
245 | if (!err) | ||
246 | err = -ETIMEDOUT; | ||
247 | else | ||
248 | err = c.error; | ||
249 | break; | ||
250 | default: | ||
251 | break; | ||
252 | } | ||
253 | |||
254 | return err; | ||
255 | } | ||
256 | |||
257 | /* | ||
258 | * DST uses generic iteration approach for data crypto processing. | ||
259 | * Single block IO request is switched into array of scatterlists, | ||
260 | * which are submitted to the crypto processing iterator. | ||
261 | * | ||
262 | * Input and output iterator initialization are different, since | ||
263 | * in output case we can not encrypt data in-place and need a | ||
264 | * temporary storage, which is then being sent to the remote peer. | ||
265 | */ | ||
266 | static int dst_trans_iter_out(struct bio *bio, struct dst_crypto_engine *e, | ||
267 | int (*iterator) (struct dst_crypto_engine *e, | ||
268 | struct scatterlist *dst, | ||
269 | struct scatterlist *src)) | ||
270 | { | ||
271 | struct bio_vec *bv; | ||
272 | int err, i; | ||
273 | |||
274 | sg_init_table(e->src, bio->bi_vcnt); | ||
275 | sg_init_table(e->dst, bio->bi_vcnt); | ||
276 | |||
277 | bio_for_each_segment(bv, bio, i) { | ||
278 | sg_set_page(&e->src[i], bv->bv_page, bv->bv_len, bv->bv_offset); | ||
279 | sg_set_page(&e->dst[i], e->pages[i], bv->bv_len, bv->bv_offset); | ||
280 | |||
281 | err = iterator(e, &e->dst[i], &e->src[i]); | ||
282 | if (err) | ||
283 | return err; | ||
284 | } | ||
285 | |||
286 | return 0; | ||
287 | } | ||
288 | |||
289 | static int dst_trans_iter_in(struct bio *bio, struct dst_crypto_engine *e, | ||
290 | int (*iterator) (struct dst_crypto_engine *e, | ||
291 | struct scatterlist *dst, | ||
292 | struct scatterlist *src)) | ||
293 | { | ||
294 | struct bio_vec *bv; | ||
295 | int err, i; | ||
296 | |||
297 | sg_init_table(e->src, bio->bi_vcnt); | ||
298 | sg_init_table(e->dst, bio->bi_vcnt); | ||
299 | |||
300 | bio_for_each_segment(bv, bio, i) { | ||
301 | sg_set_page(&e->src[i], bv->bv_page, bv->bv_len, bv->bv_offset); | ||
302 | sg_set_page(&e->dst[i], bv->bv_page, bv->bv_len, bv->bv_offset); | ||
303 | |||
304 | err = iterator(e, &e->dst[i], &e->src[i]); | ||
305 | if (err) | ||
306 | return err; | ||
307 | } | ||
308 | |||
309 | return 0; | ||
310 | } | ||
311 | |||
312 | static int dst_crypt_iterator(struct dst_crypto_engine *e, | ||
313 | struct scatterlist *sg_dst, struct scatterlist *sg_src) | ||
314 | { | ||
315 | struct ablkcipher_request *req = e->data; | ||
316 | u8 iv[32]; | ||
317 | |||
318 | memset(iv, 0, sizeof(iv)); | ||
319 | |||
320 | memcpy(iv, &e->iv, sizeof(e->iv)); | ||
321 | |||
322 | return dst_crypto_process(req, sg_dst, sg_src, iv, e->enc, e->timeout); | ||
323 | } | ||
324 | |||
325 | static int dst_crypt(struct dst_crypto_engine *e, struct bio *bio) | ||
326 | { | ||
327 | struct ablkcipher_request *req = e->data; | ||
328 | |||
329 | memset(req, 0, sizeof(struct ablkcipher_request)); | ||
330 | ablkcipher_request_set_tfm(req, e->cipher); | ||
331 | |||
332 | if (e->enc) | ||
333 | return dst_trans_iter_out(bio, e, dst_crypt_iterator); | ||
334 | else | ||
335 | return dst_trans_iter_in(bio, e, dst_crypt_iterator); | ||
336 | } | ||
337 | |||
338 | static int dst_hash_iterator(struct dst_crypto_engine *e, | ||
339 | struct scatterlist *sg_dst, struct scatterlist *sg_src) | ||
340 | { | ||
341 | return crypto_hash_update(e->data, sg_src, sg_src->length); | ||
342 | } | ||
343 | |||
344 | static int dst_hash(struct dst_crypto_engine *e, struct bio *bio, void *dst) | ||
345 | { | ||
346 | struct hash_desc *desc = e->data; | ||
347 | int err; | ||
348 | |||
349 | desc->tfm = e->hash; | ||
350 | desc->flags = 0; | ||
351 | |||
352 | err = crypto_hash_init(desc); | ||
353 | if (err) | ||
354 | return err; | ||
355 | |||
356 | err = dst_trans_iter_in(bio, e, dst_hash_iterator); | ||
357 | if (err) | ||
358 | return err; | ||
359 | |||
360 | err = crypto_hash_final(desc, dst); | ||
361 | if (err) | ||
362 | return err; | ||
363 | |||
364 | return 0; | ||
365 | } | ||
366 | |||
367 | /* | ||
368 | * Initialize/cleanup a crypto thread. The only thing it should | ||
369 | * do is to allocate a pool of pages as temporary storage. | ||
370 | * And to setup cipher and/or hash. | ||
371 | */ | ||
372 | static void *dst_crypto_thread_init(void *data) | ||
373 | { | ||
374 | struct dst_node *n = data; | ||
375 | struct dst_crypto_engine *e; | ||
376 | int err = -ENOMEM; | ||
377 | |||
378 | e = kzalloc(sizeof(struct dst_crypto_engine), GFP_KERNEL); | ||
379 | if (!e) | ||
380 | goto err_out_exit; | ||
381 | e->src = kcalloc(2 * n->max_pages, sizeof(struct scatterlist), | ||
382 | GFP_KERNEL); | ||
383 | if (!e->src) | ||
384 | goto err_out_free; | ||
385 | |||
386 | e->dst = e->src + n->max_pages; | ||
387 | |||
388 | err = dst_crypto_engine_init(e, n); | ||
389 | if (err) | ||
390 | goto err_out_free_all; | ||
391 | |||
392 | return e; | ||
393 | |||
394 | err_out_free_all: | ||
395 | kfree(e->src); | ||
396 | err_out_free: | ||
397 | kfree(e); | ||
398 | err_out_exit: | ||
399 | return ERR_PTR(err); | ||
400 | } | ||
401 | |||
402 | static void dst_crypto_thread_cleanup(void *private) | ||
403 | { | ||
404 | struct dst_crypto_engine *e = private; | ||
405 | |||
406 | dst_crypto_engine_exit(e); | ||
407 | kfree(e->src); | ||
408 | kfree(e); | ||
409 | } | ||
410 | |||
411 | /* | ||
412 | * Initialize crypto engine for given node: store keys, create pool | ||
413 | * of threads, initialize each one. | ||
414 | * | ||
415 | * Each thread has unique ID, but 0 and 1 are reserved for receiving and | ||
416 | * accepting threads (if export node), so IDs could start from 2, but starting | ||
417 | * them from 10 allows easily understand what this thread is for. | ||
418 | */ | ||
419 | int dst_node_crypto_init(struct dst_node *n, struct dst_crypto_ctl *ctl) | ||
420 | { | ||
421 | void *key = (ctl + 1); | ||
422 | int err = -ENOMEM, i; | ||
423 | char name[32]; | ||
424 | |||
425 | if (ctl->hash_keysize) { | ||
426 | n->hash_key = kmalloc(ctl->hash_keysize, GFP_KERNEL); | ||
427 | if (!n->hash_key) | ||
428 | goto err_out_exit; | ||
429 | memcpy(n->hash_key, key, ctl->hash_keysize); | ||
430 | } | ||
431 | |||
432 | if (ctl->cipher_keysize) { | ||
433 | n->cipher_key = kmalloc(ctl->cipher_keysize, GFP_KERNEL); | ||
434 | if (!n->cipher_key) | ||
435 | goto err_out_free_hash; | ||
436 | memcpy(n->cipher_key, key, ctl->cipher_keysize); | ||
437 | } | ||
438 | memcpy(&n->crypto, ctl, sizeof(struct dst_crypto_ctl)); | ||
439 | |||
440 | for (i = 0; i < ctl->thread_num; ++i) { | ||
441 | snprintf(name, sizeof(name), "%s-crypto-%d", n->name, i); | ||
442 | /* Unique ids... */ | ||
443 | err = thread_pool_add_worker(n->pool, name, i + 10, | ||
444 | dst_crypto_thread_init, dst_crypto_thread_cleanup, n); | ||
445 | if (err) | ||
446 | goto err_out_free_threads; | ||
447 | } | ||
448 | |||
449 | return 0; | ||
450 | |||
451 | err_out_free_threads: | ||
452 | while (--i >= 0) | ||
453 | thread_pool_del_worker_id(n->pool, i+10); | ||
454 | |||
455 | if (ctl->cipher_keysize) | ||
456 | kfree(n->cipher_key); | ||
457 | ctl->cipher_keysize = 0; | ||
458 | err_out_free_hash: | ||
459 | if (ctl->hash_keysize) | ||
460 | kfree(n->hash_key); | ||
461 | ctl->hash_keysize = 0; | ||
462 | err_out_exit: | ||
463 | return err; | ||
464 | } | ||
465 | |||
466 | void dst_node_crypto_exit(struct dst_node *n) | ||
467 | { | ||
468 | struct dst_crypto_ctl *ctl = &n->crypto; | ||
469 | |||
470 | if (ctl->cipher_algo[0] || ctl->hash_algo[0]) { | ||
471 | kfree(n->hash_key); | ||
472 | kfree(n->cipher_key); | ||
473 | } | ||
474 | } | ||
475 | |||
476 | /* | ||
477 | * Thrad pool setup callback. Just stores a transaction in private data. | ||
478 | */ | ||
479 | static int dst_trans_crypto_setup(void *crypto_engine, void *trans) | ||
480 | { | ||
481 | struct dst_crypto_engine *e = crypto_engine; | ||
482 | |||
483 | e->private = trans; | ||
484 | return 0; | ||
485 | } | ||
486 | |||
487 | #if 0 | ||
488 | static void dst_dump_bio(struct bio *bio) | ||
489 | { | ||
490 | u8 *p; | ||
491 | struct bio_vec *bv; | ||
492 | int i; | ||
493 | |||
494 | bio_for_each_segment(bv, bio, i) { | ||
495 | dprintk("%s: %llu/%u: size: %u, offset: %u, data: ", | ||
496 | __func__, bio->bi_sector, bio->bi_size, | ||
497 | bv->bv_len, bv->bv_offset); | ||
498 | |||
499 | p = kmap(bv->bv_page) + bv->bv_offset; | ||
500 | for (i = 0; i < bv->bv_len; ++i) | ||
501 | printk(KERN_DEBUG "%02x ", p[i]); | ||
502 | kunmap(bv->bv_page); | ||
503 | printk("\n"); | ||
504 | } | ||
505 | } | ||
506 | #endif | ||
507 | |||
508 | /* | ||
509 | * Encrypt/hash data and send it to the network. | ||
510 | */ | ||
511 | static int dst_crypto_process_sending(struct dst_crypto_engine *e, | ||
512 | struct bio *bio, u8 *hash) | ||
513 | { | ||
514 | int err; | ||
515 | |||
516 | if (e->cipher) { | ||
517 | err = dst_crypt(e, bio); | ||
518 | if (err) | ||
519 | goto err_out_exit; | ||
520 | } | ||
521 | |||
522 | if (e->hash) { | ||
523 | err = dst_hash(e, bio, hash); | ||
524 | if (err) | ||
525 | goto err_out_exit; | ||
526 | |||
527 | #ifdef CONFIG_DST_DEBUG | ||
528 | { | ||
529 | unsigned int i; | ||
530 | |||
531 | /* dst_dump_bio(bio); */ | ||
532 | |||
533 | printk(KERN_DEBUG "%s: bio: %llu/%u, rw: %lu, hash: ", | ||
534 | __func__, (u64)bio->bi_sector, | ||
535 | bio->bi_size, bio_data_dir(bio)); | ||
536 | for (i = 0; i < crypto_hash_digestsize(e->hash); ++i) | ||
537 | printk("%02x ", hash[i]); | ||
538 | printk("\n"); | ||
539 | } | ||
540 | #endif | ||
541 | } | ||
542 | |||
543 | return 0; | ||
544 | |||
545 | err_out_exit: | ||
546 | return err; | ||
547 | } | ||
548 | |||
549 | /* | ||
550 | * Check if received data is valid. Decipher if it is. | ||
551 | */ | ||
552 | static int dst_crypto_process_receiving(struct dst_crypto_engine *e, | ||
553 | struct bio *bio, u8 *hash, u8 *recv_hash) | ||
554 | { | ||
555 | int err; | ||
556 | |||
557 | if (e->hash) { | ||
558 | int mismatch; | ||
559 | |||
560 | err = dst_hash(e, bio, hash); | ||
561 | if (err) | ||
562 | goto err_out_exit; | ||
563 | |||
564 | mismatch = !!memcmp(recv_hash, hash, | ||
565 | crypto_hash_digestsize(e->hash)); | ||
566 | #ifdef CONFIG_DST_DEBUG | ||
567 | /* dst_dump_bio(bio); */ | ||
568 | |||
569 | printk(KERN_DEBUG "%s: bio: %llu/%u, rw: %lu, hash mismatch: %d", | ||
570 | __func__, (u64)bio->bi_sector, bio->bi_size, | ||
571 | bio_data_dir(bio), mismatch); | ||
572 | if (mismatch) { | ||
573 | unsigned int i; | ||
574 | |||
575 | printk(", recv/calc: "); | ||
576 | for (i = 0; i < crypto_hash_digestsize(e->hash); ++i) | ||
577 | printk("%02x/%02x ", recv_hash[i], hash[i]); | ||
578 | |||
579 | } | ||
580 | printk("\n"); | ||
581 | #endif | ||
582 | err = -1; | ||
583 | if (mismatch) | ||
584 | goto err_out_exit; | ||
585 | } | ||
586 | |||
587 | if (e->cipher) { | ||
588 | err = dst_crypt(e, bio); | ||
589 | if (err) | ||
590 | goto err_out_exit; | ||
591 | } | ||
592 | |||
593 | return 0; | ||
594 | |||
595 | err_out_exit: | ||
596 | return err; | ||
597 | } | ||
598 | |||
599 | /* | ||
600 | * Thread pool callback to encrypt data and send it to the netowork. | ||
601 | */ | ||
602 | static int dst_trans_crypto_action(void *crypto_engine, void *schedule_data) | ||
603 | { | ||
604 | struct dst_crypto_engine *e = crypto_engine; | ||
605 | struct dst_trans *t = schedule_data; | ||
606 | struct bio *bio = t->bio; | ||
607 | int err; | ||
608 | |||
609 | dprintk("%s: t: %p, gen: %llu, cipher: %p, hash: %p.\n", | ||
610 | __func__, t, t->gen, e->cipher, e->hash); | ||
611 | |||
612 | e->enc = t->enc; | ||
613 | e->iv = dst_gen_iv(t); | ||
614 | |||
615 | if (bio_data_dir(bio) == WRITE) { | ||
616 | err = dst_crypto_process_sending(e, bio, t->cmd.hash); | ||
617 | if (err) | ||
618 | goto err_out_exit; | ||
619 | |||
620 | if (e->hash) { | ||
621 | t->cmd.csize = crypto_hash_digestsize(e->hash); | ||
622 | t->cmd.size += t->cmd.csize; | ||
623 | } | ||
624 | |||
625 | return dst_trans_send(t); | ||
626 | } else { | ||
627 | u8 *hash = e->data + e->size/2; | ||
628 | |||
629 | err = dst_crypto_process_receiving(e, bio, hash, t->cmd.hash); | ||
630 | if (err) | ||
631 | goto err_out_exit; | ||
632 | |||
633 | dst_trans_remove(t); | ||
634 | dst_trans_put(t); | ||
635 | } | ||
636 | |||
637 | return 0; | ||
638 | |||
639 | err_out_exit: | ||
640 | t->error = err; | ||
641 | dst_trans_put(t); | ||
642 | return err; | ||
643 | } | ||
644 | |||
645 | /* | ||
646 | * Schedule crypto processing for given transaction. | ||
647 | */ | ||
648 | int dst_trans_crypto(struct dst_trans *t) | ||
649 | { | ||
650 | struct dst_node *n = t->n; | ||
651 | int err; | ||
652 | |||
653 | err = thread_pool_schedule(n->pool, | ||
654 | dst_trans_crypto_setup, dst_trans_crypto_action, | ||
655 | t, MAX_SCHEDULE_TIMEOUT); | ||
656 | if (err) | ||
657 | goto err_out_exit; | ||
658 | |||
659 | return 0; | ||
660 | |||
661 | err_out_exit: | ||
662 | dst_trans_put(t); | ||
663 | return err; | ||
664 | } | ||
665 | |||
666 | /* | ||
667 | * Crypto machinery for the export node. | ||
668 | */ | ||
669 | static int dst_export_crypto_setup(void *crypto_engine, void *bio) | ||
670 | { | ||
671 | struct dst_crypto_engine *e = crypto_engine; | ||
672 | |||
673 | e->private = bio; | ||
674 | return 0; | ||
675 | } | ||
676 | |||
677 | static int dst_export_crypto_action(void *crypto_engine, void *schedule_data) | ||
678 | { | ||
679 | struct dst_crypto_engine *e = crypto_engine; | ||
680 | struct bio *bio = schedule_data; | ||
681 | struct dst_export_priv *p = bio->bi_private; | ||
682 | int err; | ||
683 | |||
684 | dprintk("%s: e: %p, data: %p, bio: %llu/%u, dir: %lu.\n", | ||
685 | __func__, e, e->data, (u64)bio->bi_sector, | ||
686 | bio->bi_size, bio_data_dir(bio)); | ||
687 | |||
688 | e->enc = (bio_data_dir(bio) == READ); | ||
689 | e->iv = p->cmd.id; | ||
690 | |||
691 | if (bio_data_dir(bio) == WRITE) { | ||
692 | u8 *hash = e->data + e->size/2; | ||
693 | |||
694 | err = dst_crypto_process_receiving(e, bio, hash, p->cmd.hash); | ||
695 | if (err) | ||
696 | goto err_out_exit; | ||
697 | |||
698 | generic_make_request(bio); | ||
699 | } else { | ||
700 | err = dst_crypto_process_sending(e, bio, p->cmd.hash); | ||
701 | if (err) | ||
702 | goto err_out_exit; | ||
703 | |||
704 | if (e->hash) { | ||
705 | p->cmd.csize = crypto_hash_digestsize(e->hash); | ||
706 | p->cmd.size += p->cmd.csize; | ||
707 | } | ||
708 | |||
709 | err = dst_export_send_bio(bio); | ||
710 | } | ||
711 | return 0; | ||
712 | |||
713 | err_out_exit: | ||
714 | bio_put(bio); | ||
715 | return err; | ||
716 | } | ||
717 | |||
718 | int dst_export_crypto(struct dst_node *n, struct bio *bio) | ||
719 | { | ||
720 | int err; | ||
721 | |||
722 | err = thread_pool_schedule(n->pool, | ||
723 | dst_export_crypto_setup, dst_export_crypto_action, | ||
724 | bio, MAX_SCHEDULE_TIMEOUT); | ||
725 | if (err) | ||
726 | goto err_out_exit; | ||
727 | |||
728 | return 0; | ||
729 | |||
730 | err_out_exit: | ||
731 | bio_put(bio); | ||
732 | return err; | ||
733 | } | ||
diff --git a/drivers/staging/dst/dcore.c b/drivers/staging/dst/dcore.c deleted file mode 100644 index c83ca7e3d048..000000000000 --- a/drivers/staging/dst/dcore.c +++ /dev/null | |||
@@ -1,968 +0,0 @@ | |||
1 | /* | ||
2 | * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net> | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | */ | ||
15 | |||
16 | #include <linux/module.h> | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/blkdev.h> | ||
19 | #include <linux/bio.h> | ||
20 | #include <linux/buffer_head.h> | ||
21 | #include <linux/connector.h> | ||
22 | #include <linux/dst.h> | ||
23 | #include <linux/device.h> | ||
24 | #include <linux/jhash.h> | ||
25 | #include <linux/idr.h> | ||
26 | #include <linux/init.h> | ||
27 | #include <linux/namei.h> | ||
28 | #include <linux/slab.h> | ||
29 | #include <linux/socket.h> | ||
30 | |||
31 | #include <linux/in.h> | ||
32 | #include <linux/in6.h> | ||
33 | |||
34 | #include <net/sock.h> | ||
35 | |||
36 | static int dst_major; | ||
37 | |||
38 | static DEFINE_MUTEX(dst_hash_lock); | ||
39 | static struct list_head *dst_hashtable; | ||
40 | static unsigned int dst_hashtable_size = 128; | ||
41 | module_param(dst_hashtable_size, uint, 0644); | ||
42 | |||
43 | static char dst_name[] = "Dementianting goldfish"; | ||
44 | |||
45 | static DEFINE_IDR(dst_index_idr); | ||
46 | static struct cb_id cn_dst_id = { CN_DST_IDX, CN_DST_VAL }; | ||
47 | |||
48 | /* | ||
49 | * DST sysfs tree for device called 'storage': | ||
50 | * | ||
51 | * /sys/bus/dst/devices/storage/ | ||
52 | * /sys/bus/dst/devices/storage/type : 192.168.4.80:1025 | ||
53 | * /sys/bus/dst/devices/storage/size : 800 | ||
54 | * /sys/bus/dst/devices/storage/name : storage | ||
55 | */ | ||
56 | |||
57 | static int dst_dev_match(struct device *dev, struct device_driver *drv) | ||
58 | { | ||
59 | return 1; | ||
60 | } | ||
61 | |||
62 | static struct bus_type dst_dev_bus_type = { | ||
63 | .name = "dst", | ||
64 | .match = &dst_dev_match, | ||
65 | }; | ||
66 | |||
67 | static void dst_node_release(struct device *dev) | ||
68 | { | ||
69 | struct dst_info *info = container_of(dev, struct dst_info, device); | ||
70 | |||
71 | kfree(info); | ||
72 | } | ||
73 | |||
74 | static struct device dst_node_dev = { | ||
75 | .bus = &dst_dev_bus_type, | ||
76 | .release = &dst_node_release | ||
77 | }; | ||
78 | |||
79 | /* | ||
80 | * Setting size of the node after it was changed. | ||
81 | */ | ||
82 | static void dst_node_set_size(struct dst_node *n) | ||
83 | { | ||
84 | struct block_device *bdev; | ||
85 | |||
86 | set_capacity(n->disk, n->size >> 9); | ||
87 | |||
88 | bdev = bdget_disk(n->disk, 0); | ||
89 | if (bdev) { | ||
90 | mutex_lock(&bdev->bd_inode->i_mutex); | ||
91 | i_size_write(bdev->bd_inode, n->size); | ||
92 | mutex_unlock(&bdev->bd_inode->i_mutex); | ||
93 | bdput(bdev); | ||
94 | } | ||
95 | } | ||
96 | |||
97 | /* | ||
98 | * Distributed storage request processing function. | ||
99 | */ | ||
100 | static int dst_request(struct request_queue *q, struct bio *bio) | ||
101 | { | ||
102 | struct dst_node *n = q->queuedata; | ||
103 | int err = -EIO; | ||
104 | |||
105 | if (bio_empty_barrier(bio) && !blk_queue_discard(q)) { | ||
106 | /* | ||
107 | * This is a dirty^Wnice hack, but if we complete this | ||
108 | * operation with -EOPNOTSUPP like intended, XFS | ||
109 | * will stuck and freeze the machine. This may be | ||
110 | * not particulary XFS problem though, but it is the | ||
111 | * only FS which sends empty barrier at umount time | ||
112 | * I worked with. | ||
113 | * | ||
114 | * Empty barriers are not allowed anyway, see 51fd77bd9f512 | ||
115 | * for example, although later it was changed to | ||
116 | * bio_rw_flagged(bio, BIO_RW_DISCARD) only, which does not | ||
117 | * work in this case. | ||
118 | */ | ||
119 | /* err = -EOPNOTSUPP; */ | ||
120 | err = 0; | ||
121 | goto end_io; | ||
122 | } | ||
123 | |||
124 | bio_get(bio); | ||
125 | |||
126 | return dst_process_bio(n, bio); | ||
127 | |||
128 | end_io: | ||
129 | bio_endio(bio, err); | ||
130 | return err; | ||
131 | } | ||
132 | |||
133 | /* | ||
134 | * Open/close callbacks for appropriate block device. | ||
135 | */ | ||
136 | static int dst_bdev_open(struct block_device *bdev, fmode_t mode) | ||
137 | { | ||
138 | struct dst_node *n = bdev->bd_disk->private_data; | ||
139 | |||
140 | dst_node_get(n); | ||
141 | return 0; | ||
142 | } | ||
143 | |||
144 | static int dst_bdev_release(struct gendisk *disk, fmode_t mode) | ||
145 | { | ||
146 | struct dst_node *n = disk->private_data; | ||
147 | |||
148 | dst_node_put(n); | ||
149 | return 0; | ||
150 | } | ||
151 | |||
152 | static struct block_device_operations dst_blk_ops = { | ||
153 | .open = dst_bdev_open, | ||
154 | .release = dst_bdev_release, | ||
155 | .owner = THIS_MODULE, | ||
156 | }; | ||
157 | |||
158 | /* | ||
159 | * Block layer binding - disk is created when array is fully configured | ||
160 | * by userspace request. | ||
161 | */ | ||
162 | static int dst_node_create_disk(struct dst_node *n) | ||
163 | { | ||
164 | int err = -ENOMEM; | ||
165 | u32 index = 0; | ||
166 | |||
167 | n->queue = blk_init_queue(NULL, NULL); | ||
168 | if (!n->queue) | ||
169 | goto err_out_exit; | ||
170 | |||
171 | n->queue->queuedata = n; | ||
172 | blk_queue_make_request(n->queue, dst_request); | ||
173 | blk_queue_max_phys_segments(n->queue, n->max_pages); | ||
174 | blk_queue_max_hw_segments(n->queue, n->max_pages); | ||
175 | |||
176 | err = -ENOMEM; | ||
177 | n->disk = alloc_disk(1); | ||
178 | if (!n->disk) | ||
179 | goto err_out_free_queue; | ||
180 | |||
181 | if (!(n->state->permissions & DST_PERM_WRITE)) { | ||
182 | printk(KERN_INFO "DST node %s attached read-only.\n", n->name); | ||
183 | set_disk_ro(n->disk, 1); | ||
184 | } | ||
185 | |||
186 | if (!idr_pre_get(&dst_index_idr, GFP_KERNEL)) | ||
187 | goto err_out_put; | ||
188 | |||
189 | mutex_lock(&dst_hash_lock); | ||
190 | err = idr_get_new(&dst_index_idr, NULL, &index); | ||
191 | mutex_unlock(&dst_hash_lock); | ||
192 | if (err) | ||
193 | goto err_out_put; | ||
194 | |||
195 | n->disk->major = dst_major; | ||
196 | n->disk->first_minor = index; | ||
197 | n->disk->fops = &dst_blk_ops; | ||
198 | n->disk->queue = n->queue; | ||
199 | n->disk->private_data = n; | ||
200 | snprintf(n->disk->disk_name, sizeof(n->disk->disk_name), | ||
201 | "dst-%s", n->name); | ||
202 | |||
203 | return 0; | ||
204 | |||
205 | err_out_put: | ||
206 | put_disk(n->disk); | ||
207 | err_out_free_queue: | ||
208 | blk_cleanup_queue(n->queue); | ||
209 | err_out_exit: | ||
210 | return err; | ||
211 | } | ||
212 | |||
213 | /* | ||
214 | * Sysfs machinery: show device's size. | ||
215 | */ | ||
216 | static ssize_t dst_show_size(struct device *dev, | ||
217 | struct device_attribute *attr, char *buf) | ||
218 | { | ||
219 | struct dst_info *info = container_of(dev, struct dst_info, device); | ||
220 | |||
221 | return sprintf(buf, "%llu\n", info->size); | ||
222 | } | ||
223 | |||
224 | /* | ||
225 | * Show local exported device. | ||
226 | */ | ||
227 | static ssize_t dst_show_local(struct device *dev, | ||
228 | struct device_attribute *attr, char *buf) | ||
229 | { | ||
230 | struct dst_info *info = container_of(dev, struct dst_info, device); | ||
231 | |||
232 | return sprintf(buf, "%s\n", info->local); | ||
233 | } | ||
234 | |||
235 | /* | ||
236 | * Shows type of the remote node - device major/minor number | ||
237 | * for local nodes and address (af_inet ipv4/ipv6 only) for remote nodes. | ||
238 | */ | ||
239 | static ssize_t dst_show_type(struct device *dev, | ||
240 | struct device_attribute *attr, char *buf) | ||
241 | { | ||
242 | struct dst_info *info = container_of(dev, struct dst_info, device); | ||
243 | int family = info->net.addr.sa_family; | ||
244 | |||
245 | if (family == AF_INET) { | ||
246 | struct sockaddr_in *sin = (struct sockaddr_in *)&info->net.addr; | ||
247 | return sprintf(buf, "%u.%u.%u.%u:%d\n", | ||
248 | NIPQUAD(sin->sin_addr.s_addr), ntohs(sin->sin_port)); | ||
249 | } else if (family == AF_INET6) { | ||
250 | struct sockaddr_in6 *sin = (struct sockaddr_in6 *) | ||
251 | &info->net.addr; | ||
252 | return sprintf(buf, | ||
253 | "%pi6:%d\n", | ||
254 | &sin->sin6_addr, ntohs(sin->sin6_port)); | ||
255 | } else { | ||
256 | int i, sz = PAGE_SIZE - 2; /* 0 symbol and '\n' below */ | ||
257 | int size, addrlen = info->net.addr.sa_data_len; | ||
258 | unsigned char *a = (unsigned char *)&info->net.addr.sa_data; | ||
259 | char *buf_orig = buf; | ||
260 | |||
261 | size = snprintf(buf, sz, "family: %d, addrlen: %u, addr: ", | ||
262 | family, addrlen); | ||
263 | sz -= size; | ||
264 | buf += size; | ||
265 | |||
266 | for (i = 0; i < addrlen; ++i) { | ||
267 | if (sz < 3) | ||
268 | break; | ||
269 | |||
270 | size = snprintf(buf, sz, "%02x ", a[i]); | ||
271 | sz -= size; | ||
272 | buf += size; | ||
273 | } | ||
274 | buf += sprintf(buf, "\n"); | ||
275 | |||
276 | return buf - buf_orig; | ||
277 | } | ||
278 | return 0; | ||
279 | } | ||
280 | |||
281 | static struct device_attribute dst_node_attrs[] = { | ||
282 | __ATTR(size, 0444, dst_show_size, NULL), | ||
283 | __ATTR(type, 0444, dst_show_type, NULL), | ||
284 | __ATTR(local, 0444, dst_show_local, NULL), | ||
285 | }; | ||
286 | |||
287 | static int dst_create_node_attributes(struct dst_node *n) | ||
288 | { | ||
289 | int err, i; | ||
290 | |||
291 | for (i = 0; i < ARRAY_SIZE(dst_node_attrs); ++i) { | ||
292 | err = device_create_file(&n->info->device, | ||
293 | &dst_node_attrs[i]); | ||
294 | if (err) | ||
295 | goto err_out_remove_all; | ||
296 | } | ||
297 | return 0; | ||
298 | |||
299 | err_out_remove_all: | ||
300 | while (--i >= 0) | ||
301 | device_remove_file(&n->info->device, | ||
302 | &dst_node_attrs[i]); | ||
303 | |||
304 | return err; | ||
305 | } | ||
306 | |||
307 | static void dst_remove_node_attributes(struct dst_node *n) | ||
308 | { | ||
309 | int i; | ||
310 | |||
311 | for (i = 0; i < ARRAY_SIZE(dst_node_attrs); ++i) | ||
312 | device_remove_file(&n->info->device, | ||
313 | &dst_node_attrs[i]); | ||
314 | } | ||
315 | |||
316 | /* | ||
317 | * Sysfs cleanup and initialization. | ||
318 | * Shows number of useful parameters. | ||
319 | */ | ||
320 | static void dst_node_sysfs_exit(struct dst_node *n) | ||
321 | { | ||
322 | if (n->info) { | ||
323 | dst_remove_node_attributes(n); | ||
324 | device_unregister(&n->info->device); | ||
325 | n->info = NULL; | ||
326 | } | ||
327 | } | ||
328 | |||
329 | static int dst_node_sysfs_init(struct dst_node *n) | ||
330 | { | ||
331 | int err; | ||
332 | |||
333 | n->info = kzalloc(sizeof(struct dst_info), GFP_KERNEL); | ||
334 | if (!n->info) | ||
335 | return -ENOMEM; | ||
336 | |||
337 | memcpy(&n->info->device, &dst_node_dev, sizeof(struct device)); | ||
338 | n->info->size = n->size; | ||
339 | |||
340 | dev_set_name(&n->info->device, "dst-%s", n->name); | ||
341 | err = device_register(&n->info->device); | ||
342 | if (err) { | ||
343 | dprintk(KERN_ERR "Failed to register node '%s', err: %d.\n", | ||
344 | n->name, err); | ||
345 | goto err_out_exit; | ||
346 | } | ||
347 | |||
348 | dst_create_node_attributes(n); | ||
349 | |||
350 | return 0; | ||
351 | |||
352 | err_out_exit: | ||
353 | kfree(n->info); | ||
354 | n->info = NULL; | ||
355 | return err; | ||
356 | } | ||
357 | |||
358 | /* | ||
359 | * DST node hash tables machinery. | ||
360 | */ | ||
361 | static inline unsigned int dst_hash(char *str, unsigned int size) | ||
362 | { | ||
363 | return jhash(str, size, 0) % dst_hashtable_size; | ||
364 | } | ||
365 | |||
366 | static void dst_node_remove(struct dst_node *n) | ||
367 | { | ||
368 | mutex_lock(&dst_hash_lock); | ||
369 | list_del_init(&n->node_entry); | ||
370 | mutex_unlock(&dst_hash_lock); | ||
371 | } | ||
372 | |||
373 | static void dst_node_add(struct dst_node *n) | ||
374 | { | ||
375 | unsigned hash = dst_hash(n->name, sizeof(n->name)); | ||
376 | |||
377 | mutex_lock(&dst_hash_lock); | ||
378 | list_add_tail(&n->node_entry, &dst_hashtable[hash]); | ||
379 | mutex_unlock(&dst_hash_lock); | ||
380 | } | ||
381 | |||
382 | /* | ||
383 | * Cleaning node when it is about to be freed. | ||
384 | * There are still users of the socket though, | ||
385 | * so connection cleanup should be protected. | ||
386 | */ | ||
387 | static void dst_node_cleanup(struct dst_node *n) | ||
388 | { | ||
389 | struct dst_state *st = n->state; | ||
390 | |||
391 | if (!st) | ||
392 | return; | ||
393 | |||
394 | if (n->queue) { | ||
395 | blk_cleanup_queue(n->queue); | ||
396 | |||
397 | mutex_lock(&dst_hash_lock); | ||
398 | idr_remove(&dst_index_idr, n->disk->first_minor); | ||
399 | mutex_unlock(&dst_hash_lock); | ||
400 | |||
401 | put_disk(n->disk); | ||
402 | } | ||
403 | |||
404 | if (n->bdev) { | ||
405 | sync_blockdev(n->bdev); | ||
406 | close_bdev_exclusive(n->bdev, FMODE_READ|FMODE_WRITE); | ||
407 | } | ||
408 | |||
409 | dst_state_lock(st); | ||
410 | st->need_exit = 1; | ||
411 | dst_state_exit_connected(st); | ||
412 | dst_state_unlock(st); | ||
413 | |||
414 | wake_up(&st->thread_wait); | ||
415 | |||
416 | dst_state_put(st); | ||
417 | n->state = NULL; | ||
418 | } | ||
419 | |||
420 | /* | ||
421 | * Free security attributes attached to given node. | ||
422 | */ | ||
423 | static void dst_security_exit(struct dst_node *n) | ||
424 | { | ||
425 | struct dst_secure *s, *tmp; | ||
426 | |||
427 | list_for_each_entry_safe(s, tmp, &n->security_list, sec_entry) { | ||
428 | list_del(&s->sec_entry); | ||
429 | kfree(s); | ||
430 | } | ||
431 | } | ||
432 | |||
433 | /* | ||
434 | * Free node when there are no more users. | ||
435 | * Actually node has to be freed on behalf od userspace process, | ||
436 | * since there are number of threads, which are embedded in the | ||
437 | * node, so they can not exit and free node from there, that is | ||
438 | * why there is a wakeup if reference counter is not equal to zero. | ||
439 | */ | ||
440 | void dst_node_put(struct dst_node *n) | ||
441 | { | ||
442 | if (unlikely(!n)) | ||
443 | return; | ||
444 | |||
445 | dprintk("%s: n: %p, refcnt: %d.\n", | ||
446 | __func__, n, atomic_read(&n->refcnt)); | ||
447 | |||
448 | if (atomic_dec_and_test(&n->refcnt)) { | ||
449 | dst_node_remove(n); | ||
450 | n->trans_scan_timeout = 0; | ||
451 | dst_node_cleanup(n); | ||
452 | thread_pool_destroy(n->pool); | ||
453 | dst_node_sysfs_exit(n); | ||
454 | dst_node_crypto_exit(n); | ||
455 | dst_security_exit(n); | ||
456 | dst_node_trans_exit(n); | ||
457 | |||
458 | kfree(n); | ||
459 | |||
460 | dprintk("%s: freed n: %p.\n", __func__, n); | ||
461 | } else { | ||
462 | wake_up(&n->wait); | ||
463 | } | ||
464 | } | ||
465 | |||
466 | /* | ||
467 | * Setting up export device: lookup by the name, get its size | ||
468 | * and setup listening socket, which will accept clients, which | ||
469 | * will submit IO for given storage. | ||
470 | */ | ||
471 | static int dst_setup_export(struct dst_node *n, struct dst_ctl *ctl, | ||
472 | struct dst_export_ctl *le) | ||
473 | { | ||
474 | int err; | ||
475 | |||
476 | snprintf(n->info->local, sizeof(n->info->local), "%s", le->device); | ||
477 | |||
478 | n->bdev = open_bdev_exclusive(le->device, FMODE_READ|FMODE_WRITE, NULL); | ||
479 | if (IS_ERR(n->bdev)) | ||
480 | return PTR_ERR(n->bdev); | ||
481 | |||
482 | if (n->size != 0) | ||
483 | n->size = min_t(loff_t, n->bdev->bd_inode->i_size, n->size); | ||
484 | else | ||
485 | n->size = n->bdev->bd_inode->i_size; | ||
486 | |||
487 | n->info->size = n->size; | ||
488 | err = dst_node_init_listened(n, le); | ||
489 | if (err) | ||
490 | goto err_out_cleanup; | ||
491 | |||
492 | return 0; | ||
493 | |||
494 | err_out_cleanup: | ||
495 | close_bdev_exclusive(n->bdev, FMODE_READ|FMODE_WRITE); | ||
496 | n->bdev = NULL; | ||
497 | |||
498 | return err; | ||
499 | } | ||
500 | |||
501 | /* Empty thread pool callbacks for the network processing threads. */ | ||
502 | static inline void *dst_thread_network_init(void *data) | ||
503 | { | ||
504 | dprintk("%s: data: %p.\n", __func__, data); | ||
505 | return data; | ||
506 | } | ||
507 | |||
508 | static inline void dst_thread_network_cleanup(void *data) | ||
509 | { | ||
510 | dprintk("%s: data: %p.\n", __func__, data); | ||
511 | } | ||
512 | |||
513 | /* | ||
514 | * Allocate DST node and initialize some of its parameters. | ||
515 | */ | ||
516 | static struct dst_node *dst_alloc_node(struct dst_ctl *ctl, | ||
517 | int (*start)(struct dst_node *), | ||
518 | int num) | ||
519 | { | ||
520 | struct dst_node *n; | ||
521 | int err; | ||
522 | |||
523 | n = kzalloc(sizeof(struct dst_node), GFP_KERNEL); | ||
524 | if (!n) | ||
525 | return NULL; | ||
526 | |||
527 | INIT_LIST_HEAD(&n->node_entry); | ||
528 | |||
529 | INIT_LIST_HEAD(&n->security_list); | ||
530 | mutex_init(&n->security_lock); | ||
531 | |||
532 | init_waitqueue_head(&n->wait); | ||
533 | |||
534 | n->trans_scan_timeout = msecs_to_jiffies(ctl->trans_scan_timeout); | ||
535 | if (!n->trans_scan_timeout) | ||
536 | n->trans_scan_timeout = HZ; | ||
537 | |||
538 | n->trans_max_retries = ctl->trans_max_retries; | ||
539 | if (!n->trans_max_retries) | ||
540 | n->trans_max_retries = 10; | ||
541 | |||
542 | /* | ||
543 | * Pretty much arbitrary default numbers. | ||
544 | * 32 matches maximum number of pages in bio originated from ext3 (31). | ||
545 | */ | ||
546 | n->max_pages = ctl->max_pages; | ||
547 | if (!n->max_pages) | ||
548 | n->max_pages = 32; | ||
549 | |||
550 | if (n->max_pages > 1024) | ||
551 | n->max_pages = 1024; | ||
552 | |||
553 | n->start = start; | ||
554 | n->size = ctl->size; | ||
555 | |||
556 | atomic_set(&n->refcnt, 1); | ||
557 | atomic_long_set(&n->gen, 0); | ||
558 | snprintf(n->name, sizeof(n->name), "%s", ctl->name); | ||
559 | |||
560 | err = dst_node_sysfs_init(n); | ||
561 | if (err) | ||
562 | goto err_out_free; | ||
563 | |||
564 | n->pool = thread_pool_create(num, n->name, dst_thread_network_init, | ||
565 | dst_thread_network_cleanup, n); | ||
566 | if (IS_ERR(n->pool)) { | ||
567 | err = PTR_ERR(n->pool); | ||
568 | goto err_out_sysfs_exit; | ||
569 | } | ||
570 | |||
571 | dprintk("%s: n: %p, name: %s.\n", __func__, n, n->name); | ||
572 | |||
573 | return n; | ||
574 | |||
575 | err_out_sysfs_exit: | ||
576 | dst_node_sysfs_exit(n); | ||
577 | err_out_free: | ||
578 | kfree(n); | ||
579 | return NULL; | ||
580 | } | ||
581 | |||
582 | /* | ||
583 | * Starting a node, connected to the remote server: | ||
584 | * register block device and initialize transaction mechanism. | ||
585 | * In revers order though. | ||
586 | * | ||
587 | * It will autonegotiate some parameters with the remote node | ||
588 | * and update local if needed. | ||
589 | * | ||
590 | * Transaction initialization should be the last thing before | ||
591 | * starting the node, since transaction should include not only | ||
592 | * block IO, but also crypto related data (if any), which are | ||
593 | * initialized separately. | ||
594 | */ | ||
595 | static int dst_start_remote(struct dst_node *n) | ||
596 | { | ||
597 | int err; | ||
598 | |||
599 | err = dst_node_trans_init(n, sizeof(struct dst_trans)); | ||
600 | if (err) | ||
601 | return err; | ||
602 | |||
603 | err = dst_node_create_disk(n); | ||
604 | if (err) | ||
605 | return err; | ||
606 | |||
607 | dst_node_set_size(n); | ||
608 | add_disk(n->disk); | ||
609 | |||
610 | dprintk("DST: started remote node '%s', minor: %d.\n", | ||
611 | n->name, n->disk->first_minor); | ||
612 | |||
613 | return 0; | ||
614 | } | ||
615 | |||
616 | /* | ||
617 | * Adding remote node and initialize connection. | ||
618 | */ | ||
619 | static int dst_add_remote(struct dst_node *n, struct dst_ctl *ctl, | ||
620 | void *data, unsigned int size) | ||
621 | { | ||
622 | int err; | ||
623 | struct dst_network_ctl *rctl = data; | ||
624 | |||
625 | if (n) | ||
626 | return -EEXIST; | ||
627 | |||
628 | if (size != sizeof(struct dst_network_ctl)) | ||
629 | return -EINVAL; | ||
630 | |||
631 | n = dst_alloc_node(ctl, dst_start_remote, 1); | ||
632 | if (!n) | ||
633 | return -ENOMEM; | ||
634 | |||
635 | memcpy(&n->info->net, rctl, sizeof(struct dst_network_ctl)); | ||
636 | err = dst_node_init_connected(n, rctl); | ||
637 | if (err) | ||
638 | goto err_out_free; | ||
639 | |||
640 | dst_node_add(n); | ||
641 | |||
642 | return 0; | ||
643 | |||
644 | err_out_free: | ||
645 | dst_node_put(n); | ||
646 | return err; | ||
647 | } | ||
648 | |||
649 | /* | ||
650 | * Adding export node: initializing block device and listening socket. | ||
651 | */ | ||
652 | static int dst_add_export(struct dst_node *n, struct dst_ctl *ctl, | ||
653 | void *data, unsigned int size) | ||
654 | { | ||
655 | int err; | ||
656 | struct dst_export_ctl *le = data; | ||
657 | |||
658 | if (n) | ||
659 | return -EEXIST; | ||
660 | |||
661 | if (size != sizeof(struct dst_export_ctl)) | ||
662 | return -EINVAL; | ||
663 | |||
664 | n = dst_alloc_node(ctl, dst_start_export, 2); | ||
665 | if (!n) | ||
666 | return -EINVAL; | ||
667 | |||
668 | err = dst_setup_export(n, ctl, le); | ||
669 | if (err) | ||
670 | goto err_out_free; | ||
671 | |||
672 | dst_node_add(n); | ||
673 | |||
674 | return 0; | ||
675 | |||
676 | err_out_free: | ||
677 | dst_node_put(n); | ||
678 | return err; | ||
679 | } | ||
680 | |||
681 | static int dst_node_remove_unload(struct dst_node *n) | ||
682 | { | ||
683 | printk(KERN_INFO "STOPPED name: '%s', size: %llu.\n", | ||
684 | n->name, n->size); | ||
685 | |||
686 | if (n->disk) | ||
687 | del_gendisk(n->disk); | ||
688 | |||
689 | dst_node_remove(n); | ||
690 | dst_node_sysfs_exit(n); | ||
691 | |||
692 | /* | ||
693 | * This is not a hack. Really. | ||
694 | * Node's reference counter allows to implement fine grained | ||
695 | * node freeing, but since all transactions (which hold node's | ||
696 | * reference counter) are processed in the dedicated thread, | ||
697 | * it is possible that reference will hit zero in that thread, | ||
698 | * so we will not be able to exit thread and cleanup the node. | ||
699 | * | ||
700 | * So, we remove disk, so no new activity is possible, and | ||
701 | * wait until all pending transaction are completed (either | ||
702 | * in receiving thread or by timeout in workqueue), in this | ||
703 | * case reference counter will be less or equal to 2 (once set in | ||
704 | * dst_alloc_node() and then in connector message parser; | ||
705 | * or when we force module unloading, and connector message | ||
706 | * parser does not hold a reference, in this case reference | ||
707 | * counter will be equal to 1), | ||
708 | * and subsequent dst_node_put() calls will free the node. | ||
709 | */ | ||
710 | dprintk("%s: going to sleep with %d refcnt.\n", | ||
711 | __func__, atomic_read(&n->refcnt)); | ||
712 | wait_event(n->wait, atomic_read(&n->refcnt) <= 2); | ||
713 | |||
714 | dst_node_put(n); | ||
715 | return 0; | ||
716 | } | ||
717 | |||
718 | /* | ||
719 | * Remove node from the hash table. | ||
720 | */ | ||
721 | static int dst_del_node(struct dst_node *n, struct dst_ctl *ctl, | ||
722 | void *data, unsigned int size) | ||
723 | { | ||
724 | if (!n) | ||
725 | return -ENODEV; | ||
726 | |||
727 | return dst_node_remove_unload(n); | ||
728 | } | ||
729 | |||
730 | /* | ||
731 | * Initialize crypto processing for given node. | ||
732 | */ | ||
733 | static int dst_crypto_init(struct dst_node *n, struct dst_ctl *ctl, | ||
734 | void *data, unsigned int size) | ||
735 | { | ||
736 | struct dst_crypto_ctl *crypto = data; | ||
737 | |||
738 | if (!n) | ||
739 | return -ENODEV; | ||
740 | |||
741 | if (size != sizeof(struct dst_crypto_ctl) + crypto->hash_keysize + | ||
742 | crypto->cipher_keysize) | ||
743 | return -EINVAL; | ||
744 | |||
745 | if (n->trans_cache) | ||
746 | return -EEXIST; | ||
747 | |||
748 | return dst_node_crypto_init(n, crypto); | ||
749 | } | ||
750 | |||
751 | /* | ||
752 | * Security attributes for given node. | ||
753 | */ | ||
754 | static int dst_security_init(struct dst_node *n, struct dst_ctl *ctl, | ||
755 | void *data, unsigned int size) | ||
756 | { | ||
757 | struct dst_secure *s; | ||
758 | |||
759 | if (!n) | ||
760 | return -ENODEV; | ||
761 | |||
762 | if (size != sizeof(struct dst_secure_user)) | ||
763 | return -EINVAL; | ||
764 | |||
765 | s = kmalloc(sizeof(struct dst_secure), GFP_KERNEL); | ||
766 | if (!s) | ||
767 | return -ENOMEM; | ||
768 | |||
769 | memcpy(&s->sec, data, size); | ||
770 | |||
771 | mutex_lock(&n->security_lock); | ||
772 | list_add_tail(&s->sec_entry, &n->security_list); | ||
773 | mutex_unlock(&n->security_lock); | ||
774 | |||
775 | return 0; | ||
776 | } | ||
777 | |||
778 | /* | ||
779 | * Kill'em all! | ||
780 | */ | ||
781 | static int dst_start_node(struct dst_node *n, struct dst_ctl *ctl, | ||
782 | void *data, unsigned int size) | ||
783 | { | ||
784 | int err; | ||
785 | |||
786 | if (!n) | ||
787 | return -ENODEV; | ||
788 | |||
789 | if (n->trans_cache) | ||
790 | return 0; | ||
791 | |||
792 | err = n->start(n); | ||
793 | if (err) | ||
794 | return err; | ||
795 | |||
796 | printk(KERN_INFO "STARTED name: '%s', size: %llu.\n", n->name, n->size); | ||
797 | return 0; | ||
798 | } | ||
799 | |||
800 | typedef int (*dst_command_func)(struct dst_node *n, struct dst_ctl *ctl, | ||
801 | void *data, unsigned int size); | ||
802 | |||
803 | /* | ||
804 | * List of userspace commands. | ||
805 | */ | ||
806 | static dst_command_func dst_commands[] = { | ||
807 | [DST_ADD_REMOTE] = &dst_add_remote, | ||
808 | [DST_ADD_EXPORT] = &dst_add_export, | ||
809 | [DST_DEL_NODE] = &dst_del_node, | ||
810 | [DST_CRYPTO] = &dst_crypto_init, | ||
811 | [DST_SECURITY] = &dst_security_init, | ||
812 | [DST_START] = &dst_start_node, | ||
813 | }; | ||
814 | |||
815 | /* | ||
816 | * Configuration parser. | ||
817 | */ | ||
818 | static void cn_dst_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp) | ||
819 | { | ||
820 | struct dst_ctl *ctl; | ||
821 | int err; | ||
822 | struct dst_ctl_ack ack; | ||
823 | struct dst_node *n = NULL, *tmp; | ||
824 | unsigned int hash; | ||
825 | |||
826 | if (!cap_raised(nsp->eff_cap, CAP_SYS_ADMIN)) { | ||
827 | err = -EPERM; | ||
828 | goto out; | ||
829 | } | ||
830 | |||
831 | if (msg->len < sizeof(struct dst_ctl)) { | ||
832 | err = -EBADMSG; | ||
833 | goto out; | ||
834 | } | ||
835 | |||
836 | ctl = (struct dst_ctl *)msg->data; | ||
837 | |||
838 | if (ctl->cmd >= DST_CMD_MAX) { | ||
839 | err = -EINVAL; | ||
840 | goto out; | ||
841 | } | ||
842 | hash = dst_hash(ctl->name, sizeof(ctl->name)); | ||
843 | |||
844 | mutex_lock(&dst_hash_lock); | ||
845 | list_for_each_entry(tmp, &dst_hashtable[hash], node_entry) { | ||
846 | if (!memcmp(tmp->name, ctl->name, sizeof(tmp->name))) { | ||
847 | n = tmp; | ||
848 | dst_node_get(n); | ||
849 | break; | ||
850 | } | ||
851 | } | ||
852 | mutex_unlock(&dst_hash_lock); | ||
853 | |||
854 | err = dst_commands[ctl->cmd](n, ctl, msg->data + sizeof(struct dst_ctl), | ||
855 | msg->len - sizeof(struct dst_ctl)); | ||
856 | |||
857 | dst_node_put(n); | ||
858 | out: | ||
859 | memcpy(&ack.msg, msg, sizeof(struct cn_msg)); | ||
860 | |||
861 | ack.msg.ack = msg->ack + 1; | ||
862 | ack.msg.len = sizeof(struct dst_ctl_ack) - sizeof(struct cn_msg); | ||
863 | |||
864 | ack.error = err; | ||
865 | |||
866 | cn_netlink_send(&ack.msg, 0, GFP_KERNEL); | ||
867 | } | ||
868 | |||
869 | /* | ||
870 | * Global initialization: sysfs, hash table, block device registration, | ||
871 | * connector and various caches. | ||
872 | */ | ||
873 | static int __init dst_sysfs_init(void) | ||
874 | { | ||
875 | return bus_register(&dst_dev_bus_type); | ||
876 | } | ||
877 | |||
878 | static void dst_sysfs_exit(void) | ||
879 | { | ||
880 | bus_unregister(&dst_dev_bus_type); | ||
881 | } | ||
882 | |||
883 | static int __init dst_hashtable_init(void) | ||
884 | { | ||
885 | unsigned int i; | ||
886 | |||
887 | dst_hashtable = kcalloc(dst_hashtable_size, sizeof(struct list_head), | ||
888 | GFP_KERNEL); | ||
889 | if (!dst_hashtable) | ||
890 | return -ENOMEM; | ||
891 | |||
892 | for (i = 0; i < dst_hashtable_size; ++i) | ||
893 | INIT_LIST_HEAD(&dst_hashtable[i]); | ||
894 | |||
895 | return 0; | ||
896 | } | ||
897 | |||
898 | static void dst_hashtable_exit(void) | ||
899 | { | ||
900 | unsigned int i; | ||
901 | struct dst_node *n, *tmp; | ||
902 | |||
903 | for (i = 0; i < dst_hashtable_size; ++i) { | ||
904 | list_for_each_entry_safe(n, tmp, &dst_hashtable[i], node_entry) { | ||
905 | dst_node_remove_unload(n); | ||
906 | } | ||
907 | } | ||
908 | |||
909 | kfree(dst_hashtable); | ||
910 | } | ||
911 | |||
912 | static int __init dst_sys_init(void) | ||
913 | { | ||
914 | int err = -ENOMEM; | ||
915 | |||
916 | err = dst_hashtable_init(); | ||
917 | if (err) | ||
918 | goto err_out_exit; | ||
919 | |||
920 | err = dst_export_init(); | ||
921 | if (err) | ||
922 | goto err_out_hashtable_exit; | ||
923 | |||
924 | err = register_blkdev(dst_major, DST_NAME); | ||
925 | if (err < 0) | ||
926 | goto err_out_export_exit; | ||
927 | if (err) | ||
928 | dst_major = err; | ||
929 | |||
930 | err = dst_sysfs_init(); | ||
931 | if (err) | ||
932 | goto err_out_unregister; | ||
933 | |||
934 | err = cn_add_callback(&cn_dst_id, "DST", cn_dst_callback); | ||
935 | if (err) | ||
936 | goto err_out_sysfs_exit; | ||
937 | |||
938 | printk(KERN_INFO "Distributed storage, '%s' release.\n", dst_name); | ||
939 | |||
940 | return 0; | ||
941 | |||
942 | err_out_sysfs_exit: | ||
943 | dst_sysfs_exit(); | ||
944 | err_out_unregister: | ||
945 | unregister_blkdev(dst_major, DST_NAME); | ||
946 | err_out_export_exit: | ||
947 | dst_export_exit(); | ||
948 | err_out_hashtable_exit: | ||
949 | dst_hashtable_exit(); | ||
950 | err_out_exit: | ||
951 | return err; | ||
952 | } | ||
953 | |||
954 | static void __exit dst_sys_exit(void) | ||
955 | { | ||
956 | cn_del_callback(&cn_dst_id); | ||
957 | unregister_blkdev(dst_major, DST_NAME); | ||
958 | dst_hashtable_exit(); | ||
959 | dst_sysfs_exit(); | ||
960 | dst_export_exit(); | ||
961 | } | ||
962 | |||
963 | module_init(dst_sys_init); | ||
964 | module_exit(dst_sys_exit); | ||
965 | |||
966 | MODULE_DESCRIPTION("Distributed storage"); | ||
967 | MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>"); | ||
968 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/staging/dst/export.c b/drivers/staging/dst/export.c deleted file mode 100644 index c324230e8b60..000000000000 --- a/drivers/staging/dst/export.c +++ /dev/null | |||
@@ -1,660 +0,0 @@ | |||
1 | /* | ||
2 | * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net> | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | */ | ||
15 | |||
16 | #include <linux/blkdev.h> | ||
17 | #include <linux/bio.h> | ||
18 | #include <linux/dst.h> | ||
19 | #include <linux/in.h> | ||
20 | #include <linux/in6.h> | ||
21 | #include <linux/poll.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/socket.h> | ||
24 | |||
25 | #include <net/sock.h> | ||
26 | |||
27 | /* | ||
28 | * Export bioset is used for server block IO requests. | ||
29 | */ | ||
30 | static struct bio_set *dst_bio_set; | ||
31 | |||
32 | int __init dst_export_init(void) | ||
33 | { | ||
34 | int err = -ENOMEM; | ||
35 | |||
36 | dst_bio_set = bioset_create(32, sizeof(struct dst_export_priv)); | ||
37 | if (!dst_bio_set) | ||
38 | goto err_out_exit; | ||
39 | |||
40 | return 0; | ||
41 | |||
42 | err_out_exit: | ||
43 | return err; | ||
44 | } | ||
45 | |||
46 | void dst_export_exit(void) | ||
47 | { | ||
48 | bioset_free(dst_bio_set); | ||
49 | } | ||
50 | |||
51 | /* | ||
52 | * When client connects and autonegotiates with the server node, | ||
53 | * its permissions are checked in a security attributes and sent | ||
54 | * back. | ||
55 | */ | ||
56 | static unsigned int dst_check_permissions(struct dst_state *main, | ||
57 | struct dst_state *st) | ||
58 | { | ||
59 | struct dst_node *n = main->node; | ||
60 | struct dst_secure *sentry; | ||
61 | struct dst_secure_user *s; | ||
62 | struct saddr *sa = &st->ctl.addr; | ||
63 | unsigned int perm = 0; | ||
64 | |||
65 | mutex_lock(&n->security_lock); | ||
66 | list_for_each_entry(sentry, &n->security_list, sec_entry) { | ||
67 | s = &sentry->sec; | ||
68 | |||
69 | if (s->addr.sa_family != sa->sa_family) | ||
70 | continue; | ||
71 | |||
72 | if (s->addr.sa_data_len != sa->sa_data_len) | ||
73 | continue; | ||
74 | |||
75 | /* | ||
76 | * This '2' below is a port field. This may be very wrong to do | ||
77 | * in atalk for example though. If there will be any need | ||
78 | * to extent protocol to something else, I can create | ||
79 | * per-family helpers and use them instead of this memcmp. | ||
80 | */ | ||
81 | if (memcmp(s->addr.sa_data + 2, sa->sa_data + 2, | ||
82 | sa->sa_data_len - 2)) | ||
83 | continue; | ||
84 | |||
85 | perm = s->permissions; | ||
86 | } | ||
87 | mutex_unlock(&n->security_lock); | ||
88 | |||
89 | return perm; | ||
90 | } | ||
91 | |||
92 | /* | ||
93 | * Accept new client: allocate appropriate network state and check permissions. | ||
94 | */ | ||
95 | static struct dst_state *dst_accept_client(struct dst_state *st) | ||
96 | { | ||
97 | unsigned int revents = 0; | ||
98 | unsigned int err_mask = POLLERR | POLLHUP | POLLRDHUP; | ||
99 | unsigned int mask = err_mask | POLLIN; | ||
100 | struct dst_node *n = st->node; | ||
101 | int err = 0; | ||
102 | struct socket *sock = NULL; | ||
103 | struct dst_state *new; | ||
104 | |||
105 | while (!err && !sock) { | ||
106 | revents = dst_state_poll(st); | ||
107 | |||
108 | if (!(revents & mask)) { | ||
109 | DEFINE_WAIT(wait); | ||
110 | |||
111 | for (;;) { | ||
112 | prepare_to_wait(&st->thread_wait, | ||
113 | &wait, TASK_INTERRUPTIBLE); | ||
114 | if (!n->trans_scan_timeout || st->need_exit) | ||
115 | break; | ||
116 | |||
117 | revents = dst_state_poll(st); | ||
118 | |||
119 | if (revents & mask) | ||
120 | break; | ||
121 | |||
122 | if (signal_pending(current)) | ||
123 | break; | ||
124 | |||
125 | /* | ||
126 | * Magic HZ? Polling check above is not safe in | ||
127 | * all cases (like socket reset in BH context), | ||
128 | * so it is simpler just to postpone it to the | ||
129 | * process context instead of implementing | ||
130 | * special locking there. | ||
131 | */ | ||
132 | schedule_timeout(HZ); | ||
133 | } | ||
134 | finish_wait(&st->thread_wait, &wait); | ||
135 | } | ||
136 | |||
137 | err = -ECONNRESET; | ||
138 | dst_state_lock(st); | ||
139 | |||
140 | dprintk("%s: st: %p, revents: %x [err: %d, in: %d].\n", | ||
141 | __func__, st, revents, revents & err_mask, | ||
142 | revents & POLLIN); | ||
143 | |||
144 | if (revents & err_mask) { | ||
145 | dprintk("%s: revents: %x, socket: %p, err: %d.\n", | ||
146 | __func__, revents, st->socket, err); | ||
147 | err = -ECONNRESET; | ||
148 | } | ||
149 | |||
150 | if (!n->trans_scan_timeout || st->need_exit) | ||
151 | err = -ENODEV; | ||
152 | |||
153 | if (st->socket && (revents & POLLIN)) | ||
154 | err = kernel_accept(st->socket, &sock, 0); | ||
155 | |||
156 | dst_state_unlock(st); | ||
157 | } | ||
158 | |||
159 | if (err) | ||
160 | goto err_out_exit; | ||
161 | |||
162 | new = dst_state_alloc(st->node); | ||
163 | if (IS_ERR(new)) { | ||
164 | err = -ENOMEM; | ||
165 | goto err_out_release; | ||
166 | } | ||
167 | new->socket = sock; | ||
168 | |||
169 | new->ctl.addr.sa_data_len = sizeof(struct sockaddr); | ||
170 | err = kernel_getpeername(sock, (struct sockaddr *)&new->ctl.addr, | ||
171 | (int *)&new->ctl.addr.sa_data_len); | ||
172 | if (err) | ||
173 | goto err_out_put; | ||
174 | |||
175 | new->permissions = dst_check_permissions(st, new); | ||
176 | if (new->permissions == 0) { | ||
177 | err = -EPERM; | ||
178 | dst_dump_addr(sock, (struct sockaddr *)&new->ctl.addr, | ||
179 | "Client is not allowed to connect"); | ||
180 | goto err_out_put; | ||
181 | } | ||
182 | |||
183 | err = dst_poll_init(new); | ||
184 | if (err) | ||
185 | goto err_out_put; | ||
186 | |||
187 | dst_dump_addr(sock, (struct sockaddr *)&new->ctl.addr, | ||
188 | "Connected client"); | ||
189 | |||
190 | return new; | ||
191 | |||
192 | err_out_put: | ||
193 | dst_state_put(new); | ||
194 | err_out_release: | ||
195 | sock_release(sock); | ||
196 | err_out_exit: | ||
197 | return ERR_PTR(err); | ||
198 | } | ||
199 | |||
200 | /* | ||
201 | * Each server's block request sometime finishes. | ||
202 | * Usually it happens in hard irq context of the appropriate controller, | ||
203 | * so to play good with all cases we just queue BIO into the queue | ||
204 | * and wake up processing thread, which gets completed request and | ||
205 | * send (encrypting if needed) it back to the client (if it was a read | ||
206 | * request), or sends back reply that writing successfully completed. | ||
207 | */ | ||
208 | static int dst_export_process_request_queue(struct dst_state *st) | ||
209 | { | ||
210 | unsigned long flags; | ||
211 | struct dst_export_priv *p = NULL; | ||
212 | struct bio *bio; | ||
213 | int err = 0; | ||
214 | |||
215 | while (!list_empty(&st->request_list)) { | ||
216 | spin_lock_irqsave(&st->request_lock, flags); | ||
217 | if (!list_empty(&st->request_list)) { | ||
218 | p = list_first_entry(&st->request_list, | ||
219 | struct dst_export_priv, request_entry); | ||
220 | list_del(&p->request_entry); | ||
221 | } | ||
222 | spin_unlock_irqrestore(&st->request_lock, flags); | ||
223 | |||
224 | if (!p) | ||
225 | break; | ||
226 | |||
227 | bio = p->bio; | ||
228 | |||
229 | if (dst_need_crypto(st->node) && (bio_data_dir(bio) == READ)) | ||
230 | err = dst_export_crypto(st->node, bio); | ||
231 | else | ||
232 | err = dst_export_send_bio(bio); | ||
233 | |||
234 | if (err) | ||
235 | break; | ||
236 | } | ||
237 | |||
238 | return err; | ||
239 | } | ||
240 | |||
241 | /* | ||
242 | * Cleanup export state. | ||
243 | * It has to wait until all requests are finished, | ||
244 | * and then free them all. | ||
245 | */ | ||
246 | static void dst_state_cleanup_export(struct dst_state *st) | ||
247 | { | ||
248 | struct dst_export_priv *p; | ||
249 | unsigned long flags; | ||
250 | |||
251 | /* | ||
252 | * This loop waits for all pending bios to be completed and freed. | ||
253 | */ | ||
254 | while (atomic_read(&st->refcnt) > 1) { | ||
255 | dprintk("%s: st: %p, refcnt: %d, list_empty: %d.\n", | ||
256 | __func__, st, atomic_read(&st->refcnt), | ||
257 | list_empty(&st->request_list)); | ||
258 | wait_event_timeout(st->thread_wait, | ||
259 | (atomic_read(&st->refcnt) == 1) || | ||
260 | !list_empty(&st->request_list), | ||
261 | HZ/2); | ||
262 | |||
263 | while (!list_empty(&st->request_list)) { | ||
264 | p = NULL; | ||
265 | spin_lock_irqsave(&st->request_lock, flags); | ||
266 | if (!list_empty(&st->request_list)) { | ||
267 | p = list_first_entry(&st->request_list, | ||
268 | struct dst_export_priv, request_entry); | ||
269 | list_del(&p->request_entry); | ||
270 | } | ||
271 | spin_unlock_irqrestore(&st->request_lock, flags); | ||
272 | |||
273 | if (p) | ||
274 | bio_put(p->bio); | ||
275 | |||
276 | dprintk("%s: st: %p, refcnt: %d, list_empty: %d, p: " | ||
277 | "%p.\n", __func__, st, atomic_read(&st->refcnt), | ||
278 | list_empty(&st->request_list), p); | ||
279 | } | ||
280 | } | ||
281 | |||
282 | dst_state_put(st); | ||
283 | } | ||
284 | |||
285 | /* | ||
286 | * Client accepting thread. | ||
287 | * Not only accepts new connection, but also schedules receiving thread | ||
288 | * and performs request completion described above. | ||
289 | */ | ||
290 | static int dst_accept(void *init_data, void *schedule_data) | ||
291 | { | ||
292 | struct dst_state *main_st = schedule_data; | ||
293 | struct dst_node *n = init_data; | ||
294 | struct dst_state *st; | ||
295 | int err; | ||
296 | |||
297 | while (n->trans_scan_timeout && !main_st->need_exit) { | ||
298 | dprintk("%s: main_st: %p, n: %p.\n", __func__, main_st, n); | ||
299 | st = dst_accept_client(main_st); | ||
300 | if (IS_ERR(st)) | ||
301 | continue; | ||
302 | |||
303 | err = dst_state_schedule_receiver(st); | ||
304 | if (!err) { | ||
305 | while (n->trans_scan_timeout) { | ||
306 | err = wait_event_interruptible_timeout(st->thread_wait, | ||
307 | !list_empty(&st->request_list) || | ||
308 | !n->trans_scan_timeout || | ||
309 | st->need_exit, | ||
310 | HZ); | ||
311 | |||
312 | if (!n->trans_scan_timeout || st->need_exit) | ||
313 | break; | ||
314 | |||
315 | if (list_empty(&st->request_list)) | ||
316 | continue; | ||
317 | |||
318 | err = dst_export_process_request_queue(st); | ||
319 | if (err) | ||
320 | break; | ||
321 | } | ||
322 | |||
323 | st->need_exit = 1; | ||
324 | wake_up(&st->thread_wait); | ||
325 | } | ||
326 | |||
327 | dst_state_cleanup_export(st); | ||
328 | } | ||
329 | |||
330 | dprintk("%s: freeing listening socket st: %p.\n", __func__, main_st); | ||
331 | |||
332 | dst_state_lock(main_st); | ||
333 | dst_poll_exit(main_st); | ||
334 | dst_state_socket_release(main_st); | ||
335 | dst_state_unlock(main_st); | ||
336 | dst_state_put(main_st); | ||
337 | dprintk("%s: freed listening socket st: %p.\n", __func__, main_st); | ||
338 | |||
339 | return 0; | ||
340 | } | ||
341 | |||
342 | int dst_start_export(struct dst_node *n) | ||
343 | { | ||
344 | if (list_empty(&n->security_list)) { | ||
345 | printk(KERN_ERR "You are trying to export node '%s' " | ||
346 | "without security attributes.\nNo clients will " | ||
347 | "be allowed to connect. Exiting.\n", n->name); | ||
348 | return -EINVAL; | ||
349 | } | ||
350 | return dst_node_trans_init(n, sizeof(struct dst_export_priv)); | ||
351 | } | ||
352 | |||
353 | /* | ||
354 | * Initialize listening state and schedule accepting thread. | ||
355 | */ | ||
356 | int dst_node_init_listened(struct dst_node *n, struct dst_export_ctl *le) | ||
357 | { | ||
358 | struct dst_state *st; | ||
359 | int err = -ENOMEM; | ||
360 | struct dst_network_ctl *ctl = &le->ctl; | ||
361 | |||
362 | memcpy(&n->info->net, ctl, sizeof(struct dst_network_ctl)); | ||
363 | |||
364 | st = dst_state_alloc(n); | ||
365 | if (IS_ERR(st)) { | ||
366 | err = PTR_ERR(st); | ||
367 | goto err_out_exit; | ||
368 | } | ||
369 | memcpy(&st->ctl, ctl, sizeof(struct dst_network_ctl)); | ||
370 | |||
371 | err = dst_state_socket_create(st); | ||
372 | if (err) | ||
373 | goto err_out_put; | ||
374 | |||
375 | st->socket->sk->sk_reuse = 1; | ||
376 | |||
377 | err = kernel_bind(st->socket, (struct sockaddr *)&ctl->addr, | ||
378 | ctl->addr.sa_data_len); | ||
379 | if (err) | ||
380 | goto err_out_socket_release; | ||
381 | |||
382 | err = kernel_listen(st->socket, 1024); | ||
383 | if (err) | ||
384 | goto err_out_socket_release; | ||
385 | n->state = st; | ||
386 | |||
387 | err = dst_poll_init(st); | ||
388 | if (err) | ||
389 | goto err_out_socket_release; | ||
390 | |||
391 | dst_state_get(st); | ||
392 | |||
393 | err = thread_pool_schedule(n->pool, dst_thread_setup, | ||
394 | dst_accept, st, MAX_SCHEDULE_TIMEOUT); | ||
395 | if (err) | ||
396 | goto err_out_poll_exit; | ||
397 | |||
398 | return 0; | ||
399 | |||
400 | err_out_poll_exit: | ||
401 | dst_poll_exit(st); | ||
402 | err_out_socket_release: | ||
403 | dst_state_socket_release(st); | ||
404 | err_out_put: | ||
405 | dst_state_put(st); | ||
406 | err_out_exit: | ||
407 | n->state = NULL; | ||
408 | return err; | ||
409 | } | ||
410 | |||
411 | /* | ||
412 | * Free bio and related private data. | ||
413 | * Also drop a reference counter for appropriate state, | ||
414 | * which waits when there are no more block IOs in-flight. | ||
415 | */ | ||
416 | static void dst_bio_destructor(struct bio *bio) | ||
417 | { | ||
418 | struct bio_vec *bv; | ||
419 | struct dst_export_priv *priv = bio->bi_private; | ||
420 | int i; | ||
421 | |||
422 | bio_for_each_segment(bv, bio, i) { | ||
423 | if (!bv->bv_page) | ||
424 | break; | ||
425 | |||
426 | __free_page(bv->bv_page); | ||
427 | } | ||
428 | |||
429 | if (priv) | ||
430 | dst_state_put(priv->state); | ||
431 | bio_free(bio, dst_bio_set); | ||
432 | } | ||
433 | |||
434 | /* | ||
435 | * Block IO completion. Queue request to be sent back to | ||
436 | * the client (or just confirmation). | ||
437 | */ | ||
438 | static void dst_bio_end_io(struct bio *bio, int err) | ||
439 | { | ||
440 | struct dst_export_priv *p = bio->bi_private; | ||
441 | struct dst_state *st = p->state; | ||
442 | unsigned long flags; | ||
443 | |||
444 | spin_lock_irqsave(&st->request_lock, flags); | ||
445 | list_add_tail(&p->request_entry, &st->request_list); | ||
446 | spin_unlock_irqrestore(&st->request_lock, flags); | ||
447 | |||
448 | wake_up(&st->thread_wait); | ||
449 | } | ||
450 | |||
451 | /* | ||
452 | * Allocate read request for the server. | ||
453 | */ | ||
454 | static int dst_export_read_request(struct bio *bio, unsigned int total_size) | ||
455 | { | ||
456 | unsigned int size; | ||
457 | struct page *page; | ||
458 | int err; | ||
459 | |||
460 | while (total_size) { | ||
461 | err = -ENOMEM; | ||
462 | page = alloc_page(GFP_KERNEL); | ||
463 | if (!page) | ||
464 | goto err_out_exit; | ||
465 | |||
466 | size = min_t(unsigned int, PAGE_SIZE, total_size); | ||
467 | |||
468 | err = bio_add_page(bio, page, size, 0); | ||
469 | dprintk("%s: bio: %llu/%u, size: %u, err: %d.\n", | ||
470 | __func__, (u64)bio->bi_sector, bio->bi_size, | ||
471 | size, err); | ||
472 | if (err <= 0) | ||
473 | goto err_out_free_page; | ||
474 | |||
475 | total_size -= size; | ||
476 | } | ||
477 | |||
478 | return 0; | ||
479 | |||
480 | err_out_free_page: | ||
481 | __free_page(page); | ||
482 | err_out_exit: | ||
483 | return err; | ||
484 | } | ||
485 | |||
486 | /* | ||
487 | * Allocate write request for the server. | ||
488 | * Should not only get pages, but also read data from the network. | ||
489 | */ | ||
490 | static int dst_export_write_request(struct dst_state *st, | ||
491 | struct bio *bio, unsigned int total_size) | ||
492 | { | ||
493 | unsigned int size; | ||
494 | struct page *page; | ||
495 | void *data; | ||
496 | int err; | ||
497 | |||
498 | while (total_size) { | ||
499 | err = -ENOMEM; | ||
500 | page = alloc_page(GFP_KERNEL); | ||
501 | if (!page) | ||
502 | goto err_out_exit; | ||
503 | |||
504 | data = kmap(page); | ||
505 | if (!data) | ||
506 | goto err_out_free_page; | ||
507 | |||
508 | size = min_t(unsigned int, PAGE_SIZE, total_size); | ||
509 | |||
510 | err = dst_data_recv(st, data, size); | ||
511 | if (err) | ||
512 | goto err_out_unmap_page; | ||
513 | |||
514 | err = bio_add_page(bio, page, size, 0); | ||
515 | if (err <= 0) | ||
516 | goto err_out_unmap_page; | ||
517 | |||
518 | kunmap(page); | ||
519 | |||
520 | total_size -= size; | ||
521 | } | ||
522 | |||
523 | return 0; | ||
524 | |||
525 | err_out_unmap_page: | ||
526 | kunmap(page); | ||
527 | err_out_free_page: | ||
528 | __free_page(page); | ||
529 | err_out_exit: | ||
530 | return err; | ||
531 | } | ||
532 | |||
533 | /* | ||
534 | * Groovy, we've gotten an IO request from the client. | ||
535 | * Allocate BIO from the bioset, private data from the mempool | ||
536 | * and lots of pages for IO. | ||
537 | */ | ||
538 | int dst_process_io(struct dst_state *st) | ||
539 | { | ||
540 | struct dst_node *n = st->node; | ||
541 | struct dst_cmd *cmd = st->data; | ||
542 | struct bio *bio; | ||
543 | struct dst_export_priv *priv; | ||
544 | int err = -ENOMEM; | ||
545 | |||
546 | if (unlikely(!n->bdev)) { | ||
547 | err = -EINVAL; | ||
548 | goto err_out_exit; | ||
549 | } | ||
550 | |||
551 | bio = bio_alloc_bioset(GFP_KERNEL, | ||
552 | PAGE_ALIGN(cmd->size) >> PAGE_SHIFT, | ||
553 | dst_bio_set); | ||
554 | if (!bio) | ||
555 | goto err_out_exit; | ||
556 | |||
557 | priv = (struct dst_export_priv *)(((void *)bio) - | ||
558 | sizeof (struct dst_export_priv)); | ||
559 | |||
560 | priv->state = dst_state_get(st); | ||
561 | priv->bio = bio; | ||
562 | |||
563 | bio->bi_private = priv; | ||
564 | bio->bi_end_io = dst_bio_end_io; | ||
565 | bio->bi_destructor = dst_bio_destructor; | ||
566 | bio->bi_bdev = n->bdev; | ||
567 | |||
568 | /* | ||
569 | * Server side is only interested in two low bits: | ||
570 | * uptodate (set by itself actually) and rw block | ||
571 | */ | ||
572 | bio->bi_flags |= cmd->flags & 3; | ||
573 | |||
574 | bio->bi_rw = cmd->rw; | ||
575 | bio->bi_size = 0; | ||
576 | bio->bi_sector = cmd->sector; | ||
577 | |||
578 | dst_bio_to_cmd(bio, &priv->cmd, DST_IO_RESPONSE, cmd->id); | ||
579 | |||
580 | priv->cmd.flags = 0; | ||
581 | priv->cmd.size = cmd->size; | ||
582 | |||
583 | if (bio_data_dir(bio) == WRITE) { | ||
584 | err = dst_recv_cdata(st, priv->cmd.hash); | ||
585 | if (err) | ||
586 | goto err_out_free; | ||
587 | |||
588 | err = dst_export_write_request(st, bio, cmd->size); | ||
589 | if (err) | ||
590 | goto err_out_free; | ||
591 | |||
592 | if (dst_need_crypto(n)) | ||
593 | return dst_export_crypto(n, bio); | ||
594 | } else { | ||
595 | err = dst_export_read_request(bio, cmd->size); | ||
596 | if (err) | ||
597 | goto err_out_free; | ||
598 | } | ||
599 | |||
600 | dprintk("%s: bio: %llu/%u, rw: %lu, dir: %lu, flags: %lx, phys: %d.\n", | ||
601 | __func__, (u64)bio->bi_sector, bio->bi_size, | ||
602 | bio->bi_rw, bio_data_dir(bio), | ||
603 | bio->bi_flags, bio->bi_phys_segments); | ||
604 | |||
605 | generic_make_request(bio); | ||
606 | |||
607 | return 0; | ||
608 | |||
609 | err_out_free: | ||
610 | bio_put(bio); | ||
611 | err_out_exit: | ||
612 | return err; | ||
613 | } | ||
614 | |||
615 | /* | ||
616 | * Ok, block IO is ready, let's send it back to the client... | ||
617 | */ | ||
618 | int dst_export_send_bio(struct bio *bio) | ||
619 | { | ||
620 | struct dst_export_priv *p = bio->bi_private; | ||
621 | struct dst_state *st = p->state; | ||
622 | struct dst_cmd *cmd = &p->cmd; | ||
623 | int err; | ||
624 | |||
625 | dprintk("%s: id: %llu, bio: %llu/%u, csize: %u, flags: %lu, rw: %lu.\n", | ||
626 | __func__, cmd->id, (u64)bio->bi_sector, bio->bi_size, | ||
627 | cmd->csize, bio->bi_flags, bio->bi_rw); | ||
628 | |||
629 | dst_convert_cmd(cmd); | ||
630 | |||
631 | dst_state_lock(st); | ||
632 | if (!st->socket) { | ||
633 | err = -ECONNRESET; | ||
634 | goto err_out_unlock; | ||
635 | } | ||
636 | |||
637 | if (bio_data_dir(bio) == WRITE) { | ||
638 | /* ... or just confirmation that writing has completed. */ | ||
639 | cmd->size = cmd->csize = 0; | ||
640 | err = dst_data_send_header(st->socket, cmd, | ||
641 | sizeof(struct dst_cmd), 0); | ||
642 | if (err) | ||
643 | goto err_out_unlock; | ||
644 | } else { | ||
645 | err = dst_send_bio(st, cmd, bio); | ||
646 | if (err) | ||
647 | goto err_out_unlock; | ||
648 | } | ||
649 | |||
650 | dst_state_unlock(st); | ||
651 | |||
652 | bio_put(bio); | ||
653 | return 0; | ||
654 | |||
655 | err_out_unlock: | ||
656 | dst_state_unlock(st); | ||
657 | |||
658 | bio_put(bio); | ||
659 | return err; | ||
660 | } | ||
diff --git a/drivers/staging/dst/state.c b/drivers/staging/dst/state.c deleted file mode 100644 index 02a05e6c48c3..000000000000 --- a/drivers/staging/dst/state.c +++ /dev/null | |||
@@ -1,844 +0,0 @@ | |||
1 | /* | ||
2 | * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net> | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | */ | ||
15 | |||
16 | #include <linux/buffer_head.h> | ||
17 | #include <linux/blkdev.h> | ||
18 | #include <linux/bio.h> | ||
19 | #include <linux/connector.h> | ||
20 | #include <linux/dst.h> | ||
21 | #include <linux/device.h> | ||
22 | #include <linux/in.h> | ||
23 | #include <linux/in6.h> | ||
24 | #include <linux/socket.h> | ||
25 | #include <linux/slab.h> | ||
26 | |||
27 | #include <net/sock.h> | ||
28 | |||
29 | /* | ||
30 | * Polling machinery. | ||
31 | */ | ||
32 | |||
33 | struct dst_poll_helper { | ||
34 | poll_table pt; | ||
35 | struct dst_state *st; | ||
36 | }; | ||
37 | |||
38 | static int dst_queue_wake(wait_queue_t *wait, unsigned mode, | ||
39 | int sync, void *key) | ||
40 | { | ||
41 | struct dst_state *st = container_of(wait, struct dst_state, wait); | ||
42 | |||
43 | wake_up(&st->thread_wait); | ||
44 | return 1; | ||
45 | } | ||
46 | |||
47 | static void dst_queue_func(struct file *file, wait_queue_head_t *whead, | ||
48 | poll_table *pt) | ||
49 | { | ||
50 | struct dst_state *st = container_of(pt, struct dst_poll_helper, pt)->st; | ||
51 | |||
52 | st->whead = whead; | ||
53 | init_waitqueue_func_entry(&st->wait, dst_queue_wake); | ||
54 | add_wait_queue(whead, &st->wait); | ||
55 | } | ||
56 | |||
57 | void dst_poll_exit(struct dst_state *st) | ||
58 | { | ||
59 | if (st->whead) { | ||
60 | remove_wait_queue(st->whead, &st->wait); | ||
61 | st->whead = NULL; | ||
62 | } | ||
63 | } | ||
64 | |||
65 | int dst_poll_init(struct dst_state *st) | ||
66 | { | ||
67 | struct dst_poll_helper ph; | ||
68 | |||
69 | ph.st = st; | ||
70 | init_poll_funcptr(&ph.pt, &dst_queue_func); | ||
71 | |||
72 | st->socket->ops->poll(NULL, st->socket, &ph.pt); | ||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | /* | ||
77 | * Header receiving function - may block. | ||
78 | */ | ||
79 | static int dst_data_recv_header(struct socket *sock, | ||
80 | void *data, unsigned int size, int block) | ||
81 | { | ||
82 | struct msghdr msg; | ||
83 | struct kvec iov; | ||
84 | int err; | ||
85 | |||
86 | iov.iov_base = data; | ||
87 | iov.iov_len = size; | ||
88 | |||
89 | msg.msg_iov = (struct iovec *)&iov; | ||
90 | msg.msg_iovlen = 1; | ||
91 | msg.msg_name = NULL; | ||
92 | msg.msg_namelen = 0; | ||
93 | msg.msg_control = NULL; | ||
94 | msg.msg_controllen = 0; | ||
95 | msg.msg_flags = (block) ? MSG_WAITALL : MSG_DONTWAIT; | ||
96 | |||
97 | err = kernel_recvmsg(sock, &msg, &iov, 1, iov.iov_len, | ||
98 | msg.msg_flags); | ||
99 | if (err != size) | ||
100 | return -1; | ||
101 | |||
102 | return 0; | ||
103 | } | ||
104 | |||
105 | /* | ||
106 | * Header sending function - may block. | ||
107 | */ | ||
108 | int dst_data_send_header(struct socket *sock, | ||
109 | void *data, unsigned int size, int more) | ||
110 | { | ||
111 | struct msghdr msg; | ||
112 | struct kvec iov; | ||
113 | int err; | ||
114 | |||
115 | iov.iov_base = data; | ||
116 | iov.iov_len = size; | ||
117 | |||
118 | msg.msg_iov = (struct iovec *)&iov; | ||
119 | msg.msg_iovlen = 1; | ||
120 | msg.msg_name = NULL; | ||
121 | msg.msg_namelen = 0; | ||
122 | msg.msg_control = NULL; | ||
123 | msg.msg_controllen = 0; | ||
124 | msg.msg_flags = MSG_WAITALL | (more ? MSG_MORE : 0); | ||
125 | |||
126 | err = kernel_sendmsg(sock, &msg, &iov, 1, iov.iov_len); | ||
127 | if (err != size) { | ||
128 | dprintk("%s: size: %u, more: %d, err: %d.\n", | ||
129 | __func__, size, more, err); | ||
130 | return -1; | ||
131 | } | ||
132 | |||
133 | return 0; | ||
134 | } | ||
135 | |||
136 | /* | ||
137 | * Block autoconfiguration: request size of the storage and permissions. | ||
138 | */ | ||
139 | static int dst_request_remote_config(struct dst_state *st) | ||
140 | { | ||
141 | struct dst_node *n = st->node; | ||
142 | int err = -EINVAL; | ||
143 | struct dst_cmd *cmd = st->data; | ||
144 | |||
145 | memset(cmd, 0, sizeof(struct dst_cmd)); | ||
146 | cmd->cmd = DST_CFG; | ||
147 | |||
148 | dst_convert_cmd(cmd); | ||
149 | |||
150 | err = dst_data_send_header(st->socket, cmd, sizeof(struct dst_cmd), 0); | ||
151 | if (err) | ||
152 | goto out; | ||
153 | |||
154 | err = dst_data_recv_header(st->socket, cmd, sizeof(struct dst_cmd), 1); | ||
155 | if (err) | ||
156 | goto out; | ||
157 | |||
158 | dst_convert_cmd(cmd); | ||
159 | |||
160 | if (cmd->cmd != DST_CFG) { | ||
161 | err = -EINVAL; | ||
162 | dprintk("%s: checking result: cmd: %d, size reported: %llu.\n", | ||
163 | __func__, cmd->cmd, cmd->sector); | ||
164 | goto out; | ||
165 | } | ||
166 | |||
167 | if (n->size != 0) | ||
168 | n->size = min_t(loff_t, n->size, cmd->sector); | ||
169 | else | ||
170 | n->size = cmd->sector; | ||
171 | |||
172 | n->info->size = n->size; | ||
173 | st->permissions = cmd->rw; | ||
174 | |||
175 | out: | ||
176 | dprintk("%s: n: %p, err: %d, size: %llu, permission: %x.\n", | ||
177 | __func__, n, err, n->size, st->permissions); | ||
178 | return err; | ||
179 | } | ||
180 | |||
181 | /* | ||
182 | * Socket machinery. | ||
183 | */ | ||
184 | |||
185 | #define DST_DEFAULT_TIMEO 20000 | ||
186 | |||
187 | int dst_state_socket_create(struct dst_state *st) | ||
188 | { | ||
189 | int err; | ||
190 | struct socket *sock; | ||
191 | struct dst_network_ctl *ctl = &st->ctl; | ||
192 | |||
193 | err = sock_create(ctl->addr.sa_family, ctl->type, ctl->proto, &sock); | ||
194 | if (err < 0) | ||
195 | return err; | ||
196 | |||
197 | sock->sk->sk_sndtimeo = sock->sk->sk_rcvtimeo = | ||
198 | msecs_to_jiffies(DST_DEFAULT_TIMEO); | ||
199 | sock->sk->sk_allocation = GFP_NOIO; | ||
200 | |||
201 | st->socket = st->read_socket = sock; | ||
202 | return 0; | ||
203 | } | ||
204 | |||
205 | void dst_state_socket_release(struct dst_state *st) | ||
206 | { | ||
207 | dprintk("%s: st: %p, socket: %p, n: %p.\n", | ||
208 | __func__, st, st->socket, st->node); | ||
209 | if (st->socket) { | ||
210 | sock_release(st->socket); | ||
211 | st->socket = NULL; | ||
212 | st->read_socket = NULL; | ||
213 | } | ||
214 | } | ||
215 | |||
216 | void dst_dump_addr(struct socket *sk, struct sockaddr *sa, char *str) | ||
217 | { | ||
218 | if (sk->ops->family == AF_INET) { | ||
219 | struct sockaddr_in *sin = (struct sockaddr_in *)sa; | ||
220 | printk(KERN_INFO "%s %u.%u.%u.%u:%d.\n", str, | ||
221 | NIPQUAD(sin->sin_addr.s_addr), ntohs(sin->sin_port)); | ||
222 | } else if (sk->ops->family == AF_INET6) { | ||
223 | struct sockaddr_in6 *sin = (struct sockaddr_in6 *)sa; | ||
224 | printk(KERN_INFO "%s %pi6:%d", | ||
225 | str, &sin->sin6_addr, ntohs(sin->sin6_port)); | ||
226 | } | ||
227 | } | ||
228 | |||
229 | void dst_state_exit_connected(struct dst_state *st) | ||
230 | { | ||
231 | if (st->socket) { | ||
232 | dst_poll_exit(st); | ||
233 | st->socket->ops->shutdown(st->socket, 2); | ||
234 | |||
235 | dst_dump_addr(st->socket, (struct sockaddr *)&st->ctl.addr, | ||
236 | "Disconnected peer"); | ||
237 | dst_state_socket_release(st); | ||
238 | } | ||
239 | } | ||
240 | |||
241 | static int dst_state_init_connected(struct dst_state *st) | ||
242 | { | ||
243 | int err; | ||
244 | struct dst_network_ctl *ctl = &st->ctl; | ||
245 | |||
246 | err = dst_state_socket_create(st); | ||
247 | if (err) | ||
248 | goto err_out_exit; | ||
249 | |||
250 | err = kernel_connect(st->socket, (struct sockaddr *)&st->ctl.addr, | ||
251 | st->ctl.addr.sa_data_len, 0); | ||
252 | if (err) | ||
253 | goto err_out_release; | ||
254 | |||
255 | err = dst_poll_init(st); | ||
256 | if (err) | ||
257 | goto err_out_release; | ||
258 | |||
259 | dst_dump_addr(st->socket, (struct sockaddr *)&ctl->addr, | ||
260 | "Connected to peer"); | ||
261 | |||
262 | return 0; | ||
263 | |||
264 | err_out_release: | ||
265 | dst_state_socket_release(st); | ||
266 | err_out_exit: | ||
267 | return err; | ||
268 | } | ||
269 | |||
270 | /* | ||
271 | * State reset is used to reconnect to the remote peer. | ||
272 | * May fail, but who cares, we will try again later. | ||
273 | */ | ||
274 | static inline void dst_state_reset_nolock(struct dst_state *st) | ||
275 | { | ||
276 | dst_state_exit_connected(st); | ||
277 | dst_state_init_connected(st); | ||
278 | } | ||
279 | |||
280 | static inline void dst_state_reset(struct dst_state *st) | ||
281 | { | ||
282 | dst_state_lock(st); | ||
283 | dst_state_reset_nolock(st); | ||
284 | dst_state_unlock(st); | ||
285 | } | ||
286 | |||
287 | /* | ||
288 | * Basic network sending/receiving functions. | ||
289 | * Blocked mode is used. | ||
290 | */ | ||
291 | static int dst_data_recv_raw(struct dst_state *st, void *buf, u64 size) | ||
292 | { | ||
293 | struct msghdr msg; | ||
294 | struct kvec iov; | ||
295 | int err; | ||
296 | |||
297 | BUG_ON(!size); | ||
298 | |||
299 | iov.iov_base = buf; | ||
300 | iov.iov_len = size; | ||
301 | |||
302 | msg.msg_iov = (struct iovec *)&iov; | ||
303 | msg.msg_iovlen = 1; | ||
304 | msg.msg_name = NULL; | ||
305 | msg.msg_namelen = 0; | ||
306 | msg.msg_control = NULL; | ||
307 | msg.msg_controllen = 0; | ||
308 | msg.msg_flags = MSG_DONTWAIT; | ||
309 | |||
310 | err = kernel_recvmsg(st->socket, &msg, &iov, 1, iov.iov_len, | ||
311 | msg.msg_flags); | ||
312 | if (err <= 0) { | ||
313 | dprintk("%s: failed to recv data: size: %llu, err: %d.\n", | ||
314 | __func__, size, err); | ||
315 | if (err == 0) | ||
316 | err = -ECONNRESET; | ||
317 | |||
318 | dst_state_exit_connected(st); | ||
319 | } | ||
320 | |||
321 | return err; | ||
322 | } | ||
323 | |||
324 | /* | ||
325 | * Ping command to early detect failed nodes. | ||
326 | */ | ||
327 | static int dst_send_ping(struct dst_state *st) | ||
328 | { | ||
329 | struct dst_cmd *cmd = st->data; | ||
330 | int err = -ECONNRESET; | ||
331 | |||
332 | dst_state_lock(st); | ||
333 | if (st->socket) { | ||
334 | memset(cmd, 0, sizeof(struct dst_cmd)); | ||
335 | |||
336 | cmd->cmd = __cpu_to_be32(DST_PING); | ||
337 | |||
338 | err = dst_data_send_header(st->socket, cmd, | ||
339 | sizeof(struct dst_cmd), 0); | ||
340 | } | ||
341 | dprintk("%s: st: %p, socket: %p, err: %d.\n", __func__, | ||
342 | st, st->socket, err); | ||
343 | dst_state_unlock(st); | ||
344 | |||
345 | return err; | ||
346 | } | ||
347 | |||
348 | /* | ||
349 | * Receiving function, which should either return error or read | ||
350 | * whole block request. If there was no traffic for a one second, | ||
351 | * send a ping, since remote node may die. | ||
352 | */ | ||
353 | int dst_data_recv(struct dst_state *st, void *data, unsigned int size) | ||
354 | { | ||
355 | unsigned int revents = 0; | ||
356 | unsigned int err_mask = POLLERR | POLLHUP | POLLRDHUP; | ||
357 | unsigned int mask = err_mask | POLLIN; | ||
358 | struct dst_node *n = st->node; | ||
359 | int err = 0; | ||
360 | |||
361 | while (size && !err) { | ||
362 | revents = dst_state_poll(st); | ||
363 | |||
364 | if (!(revents & mask)) { | ||
365 | DEFINE_WAIT(wait); | ||
366 | |||
367 | for (;;) { | ||
368 | prepare_to_wait(&st->thread_wait, &wait, | ||
369 | TASK_INTERRUPTIBLE); | ||
370 | if (!n->trans_scan_timeout || st->need_exit) | ||
371 | break; | ||
372 | |||
373 | revents = dst_state_poll(st); | ||
374 | |||
375 | if (revents & mask) | ||
376 | break; | ||
377 | |||
378 | if (signal_pending(current)) | ||
379 | break; | ||
380 | |||
381 | if (!schedule_timeout(HZ)) { | ||
382 | err = dst_send_ping(st); | ||
383 | if (err) | ||
384 | return err; | ||
385 | } | ||
386 | |||
387 | continue; | ||
388 | } | ||
389 | finish_wait(&st->thread_wait, &wait); | ||
390 | } | ||
391 | |||
392 | err = -ECONNRESET; | ||
393 | dst_state_lock(st); | ||
394 | |||
395 | if (st->socket && (st->read_socket == st->socket) && | ||
396 | (revents & POLLIN)) { | ||
397 | err = dst_data_recv_raw(st, data, size); | ||
398 | if (err > 0) { | ||
399 | data += err; | ||
400 | size -= err; | ||
401 | err = 0; | ||
402 | } | ||
403 | } | ||
404 | |||
405 | if (revents & err_mask || !st->socket) { | ||
406 | dprintk("%s: revents: %x, socket: %p, size: %u, " | ||
407 | "err: %d.\n", __func__, revents, | ||
408 | st->socket, size, err); | ||
409 | err = -ECONNRESET; | ||
410 | } | ||
411 | |||
412 | dst_state_unlock(st); | ||
413 | |||
414 | if (!n->trans_scan_timeout) | ||
415 | err = -ENODEV; | ||
416 | } | ||
417 | |||
418 | return err; | ||
419 | } | ||
420 | |||
421 | /* | ||
422 | * Send block autoconf reply. | ||
423 | */ | ||
424 | static int dst_process_cfg(struct dst_state *st) | ||
425 | { | ||
426 | struct dst_node *n = st->node; | ||
427 | struct dst_cmd *cmd = st->data; | ||
428 | int err; | ||
429 | |||
430 | cmd->sector = n->size; | ||
431 | cmd->rw = st->permissions; | ||
432 | |||
433 | dst_convert_cmd(cmd); | ||
434 | |||
435 | dst_state_lock(st); | ||
436 | err = dst_data_send_header(st->socket, cmd, sizeof(struct dst_cmd), 0); | ||
437 | dst_state_unlock(st); | ||
438 | |||
439 | return err; | ||
440 | } | ||
441 | |||
442 | /* | ||
443 | * Receive block IO from the network. | ||
444 | */ | ||
445 | static int dst_recv_bio(struct dst_state *st, struct bio *bio, | ||
446 | unsigned int total_size) | ||
447 | { | ||
448 | struct bio_vec *bv; | ||
449 | int i, err; | ||
450 | void *data; | ||
451 | unsigned int sz; | ||
452 | |||
453 | bio_for_each_segment(bv, bio, i) { | ||
454 | sz = min(total_size, bv->bv_len); | ||
455 | |||
456 | dprintk("%s: bio: %llu/%u, total: %u, len: %u, sz: %u, " | ||
457 | "off: %u.\n", __func__, (u64)bio->bi_sector, | ||
458 | bio->bi_size, total_size, bv->bv_len, sz, | ||
459 | bv->bv_offset); | ||
460 | |||
461 | data = kmap(bv->bv_page) + bv->bv_offset; | ||
462 | err = dst_data_recv(st, data, sz); | ||
463 | kunmap(bv->bv_page); | ||
464 | |||
465 | bv->bv_len = sz; | ||
466 | |||
467 | if (err) | ||
468 | return err; | ||
469 | |||
470 | total_size -= sz; | ||
471 | if (total_size == 0) | ||
472 | break; | ||
473 | } | ||
474 | |||
475 | return 0; | ||
476 | } | ||
477 | |||
478 | /* | ||
479 | * Our block IO has just completed and arrived: get it. | ||
480 | */ | ||
481 | static int dst_process_io_response(struct dst_state *st) | ||
482 | { | ||
483 | struct dst_node *n = st->node; | ||
484 | struct dst_cmd *cmd = st->data; | ||
485 | struct dst_trans *t; | ||
486 | int err = 0; | ||
487 | struct bio *bio; | ||
488 | |||
489 | mutex_lock(&n->trans_lock); | ||
490 | t = dst_trans_search(n, cmd->id); | ||
491 | mutex_unlock(&n->trans_lock); | ||
492 | |||
493 | if (!t) | ||
494 | goto err_out_exit; | ||
495 | |||
496 | bio = t->bio; | ||
497 | |||
498 | dprintk("%s: bio: %llu/%u, cmd_size: %u, csize: %u, dir: %lu.\n", | ||
499 | __func__, (u64)bio->bi_sector, bio->bi_size, cmd->size, | ||
500 | cmd->csize, bio_data_dir(bio)); | ||
501 | |||
502 | if (bio_data_dir(bio) == READ) { | ||
503 | if (bio->bi_size != cmd->size - cmd->csize) | ||
504 | goto err_out_exit; | ||
505 | |||
506 | if (dst_need_crypto(n)) { | ||
507 | err = dst_recv_cdata(st, t->cmd.hash); | ||
508 | if (err) | ||
509 | goto err_out_exit; | ||
510 | } | ||
511 | |||
512 | err = dst_recv_bio(st, t->bio, bio->bi_size); | ||
513 | if (err) | ||
514 | goto err_out_exit; | ||
515 | |||
516 | if (dst_need_crypto(n)) | ||
517 | return dst_trans_crypto(t); | ||
518 | } else { | ||
519 | err = -EBADMSG; | ||
520 | if (cmd->size || cmd->csize) | ||
521 | goto err_out_exit; | ||
522 | } | ||
523 | |||
524 | dst_trans_remove(t); | ||
525 | dst_trans_put(t); | ||
526 | |||
527 | return 0; | ||
528 | |||
529 | err_out_exit: | ||
530 | return err; | ||
531 | } | ||
532 | |||
533 | /* | ||
534 | * Receive crypto data. | ||
535 | */ | ||
536 | int dst_recv_cdata(struct dst_state *st, void *cdata) | ||
537 | { | ||
538 | struct dst_cmd *cmd = st->data; | ||
539 | struct dst_node *n = st->node; | ||
540 | struct dst_crypto_ctl *c = &n->crypto; | ||
541 | int err; | ||
542 | |||
543 | if (cmd->csize != c->crypto_attached_size) { | ||
544 | dprintk("%s: cmd: cmd: %u, sector: %llu, size: %u, " | ||
545 | "csize: %u != digest size %u.\n", | ||
546 | __func__, cmd->cmd, cmd->sector, cmd->size, | ||
547 | cmd->csize, c->crypto_attached_size); | ||
548 | err = -EINVAL; | ||
549 | goto err_out_exit; | ||
550 | } | ||
551 | |||
552 | err = dst_data_recv(st, cdata, cmd->csize); | ||
553 | if (err) | ||
554 | goto err_out_exit; | ||
555 | |||
556 | cmd->size -= cmd->csize; | ||
557 | return 0; | ||
558 | |||
559 | err_out_exit: | ||
560 | return err; | ||
561 | } | ||
562 | |||
563 | /* | ||
564 | * Receive the command and start its processing. | ||
565 | */ | ||
566 | static int dst_recv_processing(struct dst_state *st) | ||
567 | { | ||
568 | int err = -EINTR; | ||
569 | struct dst_cmd *cmd = st->data; | ||
570 | |||
571 | /* | ||
572 | * If socket will be reset after this statement, then | ||
573 | * dst_data_recv() will just fail and loop will | ||
574 | * start again, so it can be done without any locks. | ||
575 | * | ||
576 | * st->read_socket is needed to prevents state machine | ||
577 | * breaking between this data reading and subsequent one | ||
578 | * in protocol specific functions during connection reset. | ||
579 | * In case of reset we have to read next command and do | ||
580 | * not expect data for old command to magically appear in | ||
581 | * new connection. | ||
582 | */ | ||
583 | st->read_socket = st->socket; | ||
584 | err = dst_data_recv(st, cmd, sizeof(struct dst_cmd)); | ||
585 | if (err) | ||
586 | goto out_exit; | ||
587 | |||
588 | dst_convert_cmd(cmd); | ||
589 | |||
590 | dprintk("%s: cmd: %u, size: %u, csize: %u, id: %llu, " | ||
591 | "sector: %llu, flags: %llx, rw: %llx.\n", | ||
592 | __func__, cmd->cmd, cmd->size, | ||
593 | cmd->csize, cmd->id, cmd->sector, | ||
594 | cmd->flags, cmd->rw); | ||
595 | |||
596 | /* | ||
597 | * This should catch protocol breakage and random garbage | ||
598 | * instead of commands. | ||
599 | */ | ||
600 | if (unlikely(cmd->csize > st->size - sizeof(struct dst_cmd))) { | ||
601 | err = -EBADMSG; | ||
602 | goto out_exit; | ||
603 | } | ||
604 | |||
605 | err = -EPROTO; | ||
606 | switch (cmd->cmd) { | ||
607 | case DST_IO_RESPONSE: | ||
608 | err = dst_process_io_response(st); | ||
609 | break; | ||
610 | case DST_IO: | ||
611 | err = dst_process_io(st); | ||
612 | break; | ||
613 | case DST_CFG: | ||
614 | err = dst_process_cfg(st); | ||
615 | break; | ||
616 | case DST_PING: | ||
617 | err = 0; | ||
618 | break; | ||
619 | default: | ||
620 | break; | ||
621 | } | ||
622 | |||
623 | out_exit: | ||
624 | return err; | ||
625 | } | ||
626 | |||
627 | /* | ||
628 | * Receiving thread. For the client node we should try to reconnect, | ||
629 | * for accepted client we just drop the state and expect it to reconnect. | ||
630 | */ | ||
631 | static int dst_recv(void *init_data, void *schedule_data) | ||
632 | { | ||
633 | struct dst_state *st = schedule_data; | ||
634 | struct dst_node *n = init_data; | ||
635 | int err = 0; | ||
636 | |||
637 | dprintk("%s: start st: %p, n: %p, scan: %lu, need_exit: %d.\n", | ||
638 | __func__, st, n, n->trans_scan_timeout, st->need_exit); | ||
639 | |||
640 | while (n->trans_scan_timeout && !st->need_exit) { | ||
641 | err = dst_recv_processing(st); | ||
642 | if (err < 0) { | ||
643 | if (!st->ctl.type) | ||
644 | break; | ||
645 | |||
646 | if (!n->trans_scan_timeout || st->need_exit) | ||
647 | break; | ||
648 | |||
649 | dst_state_reset(st); | ||
650 | msleep(1000); | ||
651 | } | ||
652 | } | ||
653 | |||
654 | st->need_exit = 1; | ||
655 | wake_up(&st->thread_wait); | ||
656 | |||
657 | dprintk("%s: freeing receiving socket st: %p.\n", __func__, st); | ||
658 | dst_state_lock(st); | ||
659 | dst_state_exit_connected(st); | ||
660 | dst_state_unlock(st); | ||
661 | dst_state_put(st); | ||
662 | |||
663 | dprintk("%s: freed receiving socket st: %p.\n", __func__, st); | ||
664 | |||
665 | return err; | ||
666 | } | ||
667 | |||
668 | /* | ||
669 | * Network state dies here and borns couple of lines below. | ||
670 | * This object is the main network state processing engine: | ||
671 | * sending, receiving, reconnections, all network related | ||
672 | * tasks are handled on behalf of the state. | ||
673 | */ | ||
674 | static void dst_state_free(struct dst_state *st) | ||
675 | { | ||
676 | dprintk("%s: st: %p.\n", __func__, st); | ||
677 | if (st->cleanup) | ||
678 | st->cleanup(st); | ||
679 | kfree(st->data); | ||
680 | kfree(st); | ||
681 | } | ||
682 | |||
683 | struct dst_state *dst_state_alloc(struct dst_node *n) | ||
684 | { | ||
685 | struct dst_state *st; | ||
686 | int err = -ENOMEM; | ||
687 | |||
688 | st = kzalloc(sizeof(struct dst_state), GFP_KERNEL); | ||
689 | if (!st) | ||
690 | goto err_out_exit; | ||
691 | |||
692 | st->node = n; | ||
693 | st->need_exit = 0; | ||
694 | |||
695 | st->size = PAGE_SIZE; | ||
696 | st->data = kmalloc(st->size, GFP_KERNEL); | ||
697 | if (!st->data) | ||
698 | goto err_out_free; | ||
699 | |||
700 | spin_lock_init(&st->request_lock); | ||
701 | INIT_LIST_HEAD(&st->request_list); | ||
702 | |||
703 | mutex_init(&st->state_lock); | ||
704 | init_waitqueue_head(&st->thread_wait); | ||
705 | |||
706 | /* | ||
707 | * One for processing thread, another one for node itself. | ||
708 | */ | ||
709 | atomic_set(&st->refcnt, 2); | ||
710 | |||
711 | dprintk("%s: st: %p, n: %p.\n", __func__, st, st->node); | ||
712 | |||
713 | return st; | ||
714 | |||
715 | err_out_free: | ||
716 | kfree(st); | ||
717 | err_out_exit: | ||
718 | return ERR_PTR(err); | ||
719 | } | ||
720 | |||
721 | int dst_state_schedule_receiver(struct dst_state *st) | ||
722 | { | ||
723 | return thread_pool_schedule_private(st->node->pool, dst_thread_setup, | ||
724 | dst_recv, st, MAX_SCHEDULE_TIMEOUT, st->node); | ||
725 | } | ||
726 | |||
727 | /* | ||
728 | * Initialize client's connection to the remote peer: allocate state, | ||
729 | * connect and perform block IO autoconfiguration. | ||
730 | */ | ||
731 | int dst_node_init_connected(struct dst_node *n, struct dst_network_ctl *r) | ||
732 | { | ||
733 | struct dst_state *st; | ||
734 | int err = -ENOMEM; | ||
735 | |||
736 | st = dst_state_alloc(n); | ||
737 | if (IS_ERR(st)) { | ||
738 | err = PTR_ERR(st); | ||
739 | goto err_out_exit; | ||
740 | } | ||
741 | memcpy(&st->ctl, r, sizeof(struct dst_network_ctl)); | ||
742 | |||
743 | err = dst_state_init_connected(st); | ||
744 | if (err) | ||
745 | goto err_out_free_data; | ||
746 | |||
747 | err = dst_request_remote_config(st); | ||
748 | if (err) | ||
749 | goto err_out_exit_connected; | ||
750 | n->state = st; | ||
751 | |||
752 | err = dst_state_schedule_receiver(st); | ||
753 | if (err) | ||
754 | goto err_out_exit_connected; | ||
755 | |||
756 | return 0; | ||
757 | |||
758 | err_out_exit_connected: | ||
759 | dst_state_exit_connected(st); | ||
760 | err_out_free_data: | ||
761 | dst_state_free(st); | ||
762 | err_out_exit: | ||
763 | n->state = NULL; | ||
764 | return err; | ||
765 | } | ||
766 | |||
767 | void dst_state_put(struct dst_state *st) | ||
768 | { | ||
769 | dprintk("%s: st: %p, refcnt: %d.\n", | ||
770 | __func__, st, atomic_read(&st->refcnt)); | ||
771 | if (atomic_dec_and_test(&st->refcnt)) | ||
772 | dst_state_free(st); | ||
773 | } | ||
774 | |||
775 | /* | ||
776 | * Send block IO to the network one by one using zero-copy ->sendpage(). | ||
777 | */ | ||
778 | int dst_send_bio(struct dst_state *st, struct dst_cmd *cmd, struct bio *bio) | ||
779 | { | ||
780 | struct bio_vec *bv; | ||
781 | struct dst_crypto_ctl *c = &st->node->crypto; | ||
782 | int err, i = 0; | ||
783 | int flags = MSG_WAITALL; | ||
784 | |||
785 | err = dst_data_send_header(st->socket, cmd, | ||
786 | sizeof(struct dst_cmd) + c->crypto_attached_size, bio->bi_vcnt); | ||
787 | if (err) | ||
788 | goto err_out_exit; | ||
789 | |||
790 | bio_for_each_segment(bv, bio, i) { | ||
791 | if (i < bio->bi_vcnt - 1) | ||
792 | flags |= MSG_MORE; | ||
793 | |||
794 | err = kernel_sendpage(st->socket, bv->bv_page, bv->bv_offset, | ||
795 | bv->bv_len, flags); | ||
796 | if (err <= 0) | ||
797 | goto err_out_exit; | ||
798 | } | ||
799 | |||
800 | return 0; | ||
801 | |||
802 | err_out_exit: | ||
803 | dprintk("%s: %d/%d, flags: %x, err: %d.\n", | ||
804 | __func__, i, bio->bi_vcnt, flags, err); | ||
805 | return err; | ||
806 | } | ||
807 | |||
808 | /* | ||
809 | * Send transaction to the remote peer. | ||
810 | */ | ||
811 | int dst_trans_send(struct dst_trans *t) | ||
812 | { | ||
813 | int err; | ||
814 | struct dst_state *st = t->n->state; | ||
815 | struct bio *bio = t->bio; | ||
816 | |||
817 | dst_convert_cmd(&t->cmd); | ||
818 | |||
819 | dst_state_lock(st); | ||
820 | if (!st->socket) { | ||
821 | err = dst_state_init_connected(st); | ||
822 | if (err) | ||
823 | goto err_out_unlock; | ||
824 | } | ||
825 | |||
826 | if (bio_data_dir(bio) == WRITE) { | ||
827 | err = dst_send_bio(st, &t->cmd, t->bio); | ||
828 | } else { | ||
829 | err = dst_data_send_header(st->socket, &t->cmd, | ||
830 | sizeof(struct dst_cmd), 0); | ||
831 | } | ||
832 | if (err) | ||
833 | goto err_out_reset; | ||
834 | |||
835 | dst_state_unlock(st); | ||
836 | return 0; | ||
837 | |||
838 | err_out_reset: | ||
839 | dst_state_reset_nolock(st); | ||
840 | err_out_unlock: | ||
841 | dst_state_unlock(st); | ||
842 | |||
843 | return err; | ||
844 | } | ||
diff --git a/drivers/staging/dst/thread_pool.c b/drivers/staging/dst/thread_pool.c deleted file mode 100644 index 29a82b2602f3..000000000000 --- a/drivers/staging/dst/thread_pool.c +++ /dev/null | |||
@@ -1,348 +0,0 @@ | |||
1 | /* | ||
2 | * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net> | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | */ | ||
15 | |||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/dst.h> | ||
18 | #include <linux/kthread.h> | ||
19 | #include <linux/slab.h> | ||
20 | |||
21 | /* | ||
22 | * Thread pool abstraction allows to schedule a work to be performed | ||
23 | * on behalf of kernel thread. One does not operate with threads itself, | ||
24 | * instead user provides setup and cleanup callbacks for thread pool itself, | ||
25 | * and action and cleanup callbacks for each submitted work. | ||
26 | * | ||
27 | * Each worker has private data initialized at creation time and data, | ||
28 | * provided by user at scheduling time. | ||
29 | * | ||
30 | * When action is being performed, thread can not be used by other users, | ||
31 | * instead they will sleep until there is free thread to pick their work. | ||
32 | */ | ||
33 | struct thread_pool_worker { | ||
34 | struct list_head worker_entry; | ||
35 | |||
36 | struct task_struct *thread; | ||
37 | |||
38 | struct thread_pool *pool; | ||
39 | |||
40 | int error; | ||
41 | int has_data; | ||
42 | int need_exit; | ||
43 | unsigned int id; | ||
44 | |||
45 | wait_queue_head_t wait; | ||
46 | |||
47 | void *private; | ||
48 | void *schedule_data; | ||
49 | |||
50 | int (*action)(void *private, void *schedule_data); | ||
51 | void (*cleanup)(void *private); | ||
52 | }; | ||
53 | |||
54 | static void thread_pool_exit_worker(struct thread_pool_worker *w) | ||
55 | { | ||
56 | kthread_stop(w->thread); | ||
57 | |||
58 | w->cleanup(w->private); | ||
59 | kfree(w); | ||
60 | } | ||
61 | |||
62 | /* | ||
63 | * Called to mark thread as ready and allow users to schedule new work. | ||
64 | */ | ||
65 | static void thread_pool_worker_make_ready(struct thread_pool_worker *w) | ||
66 | { | ||
67 | struct thread_pool *p = w->pool; | ||
68 | |||
69 | mutex_lock(&p->thread_lock); | ||
70 | |||
71 | if (!w->need_exit) { | ||
72 | list_move_tail(&w->worker_entry, &p->ready_list); | ||
73 | w->has_data = 0; | ||
74 | mutex_unlock(&p->thread_lock); | ||
75 | |||
76 | wake_up(&p->wait); | ||
77 | } else { | ||
78 | p->thread_num--; | ||
79 | list_del(&w->worker_entry); | ||
80 | mutex_unlock(&p->thread_lock); | ||
81 | |||
82 | thread_pool_exit_worker(w); | ||
83 | } | ||
84 | } | ||
85 | |||
86 | /* | ||
87 | * Thread action loop: waits until there is new work. | ||
88 | */ | ||
89 | static int thread_pool_worker_func(void *data) | ||
90 | { | ||
91 | struct thread_pool_worker *w = data; | ||
92 | |||
93 | while (!kthread_should_stop()) { | ||
94 | wait_event_interruptible(w->wait, | ||
95 | kthread_should_stop() || w->has_data); | ||
96 | |||
97 | if (kthread_should_stop()) | ||
98 | break; | ||
99 | |||
100 | if (!w->has_data) | ||
101 | continue; | ||
102 | |||
103 | w->action(w->private, w->schedule_data); | ||
104 | thread_pool_worker_make_ready(w); | ||
105 | } | ||
106 | |||
107 | return 0; | ||
108 | } | ||
109 | |||
110 | /* | ||
111 | * Remove single worker without specifying which one. | ||
112 | */ | ||
113 | void thread_pool_del_worker(struct thread_pool *p) | ||
114 | { | ||
115 | struct thread_pool_worker *w = NULL; | ||
116 | |||
117 | while (!w && p->thread_num) { | ||
118 | wait_event(p->wait, !list_empty(&p->ready_list) || | ||
119 | !p->thread_num); | ||
120 | |||
121 | dprintk("%s: locking list_empty: %d, thread_num: %d.\n", | ||
122 | __func__, list_empty(&p->ready_list), | ||
123 | p->thread_num); | ||
124 | |||
125 | mutex_lock(&p->thread_lock); | ||
126 | if (!list_empty(&p->ready_list)) { | ||
127 | w = list_first_entry(&p->ready_list, | ||
128 | struct thread_pool_worker, | ||
129 | worker_entry); | ||
130 | |||
131 | dprintk("%s: deleting w: %p, thread_num: %d, " | ||
132 | "list: %p [%p.%p].\n", __func__, | ||
133 | w, p->thread_num, &p->ready_list, | ||
134 | p->ready_list.prev, p->ready_list.next); | ||
135 | |||
136 | p->thread_num--; | ||
137 | list_del(&w->worker_entry); | ||
138 | } | ||
139 | mutex_unlock(&p->thread_lock); | ||
140 | } | ||
141 | |||
142 | if (w) | ||
143 | thread_pool_exit_worker(w); | ||
144 | dprintk("%s: deleted w: %p, thread_num: %d.\n", | ||
145 | __func__, w, p->thread_num); | ||
146 | } | ||
147 | |||
148 | /* | ||
149 | * Remove a worker with given ID. | ||
150 | */ | ||
151 | void thread_pool_del_worker_id(struct thread_pool *p, unsigned int id) | ||
152 | { | ||
153 | struct thread_pool_worker *w; | ||
154 | int found = 0; | ||
155 | |||
156 | mutex_lock(&p->thread_lock); | ||
157 | list_for_each_entry(w, &p->ready_list, worker_entry) { | ||
158 | if (w->id == id) { | ||
159 | found = 1; | ||
160 | p->thread_num--; | ||
161 | list_del(&w->worker_entry); | ||
162 | break; | ||
163 | } | ||
164 | } | ||
165 | |||
166 | if (!found) { | ||
167 | list_for_each_entry(w, &p->active_list, worker_entry) { | ||
168 | if (w->id == id) { | ||
169 | w->need_exit = 1; | ||
170 | break; | ||
171 | } | ||
172 | } | ||
173 | } | ||
174 | mutex_unlock(&p->thread_lock); | ||
175 | |||
176 | if (found) | ||
177 | thread_pool_exit_worker(w); | ||
178 | } | ||
179 | |||
180 | /* | ||
181 | * Add new worker thread with given parameters. | ||
182 | * If initialization callback fails, return error. | ||
183 | */ | ||
184 | int thread_pool_add_worker(struct thread_pool *p, | ||
185 | char *name, | ||
186 | unsigned int id, | ||
187 | void *(*init)(void *private), | ||
188 | void (*cleanup)(void *private), | ||
189 | void *private) | ||
190 | { | ||
191 | struct thread_pool_worker *w; | ||
192 | int err = -ENOMEM; | ||
193 | |||
194 | w = kzalloc(sizeof(struct thread_pool_worker), GFP_KERNEL); | ||
195 | if (!w) | ||
196 | goto err_out_exit; | ||
197 | |||
198 | w->pool = p; | ||
199 | init_waitqueue_head(&w->wait); | ||
200 | w->cleanup = cleanup; | ||
201 | w->id = id; | ||
202 | |||
203 | w->thread = kthread_run(thread_pool_worker_func, w, "%s", name); | ||
204 | if (IS_ERR(w->thread)) { | ||
205 | err = PTR_ERR(w->thread); | ||
206 | goto err_out_free; | ||
207 | } | ||
208 | |||
209 | w->private = init(private); | ||
210 | if (IS_ERR(w->private)) { | ||
211 | err = PTR_ERR(w->private); | ||
212 | goto err_out_stop_thread; | ||
213 | } | ||
214 | |||
215 | mutex_lock(&p->thread_lock); | ||
216 | list_add_tail(&w->worker_entry, &p->ready_list); | ||
217 | p->thread_num++; | ||
218 | mutex_unlock(&p->thread_lock); | ||
219 | |||
220 | return 0; | ||
221 | |||
222 | err_out_stop_thread: | ||
223 | kthread_stop(w->thread); | ||
224 | err_out_free: | ||
225 | kfree(w); | ||
226 | err_out_exit: | ||
227 | return err; | ||
228 | } | ||
229 | |||
230 | /* | ||
231 | * Destroy the whole pool. | ||
232 | */ | ||
233 | void thread_pool_destroy(struct thread_pool *p) | ||
234 | { | ||
235 | while (p->thread_num) { | ||
236 | dprintk("%s: num: %d.\n", __func__, p->thread_num); | ||
237 | thread_pool_del_worker(p); | ||
238 | } | ||
239 | |||
240 | kfree(p); | ||
241 | } | ||
242 | |||
243 | /* | ||
244 | * Create a pool with given number of threads. | ||
245 | * They will have sequential IDs started from zero. | ||
246 | */ | ||
247 | struct thread_pool *thread_pool_create(int num, char *name, | ||
248 | void *(*init)(void *private), | ||
249 | void (*cleanup)(void *private), | ||
250 | void *private) | ||
251 | { | ||
252 | struct thread_pool_worker *w, *tmp; | ||
253 | struct thread_pool *p; | ||
254 | int err = -ENOMEM; | ||
255 | int i; | ||
256 | |||
257 | p = kzalloc(sizeof(struct thread_pool), GFP_KERNEL); | ||
258 | if (!p) | ||
259 | goto err_out_exit; | ||
260 | |||
261 | init_waitqueue_head(&p->wait); | ||
262 | mutex_init(&p->thread_lock); | ||
263 | INIT_LIST_HEAD(&p->ready_list); | ||
264 | INIT_LIST_HEAD(&p->active_list); | ||
265 | p->thread_num = 0; | ||
266 | |||
267 | for (i = 0; i < num; ++i) { | ||
268 | err = thread_pool_add_worker(p, name, i, init, | ||
269 | cleanup, private); | ||
270 | if (err) | ||
271 | goto err_out_free_all; | ||
272 | } | ||
273 | |||
274 | return p; | ||
275 | |||
276 | err_out_free_all: | ||
277 | list_for_each_entry_safe(w, tmp, &p->ready_list, worker_entry) { | ||
278 | list_del(&w->worker_entry); | ||
279 | thread_pool_exit_worker(w); | ||
280 | } | ||
281 | kfree(p); | ||
282 | err_out_exit: | ||
283 | return ERR_PTR(err); | ||
284 | } | ||
285 | |||
286 | /* | ||
287 | * Schedule execution of the action on a given thread, | ||
288 | * provided ID pointer has to match previously stored | ||
289 | * private data. | ||
290 | */ | ||
291 | int thread_pool_schedule_private(struct thread_pool *p, | ||
292 | int (*setup)(void *private, void *data), | ||
293 | int (*action)(void *private, void *data), | ||
294 | void *data, long timeout, void *id) | ||
295 | { | ||
296 | struct thread_pool_worker *w, *tmp, *worker = NULL; | ||
297 | int err = 0; | ||
298 | |||
299 | while (!worker && !err) { | ||
300 | timeout = wait_event_interruptible_timeout(p->wait, | ||
301 | !list_empty(&p->ready_list), | ||
302 | timeout); | ||
303 | |||
304 | if (!timeout) { | ||
305 | err = -ETIMEDOUT; | ||
306 | break; | ||
307 | } | ||
308 | |||
309 | worker = NULL; | ||
310 | mutex_lock(&p->thread_lock); | ||
311 | list_for_each_entry_safe(w, tmp, &p->ready_list, worker_entry) { | ||
312 | if (id && id != w->private) | ||
313 | continue; | ||
314 | |||
315 | worker = w; | ||
316 | |||
317 | list_move_tail(&w->worker_entry, &p->active_list); | ||
318 | |||
319 | err = setup(w->private, data); | ||
320 | if (!err) { | ||
321 | w->schedule_data = data; | ||
322 | w->action = action; | ||
323 | w->has_data = 1; | ||
324 | wake_up(&w->wait); | ||
325 | } else { | ||
326 | list_move_tail(&w->worker_entry, | ||
327 | &p->ready_list); | ||
328 | } | ||
329 | |||
330 | break; | ||
331 | } | ||
332 | mutex_unlock(&p->thread_lock); | ||
333 | } | ||
334 | |||
335 | return err; | ||
336 | } | ||
337 | |||
338 | /* | ||
339 | * Schedule execution on arbitrary thread from the pool. | ||
340 | */ | ||
341 | int thread_pool_schedule(struct thread_pool *p, | ||
342 | int (*setup)(void *private, void *data), | ||
343 | int (*action)(void *private, void *data), | ||
344 | void *data, long timeout) | ||
345 | { | ||
346 | return thread_pool_schedule_private(p, setup, | ||
347 | action, data, timeout, NULL); | ||
348 | } | ||
diff --git a/drivers/staging/dst/trans.c b/drivers/staging/dst/trans.c deleted file mode 100644 index 1c36a6bc31d5..000000000000 --- a/drivers/staging/dst/trans.c +++ /dev/null | |||
@@ -1,337 +0,0 @@ | |||
1 | /* | ||
2 | * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net> | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | */ | ||
15 | |||
16 | #include <linux/bio.h> | ||
17 | #include <linux/dst.h> | ||
18 | #include <linux/slab.h> | ||
19 | #include <linux/mempool.h> | ||
20 | |||
21 | /* | ||
22 | * Transaction memory pool size. | ||
23 | */ | ||
24 | static int dst_mempool_num = 32; | ||
25 | module_param(dst_mempool_num, int, 0644); | ||
26 | |||
27 | /* | ||
28 | * Transaction tree management. | ||
29 | */ | ||
30 | static inline int dst_trans_cmp(dst_gen_t gen, dst_gen_t new) | ||
31 | { | ||
32 | if (gen < new) | ||
33 | return 1; | ||
34 | if (gen > new) | ||
35 | return -1; | ||
36 | return 0; | ||
37 | } | ||
38 | |||
39 | struct dst_trans *dst_trans_search(struct dst_node *node, dst_gen_t gen) | ||
40 | { | ||
41 | struct rb_root *root = &node->trans_root; | ||
42 | struct rb_node *n = root->rb_node; | ||
43 | struct dst_trans *t, *ret = NULL; | ||
44 | int cmp; | ||
45 | |||
46 | while (n) { | ||
47 | t = rb_entry(n, struct dst_trans, trans_entry); | ||
48 | |||
49 | cmp = dst_trans_cmp(t->gen, gen); | ||
50 | if (cmp < 0) | ||
51 | n = n->rb_left; | ||
52 | else if (cmp > 0) | ||
53 | n = n->rb_right; | ||
54 | else { | ||
55 | ret = t; | ||
56 | break; | ||
57 | } | ||
58 | } | ||
59 | |||
60 | dprintk("%s: %s transaction: id: %llu.\n", __func__, | ||
61 | (ret) ? "found" : "not found", gen); | ||
62 | |||
63 | return ret; | ||
64 | } | ||
65 | |||
66 | static int dst_trans_insert(struct dst_trans *new) | ||
67 | { | ||
68 | struct rb_root *root = &new->n->trans_root; | ||
69 | struct rb_node **n = &root->rb_node, *parent = NULL; | ||
70 | struct dst_trans *ret = NULL, *t; | ||
71 | int cmp; | ||
72 | |||
73 | while (*n) { | ||
74 | parent = *n; | ||
75 | |||
76 | t = rb_entry(parent, struct dst_trans, trans_entry); | ||
77 | |||
78 | cmp = dst_trans_cmp(t->gen, new->gen); | ||
79 | if (cmp < 0) | ||
80 | n = &parent->rb_left; | ||
81 | else if (cmp > 0) | ||
82 | n = &parent->rb_right; | ||
83 | else { | ||
84 | ret = t; | ||
85 | break; | ||
86 | } | ||
87 | } | ||
88 | |||
89 | new->send_time = jiffies; | ||
90 | if (ret) { | ||
91 | printk(KERN_DEBUG "%s: exist: old: gen: %llu, bio: %llu/%u, " | ||
92 | "send_time: %lu, new: gen: %llu, bio: %llu/%u, " | ||
93 | "send_time: %lu.\n", __func__, | ||
94 | ret->gen, (u64)ret->bio->bi_sector, | ||
95 | ret->bio->bi_size, ret->send_time, | ||
96 | new->gen, (u64)new->bio->bi_sector, | ||
97 | new->bio->bi_size, new->send_time); | ||
98 | return -EEXIST; | ||
99 | } | ||
100 | |||
101 | rb_link_node(&new->trans_entry, parent, n); | ||
102 | rb_insert_color(&new->trans_entry, root); | ||
103 | |||
104 | dprintk("%s: inserted: gen: %llu, bio: %llu/%u, send_time: %lu.\n", | ||
105 | __func__, new->gen, (u64)new->bio->bi_sector, | ||
106 | new->bio->bi_size, new->send_time); | ||
107 | |||
108 | return 0; | ||
109 | } | ||
110 | |||
111 | int dst_trans_remove_nolock(struct dst_trans *t) | ||
112 | { | ||
113 | struct dst_node *n = t->n; | ||
114 | |||
115 | if (t->trans_entry.rb_parent_color) { | ||
116 | rb_erase(&t->trans_entry, &n->trans_root); | ||
117 | t->trans_entry.rb_parent_color = 0; | ||
118 | } | ||
119 | return 0; | ||
120 | } | ||
121 | |||
122 | int dst_trans_remove(struct dst_trans *t) | ||
123 | { | ||
124 | int ret; | ||
125 | struct dst_node *n = t->n; | ||
126 | |||
127 | mutex_lock(&n->trans_lock); | ||
128 | ret = dst_trans_remove_nolock(t); | ||
129 | mutex_unlock(&n->trans_lock); | ||
130 | |||
131 | return ret; | ||
132 | } | ||
133 | |||
134 | /* | ||
135 | * When transaction is completed and there are no more users, | ||
136 | * we complete appriate block IO request with given error status. | ||
137 | */ | ||
138 | void dst_trans_put(struct dst_trans *t) | ||
139 | { | ||
140 | if (atomic_dec_and_test(&t->refcnt)) { | ||
141 | struct bio *bio = t->bio; | ||
142 | |||
143 | dprintk("%s: completed t: %p, gen: %llu, bio: %p.\n", | ||
144 | __func__, t, t->gen, bio); | ||
145 | |||
146 | bio_endio(bio, t->error); | ||
147 | bio_put(bio); | ||
148 | |||
149 | dst_node_put(t->n); | ||
150 | mempool_free(t, t->n->trans_pool); | ||
151 | } | ||
152 | } | ||
153 | |||
154 | /* | ||
155 | * Process given block IO request: allocate transaction, insert it into the tree | ||
156 | * and send/schedule crypto processing. | ||
157 | */ | ||
158 | int dst_process_bio(struct dst_node *n, struct bio *bio) | ||
159 | { | ||
160 | struct dst_trans *t; | ||
161 | int err = -ENOMEM; | ||
162 | |||
163 | t = mempool_alloc(n->trans_pool, GFP_NOFS); | ||
164 | if (!t) | ||
165 | goto err_out_exit; | ||
166 | |||
167 | t->n = dst_node_get(n); | ||
168 | t->bio = bio; | ||
169 | t->error = 0; | ||
170 | t->retries = 0; | ||
171 | atomic_set(&t->refcnt, 1); | ||
172 | t->gen = atomic_long_inc_return(&n->gen); | ||
173 | |||
174 | t->enc = bio_data_dir(bio); | ||
175 | dst_bio_to_cmd(bio, &t->cmd, DST_IO, t->gen); | ||
176 | |||
177 | mutex_lock(&n->trans_lock); | ||
178 | err = dst_trans_insert(t); | ||
179 | mutex_unlock(&n->trans_lock); | ||
180 | if (err) | ||
181 | goto err_out_free; | ||
182 | |||
183 | dprintk("%s: gen: %llu, bio: %llu/%u, dir/enc: %d, need_crypto: %d.\n", | ||
184 | __func__, t->gen, (u64)bio->bi_sector, | ||
185 | bio->bi_size, t->enc, dst_need_crypto(n)); | ||
186 | |||
187 | if (dst_need_crypto(n) && t->enc) | ||
188 | dst_trans_crypto(t); | ||
189 | else | ||
190 | dst_trans_send(t); | ||
191 | |||
192 | return 0; | ||
193 | |||
194 | err_out_free: | ||
195 | dst_node_put(n); | ||
196 | mempool_free(t, n->trans_pool); | ||
197 | err_out_exit: | ||
198 | bio_endio(bio, err); | ||
199 | bio_put(bio); | ||
200 | return err; | ||
201 | } | ||
202 | |||
203 | /* | ||
204 | * Scan for timeout/stale transactions. | ||
205 | * Each transaction is being resent multiple times before error completion. | ||
206 | */ | ||
207 | static void dst_trans_scan(struct work_struct *work) | ||
208 | { | ||
209 | struct dst_node *n = container_of(work, struct dst_node, | ||
210 | trans_work.work); | ||
211 | struct rb_node *rb_node; | ||
212 | struct dst_trans *t; | ||
213 | unsigned long timeout = n->trans_scan_timeout; | ||
214 | int num = 10 * n->trans_max_retries; | ||
215 | |||
216 | mutex_lock(&n->trans_lock); | ||
217 | |||
218 | for (rb_node = rb_first(&n->trans_root); rb_node; ) { | ||
219 | t = rb_entry(rb_node, struct dst_trans, trans_entry); | ||
220 | |||
221 | if (timeout && time_after(t->send_time + timeout, jiffies) | ||
222 | && t->retries == 0) | ||
223 | break; | ||
224 | #if 0 | ||
225 | dprintk("%s: t: %p, gen: %llu, n: %s, retries: %u, max: %u.\n", | ||
226 | __func__, t, t->gen, n->name, | ||
227 | t->retries, n->trans_max_retries); | ||
228 | #endif | ||
229 | if (--num == 0) | ||
230 | break; | ||
231 | |||
232 | dst_trans_get(t); | ||
233 | |||
234 | rb_node = rb_next(rb_node); | ||
235 | |||
236 | if (timeout && (++t->retries < n->trans_max_retries)) { | ||
237 | dst_trans_send(t); | ||
238 | } else { | ||
239 | t->error = -ETIMEDOUT; | ||
240 | dst_trans_remove_nolock(t); | ||
241 | dst_trans_put(t); | ||
242 | } | ||
243 | |||
244 | dst_trans_put(t); | ||
245 | } | ||
246 | |||
247 | mutex_unlock(&n->trans_lock); | ||
248 | |||
249 | /* | ||
250 | * If no timeout specified then system is in the middle of exiting | ||
251 | * process, so no need to reschedule scanning process again. | ||
252 | */ | ||
253 | if (timeout) { | ||
254 | if (!num) | ||
255 | timeout = HZ; | ||
256 | schedule_delayed_work(&n->trans_work, timeout); | ||
257 | } | ||
258 | } | ||
259 | |||
260 | /* | ||
261 | * Flush all transactions and mark them as timed out. | ||
262 | * Destroy transaction pools. | ||
263 | */ | ||
264 | void dst_node_trans_exit(struct dst_node *n) | ||
265 | { | ||
266 | struct dst_trans *t; | ||
267 | struct rb_node *rb_node; | ||
268 | |||
269 | if (!n->trans_cache) | ||
270 | return; | ||
271 | |||
272 | dprintk("%s: n: %p, cancelling the work.\n", __func__, n); | ||
273 | cancel_delayed_work_sync(&n->trans_work); | ||
274 | flush_scheduled_work(); | ||
275 | dprintk("%s: n: %p, work has been cancelled.\n", __func__, n); | ||
276 | |||
277 | for (rb_node = rb_first(&n->trans_root); rb_node; ) { | ||
278 | t = rb_entry(rb_node, struct dst_trans, trans_entry); | ||
279 | |||
280 | dprintk("%s: t: %p, gen: %llu, n: %s.\n", | ||
281 | __func__, t, t->gen, n->name); | ||
282 | |||
283 | rb_node = rb_next(rb_node); | ||
284 | |||
285 | t->error = -ETIMEDOUT; | ||
286 | dst_trans_remove_nolock(t); | ||
287 | dst_trans_put(t); | ||
288 | } | ||
289 | |||
290 | mempool_destroy(n->trans_pool); | ||
291 | kmem_cache_destroy(n->trans_cache); | ||
292 | } | ||
293 | |||
294 | /* | ||
295 | * Initialize transaction storage for given node. | ||
296 | * Transaction stores not only control information, | ||
297 | * but also network command and crypto data (if needed) | ||
298 | * to reduce number of allocations. Thus transaction size | ||
299 | * differs from node to node. | ||
300 | */ | ||
301 | int dst_node_trans_init(struct dst_node *n, unsigned int size) | ||
302 | { | ||
303 | /* | ||
304 | * We need this, since node with given name can be dropped from the | ||
305 | * hash table, but be still alive, so subsequent creation of the node | ||
306 | * with the same name may collide with existing cache name. | ||
307 | */ | ||
308 | |||
309 | snprintf(n->cache_name, sizeof(n->cache_name), "%s-%p", n->name, n); | ||
310 | |||
311 | n->trans_cache = kmem_cache_create(n->cache_name, | ||
312 | size + n->crypto.crypto_attached_size, | ||
313 | 0, 0, NULL); | ||
314 | if (!n->trans_cache) | ||
315 | goto err_out_exit; | ||
316 | |||
317 | n->trans_pool = mempool_create_slab_pool(dst_mempool_num, | ||
318 | n->trans_cache); | ||
319 | if (!n->trans_pool) | ||
320 | goto err_out_cache_destroy; | ||
321 | |||
322 | mutex_init(&n->trans_lock); | ||
323 | n->trans_root = RB_ROOT; | ||
324 | |||
325 | INIT_DELAYED_WORK(&n->trans_work, dst_trans_scan); | ||
326 | schedule_delayed_work(&n->trans_work, n->trans_scan_timeout); | ||
327 | |||
328 | dprintk("%s: n: %p, size: %u, crypto: %u.\n", | ||
329 | __func__, n, size, n->crypto.crypto_attached_size); | ||
330 | |||
331 | return 0; | ||
332 | |||
333 | err_out_cache_destroy: | ||
334 | kmem_cache_destroy(n->trans_cache); | ||
335 | err_out_exit: | ||
336 | return -ENOMEM; | ||
337 | } | ||
diff --git a/drivers/staging/panel/Kconfig b/drivers/staging/panel/Kconfig index 3abe7c9d558d..3defa0133f2e 100644 --- a/drivers/staging/panel/Kconfig +++ b/drivers/staging/panel/Kconfig | |||
@@ -47,7 +47,7 @@ config PANEL_PROFILE | |||
47 | config PANEL_KEYPAD | 47 | config PANEL_KEYPAD |
48 | depends on PANEL && PANEL_PROFILE="0" | 48 | depends on PANEL && PANEL_PROFILE="0" |
49 | int "Keypad type (0=none, 1=old 6 keys, 2=new 6 keys, 3=Nexcom 4 keys)" | 49 | int "Keypad type (0=none, 1=old 6 keys, 2=new 6 keys, 3=Nexcom 4 keys)" |
50 | range 0 4 | 50 | range 0 3 |
51 | default 0 | 51 | default 0 |
52 | ---help--- | 52 | ---help--- |
53 | This enables and configures a keypad connected to the parallel port. | 53 | This enables and configures a keypad connected to the parallel port. |
diff --git a/drivers/staging/panel/panel.c b/drivers/staging/panel/panel.c index f98a52448eae..95c93e82ccec 100644 --- a/drivers/staging/panel/panel.c +++ b/drivers/staging/panel/panel.c | |||
@@ -378,7 +378,7 @@ static unsigned char lcd_bits[LCD_PORTS][LCD_BITS][BIT_STATES]; | |||
378 | 378 | ||
379 | #ifdef CONFIG_PANEL_LCD_CHARSET | 379 | #ifdef CONFIG_PANEL_LCD_CHARSET |
380 | #undef DEFAULT_LCD_CHARSET | 380 | #undef DEFAULT_LCD_CHARSET |
381 | #define DEFAULT_LCD_CHARSET | 381 | #define DEFAULT_LCD_CHARSET CONFIG_PANEL_LCD_CHARSET |
382 | #endif | 382 | #endif |
383 | 383 | ||
384 | #endif /* DEFAULT_PROFILE == 0 */ | 384 | #endif /* DEFAULT_PROFILE == 0 */ |
diff --git a/drivers/staging/pohmelfs/dir.c b/drivers/staging/pohmelfs/dir.c index 6c5b261e9f06..aacd25bfb0cb 100644 --- a/drivers/staging/pohmelfs/dir.c +++ b/drivers/staging/pohmelfs/dir.c | |||
@@ -722,8 +722,6 @@ static int pohmelfs_remove_entry(struct inode *dir, struct dentry *dentry) | |||
722 | if (inode->i_nlink) | 722 | if (inode->i_nlink) |
723 | inode_dec_link_count(inode); | 723 | inode_dec_link_count(inode); |
724 | } | 724 | } |
725 | dprintk("%s: inode: %p, lock: %ld, unhashed: %d.\n", | ||
726 | __func__, pi, inode->i_state & I_LOCK, hlist_unhashed(&inode->i_hash)); | ||
727 | 725 | ||
728 | return err; | 726 | return err; |
729 | } | 727 | } |
diff --git a/drivers/staging/ramzswap/TODO b/drivers/staging/ramzswap/TODO index bac40d6cb9f1..8d64e28fac0e 100644 --- a/drivers/staging/ramzswap/TODO +++ b/drivers/staging/ramzswap/TODO | |||
@@ -1,6 +1,5 @@ | |||
1 | TODO: | 1 | TODO: |
2 | - Add support for swap notifiers | 2 | - Add support for swap notifiers |
3 | - Remove CONFIG_ARM hack | ||
4 | 3 | ||
5 | Please send patches to Greg Kroah-Hartman <greg@kroah.com> and | 4 | Please send patches to Greg Kroah-Hartman <greg@kroah.com> and |
6 | Nitin Gupta <ngupta@vflare.org> | 5 | Nitin Gupta <ngupta@vflare.org> |
diff --git a/drivers/staging/ramzswap/ramzswap_drv.c b/drivers/staging/ramzswap/ramzswap_drv.c index b839f05efbce..989fac5b01b3 100644 --- a/drivers/staging/ramzswap/ramzswap_drv.c +++ b/drivers/staging/ramzswap/ramzswap_drv.c | |||
@@ -222,28 +222,6 @@ out: | |||
222 | return ret; | 222 | return ret; |
223 | } | 223 | } |
224 | 224 | ||
225 | static void ramzswap_flush_dcache_page(struct page *page) | ||
226 | { | ||
227 | #ifdef CONFIG_ARM | ||
228 | int flag = 0; | ||
229 | /* | ||
230 | * Ugly hack to get flush_dcache_page() work on ARM. | ||
231 | * page_mapping(page) == NULL after clearing this swap cache flag. | ||
232 | * Without clearing this flag, flush_dcache_page() will simply set | ||
233 | * "PG_dcache_dirty" bit and return. | ||
234 | */ | ||
235 | if (PageSwapCache(page)) { | ||
236 | flag = 1; | ||
237 | ClearPageSwapCache(page); | ||
238 | } | ||
239 | #endif | ||
240 | flush_dcache_page(page); | ||
241 | #ifdef CONFIG_ARM | ||
242 | if (flag) | ||
243 | SetPageSwapCache(page); | ||
244 | #endif | ||
245 | } | ||
246 | |||
247 | void ramzswap_ioctl_get_stats(struct ramzswap *rzs, | 225 | void ramzswap_ioctl_get_stats(struct ramzswap *rzs, |
248 | struct ramzswap_ioctl_stats *s) | 226 | struct ramzswap_ioctl_stats *s) |
249 | { | 227 | { |
@@ -655,7 +633,7 @@ static int handle_zero_page(struct bio *bio) | |||
655 | memset(user_mem, 0, PAGE_SIZE); | 633 | memset(user_mem, 0, PAGE_SIZE); |
656 | kunmap_atomic(user_mem, KM_USER0); | 634 | kunmap_atomic(user_mem, KM_USER0); |
657 | 635 | ||
658 | ramzswap_flush_dcache_page(page); | 636 | flush_dcache_page(page); |
659 | 637 | ||
660 | set_bit(BIO_UPTODATE, &bio->bi_flags); | 638 | set_bit(BIO_UPTODATE, &bio->bi_flags); |
661 | bio_endio(bio, 0); | 639 | bio_endio(bio, 0); |
@@ -679,7 +657,7 @@ static int handle_uncompressed_page(struct ramzswap *rzs, struct bio *bio) | |||
679 | kunmap_atomic(user_mem, KM_USER0); | 657 | kunmap_atomic(user_mem, KM_USER0); |
680 | kunmap_atomic(cmem, KM_USER1); | 658 | kunmap_atomic(cmem, KM_USER1); |
681 | 659 | ||
682 | ramzswap_flush_dcache_page(page); | 660 | flush_dcache_page(page); |
683 | 661 | ||
684 | set_bit(BIO_UPTODATE, &bio->bi_flags); | 662 | set_bit(BIO_UPTODATE, &bio->bi_flags); |
685 | bio_endio(bio, 0); | 663 | bio_endio(bio, 0); |
@@ -779,7 +757,7 @@ static int ramzswap_read(struct ramzswap *rzs, struct bio *bio) | |||
779 | goto out; | 757 | goto out; |
780 | } | 758 | } |
781 | 759 | ||
782 | ramzswap_flush_dcache_page(page); | 760 | flush_dcache_page(page); |
783 | 761 | ||
784 | set_bit(BIO_UPTODATE, &bio->bi_flags); | 762 | set_bit(BIO_UPTODATE, &bio->bi_flags); |
785 | bio_endio(bio, 0); | 763 | bio_endio(bio, 0); |
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211.h b/drivers/staging/rtl8187se/ieee80211/ieee80211.h index 3222c22152fb..0d490c164db6 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211.h | |||
@@ -1318,13 +1318,13 @@ extern int ieee80211_encrypt_fragment( | |||
1318 | struct sk_buff *frag, | 1318 | struct sk_buff *frag, |
1319 | int hdr_len); | 1319 | int hdr_len); |
1320 | 1320 | ||
1321 | extern int ieee80211_xmit(struct sk_buff *skb, | 1321 | extern int ieee80211_rtl_xmit(struct sk_buff *skb, |
1322 | struct net_device *dev); | 1322 | struct net_device *dev); |
1323 | extern void ieee80211_txb_free(struct ieee80211_txb *); | 1323 | extern void ieee80211_txb_free(struct ieee80211_txb *); |
1324 | 1324 | ||
1325 | 1325 | ||
1326 | /* ieee80211_rx.c */ | 1326 | /* ieee80211_rx.c */ |
1327 | extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, | 1327 | extern int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, |
1328 | struct ieee80211_rx_stats *rx_stats); | 1328 | struct ieee80211_rx_stats *rx_stats); |
1329 | extern void ieee80211_rx_mgt(struct ieee80211_device *ieee, | 1329 | extern void ieee80211_rx_mgt(struct ieee80211_device *ieee, |
1330 | struct ieee80211_hdr_4addr *header, | 1330 | struct ieee80211_hdr_4addr *header, |
@@ -1376,8 +1376,8 @@ extern void ieee80211_stop_protocol(struct ieee80211_device *ieee); | |||
1376 | extern void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee); | 1376 | extern void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee); |
1377 | extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee); | 1377 | extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee); |
1378 | extern void ieee80211_reset_queue(struct ieee80211_device *ieee); | 1378 | extern void ieee80211_reset_queue(struct ieee80211_device *ieee); |
1379 | extern void ieee80211_wake_queue(struct ieee80211_device *ieee); | 1379 | extern void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee); |
1380 | extern void ieee80211_stop_queue(struct ieee80211_device *ieee); | 1380 | extern void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee); |
1381 | extern struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee); | 1381 | extern struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee); |
1382 | extern void ieee80211_start_send_beacons(struct ieee80211_device *ieee); | 1382 | extern void ieee80211_start_send_beacons(struct ieee80211_device *ieee); |
1383 | extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee); | 1383 | extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee); |
@@ -1385,7 +1385,7 @@ extern int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct | |||
1385 | extern void notify_wx_assoc_event(struct ieee80211_device *ieee); | 1385 | extern void notify_wx_assoc_event(struct ieee80211_device *ieee); |
1386 | extern void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success); | 1386 | extern void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success); |
1387 | extern void SendDisassociation(struct ieee80211_device *ieee,u8* asSta,u8 asRsn); | 1387 | extern void SendDisassociation(struct ieee80211_device *ieee,u8* asSta,u8 asRsn); |
1388 | extern void ieee80211_start_scan(struct ieee80211_device *ieee); | 1388 | extern void ieee80211_rtl_start_scan(struct ieee80211_device *ieee); |
1389 | 1389 | ||
1390 | //Add for RF power on power off by lizhaoming 080512 | 1390 | //Add for RF power on power off by lizhaoming 080512 |
1391 | extern void SendDisassociation(struct ieee80211_device *ieee, | 1391 | extern void SendDisassociation(struct ieee80211_device *ieee, |
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c index f882dd8cf9b5..9128c181bc7d 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c | |||
@@ -469,7 +469,7 @@ drop: | |||
469 | /* All received frames are sent to this function. @skb contains the frame in | 469 | /* All received frames are sent to this function. @skb contains the frame in |
470 | * IEEE 802.11 format, i.e., in the format it was sent over air. | 470 | * IEEE 802.11 format, i.e., in the format it was sent over air. |
471 | * This function is called only as a tasklet (software IRQ). */ | 471 | * This function is called only as a tasklet (software IRQ). */ |
472 | int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, | 472 | int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, |
473 | struct ieee80211_rx_stats *rx_stats) | 473 | struct ieee80211_rx_stats *rx_stats) |
474 | { | 474 | { |
475 | struct net_device *dev = ieee->dev; | 475 | struct net_device *dev = ieee->dev; |
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c index 1fe19c39d702..c7c645af0ebb 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c | |||
@@ -689,7 +689,7 @@ void ieee80211_stop_scan(struct ieee80211_device *ieee) | |||
689 | } | 689 | } |
690 | 690 | ||
691 | /* called with ieee->lock held */ | 691 | /* called with ieee->lock held */ |
692 | void ieee80211_start_scan(struct ieee80211_device *ieee) | 692 | void ieee80211_rtl_start_scan(struct ieee80211_device *ieee) |
693 | { | 693 | { |
694 | if(IS_DOT11D_ENABLE(ieee) ) | 694 | if(IS_DOT11D_ENABLE(ieee) ) |
695 | { | 695 | { |
@@ -1196,7 +1196,7 @@ void ieee80211_associate_step1(struct ieee80211_device *ieee) | |||
1196 | } | 1196 | } |
1197 | } | 1197 | } |
1198 | 1198 | ||
1199 | void ieee80211_auth_challenge(struct ieee80211_device *ieee, u8 *challenge, int chlen) | 1199 | void ieee80211_rtl_auth_challenge(struct ieee80211_device *ieee, u8 *challenge, int chlen) |
1200 | { | 1200 | { |
1201 | u8 *c; | 1201 | u8 *c; |
1202 | struct sk_buff *skb; | 1202 | struct sk_buff *skb; |
@@ -1898,7 +1898,7 @@ associate_complete: | |||
1898 | 1898 | ||
1899 | ieee80211_associate_step2(ieee); | 1899 | ieee80211_associate_step2(ieee); |
1900 | }else{ | 1900 | }else{ |
1901 | ieee80211_auth_challenge(ieee, challenge, chlen); | 1901 | ieee80211_rtl_auth_challenge(ieee, challenge, chlen); |
1902 | } | 1902 | } |
1903 | }else{ | 1903 | }else{ |
1904 | ieee->softmac_stats.rx_auth_rs_err++; | 1904 | ieee->softmac_stats.rx_auth_rs_err++; |
@@ -2047,7 +2047,7 @@ void ieee80211_reset_queue(struct ieee80211_device *ieee) | |||
2047 | 2047 | ||
2048 | } | 2048 | } |
2049 | 2049 | ||
2050 | void ieee80211_wake_queue(struct ieee80211_device *ieee) | 2050 | void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee) |
2051 | { | 2051 | { |
2052 | 2052 | ||
2053 | unsigned long flags; | 2053 | unsigned long flags; |
@@ -2089,7 +2089,7 @@ exit : | |||
2089 | } | 2089 | } |
2090 | 2090 | ||
2091 | 2091 | ||
2092 | void ieee80211_stop_queue(struct ieee80211_device *ieee) | 2092 | void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee) |
2093 | { | 2093 | { |
2094 | //unsigned long flags; | 2094 | //unsigned long flags; |
2095 | //spin_lock_irqsave(&ieee->lock,flags); | 2095 | //spin_lock_irqsave(&ieee->lock,flags); |
@@ -2301,7 +2301,7 @@ void ieee80211_start_bss(struct ieee80211_device *ieee) | |||
2301 | //#else | 2301 | //#else |
2302 | if (ieee->state == IEEE80211_NOLINK){ | 2302 | if (ieee->state == IEEE80211_NOLINK){ |
2303 | ieee->actscanning = true; | 2303 | ieee->actscanning = true; |
2304 | ieee80211_start_scan(ieee); | 2304 | ieee80211_rtl_start_scan(ieee); |
2305 | } | 2305 | } |
2306 | //#endif | 2306 | //#endif |
2307 | spin_unlock_irqrestore(&ieee->lock, flags); | 2307 | spin_unlock_irqrestore(&ieee->lock, flags); |
@@ -2357,7 +2357,7 @@ void ieee80211_associate_retry_wq(struct work_struct *work) | |||
2357 | if(ieee->state == IEEE80211_NOLINK){ | 2357 | if(ieee->state == IEEE80211_NOLINK){ |
2358 | ieee->beinretry = false; | 2358 | ieee->beinretry = false; |
2359 | ieee->actscanning = true; | 2359 | ieee->actscanning = true; |
2360 | ieee80211_start_scan(ieee); | 2360 | ieee80211_rtl_start_scan(ieee); |
2361 | } | 2361 | } |
2362 | //YJ,add,080828, notify os here | 2362 | //YJ,add,080828, notify os here |
2363 | if(ieee->state == IEEE80211_NOLINK) | 2363 | if(ieee->state == IEEE80211_NOLINK) |
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c index dde1f2e0cf32..69bd02164b0c 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c | |||
@@ -304,7 +304,7 @@ ieee80211_classify(struct sk_buff *skb, struct ieee80211_network *network) | |||
304 | } | 304 | } |
305 | 305 | ||
306 | /* SKBs are added to the ieee->tx_queue. */ | 306 | /* SKBs are added to the ieee->tx_queue. */ |
307 | int ieee80211_xmit(struct sk_buff *skb, | 307 | int ieee80211_rtl_xmit(struct sk_buff *skb, |
308 | struct net_device *dev) | 308 | struct net_device *dev) |
309 | { | 309 | { |
310 | struct ieee80211_device *ieee = netdev_priv(dev); | 310 | struct ieee80211_device *ieee = netdev_priv(dev); |
diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c index 57c62b0a402f..e0f13efdb15a 100644 --- a/drivers/staging/rtl8187se/r8180_core.c +++ b/drivers/staging/rtl8187se/r8180_core.c | |||
@@ -1811,7 +1811,7 @@ void rtl8180_rx(struct net_device *dev) | |||
1811 | if(priv->rx_skb->len > 4) | 1811 | if(priv->rx_skb->len > 4) |
1812 | skb_trim(priv->rx_skb,priv->rx_skb->len-4); | 1812 | skb_trim(priv->rx_skb,priv->rx_skb->len-4); |
1813 | #ifndef RX_DONT_PASS_UL | 1813 | #ifndef RX_DONT_PASS_UL |
1814 | if(!ieee80211_rx(priv->ieee80211, | 1814 | if(!ieee80211_rtl_rx(priv->ieee80211, |
1815 | priv->rx_skb, &stats)){ | 1815 | priv->rx_skb, &stats)){ |
1816 | #endif // RX_DONT_PASS_UL | 1816 | #endif // RX_DONT_PASS_UL |
1817 | 1817 | ||
@@ -1917,11 +1917,11 @@ rate) | |||
1917 | if (!check_nic_enought_desc(dev, priority)){ | 1917 | if (!check_nic_enought_desc(dev, priority)){ |
1918 | DMESGW("Error: no descriptor left by previous TX (avail %d) ", | 1918 | DMESGW("Error: no descriptor left by previous TX (avail %d) ", |
1919 | get_curr_tx_free_desc(dev, priority)); | 1919 | get_curr_tx_free_desc(dev, priority)); |
1920 | ieee80211_stop_queue(priv->ieee80211); | 1920 | ieee80211_rtl_stop_queue(priv->ieee80211); |
1921 | } | 1921 | } |
1922 | rtl8180_tx(dev, skb->data, skb->len, priority, morefrag,0,rate); | 1922 | rtl8180_tx(dev, skb->data, skb->len, priority, morefrag,0,rate); |
1923 | if (!check_nic_enought_desc(dev, priority)) | 1923 | if (!check_nic_enought_desc(dev, priority)) |
1924 | ieee80211_stop_queue(priv->ieee80211); | 1924 | ieee80211_rtl_stop_queue(priv->ieee80211); |
1925 | 1925 | ||
1926 | spin_unlock_irqrestore(&priv->tx_lock,flags); | 1926 | spin_unlock_irqrestore(&priv->tx_lock,flags); |
1927 | } | 1927 | } |
@@ -3680,7 +3680,7 @@ static const struct net_device_ops rtl8180_netdev_ops = { | |||
3680 | .ndo_set_mac_address = r8180_set_mac_adr, | 3680 | .ndo_set_mac_address = r8180_set_mac_adr, |
3681 | .ndo_validate_addr = eth_validate_addr, | 3681 | .ndo_validate_addr = eth_validate_addr, |
3682 | .ndo_change_mtu = eth_change_mtu, | 3682 | .ndo_change_mtu = eth_change_mtu, |
3683 | .ndo_start_xmit = ieee80211_xmit, | 3683 | .ndo_start_xmit = ieee80211_rtl_xmit, |
3684 | }; | 3684 | }; |
3685 | 3685 | ||
3686 | static int __devinit rtl8180_pci_probe(struct pci_dev *pdev, | 3686 | static int __devinit rtl8180_pci_probe(struct pci_dev *pdev, |
@@ -3900,7 +3900,7 @@ void rtl8180_try_wake_queue(struct net_device *dev, int pri) | |||
3900 | spin_unlock_irqrestore(&priv->tx_lock,flags); | 3900 | spin_unlock_irqrestore(&priv->tx_lock,flags); |
3901 | 3901 | ||
3902 | if(enough_desc) | 3902 | if(enough_desc) |
3903 | ieee80211_wake_queue(priv->ieee80211); | 3903 | ieee80211_rtl_wake_queue(priv->ieee80211); |
3904 | } | 3904 | } |
3905 | 3905 | ||
3906 | void rtl8180_tx_isr(struct net_device *dev, int pri,short error) | 3906 | void rtl8180_tx_isr(struct net_device *dev, int pri,short error) |
diff --git a/drivers/staging/rtl8187se/r8180_wx.c b/drivers/staging/rtl8187se/r8180_wx.c index 536cb6e8e796..124cde356cbc 100644 --- a/drivers/staging/rtl8187se/r8180_wx.c +++ b/drivers/staging/rtl8187se/r8180_wx.c | |||
@@ -377,7 +377,7 @@ static int r8180_wx_set_scan(struct net_device *dev, struct iw_request_info *a, | |||
377 | // queue_work(priv->ieee80211->wq, &priv->ieee80211->wx_sync_scan_wq); | 377 | // queue_work(priv->ieee80211->wq, &priv->ieee80211->wx_sync_scan_wq); |
378 | //printk("start scan============================>\n"); | 378 | //printk("start scan============================>\n"); |
379 | ieee80211_softmac_ips_scan_syncro(priv->ieee80211); | 379 | ieee80211_softmac_ips_scan_syncro(priv->ieee80211); |
380 | //ieee80211_start_scan(priv->ieee80211); | 380 | //ieee80211_rtl_start_scan(priv->ieee80211); |
381 | /* intentionally forget to up sem */ | 381 | /* intentionally forget to up sem */ |
382 | // up(&priv->ieee80211->wx_sem); | 382 | // up(&priv->ieee80211->wx_sem); |
383 | ret = 0; | 383 | ret = 0; |
diff --git a/drivers/staging/rtl8192e/ieee80211.h b/drivers/staging/rtl8192e/ieee80211.h index 97137ddefff4..3ba9e9e90bda 100644 --- a/drivers/staging/rtl8192e/ieee80211.h +++ b/drivers/staging/rtl8192e/ieee80211.h | |||
@@ -303,8 +303,8 @@ enum _ReasonCode{ | |||
303 | #define ieee80211_rx_mgt ieee80211_rx_mgt_rsl | 303 | #define ieee80211_rx_mgt ieee80211_rx_mgt_rsl |
304 | 304 | ||
305 | #define ieee80211_get_beacon ieee80211_get_beacon_rsl | 305 | #define ieee80211_get_beacon ieee80211_get_beacon_rsl |
306 | #define ieee80211_wake_queue ieee80211_wake_queue_rsl | 306 | #define ieee80211_rtl_wake_queue ieee80211_rtl_wake_queue_rsl |
307 | #define ieee80211_stop_queue ieee80211_stop_queue_rsl | 307 | #define ieee80211_rtl_stop_queue ieee80211_rtl_stop_queue_rsl |
308 | #define ieee80211_reset_queue ieee80211_reset_queue_rsl | 308 | #define ieee80211_reset_queue ieee80211_reset_queue_rsl |
309 | #define ieee80211_softmac_stop_protocol ieee80211_softmac_stop_protocol_rsl | 309 | #define ieee80211_softmac_stop_protocol ieee80211_softmac_stop_protocol_rsl |
310 | #define ieee80211_softmac_start_protocol ieee80211_softmac_start_protocol_rsl | 310 | #define ieee80211_softmac_start_protocol ieee80211_softmac_start_protocol_rsl |
@@ -2435,13 +2435,13 @@ extern int ieee80211_encrypt_fragment( | |||
2435 | struct sk_buff *frag, | 2435 | struct sk_buff *frag, |
2436 | int hdr_len); | 2436 | int hdr_len); |
2437 | 2437 | ||
2438 | extern int ieee80211_xmit(struct sk_buff *skb, | 2438 | extern int ieee80211_rtl_xmit(struct sk_buff *skb, |
2439 | struct net_device *dev); | 2439 | struct net_device *dev); |
2440 | extern void ieee80211_txb_free(struct ieee80211_txb *); | 2440 | extern void ieee80211_txb_free(struct ieee80211_txb *); |
2441 | 2441 | ||
2442 | 2442 | ||
2443 | /* ieee80211_rx.c */ | 2443 | /* ieee80211_rx.c */ |
2444 | extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, | 2444 | extern int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, |
2445 | struct ieee80211_rx_stats *rx_stats); | 2445 | struct ieee80211_rx_stats *rx_stats); |
2446 | extern void ieee80211_rx_mgt(struct ieee80211_device *ieee, | 2446 | extern void ieee80211_rx_mgt(struct ieee80211_device *ieee, |
2447 | struct ieee80211_hdr_4addr *header, | 2447 | struct ieee80211_hdr_4addr *header, |
@@ -2502,8 +2502,8 @@ extern void ieee80211_stop_protocol(struct ieee80211_device *ieee); | |||
2502 | extern void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee); | 2502 | extern void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee); |
2503 | extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee); | 2503 | extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee); |
2504 | extern void ieee80211_reset_queue(struct ieee80211_device *ieee); | 2504 | extern void ieee80211_reset_queue(struct ieee80211_device *ieee); |
2505 | extern void ieee80211_wake_queue(struct ieee80211_device *ieee); | 2505 | extern void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee); |
2506 | extern void ieee80211_stop_queue(struct ieee80211_device *ieee); | 2506 | extern void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee); |
2507 | extern struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee); | 2507 | extern struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee); |
2508 | extern void ieee80211_start_send_beacons(struct ieee80211_device *ieee); | 2508 | extern void ieee80211_start_send_beacons(struct ieee80211_device *ieee); |
2509 | extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee); | 2509 | extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee); |
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211.h b/drivers/staging/rtl8192e/ieee80211/ieee80211.h index 83c8452de378..aa76390487bb 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211.h | |||
@@ -333,8 +333,8 @@ enum _ReasonCode{ | |||
333 | #define ieee80211_rx_mgt ieee80211_rx_mgt_rsl | 333 | #define ieee80211_rx_mgt ieee80211_rx_mgt_rsl |
334 | 334 | ||
335 | #define ieee80211_get_beacon ieee80211_get_beacon_rsl | 335 | #define ieee80211_get_beacon ieee80211_get_beacon_rsl |
336 | #define ieee80211_wake_queue ieee80211_wake_queue_rsl | 336 | #define ieee80211_rtl_wake_queue ieee80211_rtl_wake_queue_rsl |
337 | #define ieee80211_stop_queue ieee80211_stop_queue_rsl | 337 | #define ieee80211_rtl_stop_queue ieee80211_rtl_stop_queue_rsl |
338 | #define ieee80211_reset_queue ieee80211_reset_queue_rsl | 338 | #define ieee80211_reset_queue ieee80211_reset_queue_rsl |
339 | #define ieee80211_softmac_stop_protocol ieee80211_softmac_stop_protocol_rsl | 339 | #define ieee80211_softmac_stop_protocol ieee80211_softmac_stop_protocol_rsl |
340 | #define ieee80211_softmac_start_protocol ieee80211_softmac_start_protocol_rsl | 340 | #define ieee80211_softmac_start_protocol ieee80211_softmac_start_protocol_rsl |
@@ -2546,13 +2546,13 @@ extern int ieee80211_encrypt_fragment( | |||
2546 | struct sk_buff *frag, | 2546 | struct sk_buff *frag, |
2547 | int hdr_len); | 2547 | int hdr_len); |
2548 | 2548 | ||
2549 | extern int ieee80211_xmit(struct sk_buff *skb, | 2549 | extern int ieee80211_rtl_xmit(struct sk_buff *skb, |
2550 | struct net_device *dev); | 2550 | struct net_device *dev); |
2551 | extern void ieee80211_txb_free(struct ieee80211_txb *); | 2551 | extern void ieee80211_txb_free(struct ieee80211_txb *); |
2552 | 2552 | ||
2553 | 2553 | ||
2554 | /* ieee80211_rx.c */ | 2554 | /* ieee80211_rx.c */ |
2555 | extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, | 2555 | extern int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, |
2556 | struct ieee80211_rx_stats *rx_stats); | 2556 | struct ieee80211_rx_stats *rx_stats); |
2557 | extern void ieee80211_rx_mgt(struct ieee80211_device *ieee, | 2557 | extern void ieee80211_rx_mgt(struct ieee80211_device *ieee, |
2558 | struct ieee80211_hdr_4addr *header, | 2558 | struct ieee80211_hdr_4addr *header, |
@@ -2613,8 +2613,8 @@ extern void ieee80211_stop_protocol(struct ieee80211_device *ieee); | |||
2613 | extern void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee); | 2613 | extern void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee); |
2614 | extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee); | 2614 | extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee); |
2615 | extern void ieee80211_reset_queue(struct ieee80211_device *ieee); | 2615 | extern void ieee80211_reset_queue(struct ieee80211_device *ieee); |
2616 | extern void ieee80211_wake_queue(struct ieee80211_device *ieee); | 2616 | extern void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee); |
2617 | extern void ieee80211_stop_queue(struct ieee80211_device *ieee); | 2617 | extern void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee); |
2618 | extern struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee); | 2618 | extern struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee); |
2619 | extern void ieee80211_start_send_beacons(struct ieee80211_device *ieee); | 2619 | extern void ieee80211_start_send_beacons(struct ieee80211_device *ieee); |
2620 | extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee); | 2620 | extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee); |
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c index 2644155737a8..f43a7db5c78b 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c | |||
@@ -119,7 +119,7 @@ struct net_device *alloc_ieee80211(int sizeof_priv) | |||
119 | ieee = (struct ieee80211_device *)dev->priv; | 119 | ieee = (struct ieee80211_device *)dev->priv; |
120 | #endif | 120 | #endif |
121 | #if 0 | 121 | #if 0 |
122 | dev->hard_start_xmit = ieee80211_xmit; | 122 | dev->hard_start_xmit = ieee80211_rtl_xmit; |
123 | #endif | 123 | #endif |
124 | 124 | ||
125 | memset(ieee, 0, sizeof(struct ieee80211_device)+sizeof_priv); | 125 | memset(ieee, 0, sizeof(struct ieee80211_device)+sizeof_priv); |
@@ -333,7 +333,7 @@ extern void ieee80211_crypto_ccmp_exit(void); | |||
333 | extern int ieee80211_crypto_wep_init(void); | 333 | extern int ieee80211_crypto_wep_init(void); |
334 | extern void ieee80211_crypto_wep_exit(void); | 334 | extern void ieee80211_crypto_wep_exit(void); |
335 | 335 | ||
336 | int __init ieee80211_init(void) | 336 | int __init ieee80211_rtl_init(void) |
337 | { | 337 | { |
338 | struct proc_dir_entry *e; | 338 | struct proc_dir_entry *e; |
339 | int retval; | 339 | int retval; |
@@ -389,7 +389,7 @@ int __init ieee80211_init(void) | |||
389 | return 0; | 389 | return 0; |
390 | } | 390 | } |
391 | 391 | ||
392 | void __exit ieee80211_exit(void) | 392 | void __exit ieee80211_rtl_exit(void) |
393 | { | 393 | { |
394 | if (ieee80211_proc) { | 394 | if (ieee80211_proc) { |
395 | remove_proc_entry("debug_level", ieee80211_proc); | 395 | remove_proc_entry("debug_level", ieee80211_proc); |
@@ -412,8 +412,8 @@ module_param(debug, int, 0444); | |||
412 | MODULE_PARM_DESC(debug, "debug output mask"); | 412 | MODULE_PARM_DESC(debug, "debug output mask"); |
413 | 413 | ||
414 | 414 | ||
415 | //module_exit(ieee80211_exit); | 415 | //module_exit(ieee80211_rtl_exit); |
416 | //module_init(ieee80211_init); | 416 | //module_init(ieee80211_rtl_init); |
417 | #endif | 417 | #endif |
418 | #endif | 418 | #endif |
419 | 419 | ||
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c index 5dc478b86375..06d91715143c 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c | |||
@@ -923,7 +923,7 @@ u8 parse_subframe(struct sk_buff *skb, | |||
923 | /* All received frames are sent to this function. @skb contains the frame in | 923 | /* All received frames are sent to this function. @skb contains the frame in |
924 | * IEEE 802.11 format, i.e., in the format it was sent over air. | 924 | * IEEE 802.11 format, i.e., in the format it was sent over air. |
925 | * This function is called only as a tasklet (software IRQ). */ | 925 | * This function is called only as a tasklet (software IRQ). */ |
926 | int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, | 926 | int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, |
927 | struct ieee80211_rx_stats *rx_stats) | 927 | struct ieee80211_rx_stats *rx_stats) |
928 | { | 928 | { |
929 | struct net_device *dev = ieee->dev; | 929 | struct net_device *dev = ieee->dev; |
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c index 593d22825184..6d1ddec39f0e 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c | |||
@@ -684,7 +684,7 @@ void ieee80211_stop_scan(struct ieee80211_device *ieee) | |||
684 | } | 684 | } |
685 | 685 | ||
686 | /* called with ieee->lock held */ | 686 | /* called with ieee->lock held */ |
687 | void ieee80211_start_scan(struct ieee80211_device *ieee) | 687 | void ieee80211_rtl_start_scan(struct ieee80211_device *ieee) |
688 | { | 688 | { |
689 | #ifdef ENABLE_DOT11D | 689 | #ifdef ENABLE_DOT11D |
690 | if(IS_DOT11D_ENABLE(ieee) ) | 690 | if(IS_DOT11D_ENABLE(ieee) ) |
@@ -1430,7 +1430,7 @@ void ieee80211_associate_step1(struct ieee80211_device *ieee) | |||
1430 | } | 1430 | } |
1431 | } | 1431 | } |
1432 | 1432 | ||
1433 | void ieee80211_auth_challenge(struct ieee80211_device *ieee, u8 *challenge, int chlen) | 1433 | void ieee80211_rtl_auth_challenge(struct ieee80211_device *ieee, u8 *challenge, int chlen) |
1434 | { | 1434 | { |
1435 | u8 *c; | 1435 | u8 *c; |
1436 | struct sk_buff *skb; | 1436 | struct sk_buff *skb; |
@@ -2262,7 +2262,7 @@ ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb, | |||
2262 | 2262 | ||
2263 | ieee80211_associate_step2(ieee); | 2263 | ieee80211_associate_step2(ieee); |
2264 | }else{ | 2264 | }else{ |
2265 | ieee80211_auth_challenge(ieee, challenge, chlen); | 2265 | ieee80211_rtl_auth_challenge(ieee, challenge, chlen); |
2266 | } | 2266 | } |
2267 | }else{ | 2267 | }else{ |
2268 | ieee->softmac_stats.rx_auth_rs_err++; | 2268 | ieee->softmac_stats.rx_auth_rs_err++; |
@@ -2376,7 +2376,7 @@ void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device * | |||
2376 | * to check it any more. | 2376 | * to check it any more. |
2377 | * */ | 2377 | * */ |
2378 | //printk("error:no descriptor left@queue_index %d\n", queue_index); | 2378 | //printk("error:no descriptor left@queue_index %d\n", queue_index); |
2379 | //ieee80211_stop_queue(ieee); | 2379 | //ieee80211_rtl_stop_queue(ieee); |
2380 | #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE | 2380 | #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE |
2381 | skb_queue_tail(&ieee->skb_drv_aggQ[queue_index], txb->fragments[i]); | 2381 | skb_queue_tail(&ieee->skb_drv_aggQ[queue_index], txb->fragments[i]); |
2382 | #else | 2382 | #else |
@@ -2440,7 +2440,7 @@ void ieee80211_reset_queue(struct ieee80211_device *ieee) | |||
2440 | 2440 | ||
2441 | } | 2441 | } |
2442 | 2442 | ||
2443 | void ieee80211_wake_queue(struct ieee80211_device *ieee) | 2443 | void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee) |
2444 | { | 2444 | { |
2445 | 2445 | ||
2446 | unsigned long flags; | 2446 | unsigned long flags; |
@@ -2481,7 +2481,7 @@ exit : | |||
2481 | } | 2481 | } |
2482 | 2482 | ||
2483 | 2483 | ||
2484 | void ieee80211_stop_queue(struct ieee80211_device *ieee) | 2484 | void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee) |
2485 | { | 2485 | { |
2486 | //unsigned long flags; | 2486 | //unsigned long flags; |
2487 | //spin_lock_irqsave(&ieee->lock,flags); | 2487 | //spin_lock_irqsave(&ieee->lock,flags); |
@@ -2706,7 +2706,7 @@ void ieee80211_start_bss(struct ieee80211_device *ieee) | |||
2706 | 2706 | ||
2707 | if (ieee->state == IEEE80211_NOLINK){ | 2707 | if (ieee->state == IEEE80211_NOLINK){ |
2708 | ieee->actscanning = true; | 2708 | ieee->actscanning = true; |
2709 | ieee80211_start_scan(ieee); | 2709 | ieee80211_rtl_start_scan(ieee); |
2710 | } | 2710 | } |
2711 | spin_unlock_irqrestore(&ieee->lock, flags); | 2711 | spin_unlock_irqrestore(&ieee->lock, flags); |
2712 | } | 2712 | } |
@@ -2775,7 +2775,7 @@ void ieee80211_associate_retry_wq(struct ieee80211_device *ieee) | |||
2775 | { | 2775 | { |
2776 | ieee->is_roaming= false; | 2776 | ieee->is_roaming= false; |
2777 | ieee->actscanning = true; | 2777 | ieee->actscanning = true; |
2778 | ieee80211_start_scan(ieee); | 2778 | ieee80211_rtl_start_scan(ieee); |
2779 | } | 2779 | } |
2780 | spin_unlock_irqrestore(&ieee->lock, flags); | 2780 | spin_unlock_irqrestore(&ieee->lock, flags); |
2781 | 2781 | ||
@@ -3497,8 +3497,8 @@ void notify_wx_assoc_event(struct ieee80211_device *ieee) | |||
3497 | 3497 | ||
3498 | #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) | 3498 | #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) |
3499 | //EXPORT_SYMBOL(ieee80211_get_beacon); | 3499 | //EXPORT_SYMBOL(ieee80211_get_beacon); |
3500 | //EXPORT_SYMBOL(ieee80211_wake_queue); | 3500 | //EXPORT_SYMBOL(ieee80211_rtl_wake_queue); |
3501 | //EXPORT_SYMBOL(ieee80211_stop_queue); | 3501 | //EXPORT_SYMBOL(ieee80211_rtl_stop_queue); |
3502 | //EXPORT_SYMBOL(ieee80211_reset_queue); | 3502 | //EXPORT_SYMBOL(ieee80211_reset_queue); |
3503 | //EXPORT_SYMBOL(ieee80211_softmac_stop_protocol); | 3503 | //EXPORT_SYMBOL(ieee80211_softmac_stop_protocol); |
3504 | //EXPORT_SYMBOL(ieee80211_softmac_start_protocol); | 3504 | //EXPORT_SYMBOL(ieee80211_softmac_start_protocol); |
@@ -3518,8 +3518,8 @@ void notify_wx_assoc_event(struct ieee80211_device *ieee) | |||
3518 | //EXPORT_SYMBOL(ieee80211_start_scan_syncro); | 3518 | //EXPORT_SYMBOL(ieee80211_start_scan_syncro); |
3519 | #else | 3519 | #else |
3520 | EXPORT_SYMBOL_NOVERS(ieee80211_get_beacon); | 3520 | EXPORT_SYMBOL_NOVERS(ieee80211_get_beacon); |
3521 | EXPORT_SYMBOL_NOVERS(ieee80211_wake_queue); | 3521 | EXPORT_SYMBOL_NOVERS(ieee80211_rtl_wake_queue); |
3522 | EXPORT_SYMBOL_NOVERS(ieee80211_stop_queue); | 3522 | EXPORT_SYMBOL_NOVERS(ieee80211_rtl_stop_queue); |
3523 | EXPORT_SYMBOL_NOVERS(ieee80211_reset_queue); | 3523 | EXPORT_SYMBOL_NOVERS(ieee80211_reset_queue); |
3524 | EXPORT_SYMBOL_NOVERS(ieee80211_softmac_stop_protocol); | 3524 | EXPORT_SYMBOL_NOVERS(ieee80211_softmac_stop_protocol); |
3525 | EXPORT_SYMBOL_NOVERS(ieee80211_softmac_start_protocol); | 3525 | EXPORT_SYMBOL_NOVERS(ieee80211_softmac_start_protocol); |
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c index 103b33c093f5..798fb4154c25 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c | |||
@@ -604,7 +604,7 @@ void ieee80211_query_seqnum(struct ieee80211_device*ieee, struct sk_buff* skb, u | |||
604 | } | 604 | } |
605 | } | 605 | } |
606 | 606 | ||
607 | int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) | 607 | int ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev) |
608 | { | 608 | { |
609 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) | 609 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) |
610 | struct ieee80211_device *ieee = netdev_priv(dev); | 610 | struct ieee80211_device *ieee = netdev_priv(dev); |
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c index 4e34a1f4c66b..3441b72dd8fa 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c | |||
@@ -976,7 +976,7 @@ int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len) | |||
976 | { | 976 | { |
977 | if (len != ie[1]+2) | 977 | if (len != ie[1]+2) |
978 | { | 978 | { |
979 | printk("len:%d, ie:%d\n", len, ie[1]); | 979 | printk("len:%zu, ie:%d\n", len, ie[1]); |
980 | return -EINVAL; | 980 | return -EINVAL; |
981 | } | 981 | } |
982 | buf = kmalloc(len, GFP_KERNEL); | 982 | buf = kmalloc(len, GFP_KERNEL); |
diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c b/drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c index 98b3bb6b6d69..e41e8a0c739c 100644 --- a/drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c +++ b/drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c | |||
@@ -382,7 +382,7 @@ int ieee80211_rx_ADDBAReq( struct ieee80211_device* ieee, struct sk_buff *skb) | |||
382 | 382 | ||
383 | if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9) | 383 | if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9) |
384 | { | 384 | { |
385 | IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BAREQ(%d / %d)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 9)); | 385 | IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BAREQ(%d / %zu)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 9)); |
386 | return -1; | 386 | return -1; |
387 | } | 387 | } |
388 | 388 | ||
@@ -481,7 +481,7 @@ int ieee80211_rx_ADDBARsp( struct ieee80211_device* ieee, struct sk_buff *skb) | |||
481 | 481 | ||
482 | if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9) | 482 | if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9) |
483 | { | 483 | { |
484 | IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BARSP(%d / %d)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 9)); | 484 | IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BARSP(%d / %zu)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 9)); |
485 | return -1; | 485 | return -1; |
486 | } | 486 | } |
487 | rsp = ( struct ieee80211_hdr_3addr*)skb->data; | 487 | rsp = ( struct ieee80211_hdr_3addr*)skb->data; |
@@ -611,7 +611,7 @@ int ieee80211_rx_DELBA(struct ieee80211_device* ieee,struct sk_buff *skb) | |||
611 | 611 | ||
612 | if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 6) | 612 | if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 6) |
613 | { | 613 | { |
614 | IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in DELBA(%d / %d)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 6)); | 614 | IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in DELBA(%d / %zu)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 6)); |
615 | return -1; | 615 | return -1; |
616 | } | 616 | } |
617 | 617 | ||
diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index ff8fe7e32a92..0ca5d8b4f746 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c | |||
@@ -5795,7 +5795,7 @@ static void rtl8192_rx(struct net_device *dev) | |||
5795 | stats.fragoffset = 0; | 5795 | stats.fragoffset = 0; |
5796 | stats.ntotalfrag = 1; | 5796 | stats.ntotalfrag = 1; |
5797 | 5797 | ||
5798 | if(!ieee80211_rx(priv->ieee80211, skb, &stats)){ | 5798 | if(!ieee80211_rtl_rx(priv->ieee80211, skb, &stats)){ |
5799 | dev_kfree_skb_any(skb); | 5799 | dev_kfree_skb_any(skb); |
5800 | } else { | 5800 | } else { |
5801 | priv->stats.rxok++; | 5801 | priv->stats.rxok++; |
@@ -5837,7 +5837,7 @@ static const struct net_device_ops rtl8192_netdev_ops = { | |||
5837 | .ndo_do_ioctl = rtl8192_ioctl, | 5837 | .ndo_do_ioctl = rtl8192_ioctl, |
5838 | .ndo_set_multicast_list = r8192_set_multicast, | 5838 | .ndo_set_multicast_list = r8192_set_multicast, |
5839 | .ndo_set_mac_address = r8192_set_mac_adr, | 5839 | .ndo_set_mac_address = r8192_set_mac_adr, |
5840 | .ndo_start_xmit = ieee80211_xmit, | 5840 | .ndo_start_xmit = ieee80211_rtl_xmit, |
5841 | }; | 5841 | }; |
5842 | 5842 | ||
5843 | /**************************************************************************** | 5843 | /**************************************************************************** |
@@ -6121,14 +6121,14 @@ static void __devexit rtl8192_pci_disconnect(struct pci_dev *pdev) | |||
6121 | RT_TRACE(COMP_DOWN, "wlan driver removed\n"); | 6121 | RT_TRACE(COMP_DOWN, "wlan driver removed\n"); |
6122 | } | 6122 | } |
6123 | 6123 | ||
6124 | extern int ieee80211_init(void); | 6124 | extern int ieee80211_rtl_init(void); |
6125 | extern void ieee80211_exit(void); | 6125 | extern void ieee80211_rtl_exit(void); |
6126 | 6126 | ||
6127 | static int __init rtl8192_pci_module_init(void) | 6127 | static int __init rtl8192_pci_module_init(void) |
6128 | { | 6128 | { |
6129 | int retval; | 6129 | int retval; |
6130 | 6130 | ||
6131 | retval = ieee80211_init(); | 6131 | retval = ieee80211_rtl_init(); |
6132 | if (retval) | 6132 | if (retval) |
6133 | return retval; | 6133 | return retval; |
6134 | 6134 | ||
@@ -6153,7 +6153,7 @@ static void __exit rtl8192_pci_module_exit(void) | |||
6153 | 6153 | ||
6154 | RT_TRACE(COMP_DOWN, "Exiting"); | 6154 | RT_TRACE(COMP_DOWN, "Exiting"); |
6155 | rtl8192_proc_module_remove(); | 6155 | rtl8192_proc_module_remove(); |
6156 | ieee80211_exit(); | 6156 | ieee80211_rtl_exit(); |
6157 | } | 6157 | } |
6158 | 6158 | ||
6159 | //warning message WB | 6159 | //warning message WB |
@@ -6313,7 +6313,7 @@ void rtl8192_try_wake_queue(struct net_device *dev, int pri) | |||
6313 | spin_unlock_irqrestore(&priv->tx_lock,flags); | 6313 | spin_unlock_irqrestore(&priv->tx_lock,flags); |
6314 | 6314 | ||
6315 | if(enough_desc) | 6315 | if(enough_desc) |
6316 | ieee80211_wake_queue(priv->ieee80211); | 6316 | ieee80211_rtl_wake_queue(priv->ieee80211); |
6317 | #endif | 6317 | #endif |
6318 | } | 6318 | } |
6319 | 6319 | ||
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211.h b/drivers/staging/rtl8192su/ieee80211/ieee80211.h index f22d024b1c39..9a4c858b0666 100644 --- a/drivers/staging/rtl8192su/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8192su/ieee80211/ieee80211.h | |||
@@ -1721,13 +1721,13 @@ extern int ieee80211_encrypt_fragment( | |||
1721 | struct sk_buff *frag, | 1721 | struct sk_buff *frag, |
1722 | int hdr_len); | 1722 | int hdr_len); |
1723 | 1723 | ||
1724 | extern int rtl8192_ieee80211_xmit(struct sk_buff *skb, | 1724 | extern int rtl8192_ieee80211_rtl_xmit(struct sk_buff *skb, |
1725 | struct net_device *dev); | 1725 | struct net_device *dev); |
1726 | extern void ieee80211_txb_free(struct ieee80211_txb *); | 1726 | extern void ieee80211_txb_free(struct ieee80211_txb *); |
1727 | 1727 | ||
1728 | 1728 | ||
1729 | /* ieee80211_rx.c */ | 1729 | /* ieee80211_rx.c */ |
1730 | extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, | 1730 | extern int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, |
1731 | struct ieee80211_rx_stats *rx_stats); | 1731 | struct ieee80211_rx_stats *rx_stats); |
1732 | extern void ieee80211_rx_mgt(struct ieee80211_device *ieee, | 1732 | extern void ieee80211_rx_mgt(struct ieee80211_device *ieee, |
1733 | struct ieee80211_hdr_4addr *header, | 1733 | struct ieee80211_hdr_4addr *header, |
@@ -1783,8 +1783,8 @@ extern void ieee80211_stop_protocol(struct ieee80211_device *ieee); | |||
1783 | extern void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee); | 1783 | extern void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee); |
1784 | extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee); | 1784 | extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee); |
1785 | extern void ieee80211_reset_queue(struct ieee80211_device *ieee); | 1785 | extern void ieee80211_reset_queue(struct ieee80211_device *ieee); |
1786 | extern void ieee80211_wake_queue(struct ieee80211_device *ieee); | 1786 | extern void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee); |
1787 | extern void ieee80211_stop_queue(struct ieee80211_device *ieee); | 1787 | extern void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee); |
1788 | extern struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee); | 1788 | extern struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee); |
1789 | extern void ieee80211_start_send_beacons(struct ieee80211_device *ieee); | 1789 | extern void ieee80211_start_send_beacons(struct ieee80211_device *ieee); |
1790 | extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee); | 1790 | extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee); |
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c index ac223cef1d33..fecfa120ff48 100644 --- a/drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c +++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c | |||
@@ -208,7 +208,7 @@ static int ieee80211_frag_cache_invalidate(struct ieee80211_device *ieee, | |||
208 | * | 208 | * |
209 | * Responsible for handling management control frames | 209 | * Responsible for handling management control frames |
210 | * | 210 | * |
211 | * Called by ieee80211_rx */ | 211 | * Called by ieee80211_rtl_rx */ |
212 | static inline int | 212 | static inline int |
213 | ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb, | 213 | ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb, |
214 | struct ieee80211_rx_stats *rx_stats, u16 type, | 214 | struct ieee80211_rx_stats *rx_stats, u16 type, |
@@ -289,7 +289,7 @@ static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee, | |||
289 | return 0; | 289 | return 0; |
290 | } | 290 | } |
291 | 291 | ||
292 | /* Called only as a tasklet (software IRQ), by ieee80211_rx */ | 292 | /* Called only as a tasklet (software IRQ), by ieee80211_rtl_rx */ |
293 | static inline int | 293 | static inline int |
294 | ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb, | 294 | ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb, |
295 | struct ieee80211_crypt_data *crypt) | 295 | struct ieee80211_crypt_data *crypt) |
@@ -858,7 +858,7 @@ u8 parse_subframe(struct sk_buff *skb, | |||
858 | /* All received frames are sent to this function. @skb contains the frame in | 858 | /* All received frames are sent to this function. @skb contains the frame in |
859 | * IEEE 802.11 format, i.e., in the format it was sent over air. | 859 | * IEEE 802.11 format, i.e., in the format it was sent over air. |
860 | * This function is called only as a tasklet (software IRQ). */ | 860 | * This function is called only as a tasklet (software IRQ). */ |
861 | int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, | 861 | int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, |
862 | struct ieee80211_rx_stats *rx_stats) | 862 | struct ieee80211_rx_stats *rx_stats) |
863 | { | 863 | { |
864 | struct net_device *dev = ieee->dev; | 864 | struct net_device *dev = ieee->dev; |
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c index 203c0a5cc8c1..95d4f84dcf3f 100644 --- a/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c | |||
@@ -610,7 +610,7 @@ void ieee80211_stop_scan(struct ieee80211_device *ieee) | |||
610 | } | 610 | } |
611 | 611 | ||
612 | /* called with ieee->lock held */ | 612 | /* called with ieee->lock held */ |
613 | void ieee80211_start_scan(struct ieee80211_device *ieee) | 613 | void ieee80211_rtl_start_scan(struct ieee80211_device *ieee) |
614 | { | 614 | { |
615 | if(IS_DOT11D_ENABLE(ieee) ) | 615 | if(IS_DOT11D_ENABLE(ieee) ) |
616 | { | 616 | { |
@@ -1281,7 +1281,7 @@ void ieee80211_associate_step1(struct ieee80211_device *ieee) | |||
1281 | } | 1281 | } |
1282 | } | 1282 | } |
1283 | 1283 | ||
1284 | void ieee80211_auth_challenge(struct ieee80211_device *ieee, u8 *challenge, int chlen) | 1284 | void ieee80211_rtl_auth_challenge(struct ieee80211_device *ieee, u8 *challenge, int chlen) |
1285 | { | 1285 | { |
1286 | u8 *c; | 1286 | u8 *c; |
1287 | struct sk_buff *skb; | 1287 | struct sk_buff *skb; |
@@ -2054,7 +2054,7 @@ ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb, | |||
2054 | 2054 | ||
2055 | ieee80211_associate_step2(ieee); | 2055 | ieee80211_associate_step2(ieee); |
2056 | }else{ | 2056 | }else{ |
2057 | ieee80211_auth_challenge(ieee, challenge, chlen); | 2057 | ieee80211_rtl_auth_challenge(ieee, challenge, chlen); |
2058 | } | 2058 | } |
2059 | }else{ | 2059 | }else{ |
2060 | ieee->softmac_stats.rx_auth_rs_err++; | 2060 | ieee->softmac_stats.rx_auth_rs_err++; |
@@ -2162,7 +2162,7 @@ void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device * | |||
2162 | * to check it any more. | 2162 | * to check it any more. |
2163 | * */ | 2163 | * */ |
2164 | //printk("error:no descriptor left@queue_index %d, %d, %d\n", queue_index, skb_queue_len(&ieee->skb_waitQ[queue_index]), ieee->check_nic_enough_desc(ieee->dev,queue_index)); | 2164 | //printk("error:no descriptor left@queue_index %d, %d, %d\n", queue_index, skb_queue_len(&ieee->skb_waitQ[queue_index]), ieee->check_nic_enough_desc(ieee->dev,queue_index)); |
2165 | //ieee80211_stop_queue(ieee); | 2165 | //ieee80211_rtl_stop_queue(ieee); |
2166 | skb_queue_tail(&ieee->skb_waitQ[queue_index], txb->fragments[i]); | 2166 | skb_queue_tail(&ieee->skb_waitQ[queue_index], txb->fragments[i]); |
2167 | }else{ | 2167 | }else{ |
2168 | ieee->softmac_data_hard_start_xmit( | 2168 | ieee->softmac_data_hard_start_xmit( |
@@ -2222,7 +2222,7 @@ void ieee80211_reset_queue(struct ieee80211_device *ieee) | |||
2222 | 2222 | ||
2223 | } | 2223 | } |
2224 | 2224 | ||
2225 | void ieee80211_wake_queue(struct ieee80211_device *ieee) | 2225 | void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee) |
2226 | { | 2226 | { |
2227 | 2227 | ||
2228 | unsigned long flags; | 2228 | unsigned long flags; |
@@ -2263,7 +2263,7 @@ exit : | |||
2263 | } | 2263 | } |
2264 | 2264 | ||
2265 | 2265 | ||
2266 | void ieee80211_stop_queue(struct ieee80211_device *ieee) | 2266 | void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee) |
2267 | { | 2267 | { |
2268 | //unsigned long flags; | 2268 | //unsigned long flags; |
2269 | //spin_lock_irqsave(&ieee->lock,flags); | 2269 | //spin_lock_irqsave(&ieee->lock,flags); |
@@ -2479,7 +2479,7 @@ void ieee80211_start_bss(struct ieee80211_device *ieee) | |||
2479 | 2479 | ||
2480 | if (ieee->state == IEEE80211_NOLINK){ | 2480 | if (ieee->state == IEEE80211_NOLINK){ |
2481 | ieee->actscanning = true; | 2481 | ieee->actscanning = true; |
2482 | ieee80211_start_scan(ieee); | 2482 | ieee80211_rtl_start_scan(ieee); |
2483 | } | 2483 | } |
2484 | spin_unlock_irqrestore(&ieee->lock, flags); | 2484 | spin_unlock_irqrestore(&ieee->lock, flags); |
2485 | } | 2485 | } |
@@ -2552,7 +2552,7 @@ void ieee80211_associate_retry_wq(struct work_struct *work) | |||
2552 | if(ieee->state == IEEE80211_NOLINK) | 2552 | if(ieee->state == IEEE80211_NOLINK) |
2553 | { | 2553 | { |
2554 | ieee->actscanning = true; | 2554 | ieee->actscanning = true; |
2555 | ieee80211_start_scan(ieee); | 2555 | ieee80211_rtl_start_scan(ieee); |
2556 | } | 2556 | } |
2557 | spin_unlock_irqrestore(&ieee->lock, flags); | 2557 | spin_unlock_irqrestore(&ieee->lock, flags); |
2558 | 2558 | ||
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_tx.c index 60621d6b2a6b..4d54e1e62d22 100644 --- a/drivers/staging/rtl8192su/ieee80211/ieee80211_tx.c +++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_tx.c | |||
@@ -604,7 +604,7 @@ void ieee80211_query_seqnum(struct ieee80211_device*ieee, struct sk_buff* skb, u | |||
604 | } | 604 | } |
605 | } | 605 | } |
606 | 606 | ||
607 | int rtl8192_ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) | 607 | int rtl8192_ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev) |
608 | { | 608 | { |
609 | struct ieee80211_device *ieee = netdev_priv(dev); | 609 | struct ieee80211_device *ieee = netdev_priv(dev); |
610 | struct ieee80211_txb *txb = NULL; | 610 | struct ieee80211_txb *txb = NULL; |
diff --git a/drivers/staging/rtl8192su/r8192U_core.c b/drivers/staging/rtl8192su/r8192U_core.c index 66274d7666ff..ccb9d5b8cd44 100644 --- a/drivers/staging/rtl8192su/r8192U_core.c +++ b/drivers/staging/rtl8192su/r8192U_core.c | |||
@@ -126,6 +126,8 @@ static struct usb_device_id rtl8192_usb_id_tbl[] = { | |||
126 | {USB_DEVICE(0x2001, 0x3301)}, | 126 | {USB_DEVICE(0x2001, 0x3301)}, |
127 | /* Zinwell */ | 127 | /* Zinwell */ |
128 | {USB_DEVICE(0x5a57, 0x0290)}, | 128 | {USB_DEVICE(0x5a57, 0x0290)}, |
129 | /* Guillemot */ | ||
130 | {USB_DEVICE(0x06f8, 0xe031)}, | ||
129 | //92SU | 131 | //92SU |
130 | {USB_DEVICE(0x0bda, 0x8172)}, | 132 | {USB_DEVICE(0x0bda, 0x8172)}, |
131 | {} | 133 | {} |
@@ -1501,7 +1503,7 @@ static void rtl8192_rx_isr(struct urb *urb) | |||
1501 | urb->context = skb; | 1503 | urb->context = skb; |
1502 | skb_queue_tail(&priv->rx_queue, skb); | 1504 | skb_queue_tail(&priv->rx_queue, skb); |
1503 | err = usb_submit_urb(urb, GFP_ATOMIC); | 1505 | err = usb_submit_urb(urb, GFP_ATOMIC); |
1504 | if(err && err != EPERM) | 1506 | if(err && err != -EPERM) |
1505 | printk("can not submit rxurb, err is %x,URB status is %x\n",err,urb->status); | 1507 | printk("can not submit rxurb, err is %x,URB status is %x\n",err,urb->status); |
1506 | } | 1508 | } |
1507 | 1509 | ||
@@ -7155,7 +7157,7 @@ void rtl8192SU_rx_nomal(struct sk_buff* skb) | |||
7155 | unicast_packet = true; | 7157 | unicast_packet = true; |
7156 | } | 7158 | } |
7157 | 7159 | ||
7158 | if(!ieee80211_rx(priv->ieee80211,skb, &stats)) { | 7160 | if(!ieee80211_rtl_rx(priv->ieee80211,skb, &stats)) { |
7159 | dev_kfree_skb_any(skb); | 7161 | dev_kfree_skb_any(skb); |
7160 | } else { | 7162 | } else { |
7161 | // priv->stats.rxoktotal++; //YJ,test,090108 | 7163 | // priv->stats.rxoktotal++; //YJ,test,090108 |
@@ -7426,7 +7428,7 @@ static const struct net_device_ops rtl8192_netdev_ops = { | |||
7426 | .ndo_set_mac_address = r8192_set_mac_adr, | 7428 | .ndo_set_mac_address = r8192_set_mac_adr, |
7427 | .ndo_validate_addr = eth_validate_addr, | 7429 | .ndo_validate_addr = eth_validate_addr, |
7428 | .ndo_change_mtu = eth_change_mtu, | 7430 | .ndo_change_mtu = eth_change_mtu, |
7429 | .ndo_start_xmit = rtl8192_ieee80211_xmit, | 7431 | .ndo_start_xmit = rtl8192_ieee80211_rtl_xmit, |
7430 | }; | 7432 | }; |
7431 | 7433 | ||
7432 | static int __devinit rtl8192_usb_probe(struct usb_interface *intf, | 7434 | static int __devinit rtl8192_usb_probe(struct usb_interface *intf, |
@@ -7619,7 +7621,7 @@ void rtl8192_try_wake_queue(struct net_device *dev, int pri) | |||
7619 | spin_unlock_irqrestore(&priv->tx_lock,flags); | 7621 | spin_unlock_irqrestore(&priv->tx_lock,flags); |
7620 | 7622 | ||
7621 | if(enough_desc) | 7623 | if(enough_desc) |
7622 | ieee80211_wake_queue(priv->ieee80211); | 7624 | ieee80211_rtl_wake_queue(priv->ieee80211); |
7623 | } | 7625 | } |
7624 | 7626 | ||
7625 | void EnableHWSecurityConfig8192(struct net_device *dev) | 7627 | void EnableHWSecurityConfig8192(struct net_device *dev) |
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c index d397f1d68eb7..5f12d62658c9 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c | |||
@@ -845,7 +845,7 @@ int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len) | |||
845 | { | 845 | { |
846 | if (len != ie[1]+2) | 846 | if (len != ie[1]+2) |
847 | { | 847 | { |
848 | printk("len:%d, ie:%d\n", len, ie[1]); | 848 | printk("len:%zu, ie:%d\n", len, ie[1]); |
849 | return -EINVAL; | 849 | return -EINVAL; |
850 | } | 850 | } |
851 | buf = kmalloc(len, GFP_KERNEL); | 851 | buf = kmalloc(len, GFP_KERNEL); |
diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c b/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c index 26af43bb8390..512a57aebde3 100644 --- a/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c +++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c | |||
@@ -340,7 +340,7 @@ int ieee80211_rx_ADDBAReq( struct ieee80211_device* ieee, struct sk_buff *skb) | |||
340 | 340 | ||
341 | if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9) | 341 | if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9) |
342 | { | 342 | { |
343 | IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BAREQ(%d / %d)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 9)); | 343 | IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BAREQ(%d / %zu)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 9)); |
344 | return -1; | 344 | return -1; |
345 | } | 345 | } |
346 | 346 | ||
@@ -439,7 +439,7 @@ int ieee80211_rx_ADDBARsp( struct ieee80211_device* ieee, struct sk_buff *skb) | |||
439 | 439 | ||
440 | if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9) | 440 | if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9) |
441 | { | 441 | { |
442 | IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BARSP(%d / %d)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 9)); | 442 | IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BARSP(%d / %zu)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 9)); |
443 | return -1; | 443 | return -1; |
444 | } | 444 | } |
445 | rsp = ( struct ieee80211_hdr_3addr*)skb->data; | 445 | rsp = ( struct ieee80211_hdr_3addr*)skb->data; |
@@ -569,7 +569,7 @@ int ieee80211_rx_DELBA(struct ieee80211_device* ieee,struct sk_buff *skb) | |||
569 | 569 | ||
570 | if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 6) | 570 | if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 6) |
571 | { | 571 | { |
572 | IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in DELBA(%d / %d)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 6)); | 572 | IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in DELBA(%d / %zu)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 6)); |
573 | return -1; | 573 | return -1; |
574 | } | 574 | } |
575 | 575 | ||
diff --git a/drivers/staging/sm7xx/Kconfig b/drivers/staging/sm7xx/Kconfig new file mode 100644 index 000000000000..204dbfc3c38b --- /dev/null +++ b/drivers/staging/sm7xx/Kconfig | |||
@@ -0,0 +1,15 @@ | |||
1 | config FB_SM7XX | ||
2 | tristate "Silicon Motion SM7XX Frame Buffer Support" | ||
3 | depends on FB | ||
4 | select FB_CFB_FILLRECT | ||
5 | select FB_CFB_COPYAREA | ||
6 | select FB_CFB_IMAGEBLIT | ||
7 | help | ||
8 | Frame Buffer driver for the Silicon Motion SM7XX serial graphic card. | ||
9 | |||
10 | config FB_SM7XX_ACCEL | ||
11 | bool "Siliconmotion Acceleration functions (EXPERIMENTAL)" | ||
12 | depends on FB_SM7XX && EXPERIMENTAL | ||
13 | help | ||
14 | This will compile the Trident frame buffer device with | ||
15 | acceleration functions. | ||
diff --git a/drivers/staging/sm7xx/Makefile b/drivers/staging/sm7xx/Makefile new file mode 100644 index 000000000000..f43cb9106305 --- /dev/null +++ b/drivers/staging/sm7xx/Makefile | |||
@@ -0,0 +1,3 @@ | |||
1 | obj-$(CONFIG_FB_SM7XX) += sm7xx.o | ||
2 | |||
3 | sm7xx-y := smtcfb.o | ||
diff --git a/drivers/staging/sm7xx/TODO b/drivers/staging/sm7xx/TODO new file mode 100644 index 000000000000..1f61f5e11cf5 --- /dev/null +++ b/drivers/staging/sm7xx/TODO | |||
@@ -0,0 +1,10 @@ | |||
1 | TODO: | ||
2 | - Dual head support | ||
3 | - use kernel coding style | ||
4 | - checkpatch.pl clean | ||
5 | - refine the code and remove unused code | ||
6 | - use kernel framebuffer mode setting instead of hard code | ||
7 | - move it to drivers/video/sm7xx/ or make it be drivers/video/sm7xxfb.c | ||
8 | |||
9 | Please send any patches to Greg Kroah-Hartman <greg@kroah.com> and | ||
10 | Teddy Wang <teddy.wang@siliconmotion.com.cn>. | ||
diff --git a/drivers/staging/sm7xx/smtc2d.c b/drivers/staging/sm7xx/smtc2d.c new file mode 100644 index 000000000000..133b86c6a678 --- /dev/null +++ b/drivers/staging/sm7xx/smtc2d.c | |||
@@ -0,0 +1,979 @@ | |||
1 | /* | ||
2 | * Silicon Motion SM7XX 2D drawing engine functions. | ||
3 | * | ||
4 | * Copyright (C) 2006 Silicon Motion Technology Corp. | ||
5 | * Author: Boyod boyod.yang@siliconmotion.com.cn | ||
6 | * | ||
7 | * Copyright (C) 2009 Lemote, Inc. | ||
8 | * Author: Wu Zhangjin, wuzj@lemote.com | ||
9 | * | ||
10 | * This file is subject to the terms and conditions of the GNU General Public | ||
11 | * License. See the file COPYING in the main directory of this archive for | ||
12 | * more details. | ||
13 | * | ||
14 | * Version 0.10.26192.21.01 | ||
15 | * - Add PowerPC support | ||
16 | * - Add 2D support for Lynx - | ||
17 | * Verified on 2.6.19.2 | ||
18 | * Boyod.yang <boyod.yang@siliconmotion.com.cn> | ||
19 | */ | ||
20 | |||
21 | unsigned char smtc_de_busy; | ||
22 | |||
23 | void SMTC_write2Dreg(unsigned long nOffset, unsigned long nData) | ||
24 | { | ||
25 | writel(nData, smtc_2DBaseAddress + nOffset); | ||
26 | } | ||
27 | |||
28 | unsigned long SMTC_read2Dreg(unsigned long nOffset) | ||
29 | { | ||
30 | return readl(smtc_2DBaseAddress + nOffset); | ||
31 | } | ||
32 | |||
33 | void SMTC_write2Ddataport(unsigned long nOffset, unsigned long nData) | ||
34 | { | ||
35 | writel(nData, smtc_2Ddataport + nOffset); | ||
36 | } | ||
37 | |||
38 | /********************************************************************** | ||
39 | * | ||
40 | * deInit | ||
41 | * | ||
42 | * Purpose | ||
43 | * Drawing engine initialization. | ||
44 | * | ||
45 | **********************************************************************/ | ||
46 | |||
47 | void deInit(unsigned int nModeWidth, unsigned int nModeHeight, | ||
48 | unsigned int bpp) | ||
49 | { | ||
50 | /* Get current power configuration. */ | ||
51 | unsigned char clock; | ||
52 | clock = smtc_seqr(0x21); | ||
53 | |||
54 | /* initialize global 'mutex lock' variable */ | ||
55 | smtc_de_busy = 0; | ||
56 | |||
57 | /* Enable 2D Drawing Engine */ | ||
58 | smtc_seqw(0x21, clock & 0xF8); | ||
59 | |||
60 | SMTC_write2Dreg(DE_CLIP_TL, | ||
61 | FIELD_VALUE(0, DE_CLIP_TL, TOP, 0) | | ||
62 | FIELD_SET(0, DE_CLIP_TL, STATUS, DISABLE) | | ||
63 | FIELD_SET(0, DE_CLIP_TL, INHIBIT, OUTSIDE) | | ||
64 | FIELD_VALUE(0, DE_CLIP_TL, LEFT, 0)); | ||
65 | |||
66 | if (bpp >= 24) { | ||
67 | SMTC_write2Dreg(DE_PITCH, | ||
68 | FIELD_VALUE(0, DE_PITCH, DESTINATION, | ||
69 | nModeWidth * 3) | FIELD_VALUE(0, | ||
70 | DE_PITCH, | ||
71 | SOURCE, | ||
72 | nModeWidth | ||
73 | * 3)); | ||
74 | } else { | ||
75 | SMTC_write2Dreg(DE_PITCH, | ||
76 | FIELD_VALUE(0, DE_PITCH, DESTINATION, | ||
77 | nModeWidth) | FIELD_VALUE(0, | ||
78 | DE_PITCH, | ||
79 | SOURCE, | ||
80 | nModeWidth)); | ||
81 | } | ||
82 | |||
83 | SMTC_write2Dreg(DE_WINDOW_WIDTH, | ||
84 | FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, | ||
85 | nModeWidth) | FIELD_VALUE(0, | ||
86 | DE_WINDOW_WIDTH, | ||
87 | SOURCE, | ||
88 | nModeWidth)); | ||
89 | |||
90 | switch (bpp) { | ||
91 | case 8: | ||
92 | SMTC_write2Dreg(DE_STRETCH_FORMAT, | ||
93 | FIELD_SET(0, DE_STRETCH_FORMAT, PATTERN_XY, | ||
94 | NORMAL) | FIELD_VALUE(0, | ||
95 | DE_STRETCH_FORMAT, | ||
96 | PATTERN_Y, | ||
97 | 0) | | ||
98 | FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_X, | ||
99 | 0) | FIELD_SET(0, DE_STRETCH_FORMAT, | ||
100 | PIXEL_FORMAT, | ||
101 | 8) | FIELD_SET(0, | ||
102 | DE_STRETCH_FORMAT, | ||
103 | ADDRESSING, | ||
104 | XY) | | ||
105 | FIELD_VALUE(0, DE_STRETCH_FORMAT, | ||
106 | SOURCE_HEIGHT, 3)); | ||
107 | break; | ||
108 | case 24: | ||
109 | SMTC_write2Dreg(DE_STRETCH_FORMAT, | ||
110 | FIELD_SET(0, DE_STRETCH_FORMAT, PATTERN_XY, | ||
111 | NORMAL) | FIELD_VALUE(0, | ||
112 | DE_STRETCH_FORMAT, | ||
113 | PATTERN_Y, | ||
114 | 0) | | ||
115 | FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_X, | ||
116 | 0) | FIELD_SET(0, DE_STRETCH_FORMAT, | ||
117 | PIXEL_FORMAT, | ||
118 | 24) | FIELD_SET(0, | ||
119 | DE_STRETCH_FORMAT, | ||
120 | ADDRESSING, | ||
121 | XY) | | ||
122 | FIELD_VALUE(0, DE_STRETCH_FORMAT, | ||
123 | SOURCE_HEIGHT, 3)); | ||
124 | break; | ||
125 | case 16: | ||
126 | default: | ||
127 | SMTC_write2Dreg(DE_STRETCH_FORMAT, | ||
128 | FIELD_SET(0, DE_STRETCH_FORMAT, PATTERN_XY, | ||
129 | NORMAL) | FIELD_VALUE(0, | ||
130 | DE_STRETCH_FORMAT, | ||
131 | PATTERN_Y, | ||
132 | 0) | | ||
133 | FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_X, | ||
134 | 0) | FIELD_SET(0, DE_STRETCH_FORMAT, | ||
135 | PIXEL_FORMAT, | ||
136 | 16) | FIELD_SET(0, | ||
137 | DE_STRETCH_FORMAT, | ||
138 | ADDRESSING, | ||
139 | XY) | | ||
140 | FIELD_VALUE(0, DE_STRETCH_FORMAT, | ||
141 | SOURCE_HEIGHT, 3)); | ||
142 | break; | ||
143 | } | ||
144 | |||
145 | SMTC_write2Dreg(DE_MASKS, | ||
146 | FIELD_VALUE(0, DE_MASKS, BYTE_MASK, 0xFFFF) | | ||
147 | FIELD_VALUE(0, DE_MASKS, BIT_MASK, 0xFFFF)); | ||
148 | SMTC_write2Dreg(DE_COLOR_COMPARE_MASK, | ||
149 | FIELD_VALUE(0, DE_COLOR_COMPARE_MASK, MASKS, \ | ||
150 | 0xFFFFFF)); | ||
151 | SMTC_write2Dreg(DE_COLOR_COMPARE, | ||
152 | FIELD_VALUE(0, DE_COLOR_COMPARE, COLOR, 0xFFFFFF)); | ||
153 | } | ||
154 | |||
155 | void deVerticalLine(unsigned long dst_base, | ||
156 | unsigned long dst_pitch, | ||
157 | unsigned long nX, | ||
158 | unsigned long nY, | ||
159 | unsigned long dst_height, unsigned long nColor) | ||
160 | { | ||
161 | deWaitForNotBusy(); | ||
162 | |||
163 | SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, | ||
164 | FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS, | ||
165 | dst_base)); | ||
166 | |||
167 | SMTC_write2Dreg(DE_PITCH, | ||
168 | FIELD_VALUE(0, DE_PITCH, DESTINATION, dst_pitch) | | ||
169 | FIELD_VALUE(0, DE_PITCH, SOURCE, dst_pitch)); | ||
170 | |||
171 | SMTC_write2Dreg(DE_WINDOW_WIDTH, | ||
172 | FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, | ||
173 | dst_pitch) | FIELD_VALUE(0, DE_WINDOW_WIDTH, | ||
174 | SOURCE, | ||
175 | dst_pitch)); | ||
176 | |||
177 | SMTC_write2Dreg(DE_FOREGROUND, | ||
178 | FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor)); | ||
179 | |||
180 | SMTC_write2Dreg(DE_DESTINATION, | ||
181 | FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) | | ||
182 | FIELD_VALUE(0, DE_DESTINATION, X, nX) | | ||
183 | FIELD_VALUE(0, DE_DESTINATION, Y, nY)); | ||
184 | |||
185 | SMTC_write2Dreg(DE_DIMENSION, | ||
186 | FIELD_VALUE(0, DE_DIMENSION, X, 1) | | ||
187 | FIELD_VALUE(0, DE_DIMENSION, Y_ET, dst_height)); | ||
188 | |||
189 | SMTC_write2Dreg(DE_CONTROL, | ||
190 | FIELD_SET(0, DE_CONTROL, STATUS, START) | | ||
191 | FIELD_SET(0, DE_CONTROL, DIRECTION, LEFT_TO_RIGHT) | | ||
192 | FIELD_SET(0, DE_CONTROL, MAJOR, Y) | | ||
193 | FIELD_SET(0, DE_CONTROL, STEP_X, NEGATIVE) | | ||
194 | FIELD_SET(0, DE_CONTROL, STEP_Y, POSITIVE) | | ||
195 | FIELD_SET(0, DE_CONTROL, LAST_PIXEL, OFF) | | ||
196 | FIELD_SET(0, DE_CONTROL, COMMAND, SHORT_STROKE) | | ||
197 | FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) | | ||
198 | FIELD_VALUE(0, DE_CONTROL, ROP, 0x0C)); | ||
199 | |||
200 | smtc_de_busy = 1; | ||
201 | } | ||
202 | |||
203 | void deHorizontalLine(unsigned long dst_base, | ||
204 | unsigned long dst_pitch, | ||
205 | unsigned long nX, | ||
206 | unsigned long nY, | ||
207 | unsigned long dst_width, unsigned long nColor) | ||
208 | { | ||
209 | deWaitForNotBusy(); | ||
210 | |||
211 | SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, | ||
212 | FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS, | ||
213 | dst_base)); | ||
214 | |||
215 | SMTC_write2Dreg(DE_PITCH, | ||
216 | FIELD_VALUE(0, DE_PITCH, DESTINATION, dst_pitch) | | ||
217 | FIELD_VALUE(0, DE_PITCH, SOURCE, dst_pitch)); | ||
218 | |||
219 | SMTC_write2Dreg(DE_WINDOW_WIDTH, | ||
220 | FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, | ||
221 | dst_pitch) | FIELD_VALUE(0, DE_WINDOW_WIDTH, | ||
222 | SOURCE, | ||
223 | dst_pitch)); | ||
224 | SMTC_write2Dreg(DE_FOREGROUND, | ||
225 | FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor)); | ||
226 | SMTC_write2Dreg(DE_DESTINATION, | ||
227 | FIELD_SET(0, DE_DESTINATION, WRAP, | ||
228 | DISABLE) | FIELD_VALUE(0, DE_DESTINATION, X, | ||
229 | nX) | FIELD_VALUE(0, | ||
230 | DE_DESTINATION, | ||
231 | Y, | ||
232 | nY)); | ||
233 | SMTC_write2Dreg(DE_DIMENSION, | ||
234 | FIELD_VALUE(0, DE_DIMENSION, X, | ||
235 | dst_width) | FIELD_VALUE(0, DE_DIMENSION, | ||
236 | Y_ET, 1)); | ||
237 | SMTC_write2Dreg(DE_CONTROL, | ||
238 | FIELD_SET(0, DE_CONTROL, STATUS, START) | FIELD_SET(0, | ||
239 | DE_CONTROL, | ||
240 | DIRECTION, | ||
241 | RIGHT_TO_LEFT) | ||
242 | | FIELD_SET(0, DE_CONTROL, MAJOR, X) | FIELD_SET(0, | ||
243 | DE_CONTROL, | ||
244 | STEP_X, | ||
245 | POSITIVE) | ||
246 | | FIELD_SET(0, DE_CONTROL, STEP_Y, | ||
247 | NEGATIVE) | FIELD_SET(0, DE_CONTROL, | ||
248 | LAST_PIXEL, | ||
249 | OFF) | FIELD_SET(0, | ||
250 | DE_CONTROL, | ||
251 | COMMAND, | ||
252 | SHORT_STROKE) | ||
253 | | FIELD_SET(0, DE_CONTROL, ROP_SELECT, | ||
254 | ROP2) | FIELD_VALUE(0, DE_CONTROL, ROP, | ||
255 | 0x0C)); | ||
256 | |||
257 | smtc_de_busy = 1; | ||
258 | } | ||
259 | |||
260 | void deLine(unsigned long dst_base, | ||
261 | unsigned long dst_pitch, | ||
262 | unsigned long nX1, | ||
263 | unsigned long nY1, | ||
264 | unsigned long nX2, unsigned long nY2, unsigned long nColor) | ||
265 | { | ||
266 | unsigned long nCommand = | ||
267 | FIELD_SET(0, DE_CONTROL, STATUS, START) | | ||
268 | FIELD_SET(0, DE_CONTROL, DIRECTION, LEFT_TO_RIGHT) | | ||
269 | FIELD_SET(0, DE_CONTROL, MAJOR, X) | | ||
270 | FIELD_SET(0, DE_CONTROL, STEP_X, POSITIVE) | | ||
271 | FIELD_SET(0, DE_CONTROL, STEP_Y, POSITIVE) | | ||
272 | FIELD_SET(0, DE_CONTROL, LAST_PIXEL, OFF) | | ||
273 | FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) | | ||
274 | FIELD_VALUE(0, DE_CONTROL, ROP, 0x0C); | ||
275 | unsigned long DeltaX; | ||
276 | unsigned long DeltaY; | ||
277 | |||
278 | /* Calculate delta X */ | ||
279 | if (nX1 <= nX2) | ||
280 | DeltaX = nX2 - nX1; | ||
281 | else { | ||
282 | DeltaX = nX1 - nX2; | ||
283 | nCommand = FIELD_SET(nCommand, DE_CONTROL, STEP_X, NEGATIVE); | ||
284 | } | ||
285 | |||
286 | /* Calculate delta Y */ | ||
287 | if (nY1 <= nY2) | ||
288 | DeltaY = nY2 - nY1; | ||
289 | else { | ||
290 | DeltaY = nY1 - nY2; | ||
291 | nCommand = FIELD_SET(nCommand, DE_CONTROL, STEP_Y, NEGATIVE); | ||
292 | } | ||
293 | |||
294 | /* Determine the major axis */ | ||
295 | if (DeltaX < DeltaY) | ||
296 | nCommand = FIELD_SET(nCommand, DE_CONTROL, MAJOR, Y); | ||
297 | |||
298 | /* Vertical line? */ | ||
299 | if (nX1 == nX2) | ||
300 | deVerticalLine(dst_base, dst_pitch, nX1, nY1, DeltaY, nColor); | ||
301 | |||
302 | /* Horizontal line? */ | ||
303 | else if (nY1 == nY2) | ||
304 | deHorizontalLine(dst_base, dst_pitch, nX1, nY1, \ | ||
305 | DeltaX, nColor); | ||
306 | |||
307 | /* Diagonal line? */ | ||
308 | else if (DeltaX == DeltaY) { | ||
309 | deWaitForNotBusy(); | ||
310 | |||
311 | SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, | ||
312 | FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, | ||
313 | ADDRESS, dst_base)); | ||
314 | |||
315 | SMTC_write2Dreg(DE_PITCH, | ||
316 | FIELD_VALUE(0, DE_PITCH, DESTINATION, | ||
317 | dst_pitch) | FIELD_VALUE(0, | ||
318 | DE_PITCH, | ||
319 | SOURCE, | ||
320 | dst_pitch)); | ||
321 | |||
322 | SMTC_write2Dreg(DE_WINDOW_WIDTH, | ||
323 | FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, | ||
324 | dst_pitch) | FIELD_VALUE(0, | ||
325 | DE_WINDOW_WIDTH, | ||
326 | SOURCE, | ||
327 | dst_pitch)); | ||
328 | |||
329 | SMTC_write2Dreg(DE_FOREGROUND, | ||
330 | FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor)); | ||
331 | |||
332 | SMTC_write2Dreg(DE_DESTINATION, | ||
333 | FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) | | ||
334 | FIELD_VALUE(0, DE_DESTINATION, X, 1) | | ||
335 | FIELD_VALUE(0, DE_DESTINATION, Y, nY1)); | ||
336 | |||
337 | SMTC_write2Dreg(DE_DIMENSION, | ||
338 | FIELD_VALUE(0, DE_DIMENSION, X, 1) | | ||
339 | FIELD_VALUE(0, DE_DIMENSION, Y_ET, DeltaX)); | ||
340 | |||
341 | SMTC_write2Dreg(DE_CONTROL, | ||
342 | FIELD_SET(nCommand, DE_CONTROL, COMMAND, | ||
343 | SHORT_STROKE)); | ||
344 | } | ||
345 | |||
346 | /* Generic line */ | ||
347 | else { | ||
348 | unsigned int k1, k2, et, w; | ||
349 | if (DeltaX < DeltaY) { | ||
350 | k1 = 2 * DeltaX; | ||
351 | et = k1 - DeltaY; | ||
352 | k2 = et - DeltaY; | ||
353 | w = DeltaY + 1; | ||
354 | } else { | ||
355 | k1 = 2 * DeltaY; | ||
356 | et = k1 - DeltaX; | ||
357 | k2 = et - DeltaX; | ||
358 | w = DeltaX + 1; | ||
359 | } | ||
360 | |||
361 | deWaitForNotBusy(); | ||
362 | |||
363 | SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, | ||
364 | FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, | ||
365 | ADDRESS, dst_base)); | ||
366 | |||
367 | SMTC_write2Dreg(DE_PITCH, | ||
368 | FIELD_VALUE(0, DE_PITCH, DESTINATION, | ||
369 | dst_pitch) | FIELD_VALUE(0, | ||
370 | DE_PITCH, | ||
371 | SOURCE, | ||
372 | dst_pitch)); | ||
373 | |||
374 | SMTC_write2Dreg(DE_WINDOW_WIDTH, | ||
375 | FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, | ||
376 | dst_pitch) | FIELD_VALUE(0, | ||
377 | DE_WINDOW_WIDTH, | ||
378 | SOURCE, | ||
379 | dst_pitch)); | ||
380 | |||
381 | SMTC_write2Dreg(DE_FOREGROUND, | ||
382 | FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor)); | ||
383 | |||
384 | SMTC_write2Dreg(DE_SOURCE, | ||
385 | FIELD_SET(0, DE_SOURCE, WRAP, DISABLE) | | ||
386 | FIELD_VALUE(0, DE_SOURCE, X_K1, k1) | | ||
387 | FIELD_VALUE(0, DE_SOURCE, Y_K2, k2)); | ||
388 | |||
389 | SMTC_write2Dreg(DE_DESTINATION, | ||
390 | FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) | | ||
391 | FIELD_VALUE(0, DE_DESTINATION, X, nX1) | | ||
392 | FIELD_VALUE(0, DE_DESTINATION, Y, nY1)); | ||
393 | |||
394 | SMTC_write2Dreg(DE_DIMENSION, | ||
395 | FIELD_VALUE(0, DE_DIMENSION, X, w) | | ||
396 | FIELD_VALUE(0, DE_DIMENSION, Y_ET, et)); | ||
397 | |||
398 | SMTC_write2Dreg(DE_CONTROL, | ||
399 | FIELD_SET(nCommand, DE_CONTROL, COMMAND, | ||
400 | LINE_DRAW)); | ||
401 | } | ||
402 | |||
403 | smtc_de_busy = 1; | ||
404 | } | ||
405 | |||
406 | void deFillRect(unsigned long dst_base, | ||
407 | unsigned long dst_pitch, | ||
408 | unsigned long dst_X, | ||
409 | unsigned long dst_Y, | ||
410 | unsigned long dst_width, | ||
411 | unsigned long dst_height, unsigned long nColor) | ||
412 | { | ||
413 | deWaitForNotBusy(); | ||
414 | |||
415 | SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, | ||
416 | FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS, | ||
417 | dst_base)); | ||
418 | |||
419 | if (dst_pitch) { | ||
420 | SMTC_write2Dreg(DE_PITCH, | ||
421 | FIELD_VALUE(0, DE_PITCH, DESTINATION, | ||
422 | dst_pitch) | FIELD_VALUE(0, | ||
423 | DE_PITCH, | ||
424 | SOURCE, | ||
425 | dst_pitch)); | ||
426 | |||
427 | SMTC_write2Dreg(DE_WINDOW_WIDTH, | ||
428 | FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, | ||
429 | dst_pitch) | FIELD_VALUE(0, | ||
430 | DE_WINDOW_WIDTH, | ||
431 | SOURCE, | ||
432 | dst_pitch)); | ||
433 | } | ||
434 | |||
435 | SMTC_write2Dreg(DE_FOREGROUND, | ||
436 | FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor)); | ||
437 | |||
438 | SMTC_write2Dreg(DE_DESTINATION, | ||
439 | FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) | | ||
440 | FIELD_VALUE(0, DE_DESTINATION, X, dst_X) | | ||
441 | FIELD_VALUE(0, DE_DESTINATION, Y, dst_Y)); | ||
442 | |||
443 | SMTC_write2Dreg(DE_DIMENSION, | ||
444 | FIELD_VALUE(0, DE_DIMENSION, X, dst_width) | | ||
445 | FIELD_VALUE(0, DE_DIMENSION, Y_ET, dst_height)); | ||
446 | |||
447 | SMTC_write2Dreg(DE_CONTROL, | ||
448 | FIELD_SET(0, DE_CONTROL, STATUS, START) | | ||
449 | FIELD_SET(0, DE_CONTROL, DIRECTION, LEFT_TO_RIGHT) | | ||
450 | FIELD_SET(0, DE_CONTROL, LAST_PIXEL, OFF) | | ||
451 | FIELD_SET(0, DE_CONTROL, COMMAND, RECTANGLE_FILL) | | ||
452 | FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) | | ||
453 | FIELD_VALUE(0, DE_CONTROL, ROP, 0x0C)); | ||
454 | |||
455 | smtc_de_busy = 1; | ||
456 | } | ||
457 | |||
458 | /********************************************************************** | ||
459 | * | ||
460 | * deRotatePattern | ||
461 | * | ||
462 | * Purpose | ||
463 | * Rotate the given pattern if necessary | ||
464 | * | ||
465 | * Parameters | ||
466 | * [in] | ||
467 | * pPattern - Pointer to DE_SURFACE structure containing | ||
468 | * pattern attributes | ||
469 | * patternX - X position (0-7) of pattern origin | ||
470 | * patternY - Y position (0-7) of pattern origin | ||
471 | * | ||
472 | * [out] | ||
473 | * pattern_dstaddr - Pointer to pre-allocated buffer containing | ||
474 | * rotated pattern | ||
475 | * | ||
476 | **********************************************************************/ | ||
477 | void deRotatePattern(unsigned char *pattern_dstaddr, | ||
478 | unsigned long pattern_src_addr, | ||
479 | unsigned long pattern_BPP, | ||
480 | unsigned long pattern_stride, int patternX, int patternY) | ||
481 | { | ||
482 | unsigned int i; | ||
483 | unsigned long pattern[PATTERN_WIDTH * PATTERN_HEIGHT]; | ||
484 | unsigned int x, y; | ||
485 | unsigned char *pjPatByte; | ||
486 | |||
487 | if (pattern_dstaddr != NULL) { | ||
488 | deWaitForNotBusy(); | ||
489 | |||
490 | if (patternX || patternY) { | ||
491 | /* Rotate pattern */ | ||
492 | pjPatByte = (unsigned char *)pattern; | ||
493 | |||
494 | switch (pattern_BPP) { | ||
495 | case 8: | ||
496 | { | ||
497 | for (y = 0; y < 8; y++) { | ||
498 | unsigned char *pjBuffer = | ||
499 | pattern_dstaddr + | ||
500 | ((patternY + y) & 7) * 8; | ||
501 | for (x = 0; x < 8; x++) { | ||
502 | pjBuffer[(patternX + | ||
503 | x) & 7] = | ||
504 | pjPatByte[x]; | ||
505 | } | ||
506 | pjPatByte += pattern_stride; | ||
507 | } | ||
508 | break; | ||
509 | } | ||
510 | |||
511 | case 16: | ||
512 | { | ||
513 | for (y = 0; y < 8; y++) { | ||
514 | unsigned short *pjBuffer = | ||
515 | (unsigned short *) | ||
516 | pattern_dstaddr + | ||
517 | ((patternY + y) & 7) * 8; | ||
518 | for (x = 0; x < 8; x++) { | ||
519 | pjBuffer[(patternX + | ||
520 | x) & 7] = | ||
521 | ((unsigned short *) | ||
522 | pjPatByte)[x]; | ||
523 | } | ||
524 | pjPatByte += pattern_stride; | ||
525 | } | ||
526 | break; | ||
527 | } | ||
528 | |||
529 | case 32: | ||
530 | { | ||
531 | for (y = 0; y < 8; y++) { | ||
532 | unsigned long *pjBuffer = | ||
533 | (unsigned long *) | ||
534 | pattern_dstaddr + | ||
535 | ((patternY + y) & 7) * 8; | ||
536 | for (x = 0; x < 8; x++) { | ||
537 | pjBuffer[(patternX + | ||
538 | x) & 7] = | ||
539 | ((unsigned long *) | ||
540 | pjPatByte)[x]; | ||
541 | } | ||
542 | pjPatByte += pattern_stride; | ||
543 | } | ||
544 | break; | ||
545 | } | ||
546 | } | ||
547 | } else { | ||
548 | /*Don't rotate,just copy pattern into pattern_dstaddr*/ | ||
549 | for (i = 0; i < (pattern_BPP * 2); i++) { | ||
550 | ((unsigned long *)pattern_dstaddr)[i] = | ||
551 | pattern[i]; | ||
552 | } | ||
553 | } | ||
554 | |||
555 | } | ||
556 | } | ||
557 | |||
558 | /********************************************************************** | ||
559 | * | ||
560 | * deCopy | ||
561 | * | ||
562 | * Purpose | ||
563 | * Copy a rectangular area of the source surface to a destination surface | ||
564 | * | ||
565 | * Remarks | ||
566 | * Source bitmap must have the same color depth (BPP) as the destination | ||
567 | * bitmap. | ||
568 | * | ||
569 | **********************************************************************/ | ||
570 | void deCopy(unsigned long dst_base, | ||
571 | unsigned long dst_pitch, | ||
572 | unsigned long dst_BPP, | ||
573 | unsigned long dst_X, | ||
574 | unsigned long dst_Y, | ||
575 | unsigned long dst_width, | ||
576 | unsigned long dst_height, | ||
577 | unsigned long src_base, | ||
578 | unsigned long src_pitch, | ||
579 | unsigned long src_X, | ||
580 | unsigned long src_Y, pTransparent pTransp, unsigned char nROP2) | ||
581 | { | ||
582 | unsigned long nDirection = 0; | ||
583 | unsigned long nTransparent = 0; | ||
584 | /* Direction of ROP2 operation: | ||
585 | * 1 = Left to Right, | ||
586 | * (-1) = Right to Left | ||
587 | */ | ||
588 | unsigned long opSign = 1; | ||
589 | /* xWidth is in pixels */ | ||
590 | unsigned long xWidth = 192 / (dst_BPP / 8); | ||
591 | unsigned long de_ctrl = 0; | ||
592 | |||
593 | deWaitForNotBusy(); | ||
594 | |||
595 | SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, | ||
596 | FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS, | ||
597 | dst_base)); | ||
598 | |||
599 | SMTC_write2Dreg(DE_WINDOW_SOURCE_BASE, | ||
600 | FIELD_VALUE(0, DE_WINDOW_SOURCE_BASE, ADDRESS, | ||
601 | src_base)); | ||
602 | |||
603 | if (dst_pitch && src_pitch) { | ||
604 | SMTC_write2Dreg(DE_PITCH, | ||
605 | FIELD_VALUE(0, DE_PITCH, DESTINATION, | ||
606 | dst_pitch) | FIELD_VALUE(0, | ||
607 | DE_PITCH, | ||
608 | SOURCE, | ||
609 | src_pitch)); | ||
610 | |||
611 | SMTC_write2Dreg(DE_WINDOW_WIDTH, | ||
612 | FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, | ||
613 | dst_pitch) | FIELD_VALUE(0, | ||
614 | DE_WINDOW_WIDTH, | ||
615 | SOURCE, | ||
616 | src_pitch)); | ||
617 | } | ||
618 | |||
619 | /* Set transparent bits if necessary */ | ||
620 | if (pTransp != NULL) { | ||
621 | nTransparent = | ||
622 | pTransp->match | pTransp->select | pTransp->control; | ||
623 | |||
624 | /* Set color compare register */ | ||
625 | SMTC_write2Dreg(DE_COLOR_COMPARE, | ||
626 | FIELD_VALUE(0, DE_COLOR_COMPARE, COLOR, | ||
627 | pTransp->color)); | ||
628 | } | ||
629 | |||
630 | /* Determine direction of operation */ | ||
631 | if (src_Y < dst_Y) { | ||
632 | /* +----------+ | ||
633 | |S | | ||
634 | | +----------+ | ||
635 | | | | | | ||
636 | | | | | | ||
637 | +---|------+ | | ||
638 | | D | | ||
639 | +----------+ */ | ||
640 | |||
641 | nDirection = BOTTOM_TO_TOP; | ||
642 | } else if (src_Y > dst_Y) { | ||
643 | /* +----------+ | ||
644 | |D | | ||
645 | | +----------+ | ||
646 | | | | | | ||
647 | | | | | | ||
648 | +---|------+ | | ||
649 | | S | | ||
650 | +----------+ */ | ||
651 | |||
652 | nDirection = TOP_TO_BOTTOM; | ||
653 | } else { | ||
654 | /* src_Y == dst_Y */ | ||
655 | |||
656 | if (src_X <= dst_X) { | ||
657 | /* +------+---+------+ | ||
658 | |S | | D| | ||
659 | | | | | | ||
660 | | | | | | ||
661 | | | | | | ||
662 | +------+---+------+ */ | ||
663 | |||
664 | nDirection = RIGHT_TO_LEFT; | ||
665 | } else { | ||
666 | /* src_X > dst_X */ | ||
667 | |||
668 | /* +------+---+------+ | ||
669 | |D | | S| | ||
670 | | | | | | ||
671 | | | | | | ||
672 | | | | | | ||
673 | +------+---+------+ */ | ||
674 | |||
675 | nDirection = LEFT_TO_RIGHT; | ||
676 | } | ||
677 | } | ||
678 | |||
679 | if ((nDirection == BOTTOM_TO_TOP) || (nDirection == RIGHT_TO_LEFT)) { | ||
680 | src_X += dst_width - 1; | ||
681 | src_Y += dst_height - 1; | ||
682 | dst_X += dst_width - 1; | ||
683 | dst_Y += dst_height - 1; | ||
684 | opSign = (-1); | ||
685 | } | ||
686 | |||
687 | if (dst_BPP >= 24) { | ||
688 | src_X *= 3; | ||
689 | src_Y *= 3; | ||
690 | dst_X *= 3; | ||
691 | dst_Y *= 3; | ||
692 | dst_width *= 3; | ||
693 | if ((nDirection == BOTTOM_TO_TOP) | ||
694 | || (nDirection == RIGHT_TO_LEFT)) { | ||
695 | src_X += 2; | ||
696 | dst_X += 2; | ||
697 | } | ||
698 | } | ||
699 | |||
700 | /* Workaround for 192 byte hw bug */ | ||
701 | if ((nROP2 != 0x0C) && ((dst_width * (dst_BPP / 8)) >= 192)) { | ||
702 | /* | ||
703 | * Perform the ROP2 operation in chunks of (xWidth * | ||
704 | * dst_height) | ||
705 | */ | ||
706 | while (1) { | ||
707 | deWaitForNotBusy(); | ||
708 | |||
709 | SMTC_write2Dreg(DE_SOURCE, | ||
710 | FIELD_SET(0, DE_SOURCE, WRAP, DISABLE) | | ||
711 | FIELD_VALUE(0, DE_SOURCE, X_K1, src_X) | | ||
712 | FIELD_VALUE(0, DE_SOURCE, Y_K2, src_Y)); | ||
713 | |||
714 | SMTC_write2Dreg(DE_DESTINATION, | ||
715 | FIELD_SET(0, DE_DESTINATION, WRAP, | ||
716 | DISABLE) | FIELD_VALUE(0, | ||
717 | DE_DESTINATION, | ||
718 | X, | ||
719 | dst_X) | ||
720 | | FIELD_VALUE(0, DE_DESTINATION, Y, | ||
721 | dst_Y)); | ||
722 | |||
723 | SMTC_write2Dreg(DE_DIMENSION, | ||
724 | FIELD_VALUE(0, DE_DIMENSION, X, | ||
725 | xWidth) | FIELD_VALUE(0, | ||
726 | DE_DIMENSION, | ||
727 | Y_ET, | ||
728 | dst_height)); | ||
729 | |||
730 | de_ctrl = | ||
731 | FIELD_VALUE(0, DE_CONTROL, ROP, | ||
732 | nROP2) | nTransparent | FIELD_SET(0, | ||
733 | DE_CONTROL, | ||
734 | ROP_SELECT, | ||
735 | ROP2) | ||
736 | | FIELD_SET(0, DE_CONTROL, COMMAND, | ||
737 | BITBLT) | ((nDirection == | ||
738 | 1) ? FIELD_SET(0, | ||
739 | DE_CONTROL, | ||
740 | DIRECTION, | ||
741 | RIGHT_TO_LEFT) | ||
742 | : FIELD_SET(0, DE_CONTROL, | ||
743 | DIRECTION, | ||
744 | LEFT_TO_RIGHT)) | | ||
745 | FIELD_SET(0, DE_CONTROL, STATUS, START); | ||
746 | |||
747 | SMTC_write2Dreg(DE_CONTROL, de_ctrl); | ||
748 | |||
749 | src_X += (opSign * xWidth); | ||
750 | dst_X += (opSign * xWidth); | ||
751 | dst_width -= xWidth; | ||
752 | |||
753 | if (dst_width <= 0) { | ||
754 | /* ROP2 operation is complete */ | ||
755 | break; | ||
756 | } | ||
757 | |||
758 | if (xWidth > dst_width) | ||
759 | xWidth = dst_width; | ||
760 | } | ||
761 | } else { | ||
762 | deWaitForNotBusy(); | ||
763 | SMTC_write2Dreg(DE_SOURCE, | ||
764 | FIELD_SET(0, DE_SOURCE, WRAP, DISABLE) | | ||
765 | FIELD_VALUE(0, DE_SOURCE, X_K1, src_X) | | ||
766 | FIELD_VALUE(0, DE_SOURCE, Y_K2, src_Y)); | ||
767 | |||
768 | SMTC_write2Dreg(DE_DESTINATION, | ||
769 | FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) | | ||
770 | FIELD_VALUE(0, DE_DESTINATION, X, dst_X) | | ||
771 | FIELD_VALUE(0, DE_DESTINATION, Y, dst_Y)); | ||
772 | |||
773 | SMTC_write2Dreg(DE_DIMENSION, | ||
774 | FIELD_VALUE(0, DE_DIMENSION, X, dst_width) | | ||
775 | FIELD_VALUE(0, DE_DIMENSION, Y_ET, dst_height)); | ||
776 | |||
777 | de_ctrl = FIELD_VALUE(0, DE_CONTROL, ROP, nROP2) | | ||
778 | nTransparent | | ||
779 | FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) | | ||
780 | FIELD_SET(0, DE_CONTROL, COMMAND, BITBLT) | | ||
781 | ((nDirection == 1) ? FIELD_SET(0, DE_CONTROL, DIRECTION, | ||
782 | RIGHT_TO_LEFT) | ||
783 | : FIELD_SET(0, DE_CONTROL, DIRECTION, | ||
784 | LEFT_TO_RIGHT)) | FIELD_SET(0, DE_CONTROL, | ||
785 | STATUS, START); | ||
786 | SMTC_write2Dreg(DE_CONTROL, de_ctrl); | ||
787 | } | ||
788 | |||
789 | smtc_de_busy = 1; | ||
790 | } | ||
791 | |||
792 | /* | ||
793 | * This function sets the pixel format that will apply to the 2D Engine. | ||
794 | */ | ||
795 | void deSetPixelFormat(unsigned long bpp) | ||
796 | { | ||
797 | unsigned long de_format; | ||
798 | |||
799 | de_format = SMTC_read2Dreg(DE_STRETCH_FORMAT); | ||
800 | |||
801 | switch (bpp) { | ||
802 | case 8: | ||
803 | de_format = | ||
804 | FIELD_SET(de_format, DE_STRETCH_FORMAT, PIXEL_FORMAT, 8); | ||
805 | break; | ||
806 | default: | ||
807 | case 16: | ||
808 | de_format = | ||
809 | FIELD_SET(de_format, DE_STRETCH_FORMAT, PIXEL_FORMAT, 16); | ||
810 | break; | ||
811 | case 32: | ||
812 | de_format = | ||
813 | FIELD_SET(de_format, DE_STRETCH_FORMAT, PIXEL_FORMAT, 32); | ||
814 | break; | ||
815 | } | ||
816 | |||
817 | SMTC_write2Dreg(DE_STRETCH_FORMAT, de_format); | ||
818 | } | ||
819 | |||
820 | /* | ||
821 | * System memory to Video memory monochrome expansion. | ||
822 | * | ||
823 | * Source is monochrome image in system memory. This function expands the | ||
824 | * monochrome data to color image in video memory. | ||
825 | */ | ||
826 | |||
827 | long deSystemMem2VideoMemMonoBlt(const char *pSrcbuf, | ||
828 | long srcDelta, | ||
829 | unsigned long startBit, | ||
830 | unsigned long dBase, | ||
831 | unsigned long dPitch, | ||
832 | unsigned long bpp, | ||
833 | unsigned long dx, unsigned long dy, | ||
834 | unsigned long width, unsigned long height, | ||
835 | unsigned long fColor, | ||
836 | unsigned long bColor, | ||
837 | unsigned long rop2) { | ||
838 | unsigned long bytePerPixel; | ||
839 | unsigned long ulBytesPerScan; | ||
840 | unsigned long ul4BytesPerScan; | ||
841 | unsigned long ulBytesRemain; | ||
842 | unsigned long de_ctrl = 0; | ||
843 | unsigned char ajRemain[4]; | ||
844 | long i, j; | ||
845 | |||
846 | bytePerPixel = bpp / 8; | ||
847 | |||
848 | /* Just make sure the start bit is within legal range */ | ||
849 | startBit &= 7; | ||
850 | |||
851 | ulBytesPerScan = (width + startBit + 7) / 8; | ||
852 | ul4BytesPerScan = ulBytesPerScan & ~3; | ||
853 | ulBytesRemain = ulBytesPerScan & 3; | ||
854 | |||
855 | if (smtc_de_busy) | ||
856 | deWaitForNotBusy(); | ||
857 | |||
858 | /* | ||
859 | * 2D Source Base. Use 0 for HOST Blt. | ||
860 | */ | ||
861 | |||
862 | SMTC_write2Dreg(DE_WINDOW_SOURCE_BASE, 0); | ||
863 | |||
864 | /* | ||
865 | * 2D Destination Base. | ||
866 | * | ||
867 | * It is an address offset (128 bit aligned) from the beginning of | ||
868 | * frame buffer. | ||
869 | */ | ||
870 | |||
871 | SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, dBase); | ||
872 | |||
873 | if (dPitch) { | ||
874 | |||
875 | /* | ||
876 | * Program pitch (distance between the 1st points of two | ||
877 | * adjacent lines). | ||
878 | * | ||
879 | * Note that input pitch is BYTE value, but the 2D Pitch | ||
880 | * register uses pixel values. Need Byte to pixel convertion. | ||
881 | */ | ||
882 | |||
883 | SMTC_write2Dreg(DE_PITCH, | ||
884 | FIELD_VALUE(0, DE_PITCH, DESTINATION, | ||
885 | dPitch / | ||
886 | bytePerPixel) | FIELD_VALUE(0, | ||
887 | DE_PITCH, | ||
888 | SOURCE, | ||
889 | dPitch / | ||
890 | bytePerPixel)); | ||
891 | |||
892 | /* Screen Window width in Pixels. | ||
893 | * | ||
894 | * 2D engine uses this value to calculate the linear address in | ||
895 | * frame buffer for a given point. | ||
896 | */ | ||
897 | |||
898 | SMTC_write2Dreg(DE_WINDOW_WIDTH, | ||
899 | FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, | ||
900 | (dPitch / | ||
901 | bytePerPixel)) | FIELD_VALUE(0, | ||
902 | DE_WINDOW_WIDTH, | ||
903 | SOURCE, | ||
904 | (dPitch | ||
905 | / | ||
906 | bytePerPixel))); | ||
907 | } | ||
908 | /* Note: For 2D Source in Host Write, only X_K1 field is needed, and | ||
909 | * Y_K2 field is not used. For mono bitmap, use startBit for X_K1. | ||
910 | */ | ||
911 | |||
912 | SMTC_write2Dreg(DE_SOURCE, | ||
913 | FIELD_SET(0, DE_SOURCE, WRAP, DISABLE) | | ||
914 | FIELD_VALUE(0, DE_SOURCE, X_K1, startBit) | | ||
915 | FIELD_VALUE(0, DE_SOURCE, Y_K2, 0)); | ||
916 | |||
917 | SMTC_write2Dreg(DE_DESTINATION, | ||
918 | FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) | | ||
919 | FIELD_VALUE(0, DE_DESTINATION, X, dx) | | ||
920 | FIELD_VALUE(0, DE_DESTINATION, Y, dy)); | ||
921 | |||
922 | SMTC_write2Dreg(DE_DIMENSION, | ||
923 | FIELD_VALUE(0, DE_DIMENSION, X, width) | | ||
924 | FIELD_VALUE(0, DE_DIMENSION, Y_ET, height)); | ||
925 | |||
926 | SMTC_write2Dreg(DE_FOREGROUND, fColor); | ||
927 | SMTC_write2Dreg(DE_BACKGROUND, bColor); | ||
928 | |||
929 | if (bpp) | ||
930 | deSetPixelFormat(bpp); | ||
931 | /* Set the pixel format of the destination */ | ||
932 | |||
933 | de_ctrl = FIELD_VALUE(0, DE_CONTROL, ROP, rop2) | | ||
934 | FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) | | ||
935 | FIELD_SET(0, DE_CONTROL, COMMAND, HOST_WRITE) | | ||
936 | FIELD_SET(0, DE_CONTROL, HOST, MONO) | | ||
937 | FIELD_SET(0, DE_CONTROL, STATUS, START); | ||
938 | |||
939 | SMTC_write2Dreg(DE_CONTROL, de_ctrl | deGetTransparency()); | ||
940 | |||
941 | /* Write MONO data (line by line) to 2D Engine data port */ | ||
942 | for (i = 0; i < height; i++) { | ||
943 | /* For each line, send the data in chunks of 4 bytes */ | ||
944 | for (j = 0; j < (ul4BytesPerScan / 4); j++) | ||
945 | SMTC_write2Ddataport(0, | ||
946 | *(unsigned long *)(pSrcbuf + | ||
947 | (j * 4))); | ||
948 | |||
949 | if (ulBytesRemain) { | ||
950 | memcpy(ajRemain, pSrcbuf + ul4BytesPerScan, | ||
951 | ulBytesRemain); | ||
952 | SMTC_write2Ddataport(0, *(unsigned long *)ajRemain); | ||
953 | } | ||
954 | |||
955 | pSrcbuf += srcDelta; | ||
956 | } | ||
957 | smtc_de_busy = 1; | ||
958 | |||
959 | return 0; | ||
960 | } | ||
961 | |||
962 | /* | ||
963 | * This function gets the transparency status from DE_CONTROL register. | ||
964 | * It returns a double word with the transparent fields properly set, | ||
965 | * while other fields are 0. | ||
966 | */ | ||
967 | unsigned long deGetTransparency(void) | ||
968 | { | ||
969 | unsigned long de_ctrl; | ||
970 | |||
971 | de_ctrl = SMTC_read2Dreg(DE_CONTROL); | ||
972 | |||
973 | de_ctrl &= | ||
974 | FIELD_MASK(DE_CONTROL_TRANSPARENCY_MATCH) | | ||
975 | FIELD_MASK(DE_CONTROL_TRANSPARENCY_SELECT) | | ||
976 | FIELD_MASK(DE_CONTROL_TRANSPARENCY); | ||
977 | |||
978 | return de_ctrl; | ||
979 | } | ||
diff --git a/drivers/staging/sm7xx/smtc2d.h b/drivers/staging/sm7xx/smtc2d.h new file mode 100644 index 000000000000..38d0c335322b --- /dev/null +++ b/drivers/staging/sm7xx/smtc2d.h | |||
@@ -0,0 +1,530 @@ | |||
1 | /* | ||
2 | * Silicon Motion SM712 2D drawing engine functions. | ||
3 | * | ||
4 | * Copyright (C) 2006 Silicon Motion Technology Corp. | ||
5 | * Author: Ge Wang, gewang@siliconmotion.com | ||
6 | * | ||
7 | * Copyright (C) 2009 Lemote, Inc. | ||
8 | * Author: Wu Zhangjin, wuzj@lemote.com | ||
9 | * | ||
10 | * This file is subject to the terms and conditions of the GNU General Public | ||
11 | * License. See the file COPYING in the main directory of this archive for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef NULL | ||
16 | #define NULL 0 | ||
17 | #endif | ||
18 | |||
19 | /* Internal macros */ | ||
20 | |||
21 | #define _F_START(f) (0 ? f) | ||
22 | #define _F_END(f) (1 ? f) | ||
23 | #define _F_SIZE(f) (1 + _F_END(f) - _F_START(f)) | ||
24 | #define _F_MASK(f) (((1ULL << _F_SIZE(f)) - 1) << _F_START(f)) | ||
25 | #define _F_NORMALIZE(v, f) (((v) & _F_MASK(f)) >> _F_START(f)) | ||
26 | #define _F_DENORMALIZE(v, f) (((v) << _F_START(f)) & _F_MASK(f)) | ||
27 | |||
28 | /* Global macros */ | ||
29 | |||
30 | #define FIELD_GET(x, reg, field) \ | ||
31 | ( \ | ||
32 | _F_NORMALIZE((x), reg ## _ ## field) \ | ||
33 | ) | ||
34 | |||
35 | #define FIELD_SET(x, reg, field, value) \ | ||
36 | ( \ | ||
37 | (x & ~_F_MASK(reg ## _ ## field)) \ | ||
38 | | _F_DENORMALIZE(reg ## _ ## field ## _ ## value, reg ## _ ## field) \ | ||
39 | ) | ||
40 | |||
41 | #define FIELD_VALUE(x, reg, field, value) \ | ||
42 | ( \ | ||
43 | (x & ~_F_MASK(reg ## _ ## field)) \ | ||
44 | | _F_DENORMALIZE(value, reg ## _ ## field) \ | ||
45 | ) | ||
46 | |||
47 | #define FIELD_CLEAR(reg, field) \ | ||
48 | ( \ | ||
49 | ~_F_MASK(reg ## _ ## field) \ | ||
50 | ) | ||
51 | |||
52 | /* Field Macros */ | ||
53 | |||
54 | #define FIELD_START(field) (0 ? field) | ||
55 | #define FIELD_END(field) (1 ? field) | ||
56 | #define FIELD_SIZE(field) \ | ||
57 | (1 + FIELD_END(field) - FIELD_START(field)) | ||
58 | |||
59 | #define FIELD_MASK(field) \ | ||
60 | (((1 << (FIELD_SIZE(field)-1)) \ | ||
61 | | ((1 << (FIELD_SIZE(field)-1)) - 1)) \ | ||
62 | << FIELD_START(field)) | ||
63 | |||
64 | #define FIELD_NORMALIZE(reg, field) \ | ||
65 | (((reg) & FIELD_MASK(field)) >> FIELD_START(field)) | ||
66 | |||
67 | #define FIELD_DENORMALIZE(field, value) \ | ||
68 | (((value) << FIELD_START(field)) & FIELD_MASK(field)) | ||
69 | |||
70 | #define FIELD_INIT(reg, field, value) \ | ||
71 | FIELD_DENORMALIZE(reg ## _ ## field, \ | ||
72 | reg ## _ ## field ## _ ## value) | ||
73 | |||
74 | #define FIELD_INIT_VAL(reg, field, value) \ | ||
75 | (FIELD_DENORMALIZE(reg ## _ ## field, value)) | ||
76 | |||
77 | #define FIELD_VAL_SET(x, r, f, v) ({ \ | ||
78 | x = (x & ~FIELD_MASK(r ## _ ## f)) \ | ||
79 | | FIELD_DENORMALIZE(r ## _ ## f, r ## _ ## f ## _ ## v) \ | ||
80 | }) | ||
81 | |||
82 | #define RGB(r, g, b) ((unsigned long)(((r) << 16) | ((g) << 8) | (b))) | ||
83 | |||
84 | /* Transparent info definition */ | ||
85 | typedef struct { | ||
86 | unsigned long match; /* Matching pixel is OPAQUE/TRANSPARENT */ | ||
87 | unsigned long select; /* Transparency controlled by SRC/DST */ | ||
88 | unsigned long control; /* ENABLE/DISABLE transparency */ | ||
89 | unsigned long color; /* Transparent color */ | ||
90 | } Transparent, *pTransparent; | ||
91 | |||
92 | #define PIXEL_DEPTH_1_BP 0 /* 1 bit per pixel */ | ||
93 | #define PIXEL_DEPTH_8_BPP 1 /* 8 bits per pixel */ | ||
94 | #define PIXEL_DEPTH_16_BPP 2 /* 16 bits per pixel */ | ||
95 | #define PIXEL_DEPTH_32_BPP 3 /* 32 bits per pixel */ | ||
96 | #define PIXEL_DEPTH_YUV422 8 /* 16 bits per pixel YUV422 */ | ||
97 | #define PIXEL_DEPTH_YUV420 9 /* 16 bits per pixel YUV420 */ | ||
98 | |||
99 | #define PATTERN_WIDTH 8 | ||
100 | #define PATTERN_HEIGHT 8 | ||
101 | |||
102 | #define TOP_TO_BOTTOM 0 | ||
103 | #define BOTTOM_TO_TOP 1 | ||
104 | #define RIGHT_TO_LEFT BOTTOM_TO_TOP | ||
105 | #define LEFT_TO_RIGHT TOP_TO_BOTTOM | ||
106 | |||
107 | /* Constants used in Transparent structure */ | ||
108 | #define MATCH_OPAQUE 0x00000000 | ||
109 | #define MATCH_TRANSPARENT 0x00000400 | ||
110 | #define SOURCE 0x00000000 | ||
111 | #define DESTINATION 0x00000200 | ||
112 | |||
113 | /* 2D registers. */ | ||
114 | |||
115 | #define DE_SOURCE 0x000000 | ||
116 | #define DE_SOURCE_WRAP 31 : 31 | ||
117 | #define DE_SOURCE_WRAP_DISABLE 0 | ||
118 | #define DE_SOURCE_WRAP_ENABLE 1 | ||
119 | #define DE_SOURCE_X_K1 29 : 16 | ||
120 | #define DE_SOURCE_Y_K2 15 : 0 | ||
121 | |||
122 | #define DE_DESTINATION 0x000004 | ||
123 | #define DE_DESTINATION_WRAP 31 : 31 | ||
124 | #define DE_DESTINATION_WRAP_DISABLE 0 | ||
125 | #define DE_DESTINATION_WRAP_ENABLE 1 | ||
126 | #define DE_DESTINATION_X 28 : 16 | ||
127 | #define DE_DESTINATION_Y 15 : 0 | ||
128 | |||
129 | #define DE_DIMENSION 0x000008 | ||
130 | #define DE_DIMENSION_X 28 : 16 | ||
131 | #define DE_DIMENSION_Y_ET 15 : 0 | ||
132 | |||
133 | #define DE_CONTROL 0x00000C | ||
134 | #define DE_CONTROL_STATUS 31 : 31 | ||
135 | #define DE_CONTROL_STATUS_STOP 0 | ||
136 | #define DE_CONTROL_STATUS_START 1 | ||
137 | #define DE_CONTROL_PATTERN 30 : 30 | ||
138 | #define DE_CONTROL_PATTERN_MONO 0 | ||
139 | #define DE_CONTROL_PATTERN_COLOR 1 | ||
140 | #define DE_CONTROL_UPDATE_DESTINATION_X 29 : 29 | ||
141 | #define DE_CONTROL_UPDATE_DESTINATION_X_DISABLE 0 | ||
142 | #define DE_CONTROL_UPDATE_DESTINATION_X_ENABLE 1 | ||
143 | #define DE_CONTROL_QUICK_START 28 : 28 | ||
144 | #define DE_CONTROL_QUICK_START_DISABLE 0 | ||
145 | #define DE_CONTROL_QUICK_START_ENABLE 1 | ||
146 | #define DE_CONTROL_DIRECTION 27 : 27 | ||
147 | #define DE_CONTROL_DIRECTION_LEFT_TO_RIGHT 0 | ||
148 | #define DE_CONTROL_DIRECTION_RIGHT_TO_LEFT 1 | ||
149 | #define DE_CONTROL_MAJOR 26 : 26 | ||
150 | #define DE_CONTROL_MAJOR_X 0 | ||
151 | #define DE_CONTROL_MAJOR_Y 1 | ||
152 | #define DE_CONTROL_STEP_X 25 : 25 | ||
153 | #define DE_CONTROL_STEP_X_POSITIVE 1 | ||
154 | #define DE_CONTROL_STEP_X_NEGATIVE 0 | ||
155 | #define DE_CONTROL_STEP_Y 24 : 24 | ||
156 | #define DE_CONTROL_STEP_Y_POSITIVE 1 | ||
157 | #define DE_CONTROL_STEP_Y_NEGATIVE 0 | ||
158 | #define DE_CONTROL_STRETCH 23 : 23 | ||
159 | #define DE_CONTROL_STRETCH_DISABLE 0 | ||
160 | #define DE_CONTROL_STRETCH_ENABLE 1 | ||
161 | #define DE_CONTROL_HOST 22 : 22 | ||
162 | #define DE_CONTROL_HOST_COLOR 0 | ||
163 | #define DE_CONTROL_HOST_MONO 1 | ||
164 | #define DE_CONTROL_LAST_PIXEL 21 : 21 | ||
165 | #define DE_CONTROL_LAST_PIXEL_OFF 0 | ||
166 | #define DE_CONTROL_LAST_PIXEL_ON 1 | ||
167 | #define DE_CONTROL_COMMAND 20 : 16 | ||
168 | #define DE_CONTROL_COMMAND_BITBLT 0 | ||
169 | #define DE_CONTROL_COMMAND_RECTANGLE_FILL 1 | ||
170 | #define DE_CONTROL_COMMAND_DE_TILE 2 | ||
171 | #define DE_CONTROL_COMMAND_TRAPEZOID_FILL 3 | ||
172 | #define DE_CONTROL_COMMAND_ALPHA_BLEND 4 | ||
173 | #define DE_CONTROL_COMMAND_RLE_STRIP 5 | ||
174 | #define DE_CONTROL_COMMAND_SHORT_STROKE 6 | ||
175 | #define DE_CONTROL_COMMAND_LINE_DRAW 7 | ||
176 | #define DE_CONTROL_COMMAND_HOST_WRITE 8 | ||
177 | #define DE_CONTROL_COMMAND_HOST_READ 9 | ||
178 | #define DE_CONTROL_COMMAND_HOST_WRITE_BOTTOM_UP 10 | ||
179 | #define DE_CONTROL_COMMAND_ROTATE 11 | ||
180 | #define DE_CONTROL_COMMAND_FONT 12 | ||
181 | #define DE_CONTROL_COMMAND_TEXTURE_LOAD 15 | ||
182 | #define DE_CONTROL_ROP_SELECT 15 : 15 | ||
183 | #define DE_CONTROL_ROP_SELECT_ROP3 0 | ||
184 | #define DE_CONTROL_ROP_SELECT_ROP2 1 | ||
185 | #define DE_CONTROL_ROP2_SOURCE 14 : 14 | ||
186 | #define DE_CONTROL_ROP2_SOURCE_BITMAP 0 | ||
187 | #define DE_CONTROL_ROP2_SOURCE_PATTERN 1 | ||
188 | #define DE_CONTROL_MONO_DATA 13 : 12 | ||
189 | #define DE_CONTROL_MONO_DATA_NOT_PACKED 0 | ||
190 | #define DE_CONTROL_MONO_DATA_8_PACKED 1 | ||
191 | #define DE_CONTROL_MONO_DATA_16_PACKED 2 | ||
192 | #define DE_CONTROL_MONO_DATA_32_PACKED 3 | ||
193 | #define DE_CONTROL_REPEAT_ROTATE 11 : 11 | ||
194 | #define DE_CONTROL_REPEAT_ROTATE_DISABLE 0 | ||
195 | #define DE_CONTROL_REPEAT_ROTATE_ENABLE 1 | ||
196 | #define DE_CONTROL_TRANSPARENCY_MATCH 10 : 10 | ||
197 | #define DE_CONTROL_TRANSPARENCY_MATCH_OPAQUE 0 | ||
198 | #define DE_CONTROL_TRANSPARENCY_MATCH_TRANSPARENT 1 | ||
199 | #define DE_CONTROL_TRANSPARENCY_SELECT 9 : 9 | ||
200 | #define DE_CONTROL_TRANSPARENCY_SELECT_SOURCE 0 | ||
201 | #define DE_CONTROL_TRANSPARENCY_SELECT_DESTINATION 1 | ||
202 | #define DE_CONTROL_TRANSPARENCY 8 : 8 | ||
203 | #define DE_CONTROL_TRANSPARENCY_DISABLE 0 | ||
204 | #define DE_CONTROL_TRANSPARENCY_ENABLE 1 | ||
205 | #define DE_CONTROL_ROP 7 : 0 | ||
206 | |||
207 | /* Pseudo fields. */ | ||
208 | |||
209 | #define DE_CONTROL_SHORT_STROKE_DIR 27 : 24 | ||
210 | #define DE_CONTROL_SHORT_STROKE_DIR_225 0 | ||
211 | #define DE_CONTROL_SHORT_STROKE_DIR_135 1 | ||
212 | #define DE_CONTROL_SHORT_STROKE_DIR_315 2 | ||
213 | #define DE_CONTROL_SHORT_STROKE_DIR_45 3 | ||
214 | #define DE_CONTROL_SHORT_STROKE_DIR_270 4 | ||
215 | #define DE_CONTROL_SHORT_STROKE_DIR_90 5 | ||
216 | #define DE_CONTROL_SHORT_STROKE_DIR_180 8 | ||
217 | #define DE_CONTROL_SHORT_STROKE_DIR_0 10 | ||
218 | #define DE_CONTROL_ROTATION 25 : 24 | ||
219 | #define DE_CONTROL_ROTATION_0 0 | ||
220 | #define DE_CONTROL_ROTATION_270 1 | ||
221 | #define DE_CONTROL_ROTATION_90 2 | ||
222 | #define DE_CONTROL_ROTATION_180 3 | ||
223 | |||
224 | #define DE_PITCH 0x000010 | ||
225 | #define DE_PITCH_DESTINATION 28 : 16 | ||
226 | #define DE_PITCH_SOURCE 12 : 0 | ||
227 | |||
228 | #define DE_FOREGROUND 0x000014 | ||
229 | #define DE_FOREGROUND_COLOR 31 : 0 | ||
230 | |||
231 | #define DE_BACKGROUND 0x000018 | ||
232 | #define DE_BACKGROUND_COLOR 31 : 0 | ||
233 | |||
234 | #define DE_STRETCH_FORMAT 0x00001C | ||
235 | #define DE_STRETCH_FORMAT_PATTERN_XY 30 : 30 | ||
236 | #define DE_STRETCH_FORMAT_PATTERN_XY_NORMAL 0 | ||
237 | #define DE_STRETCH_FORMAT_PATTERN_XY_OVERWRITE 1 | ||
238 | #define DE_STRETCH_FORMAT_PATTERN_Y 29 : 27 | ||
239 | #define DE_STRETCH_FORMAT_PATTERN_X 25 : 23 | ||
240 | #define DE_STRETCH_FORMAT_PIXEL_FORMAT 21 : 20 | ||
241 | #define DE_STRETCH_FORMAT_PIXEL_FORMAT_8 0 | ||
242 | #define DE_STRETCH_FORMAT_PIXEL_FORMAT_16 1 | ||
243 | #define DE_STRETCH_FORMAT_PIXEL_FORMAT_24 3 | ||
244 | #define DE_STRETCH_FORMAT_PIXEL_FORMAT_32 2 | ||
245 | #define DE_STRETCH_FORMAT_ADDRESSING 19 : 16 | ||
246 | #define DE_STRETCH_FORMAT_ADDRESSING_XY 0 | ||
247 | #define DE_STRETCH_FORMAT_ADDRESSING_LINEAR 15 | ||
248 | #define DE_STRETCH_FORMAT_SOURCE_HEIGHT 11 : 0 | ||
249 | |||
250 | #define DE_COLOR_COMPARE 0x000020 | ||
251 | #define DE_COLOR_COMPARE_COLOR 23 : 0 | ||
252 | |||
253 | #define DE_COLOR_COMPARE_MASK 0x000024 | ||
254 | #define DE_COLOR_COMPARE_MASK_MASKS 23 : 0 | ||
255 | |||
256 | #define DE_MASKS 0x000028 | ||
257 | #define DE_MASKS_BYTE_MASK 31 : 16 | ||
258 | #define DE_MASKS_BIT_MASK 15 : 0 | ||
259 | |||
260 | #define DE_CLIP_TL 0x00002C | ||
261 | #define DE_CLIP_TL_TOP 31 : 16 | ||
262 | #define DE_CLIP_TL_STATUS 13 : 13 | ||
263 | #define DE_CLIP_TL_STATUS_DISABLE 0 | ||
264 | #define DE_CLIP_TL_STATUS_ENABLE 1 | ||
265 | #define DE_CLIP_TL_INHIBIT 12 : 12 | ||
266 | #define DE_CLIP_TL_INHIBIT_OUTSIDE 0 | ||
267 | #define DE_CLIP_TL_INHIBIT_INSIDE 1 | ||
268 | #define DE_CLIP_TL_LEFT 11 : 0 | ||
269 | |||
270 | #define DE_CLIP_BR 0x000030 | ||
271 | #define DE_CLIP_BR_BOTTOM 31 : 16 | ||
272 | #define DE_CLIP_BR_RIGHT 12 : 0 | ||
273 | |||
274 | #define DE_MONO_PATTERN_LOW 0x000034 | ||
275 | #define DE_MONO_PATTERN_LOW_PATTERN 31 : 0 | ||
276 | |||
277 | #define DE_MONO_PATTERN_HIGH 0x000038 | ||
278 | #define DE_MONO_PATTERN_HIGH_PATTERN 31 : 0 | ||
279 | |||
280 | #define DE_WINDOW_WIDTH 0x00003C | ||
281 | #define DE_WINDOW_WIDTH_DESTINATION 28 : 16 | ||
282 | #define DE_WINDOW_WIDTH_SOURCE 12 : 0 | ||
283 | |||
284 | #define DE_WINDOW_SOURCE_BASE 0x000040 | ||
285 | #define DE_WINDOW_SOURCE_BASE_EXT 27 : 27 | ||
286 | #define DE_WINDOW_SOURCE_BASE_EXT_LOCAL 0 | ||
287 | #define DE_WINDOW_SOURCE_BASE_EXT_EXTERNAL 1 | ||
288 | #define DE_WINDOW_SOURCE_BASE_CS 26 : 26 | ||
289 | #define DE_WINDOW_SOURCE_BASE_CS_0 0 | ||
290 | #define DE_WINDOW_SOURCE_BASE_CS_1 1 | ||
291 | #define DE_WINDOW_SOURCE_BASE_ADDRESS 25 : 0 | ||
292 | |||
293 | #define DE_WINDOW_DESTINATION_BASE 0x000044 | ||
294 | #define DE_WINDOW_DESTINATION_BASE_EXT 27 : 27 | ||
295 | #define DE_WINDOW_DESTINATION_BASE_EXT_LOCAL 0 | ||
296 | #define DE_WINDOW_DESTINATION_BASE_EXT_EXTERNAL 1 | ||
297 | #define DE_WINDOW_DESTINATION_BASE_CS 26 : 26 | ||
298 | #define DE_WINDOW_DESTINATION_BASE_CS_0 0 | ||
299 | #define DE_WINDOW_DESTINATION_BASE_CS_1 1 | ||
300 | #define DE_WINDOW_DESTINATION_BASE_ADDRESS 25 : 0 | ||
301 | |||
302 | #define DE_ALPHA 0x000048 | ||
303 | #define DE_ALPHA_VALUE 7 : 0 | ||
304 | |||
305 | #define DE_WRAP 0x00004C | ||
306 | #define DE_WRAP_X 31 : 16 | ||
307 | #define DE_WRAP_Y 15 : 0 | ||
308 | |||
309 | #define DE_STATUS 0x000050 | ||
310 | #define DE_STATUS_CSC 1 : 1 | ||
311 | #define DE_STATUS_CSC_CLEAR 0 | ||
312 | #define DE_STATUS_CSC_NOT_ACTIVE 0 | ||
313 | #define DE_STATUS_CSC_ACTIVE 1 | ||
314 | #define DE_STATUS_2D 0 : 0 | ||
315 | #define DE_STATUS_2D_CLEAR 0 | ||
316 | #define DE_STATUS_2D_NOT_ACTIVE 0 | ||
317 | #define DE_STATUS_2D_ACTIVE 1 | ||
318 | |||
319 | /* Color Space Conversion registers. */ | ||
320 | |||
321 | #define CSC_Y_SOURCE_BASE 0x0000C8 | ||
322 | #define CSC_Y_SOURCE_BASE_EXT 27 : 27 | ||
323 | #define CSC_Y_SOURCE_BASE_EXT_LOCAL 0 | ||
324 | #define CSC_Y_SOURCE_BASE_EXT_EXTERNAL 1 | ||
325 | #define CSC_Y_SOURCE_BASE_CS 26 : 26 | ||
326 | #define CSC_Y_SOURCE_BASE_CS_0 0 | ||
327 | #define CSC_Y_SOURCE_BASE_CS_1 1 | ||
328 | #define CSC_Y_SOURCE_BASE_ADDRESS 25 : 0 | ||
329 | |||
330 | #define CSC_CONSTANTS 0x0000CC | ||
331 | #define CSC_CONSTANTS_Y 31 : 24 | ||
332 | #define CSC_CONSTANTS_R 23 : 16 | ||
333 | #define CSC_CONSTANTS_G 15 : 8 | ||
334 | #define CSC_CONSTANTS_B 7 : 0 | ||
335 | |||
336 | #define CSC_Y_SOURCE_X 0x0000D0 | ||
337 | #define CSC_Y_SOURCE_X_INTEGER 26 : 16 | ||
338 | #define CSC_Y_SOURCE_X_FRACTION 15 : 3 | ||
339 | |||
340 | #define CSC_Y_SOURCE_Y 0x0000D4 | ||
341 | #define CSC_Y_SOURCE_Y_INTEGER 27 : 16 | ||
342 | #define CSC_Y_SOURCE_Y_FRACTION 15 : 3 | ||
343 | |||
344 | #define CSC_U_SOURCE_BASE 0x0000D8 | ||
345 | #define CSC_U_SOURCE_BASE_EXT 27 : 27 | ||
346 | #define CSC_U_SOURCE_BASE_EXT_LOCAL 0 | ||
347 | #define CSC_U_SOURCE_BASE_EXT_EXTERNAL 1 | ||
348 | #define CSC_U_SOURCE_BASE_CS 26 : 26 | ||
349 | #define CSC_U_SOURCE_BASE_CS_0 0 | ||
350 | #define CSC_U_SOURCE_BASE_CS_1 1 | ||
351 | #define CSC_U_SOURCE_BASE_ADDRESS 25 : 0 | ||
352 | |||
353 | #define CSC_V_SOURCE_BASE 0x0000DC | ||
354 | #define CSC_V_SOURCE_BASE_EXT 27 : 27 | ||
355 | #define CSC_V_SOURCE_BASE_EXT_LOCAL 0 | ||
356 | #define CSC_V_SOURCE_BASE_EXT_EXTERNAL 1 | ||
357 | #define CSC_V_SOURCE_BASE_CS 26 : 26 | ||
358 | #define CSC_V_SOURCE_BASE_CS_0 0 | ||
359 | #define CSC_V_SOURCE_BASE_CS_1 1 | ||
360 | #define CSC_V_SOURCE_BASE_ADDRESS 25 : 0 | ||
361 | |||
362 | #define CSC_SOURCE_DIMENSION 0x0000E0 | ||
363 | #define CSC_SOURCE_DIMENSION_X 31 : 16 | ||
364 | #define CSC_SOURCE_DIMENSION_Y 15 : 0 | ||
365 | |||
366 | #define CSC_SOURCE_PITCH 0x0000E4 | ||
367 | #define CSC_SOURCE_PITCH_Y 31 : 16 | ||
368 | #define CSC_SOURCE_PITCH_UV 15 : 0 | ||
369 | |||
370 | #define CSC_DESTINATION 0x0000E8 | ||
371 | #define CSC_DESTINATION_WRAP 31 : 31 | ||
372 | #define CSC_DESTINATION_WRAP_DISABLE 0 | ||
373 | #define CSC_DESTINATION_WRAP_ENABLE 1 | ||
374 | #define CSC_DESTINATION_X 27 : 16 | ||
375 | #define CSC_DESTINATION_Y 11 : 0 | ||
376 | |||
377 | #define CSC_DESTINATION_DIMENSION 0x0000EC | ||
378 | #define CSC_DESTINATION_DIMENSION_X 31 : 16 | ||
379 | #define CSC_DESTINATION_DIMENSION_Y 15 : 0 | ||
380 | |||
381 | #define CSC_DESTINATION_PITCH 0x0000F0 | ||
382 | #define CSC_DESTINATION_PITCH_X 31 : 16 | ||
383 | #define CSC_DESTINATION_PITCH_Y 15 : 0 | ||
384 | |||
385 | #define CSC_SCALE_FACTOR 0x0000F4 | ||
386 | #define CSC_SCALE_FACTOR_HORIZONTAL 31 : 16 | ||
387 | #define CSC_SCALE_FACTOR_VERTICAL 15 : 0 | ||
388 | |||
389 | #define CSC_DESTINATION_BASE 0x0000F8 | ||
390 | #define CSC_DESTINATION_BASE_EXT 27 : 27 | ||
391 | #define CSC_DESTINATION_BASE_EXT_LOCAL 0 | ||
392 | #define CSC_DESTINATION_BASE_EXT_EXTERNAL 1 | ||
393 | #define CSC_DESTINATION_BASE_CS 26 : 26 | ||
394 | #define CSC_DESTINATION_BASE_CS_0 0 | ||
395 | #define CSC_DESTINATION_BASE_CS_1 1 | ||
396 | #define CSC_DESTINATION_BASE_ADDRESS 25 : 0 | ||
397 | |||
398 | #define CSC_CONTROL 0x0000FC | ||
399 | #define CSC_CONTROL_STATUS 31 : 31 | ||
400 | #define CSC_CONTROL_STATUS_STOP 0 | ||
401 | #define CSC_CONTROL_STATUS_START 1 | ||
402 | #define CSC_CONTROL_SOURCE_FORMAT 30 : 28 | ||
403 | #define CSC_CONTROL_SOURCE_FORMAT_YUV422 0 | ||
404 | #define CSC_CONTROL_SOURCE_FORMAT_YUV420I 1 | ||
405 | #define CSC_CONTROL_SOURCE_FORMAT_YUV420 2 | ||
406 | #define CSC_CONTROL_SOURCE_FORMAT_YVU9 3 | ||
407 | #define CSC_CONTROL_SOURCE_FORMAT_IYU1 4 | ||
408 | #define CSC_CONTROL_SOURCE_FORMAT_IYU2 5 | ||
409 | #define CSC_CONTROL_SOURCE_FORMAT_RGB565 6 | ||
410 | #define CSC_CONTROL_SOURCE_FORMAT_RGB8888 7 | ||
411 | #define CSC_CONTROL_DESTINATION_FORMAT 27 : 26 | ||
412 | #define CSC_CONTROL_DESTINATION_FORMAT_RGB565 0 | ||
413 | #define CSC_CONTROL_DESTINATION_FORMAT_RGB8888 1 | ||
414 | #define CSC_CONTROL_HORIZONTAL_FILTER 25 : 25 | ||
415 | #define CSC_CONTROL_HORIZONTAL_FILTER_DISABLE 0 | ||
416 | #define CSC_CONTROL_HORIZONTAL_FILTER_ENABLE 1 | ||
417 | #define CSC_CONTROL_VERTICAL_FILTER 24 : 24 | ||
418 | #define CSC_CONTROL_VERTICAL_FILTER_DISABLE 0 | ||
419 | #define CSC_CONTROL_VERTICAL_FILTER_ENABLE 1 | ||
420 | #define CSC_CONTROL_BYTE_ORDER 23 : 23 | ||
421 | #define CSC_CONTROL_BYTE_ORDER_YUYV 0 | ||
422 | #define CSC_CONTROL_BYTE_ORDER_UYVY 1 | ||
423 | |||
424 | #define DE_DATA_PORT_501 0x110000 | ||
425 | #define DE_DATA_PORT_712 0x400000 | ||
426 | #define DE_DATA_PORT_722 0x6000 | ||
427 | |||
428 | /* point to virtual Memory Map IO starting address */ | ||
429 | extern char *smtc_RegBaseAddress; | ||
430 | /* point to virtual video memory starting address */ | ||
431 | extern char *smtc_VRAMBaseAddress; | ||
432 | extern unsigned char smtc_de_busy; | ||
433 | |||
434 | extern unsigned long memRead32(unsigned long nOffset); | ||
435 | extern void memWrite32(unsigned long nOffset, unsigned long nData); | ||
436 | extern unsigned long SMTC_read2Dreg(unsigned long nOffset); | ||
437 | |||
438 | /* 2D functions */ | ||
439 | extern void deInit(unsigned int nModeWidth, unsigned int nModeHeight, | ||
440 | unsigned int bpp); | ||
441 | |||
442 | extern void deWaitForNotBusy(void); | ||
443 | |||
444 | extern void deVerticalLine(unsigned long dst_base, | ||
445 | unsigned long dst_pitch, | ||
446 | unsigned long nX, | ||
447 | unsigned long nY, | ||
448 | unsigned long dst_height, | ||
449 | unsigned long nColor); | ||
450 | |||
451 | extern void deHorizontalLine(unsigned long dst_base, | ||
452 | unsigned long dst_pitch, | ||
453 | unsigned long nX, | ||
454 | unsigned long nY, | ||
455 | unsigned long dst_width, | ||
456 | unsigned long nColor); | ||
457 | |||
458 | extern void deLine(unsigned long dst_base, | ||
459 | unsigned long dst_pitch, | ||
460 | unsigned long nX1, | ||
461 | unsigned long nY1, | ||
462 | unsigned long nX2, | ||
463 | unsigned long nY2, | ||
464 | unsigned long nColor); | ||
465 | |||
466 | extern void deFillRect(unsigned long dst_base, | ||
467 | unsigned long dst_pitch, | ||
468 | unsigned long dst_X, | ||
469 | unsigned long dst_Y, | ||
470 | unsigned long dst_width, | ||
471 | unsigned long dst_height, | ||
472 | unsigned long nColor); | ||
473 | |||
474 | extern void deRotatePattern(unsigned char *pattern_dstaddr, | ||
475 | unsigned long pattern_src_addr, | ||
476 | unsigned long pattern_BPP, | ||
477 | unsigned long pattern_stride, | ||
478 | int patternX, | ||
479 | int patternY); | ||
480 | |||
481 | extern void deCopy(unsigned long dst_base, | ||
482 | unsigned long dst_pitch, | ||
483 | unsigned long dst_BPP, | ||
484 | unsigned long dst_X, | ||
485 | unsigned long dst_Y, | ||
486 | unsigned long dst_width, | ||
487 | unsigned long dst_height, | ||
488 | unsigned long src_base, | ||
489 | unsigned long src_pitch, | ||
490 | unsigned long src_X, | ||
491 | unsigned long src_Y, | ||
492 | pTransparent pTransp, | ||
493 | unsigned char nROP2); | ||
494 | |||
495 | /* | ||
496 | * System memory to Video memory monochrome expansion. | ||
497 | * | ||
498 | * Source is monochrome image in system memory. This function expands the | ||
499 | * monochrome data to color image in video memory. | ||
500 | * | ||
501 | * @pSrcbuf: pointer to start of source buffer in system memory | ||
502 | * @srcDelta: Pitch value (in bytes) of the source buffer, +ive means top | ||
503 | * down and -ive mean button up | ||
504 | * @startBit: Mono data can start at any bit in a byte, this value should | ||
505 | * be 0 to 7 | ||
506 | * @dBase: Address of destination : offset in frame buffer | ||
507 | * @dPitch: Pitch value of destination surface in BYTE | ||
508 | * @bpp: Color depth of destination surface | ||
509 | * @dx, dy: Starting coordinate of destination surface | ||
510 | * @width, height: width and height of rectange in pixel value | ||
511 | * @fColor,bColor: Foreground, Background color (corresponding to a 1, 0 in | ||
512 | * the monochrome data) | ||
513 | * @rop2: ROP value | ||
514 | */ | ||
515 | |||
516 | extern long deSystemMem2VideoMemMonoBlt( | ||
517 | const char *pSrcbuf, | ||
518 | long srcDelta, | ||
519 | unsigned long startBit, | ||
520 | unsigned long dBase, | ||
521 | unsigned long dPitch, | ||
522 | unsigned long bpp, | ||
523 | unsigned long dx, unsigned long dy, | ||
524 | unsigned long width, unsigned long height, | ||
525 | unsigned long fColor, | ||
526 | unsigned long bColor, | ||
527 | unsigned long rop2); | ||
528 | |||
529 | extern unsigned long deGetTransparency(void); | ||
530 | extern void deSetPixelFormat(unsigned long bpp); | ||
diff --git a/drivers/staging/sm7xx/smtcfb.c b/drivers/staging/sm7xx/smtcfb.c new file mode 100644 index 000000000000..161dbc9c1397 --- /dev/null +++ b/drivers/staging/sm7xx/smtcfb.c | |||
@@ -0,0 +1,1253 @@ | |||
1 | /* | ||
2 | * Silicon Motion SM7XX frame buffer device | ||
3 | * | ||
4 | * Copyright (C) 2006 Silicon Motion Technology Corp. | ||
5 | * Authors: Ge Wang, gewang@siliconmotion.com | ||
6 | * Boyod boyod.yang@siliconmotion.com.cn | ||
7 | * | ||
8 | * Copyright (C) 2009 Lemote, Inc. | ||
9 | * Author: Wu Zhangjin, wuzj@lemote.com | ||
10 | * | ||
11 | * This file is subject to the terms and conditions of the GNU General Public | ||
12 | * License. See the file COPYING in the main directory of this archive for | ||
13 | * more details. | ||
14 | * | ||
15 | * Version 0.10.26192.21.01 | ||
16 | * - Add PowerPC/Big endian support | ||
17 | * - Add 2D support for Lynx | ||
18 | * - Verified on2.6.19.2 Boyod.yang <boyod.yang@siliconmotion.com.cn> | ||
19 | * | ||
20 | * Version 0.09.2621.00.01 | ||
21 | * - Only support Linux Kernel's version 2.6.21. | ||
22 | * Boyod.yang <boyod.yang@siliconmotion.com.cn> | ||
23 | * | ||
24 | * Version 0.09 | ||
25 | * - Only support Linux Kernel's version 2.6.12. | ||
26 | * Boyod.yang <boyod.yang@siliconmotion.com.cn> | ||
27 | */ | ||
28 | |||
29 | #ifndef __KERNEL__ | ||
30 | #define __KERNEL__ | ||
31 | #endif | ||
32 | |||
33 | #include <linux/io.h> | ||
34 | #include <linux/fb.h> | ||
35 | #include <linux/pci.h> | ||
36 | #include <linux/init.h> | ||
37 | #include <linux/uaccess.h> | ||
38 | #include <linux/console.h> | ||
39 | #include <linux/screen_info.h> | ||
40 | |||
41 | #ifdef CONFIG_PM | ||
42 | #include <linux/pm.h> | ||
43 | #endif | ||
44 | |||
45 | struct screen_info smtc_screen_info; | ||
46 | |||
47 | #include "smtcfb.h" | ||
48 | #include "smtc2d.h" | ||
49 | |||
50 | #ifdef DEBUG | ||
51 | #define smdbg(format, arg...) printk(KERN_DEBUG format , ## arg) | ||
52 | #else | ||
53 | #define smdbg(format, arg...) | ||
54 | #endif | ||
55 | |||
56 | /* | ||
57 | * Private structure | ||
58 | */ | ||
59 | struct smtcfb_info { | ||
60 | /* | ||
61 | * The following is a pointer to be passed into the | ||
62 | * functions below. The modules outside the main | ||
63 | * voyager.c driver have no knowledge as to what | ||
64 | * is within this structure. | ||
65 | */ | ||
66 | struct fb_info fb; | ||
67 | struct display_switch *dispsw; | ||
68 | struct pci_dev *dev; | ||
69 | signed int currcon; | ||
70 | |||
71 | struct { | ||
72 | u8 red, green, blue; | ||
73 | } palette[NR_RGB]; | ||
74 | |||
75 | u_int palette_size; | ||
76 | }; | ||
77 | |||
78 | struct par_info { | ||
79 | /* | ||
80 | * Hardware | ||
81 | */ | ||
82 | u16 chipID; | ||
83 | unsigned char __iomem *m_pMMIO; | ||
84 | char __iomem *m_pLFB; | ||
85 | char *m_pDPR; | ||
86 | char *m_pVPR; | ||
87 | char *m_pCPR; | ||
88 | |||
89 | u_int width; | ||
90 | u_int height; | ||
91 | u_int hz; | ||
92 | u_long BaseAddressInVRAM; | ||
93 | u8 chipRevID; | ||
94 | }; | ||
95 | |||
96 | struct vesa_mode_table { | ||
97 | char mode_index[6]; | ||
98 | u16 lfb_width; | ||
99 | u16 lfb_height; | ||
100 | u16 lfb_depth; | ||
101 | }; | ||
102 | |||
103 | static struct vesa_mode_table vesa_mode[] = { | ||
104 | {"0x301", 640, 480, 8}, | ||
105 | {"0x303", 800, 600, 8}, | ||
106 | {"0x305", 1024, 768, 8}, | ||
107 | {"0x307", 1280, 1024, 8}, | ||
108 | |||
109 | {"0x311", 640, 480, 16}, | ||
110 | {"0x314", 800, 600, 16}, | ||
111 | {"0x317", 1024, 768, 16}, | ||
112 | {"0x31A", 1280, 1024, 16}, | ||
113 | |||
114 | {"0x312", 640, 480, 24}, | ||
115 | {"0x315", 800, 600, 24}, | ||
116 | {"0x318", 1024, 768, 24}, | ||
117 | {"0x31B", 1280, 1024, 24}, | ||
118 | }; | ||
119 | |||
120 | char __iomem *smtc_RegBaseAddress; /* Memory Map IO starting address */ | ||
121 | char __iomem *smtc_VRAMBaseAddress; /* video memory starting address */ | ||
122 | |||
123 | char *smtc_2DBaseAddress; /* 2D engine starting address */ | ||
124 | char *smtc_2Ddataport; /* 2D data port offset */ | ||
125 | short smtc_2Dacceleration; | ||
126 | |||
127 | static u32 colreg[17]; | ||
128 | static struct par_info hw; /* hardware information */ | ||
129 | |||
130 | u16 smtc_ChipIDs[] = { | ||
131 | 0x710, | ||
132 | 0x712, | ||
133 | 0x720 | ||
134 | }; | ||
135 | |||
136 | #define numSMTCchipIDs (sizeof(smtc_ChipIDs) / sizeof(u16)) | ||
137 | |||
138 | void deWaitForNotBusy(void) | ||
139 | { | ||
140 | unsigned long i = 0x1000000; | ||
141 | while (i--) { | ||
142 | if ((smtc_seqr(0x16) & 0x18) == 0x10) | ||
143 | break; | ||
144 | } | ||
145 | smtc_de_busy = 0; | ||
146 | } | ||
147 | |||
148 | static void sm712_set_timing(struct smtcfb_info *sfb, | ||
149 | struct par_info *ppar_info) | ||
150 | { | ||
151 | int i = 0, j = 0; | ||
152 | u32 m_nScreenStride; | ||
153 | |||
154 | smdbg("\nppar_info->width = %d ppar_info->height = %d" | ||
155 | "sfb->fb.var.bits_per_pixel = %d ppar_info->hz = %d\n", | ||
156 | ppar_info->width, ppar_info->height, | ||
157 | sfb->fb.var.bits_per_pixel, ppar_info->hz); | ||
158 | |||
159 | for (j = 0; j < numVGAModes; j++) { | ||
160 | if (VGAMode[j].mmSizeX == ppar_info->width && | ||
161 | VGAMode[j].mmSizeY == ppar_info->height && | ||
162 | VGAMode[j].bpp == sfb->fb.var.bits_per_pixel && | ||
163 | VGAMode[j].hz == ppar_info->hz) { | ||
164 | |||
165 | smdbg("\nVGAMode[j].mmSizeX = %d VGAMode[j].mmSizeY =" | ||
166 | "%d VGAMode[j].bpp = %d" | ||
167 | "VGAMode[j].hz=%d\n", | ||
168 | VGAMode[j].mmSizeX, VGAMode[j].mmSizeY, | ||
169 | VGAMode[j].bpp, VGAMode[j].hz); | ||
170 | |||
171 | smdbg("VGAMode index=%d\n", j); | ||
172 | |||
173 | smtc_mmiowb(0x0, 0x3c6); | ||
174 | |||
175 | smtc_seqw(0, 0x1); | ||
176 | |||
177 | smtc_mmiowb(VGAMode[j].Init_MISC, 0x3c2); | ||
178 | |||
179 | /* init SEQ register SR00 - SR04 */ | ||
180 | for (i = 0; i < SIZE_SR00_SR04; i++) | ||
181 | smtc_seqw(i, VGAMode[j].Init_SR00_SR04[i]); | ||
182 | |||
183 | /* init SEQ register SR10 - SR24 */ | ||
184 | for (i = 0; i < SIZE_SR10_SR24; i++) | ||
185 | smtc_seqw(i + 0x10, | ||
186 | VGAMode[j].Init_SR10_SR24[i]); | ||
187 | |||
188 | /* init SEQ register SR30 - SR75 */ | ||
189 | for (i = 0; i < SIZE_SR30_SR75; i++) | ||
190 | if (((i + 0x30) != 0x62) \ | ||
191 | && ((i + 0x30) != 0x6a) \ | ||
192 | && ((i + 0x30) != 0x6b)) | ||
193 | smtc_seqw(i + 0x30, | ||
194 | VGAMode[j].Init_SR30_SR75[i]); | ||
195 | |||
196 | /* init SEQ register SR80 - SR93 */ | ||
197 | for (i = 0; i < SIZE_SR80_SR93; i++) | ||
198 | smtc_seqw(i + 0x80, | ||
199 | VGAMode[j].Init_SR80_SR93[i]); | ||
200 | |||
201 | /* init SEQ register SRA0 - SRAF */ | ||
202 | for (i = 0; i < SIZE_SRA0_SRAF; i++) | ||
203 | smtc_seqw(i + 0xa0, | ||
204 | VGAMode[j].Init_SRA0_SRAF[i]); | ||
205 | |||
206 | /* init Graphic register GR00 - GR08 */ | ||
207 | for (i = 0; i < SIZE_GR00_GR08; i++) | ||
208 | smtc_grphw(i, VGAMode[j].Init_GR00_GR08[i]); | ||
209 | |||
210 | /* init Attribute register AR00 - AR14 */ | ||
211 | for (i = 0; i < SIZE_AR00_AR14; i++) | ||
212 | smtc_attrw(i, VGAMode[j].Init_AR00_AR14[i]); | ||
213 | |||
214 | /* init CRTC register CR00 - CR18 */ | ||
215 | for (i = 0; i < SIZE_CR00_CR18; i++) | ||
216 | smtc_crtcw(i, VGAMode[j].Init_CR00_CR18[i]); | ||
217 | |||
218 | /* init CRTC register CR30 - CR4D */ | ||
219 | for (i = 0; i < SIZE_CR30_CR4D; i++) | ||
220 | smtc_crtcw(i + 0x30, | ||
221 | VGAMode[j].Init_CR30_CR4D[i]); | ||
222 | |||
223 | /* init CRTC register CR90 - CRA7 */ | ||
224 | for (i = 0; i < SIZE_CR90_CRA7; i++) | ||
225 | smtc_crtcw(i + 0x90, | ||
226 | VGAMode[j].Init_CR90_CRA7[i]); | ||
227 | } | ||
228 | } | ||
229 | smtc_mmiowb(0x67, 0x3c2); | ||
230 | |||
231 | /* set VPR registers */ | ||
232 | writel(0x0, ppar_info->m_pVPR + 0x0C); | ||
233 | writel(0x0, ppar_info->m_pVPR + 0x40); | ||
234 | |||
235 | /* set data width */ | ||
236 | m_nScreenStride = | ||
237 | (ppar_info->width * sfb->fb.var.bits_per_pixel) / 64; | ||
238 | switch (sfb->fb.var.bits_per_pixel) { | ||
239 | case 8: | ||
240 | writel(0x0, ppar_info->m_pVPR + 0x0); | ||
241 | break; | ||
242 | case 16: | ||
243 | writel(0x00020000, ppar_info->m_pVPR + 0x0); | ||
244 | break; | ||
245 | case 24: | ||
246 | writel(0x00040000, ppar_info->m_pVPR + 0x0); | ||
247 | break; | ||
248 | case 32: | ||
249 | writel(0x00030000, ppar_info->m_pVPR + 0x0); | ||
250 | break; | ||
251 | } | ||
252 | writel((u32) (((m_nScreenStride + 2) << 16) | m_nScreenStride), | ||
253 | ppar_info->m_pVPR + 0x10); | ||
254 | |||
255 | } | ||
256 | |||
257 | static void sm712_setpalette(int regno, unsigned red, unsigned green, | ||
258 | unsigned blue, struct fb_info *info) | ||
259 | { | ||
260 | struct par_info *cur_par = (struct par_info *)info->par; | ||
261 | |||
262 | if (cur_par->BaseAddressInVRAM) | ||
263 | /* | ||
264 | * second display palette for dual head. Enable CRT RAM, 6-bit | ||
265 | * RAM | ||
266 | */ | ||
267 | smtc_seqw(0x66, (smtc_seqr(0x66) & 0xC3) | 0x20); | ||
268 | else | ||
269 | /* primary display palette. Enable LCD RAM only, 6-bit RAM */ | ||
270 | smtc_seqw(0x66, (smtc_seqr(0x66) & 0xC3) | 0x10); | ||
271 | smtc_mmiowb(regno, dac_reg); | ||
272 | smtc_mmiowb(red >> 10, dac_val); | ||
273 | smtc_mmiowb(green >> 10, dac_val); | ||
274 | smtc_mmiowb(blue >> 10, dac_val); | ||
275 | } | ||
276 | |||
277 | static void smtc_set_timing(struct smtcfb_info *sfb, struct par_info | ||
278 | *ppar_info) | ||
279 | { | ||
280 | switch (ppar_info->chipID) { | ||
281 | case 0x710: | ||
282 | case 0x712: | ||
283 | case 0x720: | ||
284 | sm712_set_timing(sfb, ppar_info); | ||
285 | break; | ||
286 | } | ||
287 | } | ||
288 | |||
289 | static struct fb_var_screeninfo smtcfb_var = { | ||
290 | .xres = 1024, | ||
291 | .yres = 600, | ||
292 | .xres_virtual = 1024, | ||
293 | .yres_virtual = 600, | ||
294 | .bits_per_pixel = 16, | ||
295 | .red = {16, 8, 0}, | ||
296 | .green = {8, 8, 0}, | ||
297 | .blue = {0, 8, 0}, | ||
298 | .activate = FB_ACTIVATE_NOW, | ||
299 | .height = -1, | ||
300 | .width = -1, | ||
301 | .vmode = FB_VMODE_NONINTERLACED, | ||
302 | }; | ||
303 | |||
304 | static struct fb_fix_screeninfo smtcfb_fix = { | ||
305 | .id = "sm712fb", | ||
306 | .type = FB_TYPE_PACKED_PIXELS, | ||
307 | .visual = FB_VISUAL_TRUECOLOR, | ||
308 | .line_length = 800 * 3, | ||
309 | .accel = FB_ACCEL_SMI_LYNX, | ||
310 | }; | ||
311 | |||
312 | /* chan_to_field | ||
313 | * | ||
314 | * convert a colour value into a field position | ||
315 | * | ||
316 | * from pxafb.c | ||
317 | */ | ||
318 | |||
319 | static inline unsigned int chan_to_field(unsigned int chan, | ||
320 | struct fb_bitfield *bf) | ||
321 | { | ||
322 | chan &= 0xffff; | ||
323 | chan >>= 16 - bf->length; | ||
324 | return chan << bf->offset; | ||
325 | } | ||
326 | |||
327 | static int smtcfb_blank(int blank_mode, struct fb_info *info) | ||
328 | { | ||
329 | /* clear DPMS setting */ | ||
330 | switch (blank_mode) { | ||
331 | case FB_BLANK_UNBLANK: | ||
332 | /* Screen On: HSync: On, VSync : On */ | ||
333 | smtc_seqw(0x01, (smtc_seqr(0x01) & (~0x20))); | ||
334 | smtc_seqw(0x6a, 0x16); | ||
335 | smtc_seqw(0x6b, 0x02); | ||
336 | smtc_seqw(0x21, (smtc_seqr(0x21) & 0x77)); | ||
337 | smtc_seqw(0x22, (smtc_seqr(0x22) & (~0x30))); | ||
338 | smtc_seqw(0x23, (smtc_seqr(0x23) & (~0xc0))); | ||
339 | smtc_seqw(0x24, (smtc_seqr(0x24) | 0x01)); | ||
340 | smtc_seqw(0x31, (smtc_seqr(0x31) | 0x03)); | ||
341 | break; | ||
342 | case FB_BLANK_NORMAL: | ||
343 | /* Screen Off: HSync: On, VSync : On Soft blank */ | ||
344 | smtc_seqw(0x01, (smtc_seqr(0x01) & (~0x20))); | ||
345 | smtc_seqw(0x6a, 0x16); | ||
346 | smtc_seqw(0x6b, 0x02); | ||
347 | smtc_seqw(0x22, (smtc_seqr(0x22) & (~0x30))); | ||
348 | smtc_seqw(0x23, (smtc_seqr(0x23) & (~0xc0))); | ||
349 | smtc_seqw(0x24, (smtc_seqr(0x24) | 0x01)); | ||
350 | smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00)); | ||
351 | break; | ||
352 | case FB_BLANK_VSYNC_SUSPEND: | ||
353 | /* Screen On: HSync: On, VSync : Off */ | ||
354 | smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20)); | ||
355 | smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0))); | ||
356 | smtc_seqw(0x6a, 0x0c); | ||
357 | smtc_seqw(0x6b, 0x02); | ||
358 | smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88)); | ||
359 | smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x20)); | ||
360 | smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0x20)); | ||
361 | smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01))); | ||
362 | smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00)); | ||
363 | smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80)); | ||
364 | break; | ||
365 | case FB_BLANK_HSYNC_SUSPEND: | ||
366 | /* Screen On: HSync: Off, VSync : On */ | ||
367 | smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20)); | ||
368 | smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0))); | ||
369 | smtc_seqw(0x6a, 0x0c); | ||
370 | smtc_seqw(0x6b, 0x02); | ||
371 | smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88)); | ||
372 | smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x10)); | ||
373 | smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0xD8)); | ||
374 | smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01))); | ||
375 | smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00)); | ||
376 | smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80)); | ||
377 | break; | ||
378 | case FB_BLANK_POWERDOWN: | ||
379 | /* Screen On: HSync: Off, VSync : Off */ | ||
380 | smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20)); | ||
381 | smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0))); | ||
382 | smtc_seqw(0x6a, 0x0c); | ||
383 | smtc_seqw(0x6b, 0x02); | ||
384 | smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88)); | ||
385 | smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x30)); | ||
386 | smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0xD8)); | ||
387 | smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01))); | ||
388 | smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00)); | ||
389 | smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80)); | ||
390 | break; | ||
391 | default: | ||
392 | return -EINVAL; | ||
393 | } | ||
394 | |||
395 | return 0; | ||
396 | } | ||
397 | |||
398 | static int smtc_setcolreg(unsigned regno, unsigned red, unsigned green, | ||
399 | unsigned blue, unsigned trans, struct fb_info *info) | ||
400 | { | ||
401 | struct smtcfb_info *sfb = (struct smtcfb_info *)info; | ||
402 | u32 val; | ||
403 | |||
404 | if (regno > 255) | ||
405 | return 1; | ||
406 | |||
407 | switch (sfb->fb.fix.visual) { | ||
408 | case FB_VISUAL_DIRECTCOLOR: | ||
409 | case FB_VISUAL_TRUECOLOR: | ||
410 | /* | ||
411 | * 16/32 bit true-colour, use pseuo-palette for 16 base color | ||
412 | */ | ||
413 | if (regno < 16) { | ||
414 | if (sfb->fb.var.bits_per_pixel == 16) { | ||
415 | u32 *pal = sfb->fb.pseudo_palette; | ||
416 | val = chan_to_field(red, &sfb->fb.var.red); | ||
417 | val |= chan_to_field(green, \ | ||
418 | &sfb->fb.var.green); | ||
419 | val |= chan_to_field(blue, &sfb->fb.var.blue); | ||
420 | #ifdef __BIG_ENDIAN | ||
421 | pal[regno] = | ||
422 | ((red & 0xf800) >> 8) | | ||
423 | ((green & 0xe000) >> 13) | | ||
424 | ((green & 0x1c00) << 3) | | ||
425 | ((blue & 0xf800) >> 3); | ||
426 | #else | ||
427 | pal[regno] = val; | ||
428 | #endif | ||
429 | } else { | ||
430 | u32 *pal = sfb->fb.pseudo_palette; | ||
431 | val = chan_to_field(red, &sfb->fb.var.red); | ||
432 | val |= chan_to_field(green, \ | ||
433 | &sfb->fb.var.green); | ||
434 | val |= chan_to_field(blue, &sfb->fb.var.blue); | ||
435 | #ifdef __BIG_ENDIAN | ||
436 | val = | ||
437 | (val & 0xff00ff00 >> 8) | | ||
438 | (val & 0x00ff00ff << 8); | ||
439 | #endif | ||
440 | pal[regno] = val; | ||
441 | } | ||
442 | } | ||
443 | break; | ||
444 | |||
445 | case FB_VISUAL_PSEUDOCOLOR: | ||
446 | /* color depth 8 bit */ | ||
447 | sm712_setpalette(regno, red, green, blue, info); | ||
448 | break; | ||
449 | |||
450 | default: | ||
451 | return 1; /* unknown type */ | ||
452 | } | ||
453 | |||
454 | return 0; | ||
455 | |||
456 | } | ||
457 | |||
458 | #ifdef __BIG_ENDIAN | ||
459 | static ssize_t smtcfb_read(struct fb_info *info, char __user * buf, size_t | ||
460 | count, loff_t *ppos) | ||
461 | { | ||
462 | unsigned long p = *ppos; | ||
463 | |||
464 | u32 *buffer, *dst; | ||
465 | u32 __iomem *src; | ||
466 | int c, i, cnt = 0, err = 0; | ||
467 | unsigned long total_size; | ||
468 | |||
469 | if (!info || !info->screen_base) | ||
470 | return -ENODEV; | ||
471 | |||
472 | if (info->state != FBINFO_STATE_RUNNING) | ||
473 | return -EPERM; | ||
474 | |||
475 | total_size = info->screen_size; | ||
476 | |||
477 | if (total_size == 0) | ||
478 | total_size = info->fix.smem_len; | ||
479 | |||
480 | if (p >= total_size) | ||
481 | return 0; | ||
482 | |||
483 | if (count >= total_size) | ||
484 | count = total_size; | ||
485 | |||
486 | if (count + p > total_size) | ||
487 | count = total_size - p; | ||
488 | |||
489 | buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count, GFP_KERNEL); | ||
490 | if (!buffer) | ||
491 | return -ENOMEM; | ||
492 | |||
493 | src = (u32 __iomem *) (info->screen_base + p); | ||
494 | |||
495 | if (info->fbops->fb_sync) | ||
496 | info->fbops->fb_sync(info); | ||
497 | |||
498 | while (count) { | ||
499 | c = (count > PAGE_SIZE) ? PAGE_SIZE : count; | ||
500 | dst = buffer; | ||
501 | for (i = c >> 2; i--;) { | ||
502 | *dst = fb_readl(src++); | ||
503 | *dst = | ||
504 | (*dst & 0xff00ff00 >> 8) | | ||
505 | (*dst & 0x00ff00ff << 8); | ||
506 | dst++; | ||
507 | } | ||
508 | if (c & 3) { | ||
509 | u8 *dst8 = (u8 *) dst; | ||
510 | u8 __iomem *src8 = (u8 __iomem *) src; | ||
511 | |||
512 | for (i = c & 3; i--;) { | ||
513 | if (i & 1) { | ||
514 | *dst8++ = fb_readb(++src8); | ||
515 | } else { | ||
516 | *dst8++ = fb_readb(--src8); | ||
517 | src8 += 2; | ||
518 | } | ||
519 | } | ||
520 | src = (u32 __iomem *) src8; | ||
521 | } | ||
522 | |||
523 | if (copy_to_user(buf, buffer, c)) { | ||
524 | err = -EFAULT; | ||
525 | break; | ||
526 | } | ||
527 | *ppos += c; | ||
528 | buf += c; | ||
529 | cnt += c; | ||
530 | count -= c; | ||
531 | } | ||
532 | |||
533 | kfree(buffer); | ||
534 | |||
535 | return (err) ? err : cnt; | ||
536 | } | ||
537 | |||
538 | static ssize_t | ||
539 | smtcfb_write(struct fb_info *info, const char __user *buf, size_t count, | ||
540 | loff_t *ppos) | ||
541 | { | ||
542 | unsigned long p = *ppos; | ||
543 | |||
544 | u32 *buffer, *src; | ||
545 | u32 __iomem *dst; | ||
546 | int c, i, cnt = 0, err = 0; | ||
547 | unsigned long total_size; | ||
548 | |||
549 | if (!info || !info->screen_base) | ||
550 | return -ENODEV; | ||
551 | |||
552 | if (info->state != FBINFO_STATE_RUNNING) | ||
553 | return -EPERM; | ||
554 | |||
555 | total_size = info->screen_size; | ||
556 | |||
557 | if (total_size == 0) | ||
558 | total_size = info->fix.smem_len; | ||
559 | |||
560 | if (p > total_size) | ||
561 | return -EFBIG; | ||
562 | |||
563 | if (count > total_size) { | ||
564 | err = -EFBIG; | ||
565 | count = total_size; | ||
566 | } | ||
567 | |||
568 | if (count + p > total_size) { | ||
569 | if (!err) | ||
570 | err = -ENOSPC; | ||
571 | |||
572 | count = total_size - p; | ||
573 | } | ||
574 | |||
575 | buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count, GFP_KERNEL); | ||
576 | if (!buffer) | ||
577 | return -ENOMEM; | ||
578 | |||
579 | dst = (u32 __iomem *) (info->screen_base + p); | ||
580 | |||
581 | if (info->fbops->fb_sync) | ||
582 | info->fbops->fb_sync(info); | ||
583 | |||
584 | while (count) { | ||
585 | c = (count > PAGE_SIZE) ? PAGE_SIZE : count; | ||
586 | src = buffer; | ||
587 | |||
588 | if (copy_from_user(src, buf, c)) { | ||
589 | err = -EFAULT; | ||
590 | break; | ||
591 | } | ||
592 | |||
593 | for (i = c >> 2; i--;) { | ||
594 | fb_writel((*src & 0xff00ff00 >> 8) | | ||
595 | (*src & 0x00ff00ff << 8), dst++); | ||
596 | src++; | ||
597 | } | ||
598 | if (c & 3) { | ||
599 | u8 *src8 = (u8 *) src; | ||
600 | u8 __iomem *dst8 = (u8 __iomem *) dst; | ||
601 | |||
602 | for (i = c & 3; i--;) { | ||
603 | if (i & 1) { | ||
604 | fb_writeb(*src8++, ++dst8); | ||
605 | } else { | ||
606 | fb_writeb(*src8++, --dst8); | ||
607 | dst8 += 2; | ||
608 | } | ||
609 | } | ||
610 | dst = (u32 __iomem *) dst8; | ||
611 | } | ||
612 | |||
613 | *ppos += c; | ||
614 | buf += c; | ||
615 | cnt += c; | ||
616 | count -= c; | ||
617 | } | ||
618 | |||
619 | kfree(buffer); | ||
620 | |||
621 | return (cnt) ? cnt : err; | ||
622 | } | ||
623 | #endif /* ! __BIG_ENDIAN */ | ||
624 | |||
625 | #include "smtc2d.c" | ||
626 | |||
627 | void smtcfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) | ||
628 | { | ||
629 | struct par_info *p = (struct par_info *)info->par; | ||
630 | |||
631 | if (smtc_2Dacceleration) { | ||
632 | if (!area->width || !area->height) | ||
633 | return; | ||
634 | |||
635 | deCopy(p->BaseAddressInVRAM, 0, info->var.bits_per_pixel, | ||
636 | area->dx, area->dy, area->width, area->height, | ||
637 | p->BaseAddressInVRAM, 0, area->sx, area->sy, 0, 0xC); | ||
638 | |||
639 | } else | ||
640 | cfb_copyarea(info, area); | ||
641 | } | ||
642 | |||
643 | void smtcfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) | ||
644 | { | ||
645 | struct par_info *p = (struct par_info *)info->par; | ||
646 | |||
647 | if (smtc_2Dacceleration) { | ||
648 | if (!rect->width || !rect->height) | ||
649 | return; | ||
650 | if (info->var.bits_per_pixel >= 24) | ||
651 | deFillRect(p->BaseAddressInVRAM, 0, rect->dx * 3, | ||
652 | rect->dy * 3, rect->width * 3, rect->height, | ||
653 | rect->color); | ||
654 | else | ||
655 | deFillRect(p->BaseAddressInVRAM, 0, rect->dx, rect->dy, | ||
656 | rect->width, rect->height, rect->color); | ||
657 | } else | ||
658 | cfb_fillrect(info, rect); | ||
659 | } | ||
660 | |||
661 | void smtcfb_imageblit(struct fb_info *info, const struct fb_image *image) | ||
662 | { | ||
663 | struct par_info *p = (struct par_info *)info->par; | ||
664 | u32 bg_col = 0, fg_col = 0; | ||
665 | |||
666 | if ((smtc_2Dacceleration) && (image->depth == 1)) { | ||
667 | if (smtc_de_busy) | ||
668 | deWaitForNotBusy(); | ||
669 | |||
670 | switch (info->var.bits_per_pixel) { | ||
671 | case 8: | ||
672 | bg_col = image->bg_color; | ||
673 | fg_col = image->fg_color; | ||
674 | break; | ||
675 | case 16: | ||
676 | bg_col = | ||
677 | ((u32 *) (info->pseudo_palette))[image->bg_color]; | ||
678 | fg_col = | ||
679 | ((u32 *) (info->pseudo_palette))[image->fg_color]; | ||
680 | break; | ||
681 | case 32: | ||
682 | bg_col = | ||
683 | ((u32 *) (info->pseudo_palette))[image->bg_color]; | ||
684 | fg_col = | ||
685 | ((u32 *) (info->pseudo_palette))[image->fg_color]; | ||
686 | break; | ||
687 | } | ||
688 | |||
689 | deSystemMem2VideoMemMonoBlt( | ||
690 | image->data, | ||
691 | image->width / 8, | ||
692 | 0, | ||
693 | p->BaseAddressInVRAM, | ||
694 | 0, | ||
695 | 0, | ||
696 | image->dx, image->dy, | ||
697 | image->width, image->height, | ||
698 | fg_col, bg_col, | ||
699 | 0x0C); | ||
700 | |||
701 | } else | ||
702 | cfb_imageblit(info, image); | ||
703 | } | ||
704 | |||
705 | static struct fb_ops smtcfb_ops = { | ||
706 | .owner = THIS_MODULE, | ||
707 | .fb_setcolreg = smtc_setcolreg, | ||
708 | .fb_blank = smtcfb_blank, | ||
709 | .fb_fillrect = smtcfb_fillrect, | ||
710 | .fb_imageblit = smtcfb_imageblit, | ||
711 | .fb_copyarea = smtcfb_copyarea, | ||
712 | #ifdef __BIG_ENDIAN | ||
713 | .fb_read = smtcfb_read, | ||
714 | .fb_write = smtcfb_write, | ||
715 | #endif | ||
716 | |||
717 | }; | ||
718 | |||
719 | void smtcfb_setmode(struct smtcfb_info *sfb) | ||
720 | { | ||
721 | switch (sfb->fb.var.bits_per_pixel) { | ||
722 | case 32: | ||
723 | sfb->fb.fix.visual = FB_VISUAL_TRUECOLOR; | ||
724 | sfb->fb.fix.line_length = sfb->fb.var.xres * 4; | ||
725 | sfb->fb.var.red.length = 8; | ||
726 | sfb->fb.var.green.length = 8; | ||
727 | sfb->fb.var.blue.length = 8; | ||
728 | sfb->fb.var.red.offset = 16; | ||
729 | sfb->fb.var.green.offset = 8; | ||
730 | sfb->fb.var.blue.offset = 0; | ||
731 | |||
732 | break; | ||
733 | case 8: | ||
734 | sfb->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR; | ||
735 | sfb->fb.fix.line_length = sfb->fb.var.xres; | ||
736 | sfb->fb.var.red.offset = 5; | ||
737 | sfb->fb.var.red.length = 3; | ||
738 | sfb->fb.var.green.offset = 2; | ||
739 | sfb->fb.var.green.length = 3; | ||
740 | sfb->fb.var.blue.offset = 0; | ||
741 | sfb->fb.var.blue.length = 2; | ||
742 | break; | ||
743 | case 24: | ||
744 | sfb->fb.fix.visual = FB_VISUAL_TRUECOLOR; | ||
745 | sfb->fb.fix.line_length = sfb->fb.var.xres * 3; | ||
746 | sfb->fb.var.red.length = 8; | ||
747 | sfb->fb.var.green.length = 8; | ||
748 | sfb->fb.var.blue.length = 8; | ||
749 | |||
750 | sfb->fb.var.red.offset = 16; | ||
751 | sfb->fb.var.green.offset = 8; | ||
752 | sfb->fb.var.blue.offset = 0; | ||
753 | |||
754 | break; | ||
755 | case 16: | ||
756 | default: | ||
757 | sfb->fb.fix.visual = FB_VISUAL_TRUECOLOR; | ||
758 | sfb->fb.fix.line_length = sfb->fb.var.xres * 2; | ||
759 | |||
760 | sfb->fb.var.red.length = 5; | ||
761 | sfb->fb.var.green.length = 6; | ||
762 | sfb->fb.var.blue.length = 5; | ||
763 | |||
764 | sfb->fb.var.red.offset = 11; | ||
765 | sfb->fb.var.green.offset = 5; | ||
766 | sfb->fb.var.blue.offset = 0; | ||
767 | |||
768 | break; | ||
769 | } | ||
770 | |||
771 | hw.width = sfb->fb.var.xres; | ||
772 | hw.height = sfb->fb.var.yres; | ||
773 | hw.hz = 60; | ||
774 | smtc_set_timing(sfb, &hw); | ||
775 | if (smtc_2Dacceleration) { | ||
776 | printk("2D acceleration enabled!\n"); | ||
777 | /* Init smtc drawing engine */ | ||
778 | deInit(sfb->fb.var.xres, sfb->fb.var.yres, | ||
779 | sfb->fb.var.bits_per_pixel); | ||
780 | } | ||
781 | } | ||
782 | |||
783 | /* | ||
784 | * Alloc struct smtcfb_info and assign the default value | ||
785 | */ | ||
786 | static struct smtcfb_info *smtc_alloc_fb_info(struct pci_dev *dev, | ||
787 | char *name) | ||
788 | { | ||
789 | struct smtcfb_info *sfb; | ||
790 | |||
791 | sfb = kmalloc(sizeof(struct smtcfb_info), GFP_KERNEL); | ||
792 | |||
793 | if (!sfb) | ||
794 | return NULL; | ||
795 | |||
796 | memset(sfb, 0, sizeof(struct smtcfb_info)); | ||
797 | |||
798 | sfb->currcon = -1; | ||
799 | sfb->dev = dev; | ||
800 | |||
801 | /*** Init sfb->fb with default value ***/ | ||
802 | sfb->fb.flags = FBINFO_FLAG_DEFAULT; | ||
803 | sfb->fb.fbops = &smtcfb_ops; | ||
804 | sfb->fb.var = smtcfb_var; | ||
805 | sfb->fb.fix = smtcfb_fix; | ||
806 | |||
807 | strcpy(sfb->fb.fix.id, name); | ||
808 | |||
809 | sfb->fb.fix.type = FB_TYPE_PACKED_PIXELS; | ||
810 | sfb->fb.fix.type_aux = 0; | ||
811 | sfb->fb.fix.xpanstep = 0; | ||
812 | sfb->fb.fix.ypanstep = 0; | ||
813 | sfb->fb.fix.ywrapstep = 0; | ||
814 | sfb->fb.fix.accel = FB_ACCEL_SMI_LYNX; | ||
815 | |||
816 | sfb->fb.var.nonstd = 0; | ||
817 | sfb->fb.var.activate = FB_ACTIVATE_NOW; | ||
818 | sfb->fb.var.height = -1; | ||
819 | sfb->fb.var.width = -1; | ||
820 | /* text mode acceleration */ | ||
821 | sfb->fb.var.accel_flags = FB_ACCELF_TEXT; | ||
822 | sfb->fb.var.vmode = FB_VMODE_NONINTERLACED; | ||
823 | sfb->fb.par = &hw; | ||
824 | sfb->fb.pseudo_palette = colreg; | ||
825 | |||
826 | return sfb; | ||
827 | } | ||
828 | |||
829 | /* | ||
830 | * Unmap in the memory mapped IO registers | ||
831 | */ | ||
832 | |||
833 | static void smtc_unmap_mmio(struct smtcfb_info *sfb) | ||
834 | { | ||
835 | if (sfb && smtc_RegBaseAddress) | ||
836 | smtc_RegBaseAddress = NULL; | ||
837 | } | ||
838 | |||
839 | /* | ||
840 | * Map in the screen memory | ||
841 | */ | ||
842 | |||
843 | static int smtc_map_smem(struct smtcfb_info *sfb, | ||
844 | struct pci_dev *dev, u_long smem_len) | ||
845 | { | ||
846 | if (sfb->fb.var.bits_per_pixel == 32) { | ||
847 | #ifdef __BIG_ENDIAN | ||
848 | sfb->fb.fix.smem_start = pci_resource_start(dev, 0) | ||
849 | + 0x800000; | ||
850 | #else | ||
851 | sfb->fb.fix.smem_start = pci_resource_start(dev, 0); | ||
852 | #endif | ||
853 | } else { | ||
854 | sfb->fb.fix.smem_start = pci_resource_start(dev, 0); | ||
855 | } | ||
856 | |||
857 | sfb->fb.fix.smem_len = smem_len; | ||
858 | |||
859 | sfb->fb.screen_base = smtc_VRAMBaseAddress; | ||
860 | |||
861 | if (!sfb->fb.screen_base) { | ||
862 | printk(KERN_INFO "%s: unable to map screen memory\n", | ||
863 | sfb->fb.fix.id); | ||
864 | return -ENOMEM; | ||
865 | } | ||
866 | |||
867 | return 0; | ||
868 | } | ||
869 | |||
870 | /* | ||
871 | * Unmap in the screen memory | ||
872 | * | ||
873 | */ | ||
874 | static void smtc_unmap_smem(struct smtcfb_info *sfb) | ||
875 | { | ||
876 | if (sfb && sfb->fb.screen_base) { | ||
877 | iounmap(sfb->fb.screen_base); | ||
878 | sfb->fb.screen_base = NULL; | ||
879 | } | ||
880 | } | ||
881 | |||
882 | /* | ||
883 | * We need to wake up the LynxEM+, and make sure its in linear memory mode. | ||
884 | */ | ||
885 | static inline void sm7xx_init_hw(void) | ||
886 | { | ||
887 | outb_p(0x18, 0x3c4); | ||
888 | outb_p(0x11, 0x3c5); | ||
889 | } | ||
890 | |||
891 | static void smtc_free_fb_info(struct smtcfb_info *sfb) | ||
892 | { | ||
893 | if (sfb) { | ||
894 | fb_alloc_cmap(&sfb->fb.cmap, 0, 0); | ||
895 | kfree(sfb); | ||
896 | } | ||
897 | } | ||
898 | |||
899 | /* | ||
900 | * sm712vga_setup - process command line options, get vga parameter | ||
901 | * @options: string of options | ||
902 | * Returns zero. | ||
903 | * | ||
904 | */ | ||
905 | static int __init __maybe_unused sm712vga_setup(char *options) | ||
906 | { | ||
907 | int index; | ||
908 | |||
909 | if (!options || !*options) { | ||
910 | smdbg("\n No vga parameter\n"); | ||
911 | return -EINVAL; | ||
912 | } | ||
913 | |||
914 | smtc_screen_info.lfb_width = 0; | ||
915 | smtc_screen_info.lfb_height = 0; | ||
916 | smtc_screen_info.lfb_depth = 0; | ||
917 | |||
918 | smdbg("\nsm712vga_setup = %s\n", options); | ||
919 | |||
920 | for (index = 0; | ||
921 | index < (sizeof(vesa_mode) / sizeof(struct vesa_mode_table)); | ||
922 | index++) { | ||
923 | if (strstr(options, vesa_mode[index].mode_index)) { | ||
924 | smtc_screen_info.lfb_width = vesa_mode[index].lfb_width; | ||
925 | smtc_screen_info.lfb_height = | ||
926 | vesa_mode[index].lfb_height; | ||
927 | smtc_screen_info.lfb_depth = vesa_mode[index].lfb_depth; | ||
928 | return 0; | ||
929 | } | ||
930 | } | ||
931 | |||
932 | return -1; | ||
933 | } | ||
934 | __setup("vga=", sm712vga_setup); | ||
935 | |||
936 | /* Jason (08/13/2009) | ||
937 | * Original init function changed to probe method to be used by pci_drv | ||
938 | * process used to detect chips replaced with kernel process in pci_drv | ||
939 | */ | ||
940 | static int __init smtcfb_pci_probe(struct pci_dev *pdev, | ||
941 | const struct pci_device_id *ent) | ||
942 | { | ||
943 | struct smtcfb_info *sfb; | ||
944 | u_long smem_size = 0x00800000; /* default 8MB */ | ||
945 | char name[16]; | ||
946 | int err; | ||
947 | unsigned long pFramebufferPhysical; | ||
948 | |||
949 | printk(KERN_INFO | ||
950 | "Silicon Motion display driver " SMTC_LINUX_FB_VERSION "\n"); | ||
951 | |||
952 | err = pci_enable_device(pdev); /* enable SMTC chip */ | ||
953 | |||
954 | if (err) | ||
955 | return err; | ||
956 | err = -ENOMEM; | ||
957 | |||
958 | hw.chipID = ent->device; | ||
959 | sprintf(name, "sm%Xfb", hw.chipID); | ||
960 | |||
961 | sfb = smtc_alloc_fb_info(pdev, name); | ||
962 | |||
963 | if (!sfb) | ||
964 | goto failed; | ||
965 | /* Jason (08/13/2009) | ||
966 | * Store fb_info to be further used when suspending and resuming | ||
967 | */ | ||
968 | pci_set_drvdata(pdev, sfb); | ||
969 | |||
970 | sm7xx_init_hw(); | ||
971 | |||
972 | /*get mode parameter from smtc_screen_info */ | ||
973 | if (smtc_screen_info.lfb_width != 0) { | ||
974 | sfb->fb.var.xres = smtc_screen_info.lfb_width; | ||
975 | sfb->fb.var.yres = smtc_screen_info.lfb_height; | ||
976 | sfb->fb.var.bits_per_pixel = smtc_screen_info.lfb_depth; | ||
977 | } else { | ||
978 | /* default resolution 1024x600 16bit mode */ | ||
979 | sfb->fb.var.xres = SCREEN_X_RES; | ||
980 | sfb->fb.var.yres = SCREEN_Y_RES; | ||
981 | sfb->fb.var.bits_per_pixel = SCREEN_BPP; | ||
982 | } | ||
983 | |||
984 | #ifdef __BIG_ENDIAN | ||
985 | if (sfb->fb.var.bits_per_pixel == 24) | ||
986 | sfb->fb.var.bits_per_pixel = (smtc_screen_info.lfb_depth = 32); | ||
987 | #endif | ||
988 | /* Map address and memory detection */ | ||
989 | pFramebufferPhysical = pci_resource_start(pdev, 0); | ||
990 | pci_read_config_byte(pdev, PCI_REVISION_ID, &hw.chipRevID); | ||
991 | |||
992 | switch (hw.chipID) { | ||
993 | case 0x710: | ||
994 | case 0x712: | ||
995 | sfb->fb.fix.mmio_start = pFramebufferPhysical + 0x00400000; | ||
996 | sfb->fb.fix.mmio_len = 0x00400000; | ||
997 | smem_size = SM712_VIDEOMEMORYSIZE; | ||
998 | #ifdef __BIG_ENDIAN | ||
999 | hw.m_pLFB = (smtc_VRAMBaseAddress = | ||
1000 | ioremap(pFramebufferPhysical, 0x00c00000)); | ||
1001 | #else | ||
1002 | hw.m_pLFB = (smtc_VRAMBaseAddress = | ||
1003 | ioremap(pFramebufferPhysical, 0x00800000)); | ||
1004 | #endif | ||
1005 | hw.m_pMMIO = (smtc_RegBaseAddress = | ||
1006 | smtc_VRAMBaseAddress + 0x00700000); | ||
1007 | smtc_2DBaseAddress = (hw.m_pDPR = | ||
1008 | smtc_VRAMBaseAddress + 0x00408000); | ||
1009 | smtc_2Ddataport = smtc_VRAMBaseAddress + DE_DATA_PORT_712; | ||
1010 | hw.m_pVPR = hw.m_pLFB + 0x0040c000; | ||
1011 | #ifdef __BIG_ENDIAN | ||
1012 | if (sfb->fb.var.bits_per_pixel == 32) { | ||
1013 | smtc_VRAMBaseAddress += 0x800000; | ||
1014 | hw.m_pLFB += 0x800000; | ||
1015 | printk(KERN_INFO | ||
1016 | "\nsmtc_VRAMBaseAddress=%p hw.m_pLFB=%p\n", | ||
1017 | smtc_VRAMBaseAddress, hw.m_pLFB); | ||
1018 | } | ||
1019 | #endif | ||
1020 | if (!smtc_RegBaseAddress) { | ||
1021 | printk(KERN_INFO | ||
1022 | "%s: unable to map memory mapped IO\n", | ||
1023 | sfb->fb.fix.id); | ||
1024 | return -ENOMEM; | ||
1025 | } | ||
1026 | |||
1027 | /* set MCLK = 14.31818 * (0x16 / 0x2) */ | ||
1028 | smtc_seqw(0x6a, 0x16); | ||
1029 | smtc_seqw(0x6b, 0x02); | ||
1030 | smtc_seqw(0x62, 0x3e); | ||
1031 | /* enable PCI burst */ | ||
1032 | smtc_seqw(0x17, 0x20); | ||
1033 | /* enable word swap */ | ||
1034 | #ifdef __BIG_ENDIAN | ||
1035 | if (sfb->fb.var.bits_per_pixel == 32) | ||
1036 | smtc_seqw(0x17, 0x30); | ||
1037 | #endif | ||
1038 | #ifdef CONFIG_FB_SM7XX_ACCEL | ||
1039 | smtc_2Dacceleration = 1; | ||
1040 | #endif | ||
1041 | break; | ||
1042 | case 0x720: | ||
1043 | sfb->fb.fix.mmio_start = pFramebufferPhysical; | ||
1044 | sfb->fb.fix.mmio_len = 0x00200000; | ||
1045 | smem_size = SM722_VIDEOMEMORYSIZE; | ||
1046 | smtc_2DBaseAddress = (hw.m_pDPR = | ||
1047 | ioremap(pFramebufferPhysical, 0x00a00000)); | ||
1048 | hw.m_pLFB = (smtc_VRAMBaseAddress = | ||
1049 | smtc_2DBaseAddress + 0x00200000); | ||
1050 | hw.m_pMMIO = (smtc_RegBaseAddress = | ||
1051 | smtc_2DBaseAddress + 0x000c0000); | ||
1052 | smtc_2Ddataport = smtc_2DBaseAddress + DE_DATA_PORT_722; | ||
1053 | hw.m_pVPR = smtc_2DBaseAddress + 0x800; | ||
1054 | |||
1055 | smtc_seqw(0x62, 0xff); | ||
1056 | smtc_seqw(0x6a, 0x0d); | ||
1057 | smtc_seqw(0x6b, 0x02); | ||
1058 | smtc_2Dacceleration = 0; | ||
1059 | break; | ||
1060 | default: | ||
1061 | printk(KERN_INFO | ||
1062 | "No valid Silicon Motion display chip was detected!\n"); | ||
1063 | |||
1064 | smtc_free_fb_info(sfb); | ||
1065 | return err; | ||
1066 | } | ||
1067 | |||
1068 | /* can support 32 bpp */ | ||
1069 | if (15 == sfb->fb.var.bits_per_pixel) | ||
1070 | sfb->fb.var.bits_per_pixel = 16; | ||
1071 | |||
1072 | sfb->fb.var.xres_virtual = sfb->fb.var.xres; | ||
1073 | sfb->fb.var.yres_virtual = sfb->fb.var.yres; | ||
1074 | err = smtc_map_smem(sfb, pdev, smem_size); | ||
1075 | if (err) | ||
1076 | goto failed; | ||
1077 | |||
1078 | smtcfb_setmode(sfb); | ||
1079 | /* Primary display starting from 0 postion */ | ||
1080 | hw.BaseAddressInVRAM = 0; | ||
1081 | sfb->fb.par = &hw; | ||
1082 | |||
1083 | err = register_framebuffer(&sfb->fb); | ||
1084 | if (err < 0) | ||
1085 | goto failed; | ||
1086 | |||
1087 | printk(KERN_INFO "Silicon Motion SM%X Rev%X primary display mode" | ||
1088 | "%dx%d-%d Init Complete.\n", hw.chipID, hw.chipRevID, | ||
1089 | sfb->fb.var.xres, sfb->fb.var.yres, | ||
1090 | sfb->fb.var.bits_per_pixel); | ||
1091 | |||
1092 | return 0; | ||
1093 | |||
1094 | failed: | ||
1095 | printk(KERN_INFO "Silicon Motion, Inc. primary display init fail\n"); | ||
1096 | |||
1097 | smtc_unmap_smem(sfb); | ||
1098 | smtc_unmap_mmio(sfb); | ||
1099 | smtc_free_fb_info(sfb); | ||
1100 | |||
1101 | return err; | ||
1102 | } | ||
1103 | |||
1104 | |||
1105 | /* Jason (08/11/2009) PCI_DRV wrapper essential structs */ | ||
1106 | static struct pci_device_id smtcfb_pci_table[] = { | ||
1107 | {0x126f, 0x710, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | ||
1108 | {0x126f, 0x712, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | ||
1109 | {0x126f, 0x720, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | ||
1110 | {0,} | ||
1111 | }; | ||
1112 | |||
1113 | |||
1114 | /* Jason (08/14/2009) | ||
1115 | * do some clean up when the driver module is removed | ||
1116 | */ | ||
1117 | static void __devexit smtcfb_pci_remove(struct pci_dev *pdev) | ||
1118 | { | ||
1119 | struct smtcfb_info *sfb; | ||
1120 | |||
1121 | sfb = pci_get_drvdata(pdev); | ||
1122 | pci_set_drvdata(pdev, NULL); | ||
1123 | smtc_unmap_smem(sfb); | ||
1124 | smtc_unmap_mmio(sfb); | ||
1125 | unregister_framebuffer(&sfb->fb); | ||
1126 | smtc_free_fb_info(sfb); | ||
1127 | } | ||
1128 | |||
1129 | /* Jason (08/14/2009) | ||
1130 | * suspend function, called when the suspend event is triggered | ||
1131 | */ | ||
1132 | static int __maybe_unused smtcfb_suspend(struct pci_dev *pdev, pm_message_t msg) | ||
1133 | { | ||
1134 | struct smtcfb_info *sfb; | ||
1135 | int retv; | ||
1136 | |||
1137 | sfb = pci_get_drvdata(pdev); | ||
1138 | |||
1139 | /* set the hw in sleep mode use externel clock and self memory refresh | ||
1140 | * so that we can turn off internal PLLs later on | ||
1141 | */ | ||
1142 | smtc_seqw(0x20, (smtc_seqr(0x20) | 0xc0)); | ||
1143 | smtc_seqw(0x69, (smtc_seqr(0x69) & 0xf7)); | ||
1144 | |||
1145 | switch (msg.event) { | ||
1146 | case PM_EVENT_FREEZE: | ||
1147 | case PM_EVENT_PRETHAW: | ||
1148 | pdev->dev.power.power_state = msg; | ||
1149 | return 0; | ||
1150 | } | ||
1151 | |||
1152 | /* when doing suspend, call fb apis and pci apis */ | ||
1153 | if (msg.event == PM_EVENT_SUSPEND) { | ||
1154 | acquire_console_sem(); | ||
1155 | fb_set_suspend(&sfb->fb, 1); | ||
1156 | release_console_sem(); | ||
1157 | retv = pci_save_state(pdev); | ||
1158 | pci_disable_device(pdev); | ||
1159 | retv = pci_choose_state(pdev, msg); | ||
1160 | retv = pci_set_power_state(pdev, retv); | ||
1161 | } | ||
1162 | |||
1163 | pdev->dev.power.power_state = msg; | ||
1164 | |||
1165 | /* additionaly turn off all function blocks including internal PLLs */ | ||
1166 | smtc_seqw(0x21, 0xff); | ||
1167 | |||
1168 | return 0; | ||
1169 | } | ||
1170 | |||
1171 | static int __maybe_unused smtcfb_resume(struct pci_dev *pdev) | ||
1172 | { | ||
1173 | struct smtcfb_info *sfb; | ||
1174 | int retv; | ||
1175 | |||
1176 | sfb = pci_get_drvdata(pdev); | ||
1177 | |||
1178 | /* when resuming, restore pci data and fb cursor */ | ||
1179 | if (pdev->dev.power.power_state.event != PM_EVENT_FREEZE) { | ||
1180 | retv = pci_set_power_state(pdev, PCI_D0); | ||
1181 | retv = pci_restore_state(pdev); | ||
1182 | if (pci_enable_device(pdev)) | ||
1183 | return -1; | ||
1184 | pci_set_master(pdev); | ||
1185 | } | ||
1186 | |||
1187 | /* reinit hardware */ | ||
1188 | sm7xx_init_hw(); | ||
1189 | switch (hw.chipID) { | ||
1190 | case 0x710: | ||
1191 | case 0x712: | ||
1192 | /* set MCLK = 14.31818 * (0x16 / 0x2) */ | ||
1193 | smtc_seqw(0x6a, 0x16); | ||
1194 | smtc_seqw(0x6b, 0x02); | ||
1195 | smtc_seqw(0x62, 0x3e); | ||
1196 | /* enable PCI burst */ | ||
1197 | smtc_seqw(0x17, 0x20); | ||
1198 | #ifdef __BIG_ENDIAN | ||
1199 | if (sfb->fb.var.bits_per_pixel == 32) | ||
1200 | smtc_seqw(0x17, 0x30); | ||
1201 | #endif | ||
1202 | break; | ||
1203 | case 0x720: | ||
1204 | smtc_seqw(0x62, 0xff); | ||
1205 | smtc_seqw(0x6a, 0x0d); | ||
1206 | smtc_seqw(0x6b, 0x02); | ||
1207 | break; | ||
1208 | } | ||
1209 | |||
1210 | smtc_seqw(0x34, (smtc_seqr(0x34) | 0xc0)); | ||
1211 | smtc_seqw(0x33, ((smtc_seqr(0x33) | 0x08) & 0xfb)); | ||
1212 | |||
1213 | smtcfb_setmode(sfb); | ||
1214 | |||
1215 | acquire_console_sem(); | ||
1216 | fb_set_suspend(&sfb->fb, 0); | ||
1217 | release_console_sem(); | ||
1218 | |||
1219 | return 0; | ||
1220 | } | ||
1221 | |||
1222 | /* Jason (08/13/2009) | ||
1223 | * pci_driver struct used to wrap the original driver | ||
1224 | * so that it can be registered into the kernel and | ||
1225 | * the proper method would be called when suspending and resuming | ||
1226 | */ | ||
1227 | static struct pci_driver smtcfb_driver = { | ||
1228 | .name = "smtcfb", | ||
1229 | .id_table = smtcfb_pci_table, | ||
1230 | .probe = smtcfb_pci_probe, | ||
1231 | .remove = __devexit_p(smtcfb_pci_remove), | ||
1232 | #ifdef CONFIG_PM | ||
1233 | .suspend = smtcfb_suspend, | ||
1234 | .resume = smtcfb_resume, | ||
1235 | #endif | ||
1236 | }; | ||
1237 | |||
1238 | static int __init smtcfb_init(void) | ||
1239 | { | ||
1240 | return pci_register_driver(&smtcfb_driver); | ||
1241 | } | ||
1242 | |||
1243 | static void __exit smtcfb_exit(void) | ||
1244 | { | ||
1245 | pci_unregister_driver(&smtcfb_driver); | ||
1246 | } | ||
1247 | |||
1248 | module_init(smtcfb_init); | ||
1249 | module_exit(smtcfb_exit); | ||
1250 | |||
1251 | MODULE_AUTHOR("Siliconmotion "); | ||
1252 | MODULE_DESCRIPTION("Framebuffer driver for SMI Graphic Cards"); | ||
1253 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/staging/sm7xx/smtcfb.h b/drivers/staging/sm7xx/smtcfb.h new file mode 100644 index 000000000000..7f2c34138215 --- /dev/null +++ b/drivers/staging/sm7xx/smtcfb.h | |||
@@ -0,0 +1,793 @@ | |||
1 | /* | ||
2 | * Silicon Motion SM712 frame buffer device | ||
3 | * | ||
4 | * Copyright (C) 2006 Silicon Motion Technology Corp. | ||
5 | * Authors: Ge Wang, gewang@siliconmotion.com | ||
6 | * Boyod boyod.yang@siliconmotion.com.cn | ||
7 | * | ||
8 | * Copyright (C) 2009 Lemote, Inc. | ||
9 | * Author: Wu Zhangjin, wuzj@lemote.com | ||
10 | * | ||
11 | * This file is subject to the terms and conditions of the GNU General Public | ||
12 | * License. See the file COPYING in the main directory of this archive for | ||
13 | * more details. | ||
14 | */ | ||
15 | |||
16 | #define SMTC_LINUX_FB_VERSION "version 0.11.2619.21.01 July 27, 2008" | ||
17 | |||
18 | #define NR_PALETTE 256 | ||
19 | #define NR_RGB 2 | ||
20 | |||
21 | #define FB_ACCEL_SMI_LYNX 88 | ||
22 | |||
23 | #ifdef __BIG_ENDIAN | ||
24 | #define PC_VGA 0 | ||
25 | #else | ||
26 | #define PC_VGA 1 | ||
27 | #endif | ||
28 | |||
29 | #define SCREEN_X_RES 1024 | ||
30 | #define SCREEN_Y_RES 600 | ||
31 | #define SCREEN_BPP 16 | ||
32 | |||
33 | #ifndef FIELD_OFFSET | ||
34 | #define FIELD_OFSFET(type, field) \ | ||
35 | ((unsigned long) (PUCHAR) & (((type *)0)->field)) | ||
36 | #endif | ||
37 | |||
38 | /*Assume SM712 graphics chip has 4MB VRAM */ | ||
39 | #define SM712_VIDEOMEMORYSIZE 0x00400000 | ||
40 | /*Assume SM722 graphics chip has 8MB VRAM */ | ||
41 | #define SM722_VIDEOMEMORYSIZE 0x00800000 | ||
42 | |||
43 | #define dac_reg (0x3c8) | ||
44 | #define dac_val (0x3c9) | ||
45 | |||
46 | extern char *smtc_RegBaseAddress; | ||
47 | #define smtc_mmiowb(dat, reg) writeb(dat, smtc_RegBaseAddress + reg) | ||
48 | #define smtc_mmioww(dat, reg) writew(dat, smtc_RegBaseAddress + reg) | ||
49 | #define smtc_mmiowl(dat, reg) writel(dat, smtc_RegBaseAddress + reg) | ||
50 | |||
51 | #define smtc_mmiorb(reg) readb(smtc_RegBaseAddress + reg) | ||
52 | #define smtc_mmiorw(reg) readw(smtc_RegBaseAddress + reg) | ||
53 | #define smtc_mmiorl(reg) readl(smtc_RegBaseAddress + reg) | ||
54 | |||
55 | #define SIZE_SR00_SR04 (0x04 - 0x00 + 1) | ||
56 | #define SIZE_SR10_SR24 (0x24 - 0x10 + 1) | ||
57 | #define SIZE_SR30_SR75 (0x75 - 0x30 + 1) | ||
58 | #define SIZE_SR80_SR93 (0x93 - 0x80 + 1) | ||
59 | #define SIZE_SRA0_SRAF (0xAF - 0xA0 + 1) | ||
60 | #define SIZE_GR00_GR08 (0x08 - 0x00 + 1) | ||
61 | #define SIZE_AR00_AR14 (0x14 - 0x00 + 1) | ||
62 | #define SIZE_CR00_CR18 (0x18 - 0x00 + 1) | ||
63 | #define SIZE_CR30_CR4D (0x4D - 0x30 + 1) | ||
64 | #define SIZE_CR90_CRA7 (0xA7 - 0x90 + 1) | ||
65 | #define SIZE_VPR (0x6C + 1) | ||
66 | #define SIZE_DPR (0x44 + 1) | ||
67 | |||
68 | static inline void smtc_crtcw(int reg, int val) | ||
69 | { | ||
70 | smtc_mmiowb(reg, 0x3d4); | ||
71 | smtc_mmiowb(val, 0x3d5); | ||
72 | } | ||
73 | |||
74 | static inline unsigned int smtc_crtcr(int reg) | ||
75 | { | ||
76 | smtc_mmiowb(reg, 0x3d4); | ||
77 | return smtc_mmiorb(0x3d5); | ||
78 | } | ||
79 | |||
80 | static inline void smtc_grphw(int reg, int val) | ||
81 | { | ||
82 | smtc_mmiowb(reg, 0x3ce); | ||
83 | smtc_mmiowb(val, 0x3cf); | ||
84 | } | ||
85 | |||
86 | static inline unsigned int smtc_grphr(int reg) | ||
87 | { | ||
88 | smtc_mmiowb(reg, 0x3ce); | ||
89 | return smtc_mmiorb(0x3cf); | ||
90 | } | ||
91 | |||
92 | static inline void smtc_attrw(int reg, int val) | ||
93 | { | ||
94 | smtc_mmiorb(0x3da); | ||
95 | smtc_mmiowb(reg, 0x3c0); | ||
96 | smtc_mmiorb(0x3c1); | ||
97 | smtc_mmiowb(val, 0x3c0); | ||
98 | } | ||
99 | |||
100 | static inline void smtc_seqw(int reg, int val) | ||
101 | { | ||
102 | smtc_mmiowb(reg, 0x3c4); | ||
103 | smtc_mmiowb(val, 0x3c5); | ||
104 | } | ||
105 | |||
106 | static inline unsigned int smtc_seqr(int reg) | ||
107 | { | ||
108 | smtc_mmiowb(reg, 0x3c4); | ||
109 | return smtc_mmiorb(0x3c5); | ||
110 | } | ||
111 | |||
112 | /* The next structure holds all information relevant for a specific video mode. | ||
113 | */ | ||
114 | |||
115 | struct ModeInit { | ||
116 | int mmSizeX; | ||
117 | int mmSizeY; | ||
118 | int bpp; | ||
119 | int hz; | ||
120 | unsigned char Init_MISC; | ||
121 | unsigned char Init_SR00_SR04[SIZE_SR00_SR04]; | ||
122 | unsigned char Init_SR10_SR24[SIZE_SR10_SR24]; | ||
123 | unsigned char Init_SR30_SR75[SIZE_SR30_SR75]; | ||
124 | unsigned char Init_SR80_SR93[SIZE_SR80_SR93]; | ||
125 | unsigned char Init_SRA0_SRAF[SIZE_SRA0_SRAF]; | ||
126 | unsigned char Init_GR00_GR08[SIZE_GR00_GR08]; | ||
127 | unsigned char Init_AR00_AR14[SIZE_AR00_AR14]; | ||
128 | unsigned char Init_CR00_CR18[SIZE_CR00_CR18]; | ||
129 | unsigned char Init_CR30_CR4D[SIZE_CR30_CR4D]; | ||
130 | unsigned char Init_CR90_CRA7[SIZE_CR90_CRA7]; | ||
131 | }; | ||
132 | |||
133 | /********************************************************************** | ||
134 | SM712 Mode table. | ||
135 | **********************************************************************/ | ||
136 | struct ModeInit VGAMode[] = { | ||
137 | { | ||
138 | /* mode#0: 640 x 480 16Bpp 60Hz */ | ||
139 | 640, 480, 16, 60, | ||
140 | /* Init_MISC */ | ||
141 | 0xE3, | ||
142 | { /* Init_SR0_SR4 */ | ||
143 | 0x03, 0x01, 0x0F, 0x00, 0x0E, | ||
144 | }, | ||
145 | { /* Init_SR10_SR24 */ | ||
146 | 0xFF, 0xBE, 0xEF, 0xFF, 0x00, 0x0E, 0x17, 0x2C, | ||
147 | 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
148 | 0xC4, 0x30, 0x02, 0x01, 0x01, | ||
149 | }, | ||
150 | { /* Init_SR30_SR75 */ | ||
151 | 0x32, 0x03, 0xA0, 0x09, 0xC0, 0x32, 0x32, 0x32, | ||
152 | 0x32, 0x32, 0x32, 0x32, 0x00, 0x00, 0x03, 0xFF, | ||
153 | 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, | ||
154 | 0x20, 0x0C, 0x44, 0x20, 0x00, 0x32, 0x32, 0x32, | ||
155 | 0x04, 0x24, 0x63, 0x4F, 0x52, 0x0B, 0xDF, 0xEA, | ||
156 | 0x04, 0x50, 0x19, 0x32, 0x32, 0x00, 0x00, 0x32, | ||
157 | 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, | ||
158 | 0x50, 0x03, 0x74, 0x14, 0x07, 0x82, 0x07, 0x04, | ||
159 | 0x00, 0x45, 0x30, 0x30, 0x40, 0x30, | ||
160 | }, | ||
161 | { /* Init_SR80_SR93 */ | ||
162 | 0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x32, | ||
163 | 0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x32, 0x32, | ||
164 | 0x00, 0x00, 0x00, 0x00, | ||
165 | }, | ||
166 | { /* Init_SRA0_SRAF */ | ||
167 | 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED, | ||
168 | 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xFF, 0xDF, | ||
169 | }, | ||
170 | { /* Init_GR00_GR08 */ | ||
171 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, | ||
172 | 0xFF, | ||
173 | }, | ||
174 | { /* Init_AR00_AR14 */ | ||
175 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, | ||
176 | 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, | ||
177 | 0x41, 0x00, 0x0F, 0x00, 0x00, | ||
178 | }, | ||
179 | { /* Init_CR00_CR18 */ | ||
180 | 0x5F, 0x4F, 0x4F, 0x00, 0x53, 0x1F, 0x0B, 0x3E, | ||
181 | 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
182 | 0xEA, 0x0C, 0xDF, 0x50, 0x40, 0xDF, 0x00, 0xE3, | ||
183 | 0xFF, | ||
184 | }, | ||
185 | { /* Init_CR30_CR4D */ | ||
186 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x20, | ||
187 | 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xFF, 0xFD, | ||
188 | 0x5F, 0x4F, 0x00, 0x54, 0x00, 0x0B, 0xDF, 0x00, | ||
189 | 0xEA, 0x0C, 0x2E, 0x00, 0x4F, 0xDF, | ||
190 | }, | ||
191 | { /* Init_CR90_CRA7 */ | ||
192 | 0x56, 0xDD, 0x5E, 0xEA, 0x87, 0x44, 0x8F, 0x55, | ||
193 | 0x0A, 0x8F, 0x55, 0x0A, 0x00, 0x00, 0x18, 0x00, | ||
194 | 0x11, 0x10, 0x0B, 0x0A, 0x0A, 0x0A, 0x0A, 0x00, | ||
195 | }, | ||
196 | }, | ||
197 | { | ||
198 | /* mode#1: 640 x 480 24Bpp 60Hz */ | ||
199 | 640, 480, 24, 60, | ||
200 | /* Init_MISC */ | ||
201 | 0xE3, | ||
202 | { /* Init_SR0_SR4 */ | ||
203 | 0x03, 0x01, 0x0F, 0x00, 0x0E, | ||
204 | }, | ||
205 | { /* Init_SR10_SR24 */ | ||
206 | 0xFF, 0xBE, 0xEF, 0xFF, 0x00, 0x0E, 0x17, 0x2C, | ||
207 | 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
208 | 0xC4, 0x30, 0x02, 0x01, 0x01, | ||
209 | }, | ||
210 | { /* Init_SR30_SR75 */ | ||
211 | 0x32, 0x03, 0xA0, 0x09, 0xC0, 0x32, 0x32, 0x32, | ||
212 | 0x32, 0x32, 0x32, 0x32, 0x00, 0x00, 0x03, 0xFF, | ||
213 | 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, | ||
214 | 0x20, 0x0C, 0x44, 0x20, 0x00, 0x32, 0x32, 0x32, | ||
215 | 0x04, 0x24, 0x63, 0x4F, 0x52, 0x0B, 0xDF, 0xEA, | ||
216 | 0x04, 0x50, 0x19, 0x32, 0x32, 0x00, 0x00, 0x32, | ||
217 | 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, | ||
218 | 0x50, 0x03, 0x74, 0x14, 0x07, 0x82, 0x07, 0x04, | ||
219 | 0x00, 0x45, 0x30, 0x30, 0x40, 0x30, | ||
220 | }, | ||
221 | { /* Init_SR80_SR93 */ | ||
222 | 0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x32, | ||
223 | 0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x32, 0x32, | ||
224 | 0x00, 0x00, 0x00, 0x00, | ||
225 | }, | ||
226 | { /* Init_SRA0_SRAF */ | ||
227 | 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED, | ||
228 | 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xFF, 0xDF, | ||
229 | }, | ||
230 | { /* Init_GR00_GR08 */ | ||
231 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, | ||
232 | 0xFF, | ||
233 | }, | ||
234 | { /* Init_AR00_AR14 */ | ||
235 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, | ||
236 | 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, | ||
237 | 0x41, 0x00, 0x0F, 0x00, 0x00, | ||
238 | }, | ||
239 | { /* Init_CR00_CR18 */ | ||
240 | 0x5F, 0x4F, 0x4F, 0x00, 0x53, 0x1F, 0x0B, 0x3E, | ||
241 | 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
242 | 0xEA, 0x0C, 0xDF, 0x50, 0x40, 0xDF, 0x00, 0xE3, | ||
243 | 0xFF, | ||
244 | }, | ||
245 | { /* Init_CR30_CR4D */ | ||
246 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x20, | ||
247 | 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xFF, 0xFD, | ||
248 | 0x5F, 0x4F, 0x00, 0x54, 0x00, 0x0B, 0xDF, 0x00, | ||
249 | 0xEA, 0x0C, 0x2E, 0x00, 0x4F, 0xDF, | ||
250 | }, | ||
251 | { /* Init_CR90_CRA7 */ | ||
252 | 0x56, 0xDD, 0x5E, 0xEA, 0x87, 0x44, 0x8F, 0x55, | ||
253 | 0x0A, 0x8F, 0x55, 0x0A, 0x00, 0x00, 0x18, 0x00, | ||
254 | 0x11, 0x10, 0x0B, 0x0A, 0x0A, 0x0A, 0x0A, 0x00, | ||
255 | }, | ||
256 | }, | ||
257 | { | ||
258 | /* mode#0: 640 x 480 32Bpp 60Hz */ | ||
259 | 640, 480, 32, 60, | ||
260 | /* Init_MISC */ | ||
261 | 0xE3, | ||
262 | { /* Init_SR0_SR4 */ | ||
263 | 0x03, 0x01, 0x0F, 0x00, 0x0E, | ||
264 | }, | ||
265 | { /* Init_SR10_SR24 */ | ||
266 | 0xFF, 0xBE, 0xEF, 0xFF, 0x00, 0x0E, 0x17, 0x2C, | ||
267 | 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
268 | 0xC4, 0x30, 0x02, 0x01, 0x01, | ||
269 | }, | ||
270 | { /* Init_SR30_SR75 */ | ||
271 | 0x32, 0x03, 0xA0, 0x09, 0xC0, 0x32, 0x32, 0x32, | ||
272 | 0x32, 0x32, 0x32, 0x32, 0x00, 0x00, 0x03, 0xFF, | ||
273 | 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, | ||
274 | 0x20, 0x0C, 0x44, 0x20, 0x00, 0x32, 0x32, 0x32, | ||
275 | 0x04, 0x24, 0x63, 0x4F, 0x52, 0x0B, 0xDF, 0xEA, | ||
276 | 0x04, 0x50, 0x19, 0x32, 0x32, 0x00, 0x00, 0x32, | ||
277 | 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, | ||
278 | 0x50, 0x03, 0x74, 0x14, 0x07, 0x82, 0x07, 0x04, | ||
279 | 0x00, 0x45, 0x30, 0x30, 0x40, 0x30, | ||
280 | }, | ||
281 | { /* Init_SR80_SR93 */ | ||
282 | 0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x32, | ||
283 | 0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x32, 0x32, | ||
284 | 0x00, 0x00, 0x00, 0x00, | ||
285 | }, | ||
286 | { /* Init_SRA0_SRAF */ | ||
287 | 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED, | ||
288 | 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xFF, 0xDF, | ||
289 | }, | ||
290 | { /* Init_GR00_GR08 */ | ||
291 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, | ||
292 | 0xFF, | ||
293 | }, | ||
294 | { /* Init_AR00_AR14 */ | ||
295 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, | ||
296 | 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, | ||
297 | 0x41, 0x00, 0x0F, 0x00, 0x00, | ||
298 | }, | ||
299 | { /* Init_CR00_CR18 */ | ||
300 | 0x5F, 0x4F, 0x4F, 0x00, 0x53, 0x1F, 0x0B, 0x3E, | ||
301 | 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
302 | 0xEA, 0x0C, 0xDF, 0x50, 0x40, 0xDF, 0x00, 0xE3, | ||
303 | 0xFF, | ||
304 | }, | ||
305 | { /* Init_CR30_CR4D */ | ||
306 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x20, | ||
307 | 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xFF, 0xFD, | ||
308 | 0x5F, 0x4F, 0x00, 0x54, 0x00, 0x0B, 0xDF, 0x00, | ||
309 | 0xEA, 0x0C, 0x2E, 0x00, 0x4F, 0xDF, | ||
310 | }, | ||
311 | { /* Init_CR90_CRA7 */ | ||
312 | 0x56, 0xDD, 0x5E, 0xEA, 0x87, 0x44, 0x8F, 0x55, | ||
313 | 0x0A, 0x8F, 0x55, 0x0A, 0x00, 0x00, 0x18, 0x00, | ||
314 | 0x11, 0x10, 0x0B, 0x0A, 0x0A, 0x0A, 0x0A, 0x00, | ||
315 | }, | ||
316 | }, | ||
317 | |||
318 | { /* mode#2: 800 x 600 16Bpp 60Hz */ | ||
319 | 800, 600, 16, 60, | ||
320 | /* Init_MISC */ | ||
321 | 0x2B, | ||
322 | { /* Init_SR0_SR4 */ | ||
323 | 0x03, 0x01, 0x0F, 0x03, 0x0E, | ||
324 | }, | ||
325 | { /* Init_SR10_SR24 */ | ||
326 | 0xFF, 0xBE, 0xEE, 0xFF, 0x00, 0x0E, 0x17, 0x2C, | ||
327 | 0x99, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
328 | 0xC4, 0x30, 0x02, 0x01, 0x01, | ||
329 | }, | ||
330 | { /* Init_SR30_SR75 */ | ||
331 | 0x34, 0x03, 0x20, 0x09, 0xC0, 0x24, 0x24, 0x24, | ||
332 | 0x24, 0x24, 0x24, 0x24, 0x00, 0x00, 0x03, 0xFF, | ||
333 | 0x00, 0xFC, 0x00, 0x00, 0x20, 0x38, 0x00, 0xFC, | ||
334 | 0x20, 0x0C, 0x44, 0x20, 0x00, 0x24, 0x24, 0x24, | ||
335 | 0x04, 0x48, 0x83, 0x63, 0x68, 0x72, 0x57, 0x58, | ||
336 | 0x04, 0x55, 0x59, 0x24, 0x24, 0x00, 0x00, 0x24, | ||
337 | 0x01, 0x80, 0x7A, 0x1A, 0x1A, 0x00, 0x00, 0x00, | ||
338 | 0x50, 0x03, 0x74, 0x14, 0x1C, 0x85, 0x35, 0x13, | ||
339 | 0x02, 0x45, 0x30, 0x35, 0x40, 0x20, | ||
340 | }, | ||
341 | { /* Init_SR80_SR93 */ | ||
342 | 0x00, 0x00, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x24, | ||
343 | 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x24, 0x24, | ||
344 | 0x00, 0x00, 0x00, 0x00, | ||
345 | }, | ||
346 | { /* Init_SRA0_SRAF */ | ||
347 | 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED, | ||
348 | 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xBF, 0xDF, | ||
349 | }, | ||
350 | { /* Init_GR00_GR08 */ | ||
351 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, | ||
352 | 0xFF, | ||
353 | }, | ||
354 | { /* Init_AR00_AR14 */ | ||
355 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, | ||
356 | 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, | ||
357 | 0x41, 0x00, 0x0F, 0x00, 0x00, | ||
358 | }, | ||
359 | { /* Init_CR00_CR18 */ | ||
360 | 0x7F, 0x63, 0x63, 0x00, 0x68, 0x18, 0x72, 0xF0, | ||
361 | 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
362 | 0x58, 0x0C, 0x57, 0x64, 0x40, 0x57, 0x00, 0xE3, | ||
363 | 0xFF, | ||
364 | }, | ||
365 | { /* Init_CR30_CR4D */ | ||
366 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x03, 0x20, | ||
367 | 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xBF, 0xFD, | ||
368 | 0x7F, 0x63, 0x00, 0x69, 0x18, 0x72, 0x57, 0x00, | ||
369 | 0x58, 0x0C, 0xE0, 0x20, 0x63, 0x57, | ||
370 | }, | ||
371 | { /* Init_CR90_CRA7 */ | ||
372 | 0x56, 0x4B, 0x5E, 0x55, 0x86, 0x9D, 0x8E, 0xAA, | ||
373 | 0xDB, 0x2A, 0xDF, 0x33, 0x00, 0x00, 0x18, 0x00, | ||
374 | 0x20, 0x1F, 0x1A, 0x19, 0x0F, 0x0F, 0x0F, 0x00, | ||
375 | }, | ||
376 | }, | ||
377 | { /* mode#3: 800 x 600 24Bpp 60Hz */ | ||
378 | 800, 600, 24, 60, | ||
379 | 0x2B, | ||
380 | { /* Init_SR0_SR4 */ | ||
381 | 0x03, 0x01, 0x0F, 0x03, 0x0E, | ||
382 | }, | ||
383 | { /* Init_SR10_SR24 */ | ||
384 | 0xFF, 0xBE, 0xEE, 0xFF, 0x00, 0x0E, 0x17, 0x2C, | ||
385 | 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
386 | 0xC4, 0x30, 0x02, 0x01, 0x01, | ||
387 | }, | ||
388 | { /* Init_SR30_SR75 */ | ||
389 | 0x36, 0x03, 0x20, 0x09, 0xC0, 0x36, 0x36, 0x36, | ||
390 | 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x03, 0xFF, | ||
391 | 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, | ||
392 | 0x20, 0x0C, 0x44, 0x20, 0x00, 0x36, 0x36, 0x36, | ||
393 | 0x04, 0x48, 0x83, 0x63, 0x68, 0x72, 0x57, 0x58, | ||
394 | 0x04, 0x55, 0x59, 0x36, 0x36, 0x00, 0x00, 0x36, | ||
395 | 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, | ||
396 | 0x50, 0x03, 0x74, 0x14, 0x1C, 0x85, 0x35, 0x13, | ||
397 | 0x02, 0x45, 0x30, 0x30, 0x40, 0x20, | ||
398 | }, | ||
399 | { /* Init_SR80_SR93 */ | ||
400 | 0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x36, | ||
401 | 0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x36, 0x36, | ||
402 | 0x00, 0x00, 0x00, 0x00, | ||
403 | }, | ||
404 | { /* Init_SRA0_SRAF */ | ||
405 | 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED, | ||
406 | 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xBF, 0xDF, | ||
407 | }, | ||
408 | { /* Init_GR00_GR08 */ | ||
409 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, | ||
410 | 0xFF, | ||
411 | }, | ||
412 | { /* Init_AR00_AR14 */ | ||
413 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, | ||
414 | 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, | ||
415 | 0x41, 0x00, 0x0F, 0x00, 0x00, | ||
416 | }, | ||
417 | { /* Init_CR00_CR18 */ | ||
418 | 0x7F, 0x63, 0x63, 0x00, 0x68, 0x18, 0x72, 0xF0, | ||
419 | 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
420 | 0x58, 0x0C, 0x57, 0x64, 0x40, 0x57, 0x00, 0xE3, | ||
421 | 0xFF, | ||
422 | }, | ||
423 | { /* Init_CR30_CR4D */ | ||
424 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x03, 0x20, | ||
425 | 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xBF, 0xFD, | ||
426 | 0x7F, 0x63, 0x00, 0x69, 0x18, 0x72, 0x57, 0x00, | ||
427 | 0x58, 0x0C, 0xE0, 0x20, 0x63, 0x57, | ||
428 | }, | ||
429 | { /* Init_CR90_CRA7 */ | ||
430 | 0x56, 0x4B, 0x5E, 0x55, 0x86, 0x9D, 0x8E, 0xAA, | ||
431 | 0xDB, 0x2A, 0xDF, 0x33, 0x00, 0x00, 0x18, 0x00, | ||
432 | 0x20, 0x1F, 0x1A, 0x19, 0x0F, 0x0F, 0x0F, 0x00, | ||
433 | }, | ||
434 | }, | ||
435 | { /* mode#7: 800 x 600 32Bpp 60Hz */ | ||
436 | 800, 600, 32, 60, | ||
437 | /* Init_MISC */ | ||
438 | 0x2B, | ||
439 | { /* Init_SR0_SR4 */ | ||
440 | 0x03, 0x01, 0x0F, 0x03, 0x0E, | ||
441 | }, | ||
442 | { /* Init_SR10_SR24 */ | ||
443 | 0xFF, 0xBE, 0xEE, 0xFF, 0x00, 0x0E, 0x17, 0x2C, | ||
444 | 0x99, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
445 | 0xC4, 0x30, 0x02, 0x01, 0x01, | ||
446 | }, | ||
447 | { /* Init_SR30_SR75 */ | ||
448 | 0x34, 0x03, 0x20, 0x09, 0xC0, 0x24, 0x24, 0x24, | ||
449 | 0x24, 0x24, 0x24, 0x24, 0x00, 0x00, 0x03, 0xFF, | ||
450 | 0x00, 0xFC, 0x00, 0x00, 0x20, 0x38, 0x00, 0xFC, | ||
451 | 0x20, 0x0C, 0x44, 0x20, 0x00, 0x24, 0x24, 0x24, | ||
452 | 0x04, 0x48, 0x83, 0x63, 0x68, 0x72, 0x57, 0x58, | ||
453 | 0x04, 0x55, 0x59, 0x24, 0x24, 0x00, 0x00, 0x24, | ||
454 | 0x01, 0x80, 0x7A, 0x1A, 0x1A, 0x00, 0x00, 0x00, | ||
455 | 0x50, 0x03, 0x74, 0x14, 0x1C, 0x85, 0x35, 0x13, | ||
456 | 0x02, 0x45, 0x30, 0x35, 0x40, 0x20, | ||
457 | }, | ||
458 | { /* Init_SR80_SR93 */ | ||
459 | 0x00, 0x00, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x24, | ||
460 | 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x24, 0x24, | ||
461 | 0x00, 0x00, 0x00, 0x00, | ||
462 | }, | ||
463 | { /* Init_SRA0_SRAF */ | ||
464 | 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED, | ||
465 | 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xBF, 0xDF, | ||
466 | }, | ||
467 | { /* Init_GR00_GR08 */ | ||
468 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, | ||
469 | 0xFF, | ||
470 | }, | ||
471 | { /* Init_AR00_AR14 */ | ||
472 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, | ||
473 | 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, | ||
474 | 0x41, 0x00, 0x0F, 0x00, 0x00, | ||
475 | }, | ||
476 | { /* Init_CR00_CR18 */ | ||
477 | 0x7F, 0x63, 0x63, 0x00, 0x68, 0x18, 0x72, 0xF0, | ||
478 | 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
479 | 0x58, 0x0C, 0x57, 0x64, 0x40, 0x57, 0x00, 0xE3, | ||
480 | 0xFF, | ||
481 | }, | ||
482 | { /* Init_CR30_CR4D */ | ||
483 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x03, 0x20, | ||
484 | 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xBF, 0xFD, | ||
485 | 0x7F, 0x63, 0x00, 0x69, 0x18, 0x72, 0x57, 0x00, | ||
486 | 0x58, 0x0C, 0xE0, 0x20, 0x63, 0x57, | ||
487 | }, | ||
488 | { /* Init_CR90_CRA7 */ | ||
489 | 0x56, 0x4B, 0x5E, 0x55, 0x86, 0x9D, 0x8E, 0xAA, | ||
490 | 0xDB, 0x2A, 0xDF, 0x33, 0x00, 0x00, 0x18, 0x00, | ||
491 | 0x20, 0x1F, 0x1A, 0x19, 0x0F, 0x0F, 0x0F, 0x00, | ||
492 | }, | ||
493 | }, | ||
494 | /* We use 1024x768 table to light 1024x600 panel for lemote */ | ||
495 | { /* mode#4: 1024 x 600 16Bpp 60Hz */ | ||
496 | 1024, 600, 16, 60, | ||
497 | /* Init_MISC */ | ||
498 | 0xEB, | ||
499 | { /* Init_SR0_SR4 */ | ||
500 | 0x03, 0x01, 0x0F, 0x00, 0x0E, | ||
501 | }, | ||
502 | { /* Init_SR10_SR24 */ | ||
503 | 0xC8, 0x40, 0x14, 0x60, 0x00, 0x0A, 0x17, 0x20, | ||
504 | 0x51, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
505 | 0xC4, 0x30, 0x02, 0x00, 0x01, | ||
506 | }, | ||
507 | { /* Init_SR30_SR75 */ | ||
508 | 0x22, 0x03, 0x24, 0x09, 0xC0, 0x22, 0x22, 0x22, | ||
509 | 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x03, 0xFF, | ||
510 | 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, | ||
511 | 0x20, 0x0C, 0x44, 0x20, 0x00, 0x22, 0x22, 0x22, | ||
512 | 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03, | ||
513 | 0x00, 0x60, 0x59, 0x22, 0x22, 0x00, 0x00, 0x22, | ||
514 | 0x01, 0x80, 0x7A, 0x1A, 0x1A, 0x00, 0x00, 0x00, | ||
515 | 0x50, 0x03, 0x16, 0x02, 0x0D, 0x82, 0x09, 0x02, | ||
516 | 0x04, 0x45, 0x3F, 0x30, 0x40, 0x20, | ||
517 | }, | ||
518 | { /* Init_SR80_SR93 */ | ||
519 | 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A, | ||
520 | 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A, | ||
521 | 0x00, 0x00, 0x00, 0x00, | ||
522 | }, | ||
523 | { /* Init_SRA0_SRAF */ | ||
524 | 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED, | ||
525 | 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF, | ||
526 | }, | ||
527 | { /* Init_GR00_GR08 */ | ||
528 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, | ||
529 | 0xFF, | ||
530 | }, | ||
531 | { /* Init_AR00_AR14 */ | ||
532 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, | ||
533 | 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, | ||
534 | 0x41, 0x00, 0x0F, 0x00, 0x00, | ||
535 | }, | ||
536 | { /* Init_CR00_CR18 */ | ||
537 | 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5, | ||
538 | 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
539 | 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3, | ||
540 | 0xFF, | ||
541 | }, | ||
542 | { /* Init_CR30_CR4D */ | ||
543 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20, | ||
544 | 0x00, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xBF, 0xFF, | ||
545 | 0xA3, 0x7F, 0x00, 0x82, 0x0b, 0x6f, 0x57, 0x00, | ||
546 | 0x5c, 0x0f, 0xE0, 0xe0, 0x7F, 0x57, | ||
547 | }, | ||
548 | { /* Init_CR90_CRA7 */ | ||
549 | 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26, | ||
550 | 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00, | ||
551 | 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03, | ||
552 | }, | ||
553 | }, | ||
554 | { /* mode#5: 1024 x 768 24Bpp 60Hz */ | ||
555 | 1024, 768, 24, 60, | ||
556 | /* Init_MISC */ | ||
557 | 0xEB, | ||
558 | { /* Init_SR0_SR4 */ | ||
559 | 0x03, 0x01, 0x0F, 0x03, 0x0E, | ||
560 | }, | ||
561 | { /* Init_SR10_SR24 */ | ||
562 | 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C, | ||
563 | 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
564 | 0xC4, 0x30, 0x02, 0x01, 0x01, | ||
565 | }, | ||
566 | { /* Init_SR30_SR75 */ | ||
567 | 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A, | ||
568 | 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF, | ||
569 | 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, | ||
570 | 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A, | ||
571 | 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03, | ||
572 | 0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A, | ||
573 | 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, | ||
574 | 0x50, 0x03, 0x74, 0x14, 0x3B, 0x0D, 0x09, 0x02, | ||
575 | 0x04, 0x45, 0x30, 0x30, 0x40, 0x20, | ||
576 | }, | ||
577 | { /* Init_SR80_SR93 */ | ||
578 | 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A, | ||
579 | 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A, | ||
580 | 0x00, 0x00, 0x00, 0x00, | ||
581 | }, | ||
582 | { /* Init_SRA0_SRAF */ | ||
583 | 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED, | ||
584 | 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF, | ||
585 | }, | ||
586 | { /* Init_GR00_GR08 */ | ||
587 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, | ||
588 | 0xFF, | ||
589 | }, | ||
590 | { /* Init_AR00_AR14 */ | ||
591 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, | ||
592 | 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, | ||
593 | 0x41, 0x00, 0x0F, 0x00, 0x00, | ||
594 | }, | ||
595 | { /* Init_CR00_CR18 */ | ||
596 | 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5, | ||
597 | 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
598 | 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3, | ||
599 | 0xFF, | ||
600 | }, | ||
601 | { /* Init_CR30_CR4D */ | ||
602 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20, | ||
603 | 0x00, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xBF, 0xFF, | ||
604 | 0xA3, 0x7F, 0x00, 0x86, 0x15, 0x24, 0xFF, 0x00, | ||
605 | 0x01, 0x07, 0xE5, 0x20, 0x7F, 0xFF, | ||
606 | }, | ||
607 | { /* Init_CR90_CRA7 */ | ||
608 | 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26, | ||
609 | 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00, | ||
610 | 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03, | ||
611 | }, | ||
612 | }, | ||
613 | { /* mode#4: 1024 x 768 32Bpp 60Hz */ | ||
614 | 1024, 768, 32, 60, | ||
615 | /* Init_MISC */ | ||
616 | 0xEB, | ||
617 | { /* Init_SR0_SR4 */ | ||
618 | 0x03, 0x01, 0x0F, 0x03, 0x0E, | ||
619 | }, | ||
620 | { /* Init_SR10_SR24 */ | ||
621 | 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C, | ||
622 | 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
623 | 0xC4, 0x32, 0x02, 0x01, 0x01, | ||
624 | }, | ||
625 | { /* Init_SR30_SR75 */ | ||
626 | 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A, | ||
627 | 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF, | ||
628 | 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, | ||
629 | 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A, | ||
630 | 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03, | ||
631 | 0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A, | ||
632 | 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, | ||
633 | 0x50, 0x03, 0x74, 0x14, 0x3B, 0x0D, 0x09, 0x02, | ||
634 | 0x04, 0x45, 0x30, 0x30, 0x40, 0x20, | ||
635 | }, | ||
636 | { /* Init_SR80_SR93 */ | ||
637 | 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A, | ||
638 | 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A, | ||
639 | 0x00, 0x00, 0x00, 0x00, | ||
640 | }, | ||
641 | { /* Init_SRA0_SRAF */ | ||
642 | 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED, | ||
643 | 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF, | ||
644 | }, | ||
645 | { /* Init_GR00_GR08 */ | ||
646 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, | ||
647 | 0xFF, | ||
648 | }, | ||
649 | { /* Init_AR00_AR14 */ | ||
650 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, | ||
651 | 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, | ||
652 | 0x41, 0x00, 0x0F, 0x00, 0x00, | ||
653 | }, | ||
654 | { /* Init_CR00_CR18 */ | ||
655 | 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5, | ||
656 | 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
657 | 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3, | ||
658 | 0xFF, | ||
659 | }, | ||
660 | { /* Init_CR30_CR4D */ | ||
661 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20, | ||
662 | 0x00, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xBF, 0xFF, | ||
663 | 0xA3, 0x7F, 0x00, 0x86, 0x15, 0x24, 0xFF, 0x00, | ||
664 | 0x01, 0x07, 0xE5, 0x20, 0x7F, 0xFF, | ||
665 | }, | ||
666 | { /* Init_CR90_CRA7 */ | ||
667 | 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26, | ||
668 | 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00, | ||
669 | 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03, | ||
670 | }, | ||
671 | }, | ||
672 | { /* mode#6: 320 x 240 16Bpp 60Hz */ | ||
673 | 320, 240, 16, 60, | ||
674 | /* Init_MISC */ | ||
675 | 0xEB, | ||
676 | { /* Init_SR0_SR4 */ | ||
677 | 0x03, 0x01, 0x0F, 0x03, 0x0E, | ||
678 | }, | ||
679 | { /* Init_SR10_SR24 */ | ||
680 | 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C, | ||
681 | 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
682 | 0xC4, 0x32, 0x02, 0x01, 0x01, | ||
683 | }, | ||
684 | { /* Init_SR30_SR75 */ | ||
685 | 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A, | ||
686 | 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF, | ||
687 | 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, | ||
688 | 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A, | ||
689 | 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03, | ||
690 | 0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A, | ||
691 | 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, | ||
692 | 0x50, 0x03, 0x74, 0x14, 0x08, 0x43, 0x08, 0x43, | ||
693 | 0x04, 0x45, 0x30, 0x30, 0x40, 0x20, | ||
694 | }, | ||
695 | { /* Init_SR80_SR93 */ | ||
696 | 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A, | ||
697 | 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A, | ||
698 | 0x00, 0x00, 0x00, 0x00, | ||
699 | }, | ||
700 | { /* Init_SRA0_SRAF */ | ||
701 | 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED, | ||
702 | 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF, | ||
703 | }, | ||
704 | { /* Init_GR00_GR08 */ | ||
705 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, | ||
706 | 0xFF, | ||
707 | }, | ||
708 | { /* Init_AR00_AR14 */ | ||
709 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, | ||
710 | 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, | ||
711 | 0x41, 0x00, 0x0F, 0x00, 0x00, | ||
712 | }, | ||
713 | { /* Init_CR00_CR18 */ | ||
714 | 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5, | ||
715 | 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
716 | 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3, | ||
717 | 0xFF, | ||
718 | }, | ||
719 | { /* Init_CR30_CR4D */ | ||
720 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20, | ||
721 | 0x00, 0x00, 0x30, 0x40, 0x00, 0xFF, 0xBF, 0xFF, | ||
722 | 0x2E, 0x27, 0x00, 0x2b, 0x0c, 0x0F, 0xEF, 0x00, | ||
723 | 0xFe, 0x0f, 0x01, 0xC0, 0x27, 0xEF, | ||
724 | }, | ||
725 | { /* Init_CR90_CRA7 */ | ||
726 | 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26, | ||
727 | 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00, | ||
728 | 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03, | ||
729 | }, | ||
730 | }, | ||
731 | |||
732 | { /* mode#8: 320 x 240 32Bpp 60Hz */ | ||
733 | 320, 240, 32, 60, | ||
734 | /* Init_MISC */ | ||
735 | 0xEB, | ||
736 | { /* Init_SR0_SR4 */ | ||
737 | 0x03, 0x01, 0x0F, 0x03, 0x0E, | ||
738 | }, | ||
739 | { /* Init_SR10_SR24 */ | ||
740 | 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C, | ||
741 | 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
742 | 0xC4, 0x32, 0x02, 0x01, 0x01, | ||
743 | }, | ||
744 | { /* Init_SR30_SR75 */ | ||
745 | 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A, | ||
746 | 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF, | ||
747 | 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC, | ||
748 | 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A, | ||
749 | 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03, | ||
750 | 0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A, | ||
751 | 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00, | ||
752 | 0x50, 0x03, 0x74, 0x14, 0x08, 0x43, 0x08, 0x43, | ||
753 | 0x04, 0x45, 0x30, 0x30, 0x40, 0x20, | ||
754 | }, | ||
755 | { /* Init_SR80_SR93 */ | ||
756 | 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A, | ||
757 | 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A, | ||
758 | 0x00, 0x00, 0x00, 0x00, | ||
759 | }, | ||
760 | { /* Init_SRA0_SRAF */ | ||
761 | 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED, | ||
762 | 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF, | ||
763 | }, | ||
764 | { /* Init_GR00_GR08 */ | ||
765 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, | ||
766 | 0xFF, | ||
767 | }, | ||
768 | { /* Init_AR00_AR14 */ | ||
769 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, | ||
770 | 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, | ||
771 | 0x41, 0x00, 0x0F, 0x00, 0x00, | ||
772 | }, | ||
773 | { /* Init_CR00_CR18 */ | ||
774 | 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5, | ||
775 | 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
776 | 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3, | ||
777 | 0xFF, | ||
778 | }, | ||
779 | { /* Init_CR30_CR4D */ | ||
780 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20, | ||
781 | 0x00, 0x00, 0x30, 0x40, 0x00, 0xFF, 0xBF, 0xFF, | ||
782 | 0x2E, 0x27, 0x00, 0x2b, 0x0c, 0x0F, 0xEF, 0x00, | ||
783 | 0xFe, 0x0f, 0x01, 0xC0, 0x27, 0xEF, | ||
784 | }, | ||
785 | { /* Init_CR90_CRA7 */ | ||
786 | 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26, | ||
787 | 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00, | ||
788 | 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03, | ||
789 | }, | ||
790 | }, | ||
791 | }; | ||
792 | |||
793 | #define numVGAModes (sizeof(VGAMode) / sizeof(struct ModeInit)) | ||
diff --git a/drivers/staging/vt6655/Kconfig b/drivers/staging/vt6655/Kconfig index 825bbc4fc3fa..061e730df2d0 100644 --- a/drivers/staging/vt6655/Kconfig +++ b/drivers/staging/vt6655/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config VT6655 | 1 | config VT6655 |
2 | tristate "VIA Technologies VT6655 support" | 2 | tristate "VIA Technologies VT6655 support" |
3 | depends on PCI | 3 | depends on PCI && WLAN |
4 | select WIRELESS_EXT | 4 | select WIRELESS_EXT |
5 | select WEXT_PRIV | 5 | select WEXT_PRIV |
6 | ---help--- | 6 | ---help--- |
diff --git a/drivers/staging/vt6656/Kconfig b/drivers/staging/vt6656/Kconfig index 87bcd269310c..1055b526c532 100644 --- a/drivers/staging/vt6656/Kconfig +++ b/drivers/staging/vt6656/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config VT6656 | 1 | config VT6656 |
2 | tristate "VIA Technologies VT6656 support" | 2 | tristate "VIA Technologies VT6656 support" |
3 | depends on USB | 3 | depends on USB && WLAN |
4 | select WIRELESS_EXT | 4 | select WIRELESS_EXT |
5 | select WEXT_PRIV | 5 | select WEXT_PRIV |
6 | ---help--- | 6 | ---help--- |
diff --git a/drivers/staging/wlan-ng/prism2fw.c b/drivers/staging/wlan-ng/prism2fw.c index 7d76a7f92a33..aaa70ed57710 100644 --- a/drivers/staging/wlan-ng/prism2fw.c +++ b/drivers/staging/wlan-ng/prism2fw.c | |||
@@ -439,7 +439,7 @@ void free_chunks(imgchunk_t *fchunk, unsigned int *nfchunks) | |||
439 | } | 439 | } |
440 | } | 440 | } |
441 | *nfchunks = 0; | 441 | *nfchunks = 0; |
442 | memset(fchunk, 0, sizeof(fchunk)); | 442 | memset(fchunk, 0, sizeof(*fchunk)); |
443 | 443 | ||
444 | } | 444 | } |
445 | 445 | ||
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index 473aa1a20de9..be3c9b80bc9f 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile | |||
@@ -44,5 +44,3 @@ obj-y += early/ | |||
44 | 44 | ||
45 | obj-$(CONFIG_USB_ATM) += atm/ | 45 | obj-$(CONFIG_USB_ATM) += atm/ |
46 | obj-$(CONFIG_USB_SPEEDTOUCH) += atm/ | 46 | obj-$(CONFIG_USB_SPEEDTOUCH) += atm/ |
47 | |||
48 | obj-$(CONFIG_USB_ULPI) += otg/ | ||
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 6dac3b802d41..0495fa651225 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -1597,7 +1597,9 @@ rescan: | |||
1597 | } | 1597 | } |
1598 | 1598 | ||
1599 | /** | 1599 | /** |
1600 | * Check whether a new bandwidth setting exceeds the bus bandwidth. | 1600 | * usb_hcd_alloc_bandwidth - check whether a new bandwidth setting exceeds |
1601 | * the bus bandwidth | ||
1602 | * @udev: target &usb_device | ||
1601 | * @new_config: new configuration to install | 1603 | * @new_config: new configuration to install |
1602 | * @cur_alt: the current alternate interface setting | 1604 | * @cur_alt: the current alternate interface setting |
1603 | * @new_alt: alternate interface setting that is being installed | 1605 | * @new_alt: alternate interface setting that is being installed |
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 06af970e1064..0cec6caf6e9b 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -1658,12 +1658,12 @@ static inline void announce_device(struct usb_device *udev) { } | |||
1658 | #endif | 1658 | #endif |
1659 | 1659 | ||
1660 | /** | 1660 | /** |
1661 | * usb_configure_device_otg - FIXME (usbcore-internal) | 1661 | * usb_enumerate_device_otg - FIXME (usbcore-internal) |
1662 | * @udev: newly addressed device (in ADDRESS state) | 1662 | * @udev: newly addressed device (in ADDRESS state) |
1663 | * | 1663 | * |
1664 | * Do configuration for On-The-Go devices | 1664 | * Finish enumeration for On-The-Go devices |
1665 | */ | 1665 | */ |
1666 | static int usb_configure_device_otg(struct usb_device *udev) | 1666 | static int usb_enumerate_device_otg(struct usb_device *udev) |
1667 | { | 1667 | { |
1668 | int err = 0; | 1668 | int err = 0; |
1669 | 1669 | ||
@@ -1734,7 +1734,7 @@ fail: | |||
1734 | 1734 | ||
1735 | 1735 | ||
1736 | /** | 1736 | /** |
1737 | * usb_configure_device - Detect and probe device intfs/otg (usbcore-internal) | 1737 | * usb_enumerate_device - Read device configs/intfs/otg (usbcore-internal) |
1738 | * @udev: newly addressed device (in ADDRESS state) | 1738 | * @udev: newly addressed device (in ADDRESS state) |
1739 | * | 1739 | * |
1740 | * This is only called by usb_new_device() and usb_authorize_device() | 1740 | * This is only called by usb_new_device() and usb_authorize_device() |
@@ -1745,7 +1745,7 @@ fail: | |||
1745 | * the string descriptors, as they will be errored out by the device | 1745 | * the string descriptors, as they will be errored out by the device |
1746 | * until it has been authorized. | 1746 | * until it has been authorized. |
1747 | */ | 1747 | */ |
1748 | static int usb_configure_device(struct usb_device *udev) | 1748 | static int usb_enumerate_device(struct usb_device *udev) |
1749 | { | 1749 | { |
1750 | int err; | 1750 | int err; |
1751 | 1751 | ||
@@ -1769,7 +1769,7 @@ static int usb_configure_device(struct usb_device *udev) | |||
1769 | udev->descriptor.iManufacturer); | 1769 | udev->descriptor.iManufacturer); |
1770 | udev->serial = usb_cache_string(udev, udev->descriptor.iSerialNumber); | 1770 | udev->serial = usb_cache_string(udev, udev->descriptor.iSerialNumber); |
1771 | } | 1771 | } |
1772 | err = usb_configure_device_otg(udev); | 1772 | err = usb_enumerate_device_otg(udev); |
1773 | fail: | 1773 | fail: |
1774 | return err; | 1774 | return err; |
1775 | } | 1775 | } |
@@ -1779,8 +1779,8 @@ fail: | |||
1779 | * usb_new_device - perform initial device setup (usbcore-internal) | 1779 | * usb_new_device - perform initial device setup (usbcore-internal) |
1780 | * @udev: newly addressed device (in ADDRESS state) | 1780 | * @udev: newly addressed device (in ADDRESS state) |
1781 | * | 1781 | * |
1782 | * This is called with devices which have been enumerated, but not yet | 1782 | * This is called with devices which have been detected but not fully |
1783 | * configured. The device descriptor is available, but not descriptors | 1783 | * enumerated. The device descriptor is available, but not descriptors |
1784 | * for any device configuration. The caller must have locked either | 1784 | * for any device configuration. The caller must have locked either |
1785 | * the parent hub (if udev is a normal device) or else the | 1785 | * the parent hub (if udev is a normal device) or else the |
1786 | * usb_bus_list_lock (if udev is a root hub). The parent's pointer to | 1786 | * usb_bus_list_lock (if udev is a root hub). The parent's pointer to |
@@ -1803,8 +1803,8 @@ int usb_new_device(struct usb_device *udev) | |||
1803 | if (udev->parent) | 1803 | if (udev->parent) |
1804 | usb_autoresume_device(udev->parent); | 1804 | usb_autoresume_device(udev->parent); |
1805 | 1805 | ||
1806 | usb_detect_quirks(udev); /* Determine quirks */ | 1806 | usb_detect_quirks(udev); |
1807 | err = usb_configure_device(udev); /* detect & probe dev/intfs */ | 1807 | err = usb_enumerate_device(udev); /* Read descriptors */ |
1808 | if (err < 0) | 1808 | if (err < 0) |
1809 | goto fail; | 1809 | goto fail; |
1810 | dev_dbg(&udev->dev, "udev %d, busnum %d, minor = %d\n", | 1810 | dev_dbg(&udev->dev, "udev %d, busnum %d, minor = %d\n", |
@@ -1849,21 +1849,23 @@ fail: | |||
1849 | */ | 1849 | */ |
1850 | int usb_deauthorize_device(struct usb_device *usb_dev) | 1850 | int usb_deauthorize_device(struct usb_device *usb_dev) |
1851 | { | 1851 | { |
1852 | unsigned cnt; | ||
1853 | usb_lock_device(usb_dev); | 1852 | usb_lock_device(usb_dev); |
1854 | if (usb_dev->authorized == 0) | 1853 | if (usb_dev->authorized == 0) |
1855 | goto out_unauthorized; | 1854 | goto out_unauthorized; |
1855 | |||
1856 | usb_dev->authorized = 0; | 1856 | usb_dev->authorized = 0; |
1857 | usb_set_configuration(usb_dev, -1); | 1857 | usb_set_configuration(usb_dev, -1); |
1858 | |||
1859 | kfree(usb_dev->product); | ||
1858 | usb_dev->product = kstrdup("n/a (unauthorized)", GFP_KERNEL); | 1860 | usb_dev->product = kstrdup("n/a (unauthorized)", GFP_KERNEL); |
1861 | kfree(usb_dev->manufacturer); | ||
1859 | usb_dev->manufacturer = kstrdup("n/a (unauthorized)", GFP_KERNEL); | 1862 | usb_dev->manufacturer = kstrdup("n/a (unauthorized)", GFP_KERNEL); |
1863 | kfree(usb_dev->serial); | ||
1860 | usb_dev->serial = kstrdup("n/a (unauthorized)", GFP_KERNEL); | 1864 | usb_dev->serial = kstrdup("n/a (unauthorized)", GFP_KERNEL); |
1861 | kfree(usb_dev->config); | 1865 | |
1862 | usb_dev->config = NULL; | 1866 | usb_destroy_configuration(usb_dev); |
1863 | for (cnt = 0; cnt < usb_dev->descriptor.bNumConfigurations; cnt++) | ||
1864 | kfree(usb_dev->rawdescriptors[cnt]); | ||
1865 | usb_dev->descriptor.bNumConfigurations = 0; | 1867 | usb_dev->descriptor.bNumConfigurations = 0; |
1866 | kfree(usb_dev->rawdescriptors); | 1868 | |
1867 | out_unauthorized: | 1869 | out_unauthorized: |
1868 | usb_unlock_device(usb_dev); | 1870 | usb_unlock_device(usb_dev); |
1869 | return 0; | 1871 | return 0; |
@@ -1873,15 +1875,11 @@ out_unauthorized: | |||
1873 | int usb_authorize_device(struct usb_device *usb_dev) | 1875 | int usb_authorize_device(struct usb_device *usb_dev) |
1874 | { | 1876 | { |
1875 | int result = 0, c; | 1877 | int result = 0, c; |
1878 | |||
1876 | usb_lock_device(usb_dev); | 1879 | usb_lock_device(usb_dev); |
1877 | if (usb_dev->authorized == 1) | 1880 | if (usb_dev->authorized == 1) |
1878 | goto out_authorized; | 1881 | goto out_authorized; |
1879 | kfree(usb_dev->product); | 1882 | |
1880 | usb_dev->product = NULL; | ||
1881 | kfree(usb_dev->manufacturer); | ||
1882 | usb_dev->manufacturer = NULL; | ||
1883 | kfree(usb_dev->serial); | ||
1884 | usb_dev->serial = NULL; | ||
1885 | result = usb_autoresume_device(usb_dev); | 1883 | result = usb_autoresume_device(usb_dev); |
1886 | if (result < 0) { | 1884 | if (result < 0) { |
1887 | dev_err(&usb_dev->dev, | 1885 | dev_err(&usb_dev->dev, |
@@ -1894,10 +1892,18 @@ int usb_authorize_device(struct usb_device *usb_dev) | |||
1894 | "authorization: %d\n", result); | 1892 | "authorization: %d\n", result); |
1895 | goto error_device_descriptor; | 1893 | goto error_device_descriptor; |
1896 | } | 1894 | } |
1895 | |||
1896 | kfree(usb_dev->product); | ||
1897 | usb_dev->product = NULL; | ||
1898 | kfree(usb_dev->manufacturer); | ||
1899 | usb_dev->manufacturer = NULL; | ||
1900 | kfree(usb_dev->serial); | ||
1901 | usb_dev->serial = NULL; | ||
1902 | |||
1897 | usb_dev->authorized = 1; | 1903 | usb_dev->authorized = 1; |
1898 | result = usb_configure_device(usb_dev); | 1904 | result = usb_enumerate_device(usb_dev); |
1899 | if (result < 0) | 1905 | if (result < 0) |
1900 | goto error_configure; | 1906 | goto error_enumerate; |
1901 | /* Choose and set the configuration. This registers the interfaces | 1907 | /* Choose and set the configuration. This registers the interfaces |
1902 | * with the driver core and lets interface drivers bind to them. | 1908 | * with the driver core and lets interface drivers bind to them. |
1903 | */ | 1909 | */ |
@@ -1912,8 +1918,10 @@ int usb_authorize_device(struct usb_device *usb_dev) | |||
1912 | } | 1918 | } |
1913 | } | 1919 | } |
1914 | dev_info(&usb_dev->dev, "authorized to connect\n"); | 1920 | dev_info(&usb_dev->dev, "authorized to connect\n"); |
1915 | error_configure: | 1921 | |
1922 | error_enumerate: | ||
1916 | error_device_descriptor: | 1923 | error_device_descriptor: |
1924 | usb_autosuspend_device(usb_dev); | ||
1917 | error_autoresume: | 1925 | error_autoresume: |
1918 | out_authorized: | 1926 | out_authorized: |
1919 | usb_unlock_device(usb_dev); // complements locktree | 1927 | usb_unlock_device(usb_dev); // complements locktree |
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index 15477008b631..485edf937f25 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c | |||
@@ -82,9 +82,13 @@ static ssize_t show_##name(struct device *dev, \ | |||
82 | struct device_attribute *attr, char *buf) \ | 82 | struct device_attribute *attr, char *buf) \ |
83 | { \ | 83 | { \ |
84 | struct usb_device *udev; \ | 84 | struct usb_device *udev; \ |
85 | int retval; \ | ||
85 | \ | 86 | \ |
86 | udev = to_usb_device(dev); \ | 87 | udev = to_usb_device(dev); \ |
87 | return sprintf(buf, "%s\n", udev->name); \ | 88 | usb_lock_device(udev); \ |
89 | retval = sprintf(buf, "%s\n", udev->name); \ | ||
90 | usb_unlock_device(udev); \ | ||
91 | return retval; \ | ||
88 | } \ | 92 | } \ |
89 | static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL); | 93 | static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL); |
90 | 94 | ||
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 2fb42043b305..0daff0d968ba 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c | |||
@@ -66,9 +66,9 @@ MODULE_PARM_DESC(autosuspend, "default autosuspend delay"); | |||
66 | /** | 66 | /** |
67 | * usb_find_alt_setting() - Given a configuration, find the alternate setting | 67 | * usb_find_alt_setting() - Given a configuration, find the alternate setting |
68 | * for the given interface. | 68 | * for the given interface. |
69 | * @config - the configuration to search (not necessarily the current config). | 69 | * @config: the configuration to search (not necessarily the current config). |
70 | * @iface_num - interface number to search in | 70 | * @iface_num: interface number to search in |
71 | * @alt_num - alternate interface setting number to search for. | 71 | * @alt_num: alternate interface setting number to search for. |
72 | * | 72 | * |
73 | * Search the configuration's interface cache for the given alt setting. | 73 | * Search the configuration's interface cache for the given alt setting. |
74 | */ | 74 | */ |
diff --git a/drivers/usb/early/ehci-dbgp.c b/drivers/usb/early/ehci-dbgp.c index 1206a26ef893..2958a1271b20 100644 --- a/drivers/usb/early/ehci-dbgp.c +++ b/drivers/usb/early/ehci-dbgp.c | |||
@@ -613,7 +613,7 @@ err: | |||
613 | } | 613 | } |
614 | EXPORT_SYMBOL_GPL(dbgp_external_startup); | 614 | EXPORT_SYMBOL_GPL(dbgp_external_startup); |
615 | 615 | ||
616 | static int __init ehci_reset_port(int port) | 616 | static int ehci_reset_port(int port) |
617 | { | 617 | { |
618 | u32 portsc; | 618 | u32 portsc; |
619 | u32 delay_time, delay; | 619 | u32 delay_time, delay; |
diff --git a/drivers/usb/gadget/audio.c b/drivers/usb/gadget/audio.c index 58f220323847..a62af7b59094 100644 --- a/drivers/usb/gadget/audio.c +++ b/drivers/usb/gadget/audio.c | |||
@@ -158,6 +158,7 @@ fail: | |||
158 | 158 | ||
159 | static int __exit audio_unbind(struct usb_composite_dev *cdev) | 159 | static int __exit audio_unbind(struct usb_composite_dev *cdev) |
160 | { | 160 | { |
161 | gaudio_cleanup(); | ||
161 | return 0; | 162 | return 0; |
162 | } | 163 | } |
163 | 164 | ||
diff --git a/drivers/usb/gadget/f_audio.c b/drivers/usb/gadget/f_audio.c index c43c89ffa2c8..df77f6131c73 100644 --- a/drivers/usb/gadget/f_audio.c +++ b/drivers/usb/gadget/f_audio.c | |||
@@ -56,13 +56,16 @@ static struct usb_interface_descriptor ac_interface_desc __initdata = { | |||
56 | DECLARE_UAC_AC_HEADER_DESCRIPTOR(2); | 56 | DECLARE_UAC_AC_HEADER_DESCRIPTOR(2); |
57 | 57 | ||
58 | #define UAC_DT_AC_HEADER_LENGTH UAC_DT_AC_HEADER_SIZE(F_AUDIO_NUM_INTERFACES) | 58 | #define UAC_DT_AC_HEADER_LENGTH UAC_DT_AC_HEADER_SIZE(F_AUDIO_NUM_INTERFACES) |
59 | /* 1 input terminal, 1 output terminal and 1 feature unit */ | ||
60 | #define UAC_DT_TOTAL_LENGTH (UAC_DT_AC_HEADER_LENGTH + UAC_DT_INPUT_TERMINAL_SIZE \ | ||
61 | + UAC_DT_OUTPUT_TERMINAL_SIZE + UAC_DT_FEATURE_UNIT_SIZE(0)) | ||
59 | /* B.3.2 Class-Specific AC Interface Descriptor */ | 62 | /* B.3.2 Class-Specific AC Interface Descriptor */ |
60 | static struct uac_ac_header_descriptor_2 ac_header_desc = { | 63 | static struct uac_ac_header_descriptor_2 ac_header_desc = { |
61 | .bLength = UAC_DT_AC_HEADER_LENGTH, | 64 | .bLength = UAC_DT_AC_HEADER_LENGTH, |
62 | .bDescriptorType = USB_DT_CS_INTERFACE, | 65 | .bDescriptorType = USB_DT_CS_INTERFACE, |
63 | .bDescriptorSubtype = UAC_HEADER, | 66 | .bDescriptorSubtype = UAC_HEADER, |
64 | .bcdADC = __constant_cpu_to_le16(0x0100), | 67 | .bcdADC = __constant_cpu_to_le16(0x0100), |
65 | .wTotalLength = __constant_cpu_to_le16(UAC_DT_AC_HEADER_LENGTH), | 68 | .wTotalLength = __constant_cpu_to_le16(UAC_DT_TOTAL_LENGTH), |
66 | .bInCollection = F_AUDIO_NUM_INTERFACES, | 69 | .bInCollection = F_AUDIO_NUM_INTERFACES, |
67 | .baInterfaceNr = { | 70 | .baInterfaceNr = { |
68 | [0] = F_AUDIO_AC_INTERFACE, | 71 | [0] = F_AUDIO_AC_INTERFACE, |
@@ -252,12 +255,12 @@ static struct f_audio_buf *f_audio_buffer_alloc(int buf_size) | |||
252 | 255 | ||
253 | copy_buf = kzalloc(sizeof *copy_buf, GFP_ATOMIC); | 256 | copy_buf = kzalloc(sizeof *copy_buf, GFP_ATOMIC); |
254 | if (!copy_buf) | 257 | if (!copy_buf) |
255 | return (struct f_audio_buf *)-ENOMEM; | 258 | return ERR_PTR(-ENOMEM); |
256 | 259 | ||
257 | copy_buf->buf = kzalloc(buf_size, GFP_ATOMIC); | 260 | copy_buf->buf = kzalloc(buf_size, GFP_ATOMIC); |
258 | if (!copy_buf->buf) { | 261 | if (!copy_buf->buf) { |
259 | kfree(copy_buf); | 262 | kfree(copy_buf); |
260 | return (struct f_audio_buf *)-ENOMEM; | 263 | return ERR_PTR(-ENOMEM); |
261 | } | 264 | } |
262 | 265 | ||
263 | return copy_buf; | 266 | return copy_buf; |
@@ -332,7 +335,7 @@ static int f_audio_out_ep_complete(struct usb_ep *ep, struct usb_request *req) | |||
332 | list_add_tail(©_buf->list, &audio->play_queue); | 335 | list_add_tail(©_buf->list, &audio->play_queue); |
333 | schedule_work(&audio->playback_work); | 336 | schedule_work(&audio->playback_work); |
334 | copy_buf = f_audio_buffer_alloc(audio_buf_size); | 337 | copy_buf = f_audio_buffer_alloc(audio_buf_size); |
335 | if (copy_buf < 0) | 338 | if (IS_ERR(copy_buf)) |
336 | return -ENOMEM; | 339 | return -ENOMEM; |
337 | } | 340 | } |
338 | 341 | ||
@@ -576,6 +579,8 @@ static int f_audio_set_alt(struct usb_function *f, unsigned intf, unsigned alt) | |||
576 | usb_ep_enable(out_ep, audio->out_desc); | 579 | usb_ep_enable(out_ep, audio->out_desc); |
577 | out_ep->driver_data = audio; | 580 | out_ep->driver_data = audio; |
578 | audio->copy_buf = f_audio_buffer_alloc(audio_buf_size); | 581 | audio->copy_buf = f_audio_buffer_alloc(audio_buf_size); |
582 | if (IS_ERR(audio->copy_buf)) | ||
583 | return -ENOMEM; | ||
579 | 584 | ||
580 | /* | 585 | /* |
581 | * allocate a bunch of read buffers | 586 | * allocate a bunch of read buffers |
@@ -787,7 +792,7 @@ int __init audio_bind_config(struct usb_configuration *c) | |||
787 | return status; | 792 | return status; |
788 | 793 | ||
789 | add_fail: | 794 | add_fail: |
790 | gaudio_cleanup(&audio->card); | 795 | gaudio_cleanup(); |
791 | setup_fail: | 796 | setup_fail: |
792 | kfree(audio); | 797 | kfree(audio); |
793 | return status; | 798 | return status; |
diff --git a/drivers/usb/gadget/u_audio.c b/drivers/usb/gadget/u_audio.c index 8252595d619d..35e0930f5bbb 100644 --- a/drivers/usb/gadget/u_audio.c +++ b/drivers/usb/gadget/u_audio.c | |||
@@ -288,6 +288,7 @@ static int gaudio_close_snd_dev(struct gaudio *gau) | |||
288 | return 0; | 288 | return 0; |
289 | } | 289 | } |
290 | 290 | ||
291 | static struct gaudio *the_card; | ||
291 | /** | 292 | /** |
292 | * gaudio_setup - setup ALSA interface and preparing for USB transfer | 293 | * gaudio_setup - setup ALSA interface and preparing for USB transfer |
293 | * | 294 | * |
@@ -303,6 +304,9 @@ int __init gaudio_setup(struct gaudio *card) | |||
303 | if (ret) | 304 | if (ret) |
304 | ERROR(card, "we need at least one control device\n"); | 305 | ERROR(card, "we need at least one control device\n"); |
305 | 306 | ||
307 | if (!the_card) | ||
308 | the_card = card; | ||
309 | |||
306 | return ret; | 310 | return ret; |
307 | 311 | ||
308 | } | 312 | } |
@@ -312,9 +316,11 @@ int __init gaudio_setup(struct gaudio *card) | |||
312 | * | 316 | * |
313 | * This is called to free all resources allocated by @gaudio_setup(). | 317 | * This is called to free all resources allocated by @gaudio_setup(). |
314 | */ | 318 | */ |
315 | void gaudio_cleanup(struct gaudio *card) | 319 | void gaudio_cleanup(void) |
316 | { | 320 | { |
317 | if (card) | 321 | if (the_card) { |
318 | gaudio_close_snd_dev(card); | 322 | gaudio_close_snd_dev(the_card); |
323 | the_card = NULL; | ||
324 | } | ||
319 | } | 325 | } |
320 | 326 | ||
diff --git a/drivers/usb/gadget/u_audio.h b/drivers/usb/gadget/u_audio.h index cc8d159c648a..08ffce3298e6 100644 --- a/drivers/usb/gadget/u_audio.h +++ b/drivers/usb/gadget/u_audio.h | |||
@@ -51,6 +51,6 @@ struct gaudio { | |||
51 | }; | 51 | }; |
52 | 52 | ||
53 | int gaudio_setup(struct gaudio *card); | 53 | int gaudio_setup(struct gaudio *card); |
54 | void gaudio_cleanup(struct gaudio *card); | 54 | void gaudio_cleanup(void); |
55 | 55 | ||
56 | #endif /* __U_AUDIO_H */ | 56 | #endif /* __U_AUDIO_H */ |
diff --git a/drivers/usb/host/fhci-sched.c b/drivers/usb/host/fhci-sched.c index 00a29855d0c4..ff43747a614f 100644 --- a/drivers/usb/host/fhci-sched.c +++ b/drivers/usb/host/fhci-sched.c | |||
@@ -37,7 +37,7 @@ static void recycle_frame(struct fhci_usb *usb, struct packet *pkt) | |||
37 | pkt->info = 0; | 37 | pkt->info = 0; |
38 | pkt->priv_data = NULL; | 38 | pkt->priv_data = NULL; |
39 | 39 | ||
40 | cq_put(usb->ep0->empty_frame_Q, pkt); | 40 | cq_put(&usb->ep0->empty_frame_Q, pkt); |
41 | } | 41 | } |
42 | 42 | ||
43 | /* confirm submitted packet */ | 43 | /* confirm submitted packet */ |
@@ -57,7 +57,7 @@ void fhci_transaction_confirm(struct fhci_usb *usb, struct packet *pkt) | |||
57 | if ((td->data + td->actual_len) && trans_len) | 57 | if ((td->data + td->actual_len) && trans_len) |
58 | memcpy(td->data + td->actual_len, pkt->data, | 58 | memcpy(td->data + td->actual_len, pkt->data, |
59 | trans_len); | 59 | trans_len); |
60 | cq_put(usb->ep0->dummy_packets_Q, pkt->data); | 60 | cq_put(&usb->ep0->dummy_packets_Q, pkt->data); |
61 | } | 61 | } |
62 | 62 | ||
63 | recycle_frame(usb, pkt); | 63 | recycle_frame(usb, pkt); |
@@ -213,7 +213,7 @@ static int add_packet(struct fhci_usb *usb, struct ed *ed, struct td *td) | |||
213 | } | 213 | } |
214 | 214 | ||
215 | /* update frame object fields before transmitting */ | 215 | /* update frame object fields before transmitting */ |
216 | pkt = cq_get(usb->ep0->empty_frame_Q); | 216 | pkt = cq_get(&usb->ep0->empty_frame_Q); |
217 | if (!pkt) { | 217 | if (!pkt) { |
218 | fhci_dbg(usb->fhci, "there is no empty frame\n"); | 218 | fhci_dbg(usb->fhci, "there is no empty frame\n"); |
219 | return -1; | 219 | return -1; |
@@ -222,7 +222,7 @@ static int add_packet(struct fhci_usb *usb, struct ed *ed, struct td *td) | |||
222 | 222 | ||
223 | pkt->info = 0; | 223 | pkt->info = 0; |
224 | if (data == NULL) { | 224 | if (data == NULL) { |
225 | data = cq_get(usb->ep0->dummy_packets_Q); | 225 | data = cq_get(&usb->ep0->dummy_packets_Q); |
226 | BUG_ON(!data); | 226 | BUG_ON(!data); |
227 | pkt->info = PKT_DUMMY_PACKET; | 227 | pkt->info = PKT_DUMMY_PACKET; |
228 | } | 228 | } |
@@ -246,7 +246,7 @@ static int add_packet(struct fhci_usb *usb, struct ed *ed, struct td *td) | |||
246 | list_del_init(&td->frame_lh); | 246 | list_del_init(&td->frame_lh); |
247 | td->status = USB_TD_OK; | 247 | td->status = USB_TD_OK; |
248 | if (pkt->info & PKT_DUMMY_PACKET) | 248 | if (pkt->info & PKT_DUMMY_PACKET) |
249 | cq_put(usb->ep0->dummy_packets_Q, pkt->data); | 249 | cq_put(&usb->ep0->dummy_packets_Q, pkt->data); |
250 | recycle_frame(usb, pkt); | 250 | recycle_frame(usb, pkt); |
251 | usb->actual_frame->total_bytes -= (len + PROTOCOL_OVERHEAD); | 251 | usb->actual_frame->total_bytes -= (len + PROTOCOL_OVERHEAD); |
252 | fhci_err(usb->fhci, "host transaction failed\n"); | 252 | fhci_err(usb->fhci, "host transaction failed\n"); |
diff --git a/drivers/usb/host/fhci-tds.c b/drivers/usb/host/fhci-tds.c index b40332290319..d224ab467a40 100644 --- a/drivers/usb/host/fhci-tds.c +++ b/drivers/usb/host/fhci-tds.c | |||
@@ -106,33 +106,33 @@ void fhci_ep0_free(struct fhci_usb *usb) | |||
106 | cpm_muram_free(cpm_muram_offset(ep->td_base)); | 106 | cpm_muram_free(cpm_muram_offset(ep->td_base)); |
107 | 107 | ||
108 | if (ep->conf_frame_Q) { | 108 | if (ep->conf_frame_Q) { |
109 | size = cq_howmany(ep->conf_frame_Q); | 109 | size = cq_howmany(&ep->conf_frame_Q); |
110 | for (; size; size--) { | 110 | for (; size; size--) { |
111 | struct packet *pkt = cq_get(ep->conf_frame_Q); | 111 | struct packet *pkt = cq_get(&ep->conf_frame_Q); |
112 | 112 | ||
113 | kfree(pkt); | 113 | kfree(pkt); |
114 | } | 114 | } |
115 | cq_delete(ep->conf_frame_Q); | 115 | cq_delete(&ep->conf_frame_Q); |
116 | } | 116 | } |
117 | 117 | ||
118 | if (ep->empty_frame_Q) { | 118 | if (ep->empty_frame_Q) { |
119 | size = cq_howmany(ep->empty_frame_Q); | 119 | size = cq_howmany(&ep->empty_frame_Q); |
120 | for (; size; size--) { | 120 | for (; size; size--) { |
121 | struct packet *pkt = cq_get(ep->empty_frame_Q); | 121 | struct packet *pkt = cq_get(&ep->empty_frame_Q); |
122 | 122 | ||
123 | kfree(pkt); | 123 | kfree(pkt); |
124 | } | 124 | } |
125 | cq_delete(ep->empty_frame_Q); | 125 | cq_delete(&ep->empty_frame_Q); |
126 | } | 126 | } |
127 | 127 | ||
128 | if (ep->dummy_packets_Q) { | 128 | if (ep->dummy_packets_Q) { |
129 | size = cq_howmany(ep->dummy_packets_Q); | 129 | size = cq_howmany(&ep->dummy_packets_Q); |
130 | for (; size; size--) { | 130 | for (; size; size--) { |
131 | u8 *buff = cq_get(ep->dummy_packets_Q); | 131 | u8 *buff = cq_get(&ep->dummy_packets_Q); |
132 | 132 | ||
133 | kfree(buff); | 133 | kfree(buff); |
134 | } | 134 | } |
135 | cq_delete(ep->dummy_packets_Q); | 135 | cq_delete(&ep->dummy_packets_Q); |
136 | } | 136 | } |
137 | 137 | ||
138 | kfree(ep); | 138 | kfree(ep); |
@@ -175,10 +175,9 @@ u32 fhci_create_ep(struct fhci_usb *usb, enum fhci_mem_alloc data_mem, | |||
175 | ep->td_base = cpm_muram_addr(ep_offset); | 175 | ep->td_base = cpm_muram_addr(ep_offset); |
176 | 176 | ||
177 | /* zero all queue pointers */ | 177 | /* zero all queue pointers */ |
178 | ep->conf_frame_Q = cq_new(ring_len + 2); | 178 | if (cq_new(&ep->conf_frame_Q, ring_len + 2) || |
179 | ep->empty_frame_Q = cq_new(ring_len + 2); | 179 | cq_new(&ep->empty_frame_Q, ring_len + 2) || |
180 | ep->dummy_packets_Q = cq_new(ring_len + 2); | 180 | cq_new(&ep->dummy_packets_Q, ring_len + 2)) { |
181 | if (!ep->conf_frame_Q || !ep->empty_frame_Q || !ep->dummy_packets_Q) { | ||
182 | err_for = "frame_queues"; | 181 | err_for = "frame_queues"; |
183 | goto err; | 182 | goto err; |
184 | } | 183 | } |
@@ -199,8 +198,8 @@ u32 fhci_create_ep(struct fhci_usb *usb, enum fhci_mem_alloc data_mem, | |||
199 | err_for = "buffer"; | 198 | err_for = "buffer"; |
200 | goto err; | 199 | goto err; |
201 | } | 200 | } |
202 | cq_put(ep->empty_frame_Q, pkt); | 201 | cq_put(&ep->empty_frame_Q, pkt); |
203 | cq_put(ep->dummy_packets_Q, buff); | 202 | cq_put(&ep->dummy_packets_Q, buff); |
204 | } | 203 | } |
205 | 204 | ||
206 | /* we put the endpoint parameter RAM right behind the TD ring */ | 205 | /* we put the endpoint parameter RAM right behind the TD ring */ |
@@ -319,7 +318,7 @@ static void fhci_td_transaction_confirm(struct fhci_usb *usb) | |||
319 | if ((buf == DUMMY2_BD_BUFFER) && !(td_status & ~TD_W)) | 318 | if ((buf == DUMMY2_BD_BUFFER) && !(td_status & ~TD_W)) |
320 | continue; | 319 | continue; |
321 | 320 | ||
322 | pkt = cq_get(ep->conf_frame_Q); | 321 | pkt = cq_get(&ep->conf_frame_Q); |
323 | if (!pkt) | 322 | if (!pkt) |
324 | fhci_err(usb->fhci, "no frame to confirm\n"); | 323 | fhci_err(usb->fhci, "no frame to confirm\n"); |
325 | 324 | ||
@@ -460,9 +459,9 @@ u32 fhci_host_transaction(struct fhci_usb *usb, | |||
460 | out_be16(&td->length, pkt->len); | 459 | out_be16(&td->length, pkt->len); |
461 | 460 | ||
462 | /* put the frame to the confirmation queue */ | 461 | /* put the frame to the confirmation queue */ |
463 | cq_put(ep->conf_frame_Q, pkt); | 462 | cq_put(&ep->conf_frame_Q, pkt); |
464 | 463 | ||
465 | if (cq_howmany(ep->conf_frame_Q) == 1) | 464 | if (cq_howmany(&ep->conf_frame_Q) == 1) |
466 | out_8(&usb->fhci->regs->usb_comm, USB_CMD_STR_FIFO); | 465 | out_8(&usb->fhci->regs->usb_comm, USB_CMD_STR_FIFO); |
467 | 466 | ||
468 | return 0; | 467 | return 0; |
diff --git a/drivers/usb/host/fhci.h b/drivers/usb/host/fhci.h index 7116284ed21a..72dae1c5ab38 100644 --- a/drivers/usb/host/fhci.h +++ b/drivers/usb/host/fhci.h | |||
@@ -423,9 +423,9 @@ struct endpoint { | |||
423 | struct usb_td __iomem *td_base; /* first TD in the ring */ | 423 | struct usb_td __iomem *td_base; /* first TD in the ring */ |
424 | struct usb_td __iomem *conf_td; /* next TD for confirm after transac */ | 424 | struct usb_td __iomem *conf_td; /* next TD for confirm after transac */ |
425 | struct usb_td __iomem *empty_td;/* next TD for new transaction req. */ | 425 | struct usb_td __iomem *empty_td;/* next TD for new transaction req. */ |
426 | struct kfifo *empty_frame_Q; /* Empty frames list to use */ | 426 | struct kfifo empty_frame_Q; /* Empty frames list to use */ |
427 | struct kfifo *conf_frame_Q; /* frames passed to TDs,waiting for tx */ | 427 | struct kfifo conf_frame_Q; /* frames passed to TDs,waiting for tx */ |
428 | struct kfifo *dummy_packets_Q;/* dummy packets for the CRC overun */ | 428 | struct kfifo dummy_packets_Q;/* dummy packets for the CRC overun */ |
429 | 429 | ||
430 | bool already_pushed_dummy_bd; | 430 | bool already_pushed_dummy_bd; |
431 | }; | 431 | }; |
@@ -493,9 +493,9 @@ static inline struct usb_hcd *fhci_to_hcd(struct fhci_hcd *fhci) | |||
493 | } | 493 | } |
494 | 494 | ||
495 | /* fifo of pointers */ | 495 | /* fifo of pointers */ |
496 | static inline struct kfifo *cq_new(int size) | 496 | static inline int cq_new(struct kfifo *fifo, int size) |
497 | { | 497 | { |
498 | return kfifo_alloc(size * sizeof(void *), GFP_KERNEL, NULL); | 498 | return kfifo_alloc(fifo, size * sizeof(void *), GFP_KERNEL); |
499 | } | 499 | } |
500 | 500 | ||
501 | static inline void cq_delete(struct kfifo *kfifo) | 501 | static inline void cq_delete(struct kfifo *kfifo) |
@@ -505,19 +505,19 @@ static inline void cq_delete(struct kfifo *kfifo) | |||
505 | 505 | ||
506 | static inline unsigned int cq_howmany(struct kfifo *kfifo) | 506 | static inline unsigned int cq_howmany(struct kfifo *kfifo) |
507 | { | 507 | { |
508 | return __kfifo_len(kfifo) / sizeof(void *); | 508 | return kfifo_len(kfifo) / sizeof(void *); |
509 | } | 509 | } |
510 | 510 | ||
511 | static inline int cq_put(struct kfifo *kfifo, void *p) | 511 | static inline int cq_put(struct kfifo *kfifo, void *p) |
512 | { | 512 | { |
513 | return __kfifo_put(kfifo, (void *)&p, sizeof(p)); | 513 | return kfifo_in(kfifo, (void *)&p, sizeof(p)); |
514 | } | 514 | } |
515 | 515 | ||
516 | static inline void *cq_get(struct kfifo *kfifo) | 516 | static inline void *cq_get(struct kfifo *kfifo) |
517 | { | 517 | { |
518 | void *p = NULL; | 518 | void *p = NULL; |
519 | 519 | ||
520 | __kfifo_get(kfifo, (void *)&p, sizeof(p)); | 520 | kfifo_out(kfifo, (void *)&p, sizeof(p)); |
521 | return p; | 521 | return p; |
522 | } | 522 | } |
523 | 523 | ||
diff --git a/drivers/usb/misc/appledisplay.c b/drivers/usb/misc/appledisplay.c index 1d8e39a557d9..1eb9e4162cc6 100644 --- a/drivers/usb/misc/appledisplay.c +++ b/drivers/usb/misc/appledisplay.c | |||
@@ -60,6 +60,7 @@ | |||
60 | static struct usb_device_id appledisplay_table [] = { | 60 | static struct usb_device_id appledisplay_table [] = { |
61 | { APPLEDISPLAY_DEVICE(0x9218) }, | 61 | { APPLEDISPLAY_DEVICE(0x9218) }, |
62 | { APPLEDISPLAY_DEVICE(0x9219) }, | 62 | { APPLEDISPLAY_DEVICE(0x9219) }, |
63 | { APPLEDISPLAY_DEVICE(0x921c) }, | ||
63 | { APPLEDISPLAY_DEVICE(0x921d) }, | 64 | { APPLEDISPLAY_DEVICE(0x921d) }, |
64 | 65 | ||
65 | /* Terminating entry */ | 66 | /* Terminating entry */ |
@@ -72,8 +73,8 @@ struct appledisplay { | |||
72 | struct usb_device *udev; /* usb device */ | 73 | struct usb_device *udev; /* usb device */ |
73 | struct urb *urb; /* usb request block */ | 74 | struct urb *urb; /* usb request block */ |
74 | struct backlight_device *bd; /* backlight device */ | 75 | struct backlight_device *bd; /* backlight device */ |
75 | char *urbdata; /* interrupt URB data buffer */ | 76 | u8 *urbdata; /* interrupt URB data buffer */ |
76 | char *msgdata; /* control message data buffer */ | 77 | u8 *msgdata; /* control message data buffer */ |
77 | 78 | ||
78 | struct delayed_work work; | 79 | struct delayed_work work; |
79 | int button_pressed; | 80 | int button_pressed; |
diff --git a/drivers/usb/misc/emi62.c b/drivers/usb/misc/emi62.c index 602ee05ba9ff..59860b328534 100644 --- a/drivers/usb/misc/emi62.c +++ b/drivers/usb/misc/emi62.c | |||
@@ -167,7 +167,7 @@ static int emi62_load_firmware (struct usb_device *dev) | |||
167 | err("%s - error loading firmware: error = %d", __func__, err); | 167 | err("%s - error loading firmware: error = %d", __func__, err); |
168 | goto wraperr; | 168 | goto wraperr; |
169 | } | 169 | } |
170 | } while (i > 0); | 170 | } while (rec); |
171 | 171 | ||
172 | /* Assert reset (stop the CPU in the EMI) */ | 172 | /* Assert reset (stop the CPU in the EMI) */ |
173 | err = emi62_set_reset(dev,1); | 173 | err = emi62_set_reset(dev,1); |
diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c index fe4934d9602c..ad26e6569665 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c | |||
@@ -29,6 +29,8 @@ void musb_write_fifo(struct musb_hw_ep *hw_ep, u16 len, const u8 *src) | |||
29 | { | 29 | { |
30 | void __iomem *fifo = hw_ep->fifo; | 30 | void __iomem *fifo = hw_ep->fifo; |
31 | void __iomem *epio = hw_ep->regs; | 31 | void __iomem *epio = hw_ep->regs; |
32 | u8 epnum = hw_ep->epnum; | ||
33 | u16 dma_reg = 0; | ||
32 | 34 | ||
33 | prefetch((u8 *)src); | 35 | prefetch((u8 *)src); |
34 | 36 | ||
@@ -39,67 +41,113 @@ void musb_write_fifo(struct musb_hw_ep *hw_ep, u16 len, const u8 *src) | |||
39 | 41 | ||
40 | dump_fifo_data(src, len); | 42 | dump_fifo_data(src, len); |
41 | 43 | ||
42 | if (unlikely((unsigned long)src & 0x01)) | 44 | if (!ANOMALY_05000380 && epnum != 0) { |
43 | outsw_8((unsigned long)fifo, src, | 45 | flush_dcache_range((unsigned int)src, |
44 | len & 0x01 ? (len >> 1) + 1 : len >> 1); | 46 | (unsigned int)(src + len)); |
45 | else | 47 | |
46 | outsw((unsigned long)fifo, src, | 48 | /* Setup DMA address register */ |
47 | len & 0x01 ? (len >> 1) + 1 : len >> 1); | 49 | dma_reg = (u16) ((u32) src & 0xFFFF); |
48 | } | 50 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_LOW), dma_reg); |
51 | SSYNC(); | ||
52 | |||
53 | dma_reg = (u16) (((u32) src >> 16) & 0xFFFF); | ||
54 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_HIGH), dma_reg); | ||
55 | SSYNC(); | ||
56 | |||
57 | /* Setup DMA count register */ | ||
58 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_COUNT_LOW), len); | ||
59 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_COUNT_HIGH), 0); | ||
60 | SSYNC(); | ||
61 | |||
62 | /* Enable the DMA */ | ||
63 | dma_reg = (epnum << 4) | DMA_ENA | INT_ENA | DIRECTION; | ||
64 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_CTRL), dma_reg); | ||
65 | SSYNC(); | ||
66 | |||
67 | /* Wait for compelete */ | ||
68 | while (!(bfin_read_USB_DMA_INTERRUPT() & (1 << epnum))) | ||
69 | cpu_relax(); | ||
70 | |||
71 | /* acknowledge dma interrupt */ | ||
72 | bfin_write_USB_DMA_INTERRUPT(1 << epnum); | ||
73 | SSYNC(); | ||
74 | |||
75 | /* Reset DMA */ | ||
76 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_CTRL), 0); | ||
77 | SSYNC(); | ||
78 | } else { | ||
79 | SSYNC(); | ||
80 | |||
81 | if (unlikely((unsigned long)src & 0x01)) | ||
82 | outsw_8((unsigned long)fifo, src, | ||
83 | len & 0x01 ? (len >> 1) + 1 : len >> 1); | ||
84 | else | ||
85 | outsw((unsigned long)fifo, src, | ||
86 | len & 0x01 ? (len >> 1) + 1 : len >> 1); | ||
49 | 87 | ||
88 | } | ||
89 | } | ||
50 | /* | 90 | /* |
51 | * Unload an endpoint's FIFO | 91 | * Unload an endpoint's FIFO |
52 | */ | 92 | */ |
53 | void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst) | 93 | void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst) |
54 | { | 94 | { |
55 | void __iomem *fifo = hw_ep->fifo; | 95 | void __iomem *fifo = hw_ep->fifo; |
56 | |||
57 | #ifdef CONFIG_BF52x | ||
58 | u8 epnum = hw_ep->epnum; | 96 | u8 epnum = hw_ep->epnum; |
59 | u16 dma_reg = 0; | 97 | u16 dma_reg = 0; |
60 | 98 | ||
61 | invalidate_dcache_range((unsigned int)dst, | 99 | if (ANOMALY_05000467 && epnum != 0) { |
62 | (unsigned int)(dst + len)); | ||
63 | 100 | ||
64 | /* Setup DMA address register */ | 101 | invalidate_dcache_range((unsigned int)dst, |
65 | dma_reg = (u16) ((u32) dst & 0xFFFF); | 102 | (unsigned int)(dst + len)); |
66 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_LOW), dma_reg); | ||
67 | SSYNC(); | ||
68 | 103 | ||
69 | dma_reg = (u16) (((u32) dst >> 16) & 0xFFFF); | 104 | /* Setup DMA address register */ |
70 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_HIGH), dma_reg); | 105 | dma_reg = (u16) ((u32) dst & 0xFFFF); |
71 | SSYNC(); | 106 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_LOW), dma_reg); |
107 | SSYNC(); | ||
72 | 108 | ||
73 | /* Setup DMA count register */ | 109 | dma_reg = (u16) (((u32) dst >> 16) & 0xFFFF); |
74 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_COUNT_LOW), len); | 110 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_HIGH), dma_reg); |
75 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_COUNT_HIGH), 0); | 111 | SSYNC(); |
76 | SSYNC(); | ||
77 | 112 | ||
78 | /* Enable the DMA */ | 113 | /* Setup DMA count register */ |
79 | dma_reg = (epnum << 4) | DMA_ENA | INT_ENA; | 114 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_COUNT_LOW), len); |
80 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_CTRL), dma_reg); | 115 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_COUNT_HIGH), 0); |
81 | SSYNC(); | 116 | SSYNC(); |
82 | 117 | ||
83 | /* Wait for compelete */ | 118 | /* Enable the DMA */ |
84 | while (!(bfin_read_USB_DMA_INTERRUPT() & (1 << epnum))) | 119 | dma_reg = (epnum << 4) | DMA_ENA | INT_ENA; |
85 | cpu_relax(); | 120 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_CTRL), dma_reg); |
121 | SSYNC(); | ||
86 | 122 | ||
87 | /* acknowledge dma interrupt */ | 123 | /* Wait for compelete */ |
88 | bfin_write_USB_DMA_INTERRUPT(1 << epnum); | 124 | while (!(bfin_read_USB_DMA_INTERRUPT() & (1 << epnum))) |
89 | SSYNC(); | 125 | cpu_relax(); |
90 | 126 | ||
91 | /* Reset DMA */ | 127 | /* acknowledge dma interrupt */ |
92 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_CTRL), 0); | 128 | bfin_write_USB_DMA_INTERRUPT(1 << epnum); |
93 | SSYNC(); | 129 | SSYNC(); |
94 | #else | ||
95 | if (unlikely((unsigned long)dst & 0x01)) | ||
96 | insw_8((unsigned long)fifo, dst, | ||
97 | len & 0x01 ? (len >> 1) + 1 : len >> 1); | ||
98 | else | ||
99 | insw((unsigned long)fifo, dst, | ||
100 | len & 0x01 ? (len >> 1) + 1 : len >> 1); | ||
101 | #endif | ||
102 | 130 | ||
131 | /* Reset DMA */ | ||
132 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_CTRL), 0); | ||
133 | SSYNC(); | ||
134 | } else { | ||
135 | SSYNC(); | ||
136 | /* Read the last byte of packet with odd size from address fifo + 4 | ||
137 | * to trigger 1 byte access to EP0 FIFO. | ||
138 | */ | ||
139 | if (len == 1) | ||
140 | *dst = (u8)inw((unsigned long)fifo + 4); | ||
141 | else { | ||
142 | if (unlikely((unsigned long)dst & 0x01)) | ||
143 | insw_8((unsigned long)fifo, dst, len >> 1); | ||
144 | else | ||
145 | insw((unsigned long)fifo, dst, len >> 1); | ||
146 | |||
147 | if (len & 0x01) | ||
148 | *(dst + len - 1) = (u8)inw((unsigned long)fifo + 4); | ||
149 | } | ||
150 | } | ||
103 | DBG(4, "%cX ep%d fifo %p count %d buf %p\n", | 151 | DBG(4, "%cX ep%d fifo %p count %d buf %p\n", |
104 | 'R', hw_ep->epnum, fifo, len, dst); | 152 | 'R', hw_ep->epnum, fifo, len, dst); |
105 | 153 | ||
diff --git a/drivers/usb/musb/blackfin.h b/drivers/usb/musb/blackfin.h index 10b7d7584f4b..bd9352a2ef2a 100644 --- a/drivers/usb/musb/blackfin.h +++ b/drivers/usb/musb/blackfin.h | |||
@@ -69,7 +69,6 @@ static void dump_fifo_data(u8 *buf, u16 len) | |||
69 | #define dump_fifo_data(buf, len) do {} while (0) | 69 | #define dump_fifo_data(buf, len) do {} while (0) |
70 | #endif | 70 | #endif |
71 | 71 | ||
72 | #ifdef CONFIG_BF52x | ||
73 | 72 | ||
74 | #define USB_DMA_BASE USB_DMA_INTERRUPT | 73 | #define USB_DMA_BASE USB_DMA_INTERRUPT |
75 | #define USB_DMAx_CTRL 0x04 | 74 | #define USB_DMAx_CTRL 0x04 |
@@ -79,7 +78,6 @@ static void dump_fifo_data(u8 *buf, u16 len) | |||
79 | #define USB_DMAx_COUNT_HIGH 0x14 | 78 | #define USB_DMAx_COUNT_HIGH 0x14 |
80 | 79 | ||
81 | #define USB_DMA_REG(ep, reg) (USB_DMA_BASE + 0x20 * ep + reg) | 80 | #define USB_DMA_REG(ep, reg) (USB_DMA_BASE + 0x20 * ep + reg) |
82 | #endif | ||
83 | 81 | ||
84 | /* Almost 1 second */ | 82 | /* Almost 1 second */ |
85 | #define TIMER_DELAY (1 * HZ) | 83 | #define TIMER_DELAY (1 * HZ) |
diff --git a/drivers/usb/musb/cppi_dma.c b/drivers/usb/musb/cppi_dma.c index ef2332a9941d..a44a450c860d 100644 --- a/drivers/usb/musb/cppi_dma.c +++ b/drivers/usb/musb/cppi_dma.c | |||
@@ -1154,8 +1154,11 @@ irqreturn_t cppi_interrupt(int irq, void *dev_id) | |||
1154 | struct musb_hw_ep *hw_ep = NULL; | 1154 | struct musb_hw_ep *hw_ep = NULL; |
1155 | u32 rx, tx; | 1155 | u32 rx, tx; |
1156 | int i, index; | 1156 | int i, index; |
1157 | unsigned long flags; | ||
1157 | 1158 | ||
1158 | cppi = container_of(musb->dma_controller, struct cppi, controller); | 1159 | cppi = container_of(musb->dma_controller, struct cppi, controller); |
1160 | if (cppi->irq) | ||
1161 | spin_lock_irqsave(&musb->lock, flags); | ||
1159 | 1162 | ||
1160 | tibase = musb->ctrl_base; | 1163 | tibase = musb->ctrl_base; |
1161 | 1164 | ||
@@ -1285,6 +1288,9 @@ irqreturn_t cppi_interrupt(int irq, void *dev_id) | |||
1285 | /* write to CPPI EOI register to re-enable interrupts */ | 1288 | /* write to CPPI EOI register to re-enable interrupts */ |
1286 | musb_writel(tibase, DAVINCI_CPPI_EOI_REG, 0); | 1289 | musb_writel(tibase, DAVINCI_CPPI_EOI_REG, 0); |
1287 | 1290 | ||
1291 | if (cppi->irq) | ||
1292 | spin_unlock_irqrestore(&musb->lock, flags); | ||
1293 | |||
1288 | return IRQ_HANDLED; | 1294 | return IRQ_HANDLED; |
1289 | } | 1295 | } |
1290 | 1296 | ||
diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index e16ff605c458..66913811af5e 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c | |||
@@ -42,7 +42,7 @@ | |||
42 | #include "musb_core.h" | 42 | #include "musb_core.h" |
43 | 43 | ||
44 | #ifdef CONFIG_MACH_DAVINCI_EVM | 44 | #ifdef CONFIG_MACH_DAVINCI_EVM |
45 | #define GPIO_nVBUS_DRV 144 | 45 | #define GPIO_nVBUS_DRV 160 |
46 | #endif | 46 | #endif |
47 | 47 | ||
48 | #include "davinci.h" | 48 | #include "davinci.h" |
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index bfe08f4975a3..5eb9318cff77 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c | |||
@@ -1319,7 +1319,7 @@ static int __init musb_core_init(u16 musb_type, struct musb *musb) | |||
1319 | #endif | 1319 | #endif |
1320 | u8 reg; | 1320 | u8 reg; |
1321 | char *type; | 1321 | char *type; |
1322 | char aInfo[78], aRevision[32], aDate[12]; | 1322 | char aInfo[90], aRevision[32], aDate[12]; |
1323 | void __iomem *mbase = musb->mregs; | 1323 | void __iomem *mbase = musb->mregs; |
1324 | int status = 0; | 1324 | int status = 0; |
1325 | int i; | 1325 | int i; |
@@ -1521,6 +1521,14 @@ irqreturn_t musb_interrupt(struct musb *musb) | |||
1521 | (devctl & MUSB_DEVCTL_HM) ? "host" : "peripheral", | 1521 | (devctl & MUSB_DEVCTL_HM) ? "host" : "peripheral", |
1522 | musb->int_usb, musb->int_tx, musb->int_rx); | 1522 | musb->int_usb, musb->int_tx, musb->int_rx); |
1523 | 1523 | ||
1524 | #ifdef CONFIG_USB_GADGET_MUSB_HDRC | ||
1525 | if (is_otg_enabled(musb) || is_peripheral_enabled(musb)) | ||
1526 | if (!musb->gadget_driver) { | ||
1527 | DBG(5, "No gadget driver loaded\n"); | ||
1528 | return IRQ_HANDLED; | ||
1529 | } | ||
1530 | #endif | ||
1531 | |||
1524 | /* the core can interrupt us for multiple reasons; docs have | 1532 | /* the core can interrupt us for multiple reasons; docs have |
1525 | * a generic interrupt flowchart to follow | 1533 | * a generic interrupt flowchart to follow |
1526 | */ | 1534 | */ |
@@ -2139,7 +2147,7 @@ static int __init musb_probe(struct platform_device *pdev) | |||
2139 | return musb_init_controller(dev, irq, base); | 2147 | return musb_init_controller(dev, irq, base); |
2140 | } | 2148 | } |
2141 | 2149 | ||
2142 | static int __devexit musb_remove(struct platform_device *pdev) | 2150 | static int __exit musb_remove(struct platform_device *pdev) |
2143 | { | 2151 | { |
2144 | struct musb *musb = dev_to_musb(&pdev->dev); | 2152 | struct musb *musb = dev_to_musb(&pdev->dev); |
2145 | void __iomem *ctrl_base = musb->ctrl_base; | 2153 | void __iomem *ctrl_base = musb->ctrl_base; |
@@ -2231,7 +2239,7 @@ static struct platform_driver musb_driver = { | |||
2231 | .owner = THIS_MODULE, | 2239 | .owner = THIS_MODULE, |
2232 | .pm = MUSB_DEV_PM_OPS, | 2240 | .pm = MUSB_DEV_PM_OPS, |
2233 | }, | 2241 | }, |
2234 | .remove = __devexit_p(musb_remove), | 2242 | .remove = __exit_p(musb_remove), |
2235 | .shutdown = musb_shutdown, | 2243 | .shutdown = musb_shutdown, |
2236 | }; | 2244 | }; |
2237 | 2245 | ||
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index c49b9ba025ab..cbcf14a236e6 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c | |||
@@ -309,7 +309,7 @@ static void txstate(struct musb *musb, struct musb_request *req) | |||
309 | size_t request_size; | 309 | size_t request_size; |
310 | 310 | ||
311 | /* setup DMA, then program endpoint CSR */ | 311 | /* setup DMA, then program endpoint CSR */ |
312 | request_size = min(request->length, | 312 | request_size = min_t(size_t, request->length, |
313 | musb_ep->dma->max_len); | 313 | musb_ep->dma->max_len); |
314 | if (request_size < musb_ep->packet_sz) | 314 | if (request_size < musb_ep->packet_sz) |
315 | musb_ep->dma->desired_mode = 0; | 315 | musb_ep->dma->desired_mode = 0; |
@@ -319,7 +319,7 @@ static void txstate(struct musb *musb, struct musb_request *req) | |||
319 | use_dma = use_dma && c->channel_program( | 319 | use_dma = use_dma && c->channel_program( |
320 | musb_ep->dma, musb_ep->packet_sz, | 320 | musb_ep->dma, musb_ep->packet_sz, |
321 | musb_ep->dma->desired_mode, | 321 | musb_ep->dma->desired_mode, |
322 | request->dma, request_size); | 322 | request->dma + request->actual, request_size); |
323 | if (use_dma) { | 323 | if (use_dma) { |
324 | if (musb_ep->dma->desired_mode == 0) { | 324 | if (musb_ep->dma->desired_mode == 0) { |
325 | /* | 325 | /* |
@@ -515,12 +515,12 @@ void musb_g_tx(struct musb *musb, u8 epnum) | |||
515 | if (csr & MUSB_TXCSR_FIFONOTEMPTY) | 515 | if (csr & MUSB_TXCSR_FIFONOTEMPTY) |
516 | return; | 516 | return; |
517 | 517 | ||
518 | if (!musb_ep->desc) { | 518 | request = musb_ep->desc ? next_request(musb_ep) : NULL; |
519 | if (!request) { | ||
519 | DBG(4, "%s idle now\n", | 520 | DBG(4, "%s idle now\n", |
520 | musb_ep->end_point.name); | 521 | musb_ep->end_point.name); |
521 | return; | 522 | return; |
522 | } else | 523 | } |
523 | request = next_request(musb_ep); | ||
524 | } | 524 | } |
525 | 525 | ||
526 | txstate(musb, to_musb_request(request)); | 526 | txstate(musb, to_musb_request(request)); |
@@ -746,6 +746,8 @@ void musb_g_rx(struct musb *musb, u8 epnum) | |||
746 | musb_ep_select(mbase, epnum); | 746 | musb_ep_select(mbase, epnum); |
747 | 747 | ||
748 | request = next_request(musb_ep); | 748 | request = next_request(musb_ep); |
749 | if (!request) | ||
750 | return; | ||
749 | 751 | ||
750 | csr = musb_readw(epio, MUSB_RXCSR); | 752 | csr = musb_readw(epio, MUSB_RXCSR); |
751 | dma = is_dma_capable() ? musb_ep->dma : NULL; | 753 | dma = is_dma_capable() ? musb_ep->dma : NULL; |
@@ -1731,6 +1733,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) | |||
1731 | spin_lock_irqsave(&musb->lock, flags); | 1733 | spin_lock_irqsave(&musb->lock, flags); |
1732 | 1734 | ||
1733 | otg_set_peripheral(musb->xceiv, &musb->g); | 1735 | otg_set_peripheral(musb->xceiv, &musb->g); |
1736 | musb->xceiv->state = OTG_STATE_B_IDLE; | ||
1734 | musb->is_active = 1; | 1737 | musb->is_active = 1; |
1735 | 1738 | ||
1736 | /* FIXME this ignores the softconnect flag. Drivers are | 1739 | /* FIXME this ignores the softconnect flag. Drivers are |
diff --git a/drivers/usb/musb/musb_gadget_ep0.c b/drivers/usb/musb/musb_gadget_ep0.c index 8fba3f11e473..53d06451f820 100644 --- a/drivers/usb/musb/musb_gadget_ep0.c +++ b/drivers/usb/musb/musb_gadget_ep0.c | |||
@@ -664,7 +664,7 @@ irqreturn_t musb_g_ep0_irq(struct musb *musb) | |||
664 | musb->ep0_state = MUSB_EP0_STAGE_STATUSIN; | 664 | musb->ep0_state = MUSB_EP0_STAGE_STATUSIN; |
665 | break; | 665 | break; |
666 | default: | 666 | default: |
667 | ERR("SetupEnd came in a wrong ep0stage %s", | 667 | ERR("SetupEnd came in a wrong ep0stage %s\n", |
668 | decode_ep0stage(musb->ep0_state)); | 668 | decode_ep0stage(musb->ep0_state)); |
669 | } | 669 | } |
670 | csr = musb_readw(regs, MUSB_CSR0); | 670 | csr = musb_readw(regs, MUSB_CSR0); |
@@ -787,12 +787,18 @@ setup: | |||
787 | handled = service_zero_data_request( | 787 | handled = service_zero_data_request( |
788 | musb, &setup); | 788 | musb, &setup); |
789 | 789 | ||
790 | /* | ||
791 | * We're expecting no data in any case, so | ||
792 | * always set the DATAEND bit -- doing this | ||
793 | * here helps avoid SetupEnd interrupt coming | ||
794 | * in the idle stage when we're stalling... | ||
795 | */ | ||
796 | musb->ackpend |= MUSB_CSR0_P_DATAEND; | ||
797 | |||
790 | /* status stage might be immediate */ | 798 | /* status stage might be immediate */ |
791 | if (handled > 0) { | 799 | if (handled > 0) |
792 | musb->ackpend |= MUSB_CSR0_P_DATAEND; | ||
793 | musb->ep0_state = | 800 | musb->ep0_state = |
794 | MUSB_EP0_STAGE_STATUSIN; | 801 | MUSB_EP0_STAGE_STATUSIN; |
795 | } | ||
796 | break; | 802 | break; |
797 | 803 | ||
798 | /* sequence #1 (IN to host), includes GET_STATUS | 804 | /* sequence #1 (IN to host), includes GET_STATUS |
diff --git a/drivers/usb/otg/isp1301_omap.c b/drivers/usb/otg/isp1301_omap.c index d54460a88173..78a209709260 100644 --- a/drivers/usb/otg/isp1301_omap.c +++ b/drivers/usb/otg/isp1301_omap.c | |||
@@ -843,7 +843,7 @@ static irqreturn_t omap_otg_irq(int irq, void *_isp) | |||
843 | 843 | ||
844 | static struct platform_device *otg_dev; | 844 | static struct platform_device *otg_dev; |
845 | 845 | ||
846 | static int otg_init(struct isp1301 *isp) | 846 | static int isp1301_otg_init(struct isp1301 *isp) |
847 | { | 847 | { |
848 | u32 l; | 848 | u32 l; |
849 | 849 | ||
@@ -1275,7 +1275,7 @@ static int __exit isp1301_remove(struct i2c_client *i2c) | |||
1275 | static int isp1301_otg_enable(struct isp1301 *isp) | 1275 | static int isp1301_otg_enable(struct isp1301 *isp) |
1276 | { | 1276 | { |
1277 | power_up(isp); | 1277 | power_up(isp); |
1278 | otg_init(isp); | 1278 | isp1301_otg_init(isp); |
1279 | 1279 | ||
1280 | /* NOTE: since we don't change this, this provides | 1280 | /* NOTE: since we don't change this, this provides |
1281 | * a few more interrupts than are strictly needed. | 1281 | * a few more interrupts than are strictly needed. |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index f99498fca99a..216f187582ab 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #include <linux/serial.h> | 44 | #include <linux/serial.h> |
45 | #include <linux/usb/serial.h> | 45 | #include <linux/usb/serial.h> |
46 | #include "ftdi_sio.h" | 46 | #include "ftdi_sio.h" |
47 | #include "ftdi_sio_ids.h" | ||
47 | 48 | ||
48 | /* | 49 | /* |
49 | * Version Information | 50 | * Version Information |
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 4586a24fafb0..b0e0d64f822e 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h | |||
@@ -1,7 +1,10 @@ | |||
1 | /* | 1 | /* |
2 | * Definitions for the FTDI USB Single Port Serial Converter - | 2 | * Driver definitions for the FTDI USB Single Port Serial Converter - |
3 | * known as FTDI_SIO (Serial Input/Output application of the chipset) | 3 | * known as FTDI_SIO (Serial Input/Output application of the chipset) |
4 | * | 4 | * |
5 | * For USB vendor/product IDs (VID/PID), please see ftdi_sio_ids.h | ||
6 | * | ||
7 | * | ||
5 | * The example I have is known as the USC-1000 which is available from | 8 | * The example I have is known as the USC-1000 which is available from |
6 | * http://www.dse.co.nz - cat no XH4214 It looks similar to this: | 9 | * http://www.dse.co.nz - cat no XH4214 It looks similar to this: |
7 | * http://www.dansdata.com/usbser.htm but I can't be sure There are other | 10 | * http://www.dansdata.com/usbser.htm but I can't be sure There are other |
@@ -17,880 +20,7 @@ | |||
17 | * Bill Ryder - bryder@sgi.com formerly of Silicon Graphics, Inc.- wrote the | 20 | * Bill Ryder - bryder@sgi.com formerly of Silicon Graphics, Inc.- wrote the |
18 | * FTDI_SIO implementation. | 21 | * FTDI_SIO implementation. |
19 | * | 22 | * |
20 | * Philipp Gühring - pg@futureware.at - added the Device ID of the USB relais | ||
21 | * from Rudolf Gugler | ||
22 | * | ||
23 | */ | ||
24 | |||
25 | #define FTDI_VID 0x0403 /* Vendor Id */ | ||
26 | #define FTDI_SIO_PID 0x8372 /* Product Id SIO application of 8U100AX */ | ||
27 | #define FTDI_8U232AM_PID 0x6001 /* Similar device to SIO above */ | ||
28 | #define FTDI_8U232AM_ALT_PID 0x6006 /* FTDI's alternate PID for above */ | ||
29 | #define FTDI_8U2232C_PID 0x6010 /* Dual channel device */ | ||
30 | #define FTDI_232RL_PID 0xFBFA /* Product ID for FT232RL */ | ||
31 | #define FTDI_4232H_PID 0x6011 /* Quad channel hi-speed device */ | ||
32 | #define FTDI_RELAIS_PID 0xFA10 /* Relais device from Rudolf Gugler */ | ||
33 | #define FTDI_NF_RIC_VID 0x0DCD /* Vendor Id */ | ||
34 | #define FTDI_NF_RIC_PID 0x0001 /* Product Id */ | ||
35 | #define FTDI_USBX_707_PID 0xF857 /* ADSTech IR Blaster USBX-707 */ | ||
36 | |||
37 | /* Larsen and Brusgaard AltiTrack/USBtrack */ | ||
38 | #define LARSENBRUSGAARD_VID 0x0FD8 | ||
39 | #define LB_ALTITRACK_PID 0x0001 | ||
40 | |||
41 | /* www.canusb.com Lawicel CANUSB device */ | ||
42 | #define FTDI_CANUSB_PID 0xFFA8 /* Product Id */ | ||
43 | |||
44 | /* AlphaMicro Components AMC-232USB01 device */ | ||
45 | #define FTDI_AMC232_PID 0xFF00 /* Product Id */ | ||
46 | |||
47 | /* www.candapter.com Ewert Energy Systems CANdapter device */ | ||
48 | #define FTDI_CANDAPTER_PID 0x9F80 /* Product Id */ | ||
49 | |||
50 | /* SCS HF Radio Modems PID's (http://www.scs-ptc.com) */ | ||
51 | /* the VID is the standard ftdi vid (FTDI_VID) */ | ||
52 | #define FTDI_SCS_DEVICE_0_PID 0xD010 /* SCS PTC-IIusb */ | ||
53 | #define FTDI_SCS_DEVICE_1_PID 0xD011 /* SCS Tracker / DSP TNC */ | ||
54 | #define FTDI_SCS_DEVICE_2_PID 0xD012 | ||
55 | #define FTDI_SCS_DEVICE_3_PID 0xD013 | ||
56 | #define FTDI_SCS_DEVICE_4_PID 0xD014 | ||
57 | #define FTDI_SCS_DEVICE_5_PID 0xD015 | ||
58 | #define FTDI_SCS_DEVICE_6_PID 0xD016 | ||
59 | #define FTDI_SCS_DEVICE_7_PID 0xD017 | ||
60 | |||
61 | /* ACT Solutions HomePro ZWave interface (http://www.act-solutions.com/HomePro.htm) */ | ||
62 | #define FTDI_ACTZWAVE_PID 0xF2D0 | ||
63 | |||
64 | |||
65 | /* www.starting-point-systems.com µChameleon device */ | ||
66 | #define FTDI_MICRO_CHAMELEON_PID 0xCAA0 /* Product Id */ | ||
67 | |||
68 | /* www.irtrans.de device */ | ||
69 | #define FTDI_IRTRANS_PID 0xFC60 /* Product Id */ | ||
70 | |||
71 | |||
72 | /* www.thoughttechnology.com/ TT-USB provide with procomp use ftdi_sio */ | ||
73 | #define FTDI_TTUSB_PID 0xFF20 /* Product Id */ | ||
74 | |||
75 | /* iPlus device */ | ||
76 | #define FTDI_IPLUS_PID 0xD070 /* Product Id */ | ||
77 | #define FTDI_IPLUS2_PID 0xD071 /* Product Id */ | ||
78 | |||
79 | /* DMX4ALL DMX Interfaces */ | ||
80 | #define FTDI_DMX4ALL 0xC850 | ||
81 | |||
82 | /* OpenDCC (www.opendcc.de) product id */ | ||
83 | #define FTDI_OPENDCC_PID 0xBFD8 | ||
84 | #define FTDI_OPENDCC_SNIFFER_PID 0xBFD9 | ||
85 | #define FTDI_OPENDCC_THROTTLE_PID 0xBFDA | ||
86 | #define FTDI_OPENDCC_GATEWAY_PID 0xBFDB | ||
87 | |||
88 | /* Sprog II (Andrew Crosland's SprogII DCC interface) */ | ||
89 | #define FTDI_SPROG_II 0xF0C8 | ||
90 | |||
91 | /* www.crystalfontz.com devices - thanx for providing free devices for evaluation ! */ | ||
92 | /* they use the ftdi chipset for the USB interface and the vendor id is the same */ | ||
93 | #define FTDI_XF_632_PID 0xFC08 /* 632: 16x2 Character Display */ | ||
94 | #define FTDI_XF_634_PID 0xFC09 /* 634: 20x4 Character Display */ | ||
95 | #define FTDI_XF_547_PID 0xFC0A /* 547: Two line Display */ | ||
96 | #define FTDI_XF_633_PID 0xFC0B /* 633: 16x2 Character Display with Keys */ | ||
97 | #define FTDI_XF_631_PID 0xFC0C /* 631: 20x2 Character Display */ | ||
98 | #define FTDI_XF_635_PID 0xFC0D /* 635: 20x4 Character Display */ | ||
99 | #define FTDI_XF_640_PID 0xFC0E /* 640: Two line Display */ | ||
100 | #define FTDI_XF_642_PID 0xFC0F /* 642: Two line Display */ | ||
101 | |||
102 | /* Video Networks Limited / Homechoice in the UK use an ftdi-based device for their 1Mb */ | ||
103 | /* broadband internet service. The following PID is exhibited by the usb device supplied */ | ||
104 | /* (the VID is the standard ftdi vid (FTDI_VID) */ | ||
105 | #define FTDI_VNHCPCUSB_D_PID 0xfe38 /* Product Id */ | ||
106 | |||
107 | /* | ||
108 | * PCDJ use ftdi based dj-controllers. The following PID is for their DAC-2 device | ||
109 | * http://www.pcdjhardware.com/DAC2.asp (PID sent by Wouter Paesen) | ||
110 | * (the VID is the standard ftdi vid (FTDI_VID) */ | ||
111 | #define FTDI_PCDJ_DAC2_PID 0xFA88 | ||
112 | |||
113 | /* | ||
114 | * The following are the values for the Matrix Orbital LCD displays, | ||
115 | * which are the FT232BM ( similar to the 8U232AM ) | ||
116 | */ | ||
117 | #define FTDI_MTXORB_0_PID 0xFA00 /* Matrix Orbital Product Id */ | ||
118 | #define FTDI_MTXORB_1_PID 0xFA01 /* Matrix Orbital Product Id */ | ||
119 | #define FTDI_MTXORB_2_PID 0xFA02 /* Matrix Orbital Product Id */ | ||
120 | #define FTDI_MTXORB_3_PID 0xFA03 /* Matrix Orbital Product Id */ | ||
121 | #define FTDI_MTXORB_4_PID 0xFA04 /* Matrix Orbital Product Id */ | ||
122 | #define FTDI_MTXORB_5_PID 0xFA05 /* Matrix Orbital Product Id */ | ||
123 | #define FTDI_MTXORB_6_PID 0xFA06 /* Matrix Orbital Product Id */ | ||
124 | |||
125 | /* OOCDlink by Joern Kaipf <joernk@web.de> | ||
126 | * (http://www.joernonline.de/dw/doku.php?id=start&idx=projects:oocdlink) */ | ||
127 | #define FTDI_OOCDLINK_PID 0xbaf8 /* Amontec JTAGkey */ | ||
128 | |||
129 | /* | ||
130 | * The following are the values for the Matrix Orbital FTDI Range | ||
131 | * Anything in this range will use an FT232RL. | ||
132 | */ | ||
133 | #define MTXORB_VID 0x1B3D | ||
134 | #define MTXORB_FTDI_RANGE_0100_PID 0x0100 | ||
135 | #define MTXORB_FTDI_RANGE_0101_PID 0x0101 | ||
136 | #define MTXORB_FTDI_RANGE_0102_PID 0x0102 | ||
137 | #define MTXORB_FTDI_RANGE_0103_PID 0x0103 | ||
138 | #define MTXORB_FTDI_RANGE_0104_PID 0x0104 | ||
139 | #define MTXORB_FTDI_RANGE_0105_PID 0x0105 | ||
140 | #define MTXORB_FTDI_RANGE_0106_PID 0x0106 | ||
141 | #define MTXORB_FTDI_RANGE_0107_PID 0x0107 | ||
142 | #define MTXORB_FTDI_RANGE_0108_PID 0x0108 | ||
143 | #define MTXORB_FTDI_RANGE_0109_PID 0x0109 | ||
144 | #define MTXORB_FTDI_RANGE_010A_PID 0x010A | ||
145 | #define MTXORB_FTDI_RANGE_010B_PID 0x010B | ||
146 | #define MTXORB_FTDI_RANGE_010C_PID 0x010C | ||
147 | #define MTXORB_FTDI_RANGE_010D_PID 0x010D | ||
148 | #define MTXORB_FTDI_RANGE_010E_PID 0x010E | ||
149 | #define MTXORB_FTDI_RANGE_010F_PID 0x010F | ||
150 | #define MTXORB_FTDI_RANGE_0110_PID 0x0110 | ||
151 | #define MTXORB_FTDI_RANGE_0111_PID 0x0111 | ||
152 | #define MTXORB_FTDI_RANGE_0112_PID 0x0112 | ||
153 | #define MTXORB_FTDI_RANGE_0113_PID 0x0113 | ||
154 | #define MTXORB_FTDI_RANGE_0114_PID 0x0114 | ||
155 | #define MTXORB_FTDI_RANGE_0115_PID 0x0115 | ||
156 | #define MTXORB_FTDI_RANGE_0116_PID 0x0116 | ||
157 | #define MTXORB_FTDI_RANGE_0117_PID 0x0117 | ||
158 | #define MTXORB_FTDI_RANGE_0118_PID 0x0118 | ||
159 | #define MTXORB_FTDI_RANGE_0119_PID 0x0119 | ||
160 | #define MTXORB_FTDI_RANGE_011A_PID 0x011A | ||
161 | #define MTXORB_FTDI_RANGE_011B_PID 0x011B | ||
162 | #define MTXORB_FTDI_RANGE_011C_PID 0x011C | ||
163 | #define MTXORB_FTDI_RANGE_011D_PID 0x011D | ||
164 | #define MTXORB_FTDI_RANGE_011E_PID 0x011E | ||
165 | #define MTXORB_FTDI_RANGE_011F_PID 0x011F | ||
166 | #define MTXORB_FTDI_RANGE_0120_PID 0x0120 | ||
167 | #define MTXORB_FTDI_RANGE_0121_PID 0x0121 | ||
168 | #define MTXORB_FTDI_RANGE_0122_PID 0x0122 | ||
169 | #define MTXORB_FTDI_RANGE_0123_PID 0x0123 | ||
170 | #define MTXORB_FTDI_RANGE_0124_PID 0x0124 | ||
171 | #define MTXORB_FTDI_RANGE_0125_PID 0x0125 | ||
172 | #define MTXORB_FTDI_RANGE_0126_PID 0x0126 | ||
173 | #define MTXORB_FTDI_RANGE_0127_PID 0x0127 | ||
174 | #define MTXORB_FTDI_RANGE_0128_PID 0x0128 | ||
175 | #define MTXORB_FTDI_RANGE_0129_PID 0x0129 | ||
176 | #define MTXORB_FTDI_RANGE_012A_PID 0x012A | ||
177 | #define MTXORB_FTDI_RANGE_012B_PID 0x012B | ||
178 | #define MTXORB_FTDI_RANGE_012C_PID 0x012C | ||
179 | #define MTXORB_FTDI_RANGE_012D_PID 0x012D | ||
180 | #define MTXORB_FTDI_RANGE_012E_PID 0x012E | ||
181 | #define MTXORB_FTDI_RANGE_012F_PID 0x012F | ||
182 | #define MTXORB_FTDI_RANGE_0130_PID 0x0130 | ||
183 | #define MTXORB_FTDI_RANGE_0131_PID 0x0131 | ||
184 | #define MTXORB_FTDI_RANGE_0132_PID 0x0132 | ||
185 | #define MTXORB_FTDI_RANGE_0133_PID 0x0133 | ||
186 | #define MTXORB_FTDI_RANGE_0134_PID 0x0134 | ||
187 | #define MTXORB_FTDI_RANGE_0135_PID 0x0135 | ||
188 | #define MTXORB_FTDI_RANGE_0136_PID 0x0136 | ||
189 | #define MTXORB_FTDI_RANGE_0137_PID 0x0137 | ||
190 | #define MTXORB_FTDI_RANGE_0138_PID 0x0138 | ||
191 | #define MTXORB_FTDI_RANGE_0139_PID 0x0139 | ||
192 | #define MTXORB_FTDI_RANGE_013A_PID 0x013A | ||
193 | #define MTXORB_FTDI_RANGE_013B_PID 0x013B | ||
194 | #define MTXORB_FTDI_RANGE_013C_PID 0x013C | ||
195 | #define MTXORB_FTDI_RANGE_013D_PID 0x013D | ||
196 | #define MTXORB_FTDI_RANGE_013E_PID 0x013E | ||
197 | #define MTXORB_FTDI_RANGE_013F_PID 0x013F | ||
198 | #define MTXORB_FTDI_RANGE_0140_PID 0x0140 | ||
199 | #define MTXORB_FTDI_RANGE_0141_PID 0x0141 | ||
200 | #define MTXORB_FTDI_RANGE_0142_PID 0x0142 | ||
201 | #define MTXORB_FTDI_RANGE_0143_PID 0x0143 | ||
202 | #define MTXORB_FTDI_RANGE_0144_PID 0x0144 | ||
203 | #define MTXORB_FTDI_RANGE_0145_PID 0x0145 | ||
204 | #define MTXORB_FTDI_RANGE_0146_PID 0x0146 | ||
205 | #define MTXORB_FTDI_RANGE_0147_PID 0x0147 | ||
206 | #define MTXORB_FTDI_RANGE_0148_PID 0x0148 | ||
207 | #define MTXORB_FTDI_RANGE_0149_PID 0x0149 | ||
208 | #define MTXORB_FTDI_RANGE_014A_PID 0x014A | ||
209 | #define MTXORB_FTDI_RANGE_014B_PID 0x014B | ||
210 | #define MTXORB_FTDI_RANGE_014C_PID 0x014C | ||
211 | #define MTXORB_FTDI_RANGE_014D_PID 0x014D | ||
212 | #define MTXORB_FTDI_RANGE_014E_PID 0x014E | ||
213 | #define MTXORB_FTDI_RANGE_014F_PID 0x014F | ||
214 | #define MTXORB_FTDI_RANGE_0150_PID 0x0150 | ||
215 | #define MTXORB_FTDI_RANGE_0151_PID 0x0151 | ||
216 | #define MTXORB_FTDI_RANGE_0152_PID 0x0152 | ||
217 | #define MTXORB_FTDI_RANGE_0153_PID 0x0153 | ||
218 | #define MTXORB_FTDI_RANGE_0154_PID 0x0154 | ||
219 | #define MTXORB_FTDI_RANGE_0155_PID 0x0155 | ||
220 | #define MTXORB_FTDI_RANGE_0156_PID 0x0156 | ||
221 | #define MTXORB_FTDI_RANGE_0157_PID 0x0157 | ||
222 | #define MTXORB_FTDI_RANGE_0158_PID 0x0158 | ||
223 | #define MTXORB_FTDI_RANGE_0159_PID 0x0159 | ||
224 | #define MTXORB_FTDI_RANGE_015A_PID 0x015A | ||
225 | #define MTXORB_FTDI_RANGE_015B_PID 0x015B | ||
226 | #define MTXORB_FTDI_RANGE_015C_PID 0x015C | ||
227 | #define MTXORB_FTDI_RANGE_015D_PID 0x015D | ||
228 | #define MTXORB_FTDI_RANGE_015E_PID 0x015E | ||
229 | #define MTXORB_FTDI_RANGE_015F_PID 0x015F | ||
230 | #define MTXORB_FTDI_RANGE_0160_PID 0x0160 | ||
231 | #define MTXORB_FTDI_RANGE_0161_PID 0x0161 | ||
232 | #define MTXORB_FTDI_RANGE_0162_PID 0x0162 | ||
233 | #define MTXORB_FTDI_RANGE_0163_PID 0x0163 | ||
234 | #define MTXORB_FTDI_RANGE_0164_PID 0x0164 | ||
235 | #define MTXORB_FTDI_RANGE_0165_PID 0x0165 | ||
236 | #define MTXORB_FTDI_RANGE_0166_PID 0x0166 | ||
237 | #define MTXORB_FTDI_RANGE_0167_PID 0x0167 | ||
238 | #define MTXORB_FTDI_RANGE_0168_PID 0x0168 | ||
239 | #define MTXORB_FTDI_RANGE_0169_PID 0x0169 | ||
240 | #define MTXORB_FTDI_RANGE_016A_PID 0x016A | ||
241 | #define MTXORB_FTDI_RANGE_016B_PID 0x016B | ||
242 | #define MTXORB_FTDI_RANGE_016C_PID 0x016C | ||
243 | #define MTXORB_FTDI_RANGE_016D_PID 0x016D | ||
244 | #define MTXORB_FTDI_RANGE_016E_PID 0x016E | ||
245 | #define MTXORB_FTDI_RANGE_016F_PID 0x016F | ||
246 | #define MTXORB_FTDI_RANGE_0170_PID 0x0170 | ||
247 | #define MTXORB_FTDI_RANGE_0171_PID 0x0171 | ||
248 | #define MTXORB_FTDI_RANGE_0172_PID 0x0172 | ||
249 | #define MTXORB_FTDI_RANGE_0173_PID 0x0173 | ||
250 | #define MTXORB_FTDI_RANGE_0174_PID 0x0174 | ||
251 | #define MTXORB_FTDI_RANGE_0175_PID 0x0175 | ||
252 | #define MTXORB_FTDI_RANGE_0176_PID 0x0176 | ||
253 | #define MTXORB_FTDI_RANGE_0177_PID 0x0177 | ||
254 | #define MTXORB_FTDI_RANGE_0178_PID 0x0178 | ||
255 | #define MTXORB_FTDI_RANGE_0179_PID 0x0179 | ||
256 | #define MTXORB_FTDI_RANGE_017A_PID 0x017A | ||
257 | #define MTXORB_FTDI_RANGE_017B_PID 0x017B | ||
258 | #define MTXORB_FTDI_RANGE_017C_PID 0x017C | ||
259 | #define MTXORB_FTDI_RANGE_017D_PID 0x017D | ||
260 | #define MTXORB_FTDI_RANGE_017E_PID 0x017E | ||
261 | #define MTXORB_FTDI_RANGE_017F_PID 0x017F | ||
262 | #define MTXORB_FTDI_RANGE_0180_PID 0x0180 | ||
263 | #define MTXORB_FTDI_RANGE_0181_PID 0x0181 | ||
264 | #define MTXORB_FTDI_RANGE_0182_PID 0x0182 | ||
265 | #define MTXORB_FTDI_RANGE_0183_PID 0x0183 | ||
266 | #define MTXORB_FTDI_RANGE_0184_PID 0x0184 | ||
267 | #define MTXORB_FTDI_RANGE_0185_PID 0x0185 | ||
268 | #define MTXORB_FTDI_RANGE_0186_PID 0x0186 | ||
269 | #define MTXORB_FTDI_RANGE_0187_PID 0x0187 | ||
270 | #define MTXORB_FTDI_RANGE_0188_PID 0x0188 | ||
271 | #define MTXORB_FTDI_RANGE_0189_PID 0x0189 | ||
272 | #define MTXORB_FTDI_RANGE_018A_PID 0x018A | ||
273 | #define MTXORB_FTDI_RANGE_018B_PID 0x018B | ||
274 | #define MTXORB_FTDI_RANGE_018C_PID 0x018C | ||
275 | #define MTXORB_FTDI_RANGE_018D_PID 0x018D | ||
276 | #define MTXORB_FTDI_RANGE_018E_PID 0x018E | ||
277 | #define MTXORB_FTDI_RANGE_018F_PID 0x018F | ||
278 | #define MTXORB_FTDI_RANGE_0190_PID 0x0190 | ||
279 | #define MTXORB_FTDI_RANGE_0191_PID 0x0191 | ||
280 | #define MTXORB_FTDI_RANGE_0192_PID 0x0192 | ||
281 | #define MTXORB_FTDI_RANGE_0193_PID 0x0193 | ||
282 | #define MTXORB_FTDI_RANGE_0194_PID 0x0194 | ||
283 | #define MTXORB_FTDI_RANGE_0195_PID 0x0195 | ||
284 | #define MTXORB_FTDI_RANGE_0196_PID 0x0196 | ||
285 | #define MTXORB_FTDI_RANGE_0197_PID 0x0197 | ||
286 | #define MTXORB_FTDI_RANGE_0198_PID 0x0198 | ||
287 | #define MTXORB_FTDI_RANGE_0199_PID 0x0199 | ||
288 | #define MTXORB_FTDI_RANGE_019A_PID 0x019A | ||
289 | #define MTXORB_FTDI_RANGE_019B_PID 0x019B | ||
290 | #define MTXORB_FTDI_RANGE_019C_PID 0x019C | ||
291 | #define MTXORB_FTDI_RANGE_019D_PID 0x019D | ||
292 | #define MTXORB_FTDI_RANGE_019E_PID 0x019E | ||
293 | #define MTXORB_FTDI_RANGE_019F_PID 0x019F | ||
294 | #define MTXORB_FTDI_RANGE_01A0_PID 0x01A0 | ||
295 | #define MTXORB_FTDI_RANGE_01A1_PID 0x01A1 | ||
296 | #define MTXORB_FTDI_RANGE_01A2_PID 0x01A2 | ||
297 | #define MTXORB_FTDI_RANGE_01A3_PID 0x01A3 | ||
298 | #define MTXORB_FTDI_RANGE_01A4_PID 0x01A4 | ||
299 | #define MTXORB_FTDI_RANGE_01A5_PID 0x01A5 | ||
300 | #define MTXORB_FTDI_RANGE_01A6_PID 0x01A6 | ||
301 | #define MTXORB_FTDI_RANGE_01A7_PID 0x01A7 | ||
302 | #define MTXORB_FTDI_RANGE_01A8_PID 0x01A8 | ||
303 | #define MTXORB_FTDI_RANGE_01A9_PID 0x01A9 | ||
304 | #define MTXORB_FTDI_RANGE_01AA_PID 0x01AA | ||
305 | #define MTXORB_FTDI_RANGE_01AB_PID 0x01AB | ||
306 | #define MTXORB_FTDI_RANGE_01AC_PID 0x01AC | ||
307 | #define MTXORB_FTDI_RANGE_01AD_PID 0x01AD | ||
308 | #define MTXORB_FTDI_RANGE_01AE_PID 0x01AE | ||
309 | #define MTXORB_FTDI_RANGE_01AF_PID 0x01AF | ||
310 | #define MTXORB_FTDI_RANGE_01B0_PID 0x01B0 | ||
311 | #define MTXORB_FTDI_RANGE_01B1_PID 0x01B1 | ||
312 | #define MTXORB_FTDI_RANGE_01B2_PID 0x01B2 | ||
313 | #define MTXORB_FTDI_RANGE_01B3_PID 0x01B3 | ||
314 | #define MTXORB_FTDI_RANGE_01B4_PID 0x01B4 | ||
315 | #define MTXORB_FTDI_RANGE_01B5_PID 0x01B5 | ||
316 | #define MTXORB_FTDI_RANGE_01B6_PID 0x01B6 | ||
317 | #define MTXORB_FTDI_RANGE_01B7_PID 0x01B7 | ||
318 | #define MTXORB_FTDI_RANGE_01B8_PID 0x01B8 | ||
319 | #define MTXORB_FTDI_RANGE_01B9_PID 0x01B9 | ||
320 | #define MTXORB_FTDI_RANGE_01BA_PID 0x01BA | ||
321 | #define MTXORB_FTDI_RANGE_01BB_PID 0x01BB | ||
322 | #define MTXORB_FTDI_RANGE_01BC_PID 0x01BC | ||
323 | #define MTXORB_FTDI_RANGE_01BD_PID 0x01BD | ||
324 | #define MTXORB_FTDI_RANGE_01BE_PID 0x01BE | ||
325 | #define MTXORB_FTDI_RANGE_01BF_PID 0x01BF | ||
326 | #define MTXORB_FTDI_RANGE_01C0_PID 0x01C0 | ||
327 | #define MTXORB_FTDI_RANGE_01C1_PID 0x01C1 | ||
328 | #define MTXORB_FTDI_RANGE_01C2_PID 0x01C2 | ||
329 | #define MTXORB_FTDI_RANGE_01C3_PID 0x01C3 | ||
330 | #define MTXORB_FTDI_RANGE_01C4_PID 0x01C4 | ||
331 | #define MTXORB_FTDI_RANGE_01C5_PID 0x01C5 | ||
332 | #define MTXORB_FTDI_RANGE_01C6_PID 0x01C6 | ||
333 | #define MTXORB_FTDI_RANGE_01C7_PID 0x01C7 | ||
334 | #define MTXORB_FTDI_RANGE_01C8_PID 0x01C8 | ||
335 | #define MTXORB_FTDI_RANGE_01C9_PID 0x01C9 | ||
336 | #define MTXORB_FTDI_RANGE_01CA_PID 0x01CA | ||
337 | #define MTXORB_FTDI_RANGE_01CB_PID 0x01CB | ||
338 | #define MTXORB_FTDI_RANGE_01CC_PID 0x01CC | ||
339 | #define MTXORB_FTDI_RANGE_01CD_PID 0x01CD | ||
340 | #define MTXORB_FTDI_RANGE_01CE_PID 0x01CE | ||
341 | #define MTXORB_FTDI_RANGE_01CF_PID 0x01CF | ||
342 | #define MTXORB_FTDI_RANGE_01D0_PID 0x01D0 | ||
343 | #define MTXORB_FTDI_RANGE_01D1_PID 0x01D1 | ||
344 | #define MTXORB_FTDI_RANGE_01D2_PID 0x01D2 | ||
345 | #define MTXORB_FTDI_RANGE_01D3_PID 0x01D3 | ||
346 | #define MTXORB_FTDI_RANGE_01D4_PID 0x01D4 | ||
347 | #define MTXORB_FTDI_RANGE_01D5_PID 0x01D5 | ||
348 | #define MTXORB_FTDI_RANGE_01D6_PID 0x01D6 | ||
349 | #define MTXORB_FTDI_RANGE_01D7_PID 0x01D7 | ||
350 | #define MTXORB_FTDI_RANGE_01D8_PID 0x01D8 | ||
351 | #define MTXORB_FTDI_RANGE_01D9_PID 0x01D9 | ||
352 | #define MTXORB_FTDI_RANGE_01DA_PID 0x01DA | ||
353 | #define MTXORB_FTDI_RANGE_01DB_PID 0x01DB | ||
354 | #define MTXORB_FTDI_RANGE_01DC_PID 0x01DC | ||
355 | #define MTXORB_FTDI_RANGE_01DD_PID 0x01DD | ||
356 | #define MTXORB_FTDI_RANGE_01DE_PID 0x01DE | ||
357 | #define MTXORB_FTDI_RANGE_01DF_PID 0x01DF | ||
358 | #define MTXORB_FTDI_RANGE_01E0_PID 0x01E0 | ||
359 | #define MTXORB_FTDI_RANGE_01E1_PID 0x01E1 | ||
360 | #define MTXORB_FTDI_RANGE_01E2_PID 0x01E2 | ||
361 | #define MTXORB_FTDI_RANGE_01E3_PID 0x01E3 | ||
362 | #define MTXORB_FTDI_RANGE_01E4_PID 0x01E4 | ||
363 | #define MTXORB_FTDI_RANGE_01E5_PID 0x01E5 | ||
364 | #define MTXORB_FTDI_RANGE_01E6_PID 0x01E6 | ||
365 | #define MTXORB_FTDI_RANGE_01E7_PID 0x01E7 | ||
366 | #define MTXORB_FTDI_RANGE_01E8_PID 0x01E8 | ||
367 | #define MTXORB_FTDI_RANGE_01E9_PID 0x01E9 | ||
368 | #define MTXORB_FTDI_RANGE_01EA_PID 0x01EA | ||
369 | #define MTXORB_FTDI_RANGE_01EB_PID 0x01EB | ||
370 | #define MTXORB_FTDI_RANGE_01EC_PID 0x01EC | ||
371 | #define MTXORB_FTDI_RANGE_01ED_PID 0x01ED | ||
372 | #define MTXORB_FTDI_RANGE_01EE_PID 0x01EE | ||
373 | #define MTXORB_FTDI_RANGE_01EF_PID 0x01EF | ||
374 | #define MTXORB_FTDI_RANGE_01F0_PID 0x01F0 | ||
375 | #define MTXORB_FTDI_RANGE_01F1_PID 0x01F1 | ||
376 | #define MTXORB_FTDI_RANGE_01F2_PID 0x01F2 | ||
377 | #define MTXORB_FTDI_RANGE_01F3_PID 0x01F3 | ||
378 | #define MTXORB_FTDI_RANGE_01F4_PID 0x01F4 | ||
379 | #define MTXORB_FTDI_RANGE_01F5_PID 0x01F5 | ||
380 | #define MTXORB_FTDI_RANGE_01F6_PID 0x01F6 | ||
381 | #define MTXORB_FTDI_RANGE_01F7_PID 0x01F7 | ||
382 | #define MTXORB_FTDI_RANGE_01F8_PID 0x01F8 | ||
383 | #define MTXORB_FTDI_RANGE_01F9_PID 0x01F9 | ||
384 | #define MTXORB_FTDI_RANGE_01FA_PID 0x01FA | ||
385 | #define MTXORB_FTDI_RANGE_01FB_PID 0x01FB | ||
386 | #define MTXORB_FTDI_RANGE_01FC_PID 0x01FC | ||
387 | #define MTXORB_FTDI_RANGE_01FD_PID 0x01FD | ||
388 | #define MTXORB_FTDI_RANGE_01FE_PID 0x01FE | ||
389 | #define MTXORB_FTDI_RANGE_01FF_PID 0x01FF | ||
390 | |||
391 | |||
392 | |||
393 | /* Interbiometrics USB I/O Board */ | ||
394 | /* Developed for Interbiometrics by Rudolf Gugler */ | ||
395 | #define INTERBIOMETRICS_VID 0x1209 | ||
396 | #define INTERBIOMETRICS_IOBOARD_PID 0x1002 | ||
397 | #define INTERBIOMETRICS_MINI_IOBOARD_PID 0x1006 | ||
398 | |||
399 | /* | ||
400 | * The following are the values for the Perle Systems | ||
401 | * UltraPort USB serial converters | ||
402 | */ | ||
403 | #define FTDI_PERLE_ULTRAPORT_PID 0xF0C0 /* Perle UltraPort Product Id */ | ||
404 | |||
405 | /* | ||
406 | * The following are the values for the Sealevel SeaLINK+ adapters. | ||
407 | * (Original list sent by Tuan Hoang. Ian Abbott renamed the macros and | ||
408 | * removed some PIDs that don't seem to match any existing products.) | ||
409 | */ | ||
410 | #define SEALEVEL_VID 0x0c52 /* Sealevel Vendor ID */ | ||
411 | #define SEALEVEL_2101_PID 0x2101 /* SeaLINK+232 (2101/2105) */ | ||
412 | #define SEALEVEL_2102_PID 0x2102 /* SeaLINK+485 (2102) */ | ||
413 | #define SEALEVEL_2103_PID 0x2103 /* SeaLINK+232I (2103) */ | ||
414 | #define SEALEVEL_2104_PID 0x2104 /* SeaLINK+485I (2104) */ | ||
415 | #define SEALEVEL_2106_PID 0x9020 /* SeaLINK+422 (2106) */ | ||
416 | #define SEALEVEL_2201_1_PID 0x2211 /* SeaPORT+2/232 (2201) Port 1 */ | ||
417 | #define SEALEVEL_2201_2_PID 0x2221 /* SeaPORT+2/232 (2201) Port 2 */ | ||
418 | #define SEALEVEL_2202_1_PID 0x2212 /* SeaPORT+2/485 (2202) Port 1 */ | ||
419 | #define SEALEVEL_2202_2_PID 0x2222 /* SeaPORT+2/485 (2202) Port 2 */ | ||
420 | #define SEALEVEL_2203_1_PID 0x2213 /* SeaPORT+2 (2203) Port 1 */ | ||
421 | #define SEALEVEL_2203_2_PID 0x2223 /* SeaPORT+2 (2203) Port 2 */ | ||
422 | #define SEALEVEL_2401_1_PID 0x2411 /* SeaPORT+4/232 (2401) Port 1 */ | ||
423 | #define SEALEVEL_2401_2_PID 0x2421 /* SeaPORT+4/232 (2401) Port 2 */ | ||
424 | #define SEALEVEL_2401_3_PID 0x2431 /* SeaPORT+4/232 (2401) Port 3 */ | ||
425 | #define SEALEVEL_2401_4_PID 0x2441 /* SeaPORT+4/232 (2401) Port 4 */ | ||
426 | #define SEALEVEL_2402_1_PID 0x2412 /* SeaPORT+4/485 (2402) Port 1 */ | ||
427 | #define SEALEVEL_2402_2_PID 0x2422 /* SeaPORT+4/485 (2402) Port 2 */ | ||
428 | #define SEALEVEL_2402_3_PID 0x2432 /* SeaPORT+4/485 (2402) Port 3 */ | ||
429 | #define SEALEVEL_2402_4_PID 0x2442 /* SeaPORT+4/485 (2402) Port 4 */ | ||
430 | #define SEALEVEL_2403_1_PID 0x2413 /* SeaPORT+4 (2403) Port 1 */ | ||
431 | #define SEALEVEL_2403_2_PID 0x2423 /* SeaPORT+4 (2403) Port 2 */ | ||
432 | #define SEALEVEL_2403_3_PID 0x2433 /* SeaPORT+4 (2403) Port 3 */ | ||
433 | #define SEALEVEL_2403_4_PID 0x2443 /* SeaPORT+4 (2403) Port 4 */ | ||
434 | #define SEALEVEL_2801_1_PID 0X2811 /* SeaLINK+8/232 (2801) Port 1 */ | ||
435 | #define SEALEVEL_2801_2_PID 0X2821 /* SeaLINK+8/232 (2801) Port 2 */ | ||
436 | #define SEALEVEL_2801_3_PID 0X2831 /* SeaLINK+8/232 (2801) Port 3 */ | ||
437 | #define SEALEVEL_2801_4_PID 0X2841 /* SeaLINK+8/232 (2801) Port 4 */ | ||
438 | #define SEALEVEL_2801_5_PID 0X2851 /* SeaLINK+8/232 (2801) Port 5 */ | ||
439 | #define SEALEVEL_2801_6_PID 0X2861 /* SeaLINK+8/232 (2801) Port 6 */ | ||
440 | #define SEALEVEL_2801_7_PID 0X2871 /* SeaLINK+8/232 (2801) Port 7 */ | ||
441 | #define SEALEVEL_2801_8_PID 0X2881 /* SeaLINK+8/232 (2801) Port 8 */ | ||
442 | #define SEALEVEL_2802_1_PID 0X2812 /* SeaLINK+8/485 (2802) Port 1 */ | ||
443 | #define SEALEVEL_2802_2_PID 0X2822 /* SeaLINK+8/485 (2802) Port 2 */ | ||
444 | #define SEALEVEL_2802_3_PID 0X2832 /* SeaLINK+8/485 (2802) Port 3 */ | ||
445 | #define SEALEVEL_2802_4_PID 0X2842 /* SeaLINK+8/485 (2802) Port 4 */ | ||
446 | #define SEALEVEL_2802_5_PID 0X2852 /* SeaLINK+8/485 (2802) Port 5 */ | ||
447 | #define SEALEVEL_2802_6_PID 0X2862 /* SeaLINK+8/485 (2802) Port 6 */ | ||
448 | #define SEALEVEL_2802_7_PID 0X2872 /* SeaLINK+8/485 (2802) Port 7 */ | ||
449 | #define SEALEVEL_2802_8_PID 0X2882 /* SeaLINK+8/485 (2802) Port 8 */ | ||
450 | #define SEALEVEL_2803_1_PID 0X2813 /* SeaLINK+8 (2803) Port 1 */ | ||
451 | #define SEALEVEL_2803_2_PID 0X2823 /* SeaLINK+8 (2803) Port 2 */ | ||
452 | #define SEALEVEL_2803_3_PID 0X2833 /* SeaLINK+8 (2803) Port 3 */ | ||
453 | #define SEALEVEL_2803_4_PID 0X2843 /* SeaLINK+8 (2803) Port 4 */ | ||
454 | #define SEALEVEL_2803_5_PID 0X2853 /* SeaLINK+8 (2803) Port 5 */ | ||
455 | #define SEALEVEL_2803_6_PID 0X2863 /* SeaLINK+8 (2803) Port 6 */ | ||
456 | #define SEALEVEL_2803_7_PID 0X2873 /* SeaLINK+8 (2803) Port 7 */ | ||
457 | #define SEALEVEL_2803_8_PID 0X2883 /* SeaLINK+8 (2803) Port 8 */ | ||
458 | |||
459 | /* | ||
460 | * The following are the values for two KOBIL chipcard terminals. | ||
461 | */ | ||
462 | #define KOBIL_VID 0x0d46 /* KOBIL Vendor ID */ | ||
463 | #define KOBIL_CONV_B1_PID 0x2020 /* KOBIL Konverter for B1 */ | ||
464 | #define KOBIL_CONV_KAAN_PID 0x2021 /* KOBIL_Konverter for KAAN */ | ||
465 | |||
466 | /* | ||
467 | * Icom ID-1 digital transceiver | ||
468 | */ | ||
469 | |||
470 | #define ICOM_ID1_VID 0x0C26 | ||
471 | #define ICOM_ID1_PID 0x0004 | ||
472 | |||
473 | /* | ||
474 | * ASK.fr devices | ||
475 | */ | ||
476 | #define FTDI_ASK_RDR400_PID 0xC991 /* ASK RDR 400 series card reader */ | ||
477 | |||
478 | /* | ||
479 | * FTDI USB UART chips used in construction projects from the | ||
480 | * Elektor Electronics magazine (http://elektor-electronics.co.uk) | ||
481 | */ | ||
482 | #define ELEKTOR_VID 0x0C7D | ||
483 | #define ELEKTOR_FT323R_PID 0x0005 /* RFID-Reader, issue 09-2006 */ | ||
484 | |||
485 | /* | ||
486 | * DSS-20 Sync Station for Sony Ericsson P800 | ||
487 | */ | ||
488 | #define FTDI_DSS20_PID 0xFC82 | ||
489 | |||
490 | /* | ||
491 | * Home Electronics (www.home-electro.com) USB gadgets | ||
492 | */ | ||
493 | #define FTDI_HE_TIRA1_PID 0xFA78 /* Tira-1 IR transceiver */ | ||
494 | |||
495 | /* USB-UIRT - An infrared receiver and transmitter using the 8U232AM chip */ | ||
496 | /* http://home.earthlink.net/~jrhees/USBUIRT/index.htm */ | ||
497 | #define FTDI_USB_UIRT_PID 0xF850 /* Product Id */ | ||
498 | |||
499 | /* TNC-X USB-to-packet-radio adapter, versions prior to 3.0 (DLP module) */ | ||
500 | |||
501 | #define FTDI_TNC_X_PID 0xEBE0 | ||
502 | |||
503 | /* | ||
504 | * ELV USB devices submitted by Christian Abt of ELV (www.elv.de). | ||
505 | * All of these devices use FTDI's vendor ID (0x0403). | ||
506 | * | ||
507 | * The previously included PID for the UO 100 module was incorrect. | ||
508 | * In fact, that PID was for ELV's UR 100 USB-RS232 converter (0xFB58). | ||
509 | * | ||
510 | * Armin Laeuger originally sent the PID for the UM 100 module. | ||
511 | */ | ||
512 | #define FTDI_R2000KU_TRUE_RNG 0xFB80 /* R2000KU TRUE RNG */ | ||
513 | #define FTDI_ELV_UR100_PID 0xFB58 /* USB-RS232-Umsetzer (UR 100) */ | ||
514 | #define FTDI_ELV_UM100_PID 0xFB5A /* USB-Modul UM 100 */ | ||
515 | #define FTDI_ELV_UO100_PID 0xFB5B /* USB-Modul UO 100 */ | ||
516 | #define FTDI_ELV_ALC8500_PID 0xF06E /* ALC 8500 Expert */ | ||
517 | /* Additional ELV PIDs that default to using the FTDI D2XX drivers on | ||
518 | * MS Windows, rather than the FTDI Virtual Com Port drivers. | ||
519 | * Maybe these will be easier to use with the libftdi/libusb user-space | ||
520 | * drivers, or possibly the Comedi drivers in some cases. */ | ||
521 | #define FTDI_ELV_CLI7000_PID 0xFB59 /* Computer-Light-Interface (CLI 7000) */ | ||
522 | #define FTDI_ELV_PPS7330_PID 0xFB5C /* Processor-Power-Supply (PPS 7330) */ | ||
523 | #define FTDI_ELV_TFM100_PID 0xFB5D /* Temperartur-Feuchte Messgeraet (TFM 100) */ | ||
524 | #define FTDI_ELV_UDF77_PID 0xFB5E /* USB DCF Funkurh (UDF 77) */ | ||
525 | #define FTDI_ELV_UIO88_PID 0xFB5F /* USB-I/O Interface (UIO 88) */ | ||
526 | #define FTDI_ELV_UAD8_PID 0xF068 /* USB-AD-Wandler (UAD 8) */ | ||
527 | #define FTDI_ELV_UDA7_PID 0xF069 /* USB-DA-Wandler (UDA 7) */ | ||
528 | #define FTDI_ELV_USI2_PID 0xF06A /* USB-Schrittmotoren-Interface (USI 2) */ | ||
529 | #define FTDI_ELV_T1100_PID 0xF06B /* Thermometer (T 1100) */ | ||
530 | #define FTDI_ELV_PCD200_PID 0xF06C /* PC-Datenlogger (PCD 200) */ | ||
531 | #define FTDI_ELV_ULA200_PID 0xF06D /* USB-LCD-Ansteuerung (ULA 200) */ | ||
532 | #define FTDI_ELV_FHZ1000PC_PID 0xF06F /* FHZ 1000 PC */ | ||
533 | #define FTDI_ELV_CSI8_PID 0xE0F0 /* Computer-Schalt-Interface (CSI 8) */ | ||
534 | #define FTDI_ELV_EM1000DL_PID 0xE0F1 /* PC-Datenlogger fuer Energiemonitor (EM 1000 DL) */ | ||
535 | #define FTDI_ELV_PCK100_PID 0xE0F2 /* PC-Kabeltester (PCK 100) */ | ||
536 | #define FTDI_ELV_RFP500_PID 0xE0F3 /* HF-Leistungsmesser (RFP 500) */ | ||
537 | #define FTDI_ELV_FS20SIG_PID 0xE0F4 /* Signalgeber (FS 20 SIG) */ | ||
538 | #define FTDI_ELV_WS300PC_PID 0xE0F6 /* PC-Wetterstation (WS 300 PC) */ | ||
539 | #define FTDI_ELV_FHZ1300PC_PID 0xE0E8 /* FHZ 1300 PC */ | ||
540 | #define FTDI_ELV_WS500_PID 0xE0E9 /* PC-Wetterstation (WS 500) */ | ||
541 | #define FTDI_ELV_HS485_PID 0xE0EA /* USB to RS-485 adapter */ | ||
542 | #define FTDI_ELV_EM1010PC_PID 0xE0EF /* Engery monitor EM 1010 PC */ | ||
543 | #define FTDI_PHI_FISCO_PID 0xE40B /* PHI Fisco USB to Serial cable */ | ||
544 | |||
545 | /* | ||
546 | * Definitions for ID TECH (www.idt-net.com) devices | ||
547 | */ | ||
548 | #define IDTECH_VID 0x0ACD /* ID TECH Vendor ID */ | ||
549 | #define IDTECH_IDT1221U_PID 0x0300 /* IDT1221U USB to RS-232 adapter */ | ||
550 | |||
551 | /* | ||
552 | * Definitions for Omnidirectional Control Technology, Inc. devices | ||
553 | */ | ||
554 | #define OCT_VID 0x0B39 /* OCT vendor ID */ | ||
555 | /* Note: OCT US101 is also rebadged as Dick Smith Electronics (NZ) XH6381 */ | ||
556 | /* Also rebadged as Dick Smith Electronics (Aus) XH6451 */ | ||
557 | /* Also rebadged as SIIG Inc. model US2308 hardware version 1 */ | ||
558 | #define OCT_US101_PID 0x0421 /* OCT US101 USB to RS-232 */ | ||
559 | |||
560 | /* an infrared receiver for user access control with IR tags */ | ||
561 | #define FTDI_PIEGROUP_PID 0xF208 /* Product Id */ | ||
562 | |||
563 | /* | ||
564 | * Definitions for Artemis astronomical USB based cameras | ||
565 | * Check it at http://www.artemisccd.co.uk/ | ||
566 | */ | ||
567 | #define FTDI_ARTEMIS_PID 0xDF28 /* All Artemis Cameras */ | ||
568 | |||
569 | /* | ||
570 | * Definitions for ATIK Instruments astronomical USB based cameras | ||
571 | * Check it at http://www.atik-instruments.com/ | ||
572 | */ | ||
573 | #define FTDI_ATIK_ATK16_PID 0xDF30 /* ATIK ATK-16 Grayscale Camera */ | ||
574 | #define FTDI_ATIK_ATK16C_PID 0xDF32 /* ATIK ATK-16C Colour Camera */ | ||
575 | #define FTDI_ATIK_ATK16HR_PID 0xDF31 /* ATIK ATK-16HR Grayscale Camera */ | ||
576 | #define FTDI_ATIK_ATK16HRC_PID 0xDF33 /* ATIK ATK-16HRC Colour Camera */ | ||
577 | #define FTDI_ATIK_ATK16IC_PID 0xDF35 /* ATIK ATK-16IC Grayscale Camera */ | ||
578 | |||
579 | /* | ||
580 | * Protego product ids | ||
581 | */ | ||
582 | #define PROTEGO_SPECIAL_1 0xFC70 /* special/unknown device */ | ||
583 | #define PROTEGO_R2X0 0xFC71 /* R200-USB TRNG unit (R210, R220, and R230) */ | ||
584 | #define PROTEGO_SPECIAL_3 0xFC72 /* special/unknown device */ | ||
585 | #define PROTEGO_SPECIAL_4 0xFC73 /* special/unknown device */ | ||
586 | |||
587 | /* | ||
588 | * Gude Analog- und Digitalsysteme GmbH | ||
589 | */ | ||
590 | #define FTDI_GUDEADS_E808_PID 0xE808 | ||
591 | #define FTDI_GUDEADS_E809_PID 0xE809 | ||
592 | #define FTDI_GUDEADS_E80A_PID 0xE80A | ||
593 | #define FTDI_GUDEADS_E80B_PID 0xE80B | ||
594 | #define FTDI_GUDEADS_E80C_PID 0xE80C | ||
595 | #define FTDI_GUDEADS_E80D_PID 0xE80D | ||
596 | #define FTDI_GUDEADS_E80E_PID 0xE80E | ||
597 | #define FTDI_GUDEADS_E80F_PID 0xE80F | ||
598 | #define FTDI_GUDEADS_E888_PID 0xE888 /* Expert ISDN Control USB */ | ||
599 | #define FTDI_GUDEADS_E889_PID 0xE889 /* USB RS-232 OptoBridge */ | ||
600 | #define FTDI_GUDEADS_E88A_PID 0xE88A | ||
601 | #define FTDI_GUDEADS_E88B_PID 0xE88B | ||
602 | #define FTDI_GUDEADS_E88C_PID 0xE88C | ||
603 | #define FTDI_GUDEADS_E88D_PID 0xE88D | ||
604 | #define FTDI_GUDEADS_E88E_PID 0xE88E | ||
605 | #define FTDI_GUDEADS_E88F_PID 0xE88F | ||
606 | |||
607 | /* | ||
608 | * Linx Technologies product ids | ||
609 | */ | ||
610 | #define LINX_SDMUSBQSS_PID 0xF448 /* Linx SDM-USB-QS-S */ | ||
611 | #define LINX_MASTERDEVEL2_PID 0xF449 /* Linx Master Development 2.0 */ | ||
612 | #define LINX_FUTURE_0_PID 0xF44A /* Linx future device */ | ||
613 | #define LINX_FUTURE_1_PID 0xF44B /* Linx future device */ | ||
614 | #define LINX_FUTURE_2_PID 0xF44C /* Linx future device */ | ||
615 | |||
616 | /* CCS Inc. ICDU/ICDU40 product ID - the FT232BM is used in an in-circuit-debugger */ | ||
617 | /* unit for PIC16's/PIC18's */ | ||
618 | #define FTDI_CCSICDU20_0_PID 0xF9D0 | ||
619 | #define FTDI_CCSICDU40_1_PID 0xF9D1 | ||
620 | #define FTDI_CCSMACHX_2_PID 0xF9D2 | ||
621 | #define FTDI_CCSLOAD_N_GO_3_PID 0xF9D3 | ||
622 | #define FTDI_CCSICDU64_4_PID 0xF9D4 | ||
623 | #define FTDI_CCSPRIME8_5_PID 0xF9D5 | ||
624 | |||
625 | /* Inside Accesso contactless reader (http://www.insidefr.com) */ | ||
626 | #define INSIDE_ACCESSO 0xFAD0 | ||
627 | |||
628 | /* | ||
629 | * Intrepid Control Systems (http://www.intrepidcs.com/) ValueCAN and NeoVI | ||
630 | */ | ||
631 | #define INTREPID_VID 0x093C | ||
632 | #define INTREPID_VALUECAN_PID 0x0601 | ||
633 | #define INTREPID_NEOVI_PID 0x0701 | ||
634 | |||
635 | /* | ||
636 | * Falcom Wireless Communications GmbH | ||
637 | */ | ||
638 | #define FALCOM_VID 0x0F94 /* Vendor Id */ | ||
639 | #define FALCOM_TWIST_PID 0x0001 /* Falcom Twist USB GPRS modem */ | ||
640 | #define FALCOM_SAMBA_PID 0x0005 /* Falcom Samba USB GPRS modem */ | ||
641 | |||
642 | /* | ||
643 | * SUUNTO product ids | ||
644 | */ | ||
645 | #define FTDI_SUUNTO_SPORTS_PID 0xF680 /* Suunto Sports instrument */ | ||
646 | |||
647 | /* | ||
648 | * Oceanic product ids | ||
649 | */ | ||
650 | #define FTDI_OCEANIC_PID 0xF460 /* Oceanic dive instrument */ | ||
651 | |||
652 | /* | ||
653 | * TTi (Thurlby Thandar Instruments) | ||
654 | */ | ||
655 | #define TTI_VID 0x103E /* Vendor Id */ | ||
656 | #define TTI_QL355P_PID 0x03E8 /* TTi QL355P power supply */ | ||
657 | |||
658 | /* | ||
659 | * Definitions for B&B Electronics products. | ||
660 | */ | ||
661 | #define BANDB_VID 0x0856 /* B&B Electronics Vendor ID */ | ||
662 | #define BANDB_USOTL4_PID 0xAC01 /* USOTL4 Isolated RS-485 Converter */ | ||
663 | #define BANDB_USTL4_PID 0xAC02 /* USTL4 RS-485 Converter */ | ||
664 | #define BANDB_USO9ML2_PID 0xAC03 /* USO9ML2 Isolated RS-232 Converter */ | ||
665 | #define BANDB_USOPTL4_PID 0xAC11 | ||
666 | #define BANDB_USPTL4_PID 0xAC12 | ||
667 | #define BANDB_USO9ML2DR_2_PID 0xAC16 | ||
668 | #define BANDB_USO9ML2DR_PID 0xAC17 | ||
669 | #define BANDB_USOPTL4DR2_PID 0xAC18 /* USOPTL4R-2 2-port Isolated RS-232 Converter */ | ||
670 | #define BANDB_USOPTL4DR_PID 0xAC19 | ||
671 | #define BANDB_485USB9F_2W_PID 0xAC25 | ||
672 | #define BANDB_485USB9F_4W_PID 0xAC26 | ||
673 | #define BANDB_232USB9M_PID 0xAC27 | ||
674 | #define BANDB_485USBTB_2W_PID 0xAC33 | ||
675 | #define BANDB_485USBTB_4W_PID 0xAC34 | ||
676 | #define BANDB_TTL5USB9M_PID 0xAC49 | ||
677 | #define BANDB_TTL3USB9M_PID 0xAC50 | ||
678 | #define BANDB_ZZ_PROG1_USB_PID 0xBA02 | ||
679 | |||
680 | /* | ||
681 | * RM Michaelides CANview USB (http://www.rmcan.com) | ||
682 | * CAN fieldbus interface adapter, added by port GmbH www.port.de) | ||
683 | * Ian Abbott changed the macro names for consistency. | ||
684 | */ | ||
685 | #define FTDI_RM_CANVIEW_PID 0xfd60 /* Product Id */ | ||
686 | |||
687 | /* | ||
688 | * EVER Eco Pro UPS (http://www.ever.com.pl/) | ||
689 | */ | ||
690 | |||
691 | #define EVER_ECO_PRO_CDS 0xe520 /* RS-232 converter */ | ||
692 | |||
693 | /* | ||
694 | * 4N-GALAXY.DE PIDs for CAN-USB, USB-RS232, USB-RS422, USB-RS485, | ||
695 | * USB-TTY activ, USB-TTY passiv. Some PIDs are used by several devices | ||
696 | * and I'm not entirely sure which are used by which. | ||
697 | */ | ||
698 | #define FTDI_4N_GALAXY_DE_1_PID 0xF3C0 | ||
699 | #define FTDI_4N_GALAXY_DE_2_PID 0xF3C1 | ||
700 | |||
701 | /* | ||
702 | * Mobility Electronics products. | ||
703 | */ | ||
704 | #define MOBILITY_VID 0x1342 | ||
705 | #define MOBILITY_USB_SERIAL_PID 0x0202 /* EasiDock USB 200 serial */ | ||
706 | |||
707 | /* | ||
708 | * microHAM product IDs (http://www.microham.com). | ||
709 | * Submitted by Justin Burket (KL1RL) <zorton@jtan.com> | ||
710 | * and Mike Studer (K6EEP) <k6eep@hamsoftware.org>. | ||
711 | * Ian Abbott <abbotti@mev.co.uk> added a few more from the driver INF file. | ||
712 | */ | ||
713 | #define FTDI_MHAM_KW_PID 0xEEE8 /* USB-KW interface */ | ||
714 | #define FTDI_MHAM_YS_PID 0xEEE9 /* USB-YS interface */ | ||
715 | #define FTDI_MHAM_Y6_PID 0xEEEA /* USB-Y6 interface */ | ||
716 | #define FTDI_MHAM_Y8_PID 0xEEEB /* USB-Y8 interface */ | ||
717 | #define FTDI_MHAM_IC_PID 0xEEEC /* USB-IC interface */ | ||
718 | #define FTDI_MHAM_DB9_PID 0xEEED /* USB-DB9 interface */ | ||
719 | #define FTDI_MHAM_RS232_PID 0xEEEE /* USB-RS232 interface */ | ||
720 | #define FTDI_MHAM_Y9_PID 0xEEEF /* USB-Y9 interface */ | ||
721 | |||
722 | /* | ||
723 | * Active Robots product ids. | ||
724 | */ | ||
725 | #define FTDI_ACTIVE_ROBOTS_PID 0xE548 /* USB comms board */ | ||
726 | |||
727 | /* | ||
728 | * Xsens Technologies BV products (http://www.xsens.com). | ||
729 | */ | ||
730 | #define XSENS_CONVERTER_0_PID 0xD388 | ||
731 | #define XSENS_CONVERTER_1_PID 0xD389 | ||
732 | #define XSENS_CONVERTER_2_PID 0xD38A | ||
733 | #define XSENS_CONVERTER_3_PID 0xD38B | ||
734 | #define XSENS_CONVERTER_4_PID 0xD38C | ||
735 | #define XSENS_CONVERTER_5_PID 0xD38D | ||
736 | #define XSENS_CONVERTER_6_PID 0xD38E | ||
737 | #define XSENS_CONVERTER_7_PID 0xD38F | ||
738 | |||
739 | /* | ||
740 | * Teratronik product ids. | ||
741 | * Submitted by O. Wölfelschneider. | ||
742 | */ | ||
743 | #define FTDI_TERATRONIK_VCP_PID 0xEC88 /* Teratronik device (preferring VCP driver on windows) */ | ||
744 | #define FTDI_TERATRONIK_D2XX_PID 0xEC89 /* Teratronik device (preferring D2XX driver on windows) */ | ||
745 | |||
746 | /* | ||
747 | * Evolution Robotics products (http://www.evolution.com/). | ||
748 | * Submitted by Shawn M. Lavelle. | ||
749 | */ | ||
750 | #define EVOLUTION_VID 0xDEEE /* Vendor ID */ | ||
751 | #define EVOLUTION_ER1_PID 0x0300 /* ER1 Control Module */ | ||
752 | #define EVO_8U232AM_PID 0x02FF /* Evolution robotics RCM2 (FT232AM)*/ | ||
753 | #define EVO_HYBRID_PID 0x0302 /* Evolution robotics RCM4 PID (FT232BM)*/ | ||
754 | #define EVO_RCM4_PID 0x0303 /* Evolution robotics RCM4 PID */ | ||
755 | |||
756 | /* Pyramid Computer GmbH */ | ||
757 | #define FTDI_PYRAMID_PID 0xE6C8 /* Pyramid Appliance Display */ | ||
758 | |||
759 | /* | ||
760 | * NDI (www.ndigital.com) product ids | ||
761 | */ | ||
762 | #define FTDI_NDI_HUC_PID 0xDA70 /* NDI Host USB Converter */ | ||
763 | #define FTDI_NDI_SPECTRA_SCU_PID 0xDA71 /* NDI Spectra SCU */ | ||
764 | #define FTDI_NDI_FUTURE_2_PID 0xDA72 /* NDI future device #2 */ | ||
765 | #define FTDI_NDI_FUTURE_3_PID 0xDA73 /* NDI future device #3 */ | ||
766 | #define FTDI_NDI_AURORA_SCU_PID 0xDA74 /* NDI Aurora SCU */ | ||
767 | |||
768 | /* | ||
769 | * Posiflex inc retail equipment (http://www.posiflex.com.tw) | ||
770 | */ | ||
771 | #define POSIFLEX_VID 0x0d3a /* Vendor ID */ | ||
772 | #define POSIFLEX_PP7000_PID 0x0300 /* PP-7000II thermal printer */ | ||
773 | |||
774 | /* | ||
775 | * Westrex International devices submitted by Cory Lee | ||
776 | */ | ||
777 | #define FTDI_WESTREX_MODEL_777_PID 0xDC00 /* Model 777 */ | ||
778 | #define FTDI_WESTREX_MODEL_8900F_PID 0xDC01 /* Model 8900F */ | ||
779 | |||
780 | /* | ||
781 | * RR-CirKits LocoBuffer USB (http://www.rr-cirkits.com) | ||
782 | */ | ||
783 | #define FTDI_RRCIRKITS_LOCOBUFFER_PID 0xc7d0 /* LocoBuffer USB */ | ||
784 | |||
785 | /* | ||
786 | * Eclo (http://www.eclo.pt/) product IDs. | ||
787 | * PID 0xEA90 submitted by Martin Grill. | ||
788 | */ | ||
789 | #define FTDI_ECLO_COM_1WIRE_PID 0xEA90 /* COM to 1-Wire USB adaptor */ | ||
790 | |||
791 | /* | ||
792 | * Papouch products (http://www.papouch.com/) | ||
793 | * Submitted by Folkert van Heusden | ||
794 | */ | ||
795 | |||
796 | #define PAPOUCH_VID 0x5050 /* Vendor ID */ | ||
797 | #define PAPOUCH_TMU_PID 0x0400 /* TMU USB Thermometer */ | ||
798 | #define PAPOUCH_QUIDO4x4_PID 0x0900 /* Quido 4/4 Module */ | ||
799 | |||
800 | /* | ||
801 | * ACG Identification Technologies GmbH products (http://www.acg.de/). | ||
802 | * Submitted by anton -at- goto10 -dot- org. | ||
803 | */ | 23 | */ |
804 | #define FTDI_ACG_HFDUAL_PID 0xDD20 /* HF Dual ISO Reader (RFID) */ | ||
805 | |||
806 | /* | ||
807 | * Yost Engineering, Inc. products (www.yostengineering.com). | ||
808 | * PID 0xE050 submitted by Aaron Prose. | ||
809 | */ | ||
810 | #define FTDI_YEI_SERVOCENTER31_PID 0xE050 /* YEI ServoCenter3.1 USB */ | ||
811 | |||
812 | /* | ||
813 | * ThorLabs USB motor drivers | ||
814 | */ | ||
815 | #define FTDI_THORLABS_PID 0xfaf0 /* ThorLabs USB motor drivers */ | ||
816 | |||
817 | /* | ||
818 | * Testo products (http://www.testo.com/) | ||
819 | * Submitted by Colin Leroy | ||
820 | */ | ||
821 | #define TESTO_VID 0x128D | ||
822 | #define TESTO_USB_INTERFACE_PID 0x0001 | ||
823 | |||
824 | /* | ||
825 | * Gamma Scout (http://gamma-scout.com/). Submitted by rsc@runtux.com. | ||
826 | */ | ||
827 | #define FTDI_GAMMA_SCOUT_PID 0xD678 /* Gamma Scout online */ | ||
828 | |||
829 | /* | ||
830 | * Tactrix OpenPort (ECU) devices. | ||
831 | * OpenPort 1.3M submitted by Donour Sizemore. | ||
832 | * OpenPort 1.3S and 1.3U submitted by Ian Abbott. | ||
833 | */ | ||
834 | #define FTDI_TACTRIX_OPENPORT_13M_PID 0xCC48 /* OpenPort 1.3 Mitsubishi */ | ||
835 | #define FTDI_TACTRIX_OPENPORT_13S_PID 0xCC49 /* OpenPort 1.3 Subaru */ | ||
836 | #define FTDI_TACTRIX_OPENPORT_13U_PID 0xCC4A /* OpenPort 1.3 Universal */ | ||
837 | |||
838 | /* | ||
839 | * Telldus Technologies | ||
840 | */ | ||
841 | #define TELLDUS_VID 0x1781 /* Vendor ID */ | ||
842 | #define TELLDUS_TELLSTICK_PID 0x0C30 /* RF control dongle 433 MHz using FT232RL */ | ||
843 | |||
844 | /* | ||
845 | * IBS elektronik product ids | ||
846 | * Submitted by Thomas Schleusener | ||
847 | */ | ||
848 | #define FTDI_IBS_US485_PID 0xff38 /* IBS US485 (USB<-->RS422/485 interface) */ | ||
849 | #define FTDI_IBS_PICPRO_PID 0xff39 /* IBS PIC-Programmer */ | ||
850 | #define FTDI_IBS_PCMCIA_PID 0xff3a /* IBS Card reader for PCMCIA SRAM-cards */ | ||
851 | #define FTDI_IBS_PK1_PID 0xff3b /* IBS PK1 - Particel counter */ | ||
852 | #define FTDI_IBS_RS232MON_PID 0xff3c /* IBS RS232 - Monitor */ | ||
853 | #define FTDI_IBS_APP70_PID 0xff3d /* APP 70 (dust monitoring system) */ | ||
854 | #define FTDI_IBS_PEDO_PID 0xff3e /* IBS PEDO-Modem (RF modem 868.35 MHz) */ | ||
855 | #define FTDI_IBS_PROD_PID 0xff3f /* future device */ | ||
856 | |||
857 | /* | ||
858 | * MaxStream devices www.maxstream.net | ||
859 | */ | ||
860 | #define FTDI_MAXSTREAM_PID 0xEE18 /* Xbee PKG-U Module */ | ||
861 | |||
862 | /* Olimex */ | ||
863 | #define OLIMEX_VID 0x15BA | ||
864 | #define OLIMEX_ARM_USB_OCD_PID 0x0003 | ||
865 | |||
866 | /* Luminary Micro Stellaris Boards, VID = FTDI_VID */ | ||
867 | /* FTDI 2332C Dual channel device, side A=245 FIFO (JTAG), Side B=RS232 UART */ | ||
868 | #define LMI_LM3S_DEVEL_BOARD_PID 0xbcd8 | ||
869 | #define LMI_LM3S_EVAL_BOARD_PID 0xbcd9 | ||
870 | |||
871 | /* www.elsterelectricity.com Elster Unicom III Optical Probe */ | ||
872 | #define FTDI_ELSTER_UNICOM_PID 0xE700 /* Product Id */ | ||
873 | |||
874 | /* | ||
875 | * The Mobility Lab (TML) | ||
876 | * Submitted by Pierre Castella | ||
877 | */ | ||
878 | #define TML_VID 0x1B91 /* Vendor ID */ | ||
879 | #define TML_USB_SERIAL_PID 0x0064 /* USB - Serial Converter */ | ||
880 | |||
881 | /* Propox devices */ | ||
882 | #define FTDI_PROPOX_JTAGCABLEII_PID 0xD738 | ||
883 | |||
884 | /* Rig Expert Ukraine devices */ | ||
885 | #define FTDI_REU_TINY_PID 0xED22 /* RigExpert Tiny */ | ||
886 | |||
887 | /* Domintell products http://www.domintell.com */ | ||
888 | #define FTDI_DOMINTELL_DGQG_PID 0xEF50 /* Master */ | ||
889 | #define FTDI_DOMINTELL_DUSB_PID 0xEF51 /* DUSB01 module */ | ||
890 | |||
891 | /* Alti-2 products http://www.alti-2.com */ | ||
892 | #define ALTI2_VID 0x1BC9 | ||
893 | #define ALTI2_N3_PID 0x6001 /* Neptune 3 */ | ||
894 | 24 | ||
895 | /* Commands */ | 25 | /* Commands */ |
896 | #define FTDI_SIO_RESET 0 /* Reset the port */ | 26 | #define FTDI_SIO_RESET 0 /* Reset the port */ |
@@ -910,86 +40,6 @@ | |||
910 | #define INTERFACE_C 3 | 40 | #define INTERFACE_C 3 |
911 | #define INTERFACE_D 4 | 41 | #define INTERFACE_D 4 |
912 | 42 | ||
913 | /* | ||
914 | * FIC / OpenMoko, Inc. http://wiki.openmoko.org/wiki/Neo1973_Debug_Board_v3 | ||
915 | * Submitted by Harald Welte <laforge@openmoko.org> | ||
916 | */ | ||
917 | #define FIC_VID 0x1457 | ||
918 | #define FIC_NEO1973_DEBUG_PID 0x5118 | ||
919 | |||
920 | /* | ||
921 | * RATOC REX-USB60F | ||
922 | */ | ||
923 | #define RATOC_VENDOR_ID 0x0584 | ||
924 | #define RATOC_PRODUCT_ID_USB60F 0xb020 | ||
925 | |||
926 | /* | ||
927 | * DIEBOLD BCS SE923 | ||
928 | */ | ||
929 | #define DIEBOLD_BCS_SE923_PID 0xfb99 | ||
930 | |||
931 | /* | ||
932 | * Atmel STK541 | ||
933 | */ | ||
934 | #define ATMEL_VID 0x03eb /* Vendor ID */ | ||
935 | #define STK541_PID 0x2109 /* Zigbee Controller */ | ||
936 | |||
937 | /* | ||
938 | * Dresden Elektronic Sensor Terminal Board | ||
939 | */ | ||
940 | #define DE_VID 0x1cf1 /* Vendor ID */ | ||
941 | #define STB_PID 0x0001 /* Sensor Terminal Board */ | ||
942 | #define WHT_PID 0x0004 /* Wireless Handheld Terminal */ | ||
943 | |||
944 | /* | ||
945 | * Blackfin gnICE JTAG | ||
946 | * http://docs.blackfin.uclinux.org/doku.php?id=hw:jtag:gnice | ||
947 | */ | ||
948 | #define ADI_VID 0x0456 | ||
949 | #define ADI_GNICE_PID 0xF000 | ||
950 | #define ADI_GNICEPLUS_PID 0xF001 | ||
951 | |||
952 | /* | ||
953 | * JETI SPECTROMETER SPECBOS 1201 | ||
954 | * http://www.jeti.com/products/sys/scb/scb1201.php | ||
955 | */ | ||
956 | #define JETI_VID 0x0c6c | ||
957 | #define JETI_SPC1201_PID 0x04b2 | ||
958 | |||
959 | /* | ||
960 | * Marvell SheevaPlug | ||
961 | */ | ||
962 | #define MARVELL_VID 0x9e88 | ||
963 | #define MARVELL_SHEEVAPLUG_PID 0x9e8f | ||
964 | |||
965 | #define FTDI_TURTELIZER_PID 0xBDC8 /* JTAG/RS-232 adapter by egnite GmBH */ | ||
966 | |||
967 | /* | ||
968 | * GN Otometrics (http://www.otometrics.com) | ||
969 | * Submitted by Ville Sundberg. | ||
970 | */ | ||
971 | #define GN_OTOMETRICS_VID 0x0c33 /* Vendor ID */ | ||
972 | #define AURICAL_USB_PID 0x0010 /* Aurical USB Audiometer */ | ||
973 | |||
974 | /* | ||
975 | * Bayer Ascensia Contour blood glucose meter USB-converter cable. | ||
976 | * http://winglucofacts.com/cables/ | ||
977 | */ | ||
978 | #define BAYER_VID 0x1A79 | ||
979 | #define BAYER_CONTOUR_CABLE_PID 0x6001 | ||
980 | |||
981 | /* | ||
982 | * Marvell OpenRD Base, Client | ||
983 | * http://www.open-rd.org | ||
984 | * OpenRD Base, Client use VID 0x0403 | ||
985 | */ | ||
986 | #define MARVELL_OPENRD_PID 0x9e90 | ||
987 | |||
988 | /* | ||
989 | * Hameg HO820 and HO870 interface (using VID 0x0403) | ||
990 | */ | ||
991 | #define HAMEG_HO820_PID 0xed74 | ||
992 | #define HAMEG_HO870_PID 0xed71 | ||
993 | 43 | ||
994 | /* | 44 | /* |
995 | * BmRequestType: 1100 0000b | 45 | * BmRequestType: 1100 0000b |
@@ -1504,4 +554,3 @@ typedef enum { | |||
1504 | * B2..7 Length of message - (not including Byte 0) | 554 | * B2..7 Length of message - (not including Byte 0) |
1505 | * | 555 | * |
1506 | */ | 556 | */ |
1507 | |||
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h new file mode 100644 index 000000000000..da92b4952ffb --- /dev/null +++ b/drivers/usb/serial/ftdi_sio_ids.h | |||
@@ -0,0 +1,986 @@ | |||
1 | /* | ||
2 | * vendor/product IDs (VID/PID) of devices using FTDI USB serial converters. | ||
3 | * Please keep numerically sorted within individual areas, thanks! | ||
4 | * | ||
5 | * Philipp Gühring - pg@futureware.at - added the Device ID of the USB relais | ||
6 | * from Rudolf Gugler | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | |||
11 | /**********************************/ | ||
12 | /***** devices using FTDI VID *****/ | ||
13 | /**********************************/ | ||
14 | |||
15 | |||
16 | #define FTDI_VID 0x0403 /* Vendor Id */ | ||
17 | |||
18 | |||
19 | /*** "original" FTDI device PIDs ***/ | ||
20 | |||
21 | #define FTDI_8U232AM_PID 0x6001 /* Similar device to SIO above */ | ||
22 | #define FTDI_8U232AM_ALT_PID 0x6006 /* FTDI's alternate PID for above */ | ||
23 | #define FTDI_8U2232C_PID 0x6010 /* Dual channel device */ | ||
24 | #define FTDI_4232H_PID 0x6011 /* Quad channel hi-speed device */ | ||
25 | #define FTDI_SIO_PID 0x8372 /* Product Id SIO application of 8U100AX */ | ||
26 | #define FTDI_232RL_PID 0xFBFA /* Product ID for FT232RL */ | ||
27 | |||
28 | |||
29 | /*** third-party PIDs (using FTDI_VID) ***/ | ||
30 | |||
31 | /* | ||
32 | * Marvell OpenRD Base, Client | ||
33 | * http://www.open-rd.org | ||
34 | * OpenRD Base, Client use VID 0x0403 | ||
35 | */ | ||
36 | #define MARVELL_OPENRD_PID 0x9e90 | ||
37 | |||
38 | /* www.candapter.com Ewert Energy Systems CANdapter device */ | ||
39 | #define FTDI_CANDAPTER_PID 0x9F80 /* Product Id */ | ||
40 | |||
41 | /* OOCDlink by Joern Kaipf <joernk@web.de> | ||
42 | * (http://www.joernonline.de/dw/doku.php?id=start&idx=projects:oocdlink) */ | ||
43 | #define FTDI_OOCDLINK_PID 0xbaf8 /* Amontec JTAGkey */ | ||
44 | |||
45 | /* Luminary Micro Stellaris Boards, VID = FTDI_VID */ | ||
46 | /* FTDI 2332C Dual channel device, side A=245 FIFO (JTAG), Side B=RS232 UART */ | ||
47 | #define LMI_LM3S_DEVEL_BOARD_PID 0xbcd8 | ||
48 | #define LMI_LM3S_EVAL_BOARD_PID 0xbcd9 | ||
49 | |||
50 | #define FTDI_TURTELIZER_PID 0xBDC8 /* JTAG/RS-232 adapter by egnite GmBH */ | ||
51 | |||
52 | /* OpenDCC (www.opendcc.de) product id */ | ||
53 | #define FTDI_OPENDCC_PID 0xBFD8 | ||
54 | #define FTDI_OPENDCC_SNIFFER_PID 0xBFD9 | ||
55 | #define FTDI_OPENDCC_THROTTLE_PID 0xBFDA | ||
56 | #define FTDI_OPENDCC_GATEWAY_PID 0xBFDB | ||
57 | |||
58 | /* | ||
59 | * RR-CirKits LocoBuffer USB (http://www.rr-cirkits.com) | ||
60 | */ | ||
61 | #define FTDI_RRCIRKITS_LOCOBUFFER_PID 0xc7d0 /* LocoBuffer USB */ | ||
62 | |||
63 | /* DMX4ALL DMX Interfaces */ | ||
64 | #define FTDI_DMX4ALL 0xC850 | ||
65 | |||
66 | /* | ||
67 | * ASK.fr devices | ||
68 | */ | ||
69 | #define FTDI_ASK_RDR400_PID 0xC991 /* ASK RDR 400 series card reader */ | ||
70 | |||
71 | /* www.starting-point-systems.com µChameleon device */ | ||
72 | #define FTDI_MICRO_CHAMELEON_PID 0xCAA0 /* Product Id */ | ||
73 | |||
74 | /* | ||
75 | * Tactrix OpenPort (ECU) devices. | ||
76 | * OpenPort 1.3M submitted by Donour Sizemore. | ||
77 | * OpenPort 1.3S and 1.3U submitted by Ian Abbott. | ||
78 | */ | ||
79 | #define FTDI_TACTRIX_OPENPORT_13M_PID 0xCC48 /* OpenPort 1.3 Mitsubishi */ | ||
80 | #define FTDI_TACTRIX_OPENPORT_13S_PID 0xCC49 /* OpenPort 1.3 Subaru */ | ||
81 | #define FTDI_TACTRIX_OPENPORT_13U_PID 0xCC4A /* OpenPort 1.3 Universal */ | ||
82 | |||
83 | /* SCS HF Radio Modems PID's (http://www.scs-ptc.com) */ | ||
84 | /* the VID is the standard ftdi vid (FTDI_VID) */ | ||
85 | #define FTDI_SCS_DEVICE_0_PID 0xD010 /* SCS PTC-IIusb */ | ||
86 | #define FTDI_SCS_DEVICE_1_PID 0xD011 /* SCS Tracker / DSP TNC */ | ||
87 | #define FTDI_SCS_DEVICE_2_PID 0xD012 | ||
88 | #define FTDI_SCS_DEVICE_3_PID 0xD013 | ||
89 | #define FTDI_SCS_DEVICE_4_PID 0xD014 | ||
90 | #define FTDI_SCS_DEVICE_5_PID 0xD015 | ||
91 | #define FTDI_SCS_DEVICE_6_PID 0xD016 | ||
92 | #define FTDI_SCS_DEVICE_7_PID 0xD017 | ||
93 | |||
94 | /* iPlus device */ | ||
95 | #define FTDI_IPLUS_PID 0xD070 /* Product Id */ | ||
96 | #define FTDI_IPLUS2_PID 0xD071 /* Product Id */ | ||
97 | |||
98 | /* | ||
99 | * Gamma Scout (http://gamma-scout.com/). Submitted by rsc@runtux.com. | ||
100 | */ | ||
101 | #define FTDI_GAMMA_SCOUT_PID 0xD678 /* Gamma Scout online */ | ||
102 | |||
103 | /* Propox devices */ | ||
104 | #define FTDI_PROPOX_JTAGCABLEII_PID 0xD738 | ||
105 | |||
106 | /* | ||
107 | * Xsens Technologies BV products (http://www.xsens.com). | ||
108 | */ | ||
109 | #define XSENS_CONVERTER_0_PID 0xD388 | ||
110 | #define XSENS_CONVERTER_1_PID 0xD389 | ||
111 | #define XSENS_CONVERTER_2_PID 0xD38A | ||
112 | #define XSENS_CONVERTER_3_PID 0xD38B | ||
113 | #define XSENS_CONVERTER_4_PID 0xD38C | ||
114 | #define XSENS_CONVERTER_5_PID 0xD38D | ||
115 | #define XSENS_CONVERTER_6_PID 0xD38E | ||
116 | #define XSENS_CONVERTER_7_PID 0xD38F | ||
117 | |||
118 | /* | ||
119 | * NDI (www.ndigital.com) product ids | ||
120 | */ | ||
121 | #define FTDI_NDI_HUC_PID 0xDA70 /* NDI Host USB Converter */ | ||
122 | #define FTDI_NDI_SPECTRA_SCU_PID 0xDA71 /* NDI Spectra SCU */ | ||
123 | #define FTDI_NDI_FUTURE_2_PID 0xDA72 /* NDI future device #2 */ | ||
124 | #define FTDI_NDI_FUTURE_3_PID 0xDA73 /* NDI future device #3 */ | ||
125 | #define FTDI_NDI_AURORA_SCU_PID 0xDA74 /* NDI Aurora SCU */ | ||
126 | |||
127 | /* | ||
128 | * Westrex International devices submitted by Cory Lee | ||
129 | */ | ||
130 | #define FTDI_WESTREX_MODEL_777_PID 0xDC00 /* Model 777 */ | ||
131 | #define FTDI_WESTREX_MODEL_8900F_PID 0xDC01 /* Model 8900F */ | ||
132 | |||
133 | /* | ||
134 | * ACG Identification Technologies GmbH products (http://www.acg.de/). | ||
135 | * Submitted by anton -at- goto10 -dot- org. | ||
136 | */ | ||
137 | #define FTDI_ACG_HFDUAL_PID 0xDD20 /* HF Dual ISO Reader (RFID) */ | ||
138 | |||
139 | /* | ||
140 | * Definitions for Artemis astronomical USB based cameras | ||
141 | * Check it at http://www.artemisccd.co.uk/ | ||
142 | */ | ||
143 | #define FTDI_ARTEMIS_PID 0xDF28 /* All Artemis Cameras */ | ||
144 | |||
145 | /* | ||
146 | * Definitions for ATIK Instruments astronomical USB based cameras | ||
147 | * Check it at http://www.atik-instruments.com/ | ||
148 | */ | ||
149 | #define FTDI_ATIK_ATK16_PID 0xDF30 /* ATIK ATK-16 Grayscale Camera */ | ||
150 | #define FTDI_ATIK_ATK16C_PID 0xDF32 /* ATIK ATK-16C Colour Camera */ | ||
151 | #define FTDI_ATIK_ATK16HR_PID 0xDF31 /* ATIK ATK-16HR Grayscale Camera */ | ||
152 | #define FTDI_ATIK_ATK16HRC_PID 0xDF33 /* ATIK ATK-16HRC Colour Camera */ | ||
153 | #define FTDI_ATIK_ATK16IC_PID 0xDF35 /* ATIK ATK-16IC Grayscale Camera */ | ||
154 | |||
155 | /* | ||
156 | * Yost Engineering, Inc. products (www.yostengineering.com). | ||
157 | * PID 0xE050 submitted by Aaron Prose. | ||
158 | */ | ||
159 | #define FTDI_YEI_SERVOCENTER31_PID 0xE050 /* YEI ServoCenter3.1 USB */ | ||
160 | |||
161 | /* | ||
162 | * ELV USB devices submitted by Christian Abt of ELV (www.elv.de). | ||
163 | * All of these devices use FTDI's vendor ID (0x0403). | ||
164 | * | ||
165 | * The previously included PID for the UO 100 module was incorrect. | ||
166 | * In fact, that PID was for ELV's UR 100 USB-RS232 converter (0xFB58). | ||
167 | * | ||
168 | * Armin Laeuger originally sent the PID for the UM 100 module. | ||
169 | */ | ||
170 | #define FTDI_ELV_FHZ1300PC_PID 0xE0E8 /* FHZ 1300 PC */ | ||
171 | #define FTDI_ELV_WS500_PID 0xE0E9 /* PC-Wetterstation (WS 500) */ | ||
172 | #define FTDI_ELV_HS485_PID 0xE0EA /* USB to RS-485 adapter */ | ||
173 | #define FTDI_ELV_EM1010PC_PID 0xE0EF /* Engery monitor EM 1010 PC */ | ||
174 | #define FTDI_ELV_CSI8_PID 0xE0F0 /* Computer-Schalt-Interface (CSI 8) */ | ||
175 | #define FTDI_ELV_EM1000DL_PID 0xE0F1 /* PC-Datenlogger fuer Energiemonitor (EM 1000 DL) */ | ||
176 | #define FTDI_ELV_PCK100_PID 0xE0F2 /* PC-Kabeltester (PCK 100) */ | ||
177 | #define FTDI_ELV_RFP500_PID 0xE0F3 /* HF-Leistungsmesser (RFP 500) */ | ||
178 | #define FTDI_ELV_FS20SIG_PID 0xE0F4 /* Signalgeber (FS 20 SIG) */ | ||
179 | #define FTDI_ELV_WS300PC_PID 0xE0F6 /* PC-Wetterstation (WS 300 PC) */ | ||
180 | #define FTDI_PHI_FISCO_PID 0xE40B /* PHI Fisco USB to Serial cable */ | ||
181 | #define FTDI_ELV_UAD8_PID 0xF068 /* USB-AD-Wandler (UAD 8) */ | ||
182 | #define FTDI_ELV_UDA7_PID 0xF069 /* USB-DA-Wandler (UDA 7) */ | ||
183 | #define FTDI_ELV_USI2_PID 0xF06A /* USB-Schrittmotoren-Interface (USI 2) */ | ||
184 | #define FTDI_ELV_T1100_PID 0xF06B /* Thermometer (T 1100) */ | ||
185 | #define FTDI_ELV_PCD200_PID 0xF06C /* PC-Datenlogger (PCD 200) */ | ||
186 | #define FTDI_ELV_ULA200_PID 0xF06D /* USB-LCD-Ansteuerung (ULA 200) */ | ||
187 | #define FTDI_ELV_ALC8500_PID 0xF06E /* ALC 8500 Expert */ | ||
188 | #define FTDI_ELV_FHZ1000PC_PID 0xF06F /* FHZ 1000 PC */ | ||
189 | #define FTDI_ELV_UR100_PID 0xFB58 /* USB-RS232-Umsetzer (UR 100) */ | ||
190 | #define FTDI_ELV_UM100_PID 0xFB5A /* USB-Modul UM 100 */ | ||
191 | #define FTDI_ELV_UO100_PID 0xFB5B /* USB-Modul UO 100 */ | ||
192 | /* Additional ELV PIDs that default to using the FTDI D2XX drivers on | ||
193 | * MS Windows, rather than the FTDI Virtual Com Port drivers. | ||
194 | * Maybe these will be easier to use with the libftdi/libusb user-space | ||
195 | * drivers, or possibly the Comedi drivers in some cases. */ | ||
196 | #define FTDI_ELV_CLI7000_PID 0xFB59 /* Computer-Light-Interface (CLI 7000) */ | ||
197 | #define FTDI_ELV_PPS7330_PID 0xFB5C /* Processor-Power-Supply (PPS 7330) */ | ||
198 | #define FTDI_ELV_TFM100_PID 0xFB5D /* Temperartur-Feuchte Messgeraet (TFM 100) */ | ||
199 | #define FTDI_ELV_UDF77_PID 0xFB5E /* USB DCF Funkurh (UDF 77) */ | ||
200 | #define FTDI_ELV_UIO88_PID 0xFB5F /* USB-I/O Interface (UIO 88) */ | ||
201 | |||
202 | /* | ||
203 | * EVER Eco Pro UPS (http://www.ever.com.pl/) | ||
204 | */ | ||
205 | |||
206 | #define EVER_ECO_PRO_CDS 0xe520 /* RS-232 converter */ | ||
207 | |||
208 | /* | ||
209 | * Active Robots product ids. | ||
210 | */ | ||
211 | #define FTDI_ACTIVE_ROBOTS_PID 0xE548 /* USB comms board */ | ||
212 | |||
213 | /* Pyramid Computer GmbH */ | ||
214 | #define FTDI_PYRAMID_PID 0xE6C8 /* Pyramid Appliance Display */ | ||
215 | |||
216 | /* www.elsterelectricity.com Elster Unicom III Optical Probe */ | ||
217 | #define FTDI_ELSTER_UNICOM_PID 0xE700 /* Product Id */ | ||
218 | |||
219 | /* | ||
220 | * Gude Analog- und Digitalsysteme GmbH | ||
221 | */ | ||
222 | #define FTDI_GUDEADS_E808_PID 0xE808 | ||
223 | #define FTDI_GUDEADS_E809_PID 0xE809 | ||
224 | #define FTDI_GUDEADS_E80A_PID 0xE80A | ||
225 | #define FTDI_GUDEADS_E80B_PID 0xE80B | ||
226 | #define FTDI_GUDEADS_E80C_PID 0xE80C | ||
227 | #define FTDI_GUDEADS_E80D_PID 0xE80D | ||
228 | #define FTDI_GUDEADS_E80E_PID 0xE80E | ||
229 | #define FTDI_GUDEADS_E80F_PID 0xE80F | ||
230 | #define FTDI_GUDEADS_E888_PID 0xE888 /* Expert ISDN Control USB */ | ||
231 | #define FTDI_GUDEADS_E889_PID 0xE889 /* USB RS-232 OptoBridge */ | ||
232 | #define FTDI_GUDEADS_E88A_PID 0xE88A | ||
233 | #define FTDI_GUDEADS_E88B_PID 0xE88B | ||
234 | #define FTDI_GUDEADS_E88C_PID 0xE88C | ||
235 | #define FTDI_GUDEADS_E88D_PID 0xE88D | ||
236 | #define FTDI_GUDEADS_E88E_PID 0xE88E | ||
237 | #define FTDI_GUDEADS_E88F_PID 0xE88F | ||
238 | |||
239 | /* | ||
240 | * Eclo (http://www.eclo.pt/) product IDs. | ||
241 | * PID 0xEA90 submitted by Martin Grill. | ||
242 | */ | ||
243 | #define FTDI_ECLO_COM_1WIRE_PID 0xEA90 /* COM to 1-Wire USB adaptor */ | ||
244 | |||
245 | /* TNC-X USB-to-packet-radio adapter, versions prior to 3.0 (DLP module) */ | ||
246 | #define FTDI_TNC_X_PID 0xEBE0 | ||
247 | |||
248 | /* | ||
249 | * Teratronik product ids. | ||
250 | * Submitted by O. Wölfelschneider. | ||
251 | */ | ||
252 | #define FTDI_TERATRONIK_VCP_PID 0xEC88 /* Teratronik device (preferring VCP driver on windows) */ | ||
253 | #define FTDI_TERATRONIK_D2XX_PID 0xEC89 /* Teratronik device (preferring D2XX driver on windows) */ | ||
254 | |||
255 | /* Rig Expert Ukraine devices */ | ||
256 | #define FTDI_REU_TINY_PID 0xED22 /* RigExpert Tiny */ | ||
257 | |||
258 | /* | ||
259 | * Hameg HO820 and HO870 interface (using VID 0x0403) | ||
260 | */ | ||
261 | #define HAMEG_HO820_PID 0xed74 | ||
262 | #define HAMEG_HO870_PID 0xed71 | ||
263 | |||
264 | /* | ||
265 | * MaxStream devices www.maxstream.net | ||
266 | */ | ||
267 | #define FTDI_MAXSTREAM_PID 0xEE18 /* Xbee PKG-U Module */ | ||
268 | |||
269 | /* | ||
270 | * microHAM product IDs (http://www.microham.com). | ||
271 | * Submitted by Justin Burket (KL1RL) <zorton@jtan.com> | ||
272 | * and Mike Studer (K6EEP) <k6eep@hamsoftware.org>. | ||
273 | * Ian Abbott <abbotti@mev.co.uk> added a few more from the driver INF file. | ||
274 | */ | ||
275 | #define FTDI_MHAM_KW_PID 0xEEE8 /* USB-KW interface */ | ||
276 | #define FTDI_MHAM_YS_PID 0xEEE9 /* USB-YS interface */ | ||
277 | #define FTDI_MHAM_Y6_PID 0xEEEA /* USB-Y6 interface */ | ||
278 | #define FTDI_MHAM_Y8_PID 0xEEEB /* USB-Y8 interface */ | ||
279 | #define FTDI_MHAM_IC_PID 0xEEEC /* USB-IC interface */ | ||
280 | #define FTDI_MHAM_DB9_PID 0xEEED /* USB-DB9 interface */ | ||
281 | #define FTDI_MHAM_RS232_PID 0xEEEE /* USB-RS232 interface */ | ||
282 | #define FTDI_MHAM_Y9_PID 0xEEEF /* USB-Y9 interface */ | ||
283 | |||
284 | /* Domintell products http://www.domintell.com */ | ||
285 | #define FTDI_DOMINTELL_DGQG_PID 0xEF50 /* Master */ | ||
286 | #define FTDI_DOMINTELL_DUSB_PID 0xEF51 /* DUSB01 module */ | ||
287 | |||
288 | /* | ||
289 | * The following are the values for the Perle Systems | ||
290 | * UltraPort USB serial converters | ||
291 | */ | ||
292 | #define FTDI_PERLE_ULTRAPORT_PID 0xF0C0 /* Perle UltraPort Product Id */ | ||
293 | |||
294 | /* Sprog II (Andrew Crosland's SprogII DCC interface) */ | ||
295 | #define FTDI_SPROG_II 0xF0C8 | ||
296 | |||
297 | /* an infrared receiver for user access control with IR tags */ | ||
298 | #define FTDI_PIEGROUP_PID 0xF208 /* Product Id */ | ||
299 | |||
300 | /* ACT Solutions HomePro ZWave interface | ||
301 | (http://www.act-solutions.com/HomePro.htm) */ | ||
302 | #define FTDI_ACTZWAVE_PID 0xF2D0 | ||
303 | |||
304 | /* | ||
305 | * 4N-GALAXY.DE PIDs for CAN-USB, USB-RS232, USB-RS422, USB-RS485, | ||
306 | * USB-TTY activ, USB-TTY passiv. Some PIDs are used by several devices | ||
307 | * and I'm not entirely sure which are used by which. | ||
308 | */ | ||
309 | #define FTDI_4N_GALAXY_DE_1_PID 0xF3C0 | ||
310 | #define FTDI_4N_GALAXY_DE_2_PID 0xF3C1 | ||
311 | |||
312 | /* | ||
313 | * Linx Technologies product ids | ||
314 | */ | ||
315 | #define LINX_SDMUSBQSS_PID 0xF448 /* Linx SDM-USB-QS-S */ | ||
316 | #define LINX_MASTERDEVEL2_PID 0xF449 /* Linx Master Development 2.0 */ | ||
317 | #define LINX_FUTURE_0_PID 0xF44A /* Linx future device */ | ||
318 | #define LINX_FUTURE_1_PID 0xF44B /* Linx future device */ | ||
319 | #define LINX_FUTURE_2_PID 0xF44C /* Linx future device */ | ||
320 | |||
321 | /* | ||
322 | * Oceanic product ids | ||
323 | */ | ||
324 | #define FTDI_OCEANIC_PID 0xF460 /* Oceanic dive instrument */ | ||
325 | |||
326 | /* | ||
327 | * SUUNTO product ids | ||
328 | */ | ||
329 | #define FTDI_SUUNTO_SPORTS_PID 0xF680 /* Suunto Sports instrument */ | ||
330 | |||
331 | /* USB-UIRT - An infrared receiver and transmitter using the 8U232AM chip */ | ||
332 | /* http://home.earthlink.net/~jrhees/USBUIRT/index.htm */ | ||
333 | #define FTDI_USB_UIRT_PID 0xF850 /* Product Id */ | ||
334 | |||
335 | /* CCS Inc. ICDU/ICDU40 product ID - | ||
336 | * the FT232BM is used in an in-circuit-debugger unit for PIC16's/PIC18's */ | ||
337 | #define FTDI_CCSICDU20_0_PID 0xF9D0 | ||
338 | #define FTDI_CCSICDU40_1_PID 0xF9D1 | ||
339 | #define FTDI_CCSMACHX_2_PID 0xF9D2 | ||
340 | #define FTDI_CCSLOAD_N_GO_3_PID 0xF9D3 | ||
341 | #define FTDI_CCSICDU64_4_PID 0xF9D4 | ||
342 | #define FTDI_CCSPRIME8_5_PID 0xF9D5 | ||
343 | |||
344 | /* | ||
345 | * The following are the values for the Matrix Orbital LCD displays, | ||
346 | * which are the FT232BM ( similar to the 8U232AM ) | ||
347 | */ | ||
348 | #define FTDI_MTXORB_0_PID 0xFA00 /* Matrix Orbital Product Id */ | ||
349 | #define FTDI_MTXORB_1_PID 0xFA01 /* Matrix Orbital Product Id */ | ||
350 | #define FTDI_MTXORB_2_PID 0xFA02 /* Matrix Orbital Product Id */ | ||
351 | #define FTDI_MTXORB_3_PID 0xFA03 /* Matrix Orbital Product Id */ | ||
352 | #define FTDI_MTXORB_4_PID 0xFA04 /* Matrix Orbital Product Id */ | ||
353 | #define FTDI_MTXORB_5_PID 0xFA05 /* Matrix Orbital Product Id */ | ||
354 | #define FTDI_MTXORB_6_PID 0xFA06 /* Matrix Orbital Product Id */ | ||
355 | |||
356 | /* | ||
357 | * Home Electronics (www.home-electro.com) USB gadgets | ||
358 | */ | ||
359 | #define FTDI_HE_TIRA1_PID 0xFA78 /* Tira-1 IR transceiver */ | ||
360 | |||
361 | /* Inside Accesso contactless reader (http://www.insidefr.com) */ | ||
362 | #define INSIDE_ACCESSO 0xFAD0 | ||
363 | |||
364 | /* | ||
365 | * ThorLabs USB motor drivers | ||
366 | */ | ||
367 | #define FTDI_THORLABS_PID 0xfaf0 /* ThorLabs USB motor drivers */ | ||
368 | |||
369 | /* | ||
370 | * Protego product ids | ||
371 | */ | ||
372 | #define PROTEGO_SPECIAL_1 0xFC70 /* special/unknown device */ | ||
373 | #define PROTEGO_R2X0 0xFC71 /* R200-USB TRNG unit (R210, R220, and R230) */ | ||
374 | #define PROTEGO_SPECIAL_3 0xFC72 /* special/unknown device */ | ||
375 | #define PROTEGO_SPECIAL_4 0xFC73 /* special/unknown device */ | ||
376 | |||
377 | /* | ||
378 | * DSS-20 Sync Station for Sony Ericsson P800 | ||
379 | */ | ||
380 | #define FTDI_DSS20_PID 0xFC82 | ||
381 | |||
382 | /* www.irtrans.de device */ | ||
383 | #define FTDI_IRTRANS_PID 0xFC60 /* Product Id */ | ||
384 | |||
385 | /* | ||
386 | * RM Michaelides CANview USB (http://www.rmcan.com) (FTDI_VID) | ||
387 | * CAN fieldbus interface adapter, added by port GmbH www.port.de) | ||
388 | * Ian Abbott changed the macro names for consistency. | ||
389 | */ | ||
390 | #define FTDI_RM_CANVIEW_PID 0xfd60 /* Product Id */ | ||
391 | /* www.thoughttechnology.com/ TT-USB provide with procomp use ftdi_sio */ | ||
392 | #define FTDI_TTUSB_PID 0xFF20 /* Product Id */ | ||
393 | |||
394 | #define FTDI_USBX_707_PID 0xF857 /* ADSTech IR Blaster USBX-707 (FTDI_VID) */ | ||
395 | |||
396 | #define FTDI_RELAIS_PID 0xFA10 /* Relais device from Rudolf Gugler */ | ||
397 | |||
398 | /* | ||
399 | * PCDJ use ftdi based dj-controllers. The following PID is | ||
400 | * for their DAC-2 device http://www.pcdjhardware.com/DAC2.asp | ||
401 | * (the VID is the standard ftdi vid (FTDI_VID), PID sent by Wouter Paesen) | ||
402 | */ | ||
403 | #define FTDI_PCDJ_DAC2_PID 0xFA88 | ||
404 | |||
405 | #define FTDI_R2000KU_TRUE_RNG 0xFB80 /* R2000KU TRUE RNG (FTDI_VID) */ | ||
406 | |||
407 | /* | ||
408 | * DIEBOLD BCS SE923 (FTDI_VID) | ||
409 | */ | ||
410 | #define DIEBOLD_BCS_SE923_PID 0xfb99 | ||
411 | |||
412 | /* www.crystalfontz.com devices | ||
413 | * - thanx for providing free devices for evaluation ! | ||
414 | * they use the ftdi chipset for the USB interface | ||
415 | * and the vendor id is the same | ||
416 | */ | ||
417 | #define FTDI_XF_632_PID 0xFC08 /* 632: 16x2 Character Display */ | ||
418 | #define FTDI_XF_634_PID 0xFC09 /* 634: 20x4 Character Display */ | ||
419 | #define FTDI_XF_547_PID 0xFC0A /* 547: Two line Display */ | ||
420 | #define FTDI_XF_633_PID 0xFC0B /* 633: 16x2 Character Display with Keys */ | ||
421 | #define FTDI_XF_631_PID 0xFC0C /* 631: 20x2 Character Display */ | ||
422 | #define FTDI_XF_635_PID 0xFC0D /* 635: 20x4 Character Display */ | ||
423 | #define FTDI_XF_640_PID 0xFC0E /* 640: Two line Display */ | ||
424 | #define FTDI_XF_642_PID 0xFC0F /* 642: Two line Display */ | ||
425 | |||
426 | /* | ||
427 | * Video Networks Limited / Homechoice in the UK use an ftdi-based device | ||
428 | * for their 1Mb broadband internet service. The following PID is exhibited | ||
429 | * by the usb device supplied (the VID is the standard ftdi vid (FTDI_VID) | ||
430 | */ | ||
431 | #define FTDI_VNHCPCUSB_D_PID 0xfe38 /* Product Id */ | ||
432 | |||
433 | /* AlphaMicro Components AMC-232USB01 device (FTDI_VID) */ | ||
434 | #define FTDI_AMC232_PID 0xFF00 /* Product Id */ | ||
435 | |||
436 | /* | ||
437 | * IBS elektronik product ids (FTDI_VID) | ||
438 | * Submitted by Thomas Schleusener | ||
439 | */ | ||
440 | #define FTDI_IBS_US485_PID 0xff38 /* IBS US485 (USB<-->RS422/485 interface) */ | ||
441 | #define FTDI_IBS_PICPRO_PID 0xff39 /* IBS PIC-Programmer */ | ||
442 | #define FTDI_IBS_PCMCIA_PID 0xff3a /* IBS Card reader for PCMCIA SRAM-cards */ | ||
443 | #define FTDI_IBS_PK1_PID 0xff3b /* IBS PK1 - Particel counter */ | ||
444 | #define FTDI_IBS_RS232MON_PID 0xff3c /* IBS RS232 - Monitor */ | ||
445 | #define FTDI_IBS_APP70_PID 0xff3d /* APP 70 (dust monitoring system) */ | ||
446 | #define FTDI_IBS_PEDO_PID 0xff3e /* IBS PEDO-Modem (RF modem 868.35 MHz) */ | ||
447 | #define FTDI_IBS_PROD_PID 0xff3f /* future device */ | ||
448 | /* www.canusb.com Lawicel CANUSB device (FTDI_VID) */ | ||
449 | #define FTDI_CANUSB_PID 0xFFA8 /* Product Id */ | ||
450 | |||
451 | |||
452 | |||
453 | /********************************/ | ||
454 | /** third-party VID/PID combos **/ | ||
455 | /********************************/ | ||
456 | |||
457 | |||
458 | |||
459 | /* | ||
460 | * Atmel STK541 | ||
461 | */ | ||
462 | #define ATMEL_VID 0x03eb /* Vendor ID */ | ||
463 | #define STK541_PID 0x2109 /* Zigbee Controller */ | ||
464 | |||
465 | /* | ||
466 | * Blackfin gnICE JTAG | ||
467 | * http://docs.blackfin.uclinux.org/doku.php?id=hw:jtag:gnice | ||
468 | */ | ||
469 | #define ADI_VID 0x0456 | ||
470 | #define ADI_GNICE_PID 0xF000 | ||
471 | #define ADI_GNICEPLUS_PID 0xF001 | ||
472 | |||
473 | /* | ||
474 | * RATOC REX-USB60F | ||
475 | */ | ||
476 | #define RATOC_VENDOR_ID 0x0584 | ||
477 | #define RATOC_PRODUCT_ID_USB60F 0xb020 | ||
478 | |||
479 | /* | ||
480 | * Definitions for B&B Electronics products. | ||
481 | */ | ||
482 | #define BANDB_VID 0x0856 /* B&B Electronics Vendor ID */ | ||
483 | #define BANDB_USOTL4_PID 0xAC01 /* USOTL4 Isolated RS-485 Converter */ | ||
484 | #define BANDB_USTL4_PID 0xAC02 /* USTL4 RS-485 Converter */ | ||
485 | #define BANDB_USO9ML2_PID 0xAC03 /* USO9ML2 Isolated RS-232 Converter */ | ||
486 | #define BANDB_USOPTL4_PID 0xAC11 | ||
487 | #define BANDB_USPTL4_PID 0xAC12 | ||
488 | #define BANDB_USO9ML2DR_2_PID 0xAC16 | ||
489 | #define BANDB_USO9ML2DR_PID 0xAC17 | ||
490 | #define BANDB_USOPTL4DR2_PID 0xAC18 /* USOPTL4R-2 2-port Isolated RS-232 Converter */ | ||
491 | #define BANDB_USOPTL4DR_PID 0xAC19 | ||
492 | #define BANDB_485USB9F_2W_PID 0xAC25 | ||
493 | #define BANDB_485USB9F_4W_PID 0xAC26 | ||
494 | #define BANDB_232USB9M_PID 0xAC27 | ||
495 | #define BANDB_485USBTB_2W_PID 0xAC33 | ||
496 | #define BANDB_485USBTB_4W_PID 0xAC34 | ||
497 | #define BANDB_TTL5USB9M_PID 0xAC49 | ||
498 | #define BANDB_TTL3USB9M_PID 0xAC50 | ||
499 | #define BANDB_ZZ_PROG1_USB_PID 0xBA02 | ||
500 | |||
501 | /* | ||
502 | * Intrepid Control Systems (http://www.intrepidcs.com/) ValueCAN and NeoVI | ||
503 | */ | ||
504 | #define INTREPID_VID 0x093C | ||
505 | #define INTREPID_VALUECAN_PID 0x0601 | ||
506 | #define INTREPID_NEOVI_PID 0x0701 | ||
507 | |||
508 | /* | ||
509 | * Definitions for ID TECH (www.idt-net.com) devices | ||
510 | */ | ||
511 | #define IDTECH_VID 0x0ACD /* ID TECH Vendor ID */ | ||
512 | #define IDTECH_IDT1221U_PID 0x0300 /* IDT1221U USB to RS-232 adapter */ | ||
513 | |||
514 | /* | ||
515 | * Definitions for Omnidirectional Control Technology, Inc. devices | ||
516 | */ | ||
517 | #define OCT_VID 0x0B39 /* OCT vendor ID */ | ||
518 | /* Note: OCT US101 is also rebadged as Dick Smith Electronics (NZ) XH6381 */ | ||
519 | /* Also rebadged as Dick Smith Electronics (Aus) XH6451 */ | ||
520 | /* Also rebadged as SIIG Inc. model US2308 hardware version 1 */ | ||
521 | #define OCT_US101_PID 0x0421 /* OCT US101 USB to RS-232 */ | ||
522 | |||
523 | /* | ||
524 | * Icom ID-1 digital transceiver | ||
525 | */ | ||
526 | |||
527 | #define ICOM_ID1_VID 0x0C26 | ||
528 | #define ICOM_ID1_PID 0x0004 | ||
529 | |||
530 | /* | ||
531 | * GN Otometrics (http://www.otometrics.com) | ||
532 | * Submitted by Ville Sundberg. | ||
533 | */ | ||
534 | #define GN_OTOMETRICS_VID 0x0c33 /* Vendor ID */ | ||
535 | #define AURICAL_USB_PID 0x0010 /* Aurical USB Audiometer */ | ||
536 | |||
537 | /* | ||
538 | * The following are the values for the Sealevel SeaLINK+ adapters. | ||
539 | * (Original list sent by Tuan Hoang. Ian Abbott renamed the macros and | ||
540 | * removed some PIDs that don't seem to match any existing products.) | ||
541 | */ | ||
542 | #define SEALEVEL_VID 0x0c52 /* Sealevel Vendor ID */ | ||
543 | #define SEALEVEL_2101_PID 0x2101 /* SeaLINK+232 (2101/2105) */ | ||
544 | #define SEALEVEL_2102_PID 0x2102 /* SeaLINK+485 (2102) */ | ||
545 | #define SEALEVEL_2103_PID 0x2103 /* SeaLINK+232I (2103) */ | ||
546 | #define SEALEVEL_2104_PID 0x2104 /* SeaLINK+485I (2104) */ | ||
547 | #define SEALEVEL_2106_PID 0x9020 /* SeaLINK+422 (2106) */ | ||
548 | #define SEALEVEL_2201_1_PID 0x2211 /* SeaPORT+2/232 (2201) Port 1 */ | ||
549 | #define SEALEVEL_2201_2_PID 0x2221 /* SeaPORT+2/232 (2201) Port 2 */ | ||
550 | #define SEALEVEL_2202_1_PID 0x2212 /* SeaPORT+2/485 (2202) Port 1 */ | ||
551 | #define SEALEVEL_2202_2_PID 0x2222 /* SeaPORT+2/485 (2202) Port 2 */ | ||
552 | #define SEALEVEL_2203_1_PID 0x2213 /* SeaPORT+2 (2203) Port 1 */ | ||
553 | #define SEALEVEL_2203_2_PID 0x2223 /* SeaPORT+2 (2203) Port 2 */ | ||
554 | #define SEALEVEL_2401_1_PID 0x2411 /* SeaPORT+4/232 (2401) Port 1 */ | ||
555 | #define SEALEVEL_2401_2_PID 0x2421 /* SeaPORT+4/232 (2401) Port 2 */ | ||
556 | #define SEALEVEL_2401_3_PID 0x2431 /* SeaPORT+4/232 (2401) Port 3 */ | ||
557 | #define SEALEVEL_2401_4_PID 0x2441 /* SeaPORT+4/232 (2401) Port 4 */ | ||
558 | #define SEALEVEL_2402_1_PID 0x2412 /* SeaPORT+4/485 (2402) Port 1 */ | ||
559 | #define SEALEVEL_2402_2_PID 0x2422 /* SeaPORT+4/485 (2402) Port 2 */ | ||
560 | #define SEALEVEL_2402_3_PID 0x2432 /* SeaPORT+4/485 (2402) Port 3 */ | ||
561 | #define SEALEVEL_2402_4_PID 0x2442 /* SeaPORT+4/485 (2402) Port 4 */ | ||
562 | #define SEALEVEL_2403_1_PID 0x2413 /* SeaPORT+4 (2403) Port 1 */ | ||
563 | #define SEALEVEL_2403_2_PID 0x2423 /* SeaPORT+4 (2403) Port 2 */ | ||
564 | #define SEALEVEL_2403_3_PID 0x2433 /* SeaPORT+4 (2403) Port 3 */ | ||
565 | #define SEALEVEL_2403_4_PID 0x2443 /* SeaPORT+4 (2403) Port 4 */ | ||
566 | #define SEALEVEL_2801_1_PID 0X2811 /* SeaLINK+8/232 (2801) Port 1 */ | ||
567 | #define SEALEVEL_2801_2_PID 0X2821 /* SeaLINK+8/232 (2801) Port 2 */ | ||
568 | #define SEALEVEL_2801_3_PID 0X2831 /* SeaLINK+8/232 (2801) Port 3 */ | ||
569 | #define SEALEVEL_2801_4_PID 0X2841 /* SeaLINK+8/232 (2801) Port 4 */ | ||
570 | #define SEALEVEL_2801_5_PID 0X2851 /* SeaLINK+8/232 (2801) Port 5 */ | ||
571 | #define SEALEVEL_2801_6_PID 0X2861 /* SeaLINK+8/232 (2801) Port 6 */ | ||
572 | #define SEALEVEL_2801_7_PID 0X2871 /* SeaLINK+8/232 (2801) Port 7 */ | ||
573 | #define SEALEVEL_2801_8_PID 0X2881 /* SeaLINK+8/232 (2801) Port 8 */ | ||
574 | #define SEALEVEL_2802_1_PID 0X2812 /* SeaLINK+8/485 (2802) Port 1 */ | ||
575 | #define SEALEVEL_2802_2_PID 0X2822 /* SeaLINK+8/485 (2802) Port 2 */ | ||
576 | #define SEALEVEL_2802_3_PID 0X2832 /* SeaLINK+8/485 (2802) Port 3 */ | ||
577 | #define SEALEVEL_2802_4_PID 0X2842 /* SeaLINK+8/485 (2802) Port 4 */ | ||
578 | #define SEALEVEL_2802_5_PID 0X2852 /* SeaLINK+8/485 (2802) Port 5 */ | ||
579 | #define SEALEVEL_2802_6_PID 0X2862 /* SeaLINK+8/485 (2802) Port 6 */ | ||
580 | #define SEALEVEL_2802_7_PID 0X2872 /* SeaLINK+8/485 (2802) Port 7 */ | ||
581 | #define SEALEVEL_2802_8_PID 0X2882 /* SeaLINK+8/485 (2802) Port 8 */ | ||
582 | #define SEALEVEL_2803_1_PID 0X2813 /* SeaLINK+8 (2803) Port 1 */ | ||
583 | #define SEALEVEL_2803_2_PID 0X2823 /* SeaLINK+8 (2803) Port 2 */ | ||
584 | #define SEALEVEL_2803_3_PID 0X2833 /* SeaLINK+8 (2803) Port 3 */ | ||
585 | #define SEALEVEL_2803_4_PID 0X2843 /* SeaLINK+8 (2803) Port 4 */ | ||
586 | #define SEALEVEL_2803_5_PID 0X2853 /* SeaLINK+8 (2803) Port 5 */ | ||
587 | #define SEALEVEL_2803_6_PID 0X2863 /* SeaLINK+8 (2803) Port 6 */ | ||
588 | #define SEALEVEL_2803_7_PID 0X2873 /* SeaLINK+8 (2803) Port 7 */ | ||
589 | #define SEALEVEL_2803_8_PID 0X2883 /* SeaLINK+8 (2803) Port 8 */ | ||
590 | |||
591 | /* | ||
592 | * JETI SPECTROMETER SPECBOS 1201 | ||
593 | * http://www.jeti.com/products/sys/scb/scb1201.php | ||
594 | */ | ||
595 | #define JETI_VID 0x0c6c | ||
596 | #define JETI_SPC1201_PID 0x04b2 | ||
597 | |||
598 | /* | ||
599 | * FTDI USB UART chips used in construction projects from the | ||
600 | * Elektor Electronics magazine (http://elektor-electronics.co.uk) | ||
601 | */ | ||
602 | #define ELEKTOR_VID 0x0C7D | ||
603 | #define ELEKTOR_FT323R_PID 0x0005 /* RFID-Reader, issue 09-2006 */ | ||
604 | |||
605 | /* | ||
606 | * Posiflex inc retail equipment (http://www.posiflex.com.tw) | ||
607 | */ | ||
608 | #define POSIFLEX_VID 0x0d3a /* Vendor ID */ | ||
609 | #define POSIFLEX_PP7000_PID 0x0300 /* PP-7000II thermal printer */ | ||
610 | |||
611 | /* | ||
612 | * The following are the values for two KOBIL chipcard terminals. | ||
613 | */ | ||
614 | #define KOBIL_VID 0x0d46 /* KOBIL Vendor ID */ | ||
615 | #define KOBIL_CONV_B1_PID 0x2020 /* KOBIL Konverter for B1 */ | ||
616 | #define KOBIL_CONV_KAAN_PID 0x2021 /* KOBIL_Konverter for KAAN */ | ||
617 | |||
618 | #define FTDI_NF_RIC_VID 0x0DCD /* Vendor Id */ | ||
619 | #define FTDI_NF_RIC_PID 0x0001 /* Product Id */ | ||
620 | |||
621 | /* | ||
622 | * Falcom Wireless Communications GmbH | ||
623 | */ | ||
624 | #define FALCOM_VID 0x0F94 /* Vendor Id */ | ||
625 | #define FALCOM_TWIST_PID 0x0001 /* Falcom Twist USB GPRS modem */ | ||
626 | #define FALCOM_SAMBA_PID 0x0005 /* Falcom Samba USB GPRS modem */ | ||
627 | |||
628 | /* Larsen and Brusgaard AltiTrack/USBtrack */ | ||
629 | #define LARSENBRUSGAARD_VID 0x0FD8 | ||
630 | #define LB_ALTITRACK_PID 0x0001 | ||
631 | |||
632 | /* | ||
633 | * TTi (Thurlby Thandar Instruments) | ||
634 | */ | ||
635 | #define TTI_VID 0x103E /* Vendor Id */ | ||
636 | #define TTI_QL355P_PID 0x03E8 /* TTi QL355P power supply */ | ||
637 | |||
638 | /* Interbiometrics USB I/O Board */ | ||
639 | /* Developed for Interbiometrics by Rudolf Gugler */ | ||
640 | #define INTERBIOMETRICS_VID 0x1209 | ||
641 | #define INTERBIOMETRICS_IOBOARD_PID 0x1002 | ||
642 | #define INTERBIOMETRICS_MINI_IOBOARD_PID 0x1006 | ||
643 | |||
644 | /* | ||
645 | * Testo products (http://www.testo.com/) | ||
646 | * Submitted by Colin Leroy | ||
647 | */ | ||
648 | #define TESTO_VID 0x128D | ||
649 | #define TESTO_USB_INTERFACE_PID 0x0001 | ||
650 | |||
651 | /* | ||
652 | * Mobility Electronics products. | ||
653 | */ | ||
654 | #define MOBILITY_VID 0x1342 | ||
655 | #define MOBILITY_USB_SERIAL_PID 0x0202 /* EasiDock USB 200 serial */ | ||
656 | |||
657 | /* | ||
658 | * FIC / OpenMoko, Inc. http://wiki.openmoko.org/wiki/Neo1973_Debug_Board_v3 | ||
659 | * Submitted by Harald Welte <laforge@openmoko.org> | ||
660 | */ | ||
661 | #define FIC_VID 0x1457 | ||
662 | #define FIC_NEO1973_DEBUG_PID 0x5118 | ||
663 | |||
664 | /* Olimex */ | ||
665 | #define OLIMEX_VID 0x15BA | ||
666 | #define OLIMEX_ARM_USB_OCD_PID 0x0003 | ||
667 | |||
668 | /* | ||
669 | * Telldus Technologies | ||
670 | */ | ||
671 | #define TELLDUS_VID 0x1781 /* Vendor ID */ | ||
672 | #define TELLDUS_TELLSTICK_PID 0x0C30 /* RF control dongle 433 MHz using FT232RL */ | ||
673 | |||
674 | /* | ||
675 | * Bayer Ascensia Contour blood glucose meter USB-converter cable. | ||
676 | * http://winglucofacts.com/cables/ | ||
677 | */ | ||
678 | #define BAYER_VID 0x1A79 | ||
679 | #define BAYER_CONTOUR_CABLE_PID 0x6001 | ||
680 | |||
681 | /* | ||
682 | * The following are the values for the Matrix Orbital FTDI Range | ||
683 | * Anything in this range will use an FT232RL. | ||
684 | */ | ||
685 | #define MTXORB_VID 0x1B3D | ||
686 | #define MTXORB_FTDI_RANGE_0100_PID 0x0100 | ||
687 | #define MTXORB_FTDI_RANGE_0101_PID 0x0101 | ||
688 | #define MTXORB_FTDI_RANGE_0102_PID 0x0102 | ||
689 | #define MTXORB_FTDI_RANGE_0103_PID 0x0103 | ||
690 | #define MTXORB_FTDI_RANGE_0104_PID 0x0104 | ||
691 | #define MTXORB_FTDI_RANGE_0105_PID 0x0105 | ||
692 | #define MTXORB_FTDI_RANGE_0106_PID 0x0106 | ||
693 | #define MTXORB_FTDI_RANGE_0107_PID 0x0107 | ||
694 | #define MTXORB_FTDI_RANGE_0108_PID 0x0108 | ||
695 | #define MTXORB_FTDI_RANGE_0109_PID 0x0109 | ||
696 | #define MTXORB_FTDI_RANGE_010A_PID 0x010A | ||
697 | #define MTXORB_FTDI_RANGE_010B_PID 0x010B | ||
698 | #define MTXORB_FTDI_RANGE_010C_PID 0x010C | ||
699 | #define MTXORB_FTDI_RANGE_010D_PID 0x010D | ||
700 | #define MTXORB_FTDI_RANGE_010E_PID 0x010E | ||
701 | #define MTXORB_FTDI_RANGE_010F_PID 0x010F | ||
702 | #define MTXORB_FTDI_RANGE_0110_PID 0x0110 | ||
703 | #define MTXORB_FTDI_RANGE_0111_PID 0x0111 | ||
704 | #define MTXORB_FTDI_RANGE_0112_PID 0x0112 | ||
705 | #define MTXORB_FTDI_RANGE_0113_PID 0x0113 | ||
706 | #define MTXORB_FTDI_RANGE_0114_PID 0x0114 | ||
707 | #define MTXORB_FTDI_RANGE_0115_PID 0x0115 | ||
708 | #define MTXORB_FTDI_RANGE_0116_PID 0x0116 | ||
709 | #define MTXORB_FTDI_RANGE_0117_PID 0x0117 | ||
710 | #define MTXORB_FTDI_RANGE_0118_PID 0x0118 | ||
711 | #define MTXORB_FTDI_RANGE_0119_PID 0x0119 | ||
712 | #define MTXORB_FTDI_RANGE_011A_PID 0x011A | ||
713 | #define MTXORB_FTDI_RANGE_011B_PID 0x011B | ||
714 | #define MTXORB_FTDI_RANGE_011C_PID 0x011C | ||
715 | #define MTXORB_FTDI_RANGE_011D_PID 0x011D | ||
716 | #define MTXORB_FTDI_RANGE_011E_PID 0x011E | ||
717 | #define MTXORB_FTDI_RANGE_011F_PID 0x011F | ||
718 | #define MTXORB_FTDI_RANGE_0120_PID 0x0120 | ||
719 | #define MTXORB_FTDI_RANGE_0121_PID 0x0121 | ||
720 | #define MTXORB_FTDI_RANGE_0122_PID 0x0122 | ||
721 | #define MTXORB_FTDI_RANGE_0123_PID 0x0123 | ||
722 | #define MTXORB_FTDI_RANGE_0124_PID 0x0124 | ||
723 | #define MTXORB_FTDI_RANGE_0125_PID 0x0125 | ||
724 | #define MTXORB_FTDI_RANGE_0126_PID 0x0126 | ||
725 | #define MTXORB_FTDI_RANGE_0127_PID 0x0127 | ||
726 | #define MTXORB_FTDI_RANGE_0128_PID 0x0128 | ||
727 | #define MTXORB_FTDI_RANGE_0129_PID 0x0129 | ||
728 | #define MTXORB_FTDI_RANGE_012A_PID 0x012A | ||
729 | #define MTXORB_FTDI_RANGE_012B_PID 0x012B | ||
730 | #define MTXORB_FTDI_RANGE_012C_PID 0x012C | ||
731 | #define MTXORB_FTDI_RANGE_012D_PID 0x012D | ||
732 | #define MTXORB_FTDI_RANGE_012E_PID 0x012E | ||
733 | #define MTXORB_FTDI_RANGE_012F_PID 0x012F | ||
734 | #define MTXORB_FTDI_RANGE_0130_PID 0x0130 | ||
735 | #define MTXORB_FTDI_RANGE_0131_PID 0x0131 | ||
736 | #define MTXORB_FTDI_RANGE_0132_PID 0x0132 | ||
737 | #define MTXORB_FTDI_RANGE_0133_PID 0x0133 | ||
738 | #define MTXORB_FTDI_RANGE_0134_PID 0x0134 | ||
739 | #define MTXORB_FTDI_RANGE_0135_PID 0x0135 | ||
740 | #define MTXORB_FTDI_RANGE_0136_PID 0x0136 | ||
741 | #define MTXORB_FTDI_RANGE_0137_PID 0x0137 | ||
742 | #define MTXORB_FTDI_RANGE_0138_PID 0x0138 | ||
743 | #define MTXORB_FTDI_RANGE_0139_PID 0x0139 | ||
744 | #define MTXORB_FTDI_RANGE_013A_PID 0x013A | ||
745 | #define MTXORB_FTDI_RANGE_013B_PID 0x013B | ||
746 | #define MTXORB_FTDI_RANGE_013C_PID 0x013C | ||
747 | #define MTXORB_FTDI_RANGE_013D_PID 0x013D | ||
748 | #define MTXORB_FTDI_RANGE_013E_PID 0x013E | ||
749 | #define MTXORB_FTDI_RANGE_013F_PID 0x013F | ||
750 | #define MTXORB_FTDI_RANGE_0140_PID 0x0140 | ||
751 | #define MTXORB_FTDI_RANGE_0141_PID 0x0141 | ||
752 | #define MTXORB_FTDI_RANGE_0142_PID 0x0142 | ||
753 | #define MTXORB_FTDI_RANGE_0143_PID 0x0143 | ||
754 | #define MTXORB_FTDI_RANGE_0144_PID 0x0144 | ||
755 | #define MTXORB_FTDI_RANGE_0145_PID 0x0145 | ||
756 | #define MTXORB_FTDI_RANGE_0146_PID 0x0146 | ||
757 | #define MTXORB_FTDI_RANGE_0147_PID 0x0147 | ||
758 | #define MTXORB_FTDI_RANGE_0148_PID 0x0148 | ||
759 | #define MTXORB_FTDI_RANGE_0149_PID 0x0149 | ||
760 | #define MTXORB_FTDI_RANGE_014A_PID 0x014A | ||
761 | #define MTXORB_FTDI_RANGE_014B_PID 0x014B | ||
762 | #define MTXORB_FTDI_RANGE_014C_PID 0x014C | ||
763 | #define MTXORB_FTDI_RANGE_014D_PID 0x014D | ||
764 | #define MTXORB_FTDI_RANGE_014E_PID 0x014E | ||
765 | #define MTXORB_FTDI_RANGE_014F_PID 0x014F | ||
766 | #define MTXORB_FTDI_RANGE_0150_PID 0x0150 | ||
767 | #define MTXORB_FTDI_RANGE_0151_PID 0x0151 | ||
768 | #define MTXORB_FTDI_RANGE_0152_PID 0x0152 | ||
769 | #define MTXORB_FTDI_RANGE_0153_PID 0x0153 | ||
770 | #define MTXORB_FTDI_RANGE_0154_PID 0x0154 | ||
771 | #define MTXORB_FTDI_RANGE_0155_PID 0x0155 | ||
772 | #define MTXORB_FTDI_RANGE_0156_PID 0x0156 | ||
773 | #define MTXORB_FTDI_RANGE_0157_PID 0x0157 | ||
774 | #define MTXORB_FTDI_RANGE_0158_PID 0x0158 | ||
775 | #define MTXORB_FTDI_RANGE_0159_PID 0x0159 | ||
776 | #define MTXORB_FTDI_RANGE_015A_PID 0x015A | ||
777 | #define MTXORB_FTDI_RANGE_015B_PID 0x015B | ||
778 | #define MTXORB_FTDI_RANGE_015C_PID 0x015C | ||
779 | #define MTXORB_FTDI_RANGE_015D_PID 0x015D | ||
780 | #define MTXORB_FTDI_RANGE_015E_PID 0x015E | ||
781 | #define MTXORB_FTDI_RANGE_015F_PID 0x015F | ||
782 | #define MTXORB_FTDI_RANGE_0160_PID 0x0160 | ||
783 | #define MTXORB_FTDI_RANGE_0161_PID 0x0161 | ||
784 | #define MTXORB_FTDI_RANGE_0162_PID 0x0162 | ||
785 | #define MTXORB_FTDI_RANGE_0163_PID 0x0163 | ||
786 | #define MTXORB_FTDI_RANGE_0164_PID 0x0164 | ||
787 | #define MTXORB_FTDI_RANGE_0165_PID 0x0165 | ||
788 | #define MTXORB_FTDI_RANGE_0166_PID 0x0166 | ||
789 | #define MTXORB_FTDI_RANGE_0167_PID 0x0167 | ||
790 | #define MTXORB_FTDI_RANGE_0168_PID 0x0168 | ||
791 | #define MTXORB_FTDI_RANGE_0169_PID 0x0169 | ||
792 | #define MTXORB_FTDI_RANGE_016A_PID 0x016A | ||
793 | #define MTXORB_FTDI_RANGE_016B_PID 0x016B | ||
794 | #define MTXORB_FTDI_RANGE_016C_PID 0x016C | ||
795 | #define MTXORB_FTDI_RANGE_016D_PID 0x016D | ||
796 | #define MTXORB_FTDI_RANGE_016E_PID 0x016E | ||
797 | #define MTXORB_FTDI_RANGE_016F_PID 0x016F | ||
798 | #define MTXORB_FTDI_RANGE_0170_PID 0x0170 | ||
799 | #define MTXORB_FTDI_RANGE_0171_PID 0x0171 | ||
800 | #define MTXORB_FTDI_RANGE_0172_PID 0x0172 | ||
801 | #define MTXORB_FTDI_RANGE_0173_PID 0x0173 | ||
802 | #define MTXORB_FTDI_RANGE_0174_PID 0x0174 | ||
803 | #define MTXORB_FTDI_RANGE_0175_PID 0x0175 | ||
804 | #define MTXORB_FTDI_RANGE_0176_PID 0x0176 | ||
805 | #define MTXORB_FTDI_RANGE_0177_PID 0x0177 | ||
806 | #define MTXORB_FTDI_RANGE_0178_PID 0x0178 | ||
807 | #define MTXORB_FTDI_RANGE_0179_PID 0x0179 | ||
808 | #define MTXORB_FTDI_RANGE_017A_PID 0x017A | ||
809 | #define MTXORB_FTDI_RANGE_017B_PID 0x017B | ||
810 | #define MTXORB_FTDI_RANGE_017C_PID 0x017C | ||
811 | #define MTXORB_FTDI_RANGE_017D_PID 0x017D | ||
812 | #define MTXORB_FTDI_RANGE_017E_PID 0x017E | ||
813 | #define MTXORB_FTDI_RANGE_017F_PID 0x017F | ||
814 | #define MTXORB_FTDI_RANGE_0180_PID 0x0180 | ||
815 | #define MTXORB_FTDI_RANGE_0181_PID 0x0181 | ||
816 | #define MTXORB_FTDI_RANGE_0182_PID 0x0182 | ||
817 | #define MTXORB_FTDI_RANGE_0183_PID 0x0183 | ||
818 | #define MTXORB_FTDI_RANGE_0184_PID 0x0184 | ||
819 | #define MTXORB_FTDI_RANGE_0185_PID 0x0185 | ||
820 | #define MTXORB_FTDI_RANGE_0186_PID 0x0186 | ||
821 | #define MTXORB_FTDI_RANGE_0187_PID 0x0187 | ||
822 | #define MTXORB_FTDI_RANGE_0188_PID 0x0188 | ||
823 | #define MTXORB_FTDI_RANGE_0189_PID 0x0189 | ||
824 | #define MTXORB_FTDI_RANGE_018A_PID 0x018A | ||
825 | #define MTXORB_FTDI_RANGE_018B_PID 0x018B | ||
826 | #define MTXORB_FTDI_RANGE_018C_PID 0x018C | ||
827 | #define MTXORB_FTDI_RANGE_018D_PID 0x018D | ||
828 | #define MTXORB_FTDI_RANGE_018E_PID 0x018E | ||
829 | #define MTXORB_FTDI_RANGE_018F_PID 0x018F | ||
830 | #define MTXORB_FTDI_RANGE_0190_PID 0x0190 | ||
831 | #define MTXORB_FTDI_RANGE_0191_PID 0x0191 | ||
832 | #define MTXORB_FTDI_RANGE_0192_PID 0x0192 | ||
833 | #define MTXORB_FTDI_RANGE_0193_PID 0x0193 | ||
834 | #define MTXORB_FTDI_RANGE_0194_PID 0x0194 | ||
835 | #define MTXORB_FTDI_RANGE_0195_PID 0x0195 | ||
836 | #define MTXORB_FTDI_RANGE_0196_PID 0x0196 | ||
837 | #define MTXORB_FTDI_RANGE_0197_PID 0x0197 | ||
838 | #define MTXORB_FTDI_RANGE_0198_PID 0x0198 | ||
839 | #define MTXORB_FTDI_RANGE_0199_PID 0x0199 | ||
840 | #define MTXORB_FTDI_RANGE_019A_PID 0x019A | ||
841 | #define MTXORB_FTDI_RANGE_019B_PID 0x019B | ||
842 | #define MTXORB_FTDI_RANGE_019C_PID 0x019C | ||
843 | #define MTXORB_FTDI_RANGE_019D_PID 0x019D | ||
844 | #define MTXORB_FTDI_RANGE_019E_PID 0x019E | ||
845 | #define MTXORB_FTDI_RANGE_019F_PID 0x019F | ||
846 | #define MTXORB_FTDI_RANGE_01A0_PID 0x01A0 | ||
847 | #define MTXORB_FTDI_RANGE_01A1_PID 0x01A1 | ||
848 | #define MTXORB_FTDI_RANGE_01A2_PID 0x01A2 | ||
849 | #define MTXORB_FTDI_RANGE_01A3_PID 0x01A3 | ||
850 | #define MTXORB_FTDI_RANGE_01A4_PID 0x01A4 | ||
851 | #define MTXORB_FTDI_RANGE_01A5_PID 0x01A5 | ||
852 | #define MTXORB_FTDI_RANGE_01A6_PID 0x01A6 | ||
853 | #define MTXORB_FTDI_RANGE_01A7_PID 0x01A7 | ||
854 | #define MTXORB_FTDI_RANGE_01A8_PID 0x01A8 | ||
855 | #define MTXORB_FTDI_RANGE_01A9_PID 0x01A9 | ||
856 | #define MTXORB_FTDI_RANGE_01AA_PID 0x01AA | ||
857 | #define MTXORB_FTDI_RANGE_01AB_PID 0x01AB | ||
858 | #define MTXORB_FTDI_RANGE_01AC_PID 0x01AC | ||
859 | #define MTXORB_FTDI_RANGE_01AD_PID 0x01AD | ||
860 | #define MTXORB_FTDI_RANGE_01AE_PID 0x01AE | ||
861 | #define MTXORB_FTDI_RANGE_01AF_PID 0x01AF | ||
862 | #define MTXORB_FTDI_RANGE_01B0_PID 0x01B0 | ||
863 | #define MTXORB_FTDI_RANGE_01B1_PID 0x01B1 | ||
864 | #define MTXORB_FTDI_RANGE_01B2_PID 0x01B2 | ||
865 | #define MTXORB_FTDI_RANGE_01B3_PID 0x01B3 | ||
866 | #define MTXORB_FTDI_RANGE_01B4_PID 0x01B4 | ||
867 | #define MTXORB_FTDI_RANGE_01B5_PID 0x01B5 | ||
868 | #define MTXORB_FTDI_RANGE_01B6_PID 0x01B6 | ||
869 | #define MTXORB_FTDI_RANGE_01B7_PID 0x01B7 | ||
870 | #define MTXORB_FTDI_RANGE_01B8_PID 0x01B8 | ||
871 | #define MTXORB_FTDI_RANGE_01B9_PID 0x01B9 | ||
872 | #define MTXORB_FTDI_RANGE_01BA_PID 0x01BA | ||
873 | #define MTXORB_FTDI_RANGE_01BB_PID 0x01BB | ||
874 | #define MTXORB_FTDI_RANGE_01BC_PID 0x01BC | ||
875 | #define MTXORB_FTDI_RANGE_01BD_PID 0x01BD | ||
876 | #define MTXORB_FTDI_RANGE_01BE_PID 0x01BE | ||
877 | #define MTXORB_FTDI_RANGE_01BF_PID 0x01BF | ||
878 | #define MTXORB_FTDI_RANGE_01C0_PID 0x01C0 | ||
879 | #define MTXORB_FTDI_RANGE_01C1_PID 0x01C1 | ||
880 | #define MTXORB_FTDI_RANGE_01C2_PID 0x01C2 | ||
881 | #define MTXORB_FTDI_RANGE_01C3_PID 0x01C3 | ||
882 | #define MTXORB_FTDI_RANGE_01C4_PID 0x01C4 | ||
883 | #define MTXORB_FTDI_RANGE_01C5_PID 0x01C5 | ||
884 | #define MTXORB_FTDI_RANGE_01C6_PID 0x01C6 | ||
885 | #define MTXORB_FTDI_RANGE_01C7_PID 0x01C7 | ||
886 | #define MTXORB_FTDI_RANGE_01C8_PID 0x01C8 | ||
887 | #define MTXORB_FTDI_RANGE_01C9_PID 0x01C9 | ||
888 | #define MTXORB_FTDI_RANGE_01CA_PID 0x01CA | ||
889 | #define MTXORB_FTDI_RANGE_01CB_PID 0x01CB | ||
890 | #define MTXORB_FTDI_RANGE_01CC_PID 0x01CC | ||
891 | #define MTXORB_FTDI_RANGE_01CD_PID 0x01CD | ||
892 | #define MTXORB_FTDI_RANGE_01CE_PID 0x01CE | ||
893 | #define MTXORB_FTDI_RANGE_01CF_PID 0x01CF | ||
894 | #define MTXORB_FTDI_RANGE_01D0_PID 0x01D0 | ||
895 | #define MTXORB_FTDI_RANGE_01D1_PID 0x01D1 | ||
896 | #define MTXORB_FTDI_RANGE_01D2_PID 0x01D2 | ||
897 | #define MTXORB_FTDI_RANGE_01D3_PID 0x01D3 | ||
898 | #define MTXORB_FTDI_RANGE_01D4_PID 0x01D4 | ||
899 | #define MTXORB_FTDI_RANGE_01D5_PID 0x01D5 | ||
900 | #define MTXORB_FTDI_RANGE_01D6_PID 0x01D6 | ||
901 | #define MTXORB_FTDI_RANGE_01D7_PID 0x01D7 | ||
902 | #define MTXORB_FTDI_RANGE_01D8_PID 0x01D8 | ||
903 | #define MTXORB_FTDI_RANGE_01D9_PID 0x01D9 | ||
904 | #define MTXORB_FTDI_RANGE_01DA_PID 0x01DA | ||
905 | #define MTXORB_FTDI_RANGE_01DB_PID 0x01DB | ||
906 | #define MTXORB_FTDI_RANGE_01DC_PID 0x01DC | ||
907 | #define MTXORB_FTDI_RANGE_01DD_PID 0x01DD | ||
908 | #define MTXORB_FTDI_RANGE_01DE_PID 0x01DE | ||
909 | #define MTXORB_FTDI_RANGE_01DF_PID 0x01DF | ||
910 | #define MTXORB_FTDI_RANGE_01E0_PID 0x01E0 | ||
911 | #define MTXORB_FTDI_RANGE_01E1_PID 0x01E1 | ||
912 | #define MTXORB_FTDI_RANGE_01E2_PID 0x01E2 | ||
913 | #define MTXORB_FTDI_RANGE_01E3_PID 0x01E3 | ||
914 | #define MTXORB_FTDI_RANGE_01E4_PID 0x01E4 | ||
915 | #define MTXORB_FTDI_RANGE_01E5_PID 0x01E5 | ||
916 | #define MTXORB_FTDI_RANGE_01E6_PID 0x01E6 | ||
917 | #define MTXORB_FTDI_RANGE_01E7_PID 0x01E7 | ||
918 | #define MTXORB_FTDI_RANGE_01E8_PID 0x01E8 | ||
919 | #define MTXORB_FTDI_RANGE_01E9_PID 0x01E9 | ||
920 | #define MTXORB_FTDI_RANGE_01EA_PID 0x01EA | ||
921 | #define MTXORB_FTDI_RANGE_01EB_PID 0x01EB | ||
922 | #define MTXORB_FTDI_RANGE_01EC_PID 0x01EC | ||
923 | #define MTXORB_FTDI_RANGE_01ED_PID 0x01ED | ||
924 | #define MTXORB_FTDI_RANGE_01EE_PID 0x01EE | ||
925 | #define MTXORB_FTDI_RANGE_01EF_PID 0x01EF | ||
926 | #define MTXORB_FTDI_RANGE_01F0_PID 0x01F0 | ||
927 | #define MTXORB_FTDI_RANGE_01F1_PID 0x01F1 | ||
928 | #define MTXORB_FTDI_RANGE_01F2_PID 0x01F2 | ||
929 | #define MTXORB_FTDI_RANGE_01F3_PID 0x01F3 | ||
930 | #define MTXORB_FTDI_RANGE_01F4_PID 0x01F4 | ||
931 | #define MTXORB_FTDI_RANGE_01F5_PID 0x01F5 | ||
932 | #define MTXORB_FTDI_RANGE_01F6_PID 0x01F6 | ||
933 | #define MTXORB_FTDI_RANGE_01F7_PID 0x01F7 | ||
934 | #define MTXORB_FTDI_RANGE_01F8_PID 0x01F8 | ||
935 | #define MTXORB_FTDI_RANGE_01F9_PID 0x01F9 | ||
936 | #define MTXORB_FTDI_RANGE_01FA_PID 0x01FA | ||
937 | #define MTXORB_FTDI_RANGE_01FB_PID 0x01FB | ||
938 | #define MTXORB_FTDI_RANGE_01FC_PID 0x01FC | ||
939 | #define MTXORB_FTDI_RANGE_01FD_PID 0x01FD | ||
940 | #define MTXORB_FTDI_RANGE_01FE_PID 0x01FE | ||
941 | #define MTXORB_FTDI_RANGE_01FF_PID 0x01FF | ||
942 | |||
943 | |||
944 | |||
945 | /* | ||
946 | * The Mobility Lab (TML) | ||
947 | * Submitted by Pierre Castella | ||
948 | */ | ||
949 | #define TML_VID 0x1B91 /* Vendor ID */ | ||
950 | #define TML_USB_SERIAL_PID 0x0064 /* USB - Serial Converter */ | ||
951 | |||
952 | /* Alti-2 products http://www.alti-2.com */ | ||
953 | #define ALTI2_VID 0x1BC9 | ||
954 | #define ALTI2_N3_PID 0x6001 /* Neptune 3 */ | ||
955 | |||
956 | /* | ||
957 | * Dresden Elektronic Sensor Terminal Board | ||
958 | */ | ||
959 | #define DE_VID 0x1cf1 /* Vendor ID */ | ||
960 | #define STB_PID 0x0001 /* Sensor Terminal Board */ | ||
961 | #define WHT_PID 0x0004 /* Wireless Handheld Terminal */ | ||
962 | |||
963 | /* | ||
964 | * Papouch products (http://www.papouch.com/) | ||
965 | * Submitted by Folkert van Heusden | ||
966 | */ | ||
967 | |||
968 | #define PAPOUCH_VID 0x5050 /* Vendor ID */ | ||
969 | #define PAPOUCH_TMU_PID 0x0400 /* TMU USB Thermometer */ | ||
970 | #define PAPOUCH_QUIDO4x4_PID 0x0900 /* Quido 4/4 Module */ | ||
971 | |||
972 | /* | ||
973 | * Marvell SheevaPlug | ||
974 | */ | ||
975 | #define MARVELL_VID 0x9e88 | ||
976 | #define MARVELL_SHEEVAPLUG_PID 0x9e8f | ||
977 | |||
978 | /* | ||
979 | * Evolution Robotics products (http://www.evolution.com/). | ||
980 | * Submitted by Shawn M. Lavelle. | ||
981 | */ | ||
982 | #define EVOLUTION_VID 0xDEEE /* Vendor ID */ | ||
983 | #define EVOLUTION_ER1_PID 0x0300 /* ER1 Control Module */ | ||
984 | #define EVO_8U232AM_PID 0x02FF /* Evolution robotics RCM2 (FT232AM)*/ | ||
985 | #define EVO_HYBRID_PID 0x0302 /* Evolution robotics RCM4 PID (FT232BM)*/ | ||
986 | #define EVO_RCM4_PID 0x0303 /* Evolution robotics RCM4 PID */ | ||
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index bbe005cefcfb..f1ea3a33b6e6 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c | |||
@@ -276,7 +276,7 @@ static int usb_serial_generic_write_start(struct usb_serial_port *port) | |||
276 | if (port->write_urb_busy) | 276 | if (port->write_urb_busy) |
277 | start_io = false; | 277 | start_io = false; |
278 | else { | 278 | else { |
279 | start_io = (__kfifo_len(port->write_fifo) != 0); | 279 | start_io = (kfifo_len(&port->write_fifo) != 0); |
280 | port->write_urb_busy = start_io; | 280 | port->write_urb_busy = start_io; |
281 | } | 281 | } |
282 | spin_unlock_irqrestore(&port->lock, flags); | 282 | spin_unlock_irqrestore(&port->lock, flags); |
@@ -285,7 +285,7 @@ static int usb_serial_generic_write_start(struct usb_serial_port *port) | |||
285 | return 0; | 285 | return 0; |
286 | 286 | ||
287 | data = port->write_urb->transfer_buffer; | 287 | data = port->write_urb->transfer_buffer; |
288 | count = kfifo_get(port->write_fifo, data, port->bulk_out_size); | 288 | count = kfifo_out_locked(&port->write_fifo, data, port->bulk_out_size, &port->lock); |
289 | usb_serial_debug_data(debug, &port->dev, __func__, count, data); | 289 | usb_serial_debug_data(debug, &port->dev, __func__, count, data); |
290 | 290 | ||
291 | /* set up our urb */ | 291 | /* set up our urb */ |
@@ -345,7 +345,7 @@ int usb_serial_generic_write(struct tty_struct *tty, | |||
345 | return usb_serial_multi_urb_write(tty, port, | 345 | return usb_serial_multi_urb_write(tty, port, |
346 | buf, count); | 346 | buf, count); |
347 | 347 | ||
348 | count = kfifo_put(port->write_fifo, buf, count); | 348 | count = kfifo_in_locked(&port->write_fifo, buf, count, &port->lock); |
349 | result = usb_serial_generic_write_start(port); | 349 | result = usb_serial_generic_write_start(port); |
350 | 350 | ||
351 | if (result >= 0) | 351 | if (result >= 0) |
@@ -370,7 +370,7 @@ int usb_serial_generic_write_room(struct tty_struct *tty) | |||
370 | (serial->type->max_in_flight_urbs - | 370 | (serial->type->max_in_flight_urbs - |
371 | port->urbs_in_flight); | 371 | port->urbs_in_flight); |
372 | } else if (serial->num_bulk_out) | 372 | } else if (serial->num_bulk_out) |
373 | room = port->write_fifo->size - __kfifo_len(port->write_fifo); | 373 | room = kfifo_avail(&port->write_fifo); |
374 | spin_unlock_irqrestore(&port->lock, flags); | 374 | spin_unlock_irqrestore(&port->lock, flags); |
375 | 375 | ||
376 | dbg("%s - returns %d", __func__, room); | 376 | dbg("%s - returns %d", __func__, room); |
@@ -391,7 +391,7 @@ int usb_serial_generic_chars_in_buffer(struct tty_struct *tty) | |||
391 | chars = port->tx_bytes_flight; | 391 | chars = port->tx_bytes_flight; |
392 | spin_unlock_irqrestore(&port->lock, flags); | 392 | spin_unlock_irqrestore(&port->lock, flags); |
393 | } else if (serial->num_bulk_out) | 393 | } else if (serial->num_bulk_out) |
394 | chars = kfifo_len(port->write_fifo); | 394 | chars = kfifo_len(&port->write_fifo); |
395 | 395 | ||
396 | dbg("%s - returns %d", __func__, chars); | 396 | dbg("%s - returns %d", __func__, chars); |
397 | return chars; | 397 | return chars; |
@@ -507,7 +507,7 @@ void usb_serial_generic_write_bulk_callback(struct urb *urb) | |||
507 | if (status) { | 507 | if (status) { |
508 | dbg("%s - nonzero multi-urb write bulk status " | 508 | dbg("%s - nonzero multi-urb write bulk status " |
509 | "received: %d", __func__, status); | 509 | "received: %d", __func__, status); |
510 | kfifo_reset(port->write_fifo); | 510 | kfifo_reset_out(&port->write_fifo); |
511 | } else | 511 | } else |
512 | usb_serial_generic_write_start(port); | 512 | usb_serial_generic_write_start(port); |
513 | } | 513 | } |
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 485fa9c5b107..2cfe2451ed97 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c | |||
@@ -127,8 +127,9 @@ | |||
127 | #define BANDB_DEVICE_ID_US9ML2_4 0xAC30 | 127 | #define BANDB_DEVICE_ID_US9ML2_4 0xAC30 |
128 | #define BANDB_DEVICE_ID_USPTL4_2 0xAC31 | 128 | #define BANDB_DEVICE_ID_USPTL4_2 0xAC31 |
129 | #define BANDB_DEVICE_ID_USPTL4_4 0xAC32 | 129 | #define BANDB_DEVICE_ID_USPTL4_4 0xAC32 |
130 | #define BANDB_DEVICE_ID_USOPTL4_2 0xAC42 | 130 | #define BANDB_DEVICE_ID_USOPTL4_2 0xAC42 |
131 | #define BANDB_DEVICE_ID_USOPTL4_4 0xAC44 | 131 | #define BANDB_DEVICE_ID_USOPTL4_4 0xAC44 |
132 | #define BANDB_DEVICE_ID_USOPTL2_4 0xAC24 | ||
132 | 133 | ||
133 | /* This driver also supports | 134 | /* This driver also supports |
134 | * ATEN UC2324 device using Moschip MCS7840 | 135 | * ATEN UC2324 device using Moschip MCS7840 |
@@ -191,6 +192,7 @@ static struct usb_device_id moschip_port_id_table[] = { | |||
191 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_4)}, | 192 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_4)}, |
192 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)}, | 193 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)}, |
193 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)}, | 194 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)}, |
195 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL2_4)}, | ||
194 | {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)}, | 196 | {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)}, |
195 | {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2322)}, | 197 | {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2322)}, |
196 | {} /* terminating entry */ | 198 | {} /* terminating entry */ |
@@ -207,6 +209,7 @@ static __devinitdata struct usb_device_id moschip_id_table_combined[] = { | |||
207 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_4)}, | 209 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_4)}, |
208 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)}, | 210 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)}, |
209 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)}, | 211 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)}, |
212 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL2_4)}, | ||
210 | {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)}, | 213 | {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)}, |
211 | {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2322)}, | 214 | {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2322)}, |
212 | {} /* terminating entry */ | 215 | {} /* terminating entry */ |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 9a2b903492ec..6e94a6711f08 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -340,6 +340,10 @@ static int option_resume(struct usb_serial *serial); | |||
340 | #define FOUR_G_SYSTEMS_VENDOR_ID 0x1c9e | 340 | #define FOUR_G_SYSTEMS_VENDOR_ID 0x1c9e |
341 | #define FOUR_G_SYSTEMS_PRODUCT_W14 0x9603 | 341 | #define FOUR_G_SYSTEMS_PRODUCT_W14 0x9603 |
342 | 342 | ||
343 | /* Haier products */ | ||
344 | #define HAIER_VENDOR_ID 0x201e | ||
345 | #define HAIER_PRODUCT_CE100 0x2009 | ||
346 | |||
343 | static struct usb_device_id option_ids[] = { | 347 | static struct usb_device_id option_ids[] = { |
344 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, | 348 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, |
345 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, | 349 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, |
@@ -641,6 +645,7 @@ static struct usb_device_id option_ids[] = { | |||
641 | { USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) }, | 645 | { USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) }, |
642 | { USB_DEVICE(TLAYTECH_VENDOR_ID, TLAYTECH_PRODUCT_TEU800) }, | 646 | { USB_DEVICE(TLAYTECH_VENDOR_ID, TLAYTECH_PRODUCT_TEU800) }, |
643 | { USB_DEVICE(FOUR_G_SYSTEMS_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W14) }, | 647 | { USB_DEVICE(FOUR_G_SYSTEMS_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W14) }, |
648 | { USB_DEVICE(HAIER_VENDOR_ID, HAIER_PRODUCT_CE100) }, | ||
644 | { } /* Terminating entry */ | 649 | { } /* Terminating entry */ |
645 | }; | 650 | }; |
646 | MODULE_DEVICE_TABLE(usb, option_ids); | 651 | MODULE_DEVICE_TABLE(usb, option_ids); |
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 4543f359be75..33c85f7084f8 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
@@ -595,8 +595,7 @@ static void port_release(struct device *dev) | |||
595 | usb_free_urb(port->write_urb); | 595 | usb_free_urb(port->write_urb); |
596 | usb_free_urb(port->interrupt_in_urb); | 596 | usb_free_urb(port->interrupt_in_urb); |
597 | usb_free_urb(port->interrupt_out_urb); | 597 | usb_free_urb(port->interrupt_out_urb); |
598 | if (!IS_ERR(port->write_fifo) && port->write_fifo) | 598 | kfifo_free(&port->write_fifo); |
599 | kfifo_free(port->write_fifo); | ||
600 | kfree(port->bulk_in_buffer); | 599 | kfree(port->bulk_in_buffer); |
601 | kfree(port->bulk_out_buffer); | 600 | kfree(port->bulk_out_buffer); |
602 | kfree(port->interrupt_in_buffer); | 601 | kfree(port->interrupt_in_buffer); |
@@ -939,9 +938,7 @@ int usb_serial_probe(struct usb_interface *interface, | |||
939 | dev_err(&interface->dev, "No free urbs available\n"); | 938 | dev_err(&interface->dev, "No free urbs available\n"); |
940 | goto probe_error; | 939 | goto probe_error; |
941 | } | 940 | } |
942 | port->write_fifo = kfifo_alloc(PAGE_SIZE, GFP_KERNEL, | 941 | if (kfifo_alloc(&port->write_fifo, PAGE_SIZE, GFP_KERNEL)) |
943 | &port->lock); | ||
944 | if (IS_ERR(port->write_fifo)) | ||
945 | goto probe_error; | 942 | goto probe_error; |
946 | buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); | 943 | buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); |
947 | port->bulk_out_size = buffer_size; | 944 | port->bulk_out_size = buffer_size; |
diff --git a/drivers/video/cyber2000fb.c b/drivers/video/cyber2000fb.c index da7c01b39be2..3a561df2e8a2 100644 --- a/drivers/video/cyber2000fb.c +++ b/drivers/video/cyber2000fb.c | |||
@@ -1573,15 +1573,15 @@ cyberpro_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
1573 | if (err) | 1573 | if (err) |
1574 | return err; | 1574 | return err; |
1575 | 1575 | ||
1576 | err = pci_request_regions(dev, name); | ||
1577 | if (err) | ||
1578 | return err; | ||
1579 | |||
1580 | err = -ENOMEM; | 1576 | err = -ENOMEM; |
1581 | cfb = cyberpro_alloc_fb_info(id->driver_data, name); | 1577 | cfb = cyberpro_alloc_fb_info(id->driver_data, name); |
1582 | if (!cfb) | 1578 | if (!cfb) |
1583 | goto failed_release; | 1579 | goto failed_release; |
1584 | 1580 | ||
1581 | err = pci_request_regions(dev, cfb->fb.fix.id); | ||
1582 | if (err) | ||
1583 | goto failed_regions; | ||
1584 | |||
1585 | cfb->dev = dev; | 1585 | cfb->dev = dev; |
1586 | cfb->region = pci_ioremap_bar(dev, 0); | 1586 | cfb->region = pci_ioremap_bar(dev, 0); |
1587 | if (!cfb->region) | 1587 | if (!cfb->region) |
@@ -1633,10 +1633,10 @@ cyberpro_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
1633 | failed: | 1633 | failed: |
1634 | iounmap(cfb->region); | 1634 | iounmap(cfb->region); |
1635 | failed_ioremap: | 1635 | failed_ioremap: |
1636 | pci_release_regions(dev); | ||
1637 | failed_regions: | ||
1636 | cyberpro_free_fb_info(cfb); | 1638 | cyberpro_free_fb_info(cfb); |
1637 | failed_release: | 1639 | failed_release: |
1638 | pci_release_regions(dev); | ||
1639 | |||
1640 | return err; | 1640 | return err; |
1641 | } | 1641 | } |
1642 | 1642 | ||
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index da84fd03850f..088f32f29a6e 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig | |||
@@ -368,7 +368,7 @@ config ALIM7101_WDT | |||
368 | 368 | ||
369 | config GEODE_WDT | 369 | config GEODE_WDT |
370 | tristate "AMD Geode CS5535/CS5536 Watchdog" | 370 | tristate "AMD Geode CS5535/CS5536 Watchdog" |
371 | depends on MGEODE_LX | 371 | depends on CS5535_MFGPT |
372 | help | 372 | help |
373 | This driver enables a watchdog capability built into the | 373 | This driver enables a watchdog capability built into the |
374 | CS5535/CS5536 companion chips for the AMD Geode GX and LX | 374 | CS5535/CS5536 companion chips for the AMD Geode GX and LX |
diff --git a/drivers/watchdog/adx_wdt.c b/drivers/watchdog/adx_wdt.c index 9c6594473d3b..9d7d155364f8 100644 --- a/drivers/watchdog/adx_wdt.c +++ b/drivers/watchdog/adx_wdt.c | |||
@@ -242,14 +242,14 @@ static int __devinit adx_wdt_probe(struct platform_device *pdev) | |||
242 | } | 242 | } |
243 | 243 | ||
244 | res = devm_request_mem_region(&pdev->dev, res->start, | 244 | res = devm_request_mem_region(&pdev->dev, res->start, |
245 | res->end - res->start + 1, res->name); | 245 | resource_size(res), res->name); |
246 | if (!res) { | 246 | if (!res) { |
247 | dev_err(&pdev->dev, "cannot request I/O memory region\n"); | 247 | dev_err(&pdev->dev, "cannot request I/O memory region\n"); |
248 | return -ENXIO; | 248 | return -ENXIO; |
249 | } | 249 | } |
250 | 250 | ||
251 | wdt->base = devm_ioremap_nocache(&pdev->dev, res->start, | 251 | wdt->base = devm_ioremap_nocache(&pdev->dev, res->start, |
252 | res->end - res->start + 1); | 252 | resource_size(res)); |
253 | if (!wdt->base) { | 253 | if (!wdt->base) { |
254 | dev_err(&pdev->dev, "cannot remap I/O memory region\n"); | 254 | dev_err(&pdev->dev, "cannot remap I/O memory region\n"); |
255 | return -ENXIO; | 255 | return -ENXIO; |
diff --git a/drivers/watchdog/at32ap700x_wdt.c b/drivers/watchdog/at32ap700x_wdt.c index e8ae638e5804..037847923dcb 100644 --- a/drivers/watchdog/at32ap700x_wdt.c +++ b/drivers/watchdog/at32ap700x_wdt.c | |||
@@ -326,7 +326,7 @@ static int __init at32_wdt_probe(struct platform_device *pdev) | |||
326 | return -ENOMEM; | 326 | return -ENOMEM; |
327 | } | 327 | } |
328 | 328 | ||
329 | wdt->regs = ioremap(regs->start, regs->end - regs->start + 1); | 329 | wdt->regs = ioremap(regs->start, resource_size(regs)); |
330 | if (!wdt->regs) { | 330 | if (!wdt->regs) { |
331 | ret = -ENOMEM; | 331 | ret = -ENOMEM; |
332 | dev_dbg(&pdev->dev, "could not map I/O memory\n"); | 332 | dev_dbg(&pdev->dev, "could not map I/O memory\n"); |
diff --git a/drivers/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c index 9d7520fa9e9c..887136de1857 100644 --- a/drivers/watchdog/davinci_wdt.c +++ b/drivers/watchdog/davinci_wdt.c | |||
@@ -221,7 +221,7 @@ static int __devinit davinci_wdt_probe(struct platform_device *pdev) | |||
221 | return -ENOENT; | 221 | return -ENOENT; |
222 | } | 222 | } |
223 | 223 | ||
224 | size = res->end - res->start + 1; | 224 | size = resource_size(res); |
225 | wdt_mem = request_mem_region(res->start, size, pdev->name); | 225 | wdt_mem = request_mem_region(res->start, size, pdev->name); |
226 | 226 | ||
227 | if (wdt_mem == NULL) { | 227 | if (wdt_mem == NULL) { |
diff --git a/drivers/watchdog/geodewdt.c b/drivers/watchdog/geodewdt.c index 9acf0015a1e7..38252ff828ca 100644 --- a/drivers/watchdog/geodewdt.c +++ b/drivers/watchdog/geodewdt.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /* Watchdog timer for the Geode GX/LX with the CS5535/CS5536 companion chip | 1 | /* Watchdog timer for machines with the CS5535/CS5536 companion chip |
2 | * | 2 | * |
3 | * Copyright (C) 2006-2007, Advanced Micro Devices, Inc. | 3 | * Copyright (C) 2006-2007, Advanced Micro Devices, Inc. |
4 | * Copyright (C) 2009 Andres Salomon <dilinger@collabora.co.uk> | ||
4 | * | 5 | * |
5 | * This program is free software; you can redistribute it and/or | 6 | * This program is free software; you can redistribute it and/or |
6 | * modify it under the terms of the GNU General Public License | 7 | * modify it under the terms of the GNU General Public License |
@@ -19,7 +20,7 @@ | |||
19 | #include <linux/reboot.h> | 20 | #include <linux/reboot.h> |
20 | #include <linux/uaccess.h> | 21 | #include <linux/uaccess.h> |
21 | 22 | ||
22 | #include <asm/geode.h> | 23 | #include <linux/cs5535.h> |
23 | 24 | ||
24 | #define GEODEWDT_HZ 500 | 25 | #define GEODEWDT_HZ 500 |
25 | #define GEODEWDT_SCALE 6 | 26 | #define GEODEWDT_SCALE 6 |
@@ -46,25 +47,25 @@ MODULE_PARM_DESC(nowayout, | |||
46 | 47 | ||
47 | static struct platform_device *geodewdt_platform_device; | 48 | static struct platform_device *geodewdt_platform_device; |
48 | static unsigned long wdt_flags; | 49 | static unsigned long wdt_flags; |
49 | static int wdt_timer; | 50 | static struct cs5535_mfgpt_timer *wdt_timer; |
50 | static int safe_close; | 51 | static int safe_close; |
51 | 52 | ||
52 | static void geodewdt_ping(void) | 53 | static void geodewdt_ping(void) |
53 | { | 54 | { |
54 | /* Stop the counter */ | 55 | /* Stop the counter */ |
55 | geode_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, 0); | 56 | cs5535_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, 0); |
56 | 57 | ||
57 | /* Reset the counter */ | 58 | /* Reset the counter */ |
58 | geode_mfgpt_write(wdt_timer, MFGPT_REG_COUNTER, 0); | 59 | cs5535_mfgpt_write(wdt_timer, MFGPT_REG_COUNTER, 0); |
59 | 60 | ||
60 | /* Enable the counter */ | 61 | /* Enable the counter */ |
61 | geode_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, MFGPT_SETUP_CNTEN); | 62 | cs5535_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, MFGPT_SETUP_CNTEN); |
62 | } | 63 | } |
63 | 64 | ||
64 | static void geodewdt_disable(void) | 65 | static void geodewdt_disable(void) |
65 | { | 66 | { |
66 | geode_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, 0); | 67 | cs5535_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, 0); |
67 | geode_mfgpt_write(wdt_timer, MFGPT_REG_COUNTER, 0); | 68 | cs5535_mfgpt_write(wdt_timer, MFGPT_REG_COUNTER, 0); |
68 | } | 69 | } |
69 | 70 | ||
70 | static int geodewdt_set_heartbeat(int val) | 71 | static int geodewdt_set_heartbeat(int val) |
@@ -72,10 +73,10 @@ static int geodewdt_set_heartbeat(int val) | |||
72 | if (val < 1 || val > GEODEWDT_MAX_SECONDS) | 73 | if (val < 1 || val > GEODEWDT_MAX_SECONDS) |
73 | return -EINVAL; | 74 | return -EINVAL; |
74 | 75 | ||
75 | geode_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, 0); | 76 | cs5535_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, 0); |
76 | geode_mfgpt_write(wdt_timer, MFGPT_REG_CMP2, val * GEODEWDT_HZ); | 77 | cs5535_mfgpt_write(wdt_timer, MFGPT_REG_CMP2, val * GEODEWDT_HZ); |
77 | geode_mfgpt_write(wdt_timer, MFGPT_REG_COUNTER, 0); | 78 | cs5535_mfgpt_write(wdt_timer, MFGPT_REG_COUNTER, 0); |
78 | geode_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, MFGPT_SETUP_CNTEN); | 79 | cs5535_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, MFGPT_SETUP_CNTEN); |
79 | 80 | ||
80 | timeout = val; | 81 | timeout = val; |
81 | return 0; | 82 | return 0; |
@@ -215,28 +216,25 @@ static struct miscdevice geodewdt_miscdev = { | |||
215 | 216 | ||
216 | static int __devinit geodewdt_probe(struct platform_device *dev) | 217 | static int __devinit geodewdt_probe(struct platform_device *dev) |
217 | { | 218 | { |
218 | int ret, timer; | 219 | int ret; |
219 | |||
220 | timer = geode_mfgpt_alloc_timer(MFGPT_TIMER_ANY, MFGPT_DOMAIN_WORKING); | ||
221 | 220 | ||
222 | if (timer == -1) { | 221 | wdt_timer = cs5535_mfgpt_alloc_timer(MFGPT_TIMER_ANY, MFGPT_DOMAIN_WORKING); |
222 | if (!wdt_timer) { | ||
223 | printk(KERN_ERR "geodewdt: No timers were available\n"); | 223 | printk(KERN_ERR "geodewdt: No timers were available\n"); |
224 | return -ENODEV; | 224 | return -ENODEV; |
225 | } | 225 | } |
226 | 226 | ||
227 | wdt_timer = timer; | ||
228 | |||
229 | /* Set up the timer */ | 227 | /* Set up the timer */ |
230 | 228 | ||
231 | geode_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, | 229 | cs5535_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, |
232 | GEODEWDT_SCALE | (3 << 8)); | 230 | GEODEWDT_SCALE | (3 << 8)); |
233 | 231 | ||
234 | /* Set up comparator 2 to reset when the event fires */ | 232 | /* Set up comparator 2 to reset when the event fires */ |
235 | geode_mfgpt_toggle_event(wdt_timer, MFGPT_CMP2, MFGPT_EVENT_RESET, 1); | 233 | cs5535_mfgpt_toggle_event(wdt_timer, MFGPT_CMP2, MFGPT_EVENT_RESET, 1); |
236 | 234 | ||
237 | /* Set up the initial timeout */ | 235 | /* Set up the initial timeout */ |
238 | 236 | ||
239 | geode_mfgpt_write(wdt_timer, MFGPT_REG_CMP2, | 237 | cs5535_mfgpt_write(wdt_timer, MFGPT_REG_CMP2, |
240 | timeout * GEODEWDT_HZ); | 238 | timeout * GEODEWDT_HZ); |
241 | 239 | ||
242 | ret = misc_register(&geodewdt_miscdev); | 240 | ret = misc_register(&geodewdt_miscdev); |
diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c index e44fbb31bc6f..c8a3bec26830 100644 --- a/drivers/watchdog/iTCO_wdt.c +++ b/drivers/watchdog/iTCO_wdt.c | |||
@@ -30,6 +30,7 @@ | |||
30 | * document number 316972-004, 316973-012: 82801I (ICH9) | 30 | * document number 316972-004, 316973-012: 82801I (ICH9) |
31 | * document number 319973-002, 319974-002: 82801J (ICH10) | 31 | * document number 319973-002, 319974-002: 82801J (ICH10) |
32 | * document number 322169-001, 322170-001: 5 Series, 3400 Series (PCH) | 32 | * document number 322169-001, 322170-001: 5 Series, 3400 Series (PCH) |
33 | * document number 320066-003, 320257-008: EP80597 (IICH) | ||
33 | */ | 34 | */ |
34 | 35 | ||
35 | /* | 36 | /* |
@@ -100,6 +101,7 @@ enum iTCO_chipsets { | |||
100 | TCO_PCH, /* PCH Desktop Full Featured */ | 101 | TCO_PCH, /* PCH Desktop Full Featured */ |
101 | TCO_PCHM, /* PCH Mobile Full Featured */ | 102 | TCO_PCHM, /* PCH Mobile Full Featured */ |
102 | TCO_PCHMSFF, /* PCH Mobile SFF Full Featured */ | 103 | TCO_PCHMSFF, /* PCH Mobile SFF Full Featured */ |
104 | TCO_EP80579, /* EP80579 */ | ||
103 | }; | 105 | }; |
104 | 106 | ||
105 | static struct { | 107 | static struct { |
@@ -143,6 +145,7 @@ static struct { | |||
143 | {"PCH Desktop Full Featured", 2}, | 145 | {"PCH Desktop Full Featured", 2}, |
144 | {"PCH Mobile Full Featured", 2}, | 146 | {"PCH Mobile Full Featured", 2}, |
145 | {"PCH Mobile SFF Full Featured", 2}, | 147 | {"PCH Mobile SFF Full Featured", 2}, |
148 | {"EP80579", 2}, | ||
146 | {NULL, 0} | 149 | {NULL, 0} |
147 | }; | 150 | }; |
148 | 151 | ||
@@ -214,6 +217,7 @@ static struct pci_device_id iTCO_wdt_pci_tbl[] = { | |||
214 | { ITCO_PCI_DEVICE(0x3b00, TCO_PCH)}, | 217 | { ITCO_PCI_DEVICE(0x3b00, TCO_PCH)}, |
215 | { ITCO_PCI_DEVICE(0x3b01, TCO_PCHM)}, | 218 | { ITCO_PCI_DEVICE(0x3b01, TCO_PCHM)}, |
216 | { ITCO_PCI_DEVICE(0x3b0d, TCO_PCHMSFF)}, | 219 | { ITCO_PCI_DEVICE(0x3b0d, TCO_PCHMSFF)}, |
220 | { ITCO_PCI_DEVICE(0x5031, TCO_EP80579)}, | ||
217 | { 0, }, /* End of list */ | 221 | { 0, }, /* End of list */ |
218 | }; | 222 | }; |
219 | MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl); | 223 | MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl); |
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c index 83fa34b214b4..a2dc07c2ed49 100644 --- a/drivers/watchdog/mpcore_wdt.c +++ b/drivers/watchdog/mpcore_wdt.c | |||
@@ -350,7 +350,7 @@ static int __devinit mpcore_wdt_probe(struct platform_device *dev) | |||
350 | ret = -ENXIO; | 350 | ret = -ENXIO; |
351 | goto err_free; | 351 | goto err_free; |
352 | } | 352 | } |
353 | wdt->base = ioremap(res->start, res->end - res->start + 1); | 353 | wdt->base = ioremap(res->start, resource_size(res)); |
354 | if (!wdt->base) { | 354 | if (!wdt->base) { |
355 | ret = -ENOMEM; | 355 | ret = -ENOMEM; |
356 | goto err_free; | 356 | goto err_free; |
diff --git a/drivers/watchdog/mv64x60_wdt.c b/drivers/watchdog/mv64x60_wdt.c index acf589dc057c..a51dbe4c43da 100644 --- a/drivers/watchdog/mv64x60_wdt.c +++ b/drivers/watchdog/mv64x60_wdt.c | |||
@@ -275,7 +275,7 @@ static int __devinit mv64x60_wdt_probe(struct platform_device *dev) | |||
275 | if (!r) | 275 | if (!r) |
276 | return -ENODEV; | 276 | return -ENODEV; |
277 | 277 | ||
278 | mv64x60_wdt_regs = ioremap(r->start, r->end - r->start + 1); | 278 | mv64x60_wdt_regs = ioremap(r->start, resource_size(r)); |
279 | if (mv64x60_wdt_regs == NULL) | 279 | if (mv64x60_wdt_regs == NULL) |
280 | return -ENOMEM; | 280 | return -ENOMEM; |
281 | 281 | ||
diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c index 429ea99eaee5..c6aaf2845741 100644 --- a/drivers/watchdog/omap_wdt.c +++ b/drivers/watchdog/omap_wdt.c | |||
@@ -277,8 +277,7 @@ static int __devinit omap_wdt_probe(struct platform_device *pdev) | |||
277 | goto err_busy; | 277 | goto err_busy; |
278 | } | 278 | } |
279 | 279 | ||
280 | mem = request_mem_region(res->start, res->end - res->start + 1, | 280 | mem = request_mem_region(res->start, resource_size(res), pdev->name); |
281 | pdev->name); | ||
282 | if (!mem) { | 281 | if (!mem) { |
283 | ret = -EBUSY; | 282 | ret = -EBUSY; |
284 | goto err_busy; | 283 | goto err_busy; |
@@ -306,7 +305,7 @@ static int __devinit omap_wdt_probe(struct platform_device *pdev) | |||
306 | goto err_clk; | 305 | goto err_clk; |
307 | } | 306 | } |
308 | 307 | ||
309 | wdev->base = ioremap(res->start, res->end - res->start + 1); | 308 | wdev->base = ioremap(res->start, resource_size(res)); |
310 | if (!wdev->base) { | 309 | if (!wdev->base) { |
311 | ret = -ENOMEM; | 310 | ret = -ENOMEM; |
312 | goto err_ioremap; | 311 | goto err_ioremap; |
@@ -358,7 +357,7 @@ err_clk: | |||
358 | kfree(wdev); | 357 | kfree(wdev); |
359 | 358 | ||
360 | err_kzalloc: | 359 | err_kzalloc: |
361 | release_mem_region(res->start, res->end - res->start + 1); | 360 | release_mem_region(res->start, resource_size(res)); |
362 | 361 | ||
363 | err_busy: | 362 | err_busy: |
364 | err_get_resource: | 363 | err_get_resource: |
@@ -383,7 +382,7 @@ static int __devexit omap_wdt_remove(struct platform_device *pdev) | |||
383 | return -ENOENT; | 382 | return -ENOENT; |
384 | 383 | ||
385 | misc_deregister(&(wdev->omap_wdt_miscdev)); | 384 | misc_deregister(&(wdev->omap_wdt_miscdev)); |
386 | release_mem_region(res->start, res->end - res->start + 1); | 385 | release_mem_region(res->start, resource_size(res)); |
387 | platform_set_drvdata(pdev, NULL); | 386 | platform_set_drvdata(pdev, NULL); |
388 | 387 | ||
389 | clk_put(wdev->ick); | 388 | clk_put(wdev->ick); |
diff --git a/drivers/watchdog/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c index 4d227b152001..430a5848a9a5 100644 --- a/drivers/watchdog/pnx4008_wdt.c +++ b/drivers/watchdog/pnx4008_wdt.c | |||
@@ -264,7 +264,7 @@ static int __devinit pnx4008_wdt_probe(struct platform_device *pdev) | |||
264 | return -ENOENT; | 264 | return -ENOENT; |
265 | } | 265 | } |
266 | 266 | ||
267 | size = res->end - res->start + 1; | 267 | size = resource_size(res); |
268 | wdt_mem = request_mem_region(res->start, size, pdev->name); | 268 | wdt_mem = request_mem_region(res->start, size, pdev->name); |
269 | 269 | ||
270 | if (wdt_mem == NULL) { | 270 | if (wdt_mem == NULL) { |
diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c index 85b93e15d011..8760a26ab2a3 100644 --- a/drivers/watchdog/s3c2410_wdt.c +++ b/drivers/watchdog/s3c2410_wdt.c | |||
@@ -421,7 +421,7 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev) | |||
421 | return -ENOENT; | 421 | return -ENOENT; |
422 | } | 422 | } |
423 | 423 | ||
424 | size = (res->end - res->start) + 1; | 424 | size = resource_size(res); |
425 | wdt_mem = request_mem_region(res->start, size, pdev->name); | 425 | wdt_mem = request_mem_region(res->start, size, pdev->name); |
426 | if (wdt_mem == NULL) { | 426 | if (wdt_mem == NULL) { |
427 | dev_err(dev, "failed to get memory region\n"); | 427 | dev_err(dev, "failed to get memory region\n"); |
diff --git a/drivers/watchdog/txx9wdt.c b/drivers/watchdog/txx9wdt.c index 6adab77fbbb0..d635566e9307 100644 --- a/drivers/watchdog/txx9wdt.c +++ b/drivers/watchdog/txx9wdt.c | |||
@@ -214,12 +214,10 @@ static int __init txx9wdt_probe(struct platform_device *dev) | |||
214 | res = platform_get_resource(dev, IORESOURCE_MEM, 0); | 214 | res = platform_get_resource(dev, IORESOURCE_MEM, 0); |
215 | if (!res) | 215 | if (!res) |
216 | goto exit_busy; | 216 | goto exit_busy; |
217 | if (!devm_request_mem_region(&dev->dev, | 217 | if (!devm_request_mem_region(&dev->dev, res->start, resource_size(res), |
218 | res->start, res->end - res->start + 1, | ||
219 | "txx9wdt")) | 218 | "txx9wdt")) |
220 | goto exit_busy; | 219 | goto exit_busy; |
221 | txx9wdt_reg = devm_ioremap(&dev->dev, | 220 | txx9wdt_reg = devm_ioremap(&dev->dev, res->start, resource_size(res)); |
222 | res->start, res->end - res->start + 1); | ||
223 | if (!txx9wdt_reg) | 221 | if (!txx9wdt_reg) |
224 | goto exit_busy; | 222 | goto exit_busy; |
225 | 223 | ||