diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-06-16 05:23:36 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-06-16 05:23:36 -0400 |
commit | 766d02786ecd22932beeb9ca8bad6d8c5a552ef9 (patch) | |
tree | f6f2df0e35bbea914d1f4d12be6d02f128c73575 /drivers | |
parent | 906d882cacecd37ad2fdd03ed2a9b232bcb9507e (diff) | |
parent | 066519068ad2fbe98c7f45552b1f592903a9c8c8 (diff) |
Merge branch 'linus' into core/rcu
Diffstat (limited to 'drivers')
525 files changed, 10458 insertions, 5245 deletions
diff --git a/drivers/acpi/bay.c b/drivers/acpi/bay.c index d2fc94161848..26038c2a2a71 100644 --- a/drivers/acpi/bay.c +++ b/drivers/acpi/bay.c | |||
@@ -301,16 +301,20 @@ static int bay_add(acpi_handle handle, int id) | |||
301 | */ | 301 | */ |
302 | pdev->dev.uevent_suppress = 0; | 302 | pdev->dev.uevent_suppress = 0; |
303 | 303 | ||
304 | if (acpi_bay_add_fs(new_bay)) { | ||
305 | platform_device_unregister(new_bay->pdev); | ||
306 | goto bay_add_err; | ||
307 | } | ||
308 | |||
309 | /* register for events on this device */ | 304 | /* register for events on this device */ |
310 | status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, | 305 | status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, |
311 | bay_notify, new_bay); | 306 | bay_notify, new_bay); |
312 | if (ACPI_FAILURE(status)) { | 307 | if (ACPI_FAILURE(status)) { |
313 | printk(KERN_ERR PREFIX "Error installing bay notify handler\n"); | 308 | printk(KERN_INFO PREFIX "Error installing bay notify handler\n"); |
309 | platform_device_unregister(new_bay->pdev); | ||
310 | goto bay_add_err; | ||
311 | } | ||
312 | |||
313 | if (acpi_bay_add_fs(new_bay)) { | ||
314 | acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY, | ||
315 | bay_notify); | ||
316 | platform_device_unregister(new_bay->pdev); | ||
317 | goto bay_add_err; | ||
314 | } | 318 | } |
315 | 319 | ||
316 | /* if we are on a dock station, we should register for dock | 320 | /* if we are on a dock station, we should register for dock |
diff --git a/drivers/acpi/dispatcher/dsfield.c b/drivers/acpi/dispatcher/dsfield.c index c78078315be9..f988a5e7d2b4 100644 --- a/drivers/acpi/dispatcher/dsfield.c +++ b/drivers/acpi/dispatcher/dsfield.c | |||
@@ -450,10 +450,6 @@ acpi_ds_init_field_objects(union acpi_parse_object *op, | |||
450 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 450 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
451 | } | 451 | } |
452 | 452 | ||
453 | if (!arg) { | ||
454 | return_ACPI_STATUS(AE_AML_NO_OPERAND); | ||
455 | } | ||
456 | |||
457 | /* Creating new namespace node(s), should not already exist */ | 453 | /* Creating new namespace node(s), should not already exist */ |
458 | 454 | ||
459 | flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | | 455 | flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | |
@@ -467,6 +463,7 @@ acpi_ds_init_field_objects(union acpi_parse_object *op, | |||
467 | 463 | ||
468 | /* | 464 | /* |
469 | * Walk the list of entries in the field_list | 465 | * Walk the list of entries in the field_list |
466 | * Note: field_list can be of zero length. In this case, Arg will be NULL. | ||
470 | */ | 467 | */ |
471 | while (arg) { | 468 | while (arg) { |
472 | /* | 469 | /* |
diff --git a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c index e48a3ea03117..2509809a36cf 100644 --- a/drivers/acpi/dispatcher/dsmethod.c +++ b/drivers/acpi/dispatcher/dsmethod.c | |||
@@ -565,7 +565,7 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc, | |||
565 | 565 | ||
566 | acpi_os_release_mutex(method_desc->method. | 566 | acpi_os_release_mutex(method_desc->method. |
567 | mutex->mutex.os_mutex); | 567 | mutex->mutex.os_mutex); |
568 | method_desc->method.mutex->mutex.thread_id = 0; | 568 | method_desc->method.mutex->mutex.thread_id = NULL; |
569 | } | 569 | } |
570 | } | 570 | } |
571 | 571 | ||
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index fa44fb96fc34..96c542f7fded 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c | |||
@@ -834,7 +834,7 @@ static int dock_add(acpi_handle handle) | |||
834 | goto dock_add_err; | 834 | goto dock_add_err; |
835 | } | 835 | } |
836 | 836 | ||
837 | printk(KERN_INFO PREFIX "%s \n", ACPI_DOCK_DRIVER_DESCRIPTION); | 837 | printk(KERN_INFO PREFIX "%s\n", ACPI_DOCK_DRIVER_DESCRIPTION); |
838 | 838 | ||
839 | return 0; | 839 | return 0; |
840 | 840 | ||
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 0924992187e8..5622aee996b2 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -194,7 +194,7 @@ static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll) | |||
194 | while (time_before(jiffies, delay)) { | 194 | while (time_before(jiffies, delay)) { |
195 | if (acpi_ec_check_status(ec, event)) | 195 | if (acpi_ec_check_status(ec, event)) |
196 | return 0; | 196 | return 0; |
197 | udelay(ACPI_EC_UDELAY); | 197 | msleep(1); |
198 | } | 198 | } |
199 | } | 199 | } |
200 | pr_err(PREFIX "acpi_ec_wait timeout, status = 0x%2.2x, event = %s\n", | 200 | pr_err(PREFIX "acpi_ec_wait timeout, status = 0x%2.2x, event = %s\n", |
diff --git a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c index 24da921d13e3..39d742190584 100644 --- a/drivers/acpi/executer/exconfig.c +++ b/drivers/acpi/executer/exconfig.c | |||
@@ -375,9 +375,15 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
375 | goto cleanup; | 375 | goto cleanup; |
376 | } | 376 | } |
377 | 377 | ||
378 | /* | ||
379 | * Add the table to the namespace. | ||
380 | * | ||
381 | * Note: We load the table objects relative to the root of the namespace. | ||
382 | * This appears to go against the ACPI specification, but we do it for | ||
383 | * compatibility with other ACPI implementations. | ||
384 | */ | ||
378 | status = | 385 | status = |
379 | acpi_ex_add_table(table_index, walk_state->scope_info->scope.node, | 386 | acpi_ex_add_table(table_index, acpi_gbl_root_node, &ddb_handle); |
380 | &ddb_handle); | ||
381 | if (ACPI_FAILURE(status)) { | 387 | if (ACPI_FAILURE(status)) { |
382 | 388 | ||
383 | /* On error, table_ptr was deallocated above */ | 389 | /* On error, table_ptr was deallocated above */ |
diff --git a/drivers/acpi/executer/exmutex.c b/drivers/acpi/executer/exmutex.c index c873ab40cd0e..a8bf3d713e28 100644 --- a/drivers/acpi/executer/exmutex.c +++ b/drivers/acpi/executer/exmutex.c | |||
@@ -326,7 +326,7 @@ acpi_status acpi_ex_release_mutex_object(union acpi_operand_object *obj_desc) | |||
326 | 326 | ||
327 | /* Clear mutex info */ | 327 | /* Clear mutex info */ |
328 | 328 | ||
329 | obj_desc->mutex.thread_id = 0; | 329 | obj_desc->mutex.thread_id = NULL; |
330 | return_ACPI_STATUS(status); | 330 | return_ACPI_STATUS(status); |
331 | } | 331 | } |
332 | 332 | ||
@@ -463,7 +463,7 @@ void acpi_ex_release_all_mutexes(struct acpi_thread_state *thread) | |||
463 | /* Mark mutex unowned */ | 463 | /* Mark mutex unowned */ |
464 | 464 | ||
465 | obj_desc->mutex.owner_thread = NULL; | 465 | obj_desc->mutex.owner_thread = NULL; |
466 | obj_desc->mutex.thread_id = 0; | 466 | obj_desc->mutex.thread_id = NULL; |
467 | 467 | ||
468 | /* Update Thread sync_level (Last mutex is the important one) */ | 468 | /* Update Thread sync_level (Last mutex is the important one) */ |
469 | 469 | ||
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 06f8634fe58b..2808dc60fd67 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c | |||
@@ -272,6 +272,12 @@ static u32 rtc_handler(void *context) | |||
272 | static inline void rtc_wake_setup(void) | 272 | static inline void rtc_wake_setup(void) |
273 | { | 273 | { |
274 | acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL); | 274 | acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL); |
275 | /* | ||
276 | * After the RTC handler is installed, the Fixed_RTC event should | ||
277 | * be disabled. Only when the RTC alarm is set will it be enabled. | ||
278 | */ | ||
279 | acpi_clear_event(ACPI_EVENT_RTC); | ||
280 | acpi_disable_event(ACPI_EVENT_RTC, 0); | ||
275 | } | 281 | } |
276 | 282 | ||
277 | static void rtc_wake_on(struct device *dev) | 283 | static void rtc_wake_on(struct device *dev) |
diff --git a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c index d9937e05ec6a..dba3cfbe8cba 100644 --- a/drivers/acpi/hardware/hwsleep.c +++ b/drivers/acpi/hardware/hwsleep.c | |||
@@ -223,15 +223,17 @@ acpi_status acpi_enter_sleep_state_prep(u8 sleep_state) | |||
223 | break; | 223 | break; |
224 | } | 224 | } |
225 | 225 | ||
226 | /* Set the system indicators to show the desired sleep state. */ | 226 | /* |
227 | 227 | * Set the system indicators to show the desired sleep state. | |
228 | * _SST is an optional method (return no error if not found) | ||
229 | */ | ||
228 | status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL); | 230 | status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL); |
229 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | 231 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { |
230 | ACPI_EXCEPTION((AE_INFO, status, | 232 | ACPI_EXCEPTION((AE_INFO, status, |
231 | "While executing method _SST")); | 233 | "While executing method _SST")); |
232 | } | 234 | } |
233 | 235 | ||
234 | return_ACPI_STATUS(status); | 236 | return_ACPI_STATUS(AE_OK); |
235 | } | 237 | } |
236 | 238 | ||
237 | ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep) | 239 | ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep) |
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c index 5d59cb33b1a5..658e5f3abae0 100644 --- a/drivers/acpi/numa.c +++ b/drivers/acpi/numa.c | |||
@@ -140,19 +140,42 @@ acpi_table_print_srat_entry(struct acpi_subtable_header *header) | |||
140 | } | 140 | } |
141 | } | 141 | } |
142 | 142 | ||
143 | /* | ||
144 | * A lot of BIOS fill in 10 (= no distance) everywhere. This messes | ||
145 | * up the NUMA heuristics which wants the local node to have a smaller | ||
146 | * distance than the others. | ||
147 | * Do some quick checks here and only use the SLIT if it passes. | ||
148 | */ | ||
149 | static __init int slit_valid(struct acpi_table_slit *slit) | ||
150 | { | ||
151 | int i, j; | ||
152 | int d = slit->locality_count; | ||
153 | for (i = 0; i < d; i++) { | ||
154 | for (j = 0; j < d; j++) { | ||
155 | u8 val = slit->entry[d*i + j]; | ||
156 | if (i == j) { | ||
157 | if (val != LOCAL_DISTANCE) | ||
158 | return 0; | ||
159 | } else if (val <= LOCAL_DISTANCE) | ||
160 | return 0; | ||
161 | } | ||
162 | } | ||
163 | return 1; | ||
164 | } | ||
165 | |||
143 | static int __init acpi_parse_slit(struct acpi_table_header *table) | 166 | static int __init acpi_parse_slit(struct acpi_table_header *table) |
144 | { | 167 | { |
145 | struct acpi_table_slit *slit; | 168 | struct acpi_table_slit *slit; |
146 | u32 localities; | ||
147 | 169 | ||
148 | if (!table) | 170 | if (!table) |
149 | return -EINVAL; | 171 | return -EINVAL; |
150 | 172 | ||
151 | slit = (struct acpi_table_slit *)table; | 173 | slit = (struct acpi_table_slit *)table; |
152 | 174 | ||
153 | /* downcast just for %llu vs %lu for i386/ia64 */ | 175 | if (!slit_valid(slit)) { |
154 | localities = (u32) slit->locality_count; | 176 | printk(KERN_INFO "ACPI: SLIT table looks invalid. Not used.\n"); |
155 | 177 | return -EINVAL; | |
178 | } | ||
156 | acpi_numa_slit_init(slit); | 179 | acpi_numa_slit_init(slit); |
157 | 180 | ||
158 | return 0; | 181 | return 0; |
diff --git a/drivers/acpi/parser/psargs.c b/drivers/acpi/parser/psargs.c index f1e8bf65e24e..e94463778845 100644 --- a/drivers/acpi/parser/psargs.c +++ b/drivers/acpi/parser/psargs.c | |||
@@ -268,7 +268,7 @@ acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state, | |||
268 | */ | 268 | */ |
269 | if (ACPI_SUCCESS(status) && | 269 | if (ACPI_SUCCESS(status) && |
270 | possible_method_call && (node->type == ACPI_TYPE_METHOD)) { | 270 | possible_method_call && (node->type == ACPI_TYPE_METHOD)) { |
271 | if (walk_state->op->common.aml_opcode == AML_UNLOAD_OP) { | 271 | if (walk_state->opcode == AML_UNLOAD_OP) { |
272 | /* | 272 | /* |
273 | * acpi_ps_get_next_namestring has increased the AML pointer, | 273 | * acpi_ps_get_next_namestring has increased the AML pointer, |
274 | * so we need to restore the saved AML pointer for method call. | 274 | * so we need to restore the saved AML pointer for method call. |
@@ -691,7 +691,7 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state, | |||
691 | 691 | ||
692 | /* To support super_name arg of Unload */ | 692 | /* To support super_name arg of Unload */ |
693 | 693 | ||
694 | if (walk_state->op->common.aml_opcode == AML_UNLOAD_OP) { | 694 | if (walk_state->opcode == AML_UNLOAD_OP) { |
695 | status = | 695 | status = |
696 | acpi_ps_get_next_namepath(walk_state, | 696 | acpi_ps_get_next_namepath(walk_state, |
697 | parser_state, arg, | 697 | parser_state, arg, |
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 386e5aa48834..9dd0fa93b9e1 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c | |||
@@ -86,7 +86,6 @@ static int acpi_processor_info_open_fs(struct inode *inode, struct file *file); | |||
86 | static void acpi_processor_notify(acpi_handle handle, u32 event, void *data); | 86 | static void acpi_processor_notify(acpi_handle handle, u32 event, void *data); |
87 | static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu); | 87 | static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu); |
88 | static int acpi_processor_handle_eject(struct acpi_processor *pr); | 88 | static int acpi_processor_handle_eject(struct acpi_processor *pr); |
89 | extern int acpi_processor_tstate_has_changed(struct acpi_processor *pr); | ||
90 | 89 | ||
91 | 90 | ||
92 | static const struct acpi_device_id processor_device_ids[] = { | 91 | static const struct acpi_device_id processor_device_ids[] = { |
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 2dd2c1f3a01c..556ee1585192 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
@@ -1669,6 +1669,7 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr) | |||
1669 | return -EINVAL; | 1669 | return -EINVAL; |
1670 | } | 1670 | } |
1671 | 1671 | ||
1672 | dev->cpu = pr->id; | ||
1672 | for (i = 0; i < CPUIDLE_STATE_MAX; i++) { | 1673 | for (i = 0; i < CPUIDLE_STATE_MAX; i++) { |
1673 | dev->states[i].name[0] = '\0'; | 1674 | dev->states[i].name[0] = '\0'; |
1674 | dev->states[i].desc[0] = '\0'; | 1675 | dev->states[i].desc[0] = '\0'; |
@@ -1738,7 +1739,7 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr) | |||
1738 | 1739 | ||
1739 | int acpi_processor_cst_has_changed(struct acpi_processor *pr) | 1740 | int acpi_processor_cst_has_changed(struct acpi_processor *pr) |
1740 | { | 1741 | { |
1741 | int ret; | 1742 | int ret = 0; |
1742 | 1743 | ||
1743 | if (boot_option_idle_override) | 1744 | if (boot_option_idle_override) |
1744 | return 0; | 1745 | return 0; |
@@ -1756,8 +1757,10 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr) | |||
1756 | cpuidle_pause_and_lock(); | 1757 | cpuidle_pause_and_lock(); |
1757 | cpuidle_disable_device(&pr->power.dev); | 1758 | cpuidle_disable_device(&pr->power.dev); |
1758 | acpi_processor_get_power_info(pr); | 1759 | acpi_processor_get_power_info(pr); |
1759 | acpi_processor_setup_cpuidle(pr); | 1760 | if (pr->flags.power) { |
1760 | ret = cpuidle_enable_device(&pr->power.dev); | 1761 | acpi_processor_setup_cpuidle(pr); |
1762 | ret = cpuidle_enable_device(&pr->power.dev); | ||
1763 | } | ||
1761 | cpuidle_resume_and_unlock(); | 1764 | cpuidle_resume_and_unlock(); |
1762 | 1765 | ||
1763 | return ret; | 1766 | return ret; |
@@ -1813,7 +1816,6 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, | |||
1813 | if (pr->flags.power) { | 1816 | if (pr->flags.power) { |
1814 | #ifdef CONFIG_CPU_IDLE | 1817 | #ifdef CONFIG_CPU_IDLE |
1815 | acpi_processor_setup_cpuidle(pr); | 1818 | acpi_processor_setup_cpuidle(pr); |
1816 | pr->power.dev.cpu = pr->id; | ||
1817 | if (cpuidle_register_device(&pr->power.dev)) | 1819 | if (cpuidle_register_device(&pr->power.dev)) |
1818 | return -EIO; | 1820 | return -EIO; |
1819 | #endif | 1821 | #endif |
@@ -1850,8 +1852,7 @@ int acpi_processor_power_exit(struct acpi_processor *pr, | |||
1850 | return 0; | 1852 | return 0; |
1851 | 1853 | ||
1852 | #ifdef CONFIG_CPU_IDLE | 1854 | #ifdef CONFIG_CPU_IDLE |
1853 | if (pr->flags.power) | 1855 | cpuidle_unregister_device(&pr->power.dev); |
1854 | cpuidle_unregister_device(&pr->power.dev); | ||
1855 | #endif | 1856 | #endif |
1856 | pr->flags.power_setup_done = 0; | 1857 | pr->flags.power_setup_done = 0; |
1857 | 1858 | ||
diff --git a/drivers/acpi/sleep/proc.c b/drivers/acpi/sleep/proc.c index 8a5fe8710513..224c57c03381 100644 --- a/drivers/acpi/sleep/proc.c +++ b/drivers/acpi/sleep/proc.c | |||
@@ -495,6 +495,12 @@ static int __init acpi_sleep_proc_init(void) | |||
495 | acpi_root_dir, &acpi_system_alarm_fops); | 495 | acpi_root_dir, &acpi_system_alarm_fops); |
496 | 496 | ||
497 | acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL); | 497 | acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL); |
498 | /* | ||
499 | * Disable the RTC event after installing RTC handler. | ||
500 | * Only when RTC alarm is set will it be enabled. | ||
501 | */ | ||
502 | acpi_clear_event(ACPI_EVENT_RTC); | ||
503 | acpi_disable_event(ACPI_EVENT_RTC, 0); | ||
498 | #endif /* HAVE_ACPI_LEGACY_ALARM */ | 504 | #endif /* HAVE_ACPI_LEGACY_ALARM */ |
499 | 505 | ||
500 | /* 'wakeup device' [R/W] */ | 506 | /* 'wakeup device' [R/W] */ |
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c index 769f24855eb6..5bd2dec9a7ac 100644 --- a/drivers/acpi/system.c +++ b/drivers/acpi/system.c | |||
@@ -77,7 +77,6 @@ static ssize_t acpi_table_show(struct kobject *kobj, | |||
77 | container_of(bin_attr, struct acpi_table_attr, attr); | 77 | container_of(bin_attr, struct acpi_table_attr, attr); |
78 | struct acpi_table_header *table_header = NULL; | 78 | struct acpi_table_header *table_header = NULL; |
79 | acpi_status status; | 79 | acpi_status status; |
80 | ssize_t ret_count = count; | ||
81 | 80 | ||
82 | status = | 81 | status = |
83 | acpi_get_table(table_attr->name, table_attr->instance, | 82 | acpi_get_table(table_attr->name, table_attr->instance, |
@@ -85,18 +84,8 @@ static ssize_t acpi_table_show(struct kobject *kobj, | |||
85 | if (ACPI_FAILURE(status)) | 84 | if (ACPI_FAILURE(status)) |
86 | return -ENODEV; | 85 | return -ENODEV; |
87 | 86 | ||
88 | if (offset >= table_header->length) { | 87 | return memory_read_from_buffer(buf, count, &offset, |
89 | ret_count = 0; | 88 | table_header, table_header->length); |
90 | goto end; | ||
91 | } | ||
92 | |||
93 | if (offset + ret_count > table_header->length) | ||
94 | ret_count = table_header->length - offset; | ||
95 | |||
96 | memcpy(buf, ((char *)table_header) + offset, ret_count); | ||
97 | |||
98 | end: | ||
99 | return ret_count; | ||
100 | } | 89 | } |
101 | 90 | ||
102 | static void acpi_table_attr_init(struct acpi_table_attr *table_attr, | 91 | static void acpi_table_attr_init(struct acpi_table_attr *table_attr, |
diff --git a/drivers/acpi/tables/tbinstal.c b/drivers/acpi/tables/tbinstal.c index 402f93e1ff20..5336ce88f89f 100644 --- a/drivers/acpi/tables/tbinstal.c +++ b/drivers/acpi/tables/tbinstal.c | |||
@@ -123,24 +123,13 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, | |||
123 | } | 123 | } |
124 | } | 124 | } |
125 | 125 | ||
126 | /* The table must be either an SSDT or a PSDT or an OEMx */ | 126 | /* |
127 | 127 | * Originally, we checked the table signature for "SSDT" or "PSDT" here. | |
128 | if (!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_PSDT)&& | 128 | * Next, we added support for OEMx tables, signature "OEM". |
129 | !ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_SSDT)&& | 129 | * Valid tables were encountered with a null signature, so we've just |
130 | strncmp(table_desc->pointer->signature, "OEM", 3)) { | 130 | * given up on validating the signature, since it seems to be a waste |
131 | /* Check for a printable name */ | 131 | * of code. The original code was removed (05/2008). |
132 | if (acpi_ut_valid_acpi_name( | 132 | */ |
133 | *(u32 *) table_desc->pointer->signature)) { | ||
134 | ACPI_ERROR((AE_INFO, "Table has invalid signature " | ||
135 | "[%4.4s], must be SSDT or PSDT", | ||
136 | table_desc->pointer->signature)); | ||
137 | } else { | ||
138 | ACPI_ERROR((AE_INFO, "Table has invalid signature " | ||
139 | "(0x%8.8X), must be SSDT or PSDT", | ||
140 | *(u32 *) table_desc->pointer->signature)); | ||
141 | } | ||
142 | return_ACPI_STATUS(AE_BAD_SIGNATURE); | ||
143 | } | ||
144 | 133 | ||
145 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | 134 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); |
146 | 135 | ||
diff --git a/drivers/acpi/tables/tbxface.c b/drivers/acpi/tables/tbxface.c index fb57b93c2495..0e319604d3e7 100644 --- a/drivers/acpi/tables/tbxface.c +++ b/drivers/acpi/tables/tbxface.c | |||
@@ -540,7 +540,7 @@ static acpi_status acpi_tb_load_namespace(void) | |||
540 | acpi_tb_print_table_header(0, table); | 540 | acpi_tb_print_table_header(0, table); |
541 | 541 | ||
542 | if (no_auto_ssdt == 0) { | 542 | if (no_auto_ssdt == 0) { |
543 | printk(KERN_WARNING "ACPI: DSDT override uses original SSDTs unless \"acpi_no_auto_ssdt\""); | 543 | printk(KERN_WARNING "ACPI: DSDT override uses original SSDTs unless \"acpi_no_auto_ssdt\"\n"); |
544 | } | 544 | } |
545 | } | 545 | } |
546 | 546 | ||
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 504385b1f211..84c795fb9b1e 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c | |||
@@ -364,10 +364,17 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) | |||
364 | if (flag & ACPI_TRIPS_CRITICAL) { | 364 | if (flag & ACPI_TRIPS_CRITICAL) { |
365 | status = acpi_evaluate_integer(tz->device->handle, | 365 | status = acpi_evaluate_integer(tz->device->handle, |
366 | "_CRT", NULL, &tz->trips.critical.temperature); | 366 | "_CRT", NULL, &tz->trips.critical.temperature); |
367 | if (ACPI_FAILURE(status)) { | 367 | /* |
368 | * Treat freezing temperatures as invalid as well; some | ||
369 | * BIOSes return really low values and cause reboots at startup. | ||
370 | * Below zero (Celcius) values clearly aren't right for sure.. | ||
371 | * ... so lets discard those as invalid. | ||
372 | */ | ||
373 | if (ACPI_FAILURE(status) || | ||
374 | tz->trips.critical.temperature <= 2732) { | ||
368 | tz->trips.critical.flags.valid = 0; | 375 | tz->trips.critical.flags.valid = 0; |
369 | ACPI_EXCEPTION((AE_INFO, status, | 376 | ACPI_EXCEPTION((AE_INFO, status, |
370 | "No critical threshold")); | 377 | "No or invalid critical threshold")); |
371 | return -ENODEV; | 378 | return -ENODEV; |
372 | } else { | 379 | } else { |
373 | tz->trips.critical.flags.valid = 1; | 380 | tz->trips.critical.flags.valid = 1; |
diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c index e4ba7192cd15..1f057b71db1a 100644 --- a/drivers/acpi/utilities/utmisc.c +++ b/drivers/acpi/utilities/utmisc.c | |||
@@ -1048,6 +1048,7 @@ acpi_ut_exception(char *module_name, | |||
1048 | va_start(args, format); | 1048 | va_start(args, format); |
1049 | acpi_os_vprintf(format, args); | 1049 | acpi_os_vprintf(format, args); |
1050 | acpi_os_printf(" [%X]\n", ACPI_CA_VERSION); | 1050 | acpi_os_printf(" [%X]\n", ACPI_CA_VERSION); |
1051 | va_end(args); | ||
1051 | } | 1052 | } |
1052 | 1053 | ||
1053 | EXPORT_SYMBOL(acpi_ut_exception); | 1054 | EXPORT_SYMBOL(acpi_ut_exception); |
@@ -1063,7 +1064,6 @@ acpi_ut_warning(char *module_name, u32 line_number, char *format, ...) | |||
1063 | acpi_os_vprintf(format, args); | 1064 | acpi_os_vprintf(format, args); |
1064 | acpi_os_printf(" [%X]\n", ACPI_CA_VERSION); | 1065 | acpi_os_printf(" [%X]\n", ACPI_CA_VERSION); |
1065 | va_end(args); | 1066 | va_end(args); |
1066 | va_end(args); | ||
1067 | } | 1067 | } |
1068 | 1068 | ||
1069 | void ACPI_INTERNAL_VAR_XFACE | 1069 | void ACPI_INTERNAL_VAR_XFACE |
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 97f83fb2ee2e..966ab401e523 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -89,6 +89,7 @@ enum { | |||
89 | board_ahci_sb600 = 3, | 89 | board_ahci_sb600 = 3, |
90 | board_ahci_mv = 4, | 90 | board_ahci_mv = 4, |
91 | board_ahci_sb700 = 5, | 91 | board_ahci_sb700 = 5, |
92 | board_ahci_mcp65 = 6, | ||
92 | 93 | ||
93 | /* global controller registers */ | 94 | /* global controller registers */ |
94 | HOST_CAP = 0x00, /* host capabilities */ | 95 | HOST_CAP = 0x00, /* host capabilities */ |
@@ -190,6 +191,7 @@ enum { | |||
190 | AHCI_HFLAG_NO_PMP = (1 << 6), /* no PMP */ | 191 | AHCI_HFLAG_NO_PMP = (1 << 6), /* no PMP */ |
191 | AHCI_HFLAG_NO_HOTPLUG = (1 << 7), /* ignore PxSERR.DIAG.N */ | 192 | AHCI_HFLAG_NO_HOTPLUG = (1 << 7), /* ignore PxSERR.DIAG.N */ |
192 | AHCI_HFLAG_SECT255 = (1 << 8), /* max 255 sectors */ | 193 | AHCI_HFLAG_SECT255 = (1 << 8), /* max 255 sectors */ |
194 | AHCI_HFLAG_YES_NCQ = (1 << 9), /* force NCQ cap on */ | ||
193 | 195 | ||
194 | /* ap->flags bits */ | 196 | /* ap->flags bits */ |
195 | 197 | ||
@@ -253,6 +255,8 @@ static void ahci_pmp_attach(struct ata_port *ap); | |||
253 | static void ahci_pmp_detach(struct ata_port *ap); | 255 | static void ahci_pmp_detach(struct ata_port *ap); |
254 | static int ahci_softreset(struct ata_link *link, unsigned int *class, | 256 | static int ahci_softreset(struct ata_link *link, unsigned int *class, |
255 | unsigned long deadline); | 257 | unsigned long deadline); |
258 | static int ahci_sb600_softreset(struct ata_link *link, unsigned int *class, | ||
259 | unsigned long deadline); | ||
256 | static int ahci_hardreset(struct ata_link *link, unsigned int *class, | 260 | static int ahci_hardreset(struct ata_link *link, unsigned int *class, |
257 | unsigned long deadline); | 261 | unsigned long deadline); |
258 | static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class, | 262 | static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class, |
@@ -329,6 +333,12 @@ static struct ata_port_operations ahci_p5wdh_ops = { | |||
329 | .hardreset = ahci_p5wdh_hardreset, | 333 | .hardreset = ahci_p5wdh_hardreset, |
330 | }; | 334 | }; |
331 | 335 | ||
336 | static struct ata_port_operations ahci_sb600_ops = { | ||
337 | .inherits = &ahci_ops, | ||
338 | .softreset = ahci_sb600_softreset, | ||
339 | .pmp_softreset = ahci_sb600_softreset, | ||
340 | }; | ||
341 | |||
332 | #define AHCI_HFLAGS(flags) .private_data = (void *)(flags) | 342 | #define AHCI_HFLAGS(flags) .private_data = (void *)(flags) |
333 | 343 | ||
334 | static const struct ata_port_info ahci_port_info[] = { | 344 | static const struct ata_port_info ahci_port_info[] = { |
@@ -359,11 +369,11 @@ static const struct ata_port_info ahci_port_info[] = { | |||
359 | { | 369 | { |
360 | AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL | | 370 | AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL | |
361 | AHCI_HFLAG_32BIT_ONLY | AHCI_HFLAG_NO_MSI | | 371 | AHCI_HFLAG_32BIT_ONLY | AHCI_HFLAG_NO_MSI | |
362 | AHCI_HFLAG_SECT255 | AHCI_HFLAG_NO_PMP), | 372 | AHCI_HFLAG_SECT255), |
363 | .flags = AHCI_FLAG_COMMON, | 373 | .flags = AHCI_FLAG_COMMON, |
364 | .pio_mask = 0x1f, /* pio0-4 */ | 374 | .pio_mask = 0x1f, /* pio0-4 */ |
365 | .udma_mask = ATA_UDMA6, | 375 | .udma_mask = ATA_UDMA6, |
366 | .port_ops = &ahci_ops, | 376 | .port_ops = &ahci_sb600_ops, |
367 | }, | 377 | }, |
368 | /* board_ahci_mv */ | 378 | /* board_ahci_mv */ |
369 | { | 379 | { |
@@ -377,8 +387,15 @@ static const struct ata_port_info ahci_port_info[] = { | |||
377 | }, | 387 | }, |
378 | /* board_ahci_sb700 */ | 388 | /* board_ahci_sb700 */ |
379 | { | 389 | { |
380 | AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL | | 390 | AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL), |
381 | AHCI_HFLAG_NO_PMP), | 391 | .flags = AHCI_FLAG_COMMON, |
392 | .pio_mask = 0x1f, /* pio0-4 */ | ||
393 | .udma_mask = ATA_UDMA6, | ||
394 | .port_ops = &ahci_sb600_ops, | ||
395 | }, | ||
396 | /* board_ahci_mcp65 */ | ||
397 | { | ||
398 | AHCI_HFLAGS (AHCI_HFLAG_YES_NCQ), | ||
382 | .flags = AHCI_FLAG_COMMON, | 399 | .flags = AHCI_FLAG_COMMON, |
383 | .pio_mask = 0x1f, /* pio0-4 */ | 400 | .pio_mask = 0x1f, /* pio0-4 */ |
384 | .udma_mask = ATA_UDMA6, | 401 | .udma_mask = ATA_UDMA6, |
@@ -438,14 +455,14 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
438 | { PCI_VDEVICE(VIA, 0x6287), board_ahci_vt8251 }, /* VIA VT8251 */ | 455 | { PCI_VDEVICE(VIA, 0x6287), board_ahci_vt8251 }, /* VIA VT8251 */ |
439 | 456 | ||
440 | /* NVIDIA */ | 457 | /* NVIDIA */ |
441 | { PCI_VDEVICE(NVIDIA, 0x044c), board_ahci }, /* MCP65 */ | 458 | { PCI_VDEVICE(NVIDIA, 0x044c), board_ahci_mcp65 }, /* MCP65 */ |
442 | { PCI_VDEVICE(NVIDIA, 0x044d), board_ahci }, /* MCP65 */ | 459 | { PCI_VDEVICE(NVIDIA, 0x044d), board_ahci_mcp65 }, /* MCP65 */ |
443 | { PCI_VDEVICE(NVIDIA, 0x044e), board_ahci }, /* MCP65 */ | 460 | { PCI_VDEVICE(NVIDIA, 0x044e), board_ahci_mcp65 }, /* MCP65 */ |
444 | { PCI_VDEVICE(NVIDIA, 0x044f), board_ahci }, /* MCP65 */ | 461 | { PCI_VDEVICE(NVIDIA, 0x044f), board_ahci_mcp65 }, /* MCP65 */ |
445 | { PCI_VDEVICE(NVIDIA, 0x045c), board_ahci }, /* MCP65 */ | 462 | { PCI_VDEVICE(NVIDIA, 0x045c), board_ahci_mcp65 }, /* MCP65 */ |
446 | { PCI_VDEVICE(NVIDIA, 0x045d), board_ahci }, /* MCP65 */ | 463 | { PCI_VDEVICE(NVIDIA, 0x045d), board_ahci_mcp65 }, /* MCP65 */ |
447 | { PCI_VDEVICE(NVIDIA, 0x045e), board_ahci }, /* MCP65 */ | 464 | { PCI_VDEVICE(NVIDIA, 0x045e), board_ahci_mcp65 }, /* MCP65 */ |
448 | { PCI_VDEVICE(NVIDIA, 0x045f), board_ahci }, /* MCP65 */ | 465 | { PCI_VDEVICE(NVIDIA, 0x045f), board_ahci_mcp65 }, /* MCP65 */ |
449 | { PCI_VDEVICE(NVIDIA, 0x0550), board_ahci }, /* MCP67 */ | 466 | { PCI_VDEVICE(NVIDIA, 0x0550), board_ahci }, /* MCP67 */ |
450 | { PCI_VDEVICE(NVIDIA, 0x0551), board_ahci }, /* MCP67 */ | 467 | { PCI_VDEVICE(NVIDIA, 0x0551), board_ahci }, /* MCP67 */ |
451 | { PCI_VDEVICE(NVIDIA, 0x0552), board_ahci }, /* MCP67 */ | 468 | { PCI_VDEVICE(NVIDIA, 0x0552), board_ahci }, /* MCP67 */ |
@@ -502,10 +519,10 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
502 | { PCI_VDEVICE(NVIDIA, 0x0bcd), board_ahci }, /* MCP7B */ | 519 | { PCI_VDEVICE(NVIDIA, 0x0bcd), board_ahci }, /* MCP7B */ |
503 | { PCI_VDEVICE(NVIDIA, 0x0bce), board_ahci }, /* MCP7B */ | 520 | { PCI_VDEVICE(NVIDIA, 0x0bce), board_ahci }, /* MCP7B */ |
504 | { PCI_VDEVICE(NVIDIA, 0x0bcf), board_ahci }, /* MCP7B */ | 521 | { PCI_VDEVICE(NVIDIA, 0x0bcf), board_ahci }, /* MCP7B */ |
505 | { PCI_VDEVICE(NVIDIA, 0x0bd0), board_ahci }, /* MCP7B */ | 522 | { PCI_VDEVICE(NVIDIA, 0x0bc4), board_ahci }, /* MCP7B */ |
506 | { PCI_VDEVICE(NVIDIA, 0x0bd1), board_ahci }, /* MCP7B */ | 523 | { PCI_VDEVICE(NVIDIA, 0x0bc5), board_ahci }, /* MCP7B */ |
507 | { PCI_VDEVICE(NVIDIA, 0x0bd2), board_ahci }, /* MCP7B */ | 524 | { PCI_VDEVICE(NVIDIA, 0x0bc6), board_ahci }, /* MCP7B */ |
508 | { PCI_VDEVICE(NVIDIA, 0x0bd3), board_ahci }, /* MCP7B */ | 525 | { PCI_VDEVICE(NVIDIA, 0x0bc7), board_ahci }, /* MCP7B */ |
509 | 526 | ||
510 | /* SiS */ | 527 | /* SiS */ |
511 | { PCI_VDEVICE(SI, 0x1184), board_ahci }, /* SiS 966 */ | 528 | { PCI_VDEVICE(SI, 0x1184), board_ahci }, /* SiS 966 */ |
@@ -624,6 +641,12 @@ static void ahci_save_initial_config(struct pci_dev *pdev, | |||
624 | cap &= ~HOST_CAP_NCQ; | 641 | cap &= ~HOST_CAP_NCQ; |
625 | } | 642 | } |
626 | 643 | ||
644 | if (!(cap & HOST_CAP_NCQ) && (hpriv->flags & AHCI_HFLAG_YES_NCQ)) { | ||
645 | dev_printk(KERN_INFO, &pdev->dev, | ||
646 | "controller can do NCQ, turning on CAP_NCQ\n"); | ||
647 | cap |= HOST_CAP_NCQ; | ||
648 | } | ||
649 | |||
627 | if ((cap & HOST_CAP_PMP) && (hpriv->flags & AHCI_HFLAG_NO_PMP)) { | 650 | if ((cap & HOST_CAP_PMP) && (hpriv->flags & AHCI_HFLAG_NO_PMP)) { |
628 | dev_printk(KERN_INFO, &pdev->dev, | 651 | dev_printk(KERN_INFO, &pdev->dev, |
629 | "controller can't do PMP, turning off CAP_PMP\n"); | 652 | "controller can't do PMP, turning off CAP_PMP\n"); |
@@ -1262,19 +1285,11 @@ static int ahci_exec_polled_cmd(struct ata_port *ap, int pmp, | |||
1262 | return 0; | 1285 | return 0; |
1263 | } | 1286 | } |
1264 | 1287 | ||
1265 | static int ahci_check_ready(struct ata_link *link) | 1288 | static int ahci_do_softreset(struct ata_link *link, unsigned int *class, |
1266 | { | 1289 | int pmp, unsigned long deadline, |
1267 | void __iomem *port_mmio = ahci_port_base(link->ap); | 1290 | int (*check_ready)(struct ata_link *link)) |
1268 | u8 status = readl(port_mmio + PORT_TFDATA) & 0xFF; | ||
1269 | |||
1270 | return ata_check_ready(status); | ||
1271 | } | ||
1272 | |||
1273 | static int ahci_softreset(struct ata_link *link, unsigned int *class, | ||
1274 | unsigned long deadline) | ||
1275 | { | 1291 | { |
1276 | struct ata_port *ap = link->ap; | 1292 | struct ata_port *ap = link->ap; |
1277 | int pmp = sata_srst_pmp(link); | ||
1278 | const char *reason = NULL; | 1293 | const char *reason = NULL; |
1279 | unsigned long now, msecs; | 1294 | unsigned long now, msecs; |
1280 | struct ata_taskfile tf; | 1295 | struct ata_taskfile tf; |
@@ -1312,7 +1327,7 @@ static int ahci_softreset(struct ata_link *link, unsigned int *class, | |||
1312 | ahci_exec_polled_cmd(ap, pmp, &tf, 0, 0, 0); | 1327 | ahci_exec_polled_cmd(ap, pmp, &tf, 0, 0, 0); |
1313 | 1328 | ||
1314 | /* wait for link to become ready */ | 1329 | /* wait for link to become ready */ |
1315 | rc = ata_wait_after_reset(link, deadline, ahci_check_ready); | 1330 | rc = ata_wait_after_reset(link, deadline, check_ready); |
1316 | /* link occupied, -ENODEV too is an error */ | 1331 | /* link occupied, -ENODEV too is an error */ |
1317 | if (rc) { | 1332 | if (rc) { |
1318 | reason = "device not ready"; | 1333 | reason = "device not ready"; |
@@ -1328,6 +1343,72 @@ static int ahci_softreset(struct ata_link *link, unsigned int *class, | |||
1328 | return rc; | 1343 | return rc; |
1329 | } | 1344 | } |
1330 | 1345 | ||
1346 | static int ahci_check_ready(struct ata_link *link) | ||
1347 | { | ||
1348 | void __iomem *port_mmio = ahci_port_base(link->ap); | ||
1349 | u8 status = readl(port_mmio + PORT_TFDATA) & 0xFF; | ||
1350 | |||
1351 | return ata_check_ready(status); | ||
1352 | } | ||
1353 | |||
1354 | static int ahci_softreset(struct ata_link *link, unsigned int *class, | ||
1355 | unsigned long deadline) | ||
1356 | { | ||
1357 | int pmp = sata_srst_pmp(link); | ||
1358 | |||
1359 | DPRINTK("ENTER\n"); | ||
1360 | |||
1361 | return ahci_do_softreset(link, class, pmp, deadline, ahci_check_ready); | ||
1362 | } | ||
1363 | |||
1364 | static int ahci_sb600_check_ready(struct ata_link *link) | ||
1365 | { | ||
1366 | void __iomem *port_mmio = ahci_port_base(link->ap); | ||
1367 | u8 status = readl(port_mmio + PORT_TFDATA) & 0xFF; | ||
1368 | u32 irq_status = readl(port_mmio + PORT_IRQ_STAT); | ||
1369 | |||
1370 | /* | ||
1371 | * There is no need to check TFDATA if BAD PMP is found due to HW bug, | ||
1372 | * which can save timeout delay. | ||
1373 | */ | ||
1374 | if (irq_status & PORT_IRQ_BAD_PMP) | ||
1375 | return -EIO; | ||
1376 | |||
1377 | return ata_check_ready(status); | ||
1378 | } | ||
1379 | |||
1380 | static int ahci_sb600_softreset(struct ata_link *link, unsigned int *class, | ||
1381 | unsigned long deadline) | ||
1382 | { | ||
1383 | struct ata_port *ap = link->ap; | ||
1384 | void __iomem *port_mmio = ahci_port_base(ap); | ||
1385 | int pmp = sata_srst_pmp(link); | ||
1386 | int rc; | ||
1387 | u32 irq_sts; | ||
1388 | |||
1389 | DPRINTK("ENTER\n"); | ||
1390 | |||
1391 | rc = ahci_do_softreset(link, class, pmp, deadline, | ||
1392 | ahci_sb600_check_ready); | ||
1393 | |||
1394 | /* | ||
1395 | * Soft reset fails on some ATI chips with IPMS set when PMP | ||
1396 | * is enabled but SATA HDD/ODD is connected to SATA port, | ||
1397 | * do soft reset again to port 0. | ||
1398 | */ | ||
1399 | if (rc == -EIO) { | ||
1400 | irq_sts = readl(port_mmio + PORT_IRQ_STAT); | ||
1401 | if (irq_sts & PORT_IRQ_BAD_PMP) { | ||
1402 | ata_link_printk(link, KERN_WARNING, | ||
1403 | "failed due to HW bug, retry pmp=0\n"); | ||
1404 | rc = ahci_do_softreset(link, class, 0, deadline, | ||
1405 | ahci_check_ready); | ||
1406 | } | ||
1407 | } | ||
1408 | |||
1409 | return rc; | ||
1410 | } | ||
1411 | |||
1331 | static int ahci_hardreset(struct ata_link *link, unsigned int *class, | 1412 | static int ahci_hardreset(struct ata_link *link, unsigned int *class, |
1332 | unsigned long deadline) | 1413 | unsigned long deadline) |
1333 | { | 1414 | { |
@@ -2118,7 +2199,8 @@ static void ahci_p5wdh_workaround(struct ata_host *host) | |||
2118 | static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | 2199 | static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) |
2119 | { | 2200 | { |
2120 | static int printed_version; | 2201 | static int printed_version; |
2121 | struct ata_port_info pi = ahci_port_info[ent->driver_data]; | 2202 | unsigned int board_id = ent->driver_data; |
2203 | struct ata_port_info pi = ahci_port_info[board_id]; | ||
2122 | const struct ata_port_info *ppi[] = { &pi, NULL }; | 2204 | const struct ata_port_info *ppi[] = { &pi, NULL }; |
2123 | struct device *dev = &pdev->dev; | 2205 | struct device *dev = &pdev->dev; |
2124 | struct ahci_host_priv *hpriv; | 2206 | struct ahci_host_priv *hpriv; |
@@ -2167,6 +2249,11 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2167 | return -ENOMEM; | 2249 | return -ENOMEM; |
2168 | hpriv->flags |= (unsigned long)pi.private_data; | 2250 | hpriv->flags |= (unsigned long)pi.private_data; |
2169 | 2251 | ||
2252 | /* MCP65 revision A1 and A2 can't do MSI */ | ||
2253 | if (board_id == board_ahci_mcp65 && | ||
2254 | (pdev->revision == 0xa1 || pdev->revision == 0xa2)) | ||
2255 | hpriv->flags |= AHCI_HFLAG_NO_MSI; | ||
2256 | |||
2170 | if ((hpriv->flags & AHCI_HFLAG_NO_MSI) || pci_enable_msi(pdev)) | 2257 | if ((hpriv->flags & AHCI_HFLAG_NO_MSI) || pci_enable_msi(pdev)) |
2171 | pci_intx(pdev, 1); | 2258 | pci_intx(pdev, 1); |
2172 | 2259 | ||
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index a9027b8fbdd5..81b7ae376951 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c | |||
@@ -247,10 +247,11 @@ static const struct pci_device_id piix_pci_tbl[] = { | |||
247 | { 0x8086, 0x2820, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, | 247 | { 0x8086, 0x2820, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, |
248 | /* SATA Controller 2 IDE (ICH8) */ | 248 | /* SATA Controller 2 IDE (ICH8) */ |
249 | { 0x8086, 0x2825, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, | 249 | { 0x8086, 0x2825, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, |
250 | /* Mobile SATA Controller IDE (ICH8M) */ | ||
251 | { 0x8086, 0x2828, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, | ||
252 | /* Mobile SATA Controller IDE (ICH8M), Apple */ | 250 | /* Mobile SATA Controller IDE (ICH8M), Apple */ |
253 | { 0x8086, 0x2828, 0x106b, 0x00a0, 0, 0, ich8m_apple_sata }, | 251 | { 0x8086, 0x2828, 0x106b, 0x00a0, 0, 0, ich8m_apple_sata }, |
252 | { 0x8086, 0x2828, 0x106b, 0x00a1, 0, 0, ich8m_apple_sata }, | ||
253 | /* Mobile SATA Controller IDE (ICH8M) */ | ||
254 | { 0x8086, 0x2828, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, | ||
254 | /* SATA Controller IDE (ICH9) */ | 255 | /* SATA Controller IDE (ICH9) */ |
255 | { 0x8086, 0x2920, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, | 256 | { 0x8086, 0x2920, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, |
256 | /* SATA Controller IDE (ICH9) */ | 257 | /* SATA Controller IDE (ICH9) */ |
@@ -526,7 +527,7 @@ static struct ata_port_info piix_port_info[] = { | |||
526 | 527 | ||
527 | [ich8m_apple_sata] = | 528 | [ich8m_apple_sata] = |
528 | { | 529 | { |
529 | .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SIDPR, | 530 | .flags = PIIX_SATA_FLAGS, |
530 | .pio_mask = 0x1f, /* pio0-4 */ | 531 | .pio_mask = 0x1f, /* pio0-4 */ |
531 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 532 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
532 | .udma_mask = ATA_UDMA6, | 533 | .udma_mask = ATA_UDMA6, |
@@ -573,6 +574,8 @@ static const struct ich_laptop ich_laptop[] = { | |||
573 | { 0x27DF, 0x1043, 0x1267 }, /* ICH7 on Asus W5F */ | 574 | { 0x27DF, 0x1043, 0x1267 }, /* ICH7 on Asus W5F */ |
574 | { 0x27DF, 0x103C, 0x30A1 }, /* ICH7 on HP Compaq nc2400 */ | 575 | { 0x27DF, 0x103C, 0x30A1 }, /* ICH7 on HP Compaq nc2400 */ |
575 | { 0x24CA, 0x1025, 0x0061 }, /* ICH4 on ACER Aspire 2023WLMi */ | 576 | { 0x24CA, 0x1025, 0x0061 }, /* ICH4 on ACER Aspire 2023WLMi */ |
577 | { 0x24CA, 0x1025, 0x003d }, /* ICH4 on ACER TM290 */ | ||
578 | { 0x266F, 0x1025, 0x0066 }, /* ICH6 on ACER Aspire 1694WLMi */ | ||
576 | { 0x2653, 0x1043, 0x82D8 }, /* ICH6M on Asus Eee 701 */ | 579 | { 0x2653, 0x1043, 0x82D8 }, /* ICH6M on Asus Eee 701 */ |
577 | /* end marker */ | 580 | /* end marker */ |
578 | { 0, } | 581 | { 0, } |
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index 70b77e0899a8..3ff8b14420d9 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c | |||
@@ -118,19 +118,82 @@ static void ata_acpi_associate_ide_port(struct ata_port *ap) | |||
118 | ap->pflags |= ATA_PFLAG_INIT_GTM_VALID; | 118 | ap->pflags |= ATA_PFLAG_INIT_GTM_VALID; |
119 | } | 119 | } |
120 | 120 | ||
121 | static void ata_acpi_eject_device(acpi_handle handle) | ||
122 | { | ||
123 | struct acpi_object_list arg_list; | ||
124 | union acpi_object arg; | ||
125 | |||
126 | arg_list.count = 1; | ||
127 | arg_list.pointer = &arg; | ||
128 | arg.type = ACPI_TYPE_INTEGER; | ||
129 | arg.integer.value = 1; | ||
130 | |||
131 | if (ACPI_FAILURE(acpi_evaluate_object(handle, "_EJ0", | ||
132 | &arg_list, NULL))) | ||
133 | printk(KERN_ERR "Failed to evaluate _EJ0!\n"); | ||
134 | } | ||
135 | |||
136 | /* @ap and @dev are the same as ata_acpi_handle_hotplug() */ | ||
137 | static void ata_acpi_detach_device(struct ata_port *ap, struct ata_device *dev) | ||
138 | { | ||
139 | if (dev) | ||
140 | dev->flags |= ATA_DFLAG_DETACH; | ||
141 | else { | ||
142 | struct ata_link *tlink; | ||
143 | struct ata_device *tdev; | ||
144 | |||
145 | ata_port_for_each_link(tlink, ap) | ||
146 | ata_link_for_each_dev(tdev, tlink) | ||
147 | tdev->flags |= ATA_DFLAG_DETACH; | ||
148 | } | ||
149 | |||
150 | ata_port_schedule_eh(ap); | ||
151 | } | ||
152 | |||
153 | /** | ||
154 | * ata_acpi_handle_hotplug - ACPI event handler backend | ||
155 | * @ap: ATA port ACPI event occurred | ||
156 | * @dev: ATA device ACPI event occurred (can be NULL) | ||
157 | * @event: ACPI event which occurred | ||
158 | * @is_dock_event: boolean indicating whether the event was a dock one | ||
159 | * | ||
160 | * All ACPI bay / device realted events end up in this function. If | ||
161 | * the event is port-wide @dev is NULL. If the event is specific to a | ||
162 | * device, @dev points to it. | ||
163 | * | ||
164 | * Hotplug (as opposed to unplug) notification is always handled as | ||
165 | * port-wide while unplug only kills the target device on device-wide | ||
166 | * event. | ||
167 | * | ||
168 | * LOCKING: | ||
169 | * ACPI notify handler context. May sleep. | ||
170 | */ | ||
121 | static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev, | 171 | static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev, |
122 | u32 event) | 172 | u32 event, int is_dock_event) |
123 | { | 173 | { |
124 | char event_string[12]; | 174 | char event_string[12]; |
125 | char *envp[] = { event_string, NULL }; | 175 | char *envp[] = { event_string, NULL }; |
126 | struct ata_eh_info *ehi; | 176 | struct ata_eh_info *ehi = &ap->link.eh_info; |
127 | struct kobject *kobj = NULL; | 177 | struct kobject *kobj = NULL; |
128 | int wait = 0; | 178 | int wait = 0; |
129 | unsigned long flags; | 179 | unsigned long flags; |
180 | acpi_handle handle, tmphandle; | ||
181 | unsigned long sta; | ||
182 | acpi_status status; | ||
183 | |||
184 | if (dev) { | ||
185 | if (dev->sdev) | ||
186 | kobj = &dev->sdev->sdev_gendev.kobj; | ||
187 | handle = dev->acpi_handle; | ||
188 | } else { | ||
189 | kobj = &ap->dev->kobj; | ||
190 | handle = ap->acpi_handle; | ||
191 | } | ||
130 | 192 | ||
131 | if (!ap) | 193 | status = acpi_get_handle(handle, "_EJ0", &tmphandle); |
132 | ap = dev->link->ap; | 194 | if (ACPI_FAILURE(status)) |
133 | ehi = &ap->link.eh_info; | 195 | /* This device does not support hotplug */ |
196 | return; | ||
134 | 197 | ||
135 | spin_lock_irqsave(ap->lock, flags); | 198 | spin_lock_irqsave(ap->lock, flags); |
136 | 199 | ||
@@ -138,57 +201,80 @@ static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev, | |||
138 | case ACPI_NOTIFY_BUS_CHECK: | 201 | case ACPI_NOTIFY_BUS_CHECK: |
139 | case ACPI_NOTIFY_DEVICE_CHECK: | 202 | case ACPI_NOTIFY_DEVICE_CHECK: |
140 | ata_ehi_push_desc(ehi, "ACPI event"); | 203 | ata_ehi_push_desc(ehi, "ACPI event"); |
141 | ata_ehi_hotplugged(ehi); | ||
142 | ata_port_freeze(ap); | ||
143 | break; | ||
144 | 204 | ||
205 | status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); | ||
206 | if (ACPI_FAILURE(status)) { | ||
207 | ata_port_printk(ap, KERN_ERR, | ||
208 | "acpi: failed to determine bay status (0x%x)\n", | ||
209 | status); | ||
210 | break; | ||
211 | } | ||
212 | |||
213 | if (sta) { | ||
214 | ata_ehi_hotplugged(ehi); | ||
215 | ata_port_freeze(ap); | ||
216 | } else { | ||
217 | /* The device has gone - unplug it */ | ||
218 | ata_acpi_detach_device(ap, dev); | ||
219 | wait = 1; | ||
220 | } | ||
221 | break; | ||
145 | case ACPI_NOTIFY_EJECT_REQUEST: | 222 | case ACPI_NOTIFY_EJECT_REQUEST: |
146 | ata_ehi_push_desc(ehi, "ACPI event"); | 223 | ata_ehi_push_desc(ehi, "ACPI event"); |
147 | if (dev) | ||
148 | dev->flags |= ATA_DFLAG_DETACH; | ||
149 | else { | ||
150 | struct ata_link *tlink; | ||
151 | struct ata_device *tdev; | ||
152 | |||
153 | ata_port_for_each_link(tlink, ap) | ||
154 | ata_link_for_each_dev(tdev, tlink) | ||
155 | tdev->flags |= ATA_DFLAG_DETACH; | ||
156 | } | ||
157 | 224 | ||
158 | ata_port_schedule_eh(ap); | 225 | if (!is_dock_event) |
226 | break; | ||
227 | |||
228 | /* undock event - immediate unplug */ | ||
229 | ata_acpi_detach_device(ap, dev); | ||
159 | wait = 1; | 230 | wait = 1; |
160 | break; | 231 | break; |
161 | } | 232 | } |
162 | 233 | ||
163 | if (dev) { | 234 | /* make sure kobj doesn't go away while ap->lock is released */ |
164 | if (dev->sdev) | 235 | kobject_get(kobj); |
165 | kobj = &dev->sdev->sdev_gendev.kobj; | 236 | |
166 | } else | 237 | spin_unlock_irqrestore(ap->lock, flags); |
167 | kobj = &ap->dev->kobj; | 238 | |
239 | if (wait) { | ||
240 | ata_port_wait_eh(ap); | ||
241 | ata_acpi_eject_device(handle); | ||
242 | } | ||
168 | 243 | ||
169 | if (kobj) { | 244 | if (kobj && !is_dock_event) { |
170 | sprintf(event_string, "BAY_EVENT=%d", event); | 245 | sprintf(event_string, "BAY_EVENT=%d", event); |
171 | kobject_uevent_env(kobj, KOBJ_CHANGE, envp); | 246 | kobject_uevent_env(kobj, KOBJ_CHANGE, envp); |
172 | } | 247 | } |
173 | 248 | ||
174 | spin_unlock_irqrestore(ap->lock, flags); | 249 | kobject_put(kobj); |
250 | } | ||
175 | 251 | ||
176 | if (wait) | 252 | static void ata_acpi_dev_notify_dock(acpi_handle handle, u32 event, void *data) |
177 | ata_port_wait_eh(ap); | 253 | { |
254 | struct ata_device *dev = data; | ||
255 | |||
256 | ata_acpi_handle_hotplug(dev->link->ap, dev, event, 1); | ||
257 | } | ||
258 | |||
259 | static void ata_acpi_ap_notify_dock(acpi_handle handle, u32 event, void *data) | ||
260 | { | ||
261 | struct ata_port *ap = data; | ||
262 | |||
263 | ata_acpi_handle_hotplug(ap, NULL, event, 1); | ||
178 | } | 264 | } |
179 | 265 | ||
180 | static void ata_acpi_dev_notify(acpi_handle handle, u32 event, void *data) | 266 | static void ata_acpi_dev_notify(acpi_handle handle, u32 event, void *data) |
181 | { | 267 | { |
182 | struct ata_device *dev = data; | 268 | struct ata_device *dev = data; |
183 | 269 | ||
184 | ata_acpi_handle_hotplug(NULL, dev, event); | 270 | ata_acpi_handle_hotplug(dev->link->ap, dev, event, 0); |
185 | } | 271 | } |
186 | 272 | ||
187 | static void ata_acpi_ap_notify(acpi_handle handle, u32 event, void *data) | 273 | static void ata_acpi_ap_notify(acpi_handle handle, u32 event, void *data) |
188 | { | 274 | { |
189 | struct ata_port *ap = data; | 275 | struct ata_port *ap = data; |
190 | 276 | ||
191 | ata_acpi_handle_hotplug(ap, NULL, event); | 277 | ata_acpi_handle_hotplug(ap, NULL, event, 0); |
192 | } | 278 | } |
193 | 279 | ||
194 | /** | 280 | /** |
@@ -229,7 +315,7 @@ void ata_acpi_associate(struct ata_host *host) | |||
229 | ata_acpi_ap_notify, ap); | 315 | ata_acpi_ap_notify, ap); |
230 | /* we might be on a docking station */ | 316 | /* we might be on a docking station */ |
231 | register_hotplug_dock_device(ap->acpi_handle, | 317 | register_hotplug_dock_device(ap->acpi_handle, |
232 | ata_acpi_ap_notify, ap); | 318 | ata_acpi_ap_notify_dock, ap); |
233 | } | 319 | } |
234 | 320 | ||
235 | for (j = 0; j < ata_link_max_devices(&ap->link); j++) { | 321 | for (j = 0; j < ata_link_max_devices(&ap->link); j++) { |
@@ -241,7 +327,7 @@ void ata_acpi_associate(struct ata_host *host) | |||
241 | ata_acpi_dev_notify, dev); | 327 | ata_acpi_dev_notify, dev); |
242 | /* we might be on a docking station */ | 328 | /* we might be on a docking station */ |
243 | register_hotplug_dock_device(dev->acpi_handle, | 329 | register_hotplug_dock_device(dev->acpi_handle, |
244 | ata_acpi_dev_notify, dev); | 330 | ata_acpi_dev_notify_dock, dev); |
245 | } | 331 | } |
246 | } | 332 | } |
247 | } | 333 | } |
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 927b692d723c..cc816ca623d3 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -2126,6 +2126,13 @@ int ata_dev_configure(struct ata_device *dev) | |||
2126 | dev->horkage |= ata_dev_blacklisted(dev); | 2126 | dev->horkage |= ata_dev_blacklisted(dev); |
2127 | ata_force_horkage(dev); | 2127 | ata_force_horkage(dev); |
2128 | 2128 | ||
2129 | if (dev->horkage & ATA_HORKAGE_DISABLE) { | ||
2130 | ata_dev_printk(dev, KERN_INFO, | ||
2131 | "unsupported device, disabling\n"); | ||
2132 | ata_dev_disable(dev); | ||
2133 | return 0; | ||
2134 | } | ||
2135 | |||
2129 | /* let ACPI work its magic */ | 2136 | /* let ACPI work its magic */ |
2130 | rc = ata_acpi_on_devcfg(dev); | 2137 | rc = ata_acpi_on_devcfg(dev); |
2131 | if (rc) | 2138 | if (rc) |
@@ -3490,22 +3497,11 @@ int sata_link_resume(struct ata_link *link, const unsigned long *params, | |||
3490 | if ((rc = sata_link_debounce(link, params, deadline))) | 3497 | if ((rc = sata_link_debounce(link, params, deadline))) |
3491 | return rc; | 3498 | return rc; |
3492 | 3499 | ||
3493 | /* Clear SError. PMP and some host PHYs require this to | 3500 | /* clear SError, some PHYs require this even for SRST to work */ |
3494 | * operate and clearing should be done before checking PHY | ||
3495 | * online status to avoid race condition (hotplugging between | ||
3496 | * link resume and status check). | ||
3497 | */ | ||
3498 | if (!(rc = sata_scr_read(link, SCR_ERROR, &serror))) | 3501 | if (!(rc = sata_scr_read(link, SCR_ERROR, &serror))) |
3499 | rc = sata_scr_write(link, SCR_ERROR, serror); | 3502 | rc = sata_scr_write(link, SCR_ERROR, serror); |
3500 | if (rc == 0 || rc == -EINVAL) { | ||
3501 | unsigned long flags; | ||
3502 | 3503 | ||
3503 | spin_lock_irqsave(link->ap->lock, flags); | 3504 | return rc != -EINVAL ? rc : 0; |
3504 | link->eh_info.serror = 0; | ||
3505 | spin_unlock_irqrestore(link->ap->lock, flags); | ||
3506 | rc = 0; | ||
3507 | } | ||
3508 | return rc; | ||
3509 | } | 3505 | } |
3510 | 3506 | ||
3511 | /** | 3507 | /** |
@@ -3653,9 +3649,13 @@ int sata_link_hardreset(struct ata_link *link, const unsigned long *timing, | |||
3653 | if (check_ready) | 3649 | if (check_ready) |
3654 | rc = ata_wait_ready(link, deadline, check_ready); | 3650 | rc = ata_wait_ready(link, deadline, check_ready); |
3655 | out: | 3651 | out: |
3656 | if (rc && rc != -EAGAIN) | 3652 | if (rc && rc != -EAGAIN) { |
3653 | /* online is set iff link is online && reset succeeded */ | ||
3654 | if (online) | ||
3655 | *online = false; | ||
3657 | ata_link_printk(link, KERN_ERR, | 3656 | ata_link_printk(link, KERN_ERR, |
3658 | "COMRESET failed (errno=%d)\n", rc); | 3657 | "COMRESET failed (errno=%d)\n", rc); |
3658 | } | ||
3659 | DPRINTK("EXIT, rc=%d\n", rc); | 3659 | DPRINTK("EXIT, rc=%d\n", rc); |
3660 | return rc; | 3660 | return rc; |
3661 | } | 3661 | } |
@@ -3700,8 +3700,14 @@ int sata_std_hardreset(struct ata_link *link, unsigned int *class, | |||
3700 | */ | 3700 | */ |
3701 | void ata_std_postreset(struct ata_link *link, unsigned int *classes) | 3701 | void ata_std_postreset(struct ata_link *link, unsigned int *classes) |
3702 | { | 3702 | { |
3703 | u32 serror; | ||
3704 | |||
3703 | DPRINTK("ENTER\n"); | 3705 | DPRINTK("ENTER\n"); |
3704 | 3706 | ||
3707 | /* reset complete, clear SError */ | ||
3708 | if (!sata_scr_read(link, SCR_ERROR, &serror)) | ||
3709 | sata_scr_write(link, SCR_ERROR, serror); | ||
3710 | |||
3705 | /* print link status */ | 3711 | /* print link status */ |
3706 | sata_print_link_status(link); | 3712 | sata_print_link_status(link); |
3707 | 3713 | ||
@@ -3894,8 +3900,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { | |||
3894 | { "SAMSUNG CD-ROM SN-124", "N001", ATA_HORKAGE_NODMA }, | 3900 | { "SAMSUNG CD-ROM SN-124", "N001", ATA_HORKAGE_NODMA }, |
3895 | { "Seagate STT20000A", NULL, ATA_HORKAGE_NODMA }, | 3901 | { "Seagate STT20000A", NULL, ATA_HORKAGE_NODMA }, |
3896 | /* Odd clown on sil3726/4726 PMPs */ | 3902 | /* Odd clown on sil3726/4726 PMPs */ |
3897 | { "Config Disk", NULL, ATA_HORKAGE_NODMA | | 3903 | { "Config Disk", NULL, ATA_HORKAGE_DISABLE }, |
3898 | ATA_HORKAGE_SKIP_PM }, | ||
3899 | 3904 | ||
3900 | /* Weird ATAPI devices */ | 3905 | /* Weird ATAPI devices */ |
3901 | { "TORiSAN DVD-ROM DRD-N216", NULL, ATA_HORKAGE_MAX_SEC_128 }, | 3906 | { "TORiSAN DVD-ROM DRD-N216", NULL, ATA_HORKAGE_MAX_SEC_128 }, |
@@ -5398,7 +5403,7 @@ static void ata_host_stop(struct device *gendev, void *res) | |||
5398 | */ | 5403 | */ |
5399 | static void ata_finalize_port_ops(struct ata_port_operations *ops) | 5404 | static void ata_finalize_port_ops(struct ata_port_operations *ops) |
5400 | { | 5405 | { |
5401 | static spinlock_t lock = SPIN_LOCK_UNLOCKED; | 5406 | static DEFINE_SPINLOCK(lock); |
5402 | const struct ata_port_operations *cur; | 5407 | const struct ata_port_operations *cur; |
5403 | void **begin = (void **)ops; | 5408 | void **begin = (void **)ops; |
5404 | void **end = (void **)&ops->inherits; | 5409 | void **end = (void **)&ops->inherits; |
@@ -5616,7 +5621,7 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht) | |||
5616 | spin_lock_irqsave(ap->lock, flags); | 5621 | spin_lock_irqsave(ap->lock, flags); |
5617 | 5622 | ||
5618 | ehi->probe_mask |= ATA_ALL_DEVICES; | 5623 | ehi->probe_mask |= ATA_ALL_DEVICES; |
5619 | ehi->action |= ATA_EH_RESET; | 5624 | ehi->action |= ATA_EH_RESET | ATA_EH_LPM; |
5620 | ehi->flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET; | 5625 | ehi->flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET; |
5621 | 5626 | ||
5622 | ap->pflags &= ~ATA_PFLAG_INITIALIZING; | 5627 | ap->pflags &= ~ATA_PFLAG_INITIALIZING; |
@@ -5649,7 +5654,6 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht) | |||
5649 | struct ata_port *ap = host->ports[i]; | 5654 | struct ata_port *ap = host->ports[i]; |
5650 | 5655 | ||
5651 | ata_scsi_scan_host(ap, 1); | 5656 | ata_scsi_scan_host(ap, 1); |
5652 | ata_lpm_schedule(ap, ap->pm_policy); | ||
5653 | } | 5657 | } |
5654 | 5658 | ||
5655 | return 0; | 5659 | return 0; |
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 62e033146bed..7894d83ea1eb 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c | |||
@@ -1308,12 +1308,7 @@ static void ata_eh_analyze_serror(struct ata_link *link) | |||
1308 | unsigned int err_mask = 0, action = 0; | 1308 | unsigned int err_mask = 0, action = 0; |
1309 | u32 hotplug_mask; | 1309 | u32 hotplug_mask; |
1310 | 1310 | ||
1311 | if (serror & SERR_PERSISTENT) { | 1311 | if (serror & (SERR_PERSISTENT | SERR_DATA)) { |
1312 | err_mask |= AC_ERR_ATA_BUS; | ||
1313 | action |= ATA_EH_RESET; | ||
1314 | } | ||
1315 | if (serror & | ||
1316 | (SERR_DATA_RECOVERED | SERR_COMM_RECOVERED | SERR_DATA)) { | ||
1317 | err_mask |= AC_ERR_ATA_BUS; | 1312 | err_mask |= AC_ERR_ATA_BUS; |
1318 | action |= ATA_EH_RESET; | 1313 | action |= ATA_EH_RESET; |
1319 | } | 1314 | } |
@@ -2047,19 +2042,11 @@ static int ata_do_reset(struct ata_link *link, ata_reset_fn_t reset, | |||
2047 | unsigned int *classes, unsigned long deadline) | 2042 | unsigned int *classes, unsigned long deadline) |
2048 | { | 2043 | { |
2049 | struct ata_device *dev; | 2044 | struct ata_device *dev; |
2050 | int rc; | ||
2051 | 2045 | ||
2052 | ata_link_for_each_dev(dev, link) | 2046 | ata_link_for_each_dev(dev, link) |
2053 | classes[dev->devno] = ATA_DEV_UNKNOWN; | 2047 | classes[dev->devno] = ATA_DEV_UNKNOWN; |
2054 | 2048 | ||
2055 | rc = reset(link, classes, deadline); | 2049 | return reset(link, classes, deadline); |
2056 | |||
2057 | /* convert all ATA_DEV_UNKNOWN to ATA_DEV_NONE */ | ||
2058 | ata_link_for_each_dev(dev, link) | ||
2059 | if (classes[dev->devno] == ATA_DEV_UNKNOWN) | ||
2060 | classes[dev->devno] = ATA_DEV_NONE; | ||
2061 | |||
2062 | return rc; | ||
2063 | } | 2050 | } |
2064 | 2051 | ||
2065 | static int ata_eh_followup_srst_needed(struct ata_link *link, | 2052 | static int ata_eh_followup_srst_needed(struct ata_link *link, |
@@ -2096,9 +2083,11 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
2096 | ata_reset_fn_t reset; | 2083 | ata_reset_fn_t reset; |
2097 | unsigned long flags; | 2084 | unsigned long flags; |
2098 | u32 sstatus; | 2085 | u32 sstatus; |
2099 | int rc; | 2086 | int nr_known, rc; |
2100 | 2087 | ||
2101 | /* about to reset */ | 2088 | /* |
2089 | * Prepare to reset | ||
2090 | */ | ||
2102 | spin_lock_irqsave(ap->lock, flags); | 2091 | spin_lock_irqsave(ap->lock, flags); |
2103 | ap->pflags |= ATA_PFLAG_RESETTING; | 2092 | ap->pflags |= ATA_PFLAG_RESETTING; |
2104 | spin_unlock_irqrestore(ap->lock, flags); | 2093 | spin_unlock_irqrestore(ap->lock, flags); |
@@ -2124,16 +2113,8 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
2124 | ap->ops->set_piomode(ap, dev); | 2113 | ap->ops->set_piomode(ap, dev); |
2125 | } | 2114 | } |
2126 | 2115 | ||
2127 | if (!softreset && !hardreset) { | ||
2128 | if (verbose) | ||
2129 | ata_link_printk(link, KERN_INFO, "no reset method " | ||
2130 | "available, skipping reset\n"); | ||
2131 | if (!(lflags & ATA_LFLAG_ASSUME_CLASS)) | ||
2132 | lflags |= ATA_LFLAG_ASSUME_ATA; | ||
2133 | goto done; | ||
2134 | } | ||
2135 | |||
2136 | /* prefer hardreset */ | 2116 | /* prefer hardreset */ |
2117 | reset = NULL; | ||
2137 | ehc->i.action &= ~ATA_EH_RESET; | 2118 | ehc->i.action &= ~ATA_EH_RESET; |
2138 | if (hardreset) { | 2119 | if (hardreset) { |
2139 | reset = hardreset; | 2120 | reset = hardreset; |
@@ -2141,11 +2122,6 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
2141 | } else if (softreset) { | 2122 | } else if (softreset) { |
2142 | reset = softreset; | 2123 | reset = softreset; |
2143 | ehc->i.action = ATA_EH_SOFTRESET; | 2124 | ehc->i.action = ATA_EH_SOFTRESET; |
2144 | } else { | ||
2145 | ata_link_printk(link, KERN_ERR, "BUG: no reset method, " | ||
2146 | "please report to linux-ide@vger.kernel.org\n"); | ||
2147 | dump_stack(); | ||
2148 | return -EINVAL; | ||
2149 | } | 2125 | } |
2150 | 2126 | ||
2151 | if (prereset) { | 2127 | if (prereset) { |
@@ -2165,55 +2141,71 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
2165 | "prereset failed (errno=%d)\n", rc); | 2141 | "prereset failed (errno=%d)\n", rc); |
2166 | goto out; | 2142 | goto out; |
2167 | } | 2143 | } |
2168 | } | ||
2169 | 2144 | ||
2170 | /* prereset() might have cleared ATA_EH_RESET */ | 2145 | /* prereset() might have cleared ATA_EH_RESET. If so, |
2171 | if (!(ehc->i.action & ATA_EH_RESET)) { | 2146 | * bang classes and return. |
2172 | /* prereset told us not to reset, bang classes and return */ | 2147 | */ |
2173 | ata_link_for_each_dev(dev, link) | 2148 | if (reset && !(ehc->i.action & ATA_EH_RESET)) { |
2174 | classes[dev->devno] = ATA_DEV_NONE; | 2149 | ata_link_for_each_dev(dev, link) |
2175 | rc = 0; | 2150 | classes[dev->devno] = ATA_DEV_NONE; |
2176 | goto out; | 2151 | rc = 0; |
2152 | goto out; | ||
2153 | } | ||
2177 | } | 2154 | } |
2178 | 2155 | ||
2179 | retry: | 2156 | retry: |
2157 | /* | ||
2158 | * Perform reset | ||
2159 | */ | ||
2160 | if (ata_is_host_link(link)) | ||
2161 | ata_eh_freeze_port(ap); | ||
2162 | |||
2180 | deadline = jiffies + ata_eh_reset_timeouts[try++]; | 2163 | deadline = jiffies + ata_eh_reset_timeouts[try++]; |
2181 | 2164 | ||
2182 | /* shut up during boot probing */ | 2165 | if (reset) { |
2183 | if (verbose) | 2166 | if (verbose) |
2184 | ata_link_printk(link, KERN_INFO, "%s resetting link\n", | 2167 | ata_link_printk(link, KERN_INFO, "%s resetting link\n", |
2185 | reset == softreset ? "soft" : "hard"); | 2168 | reset == softreset ? "soft" : "hard"); |
2186 | 2169 | ||
2187 | /* mark that this EH session started with reset */ | 2170 | /* mark that this EH session started with reset */ |
2188 | if (reset == hardreset) | 2171 | if (reset == hardreset) |
2189 | ehc->i.flags |= ATA_EHI_DID_HARDRESET; | 2172 | ehc->i.flags |= ATA_EHI_DID_HARDRESET; |
2190 | else | 2173 | else |
2191 | ehc->i.flags |= ATA_EHI_DID_SOFTRESET; | 2174 | ehc->i.flags |= ATA_EHI_DID_SOFTRESET; |
2192 | 2175 | ||
2193 | rc = ata_do_reset(link, reset, classes, deadline); | 2176 | rc = ata_do_reset(link, reset, classes, deadline); |
2194 | 2177 | ||
2195 | if (reset == hardreset && | 2178 | if (reset == hardreset && |
2196 | ata_eh_followup_srst_needed(link, rc, classify, classes)) { | 2179 | ata_eh_followup_srst_needed(link, rc, classify, classes)) { |
2197 | /* okay, let's do follow-up softreset */ | 2180 | /* okay, let's do follow-up softreset */ |
2198 | reset = softreset; | 2181 | reset = softreset; |
2199 | 2182 | ||
2200 | if (!reset) { | 2183 | if (!reset) { |
2201 | ata_link_printk(link, KERN_ERR, | 2184 | ata_link_printk(link, KERN_ERR, |
2202 | "follow-up softreset required " | 2185 | "follow-up softreset required " |
2203 | "but no softreset avaliable\n"); | 2186 | "but no softreset avaliable\n"); |
2204 | rc = -EINVAL; | 2187 | rc = -EINVAL; |
2205 | goto fail; | 2188 | goto fail; |
2189 | } | ||
2190 | |||
2191 | ata_eh_about_to_do(link, NULL, ATA_EH_RESET); | ||
2192 | rc = ata_do_reset(link, reset, classes, deadline); | ||
2206 | } | 2193 | } |
2207 | 2194 | ||
2208 | ata_eh_about_to_do(link, NULL, ATA_EH_RESET); | 2195 | /* -EAGAIN can happen if we skipped followup SRST */ |
2209 | rc = ata_do_reset(link, reset, classes, deadline); | 2196 | if (rc && rc != -EAGAIN) |
2197 | goto fail; | ||
2198 | } else { | ||
2199 | if (verbose) | ||
2200 | ata_link_printk(link, KERN_INFO, "no reset method " | ||
2201 | "available, skipping reset\n"); | ||
2202 | if (!(lflags & ATA_LFLAG_ASSUME_CLASS)) | ||
2203 | lflags |= ATA_LFLAG_ASSUME_ATA; | ||
2210 | } | 2204 | } |
2211 | 2205 | ||
2212 | /* -EAGAIN can happen if we skipped followup SRST */ | 2206 | /* |
2213 | if (rc && rc != -EAGAIN) | 2207 | * Post-reset processing |
2214 | goto fail; | 2208 | */ |
2215 | |||
2216 | done: | ||
2217 | ata_link_for_each_dev(dev, link) { | 2209 | ata_link_for_each_dev(dev, link) { |
2218 | /* After the reset, the device state is PIO 0 and the | 2210 | /* After the reset, the device state is PIO 0 and the |
2219 | * controller state is undefined. Reset also wakes up | 2211 | * controller state is undefined. Reset also wakes up |
@@ -2236,9 +2228,53 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
2236 | if (sata_scr_read(link, SCR_STATUS, &sstatus) == 0) | 2228 | if (sata_scr_read(link, SCR_STATUS, &sstatus) == 0) |
2237 | link->sata_spd = (sstatus >> 4) & 0xf; | 2229 | link->sata_spd = (sstatus >> 4) & 0xf; |
2238 | 2230 | ||
2231 | /* thaw the port */ | ||
2232 | if (ata_is_host_link(link)) | ||
2233 | ata_eh_thaw_port(ap); | ||
2234 | |||
2235 | /* postreset() should clear hardware SError. Although SError | ||
2236 | * is cleared during link resume, clearing SError here is | ||
2237 | * necessary as some PHYs raise hotplug events after SRST. | ||
2238 | * This introduces race condition where hotplug occurs between | ||
2239 | * reset and here. This race is mediated by cross checking | ||
2240 | * link onlineness and classification result later. | ||
2241 | */ | ||
2239 | if (postreset) | 2242 | if (postreset) |
2240 | postreset(link, classes); | 2243 | postreset(link, classes); |
2241 | 2244 | ||
2245 | /* clear cached SError */ | ||
2246 | spin_lock_irqsave(link->ap->lock, flags); | ||
2247 | link->eh_info.serror = 0; | ||
2248 | spin_unlock_irqrestore(link->ap->lock, flags); | ||
2249 | |||
2250 | /* Make sure onlineness and classification result correspond. | ||
2251 | * Hotplug could have happened during reset and some | ||
2252 | * controllers fail to wait while a drive is spinning up after | ||
2253 | * being hotplugged causing misdetection. By cross checking | ||
2254 | * link onlineness and classification result, those conditions | ||
2255 | * can be reliably detected and retried. | ||
2256 | */ | ||
2257 | nr_known = 0; | ||
2258 | ata_link_for_each_dev(dev, link) { | ||
2259 | /* convert all ATA_DEV_UNKNOWN to ATA_DEV_NONE */ | ||
2260 | if (classes[dev->devno] == ATA_DEV_UNKNOWN) | ||
2261 | classes[dev->devno] = ATA_DEV_NONE; | ||
2262 | else | ||
2263 | nr_known++; | ||
2264 | } | ||
2265 | |||
2266 | if (classify && !nr_known && ata_link_online(link)) { | ||
2267 | if (try < max_tries) { | ||
2268 | ata_link_printk(link, KERN_WARNING, "link online but " | ||
2269 | "device misclassified, retrying\n"); | ||
2270 | rc = -EAGAIN; | ||
2271 | goto fail; | ||
2272 | } | ||
2273 | ata_link_printk(link, KERN_WARNING, | ||
2274 | "link online but device misclassified, " | ||
2275 | "device detection might fail\n"); | ||
2276 | } | ||
2277 | |||
2242 | /* reset successful, schedule revalidation */ | 2278 | /* reset successful, schedule revalidation */ |
2243 | ata_eh_done(link, NULL, ATA_EH_RESET); | 2279 | ata_eh_done(link, NULL, ATA_EH_RESET); |
2244 | ehc->i.action |= ATA_EH_REVALIDATE; | 2280 | ehc->i.action |= ATA_EH_REVALIDATE; |
@@ -2587,7 +2623,7 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, | |||
2587 | struct ata_link *link; | 2623 | struct ata_link *link; |
2588 | struct ata_device *dev; | 2624 | struct ata_device *dev; |
2589 | int nr_failed_devs, nr_disabled_devs; | 2625 | int nr_failed_devs, nr_disabled_devs; |
2590 | int reset, rc; | 2626 | int rc; |
2591 | unsigned long flags; | 2627 | unsigned long flags; |
2592 | 2628 | ||
2593 | DPRINTK("ENTER\n"); | 2629 | DPRINTK("ENTER\n"); |
@@ -2630,7 +2666,6 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, | |||
2630 | rc = 0; | 2666 | rc = 0; |
2631 | nr_failed_devs = 0; | 2667 | nr_failed_devs = 0; |
2632 | nr_disabled_devs = 0; | 2668 | nr_disabled_devs = 0; |
2633 | reset = 0; | ||
2634 | 2669 | ||
2635 | /* if UNLOADING, finish immediately */ | 2670 | /* if UNLOADING, finish immediately */ |
2636 | if (ap->pflags & ATA_PFLAG_UNLOADING) | 2671 | if (ap->pflags & ATA_PFLAG_UNLOADING) |
@@ -2644,40 +2679,24 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, | |||
2644 | if (ata_eh_skip_recovery(link)) | 2679 | if (ata_eh_skip_recovery(link)) |
2645 | ehc->i.action = 0; | 2680 | ehc->i.action = 0; |
2646 | 2681 | ||
2647 | /* do we need to reset? */ | ||
2648 | if (ehc->i.action & ATA_EH_RESET) | ||
2649 | reset = 1; | ||
2650 | |||
2651 | ata_link_for_each_dev(dev, link) | 2682 | ata_link_for_each_dev(dev, link) |
2652 | ehc->classes[dev->devno] = ATA_DEV_UNKNOWN; | 2683 | ehc->classes[dev->devno] = ATA_DEV_UNKNOWN; |
2653 | } | 2684 | } |
2654 | 2685 | ||
2655 | /* reset */ | 2686 | /* reset */ |
2656 | if (reset) { | 2687 | ata_port_for_each_link(link, ap) { |
2657 | /* if PMP is attached, this function only deals with | 2688 | struct ata_eh_context *ehc = &link->eh_context; |
2658 | * downstream links, port should stay thawed. | ||
2659 | */ | ||
2660 | if (!sata_pmp_attached(ap)) | ||
2661 | ata_eh_freeze_port(ap); | ||
2662 | |||
2663 | ata_port_for_each_link(link, ap) { | ||
2664 | struct ata_eh_context *ehc = &link->eh_context; | ||
2665 | 2689 | ||
2666 | if (!(ehc->i.action & ATA_EH_RESET)) | 2690 | if (!(ehc->i.action & ATA_EH_RESET)) |
2667 | continue; | 2691 | continue; |
2668 | 2692 | ||
2669 | rc = ata_eh_reset(link, ata_link_nr_vacant(link), | 2693 | rc = ata_eh_reset(link, ata_link_nr_vacant(link), |
2670 | prereset, softreset, hardreset, | 2694 | prereset, softreset, hardreset, postreset); |
2671 | postreset); | 2695 | if (rc) { |
2672 | if (rc) { | 2696 | ata_link_printk(link, KERN_ERR, |
2673 | ata_link_printk(link, KERN_ERR, | 2697 | "reset failed, giving up\n"); |
2674 | "reset failed, giving up\n"); | 2698 | goto out; |
2675 | goto out; | ||
2676 | } | ||
2677 | } | 2699 | } |
2678 | |||
2679 | if (!sata_pmp_attached(ap)) | ||
2680 | ata_eh_thaw_port(ap); | ||
2681 | } | 2700 | } |
2682 | 2701 | ||
2683 | /* the rest */ | 2702 | /* the rest */ |
diff --git a/drivers/ata/libata-pmp.c b/drivers/ata/libata-pmp.c index ff1822a7da38..7daf4c0f6216 100644 --- a/drivers/ata/libata-pmp.c +++ b/drivers/ata/libata-pmp.c | |||
@@ -48,7 +48,7 @@ static unsigned int sata_pmp_read(struct ata_link *link, int reg, u32 *r_val) | |||
48 | tf.device = link->pmp; | 48 | tf.device = link->pmp; |
49 | 49 | ||
50 | err_mask = ata_exec_internal(pmp_dev, &tf, NULL, DMA_NONE, NULL, 0, | 50 | err_mask = ata_exec_internal(pmp_dev, &tf, NULL, DMA_NONE, NULL, 0, |
51 | SATA_PMP_SCR_TIMEOUT); | 51 | SATA_PMP_RW_TIMEOUT); |
52 | if (err_mask) | 52 | if (err_mask) |
53 | return err_mask; | 53 | return err_mask; |
54 | 54 | ||
@@ -88,7 +88,7 @@ static unsigned int sata_pmp_write(struct ata_link *link, int reg, u32 val) | |||
88 | tf.lbah = (val >> 24) & 0xff; | 88 | tf.lbah = (val >> 24) & 0xff; |
89 | 89 | ||
90 | return ata_exec_internal(pmp_dev, &tf, NULL, DMA_NONE, NULL, 0, | 90 | return ata_exec_internal(pmp_dev, &tf, NULL, DMA_NONE, NULL, 0, |
91 | SATA_PMP_SCR_TIMEOUT); | 91 | SATA_PMP_RW_TIMEOUT); |
92 | } | 92 | } |
93 | 93 | ||
94 | /** | 94 | /** |
@@ -257,19 +257,6 @@ static int sata_pmp_configure(struct ata_device *dev, int print_info) | |||
257 | goto fail; | 257 | goto fail; |
258 | } | 258 | } |
259 | 259 | ||
260 | /* turn off notification till fan-out ports are reset and configured */ | ||
261 | if (gscr[SATA_PMP_GSCR_FEAT_EN] & SATA_PMP_FEAT_NOTIFY) { | ||
262 | gscr[SATA_PMP_GSCR_FEAT_EN] &= ~SATA_PMP_FEAT_NOTIFY; | ||
263 | |||
264 | err_mask = sata_pmp_write(dev->link, SATA_PMP_GSCR_FEAT_EN, | ||
265 | gscr[SATA_PMP_GSCR_FEAT_EN]); | ||
266 | if (err_mask) { | ||
267 | rc = -EIO; | ||
268 | reason = "failed to write GSCR_FEAT_EN"; | ||
269 | goto fail; | ||
270 | } | ||
271 | } | ||
272 | |||
273 | if (print_info) { | 260 | if (print_info) { |
274 | ata_dev_printk(dev, KERN_INFO, "Port Multiplier %s, " | 261 | ata_dev_printk(dev, KERN_INFO, "Port Multiplier %s, " |
275 | "0x%04x:0x%04x r%d, %d ports, feat 0x%x/0x%x\n", | 262 | "0x%04x:0x%04x r%d, %d ports, feat 0x%x/0x%x\n", |
@@ -335,9 +322,12 @@ static void sata_pmp_quirks(struct ata_port *ap) | |||
335 | if (vendor == 0x1095 && devid == 0x3726) { | 322 | if (vendor == 0x1095 && devid == 0x3726) { |
336 | /* sil3726 quirks */ | 323 | /* sil3726 quirks */ |
337 | ata_port_for_each_link(link, ap) { | 324 | ata_port_for_each_link(link, ap) { |
338 | /* class code report is unreliable */ | 325 | /* Class code report is unreliable and SRST |
326 | * times out under certain configurations. | ||
327 | */ | ||
339 | if (link->pmp < 5) | 328 | if (link->pmp < 5) |
340 | link->flags |= ATA_LFLAG_ASSUME_ATA; | 329 | link->flags |= ATA_LFLAG_NO_SRST | |
330 | ATA_LFLAG_ASSUME_ATA; | ||
341 | 331 | ||
342 | /* port 5 is for SEMB device and it doesn't like SRST */ | 332 | /* port 5 is for SEMB device and it doesn't like SRST */ |
343 | if (link->pmp == 5) | 333 | if (link->pmp == 5) |
@@ -700,8 +690,6 @@ static int sata_pmp_eh_recover_pmp(struct ata_port *ap, | |||
700 | if (ehc->i.action & ATA_EH_RESET) { | 690 | if (ehc->i.action & ATA_EH_RESET) { |
701 | struct ata_link *tlink; | 691 | struct ata_link *tlink; |
702 | 692 | ||
703 | ata_eh_freeze_port(ap); | ||
704 | |||
705 | /* reset */ | 693 | /* reset */ |
706 | rc = ata_eh_reset(link, 0, prereset, softreset, hardreset, | 694 | rc = ata_eh_reset(link, 0, prereset, softreset, hardreset, |
707 | postreset); | 695 | postreset); |
@@ -711,8 +699,6 @@ static int sata_pmp_eh_recover_pmp(struct ata_port *ap, | |||
711 | goto fail; | 699 | goto fail; |
712 | } | 700 | } |
713 | 701 | ||
714 | ata_eh_thaw_port(ap); | ||
715 | |||
716 | /* PMP is reset, SErrors cannot be trusted, scan all */ | 702 | /* PMP is reset, SErrors cannot be trusted, scan all */ |
717 | ata_port_for_each_link(tlink, ap) { | 703 | ata_port_for_each_link(tlink, ap) { |
718 | struct ata_eh_context *ehc = &tlink->eh_context; | 704 | struct ata_eh_context *ehc = &tlink->eh_context; |
@@ -864,6 +850,7 @@ static int sata_pmp_eh_recover(struct ata_port *ap) | |||
864 | struct ata_link *pmp_link = &ap->link; | 850 | struct ata_link *pmp_link = &ap->link; |
865 | struct ata_device *pmp_dev = pmp_link->device; | 851 | struct ata_device *pmp_dev = pmp_link->device; |
866 | struct ata_eh_context *pmp_ehc = &pmp_link->eh_context; | 852 | struct ata_eh_context *pmp_ehc = &pmp_link->eh_context; |
853 | u32 *gscr = pmp_dev->gscr; | ||
867 | struct ata_link *link; | 854 | struct ata_link *link; |
868 | struct ata_device *dev; | 855 | struct ata_device *dev; |
869 | unsigned int err_mask; | 856 | unsigned int err_mask; |
@@ -901,6 +888,22 @@ static int sata_pmp_eh_recover(struct ata_port *ap) | |||
901 | if (rc) | 888 | if (rc) |
902 | goto pmp_fail; | 889 | goto pmp_fail; |
903 | 890 | ||
891 | /* PHY event notification can disturb reset and other recovery | ||
892 | * operations. Turn it off. | ||
893 | */ | ||
894 | if (gscr[SATA_PMP_GSCR_FEAT_EN] & SATA_PMP_FEAT_NOTIFY) { | ||
895 | gscr[SATA_PMP_GSCR_FEAT_EN] &= ~SATA_PMP_FEAT_NOTIFY; | ||
896 | |||
897 | err_mask = sata_pmp_write(pmp_link, SATA_PMP_GSCR_FEAT_EN, | ||
898 | gscr[SATA_PMP_GSCR_FEAT_EN]); | ||
899 | if (err_mask) { | ||
900 | ata_link_printk(pmp_link, KERN_WARNING, | ||
901 | "failed to disable NOTIFY (err_mask=0x%x)\n", | ||
902 | err_mask); | ||
903 | goto pmp_fail; | ||
904 | } | ||
905 | } | ||
906 | |||
904 | /* handle disabled links */ | 907 | /* handle disabled links */ |
905 | rc = sata_pmp_eh_handle_disabled_links(ap); | 908 | rc = sata_pmp_eh_handle_disabled_links(ap); |
906 | if (rc) | 909 | if (rc) |
@@ -923,10 +926,10 @@ static int sata_pmp_eh_recover(struct ata_port *ap) | |||
923 | 926 | ||
924 | /* enable notification */ | 927 | /* enable notification */ |
925 | if (pmp_dev->flags & ATA_DFLAG_AN) { | 928 | if (pmp_dev->flags & ATA_DFLAG_AN) { |
926 | pmp_dev->gscr[SATA_PMP_GSCR_FEAT_EN] |= SATA_PMP_FEAT_NOTIFY; | 929 | gscr[SATA_PMP_GSCR_FEAT_EN] |= SATA_PMP_FEAT_NOTIFY; |
927 | 930 | ||
928 | err_mask = sata_pmp_write(pmp_dev->link, SATA_PMP_GSCR_FEAT_EN, | 931 | err_mask = sata_pmp_write(pmp_link, SATA_PMP_GSCR_FEAT_EN, |
929 | pmp_dev->gscr[SATA_PMP_GSCR_FEAT_EN]); | 932 | gscr[SATA_PMP_GSCR_FEAT_EN]); |
930 | if (err_mask) { | 933 | if (err_mask) { |
931 | ata_dev_printk(pmp_dev, KERN_ERR, "failed to write " | 934 | ata_dev_printk(pmp_dev, KERN_ERR, "failed to write " |
932 | "PMP_FEAT_EN (Emask=0x%x)\n", err_mask); | 935 | "PMP_FEAT_EN (Emask=0x%x)\n", err_mask); |
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 3ce43920e459..2e6e1622dc6d 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c | |||
@@ -1082,12 +1082,6 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc) | |||
1082 | if (((cdb[4] >> 4) & 0xf) != 0) | 1082 | if (((cdb[4] >> 4) & 0xf) != 0) |
1083 | goto invalid_fld; /* power conditions not supported */ | 1083 | goto invalid_fld; /* power conditions not supported */ |
1084 | 1084 | ||
1085 | if (qc->dev->horkage & ATA_HORKAGE_SKIP_PM) { | ||
1086 | /* the device lacks PM support, finish without doing anything */ | ||
1087 | scmd->result = SAM_STAT_GOOD; | ||
1088 | return 1; | ||
1089 | } | ||
1090 | |||
1091 | if (cdb[4] & 0x1) { | 1085 | if (cdb[4] & 0x1) { |
1092 | tf->nsect = 1; /* 1 sector, lba=0 */ | 1086 | tf->nsect = 1; /* 1 sector, lba=0 */ |
1093 | 1087 | ||
@@ -1643,6 +1637,7 @@ defer: | |||
1643 | 1637 | ||
1644 | /** | 1638 | /** |
1645 | * ata_scsi_rbuf_get - Map response buffer. | 1639 | * ata_scsi_rbuf_get - Map response buffer. |
1640 | * @cmd: SCSI command containing buffer to be mapped. | ||
1646 | * @flags: unsigned long variable to store irq enable status | 1641 | * @flags: unsigned long variable to store irq enable status |
1647 | * @copy_in: copy in from user buffer | 1642 | * @copy_in: copy in from user buffer |
1648 | * | 1643 | * |
@@ -1960,7 +1955,7 @@ static unsigned int ata_msense_ctl_mode(u8 *buf) | |||
1960 | 1955 | ||
1961 | /** | 1956 | /** |
1962 | * ata_msense_rw_recovery - Simulate MODE SENSE r/w error recovery page | 1957 | * ata_msense_rw_recovery - Simulate MODE SENSE r/w error recovery page |
1963 | * @bufp: output buffer | 1958 | * @buf: output buffer |
1964 | * | 1959 | * |
1965 | * Generate a generic MODE SENSE r/w error recovery page. | 1960 | * Generate a generic MODE SENSE r/w error recovery page. |
1966 | * | 1961 | * |
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 3c2d2289f85e..215d18672a5a 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c | |||
@@ -247,7 +247,7 @@ u8 ata_sff_check_status(struct ata_port *ap) | |||
247 | * LOCKING: | 247 | * LOCKING: |
248 | * Inherited from caller. | 248 | * Inherited from caller. |
249 | */ | 249 | */ |
250 | u8 ata_sff_altstatus(struct ata_port *ap) | 250 | static u8 ata_sff_altstatus(struct ata_port *ap) |
251 | { | 251 | { |
252 | if (ap->ops->sff_check_altstatus) | 252 | if (ap->ops->sff_check_altstatus) |
253 | return ap->ops->sff_check_altstatus(ap); | 253 | return ap->ops->sff_check_altstatus(ap); |
@@ -256,6 +256,93 @@ u8 ata_sff_altstatus(struct ata_port *ap) | |||
256 | } | 256 | } |
257 | 257 | ||
258 | /** | 258 | /** |
259 | * ata_sff_irq_status - Check if the device is busy | ||
260 | * @ap: port where the device is | ||
261 | * | ||
262 | * Determine if the port is currently busy. Uses altstatus | ||
263 | * if available in order to avoid clearing shared IRQ status | ||
264 | * when finding an IRQ source. Non ctl capable devices don't | ||
265 | * share interrupt lines fortunately for us. | ||
266 | * | ||
267 | * LOCKING: | ||
268 | * Inherited from caller. | ||
269 | */ | ||
270 | static u8 ata_sff_irq_status(struct ata_port *ap) | ||
271 | { | ||
272 | u8 status; | ||
273 | |||
274 | if (ap->ops->sff_check_altstatus || ap->ioaddr.altstatus_addr) { | ||
275 | status = ata_sff_altstatus(ap); | ||
276 | /* Not us: We are busy */ | ||
277 | if (status & ATA_BUSY) | ||
278 | return status; | ||
279 | } | ||
280 | /* Clear INTRQ latch */ | ||
281 | status = ap->ops->sff_check_status(ap); | ||
282 | return status; | ||
283 | } | ||
284 | |||
285 | /** | ||
286 | * ata_sff_sync - Flush writes | ||
287 | * @ap: Port to wait for. | ||
288 | * | ||
289 | * CAUTION: | ||
290 | * If we have an mmio device with no ctl and no altstatus | ||
291 | * method this will fail. No such devices are known to exist. | ||
292 | * | ||
293 | * LOCKING: | ||
294 | * Inherited from caller. | ||
295 | */ | ||
296 | |||
297 | static void ata_sff_sync(struct ata_port *ap) | ||
298 | { | ||
299 | if (ap->ops->sff_check_altstatus) | ||
300 | ap->ops->sff_check_altstatus(ap); | ||
301 | else if (ap->ioaddr.altstatus_addr) | ||
302 | ioread8(ap->ioaddr.altstatus_addr); | ||
303 | } | ||
304 | |||
305 | /** | ||
306 | * ata_sff_pause - Flush writes and wait 400nS | ||
307 | * @ap: Port to pause for. | ||
308 | * | ||
309 | * CAUTION: | ||
310 | * If we have an mmio device with no ctl and no altstatus | ||
311 | * method this will fail. No such devices are known to exist. | ||
312 | * | ||
313 | * LOCKING: | ||
314 | * Inherited from caller. | ||
315 | */ | ||
316 | |||
317 | void ata_sff_pause(struct ata_port *ap) | ||
318 | { | ||
319 | ata_sff_sync(ap); | ||
320 | ndelay(400); | ||
321 | } | ||
322 | |||
323 | /** | ||
324 | * ata_sff_dma_pause - Pause before commencing DMA | ||
325 | * @ap: Port to pause for. | ||
326 | * | ||
327 | * Perform I/O fencing and ensure sufficient cycle delays occur | ||
328 | * for the HDMA1:0 transition | ||
329 | */ | ||
330 | |||
331 | void ata_sff_dma_pause(struct ata_port *ap) | ||
332 | { | ||
333 | if (ap->ops->sff_check_altstatus || ap->ioaddr.altstatus_addr) { | ||
334 | /* An altstatus read will cause the needed delay without | ||
335 | messing up the IRQ status */ | ||
336 | ata_sff_altstatus(ap); | ||
337 | return; | ||
338 | } | ||
339 | /* There are no DMA controllers without ctl. BUG here to ensure | ||
340 | we never violate the HDMA1:0 transition timing and risk | ||
341 | corruption. */ | ||
342 | BUG(); | ||
343 | } | ||
344 | |||
345 | /** | ||
259 | * ata_sff_busy_sleep - sleep until BSY clears, or timeout | 346 | * ata_sff_busy_sleep - sleep until BSY clears, or timeout |
260 | * @ap: port containing status register to be polled | 347 | * @ap: port containing status register to be polled |
261 | * @tmout_pat: impatience timeout | 348 | * @tmout_pat: impatience timeout |
@@ -742,7 +829,7 @@ static void ata_pio_sectors(struct ata_queued_cmd *qc) | |||
742 | } else | 829 | } else |
743 | ata_pio_sector(qc); | 830 | ata_pio_sector(qc); |
744 | 831 | ||
745 | ata_sff_altstatus(qc->ap); /* flush */ | 832 | ata_sff_sync(qc->ap); /* flush */ |
746 | } | 833 | } |
747 | 834 | ||
748 | /** | 835 | /** |
@@ -763,8 +850,9 @@ static void atapi_send_cdb(struct ata_port *ap, struct ata_queued_cmd *qc) | |||
763 | WARN_ON(qc->dev->cdb_len < 12); | 850 | WARN_ON(qc->dev->cdb_len < 12); |
764 | 851 | ||
765 | ap->ops->sff_data_xfer(qc->dev, qc->cdb, qc->dev->cdb_len, 1); | 852 | ap->ops->sff_data_xfer(qc->dev, qc->cdb, qc->dev->cdb_len, 1); |
766 | ata_sff_altstatus(ap); /* flush */ | 853 | ata_sff_sync(ap); |
767 | 854 | /* FIXME: If the CDB is for DMA do we need to do the transition delay | |
855 | or is bmdma_start guaranteed to do it ? */ | ||
768 | switch (qc->tf.protocol) { | 856 | switch (qc->tf.protocol) { |
769 | case ATAPI_PROT_PIO: | 857 | case ATAPI_PROT_PIO: |
770 | ap->hsm_task_state = HSM_ST; | 858 | ap->hsm_task_state = HSM_ST; |
@@ -905,7 +993,7 @@ static void atapi_pio_bytes(struct ata_queued_cmd *qc) | |||
905 | 993 | ||
906 | if (unlikely(__atapi_pio_bytes(qc, bytes))) | 994 | if (unlikely(__atapi_pio_bytes(qc, bytes))) |
907 | goto err_out; | 995 | goto err_out; |
908 | ata_sff_altstatus(ap); /* flush */ | 996 | ata_sff_sync(ap); /* flush */ |
909 | 997 | ||
910 | return; | 998 | return; |
911 | 999 | ||
@@ -1489,14 +1577,10 @@ inline unsigned int ata_sff_host_intr(struct ata_port *ap, | |||
1489 | goto idle_irq; | 1577 | goto idle_irq; |
1490 | } | 1578 | } |
1491 | 1579 | ||
1492 | /* check altstatus */ | ||
1493 | status = ata_sff_altstatus(ap); | ||
1494 | if (status & ATA_BUSY) | ||
1495 | goto idle_irq; | ||
1496 | 1580 | ||
1497 | /* check main status, clearing INTRQ */ | 1581 | /* check main status, clearing INTRQ if needed */ |
1498 | status = ap->ops->sff_check_status(ap); | 1582 | status = ata_sff_irq_status(ap); |
1499 | if (unlikely(status & ATA_BUSY)) | 1583 | if (status & ATA_BUSY) |
1500 | goto idle_irq; | 1584 | goto idle_irq; |
1501 | 1585 | ||
1502 | /* ack bmdma irq events */ | 1586 | /* ack bmdma irq events */ |
@@ -2030,7 +2114,7 @@ void ata_sff_error_handler(struct ata_port *ap) | |||
2030 | ap->ops->bmdma_stop(qc); | 2114 | ap->ops->bmdma_stop(qc); |
2031 | } | 2115 | } |
2032 | 2116 | ||
2033 | ata_sff_altstatus(ap); | 2117 | ata_sff_sync(ap); /* FIXME: We don't need this */ |
2034 | ap->ops->sff_check_status(ap); | 2118 | ap->ops->sff_check_status(ap); |
2035 | ap->ops->sff_irq_clear(ap); | 2119 | ap->ops->sff_irq_clear(ap); |
2036 | 2120 | ||
@@ -2203,7 +2287,7 @@ void ata_bmdma_stop(struct ata_queued_cmd *qc) | |||
2203 | mmio + ATA_DMA_CMD); | 2287 | mmio + ATA_DMA_CMD); |
2204 | 2288 | ||
2205 | /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */ | 2289 | /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */ |
2206 | ata_sff_altstatus(ap); /* dummy read */ | 2290 | ata_sff_dma_pause(ap); |
2207 | } | 2291 | } |
2208 | 2292 | ||
2209 | /** | 2293 | /** |
@@ -2722,7 +2806,8 @@ EXPORT_SYMBOL_GPL(ata_sff_qc_prep); | |||
2722 | EXPORT_SYMBOL_GPL(ata_sff_dumb_qc_prep); | 2806 | EXPORT_SYMBOL_GPL(ata_sff_dumb_qc_prep); |
2723 | EXPORT_SYMBOL_GPL(ata_sff_dev_select); | 2807 | EXPORT_SYMBOL_GPL(ata_sff_dev_select); |
2724 | EXPORT_SYMBOL_GPL(ata_sff_check_status); | 2808 | EXPORT_SYMBOL_GPL(ata_sff_check_status); |
2725 | EXPORT_SYMBOL_GPL(ata_sff_altstatus); | 2809 | EXPORT_SYMBOL_GPL(ata_sff_dma_pause); |
2810 | EXPORT_SYMBOL_GPL(ata_sff_pause); | ||
2726 | EXPORT_SYMBOL_GPL(ata_sff_busy_sleep); | 2811 | EXPORT_SYMBOL_GPL(ata_sff_busy_sleep); |
2727 | EXPORT_SYMBOL_GPL(ata_sff_wait_ready); | 2812 | EXPORT_SYMBOL_GPL(ata_sff_wait_ready); |
2728 | EXPORT_SYMBOL_GPL(ata_sff_tf_load); | 2813 | EXPORT_SYMBOL_GPL(ata_sff_tf_load); |
diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c index fcabe46f262b..0f3e659db99a 100644 --- a/drivers/ata/pata_ali.c +++ b/drivers/ata/pata_ali.c | |||
@@ -177,11 +177,11 @@ static void ali_program_modes(struct ata_port *ap, struct ata_device *adev, stru | |||
177 | u8 udma; | 177 | u8 udma; |
178 | 178 | ||
179 | if (t != NULL) { | 179 | if (t != NULL) { |
180 | t->setup = FIT(t->setup, 1, 8) & 7; | 180 | t->setup = clamp_val(t->setup, 1, 8) & 7; |
181 | t->act8b = FIT(t->act8b, 1, 8) & 7; | 181 | t->act8b = clamp_val(t->act8b, 1, 8) & 7; |
182 | t->rec8b = FIT(t->rec8b, 1, 16) & 15; | 182 | t->rec8b = clamp_val(t->rec8b, 1, 16) & 15; |
183 | t->active = FIT(t->active, 1, 8) & 7; | 183 | t->active = clamp_val(t->active, 1, 8) & 7; |
184 | t->recover = FIT(t->recover, 1, 16) & 15; | 184 | t->recover = clamp_val(t->recover, 1, 16) & 15; |
185 | 185 | ||
186 | pci_write_config_byte(pdev, cas, t->setup); | 186 | pci_write_config_byte(pdev, cas, t->setup); |
187 | pci_write_config_byte(pdev, cbt, (t->act8b << 4) | t->rec8b); | 187 | pci_write_config_byte(pdev, cbt, (t->act8b << 4) | t->rec8b); |
diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c index 26665c396485..57dd00f463d3 100644 --- a/drivers/ata/pata_amd.c +++ b/drivers/ata/pata_amd.c | |||
@@ -84,32 +84,32 @@ static void timing_setup(struct ata_port *ap, struct ata_device *adev, int offse | |||
84 | 84 | ||
85 | /* Configure the address set up timing */ | 85 | /* Configure the address set up timing */ |
86 | pci_read_config_byte(pdev, offset + 0x0C, &t); | 86 | pci_read_config_byte(pdev, offset + 0x0C, &t); |
87 | t = (t & ~(3 << ((3 - dn) << 1))) | ((FIT(at.setup, 1, 4) - 1) << ((3 - dn) << 1)); | 87 | t = (t & ~(3 << ((3 - dn) << 1))) | ((clamp_val(at.setup, 1, 4) - 1) << ((3 - dn) << 1)); |
88 | pci_write_config_byte(pdev, offset + 0x0C , t); | 88 | pci_write_config_byte(pdev, offset + 0x0C , t); |
89 | 89 | ||
90 | /* Configure the 8bit I/O timing */ | 90 | /* Configure the 8bit I/O timing */ |
91 | pci_write_config_byte(pdev, offset + 0x0E + (1 - (dn >> 1)), | 91 | pci_write_config_byte(pdev, offset + 0x0E + (1 - (dn >> 1)), |
92 | ((FIT(at.act8b, 1, 16) - 1) << 4) | (FIT(at.rec8b, 1, 16) - 1)); | 92 | ((clamp_val(at.act8b, 1, 16) - 1) << 4) | (clamp_val(at.rec8b, 1, 16) - 1)); |
93 | 93 | ||
94 | /* Drive timing */ | 94 | /* Drive timing */ |
95 | pci_write_config_byte(pdev, offset + 0x08 + (3 - dn), | 95 | pci_write_config_byte(pdev, offset + 0x08 + (3 - dn), |
96 | ((FIT(at.active, 1, 16) - 1) << 4) | (FIT(at.recover, 1, 16) - 1)); | 96 | ((clamp_val(at.active, 1, 16) - 1) << 4) | (clamp_val(at.recover, 1, 16) - 1)); |
97 | 97 | ||
98 | switch (clock) { | 98 | switch (clock) { |
99 | case 1: | 99 | case 1: |
100 | t = at.udma ? (0xc0 | (FIT(at.udma, 2, 5) - 2)) : 0x03; | 100 | t = at.udma ? (0xc0 | (clamp_val(at.udma, 2, 5) - 2)) : 0x03; |
101 | break; | 101 | break; |
102 | 102 | ||
103 | case 2: | 103 | case 2: |
104 | t = at.udma ? (0xc0 | amd_cyc2udma[FIT(at.udma, 2, 10)]) : 0x03; | 104 | t = at.udma ? (0xc0 | amd_cyc2udma[clamp_val(at.udma, 2, 10)]) : 0x03; |
105 | break; | 105 | break; |
106 | 106 | ||
107 | case 3: | 107 | case 3: |
108 | t = at.udma ? (0xc0 | amd_cyc2udma[FIT(at.udma, 1, 10)]) : 0x03; | 108 | t = at.udma ? (0xc0 | amd_cyc2udma[clamp_val(at.udma, 1, 10)]) : 0x03; |
109 | break; | 109 | break; |
110 | 110 | ||
111 | case 4: | 111 | case 4: |
112 | t = at.udma ? (0xc0 | amd_cyc2udma[FIT(at.udma, 1, 15)]) : 0x03; | 112 | t = at.udma ? (0xc0 | amd_cyc2udma[clamp_val(at.udma, 1, 15)]) : 0x03; |
113 | break; | 113 | break; |
114 | 114 | ||
115 | default: | 115 | default: |
diff --git a/drivers/ata/pata_at32.c b/drivers/ata/pata_at32.c index 5e104385d6a3..82fb6e273169 100644 --- a/drivers/ata/pata_at32.c +++ b/drivers/ata/pata_at32.c | |||
@@ -291,8 +291,6 @@ static int __init pata_at32_probe(struct platform_device *pdev) | |||
291 | if (!info) | 291 | if (!info) |
292 | return -ENOMEM; | 292 | return -ENOMEM; |
293 | 293 | ||
294 | memset(info, 0, sizeof(struct at32_ide_info)); | ||
295 | |||
296 | info->irq = irq; | 294 | info->irq = irq; |
297 | info->cs = board->cs; | 295 | info->cs = board->cs; |
298 | 296 | ||
diff --git a/drivers/ata/pata_bf54x.c b/drivers/ata/pata_bf54x.c index 9ab89732cf94..55516103626a 100644 --- a/drivers/ata/pata_bf54x.c +++ b/drivers/ata/pata_bf54x.c | |||
@@ -911,7 +911,10 @@ static void bfin_bmdma_start(struct ata_queued_cmd *qc) | |||
911 | /* Reset all transfer count */ | 911 | /* Reset all transfer count */ |
912 | ATAPI_SET_CONTROL(base, ATAPI_GET_CONTROL(base) | TFRCNT_RST); | 912 | ATAPI_SET_CONTROL(base, ATAPI_GET_CONTROL(base) | TFRCNT_RST); |
913 | 913 | ||
914 | /* Set transfer length to buffer len */ | 914 | /* Set ATAPI state machine contorl in terminate sequence */ |
915 | ATAPI_SET_CONTROL(base, ATAPI_GET_CONTROL(base) | END_ON_TERM); | ||
916 | |||
917 | /* Set transfer length to buffer len */ | ||
915 | for_each_sg(qc->sg, sg, qc->n_elem, si) { | 918 | for_each_sg(qc->sg, sg, qc->n_elem, si) { |
916 | ATAPI_SET_XFER_LEN(base, (sg_dma_len(sg) >> 1)); | 919 | ATAPI_SET_XFER_LEN(base, (sg_dma_len(sg) >> 1)); |
917 | } | 920 | } |
diff --git a/drivers/ata/pata_cypress.c b/drivers/ata/pata_cypress.c index a9c3218e22fd..2ff62608ae37 100644 --- a/drivers/ata/pata_cypress.c +++ b/drivers/ata/pata_cypress.c | |||
@@ -62,14 +62,14 @@ static void cy82c693_set_piomode(struct ata_port *ap, struct ata_device *adev) | |||
62 | return; | 62 | return; |
63 | } | 63 | } |
64 | 64 | ||
65 | time_16 = FIT(t.recover, 0, 15) | (FIT(t.active, 0, 15) << 4); | 65 | time_16 = clamp_val(t.recover, 0, 15) | (clamp_val(t.active, 0, 15) << 4); |
66 | time_8 = FIT(t.act8b, 0, 15) | (FIT(t.rec8b, 0, 15) << 4); | 66 | time_8 = clamp_val(t.act8b, 0, 15) | (clamp_val(t.rec8b, 0, 15) << 4); |
67 | 67 | ||
68 | if (adev->devno == 0) { | 68 | if (adev->devno == 0) { |
69 | pci_read_config_dword(pdev, CY82_IDE_ADDRSETUP, &addr); | 69 | pci_read_config_dword(pdev, CY82_IDE_ADDRSETUP, &addr); |
70 | 70 | ||
71 | addr &= ~0x0F; /* Mask bits */ | 71 | addr &= ~0x0F; /* Mask bits */ |
72 | addr |= FIT(t.setup, 0, 15); | 72 | addr |= clamp_val(t.setup, 0, 15); |
73 | 73 | ||
74 | pci_write_config_dword(pdev, CY82_IDE_ADDRSETUP, addr); | 74 | pci_write_config_dword(pdev, CY82_IDE_ADDRSETUP, addr); |
75 | pci_write_config_byte(pdev, CY82_IDE_MASTER_IOR, time_16); | 75 | pci_write_config_byte(pdev, CY82_IDE_MASTER_IOR, time_16); |
@@ -79,7 +79,7 @@ static void cy82c693_set_piomode(struct ata_port *ap, struct ata_device *adev) | |||
79 | pci_read_config_dword(pdev, CY82_IDE_ADDRSETUP, &addr); | 79 | pci_read_config_dword(pdev, CY82_IDE_ADDRSETUP, &addr); |
80 | 80 | ||
81 | addr &= ~0xF0; /* Mask bits */ | 81 | addr &= ~0xF0; /* Mask bits */ |
82 | addr |= (FIT(t.setup, 0, 15) << 4); | 82 | addr |= (clamp_val(t.setup, 0, 15) << 4); |
83 | 83 | ||
84 | pci_write_config_dword(pdev, CY82_IDE_ADDRSETUP, addr); | 84 | pci_write_config_dword(pdev, CY82_IDE_ADDRSETUP, addr); |
85 | pci_write_config_byte(pdev, CY82_IDE_SLAVE_IOR, time_16); | 85 | pci_write_config_byte(pdev, CY82_IDE_SLAVE_IOR, time_16); |
diff --git a/drivers/ata/pata_icside.c b/drivers/ata/pata_icside.c index 17138436423d..cf9e9848f8b5 100644 --- a/drivers/ata/pata_icside.c +++ b/drivers/ata/pata_icside.c | |||
@@ -270,7 +270,7 @@ static void pata_icside_bmdma_stop(struct ata_queued_cmd *qc) | |||
270 | disable_dma(state->dma); | 270 | disable_dma(state->dma); |
271 | 271 | ||
272 | /* see ata_bmdma_stop */ | 272 | /* see ata_bmdma_stop */ |
273 | ata_sff_altstatus(ap); | 273 | ata_sff_dma_pause(ap); |
274 | } | 274 | } |
275 | 275 | ||
276 | static u8 pata_icside_bmdma_status(struct ata_port *ap) | 276 | static u8 pata_icside_bmdma_status(struct ata_port *ap) |
diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c index 7af4b29cc422..fe7cc8ed4ea4 100644 --- a/drivers/ata/pata_legacy.c +++ b/drivers/ata/pata_legacy.c | |||
@@ -343,8 +343,8 @@ static void ht6560a_set_piomode(struct ata_port *ap, struct ata_device *adev) | |||
343 | /* Get the timing data in cycles. For now play safe at 50Mhz */ | 343 | /* Get the timing data in cycles. For now play safe at 50Mhz */ |
344 | ata_timing_compute(adev, adev->pio_mode, &t, 20000, 1000); | 344 | ata_timing_compute(adev, adev->pio_mode, &t, 20000, 1000); |
345 | 345 | ||
346 | active = FIT(t.active, 2, 15); | 346 | active = clamp_val(t.active, 2, 15); |
347 | recover = FIT(t.recover, 4, 15); | 347 | recover = clamp_val(t.recover, 4, 15); |
348 | 348 | ||
349 | inb(0x3E6); | 349 | inb(0x3E6); |
350 | inb(0x3E6); | 350 | inb(0x3E6); |
@@ -377,8 +377,8 @@ static void ht6560b_set_piomode(struct ata_port *ap, struct ata_device *adev) | |||
377 | /* Get the timing data in cycles. For now play safe at 50Mhz */ | 377 | /* Get the timing data in cycles. For now play safe at 50Mhz */ |
378 | ata_timing_compute(adev, adev->pio_mode, &t, 20000, 1000); | 378 | ata_timing_compute(adev, adev->pio_mode, &t, 20000, 1000); |
379 | 379 | ||
380 | active = FIT(t.active, 2, 15); | 380 | active = clamp_val(t.active, 2, 15); |
381 | recover = FIT(t.recover, 2, 16); | 381 | recover = clamp_val(t.recover, 2, 16); |
382 | recover &= 0x15; | 382 | recover &= 0x15; |
383 | 383 | ||
384 | inb(0x3E6); | 384 | inb(0x3E6); |
@@ -462,9 +462,9 @@ static void opti82c611a_set_piomode(struct ata_port *ap, | |||
462 | ata_timing_merge(&t, &tp, &t, ATA_TIMING_SETUP); | 462 | ata_timing_merge(&t, &tp, &t, ATA_TIMING_SETUP); |
463 | } | 463 | } |
464 | 464 | ||
465 | active = FIT(t.active, 2, 17) - 2; | 465 | active = clamp_val(t.active, 2, 17) - 2; |
466 | recover = FIT(t.recover, 1, 16) - 1; | 466 | recover = clamp_val(t.recover, 1, 16) - 1; |
467 | setup = FIT(t.setup, 1, 4) - 1; | 467 | setup = clamp_val(t.setup, 1, 4) - 1; |
468 | 468 | ||
469 | /* Select the right timing bank for write timing */ | 469 | /* Select the right timing bank for write timing */ |
470 | rc = ioread8(ap->ioaddr.lbal_addr); | 470 | rc = ioread8(ap->ioaddr.lbal_addr); |
@@ -541,9 +541,9 @@ static void opti82c46x_set_piomode(struct ata_port *ap, struct ata_device *adev) | |||
541 | ata_timing_merge(&t, &tp, &t, ATA_TIMING_SETUP); | 541 | ata_timing_merge(&t, &tp, &t, ATA_TIMING_SETUP); |
542 | } | 542 | } |
543 | 543 | ||
544 | active = FIT(t.active, 2, 17) - 2; | 544 | active = clamp_val(t.active, 2, 17) - 2; |
545 | recover = FIT(t.recover, 1, 16) - 1; | 545 | recover = clamp_val(t.recover, 1, 16) - 1; |
546 | setup = FIT(t.setup, 1, 4) - 1; | 546 | setup = clamp_val(t.setup, 1, 4) - 1; |
547 | 547 | ||
548 | /* Select the right timing bank for write timing */ | 548 | /* Select the right timing bank for write timing */ |
549 | rc = ioread8(ap->ioaddr.lbal_addr); | 549 | rc = ioread8(ap->ioaddr.lbal_addr); |
@@ -624,11 +624,11 @@ static void qdi6500_set_piomode(struct ata_port *ap, struct ata_device *adev) | |||
624 | ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000); | 624 | ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000); |
625 | 625 | ||
626 | if (ld_qdi->fast) { | 626 | if (ld_qdi->fast) { |
627 | active = 8 - FIT(t.active, 1, 8); | 627 | active = 8 - clamp_val(t.active, 1, 8); |
628 | recovery = 18 - FIT(t.recover, 3, 18); | 628 | recovery = 18 - clamp_val(t.recover, 3, 18); |
629 | } else { | 629 | } else { |
630 | active = 9 - FIT(t.active, 2, 9); | 630 | active = 9 - clamp_val(t.active, 2, 9); |
631 | recovery = 15 - FIT(t.recover, 0, 15); | 631 | recovery = 15 - clamp_val(t.recover, 0, 15); |
632 | } | 632 | } |
633 | timing = (recovery << 4) | active | 0x08; | 633 | timing = (recovery << 4) | active | 0x08; |
634 | 634 | ||
@@ -658,11 +658,11 @@ static void qdi6580dp_set_piomode(struct ata_port *ap, struct ata_device *adev) | |||
658 | ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000); | 658 | ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000); |
659 | 659 | ||
660 | if (ld_qdi->fast) { | 660 | if (ld_qdi->fast) { |
661 | active = 8 - FIT(t.active, 1, 8); | 661 | active = 8 - clamp_val(t.active, 1, 8); |
662 | recovery = 18 - FIT(t.recover, 3, 18); | 662 | recovery = 18 - clamp_val(t.recover, 3, 18); |
663 | } else { | 663 | } else { |
664 | active = 9 - FIT(t.active, 2, 9); | 664 | active = 9 - clamp_val(t.active, 2, 9); |
665 | recovery = 15 - FIT(t.recover, 0, 15); | 665 | recovery = 15 - clamp_val(t.recover, 0, 15); |
666 | } | 666 | } |
667 | timing = (recovery << 4) | active | 0x08; | 667 | timing = (recovery << 4) | active | 0x08; |
668 | 668 | ||
@@ -695,11 +695,11 @@ static void qdi6580_set_piomode(struct ata_port *ap, struct ata_device *adev) | |||
695 | ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000); | 695 | ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000); |
696 | 696 | ||
697 | if (ld_qdi->fast) { | 697 | if (ld_qdi->fast) { |
698 | active = 8 - FIT(t.active, 1, 8); | 698 | active = 8 - clamp_val(t.active, 1, 8); |
699 | recovery = 18 - FIT(t.recover, 3, 18); | 699 | recovery = 18 - clamp_val(t.recover, 3, 18); |
700 | } else { | 700 | } else { |
701 | active = 9 - FIT(t.active, 2, 9); | 701 | active = 9 - clamp_val(t.active, 2, 9); |
702 | recovery = 15 - FIT(t.recover, 0, 15); | 702 | recovery = 15 - clamp_val(t.recover, 0, 15); |
703 | } | 703 | } |
704 | timing = (recovery << 4) | active | 0x08; | 704 | timing = (recovery << 4) | active | 0x08; |
705 | ld_qdi->clock[adev->devno] = timing; | 705 | ld_qdi->clock[adev->devno] = timing; |
@@ -830,8 +830,8 @@ static void winbond_set_piomode(struct ata_port *ap, struct ata_device *adev) | |||
830 | else | 830 | else |
831 | ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000); | 831 | ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000); |
832 | 832 | ||
833 | active = (FIT(t.active, 3, 17) - 1) & 0x0F; | 833 | active = (clamp_val(t.active, 3, 17) - 1) & 0x0F; |
834 | recovery = (FIT(t.recover, 1, 15) + 1) & 0x0F; | 834 | recovery = (clamp_val(t.recover, 1, 15) + 1) & 0x0F; |
835 | timing = (active << 4) | recovery; | 835 | timing = (active << 4) | recovery; |
836 | winbond_writecfg(ld_winbond->timing, timing, reg); | 836 | winbond_writecfg(ld_winbond->timing, timing, reg); |
837 | 837 | ||
@@ -842,7 +842,7 @@ static void winbond_set_piomode(struct ata_port *ap, struct ata_device *adev) | |||
842 | reg |= 0x08; /* FIFO off */ | 842 | reg |= 0x08; /* FIFO off */ |
843 | if (!ata_pio_need_iordy(adev)) | 843 | if (!ata_pio_need_iordy(adev)) |
844 | reg |= 0x02; /* IORDY off */ | 844 | reg |= 0x02; /* IORDY off */ |
845 | reg |= (FIT(t.setup, 0, 3) << 6); | 845 | reg |= (clamp_val(t.setup, 0, 3) << 6); |
846 | winbond_writecfg(ld_winbond->timing, timing + 1, reg); | 846 | winbond_writecfg(ld_winbond->timing, timing + 1, reg); |
847 | } | 847 | } |
848 | 848 | ||
diff --git a/drivers/ata/pata_ns87410.c b/drivers/ata/pata_ns87410.c index 76d2455bc453..be756b7ef07e 100644 --- a/drivers/ata/pata_ns87410.c +++ b/drivers/ata/pata_ns87410.c | |||
@@ -91,9 +91,9 @@ static void ns87410_set_piomode(struct ata_port *ap, struct ata_device *adev) | |||
91 | return; | 91 | return; |
92 | } | 92 | } |
93 | 93 | ||
94 | at.active = FIT(at.active, 2, 16) - 2; | 94 | at.active = clamp_val(at.active, 2, 16) - 2; |
95 | at.setup = FIT(at.setup, 1, 4) - 1; | 95 | at.setup = clamp_val(at.setup, 1, 4) - 1; |
96 | at.recover = FIT(at.recover, 1, 12) - 1; | 96 | at.recover = clamp_val(at.recover, 1, 12) - 1; |
97 | 97 | ||
98 | idetcr = (at.setup << 6) | (recoverbits[at.recover] << 3) | activebits[at.active]; | 98 | idetcr = (at.setup << 6) | (recoverbits[at.recover] << 3) | activebits[at.active]; |
99 | 99 | ||
diff --git a/drivers/ata/pata_ns87415.c b/drivers/ata/pata_ns87415.c index ae92b0049bd5..e0aa7eaaee0a 100644 --- a/drivers/ata/pata_ns87415.c +++ b/drivers/ata/pata_ns87415.c | |||
@@ -66,8 +66,8 @@ static void ns87415_set_mode(struct ata_port *ap, struct ata_device *adev, u8 mo | |||
66 | 66 | ||
67 | ata_timing_compute(adev, adev->pio_mode, &t, T, 0); | 67 | ata_timing_compute(adev, adev->pio_mode, &t, T, 0); |
68 | 68 | ||
69 | clocking = 17 - FIT(t.active, 2, 17); | 69 | clocking = 17 - clamp_val(t.active, 2, 17); |
70 | clocking |= (16 - FIT(t.recover, 1, 16)) << 4; | 70 | clocking |= (16 - clamp_val(t.recover, 1, 16)) << 4; |
71 | /* Use the same timing for read and write bytes */ | 71 | /* Use the same timing for read and write bytes */ |
72 | clocking |= (clocking << 8); | 72 | clocking |= (clocking << 8); |
73 | pci_write_config_word(dev, timing, clocking); | 73 | pci_write_config_word(dev, timing, clocking); |
diff --git a/drivers/ata/pata_qdi.c b/drivers/ata/pata_qdi.c index bf45cf017753..97e5b090d7c2 100644 --- a/drivers/ata/pata_qdi.c +++ b/drivers/ata/pata_qdi.c | |||
@@ -60,11 +60,11 @@ static void qdi6500_set_piomode(struct ata_port *ap, struct ata_device *adev) | |||
60 | ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000); | 60 | ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000); |
61 | 61 | ||
62 | if (qdi->fast) { | 62 | if (qdi->fast) { |
63 | active = 8 - FIT(t.active, 1, 8); | 63 | active = 8 - clamp_val(t.active, 1, 8); |
64 | recovery = 18 - FIT(t.recover, 3, 18); | 64 | recovery = 18 - clamp_val(t.recover, 3, 18); |
65 | } else { | 65 | } else { |
66 | active = 9 - FIT(t.active, 2, 9); | 66 | active = 9 - clamp_val(t.active, 2, 9); |
67 | recovery = 15 - FIT(t.recover, 0, 15); | 67 | recovery = 15 - clamp_val(t.recover, 0, 15); |
68 | } | 68 | } |
69 | timing = (recovery << 4) | active | 0x08; | 69 | timing = (recovery << 4) | active | 0x08; |
70 | 70 | ||
@@ -84,11 +84,11 @@ static void qdi6580_set_piomode(struct ata_port *ap, struct ata_device *adev) | |||
84 | ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000); | 84 | ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000); |
85 | 85 | ||
86 | if (qdi->fast) { | 86 | if (qdi->fast) { |
87 | active = 8 - FIT(t.active, 1, 8); | 87 | active = 8 - clamp_val(t.active, 1, 8); |
88 | recovery = 18 - FIT(t.recover, 3, 18); | 88 | recovery = 18 - clamp_val(t.recover, 3, 18); |
89 | } else { | 89 | } else { |
90 | active = 9 - FIT(t.active, 2, 9); | 90 | active = 9 - clamp_val(t.active, 2, 9); |
91 | recovery = 15 - FIT(t.recover, 0, 15); | 91 | recovery = 15 - clamp_val(t.recover, 0, 15); |
92 | } | 92 | } |
93 | timing = (recovery << 4) | active | 0x08; | 93 | timing = (recovery << 4) | active | 0x08; |
94 | 94 | ||
diff --git a/drivers/ata/pata_rb532_cf.c b/drivers/ata/pata_rb532_cf.c index a108d259f19d..f8b3ffc8ae9e 100644 --- a/drivers/ata/pata_rb532_cf.c +++ b/drivers/ata/pata_rb532_cf.c | |||
@@ -57,7 +57,9 @@ static inline void rb532_pata_finish_io(struct ata_port *ap) | |||
57 | struct ata_host *ah = ap->host; | 57 | struct ata_host *ah = ap->host; |
58 | struct rb532_cf_info *info = ah->private_data; | 58 | struct rb532_cf_info *info = ah->private_data; |
59 | 59 | ||
60 | ata_sff_altstatus(ap); | 60 | /* FIXME: Keep previous delay. If this is merely a fence then |
61 | ata_sff_sync might be sufficient. */ | ||
62 | ata_sff_dma_pause(ap); | ||
61 | ndelay(RB500_CF_IO_DELAY); | 63 | ndelay(RB500_CF_IO_DELAY); |
62 | 64 | ||
63 | set_irq_type(info->irq, IRQ_TYPE_LEVEL_HIGH); | 65 | set_irq_type(info->irq, IRQ_TYPE_LEVEL_HIGH); |
diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c index e965b251ca24..bbf5aa345e68 100644 --- a/drivers/ata/pata_scc.c +++ b/drivers/ata/pata_scc.c | |||
@@ -726,7 +726,7 @@ static void scc_bmdma_stop (struct ata_queued_cmd *qc) | |||
726 | in_be32(bmid_base + SCC_DMA_CMD) & ~ATA_DMA_START); | 726 | in_be32(bmid_base + SCC_DMA_CMD) & ~ATA_DMA_START); |
727 | 727 | ||
728 | /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */ | 728 | /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */ |
729 | ata_sff_altstatus(ap); /* dummy read */ | 729 | ata_sff_dma_pause(ap); /* dummy read */ |
730 | } | 730 | } |
731 | 731 | ||
732 | /** | 732 | /** |
@@ -747,7 +747,8 @@ static u8 scc_bmdma_status (struct ata_port *ap) | |||
747 | return host_stat; | 747 | return host_stat; |
748 | 748 | ||
749 | /* errata A252,A308 workaround: Step4 */ | 749 | /* errata A252,A308 workaround: Step4 */ |
750 | if ((ata_sff_altstatus(ap) & ATA_ERR) && (int_status & INTSTS_INTRQ)) | 750 | if ((scc_check_altstatus(ap) & ATA_ERR) |
751 | && (int_status & INTSTS_INTRQ)) | ||
751 | return (host_stat | ATA_DMA_INTR); | 752 | return (host_stat | ATA_DMA_INTR); |
752 | 753 | ||
753 | /* errata A308 workaround Step5 */ | 754 | /* errata A308 workaround Step5 */ |
diff --git a/drivers/ata/pata_sl82c105.c b/drivers/ata/pata_sl82c105.c index 70d94fb28a5f..69877bd81815 100644 --- a/drivers/ata/pata_sl82c105.c +++ b/drivers/ata/pata_sl82c105.c | |||
@@ -216,7 +216,7 @@ static int sl82c105_qc_defer(struct ata_queued_cmd *qc) | |||
216 | struct ata_port *alt = host->ports[1 ^ qc->ap->port_no]; | 216 | struct ata_port *alt = host->ports[1 ^ qc->ap->port_no]; |
217 | int rc; | 217 | int rc; |
218 | 218 | ||
219 | /* First apply the usual rules */ | 219 | /* First apply the usual rules */ |
220 | rc = ata_std_qc_defer(qc); | 220 | rc = ata_std_qc_defer(qc); |
221 | if (rc != 0) | 221 | if (rc != 0) |
222 | return rc; | 222 | return rc; |
diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c index 2fea6cbe7755..708ed144ede9 100644 --- a/drivers/ata/pata_via.c +++ b/drivers/ata/pata_via.c | |||
@@ -259,15 +259,15 @@ static void via_do_set_mode(struct ata_port *ap, struct ata_device *adev, int mo | |||
259 | 259 | ||
260 | pci_read_config_byte(pdev, 0x4C, &setup); | 260 | pci_read_config_byte(pdev, 0x4C, &setup); |
261 | setup &= ~(3 << shift); | 261 | setup &= ~(3 << shift); |
262 | setup |= FIT(t.setup, 1, 4) << shift; /* 1,4 or 1,4 - 1 FIXME */ | 262 | setup |= clamp_val(t.setup, 1, 4) << shift; /* 1,4 or 1,4 - 1 FIXME */ |
263 | pci_write_config_byte(pdev, 0x4C, setup); | 263 | pci_write_config_byte(pdev, 0x4C, setup); |
264 | } | 264 | } |
265 | 265 | ||
266 | /* Load the PIO mode bits */ | 266 | /* Load the PIO mode bits */ |
267 | pci_write_config_byte(pdev, 0x4F - ap->port_no, | 267 | pci_write_config_byte(pdev, 0x4F - ap->port_no, |
268 | ((FIT(t.act8b, 1, 16) - 1) << 4) | (FIT(t.rec8b, 1, 16) - 1)); | 268 | ((clamp_val(t.act8b, 1, 16) - 1) << 4) | (clamp_val(t.rec8b, 1, 16) - 1)); |
269 | pci_write_config_byte(pdev, 0x48 + offset, | 269 | pci_write_config_byte(pdev, 0x48 + offset, |
270 | ((FIT(t.active, 1, 16) - 1) << 4) | (FIT(t.recover, 1, 16) - 1)); | 270 | ((clamp_val(t.active, 1, 16) - 1) << 4) | (clamp_val(t.recover, 1, 16) - 1)); |
271 | 271 | ||
272 | /* Load the UDMA bits according to type */ | 272 | /* Load the UDMA bits according to type */ |
273 | switch(udma_type) { | 273 | switch(udma_type) { |
@@ -275,16 +275,16 @@ static void via_do_set_mode(struct ata_port *ap, struct ata_device *adev, int mo | |||
275 | /* BUG() ? */ | 275 | /* BUG() ? */ |
276 | /* fall through */ | 276 | /* fall through */ |
277 | case 33: | 277 | case 33: |
278 | ut = t.udma ? (0xe0 | (FIT(t.udma, 2, 5) - 2)) : 0x03; | 278 | ut = t.udma ? (0xe0 | (clamp_val(t.udma, 2, 5) - 2)) : 0x03; |
279 | break; | 279 | break; |
280 | case 66: | 280 | case 66: |
281 | ut = t.udma ? (0xe8 | (FIT(t.udma, 2, 9) - 2)) : 0x0f; | 281 | ut = t.udma ? (0xe8 | (clamp_val(t.udma, 2, 9) - 2)) : 0x0f; |
282 | break; | 282 | break; |
283 | case 100: | 283 | case 100: |
284 | ut = t.udma ? (0xe0 | (FIT(t.udma, 2, 9) - 2)) : 0x07; | 284 | ut = t.udma ? (0xe0 | (clamp_val(t.udma, 2, 9) - 2)) : 0x07; |
285 | break; | 285 | break; |
286 | case 133: | 286 | case 133: |
287 | ut = t.udma ? (0xe0 | (FIT(t.udma, 2, 9) - 2)) : 0x07; | 287 | ut = t.udma ? (0xe0 | (clamp_val(t.udma, 2, 9) - 2)) : 0x07; |
288 | break; | 288 | break; |
289 | } | 289 | } |
290 | 290 | ||
diff --git a/drivers/ata/pata_winbond.c b/drivers/ata/pata_winbond.c index 6e52a3573fbf..474528f8fe3d 100644 --- a/drivers/ata/pata_winbond.c +++ b/drivers/ata/pata_winbond.c | |||
@@ -75,8 +75,8 @@ static void winbond_set_piomode(struct ata_port *ap, struct ata_device *adev) | |||
75 | else | 75 | else |
76 | ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000); | 76 | ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000); |
77 | 77 | ||
78 | active = (FIT(t.active, 3, 17) - 1) & 0x0F; | 78 | active = (clamp_val(t.active, 3, 17) - 1) & 0x0F; |
79 | recovery = (FIT(t.recover, 1, 15) + 1) & 0x0F; | 79 | recovery = (clamp_val(t.recover, 1, 15) + 1) & 0x0F; |
80 | timing = (active << 4) | recovery; | 80 | timing = (active << 4) | recovery; |
81 | winbond_writecfg(winbond->config, timing, reg); | 81 | winbond_writecfg(winbond->config, timing, reg); |
82 | 82 | ||
@@ -87,7 +87,7 @@ static void winbond_set_piomode(struct ata_port *ap, struct ata_device *adev) | |||
87 | reg |= 0x08; /* FIFO off */ | 87 | reg |= 0x08; /* FIFO off */ |
88 | if (!ata_pio_need_iordy(adev)) | 88 | if (!ata_pio_need_iordy(adev)) |
89 | reg |= 0x02; /* IORDY off */ | 89 | reg |= 0x02; /* IORDY off */ |
90 | reg |= (FIT(t.setup, 0, 3) << 6); | 90 | reg |= (clamp_val(t.setup, 0, 3) << 6); |
91 | winbond_writecfg(winbond->config, timing + 1, reg); | 91 | winbond_writecfg(winbond->config, timing + 1, reg); |
92 | } | 92 | } |
93 | 93 | ||
diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c index 853559e32315..3924e7209a44 100644 --- a/drivers/ata/sata_fsl.c +++ b/drivers/ata/sata_fsl.c | |||
@@ -34,7 +34,7 @@ enum { | |||
34 | 34 | ||
35 | SATA_FSL_HOST_FLAGS = (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | 35 | SATA_FSL_HOST_FLAGS = (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | |
36 | ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | | 36 | ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | |
37 | ATA_FLAG_NCQ), | 37 | ATA_FLAG_PMP | ATA_FLAG_NCQ), |
38 | 38 | ||
39 | SATA_FSL_MAX_CMDS = SATA_FSL_QUEUE_DEPTH, | 39 | SATA_FSL_MAX_CMDS = SATA_FSL_QUEUE_DEPTH, |
40 | SATA_FSL_CMD_HDR_SIZE = 16, /* 4 DWORDS */ | 40 | SATA_FSL_CMD_HDR_SIZE = 16, /* 4 DWORDS */ |
@@ -395,7 +395,7 @@ static void sata_fsl_qc_prep(struct ata_queued_cmd *qc) | |||
395 | cd = (struct command_desc *)pp->cmdentry + tag; | 395 | cd = (struct command_desc *)pp->cmdentry + tag; |
396 | cd_paddr = pp->cmdentry_paddr + tag * SATA_FSL_CMD_DESC_SIZE; | 396 | cd_paddr = pp->cmdentry_paddr + tag * SATA_FSL_CMD_DESC_SIZE; |
397 | 397 | ||
398 | ata_tf_to_fis(&qc->tf, 0, 1, (u8 *) &cd->cfis); | 398 | ata_tf_to_fis(&qc->tf, qc->dev->link->pmp, 1, (u8 *) &cd->cfis); |
399 | 399 | ||
400 | VPRINTK("Dumping cfis : 0x%x, 0x%x, 0x%x\n", | 400 | VPRINTK("Dumping cfis : 0x%x, 0x%x, 0x%x\n", |
401 | cd->cfis[0], cd->cfis[1], cd->cfis[2]); | 401 | cd->cfis[0], cd->cfis[1], cd->cfis[2]); |
@@ -438,6 +438,8 @@ static unsigned int sata_fsl_qc_issue(struct ata_queued_cmd *qc) | |||
438 | ioread32(CA + hcr_base), | 438 | ioread32(CA + hcr_base), |
439 | ioread32(CE + hcr_base), ioread32(CC + hcr_base)); | 439 | ioread32(CE + hcr_base), ioread32(CC + hcr_base)); |
440 | 440 | ||
441 | iowrite32(qc->dev->link->pmp, CQPMP + hcr_base); | ||
442 | |||
441 | /* Simply queue command to the controller/device */ | 443 | /* Simply queue command to the controller/device */ |
442 | iowrite32(1 << tag, CQ + hcr_base); | 444 | iowrite32(1 << tag, CQ + hcr_base); |
443 | 445 | ||
@@ -558,11 +560,36 @@ static void sata_fsl_thaw(struct ata_port *ap) | |||
558 | ioread32(hcr_base + HCONTROL), ioread32(hcr_base + HSTATUS)); | 560 | ioread32(hcr_base + HCONTROL), ioread32(hcr_base + HSTATUS)); |
559 | } | 561 | } |
560 | 562 | ||
563 | static void sata_fsl_pmp_attach(struct ata_port *ap) | ||
564 | { | ||
565 | struct sata_fsl_host_priv *host_priv = ap->host->private_data; | ||
566 | void __iomem *hcr_base = host_priv->hcr_base; | ||
567 | u32 temp; | ||
568 | |||
569 | temp = ioread32(hcr_base + HCONTROL); | ||
570 | iowrite32((temp | HCONTROL_PMP_ATTACHED), hcr_base + HCONTROL); | ||
571 | } | ||
572 | |||
573 | static void sata_fsl_pmp_detach(struct ata_port *ap) | ||
574 | { | ||
575 | struct sata_fsl_host_priv *host_priv = ap->host->private_data; | ||
576 | void __iomem *hcr_base = host_priv->hcr_base; | ||
577 | u32 temp; | ||
578 | |||
579 | temp = ioread32(hcr_base + HCONTROL); | ||
580 | temp &= ~HCONTROL_PMP_ATTACHED; | ||
581 | iowrite32(temp, hcr_base + HCONTROL); | ||
582 | |||
583 | /* enable interrupts on the controller/port */ | ||
584 | temp = ioread32(hcr_base + HCONTROL); | ||
585 | iowrite32((temp | DEFAULT_PORT_IRQ_ENABLE_MASK), hcr_base + HCONTROL); | ||
586 | |||
587 | } | ||
588 | |||
561 | static int sata_fsl_port_start(struct ata_port *ap) | 589 | static int sata_fsl_port_start(struct ata_port *ap) |
562 | { | 590 | { |
563 | struct device *dev = ap->host->dev; | 591 | struct device *dev = ap->host->dev; |
564 | struct sata_fsl_port_priv *pp; | 592 | struct sata_fsl_port_priv *pp; |
565 | int retval; | ||
566 | void *mem; | 593 | void *mem; |
567 | dma_addr_t mem_dma; | 594 | dma_addr_t mem_dma; |
568 | struct sata_fsl_host_priv *host_priv = ap->host->private_data; | 595 | struct sata_fsl_host_priv *host_priv = ap->host->private_data; |
@@ -688,12 +715,13 @@ static int sata_fsl_prereset(struct ata_link *link, unsigned long deadline) | |||
688 | } | 715 | } |
689 | 716 | ||
690 | static int sata_fsl_softreset(struct ata_link *link, unsigned int *class, | 717 | static int sata_fsl_softreset(struct ata_link *link, unsigned int *class, |
691 | unsigned long deadline) | 718 | unsigned long deadline) |
692 | { | 719 | { |
693 | struct ata_port *ap = link->ap; | 720 | struct ata_port *ap = link->ap; |
694 | struct sata_fsl_port_priv *pp = ap->private_data; | 721 | struct sata_fsl_port_priv *pp = ap->private_data; |
695 | struct sata_fsl_host_priv *host_priv = ap->host->private_data; | 722 | struct sata_fsl_host_priv *host_priv = ap->host->private_data; |
696 | void __iomem *hcr_base = host_priv->hcr_base; | 723 | void __iomem *hcr_base = host_priv->hcr_base; |
724 | int pmp = sata_srst_pmp(link); | ||
697 | u32 temp; | 725 | u32 temp; |
698 | struct ata_taskfile tf; | 726 | struct ata_taskfile tf; |
699 | u8 *cfis; | 727 | u8 *cfis; |
@@ -703,6 +731,9 @@ static int sata_fsl_softreset(struct ata_link *link, unsigned int *class, | |||
703 | 731 | ||
704 | DPRINTK("in xx_softreset\n"); | 732 | DPRINTK("in xx_softreset\n"); |
705 | 733 | ||
734 | if (pmp != SATA_PMP_CTRL_PORT) | ||
735 | goto issue_srst; | ||
736 | |||
706 | try_offline_again: | 737 | try_offline_again: |
707 | /* | 738 | /* |
708 | * Force host controller to go off-line, aborting current operations | 739 | * Force host controller to go off-line, aborting current operations |
@@ -746,6 +777,7 @@ try_offline_again: | |||
746 | 777 | ||
747 | temp = ioread32(hcr_base + HCONTROL); | 778 | temp = ioread32(hcr_base + HCONTROL); |
748 | temp |= (HCONTROL_ONLINE_PHY_RST | HCONTROL_SNOOP_ENABLE); | 779 | temp |= (HCONTROL_ONLINE_PHY_RST | HCONTROL_SNOOP_ENABLE); |
780 | temp |= HCONTROL_PMP_ATTACHED; | ||
749 | iowrite32(temp, hcr_base + HCONTROL); | 781 | iowrite32(temp, hcr_base + HCONTROL); |
750 | 782 | ||
751 | temp = ata_wait_register(hcr_base + HSTATUS, ONLINE, 0, 1, 500); | 783 | temp = ata_wait_register(hcr_base + HSTATUS, ONLINE, 0, 1, 500); |
@@ -771,7 +803,8 @@ try_offline_again: | |||
771 | ata_port_printk(ap, KERN_WARNING, | 803 | ata_port_printk(ap, KERN_WARNING, |
772 | "No Device OR PHYRDY change,Hstatus = 0x%x\n", | 804 | "No Device OR PHYRDY change,Hstatus = 0x%x\n", |
773 | ioread32(hcr_base + HSTATUS)); | 805 | ioread32(hcr_base + HSTATUS)); |
774 | goto err; | 806 | *class = ATA_DEV_NONE; |
807 | goto out; | ||
775 | } | 808 | } |
776 | 809 | ||
777 | /* | 810 | /* |
@@ -783,7 +816,8 @@ try_offline_again: | |||
783 | 816 | ||
784 | if ((temp & 0xFF) != 0x18) { | 817 | if ((temp & 0xFF) != 0x18) { |
785 | ata_port_printk(ap, KERN_WARNING, "No Signature Update\n"); | 818 | ata_port_printk(ap, KERN_WARNING, "No Signature Update\n"); |
786 | goto err; | 819 | *class = ATA_DEV_NONE; |
820 | goto out; | ||
787 | } else { | 821 | } else { |
788 | ata_port_printk(ap, KERN_INFO, | 822 | ata_port_printk(ap, KERN_INFO, |
789 | "Signature Update detected @ %d msecs\n", | 823 | "Signature Update detected @ %d msecs\n", |
@@ -798,6 +832,7 @@ try_offline_again: | |||
798 | * reached here, we can send a command to the target device | 832 | * reached here, we can send a command to the target device |
799 | */ | 833 | */ |
800 | 834 | ||
835 | issue_srst: | ||
801 | DPRINTK("Sending SRST/device reset\n"); | 836 | DPRINTK("Sending SRST/device reset\n"); |
802 | 837 | ||
803 | ata_tf_init(link->device, &tf); | 838 | ata_tf_init(link->device, &tf); |
@@ -808,7 +843,7 @@ try_offline_again: | |||
808 | SRST_CMD | CMD_DESC_SNOOP_ENABLE, 0, 0, 5); | 843 | SRST_CMD | CMD_DESC_SNOOP_ENABLE, 0, 0, 5); |
809 | 844 | ||
810 | tf.ctl |= ATA_SRST; /* setup SRST bit in taskfile control reg */ | 845 | tf.ctl |= ATA_SRST; /* setup SRST bit in taskfile control reg */ |
811 | ata_tf_to_fis(&tf, 0, 0, cfis); | 846 | ata_tf_to_fis(&tf, pmp, 0, cfis); |
812 | 847 | ||
813 | DPRINTK("Dumping cfis : 0x%x, 0x%x, 0x%x, 0x%x\n", | 848 | DPRINTK("Dumping cfis : 0x%x, 0x%x, 0x%x, 0x%x\n", |
814 | cfis[0], cfis[1], cfis[2], cfis[3]); | 849 | cfis[0], cfis[1], cfis[2], cfis[3]); |
@@ -854,8 +889,10 @@ try_offline_again: | |||
854 | sata_fsl_setup_cmd_hdr_entry(pp, 0, CMD_DESC_SNOOP_ENABLE, 0, 0, 5); | 889 | sata_fsl_setup_cmd_hdr_entry(pp, 0, CMD_DESC_SNOOP_ENABLE, 0, 0, 5); |
855 | 890 | ||
856 | tf.ctl &= ~ATA_SRST; /* 2nd H2D Ctl. register FIS */ | 891 | tf.ctl &= ~ATA_SRST; /* 2nd H2D Ctl. register FIS */ |
857 | ata_tf_to_fis(&tf, 0, 0, cfis); | 892 | ata_tf_to_fis(&tf, pmp, 0, cfis); |
858 | 893 | ||
894 | if (pmp != SATA_PMP_CTRL_PORT) | ||
895 | iowrite32(pmp, CQPMP + hcr_base); | ||
859 | iowrite32(1, CQ + hcr_base); | 896 | iowrite32(1, CQ + hcr_base); |
860 | msleep(150); /* ?? */ | 897 | msleep(150); /* ?? */ |
861 | 898 | ||
@@ -886,12 +923,21 @@ try_offline_again: | |||
886 | VPRINTK("cereg = 0x%x\n", ioread32(hcr_base + CE)); | 923 | VPRINTK("cereg = 0x%x\n", ioread32(hcr_base + CE)); |
887 | } | 924 | } |
888 | 925 | ||
926 | out: | ||
889 | return 0; | 927 | return 0; |
890 | 928 | ||
891 | err: | 929 | err: |
892 | return -EIO; | 930 | return -EIO; |
893 | } | 931 | } |
894 | 932 | ||
933 | static void sata_fsl_error_handler(struct ata_port *ap) | ||
934 | { | ||
935 | |||
936 | DPRINTK("in xx_error_handler\n"); | ||
937 | sata_pmp_error_handler(ap); | ||
938 | |||
939 | } | ||
940 | |||
895 | static void sata_fsl_post_internal_cmd(struct ata_queued_cmd *qc) | 941 | static void sata_fsl_post_internal_cmd(struct ata_queued_cmd *qc) |
896 | { | 942 | { |
897 | if (qc->flags & ATA_QCFLAG_FAILED) | 943 | if (qc->flags & ATA_QCFLAG_FAILED) |
@@ -905,18 +951,21 @@ static void sata_fsl_post_internal_cmd(struct ata_queued_cmd *qc) | |||
905 | 951 | ||
906 | static void sata_fsl_error_intr(struct ata_port *ap) | 952 | static void sata_fsl_error_intr(struct ata_port *ap) |
907 | { | 953 | { |
908 | struct ata_link *link = &ap->link; | ||
909 | struct ata_eh_info *ehi = &link->eh_info; | ||
910 | struct sata_fsl_host_priv *host_priv = ap->host->private_data; | 954 | struct sata_fsl_host_priv *host_priv = ap->host->private_data; |
911 | void __iomem *hcr_base = host_priv->hcr_base; | 955 | void __iomem *hcr_base = host_priv->hcr_base; |
912 | u32 hstatus, dereg, cereg = 0, SError = 0; | 956 | u32 hstatus, dereg=0, cereg = 0, SError = 0; |
913 | unsigned int err_mask = 0, action = 0; | 957 | unsigned int err_mask = 0, action = 0; |
914 | struct ata_queued_cmd *qc; | 958 | int freeze = 0, abort=0; |
915 | int freeze = 0; | 959 | struct ata_link *link = NULL; |
960 | struct ata_queued_cmd *qc = NULL; | ||
961 | struct ata_eh_info *ehi; | ||
916 | 962 | ||
917 | hstatus = ioread32(hcr_base + HSTATUS); | 963 | hstatus = ioread32(hcr_base + HSTATUS); |
918 | cereg = ioread32(hcr_base + CE); | 964 | cereg = ioread32(hcr_base + CE); |
919 | 965 | ||
966 | /* first, analyze and record host port events */ | ||
967 | link = &ap->link; | ||
968 | ehi = &link->eh_info; | ||
920 | ata_ehi_clear_desc(ehi); | 969 | ata_ehi_clear_desc(ehi); |
921 | 970 | ||
922 | /* | 971 | /* |
@@ -926,42 +975,28 @@ static void sata_fsl_error_intr(struct ata_port *ap) | |||
926 | sata_fsl_scr_read(ap, SCR_ERROR, &SError); | 975 | sata_fsl_scr_read(ap, SCR_ERROR, &SError); |
927 | if (unlikely(SError & 0xFFFF0000)) { | 976 | if (unlikely(SError & 0xFFFF0000)) { |
928 | sata_fsl_scr_write(ap, SCR_ERROR, SError); | 977 | sata_fsl_scr_write(ap, SCR_ERROR, SError); |
929 | err_mask |= AC_ERR_ATA_BUS; | ||
930 | } | 978 | } |
931 | 979 | ||
932 | DPRINTK("error_intr,hStat=0x%x,CE=0x%x,DE =0x%x,SErr=0x%x\n", | 980 | DPRINTK("error_intr,hStat=0x%x,CE=0x%x,DE =0x%x,SErr=0x%x\n", |
933 | hstatus, cereg, ioread32(hcr_base + DE), SError); | 981 | hstatus, cereg, ioread32(hcr_base + DE), SError); |
934 | 982 | ||
935 | /* handle single device errors */ | 983 | /* handle fatal errors */ |
936 | if (cereg) { | 984 | if (hstatus & FATAL_ERROR_DECODE) { |
937 | /* | 985 | ehi->err_mask |= AC_ERR_ATA_BUS; |
938 | * clear the command error, also clears queue to the device | 986 | ehi->action |= ATA_EH_SOFTRESET; |
939 | * in error, and we can (re)issue commands to this device. | ||
940 | * When a device is in error all commands queued into the | ||
941 | * host controller and at the device are considered aborted | ||
942 | * and the queue for that device is stopped. Now, after | ||
943 | * clearing the device error, we can issue commands to the | ||
944 | * device to interrogate it to find the source of the error. | ||
945 | */ | ||
946 | dereg = ioread32(hcr_base + DE); | ||
947 | iowrite32(dereg, hcr_base + DE); | ||
948 | iowrite32(cereg, hcr_base + CE); | ||
949 | 987 | ||
950 | DPRINTK("single device error, CE=0x%x, DE=0x%x\n", | ||
951 | ioread32(hcr_base + CE), ioread32(hcr_base + DE)); | ||
952 | /* | 988 | /* |
953 | * We should consider this as non fatal error, and TF must | 989 | * Ignore serror in case of fatal errors as we always want |
954 | * be updated as done below. | 990 | * to do a soft-reset of the FSL SATA controller. Analyzing |
991 | * serror may cause libata to schedule a hard-reset action, | ||
992 | * and hard-reset currently does not do controller | ||
993 | * offline/online, causing command timeouts and leads to an | ||
994 | * un-recoverable state, hence make libATA ignore | ||
995 | * autopsy in case of fatal errors. | ||
955 | */ | 996 | */ |
956 | 997 | ||
957 | err_mask |= AC_ERR_DEV; | 998 | ehi->flags |= ATA_EHI_NO_AUTOPSY; |
958 | } | ||
959 | 999 | ||
960 | /* handle fatal errors */ | ||
961 | if (hstatus & FATAL_ERROR_DECODE) { | ||
962 | err_mask |= AC_ERR_ATA_BUS; | ||
963 | action |= ATA_EH_RESET; | ||
964 | /* how will fatal error interrupts be completed ?? */ | ||
965 | freeze = 1; | 1000 | freeze = 1; |
966 | } | 1001 | } |
967 | 1002 | ||
@@ -971,30 +1006,83 @@ static void sata_fsl_error_intr(struct ata_port *ap) | |||
971 | 1006 | ||
972 | /* Setup a soft-reset EH action */ | 1007 | /* Setup a soft-reset EH action */ |
973 | ata_ehi_hotplugged(ehi); | 1008 | ata_ehi_hotplugged(ehi); |
1009 | ata_ehi_push_desc(ehi, "%s", "PHY RDY changed"); | ||
974 | freeze = 1; | 1010 | freeze = 1; |
975 | } | 1011 | } |
976 | 1012 | ||
977 | /* record error info */ | 1013 | /* handle single device errors */ |
978 | qc = ata_qc_from_tag(ap, link->active_tag); | 1014 | if (cereg) { |
1015 | /* | ||
1016 | * clear the command error, also clears queue to the device | ||
1017 | * in error, and we can (re)issue commands to this device. | ||
1018 | * When a device is in error all commands queued into the | ||
1019 | * host controller and at the device are considered aborted | ||
1020 | * and the queue for that device is stopped. Now, after | ||
1021 | * clearing the device error, we can issue commands to the | ||
1022 | * device to interrogate it to find the source of the error. | ||
1023 | */ | ||
1024 | abort = 1; | ||
1025 | |||
1026 | DPRINTK("single device error, CE=0x%x, DE=0x%x\n", | ||
1027 | ioread32(hcr_base + CE), ioread32(hcr_base + DE)); | ||
979 | 1028 | ||
980 | if (qc) | 1029 | /* find out the offending link and qc */ |
1030 | if (ap->nr_pmp_links) { | ||
1031 | dereg = ioread32(hcr_base + DE); | ||
1032 | iowrite32(dereg, hcr_base + DE); | ||
1033 | iowrite32(cereg, hcr_base + CE); | ||
1034 | |||
1035 | if (dereg < ap->nr_pmp_links) { | ||
1036 | link = &ap->pmp_link[dereg]; | ||
1037 | ehi = &link->eh_info; | ||
1038 | qc = ata_qc_from_tag(ap, link->active_tag); | ||
1039 | /* | ||
1040 | * We should consider this as non fatal error, | ||
1041 | * and TF must be updated as done below. | ||
1042 | */ | ||
1043 | |||
1044 | err_mask |= AC_ERR_DEV; | ||
1045 | |||
1046 | } else { | ||
1047 | err_mask |= AC_ERR_HSM; | ||
1048 | action |= ATA_EH_HARDRESET; | ||
1049 | freeze = 1; | ||
1050 | } | ||
1051 | } else { | ||
1052 | dereg = ioread32(hcr_base + DE); | ||
1053 | iowrite32(dereg, hcr_base + DE); | ||
1054 | iowrite32(cereg, hcr_base + CE); | ||
1055 | |||
1056 | qc = ata_qc_from_tag(ap, link->active_tag); | ||
1057 | /* | ||
1058 | * We should consider this as non fatal error, | ||
1059 | * and TF must be updated as done below. | ||
1060 | */ | ||
1061 | err_mask |= AC_ERR_DEV; | ||
1062 | } | ||
1063 | } | ||
1064 | |||
1065 | /* record error info */ | ||
1066 | if (qc) { | ||
981 | qc->err_mask |= err_mask; | 1067 | qc->err_mask |= err_mask; |
982 | else | 1068 | } else |
983 | ehi->err_mask |= err_mask; | 1069 | ehi->err_mask |= err_mask; |
984 | 1070 | ||
985 | ehi->action |= action; | 1071 | ehi->action |= action; |
986 | ehi->serror |= SError; | ||
987 | 1072 | ||
988 | /* freeze or abort */ | 1073 | /* freeze or abort */ |
989 | if (freeze) | 1074 | if (freeze) |
990 | ata_port_freeze(ap); | 1075 | ata_port_freeze(ap); |
991 | else | 1076 | else if (abort) { |
992 | ata_port_abort(ap); | 1077 | if (qc) |
1078 | ata_link_abort(qc->dev->link); | ||
1079 | else | ||
1080 | ata_port_abort(ap); | ||
1081 | } | ||
993 | } | 1082 | } |
994 | 1083 | ||
995 | static void sata_fsl_host_intr(struct ata_port *ap) | 1084 | static void sata_fsl_host_intr(struct ata_port *ap) |
996 | { | 1085 | { |
997 | struct ata_link *link = &ap->link; | ||
998 | struct sata_fsl_host_priv *host_priv = ap->host->private_data; | 1086 | struct sata_fsl_host_priv *host_priv = ap->host->private_data; |
999 | void __iomem *hcr_base = host_priv->hcr_base; | 1087 | void __iomem *hcr_base = host_priv->hcr_base; |
1000 | u32 hstatus, qc_active = 0; | 1088 | u32 hstatus, qc_active = 0; |
@@ -1017,10 +1105,19 @@ static void sata_fsl_host_intr(struct ata_port *ap) | |||
1017 | return; | 1105 | return; |
1018 | } | 1106 | } |
1019 | 1107 | ||
1020 | if (link->sactive) { /* only true for NCQ commands */ | 1108 | /* Read command completed register */ |
1109 | qc_active = ioread32(hcr_base + CC); | ||
1110 | |||
1111 | VPRINTK("Status of all queues :\n"); | ||
1112 | VPRINTK("qc_active/CC = 0x%x, CA = 0x%x, CE=0x%x,CQ=0x%x,apqa=0x%x\n", | ||
1113 | qc_active, | ||
1114 | ioread32(hcr_base + CA), | ||
1115 | ioread32(hcr_base + CE), | ||
1116 | ioread32(hcr_base + CQ), | ||
1117 | ap->qc_active); | ||
1118 | |||
1119 | if (qc_active & ap->qc_active) { | ||
1021 | int i; | 1120 | int i; |
1022 | /* Read command completed register */ | ||
1023 | qc_active = ioread32(hcr_base + CC); | ||
1024 | /* clear CC bit, this will also complete the interrupt */ | 1121 | /* clear CC bit, this will also complete the interrupt */ |
1025 | iowrite32(qc_active, hcr_base + CC); | 1122 | iowrite32(qc_active, hcr_base + CC); |
1026 | 1123 | ||
@@ -1032,8 +1129,9 @@ static void sata_fsl_host_intr(struct ata_port *ap) | |||
1032 | for (i = 0; i < SATA_FSL_QUEUE_DEPTH; i++) { | 1129 | for (i = 0; i < SATA_FSL_QUEUE_DEPTH; i++) { |
1033 | if (qc_active & (1 << i)) { | 1130 | if (qc_active & (1 << i)) { |
1034 | qc = ata_qc_from_tag(ap, i); | 1131 | qc = ata_qc_from_tag(ap, i); |
1035 | if (qc) | 1132 | if (qc) { |
1036 | ata_qc_complete(qc); | 1133 | ata_qc_complete(qc); |
1134 | } | ||
1037 | DPRINTK | 1135 | DPRINTK |
1038 | ("completing ncq cmd,tag=%d,CC=0x%x,CA=0x%x\n", | 1136 | ("completing ncq cmd,tag=%d,CC=0x%x,CA=0x%x\n", |
1039 | i, ioread32(hcr_base + CC), | 1137 | i, ioread32(hcr_base + CC), |
@@ -1042,19 +1140,21 @@ static void sata_fsl_host_intr(struct ata_port *ap) | |||
1042 | } | 1140 | } |
1043 | return; | 1141 | return; |
1044 | 1142 | ||
1045 | } else if (ap->qc_active) { | 1143 | } else if ((ap->qc_active & (1 << ATA_TAG_INTERNAL))) { |
1046 | iowrite32(1, hcr_base + CC); | 1144 | iowrite32(1, hcr_base + CC); |
1047 | qc = ata_qc_from_tag(ap, link->active_tag); | 1145 | qc = ata_qc_from_tag(ap, ATA_TAG_INTERNAL); |
1048 | 1146 | ||
1049 | DPRINTK("completing non-ncq cmd, tag=%d,CC=0x%x\n", | 1147 | DPRINTK("completing non-ncq cmd, CC=0x%x\n", |
1050 | link->active_tag, ioread32(hcr_base + CC)); | 1148 | ioread32(hcr_base + CC)); |
1051 | 1149 | ||
1052 | if (qc) | 1150 | if (qc) { |
1053 | ata_qc_complete(qc); | 1151 | ata_qc_complete(qc); |
1152 | } | ||
1054 | } else { | 1153 | } else { |
1055 | /* Spurious Interrupt!! */ | 1154 | /* Spurious Interrupt!! */ |
1056 | DPRINTK("spurious interrupt!!, CC = 0x%x\n", | 1155 | DPRINTK("spurious interrupt!!, CC = 0x%x\n", |
1057 | ioread32(hcr_base + CC)); | 1156 | ioread32(hcr_base + CC)); |
1157 | iowrite32(qc_active, hcr_base + CC); | ||
1058 | return; | 1158 | return; |
1059 | } | 1159 | } |
1060 | } | 1160 | } |
@@ -1130,9 +1230,6 @@ static int sata_fsl_init_controller(struct ata_host *host) | |||
1130 | iowrite32(0x00000FFFF, hcr_base + CE); | 1230 | iowrite32(0x00000FFFF, hcr_base + CE); |
1131 | iowrite32(0x00000FFFF, hcr_base + DE); | 1231 | iowrite32(0x00000FFFF, hcr_base + DE); |
1132 | 1232 | ||
1133 | /* initially assuming no Port multiplier, set CQPMP to 0 */ | ||
1134 | iowrite32(0x0, hcr_base + CQPMP); | ||
1135 | |||
1136 | /* | 1233 | /* |
1137 | * host controller will be brought on-line, during xx_port_start() | 1234 | * host controller will be brought on-line, during xx_port_start() |
1138 | * callback, that should also initiate the OOB, COMINIT sequence | 1235 | * callback, that should also initiate the OOB, COMINIT sequence |
@@ -1154,8 +1251,8 @@ static struct scsi_host_template sata_fsl_sht = { | |||
1154 | .dma_boundary = ATA_DMA_BOUNDARY, | 1251 | .dma_boundary = ATA_DMA_BOUNDARY, |
1155 | }; | 1252 | }; |
1156 | 1253 | ||
1157 | static const struct ata_port_operations sata_fsl_ops = { | 1254 | static struct ata_port_operations sata_fsl_ops = { |
1158 | .inherits = &sata_port_ops, | 1255 | .inherits = &sata_pmp_port_ops, |
1159 | 1256 | ||
1160 | .qc_prep = sata_fsl_qc_prep, | 1257 | .qc_prep = sata_fsl_qc_prep, |
1161 | .qc_issue = sata_fsl_qc_issue, | 1258 | .qc_issue = sata_fsl_qc_issue, |
@@ -1168,10 +1265,15 @@ static const struct ata_port_operations sata_fsl_ops = { | |||
1168 | .thaw = sata_fsl_thaw, | 1265 | .thaw = sata_fsl_thaw, |
1169 | .prereset = sata_fsl_prereset, | 1266 | .prereset = sata_fsl_prereset, |
1170 | .softreset = sata_fsl_softreset, | 1267 | .softreset = sata_fsl_softreset, |
1268 | .pmp_softreset = sata_fsl_softreset, | ||
1269 | .error_handler = sata_fsl_error_handler, | ||
1171 | .post_internal_cmd = sata_fsl_post_internal_cmd, | 1270 | .post_internal_cmd = sata_fsl_post_internal_cmd, |
1172 | 1271 | ||
1173 | .port_start = sata_fsl_port_start, | 1272 | .port_start = sata_fsl_port_start, |
1174 | .port_stop = sata_fsl_port_stop, | 1273 | .port_stop = sata_fsl_port_stop, |
1274 | |||
1275 | .pmp_attach = sata_fsl_pmp_attach, | ||
1276 | .pmp_detach = sata_fsl_pmp_detach, | ||
1175 | }; | 1277 | }; |
1176 | 1278 | ||
1177 | static const struct ata_port_info sata_fsl_port_info[] = { | 1279 | static const struct ata_port_info sata_fsl_port_info[] = { |
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index bb73b2222627..60391e9a84db 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c | |||
@@ -72,7 +72,7 @@ | |||
72 | #include <linux/libata.h> | 72 | #include <linux/libata.h> |
73 | 73 | ||
74 | #define DRV_NAME "sata_mv" | 74 | #define DRV_NAME "sata_mv" |
75 | #define DRV_VERSION "1.20" | 75 | #define DRV_VERSION "1.24" |
76 | 76 | ||
77 | enum { | 77 | enum { |
78 | /* BAR's are enumerated in terms of pci_resource_start() terms */ | 78 | /* BAR's are enumerated in terms of pci_resource_start() terms */ |
@@ -122,14 +122,17 @@ enum { | |||
122 | /* Host Flags */ | 122 | /* Host Flags */ |
123 | MV_FLAG_DUAL_HC = (1 << 30), /* two SATA Host Controllers */ | 123 | MV_FLAG_DUAL_HC = (1 << 30), /* two SATA Host Controllers */ |
124 | MV_FLAG_IRQ_COALESCE = (1 << 29), /* IRQ coalescing capability */ | 124 | MV_FLAG_IRQ_COALESCE = (1 << 29), /* IRQ coalescing capability */ |
125 | /* SoC integrated controllers, no PCI interface */ | ||
126 | MV_FLAG_SOC = (1 << 28), | ||
127 | 125 | ||
128 | MV_COMMON_FLAGS = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | 126 | MV_COMMON_FLAGS = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | |
129 | ATA_FLAG_MMIO | ATA_FLAG_NO_ATAPI | | 127 | ATA_FLAG_MMIO | ATA_FLAG_NO_ATAPI | |
130 | ATA_FLAG_PIO_POLLING, | 128 | ATA_FLAG_PIO_POLLING, |
129 | |||
131 | MV_6XXX_FLAGS = MV_FLAG_IRQ_COALESCE, | 130 | MV_6XXX_FLAGS = MV_FLAG_IRQ_COALESCE, |
132 | 131 | ||
132 | MV_GENIIE_FLAGS = MV_COMMON_FLAGS | MV_6XXX_FLAGS | | ||
133 | ATA_FLAG_PMP | ATA_FLAG_ACPI_SATA | | ||
134 | ATA_FLAG_NCQ | ATA_FLAG_AN, | ||
135 | |||
133 | CRQB_FLAG_READ = (1 << 0), | 136 | CRQB_FLAG_READ = (1 << 0), |
134 | CRQB_TAG_SHIFT = 1, | 137 | CRQB_TAG_SHIFT = 1, |
135 | CRQB_IOID_SHIFT = 6, /* CRQB Gen-II/IIE IO Id shift */ | 138 | CRQB_IOID_SHIFT = 6, /* CRQB Gen-II/IIE IO Id shift */ |
@@ -197,13 +200,6 @@ enum { | |||
197 | HC_MAIN_RSVD = (0x7f << 25), /* bits 31-25 */ | 200 | HC_MAIN_RSVD = (0x7f << 25), /* bits 31-25 */ |
198 | HC_MAIN_RSVD_5 = (0x1fff << 19), /* bits 31-19 */ | 201 | HC_MAIN_RSVD_5 = (0x1fff << 19), /* bits 31-19 */ |
199 | HC_MAIN_RSVD_SOC = (0x3fffffb << 6), /* bits 31-9, 7-6 */ | 202 | HC_MAIN_RSVD_SOC = (0x3fffffb << 6), /* bits 31-9, 7-6 */ |
200 | HC_MAIN_MASKED_IRQS = (TRAN_LO_DONE | TRAN_HI_DONE | | ||
201 | PORTS_0_3_COAL_DONE | PORTS_4_7_COAL_DONE | | ||
202 | PORTS_0_7_COAL_DONE | GPIO_INT | TWSI_INT | | ||
203 | HC_MAIN_RSVD), | ||
204 | HC_MAIN_MASKED_IRQS_5 = (PORTS_0_3_COAL_DONE | PORTS_4_7_COAL_DONE | | ||
205 | HC_MAIN_RSVD_5), | ||
206 | HC_MAIN_MASKED_IRQS_SOC = (PORTS_0_3_COAL_DONE | HC_MAIN_RSVD_SOC), | ||
207 | 203 | ||
208 | /* SATAHC registers */ | 204 | /* SATAHC registers */ |
209 | HC_CFG_OFS = 0, | 205 | HC_CFG_OFS = 0, |
@@ -221,12 +217,18 @@ enum { | |||
221 | SATA_STATUS_OFS = 0x300, /* ctrl, err regs follow status */ | 217 | SATA_STATUS_OFS = 0x300, /* ctrl, err regs follow status */ |
222 | SATA_ACTIVE_OFS = 0x350, | 218 | SATA_ACTIVE_OFS = 0x350, |
223 | SATA_FIS_IRQ_CAUSE_OFS = 0x364, | 219 | SATA_FIS_IRQ_CAUSE_OFS = 0x364, |
220 | SATA_FIS_IRQ_AN = (1 << 9), /* async notification */ | ||
224 | 221 | ||
225 | LTMODE_OFS = 0x30c, | 222 | LTMODE_OFS = 0x30c, |
226 | LTMODE_BIT8 = (1 << 8), /* unknown, but necessary */ | 223 | LTMODE_BIT8 = (1 << 8), /* unknown, but necessary */ |
227 | 224 | ||
228 | PHY_MODE3 = 0x310, | 225 | PHY_MODE3 = 0x310, |
229 | PHY_MODE4 = 0x314, | 226 | PHY_MODE4 = 0x314, |
227 | PHY_MODE4_CFG_MASK = 0x00000003, /* phy internal config field */ | ||
228 | PHY_MODE4_CFG_VALUE = 0x00000001, /* phy internal config field */ | ||
229 | PHY_MODE4_RSVD_ZEROS = 0x5de3fffa, /* Gen2e always write zeros */ | ||
230 | PHY_MODE4_RSVD_ONES = 0x00000005, /* Gen2e always write ones */ | ||
231 | |||
230 | PHY_MODE2 = 0x330, | 232 | PHY_MODE2 = 0x330, |
231 | SATA_IFCTL_OFS = 0x344, | 233 | SATA_IFCTL_OFS = 0x344, |
232 | SATA_TESTCTL_OFS = 0x348, | 234 | SATA_TESTCTL_OFS = 0x348, |
@@ -357,12 +359,12 @@ enum { | |||
357 | MV_HP_ERRATA_50XXB2 = (1 << 2), | 359 | MV_HP_ERRATA_50XXB2 = (1 << 2), |
358 | MV_HP_ERRATA_60X1B2 = (1 << 3), | 360 | MV_HP_ERRATA_60X1B2 = (1 << 3), |
359 | MV_HP_ERRATA_60X1C0 = (1 << 4), | 361 | MV_HP_ERRATA_60X1C0 = (1 << 4), |
360 | MV_HP_ERRATA_XX42A0 = (1 << 5), | ||
361 | MV_HP_GEN_I = (1 << 6), /* Generation I: 50xx */ | 362 | MV_HP_GEN_I = (1 << 6), /* Generation I: 50xx */ |
362 | MV_HP_GEN_II = (1 << 7), /* Generation II: 60xx */ | 363 | MV_HP_GEN_II = (1 << 7), /* Generation II: 60xx */ |
363 | MV_HP_GEN_IIE = (1 << 8), /* Generation IIE: 6042/7042 */ | 364 | MV_HP_GEN_IIE = (1 << 8), /* Generation IIE: 6042/7042 */ |
364 | MV_HP_PCIE = (1 << 9), /* PCIe bus/regs: 7042 */ | 365 | MV_HP_PCIE = (1 << 9), /* PCIe bus/regs: 7042 */ |
365 | MV_HP_CUT_THROUGH = (1 << 10), /* can use EDMA cut-through */ | 366 | MV_HP_CUT_THROUGH = (1 << 10), /* can use EDMA cut-through */ |
367 | MV_HP_FLAG_SOC = (1 << 11), /* SystemOnChip, no PCI */ | ||
366 | 368 | ||
367 | /* Port private flags (pp_flags) */ | 369 | /* Port private flags (pp_flags) */ |
368 | MV_PP_FLAG_EDMA_EN = (1 << 0), /* is EDMA engine enabled? */ | 370 | MV_PP_FLAG_EDMA_EN = (1 << 0), /* is EDMA engine enabled? */ |
@@ -375,7 +377,7 @@ enum { | |||
375 | #define IS_GEN_II(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_II) | 377 | #define IS_GEN_II(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_II) |
376 | #define IS_GEN_IIE(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_IIE) | 378 | #define IS_GEN_IIE(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_IIE) |
377 | #define IS_PCIE(hpriv) ((hpriv)->hp_flags & MV_HP_PCIE) | 379 | #define IS_PCIE(hpriv) ((hpriv)->hp_flags & MV_HP_PCIE) |
378 | #define HAS_PCI(host) (!((host)->ports[0]->flags & MV_FLAG_SOC)) | 380 | #define IS_SOC(hpriv) ((hpriv)->hp_flags & MV_HP_FLAG_SOC) |
379 | 381 | ||
380 | #define WINDOW_CTRL(i) (0x20030 + ((i) << 4)) | 382 | #define WINDOW_CTRL(i) (0x20030 + ((i) << 4)) |
381 | #define WINDOW_BASE(i) (0x20034 + ((i) << 4)) | 383 | #define WINDOW_BASE(i) (0x20034 + ((i) << 4)) |
@@ -459,6 +461,7 @@ struct mv_port_signal { | |||
459 | 461 | ||
460 | struct mv_host_priv { | 462 | struct mv_host_priv { |
461 | u32 hp_flags; | 463 | u32 hp_flags; |
464 | u32 main_irq_mask; | ||
462 | struct mv_port_signal signal[8]; | 465 | struct mv_port_signal signal[8]; |
463 | const struct mv_hw_ops *ops; | 466 | const struct mv_hw_ops *ops; |
464 | int n_ports; | 467 | int n_ports; |
@@ -640,25 +643,19 @@ static const struct ata_port_info mv_port_info[] = { | |||
640 | .port_ops = &mv6_ops, | 643 | .port_ops = &mv6_ops, |
641 | }, | 644 | }, |
642 | { /* chip_6042 */ | 645 | { /* chip_6042 */ |
643 | .flags = MV_COMMON_FLAGS | MV_6XXX_FLAGS | | 646 | .flags = MV_GENIIE_FLAGS, |
644 | ATA_FLAG_PMP | ATA_FLAG_ACPI_SATA | | ||
645 | ATA_FLAG_NCQ, | ||
646 | .pio_mask = 0x1f, /* pio0-4 */ | 647 | .pio_mask = 0x1f, /* pio0-4 */ |
647 | .udma_mask = ATA_UDMA6, | 648 | .udma_mask = ATA_UDMA6, |
648 | .port_ops = &mv_iie_ops, | 649 | .port_ops = &mv_iie_ops, |
649 | }, | 650 | }, |
650 | { /* chip_7042 */ | 651 | { /* chip_7042 */ |
651 | .flags = MV_COMMON_FLAGS | MV_6XXX_FLAGS | | 652 | .flags = MV_GENIIE_FLAGS, |
652 | ATA_FLAG_PMP | ATA_FLAG_ACPI_SATA | | ||
653 | ATA_FLAG_NCQ, | ||
654 | .pio_mask = 0x1f, /* pio0-4 */ | 653 | .pio_mask = 0x1f, /* pio0-4 */ |
655 | .udma_mask = ATA_UDMA6, | 654 | .udma_mask = ATA_UDMA6, |
656 | .port_ops = &mv_iie_ops, | 655 | .port_ops = &mv_iie_ops, |
657 | }, | 656 | }, |
658 | { /* chip_soc */ | 657 | { /* chip_soc */ |
659 | .flags = MV_COMMON_FLAGS | MV_6XXX_FLAGS | | 658 | .flags = MV_GENIIE_FLAGS, |
660 | ATA_FLAG_PMP | ATA_FLAG_ACPI_SATA | | ||
661 | ATA_FLAG_NCQ | MV_FLAG_SOC, | ||
662 | .pio_mask = 0x1f, /* pio0-4 */ | 659 | .pio_mask = 0x1f, /* pio0-4 */ |
663 | .udma_mask = ATA_UDMA6, | 660 | .udma_mask = ATA_UDMA6, |
664 | .port_ops = &mv_iie_ops, | 661 | .port_ops = &mv_iie_ops, |
@@ -818,12 +815,7 @@ static void mv_set_edma_ptrs(void __iomem *port_mmio, | |||
818 | writel((pp->crqb_dma >> 16) >> 16, port_mmio + EDMA_REQ_Q_BASE_HI_OFS); | 815 | writel((pp->crqb_dma >> 16) >> 16, port_mmio + EDMA_REQ_Q_BASE_HI_OFS); |
819 | writelfl((pp->crqb_dma & EDMA_REQ_Q_BASE_LO_MASK) | index, | 816 | writelfl((pp->crqb_dma & EDMA_REQ_Q_BASE_LO_MASK) | index, |
820 | port_mmio + EDMA_REQ_Q_IN_PTR_OFS); | 817 | port_mmio + EDMA_REQ_Q_IN_PTR_OFS); |
821 | 818 | writelfl(index, port_mmio + EDMA_REQ_Q_OUT_PTR_OFS); | |
822 | if (hpriv->hp_flags & MV_HP_ERRATA_XX42A0) | ||
823 | writelfl((pp->crqb_dma & 0xffffffff) | index, | ||
824 | port_mmio + EDMA_REQ_Q_OUT_PTR_OFS); | ||
825 | else | ||
826 | writelfl(index, port_mmio + EDMA_REQ_Q_OUT_PTR_OFS); | ||
827 | 819 | ||
828 | /* | 820 | /* |
829 | * initialize response queue | 821 | * initialize response queue |
@@ -833,17 +825,38 @@ static void mv_set_edma_ptrs(void __iomem *port_mmio, | |||
833 | 825 | ||
834 | WARN_ON(pp->crpb_dma & 0xff); | 826 | WARN_ON(pp->crpb_dma & 0xff); |
835 | writel((pp->crpb_dma >> 16) >> 16, port_mmio + EDMA_RSP_Q_BASE_HI_OFS); | 827 | writel((pp->crpb_dma >> 16) >> 16, port_mmio + EDMA_RSP_Q_BASE_HI_OFS); |
836 | 828 | writelfl(index, port_mmio + EDMA_RSP_Q_IN_PTR_OFS); | |
837 | if (hpriv->hp_flags & MV_HP_ERRATA_XX42A0) | ||
838 | writelfl((pp->crpb_dma & 0xffffffff) | index, | ||
839 | port_mmio + EDMA_RSP_Q_IN_PTR_OFS); | ||
840 | else | ||
841 | writelfl(index, port_mmio + EDMA_RSP_Q_IN_PTR_OFS); | ||
842 | |||
843 | writelfl((pp->crpb_dma & EDMA_RSP_Q_BASE_LO_MASK) | index, | 829 | writelfl((pp->crpb_dma & EDMA_RSP_Q_BASE_LO_MASK) | index, |
844 | port_mmio + EDMA_RSP_Q_OUT_PTR_OFS); | 830 | port_mmio + EDMA_RSP_Q_OUT_PTR_OFS); |
845 | } | 831 | } |
846 | 832 | ||
833 | static void mv_set_main_irq_mask(struct ata_host *host, | ||
834 | u32 disable_bits, u32 enable_bits) | ||
835 | { | ||
836 | struct mv_host_priv *hpriv = host->private_data; | ||
837 | u32 old_mask, new_mask; | ||
838 | |||
839 | old_mask = hpriv->main_irq_mask; | ||
840 | new_mask = (old_mask & ~disable_bits) | enable_bits; | ||
841 | if (new_mask != old_mask) { | ||
842 | hpriv->main_irq_mask = new_mask; | ||
843 | writelfl(new_mask, hpriv->main_irq_mask_addr); | ||
844 | } | ||
845 | } | ||
846 | |||
847 | static void mv_enable_port_irqs(struct ata_port *ap, | ||
848 | unsigned int port_bits) | ||
849 | { | ||
850 | unsigned int shift, hardport, port = ap->port_no; | ||
851 | u32 disable_bits, enable_bits; | ||
852 | |||
853 | MV_PORT_TO_SHIFT_AND_HARDPORT(port, shift, hardport); | ||
854 | |||
855 | disable_bits = (DONE_IRQ | ERR_IRQ) << shift; | ||
856 | enable_bits = port_bits << shift; | ||
857 | mv_set_main_irq_mask(ap->host, disable_bits, enable_bits); | ||
858 | } | ||
859 | |||
847 | /** | 860 | /** |
848 | * mv_start_dma - Enable eDMA engine | 861 | * mv_start_dma - Enable eDMA engine |
849 | * @base: port base address | 862 | * @base: port base address |
@@ -886,9 +899,11 @@ static void mv_start_dma(struct ata_port *ap, void __iomem *port_mmio, | |||
886 | mv_edma_cfg(ap, want_ncq); | 899 | mv_edma_cfg(ap, want_ncq); |
887 | 900 | ||
888 | /* clear FIS IRQ Cause */ | 901 | /* clear FIS IRQ Cause */ |
889 | writelfl(0, port_mmio + SATA_FIS_IRQ_CAUSE_OFS); | 902 | if (IS_GEN_IIE(hpriv)) |
903 | writelfl(0, port_mmio + SATA_FIS_IRQ_CAUSE_OFS); | ||
890 | 904 | ||
891 | mv_set_edma_ptrs(port_mmio, hpriv, pp); | 905 | mv_set_edma_ptrs(port_mmio, hpriv, pp); |
906 | mv_enable_port_irqs(ap, DONE_IRQ|ERR_IRQ); | ||
892 | 907 | ||
893 | writelfl(EDMA_EN, port_mmio + EDMA_CMD_OFS); | 908 | writelfl(EDMA_EN, port_mmio + EDMA_CMD_OFS); |
894 | pp->pp_flags |= MV_PP_FLAG_EDMA_EN; | 909 | pp->pp_flags |= MV_PP_FLAG_EDMA_EN; |
@@ -1231,7 +1246,7 @@ static void mv_edma_cfg(struct ata_port *ap, int want_ncq) | |||
1231 | 1246 | ||
1232 | cfg |= (1 << 23); /* do not mask PM field in rx'd FIS */ | 1247 | cfg |= (1 << 23); /* do not mask PM field in rx'd FIS */ |
1233 | cfg |= (1 << 22); /* enab 4-entry host queue cache */ | 1248 | cfg |= (1 << 22); /* enab 4-entry host queue cache */ |
1234 | if (HAS_PCI(ap->host)) | 1249 | if (!IS_SOC(hpriv)) |
1235 | cfg |= (1 << 18); /* enab early completion */ | 1250 | cfg |= (1 << 18); /* enab early completion */ |
1236 | if (hpriv->hp_flags & MV_HP_CUT_THROUGH) | 1251 | if (hpriv->hp_flags & MV_HP_CUT_THROUGH) |
1237 | cfg |= (1 << 17); /* enab cut-thru (dis stor&forwrd) */ | 1252 | cfg |= (1 << 17); /* enab cut-thru (dis stor&forwrd) */ |
@@ -1341,6 +1356,7 @@ out_port_free_dma_mem: | |||
1341 | static void mv_port_stop(struct ata_port *ap) | 1356 | static void mv_port_stop(struct ata_port *ap) |
1342 | { | 1357 | { |
1343 | mv_stop_edma(ap); | 1358 | mv_stop_edma(ap); |
1359 | mv_enable_port_irqs(ap, 0); | ||
1344 | mv_port_free_dma_mem(ap); | 1360 | mv_port_free_dma_mem(ap); |
1345 | } | 1361 | } |
1346 | 1362 | ||
@@ -1582,6 +1598,7 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc) | |||
1582 | * shadow block, etc registers. | 1598 | * shadow block, etc registers. |
1583 | */ | 1599 | */ |
1584 | mv_stop_edma(ap); | 1600 | mv_stop_edma(ap); |
1601 | mv_enable_port_irqs(ap, ERR_IRQ); | ||
1585 | mv_pmp_select(ap, qc->dev->link->pmp); | 1602 | mv_pmp_select(ap, qc->dev->link->pmp); |
1586 | return ata_sff_qc_issue(qc); | 1603 | return ata_sff_qc_issue(qc); |
1587 | } | 1604 | } |
@@ -1670,6 +1687,18 @@ static void mv_pmp_eh_prep(struct ata_port *ap, unsigned int pmp_map) | |||
1670 | } | 1687 | } |
1671 | } | 1688 | } |
1672 | 1689 | ||
1690 | static int mv_req_q_empty(struct ata_port *ap) | ||
1691 | { | ||
1692 | void __iomem *port_mmio = mv_ap_base(ap); | ||
1693 | u32 in_ptr, out_ptr; | ||
1694 | |||
1695 | in_ptr = (readl(port_mmio + EDMA_REQ_Q_IN_PTR_OFS) | ||
1696 | >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK; | ||
1697 | out_ptr = (readl(port_mmio + EDMA_REQ_Q_OUT_PTR_OFS) | ||
1698 | >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK; | ||
1699 | return (in_ptr == out_ptr); /* 1 == queue_is_empty */ | ||
1700 | } | ||
1701 | |||
1673 | static int mv_handle_fbs_ncq_dev_err(struct ata_port *ap) | 1702 | static int mv_handle_fbs_ncq_dev_err(struct ata_port *ap) |
1674 | { | 1703 | { |
1675 | struct mv_port_priv *pp = ap->private_data; | 1704 | struct mv_port_priv *pp = ap->private_data; |
@@ -1703,7 +1732,7 @@ static int mv_handle_fbs_ncq_dev_err(struct ata_port *ap) | |||
1703 | ap->qc_active, failed_links, | 1732 | ap->qc_active, failed_links, |
1704 | ap->nr_active_links); | 1733 | ap->nr_active_links); |
1705 | 1734 | ||
1706 | if (ap->nr_active_links <= failed_links) { | 1735 | if (ap->nr_active_links <= failed_links && mv_req_q_empty(ap)) { |
1707 | mv_process_crpb_entries(ap, pp); | 1736 | mv_process_crpb_entries(ap, pp); |
1708 | mv_stop_edma(ap); | 1737 | mv_stop_edma(ap); |
1709 | mv_eh_freeze(ap); | 1738 | mv_eh_freeze(ap); |
@@ -1812,6 +1841,7 @@ static void mv_err_intr(struct ata_port *ap) | |||
1812 | { | 1841 | { |
1813 | void __iomem *port_mmio = mv_ap_base(ap); | 1842 | void __iomem *port_mmio = mv_ap_base(ap); |
1814 | u32 edma_err_cause, eh_freeze_mask, serr = 0; | 1843 | u32 edma_err_cause, eh_freeze_mask, serr = 0; |
1844 | u32 fis_cause = 0; | ||
1815 | struct mv_port_priv *pp = ap->private_data; | 1845 | struct mv_port_priv *pp = ap->private_data; |
1816 | struct mv_host_priv *hpriv = ap->host->private_data; | 1846 | struct mv_host_priv *hpriv = ap->host->private_data; |
1817 | unsigned int action = 0, err_mask = 0; | 1847 | unsigned int action = 0, err_mask = 0; |
@@ -1821,16 +1851,19 @@ static void mv_err_intr(struct ata_port *ap) | |||
1821 | 1851 | ||
1822 | /* | 1852 | /* |
1823 | * Read and clear the SError and err_cause bits. | 1853 | * Read and clear the SError and err_cause bits. |
1854 | * For GenIIe, if EDMA_ERR_TRANS_IRQ_7 is set, we also must read/clear | ||
1855 | * the FIS_IRQ_CAUSE register before clearing edma_err_cause. | ||
1824 | */ | 1856 | */ |
1825 | sata_scr_read(&ap->link, SCR_ERROR, &serr); | 1857 | sata_scr_read(&ap->link, SCR_ERROR, &serr); |
1826 | sata_scr_write_flush(&ap->link, SCR_ERROR, serr); | 1858 | sata_scr_write_flush(&ap->link, SCR_ERROR, serr); |
1827 | 1859 | ||
1828 | edma_err_cause = readl(port_mmio + EDMA_ERR_IRQ_CAUSE_OFS); | 1860 | edma_err_cause = readl(port_mmio + EDMA_ERR_IRQ_CAUSE_OFS); |
1861 | if (IS_GEN_IIE(hpriv) && (edma_err_cause & EDMA_ERR_TRANS_IRQ_7)) { | ||
1862 | fis_cause = readl(port_mmio + SATA_FIS_IRQ_CAUSE_OFS); | ||
1863 | writelfl(~fis_cause, port_mmio + SATA_FIS_IRQ_CAUSE_OFS); | ||
1864 | } | ||
1829 | writelfl(~edma_err_cause, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS); | 1865 | writelfl(~edma_err_cause, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS); |
1830 | 1866 | ||
1831 | ata_port_printk(ap, KERN_INFO, "%s: err_cause=%08x pp_flags=0x%x\n", | ||
1832 | __func__, edma_err_cause, pp->pp_flags); | ||
1833 | |||
1834 | if (edma_err_cause & EDMA_ERR_DEV) { | 1867 | if (edma_err_cause & EDMA_ERR_DEV) { |
1835 | /* | 1868 | /* |
1836 | * Device errors during FIS-based switching operation | 1869 | * Device errors during FIS-based switching operation |
@@ -1844,6 +1877,18 @@ static void mv_err_intr(struct ata_port *ap) | |||
1844 | ata_ehi_clear_desc(ehi); | 1877 | ata_ehi_clear_desc(ehi); |
1845 | ata_ehi_push_desc(ehi, "edma_err_cause=%08x pp_flags=%08x", | 1878 | ata_ehi_push_desc(ehi, "edma_err_cause=%08x pp_flags=%08x", |
1846 | edma_err_cause, pp->pp_flags); | 1879 | edma_err_cause, pp->pp_flags); |
1880 | |||
1881 | if (IS_GEN_IIE(hpriv) && (edma_err_cause & EDMA_ERR_TRANS_IRQ_7)) { | ||
1882 | ata_ehi_push_desc(ehi, "fis_cause=%08x", fis_cause); | ||
1883 | if (fis_cause & SATA_FIS_IRQ_AN) { | ||
1884 | u32 ec = edma_err_cause & | ||
1885 | ~(EDMA_ERR_TRANS_IRQ_7 | EDMA_ERR_IRQ_TRANSIENT); | ||
1886 | sata_async_notification(ap); | ||
1887 | if (!ec) | ||
1888 | return; /* Just an AN; no need for the nukes */ | ||
1889 | ata_ehi_push_desc(ehi, "SDB notify"); | ||
1890 | } | ||
1891 | } | ||
1847 | /* | 1892 | /* |
1848 | * All generations share these EDMA error cause bits: | 1893 | * All generations share these EDMA error cause bits: |
1849 | */ | 1894 | */ |
@@ -2162,20 +2207,20 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance) | |||
2162 | struct ata_host *host = dev_instance; | 2207 | struct ata_host *host = dev_instance; |
2163 | struct mv_host_priv *hpriv = host->private_data; | 2208 | struct mv_host_priv *hpriv = host->private_data; |
2164 | unsigned int handled = 0; | 2209 | unsigned int handled = 0; |
2165 | u32 main_irq_cause, main_irq_mask; | 2210 | u32 main_irq_cause, pending_irqs; |
2166 | 2211 | ||
2167 | spin_lock(&host->lock); | 2212 | spin_lock(&host->lock); |
2168 | main_irq_cause = readl(hpriv->main_irq_cause_addr); | 2213 | main_irq_cause = readl(hpriv->main_irq_cause_addr); |
2169 | main_irq_mask = readl(hpriv->main_irq_mask_addr); | 2214 | pending_irqs = main_irq_cause & hpriv->main_irq_mask; |
2170 | /* | 2215 | /* |
2171 | * Deal with cases where we either have nothing pending, or have read | 2216 | * Deal with cases where we either have nothing pending, or have read |
2172 | * a bogus register value which can indicate HW removal or PCI fault. | 2217 | * a bogus register value which can indicate HW removal or PCI fault. |
2173 | */ | 2218 | */ |
2174 | if ((main_irq_cause & main_irq_mask) && (main_irq_cause != 0xffffffffU)) { | 2219 | if (pending_irqs && main_irq_cause != 0xffffffffU) { |
2175 | if (unlikely((main_irq_cause & PCI_ERR) && HAS_PCI(host))) | 2220 | if (unlikely((pending_irqs & PCI_ERR) && !IS_SOC(hpriv))) |
2176 | handled = mv_pci_error(host, hpriv->base); | 2221 | handled = mv_pci_error(host, hpriv->base); |
2177 | else | 2222 | else |
2178 | handled = mv_host_intr(host, main_irq_cause); | 2223 | handled = mv_host_intr(host, pending_irqs); |
2179 | } | 2224 | } |
2180 | spin_unlock(&host->lock); | 2225 | spin_unlock(&host->lock); |
2181 | return IRQ_RETVAL(handled); | 2226 | return IRQ_RETVAL(handled); |
@@ -2373,7 +2418,6 @@ static void mv_reset_pci_bus(struct ata_host *host, void __iomem *mmio) | |||
2373 | ZERO(MV_PCI_DISC_TIMER); | 2418 | ZERO(MV_PCI_DISC_TIMER); |
2374 | ZERO(MV_PCI_MSI_TRIGGER); | 2419 | ZERO(MV_PCI_MSI_TRIGGER); |
2375 | writel(0x000100ff, mmio + MV_PCI_XBAR_TMOUT_OFS); | 2420 | writel(0x000100ff, mmio + MV_PCI_XBAR_TMOUT_OFS); |
2376 | ZERO(PCI_HC_MAIN_IRQ_MASK_OFS); | ||
2377 | ZERO(MV_PCI_SERR_MASK); | 2421 | ZERO(MV_PCI_SERR_MASK); |
2378 | ZERO(hpriv->irq_cause_ofs); | 2422 | ZERO(hpriv->irq_cause_ofs); |
2379 | ZERO(hpriv->irq_mask_ofs); | 2423 | ZERO(hpriv->irq_mask_ofs); |
@@ -2495,7 +2539,7 @@ static void mv6_phy_errata(struct mv_host_priv *hpriv, void __iomem *mmio, | |||
2495 | hp_flags & (MV_HP_ERRATA_60X1B2 | MV_HP_ERRATA_60X1C0); | 2539 | hp_flags & (MV_HP_ERRATA_60X1B2 | MV_HP_ERRATA_60X1C0); |
2496 | int fix_phy_mode4 = | 2540 | int fix_phy_mode4 = |
2497 | hp_flags & (MV_HP_ERRATA_60X1B2 | MV_HP_ERRATA_60X1C0); | 2541 | hp_flags & (MV_HP_ERRATA_60X1B2 | MV_HP_ERRATA_60X1C0); |
2498 | u32 m2, tmp; | 2542 | u32 m2, m3; |
2499 | 2543 | ||
2500 | if (fix_phy_mode2) { | 2544 | if (fix_phy_mode2) { |
2501 | m2 = readl(port_mmio + PHY_MODE2); | 2545 | m2 = readl(port_mmio + PHY_MODE2); |
@@ -2512,28 +2556,36 @@ static void mv6_phy_errata(struct mv_host_priv *hpriv, void __iomem *mmio, | |||
2512 | udelay(200); | 2556 | udelay(200); |
2513 | } | 2557 | } |
2514 | 2558 | ||
2515 | /* who knows what this magic does */ | 2559 | /* |
2516 | tmp = readl(port_mmio + PHY_MODE3); | 2560 | * Gen-II/IIe PHY_MODE3 errata RM#2: |
2517 | tmp &= ~0x7F800000; | 2561 | * Achieves better receiver noise performance than the h/w default: |
2518 | tmp |= 0x2A800000; | 2562 | */ |
2519 | writel(tmp, port_mmio + PHY_MODE3); | 2563 | m3 = readl(port_mmio + PHY_MODE3); |
2520 | 2564 | m3 = (m3 & 0x1f) | (0x5555601 << 5); | |
2521 | if (fix_phy_mode4) { | ||
2522 | u32 m4; | ||
2523 | |||
2524 | m4 = readl(port_mmio + PHY_MODE4); | ||
2525 | |||
2526 | if (hp_flags & MV_HP_ERRATA_60X1B2) | ||
2527 | tmp = readl(port_mmio + PHY_MODE3); | ||
2528 | 2565 | ||
2529 | /* workaround for errata FEr SATA#10 (part 1) */ | 2566 | /* Guideline 88F5182 (GL# SATA-S11) */ |
2530 | m4 = (m4 & ~(1 << 1)) | (1 << 0); | 2567 | if (IS_SOC(hpriv)) |
2568 | m3 &= ~0x1c; | ||
2531 | 2569 | ||
2570 | if (fix_phy_mode4) { | ||
2571 | u32 m4 = readl(port_mmio + PHY_MODE4); | ||
2572 | /* | ||
2573 | * Enforce reserved-bit restrictions on GenIIe devices only. | ||
2574 | * For earlier chipsets, force only the internal config field | ||
2575 | * (workaround for errata FEr SATA#10 part 1). | ||
2576 | */ | ||
2577 | if (IS_GEN_IIE(hpriv)) | ||
2578 | m4 = (m4 & ~PHY_MODE4_RSVD_ZEROS) | PHY_MODE4_RSVD_ONES; | ||
2579 | else | ||
2580 | m4 = (m4 & ~PHY_MODE4_CFG_MASK) | PHY_MODE4_CFG_VALUE; | ||
2532 | writel(m4, port_mmio + PHY_MODE4); | 2581 | writel(m4, port_mmio + PHY_MODE4); |
2533 | |||
2534 | if (hp_flags & MV_HP_ERRATA_60X1B2) | ||
2535 | writel(tmp, port_mmio + PHY_MODE3); | ||
2536 | } | 2582 | } |
2583 | /* | ||
2584 | * Workaround for 60x1-B2 errata SATA#13: | ||
2585 | * Any write to PHY_MODE4 (above) may corrupt PHY_MODE3, | ||
2586 | * so we must always rewrite PHY_MODE3 after PHY_MODE4. | ||
2587 | */ | ||
2588 | writel(m3, port_mmio + PHY_MODE3); | ||
2537 | 2589 | ||
2538 | /* Revert values of pre-emphasis and signal amps to the saved ones */ | 2590 | /* Revert values of pre-emphasis and signal amps to the saved ones */ |
2539 | m2 = readl(port_mmio + PHY_MODE2); | 2591 | m2 = readl(port_mmio + PHY_MODE2); |
@@ -2728,6 +2780,7 @@ static int mv_hardreset(struct ata_link *link, unsigned int *class, | |||
2728 | 2780 | ||
2729 | rc = sata_link_hardreset(link, timing, deadline + extra, | 2781 | rc = sata_link_hardreset(link, timing, deadline + extra, |
2730 | &online, NULL); | 2782 | &online, NULL); |
2783 | rc = online ? -EAGAIN : rc; | ||
2731 | if (rc) | 2784 | if (rc) |
2732 | return rc; | 2785 | return rc; |
2733 | sata_scr_read(link, SCR_STATUS, &sstatus); | 2786 | sata_scr_read(link, SCR_STATUS, &sstatus); |
@@ -2744,32 +2797,18 @@ static int mv_hardreset(struct ata_link *link, unsigned int *class, | |||
2744 | 2797 | ||
2745 | static void mv_eh_freeze(struct ata_port *ap) | 2798 | static void mv_eh_freeze(struct ata_port *ap) |
2746 | { | 2799 | { |
2747 | struct mv_host_priv *hpriv = ap->host->private_data; | ||
2748 | unsigned int shift, hardport, port = ap->port_no; | ||
2749 | u32 main_irq_mask; | ||
2750 | |||
2751 | /* FIXME: handle coalescing completion events properly */ | ||
2752 | |||
2753 | mv_stop_edma(ap); | 2800 | mv_stop_edma(ap); |
2754 | MV_PORT_TO_SHIFT_AND_HARDPORT(port, shift, hardport); | 2801 | mv_enable_port_irqs(ap, 0); |
2755 | |||
2756 | /* disable assertion of portN err, done events */ | ||
2757 | main_irq_mask = readl(hpriv->main_irq_mask_addr); | ||
2758 | main_irq_mask &= ~((DONE_IRQ | ERR_IRQ) << shift); | ||
2759 | writelfl(main_irq_mask, hpriv->main_irq_mask_addr); | ||
2760 | } | 2802 | } |
2761 | 2803 | ||
2762 | static void mv_eh_thaw(struct ata_port *ap) | 2804 | static void mv_eh_thaw(struct ata_port *ap) |
2763 | { | 2805 | { |
2764 | struct mv_host_priv *hpriv = ap->host->private_data; | 2806 | struct mv_host_priv *hpriv = ap->host->private_data; |
2765 | unsigned int shift, hardport, port = ap->port_no; | 2807 | unsigned int port = ap->port_no; |
2808 | unsigned int hardport = mv_hardport_from_port(port); | ||
2766 | void __iomem *hc_mmio = mv_hc_base_from_port(hpriv->base, port); | 2809 | void __iomem *hc_mmio = mv_hc_base_from_port(hpriv->base, port); |
2767 | void __iomem *port_mmio = mv_ap_base(ap); | 2810 | void __iomem *port_mmio = mv_ap_base(ap); |
2768 | u32 main_irq_mask, hc_irq_cause; | 2811 | u32 hc_irq_cause; |
2769 | |||
2770 | /* FIXME: handle coalescing completion events properly */ | ||
2771 | |||
2772 | MV_PORT_TO_SHIFT_AND_HARDPORT(port, shift, hardport); | ||
2773 | 2812 | ||
2774 | /* clear EDMA errors on this port */ | 2813 | /* clear EDMA errors on this port */ |
2775 | writel(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS); | 2814 | writel(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS); |
@@ -2779,10 +2818,7 @@ static void mv_eh_thaw(struct ata_port *ap) | |||
2779 | hc_irq_cause &= ~((DEV_IRQ | DMA_IRQ) << hardport); | 2818 | hc_irq_cause &= ~((DEV_IRQ | DMA_IRQ) << hardport); |
2780 | writelfl(hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS); | 2819 | writelfl(hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS); |
2781 | 2820 | ||
2782 | /* enable assertion of portN err, done events */ | 2821 | mv_enable_port_irqs(ap, ERR_IRQ); |
2783 | main_irq_mask = readl(hpriv->main_irq_mask_addr); | ||
2784 | main_irq_mask |= ((DONE_IRQ | ERR_IRQ) << shift); | ||
2785 | writelfl(main_irq_mask, hpriv->main_irq_mask_addr); | ||
2786 | } | 2822 | } |
2787 | 2823 | ||
2788 | /** | 2824 | /** |
@@ -2840,7 +2876,7 @@ static unsigned int mv_in_pcix_mode(struct ata_host *host) | |||
2840 | void __iomem *mmio = hpriv->base; | 2876 | void __iomem *mmio = hpriv->base; |
2841 | u32 reg; | 2877 | u32 reg; |
2842 | 2878 | ||
2843 | if (!HAS_PCI(host) || !IS_PCIE(hpriv)) | 2879 | if (IS_SOC(hpriv) || !IS_PCIE(hpriv)) |
2844 | return 0; /* not PCI-X capable */ | 2880 | return 0; /* not PCI-X capable */ |
2845 | reg = readl(mmio + MV_PCI_MODE_OFS); | 2881 | reg = readl(mmio + MV_PCI_MODE_OFS); |
2846 | if ((reg & MV_PCI_MODE_MASK) == 0) | 2882 | if ((reg & MV_PCI_MODE_MASK) == 0) |
@@ -2967,10 +3003,7 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx) | |||
2967 | hp_flags |= MV_HP_CUT_THROUGH; | 3003 | hp_flags |= MV_HP_CUT_THROUGH; |
2968 | 3004 | ||
2969 | switch (pdev->revision) { | 3005 | switch (pdev->revision) { |
2970 | case 0x0: | 3006 | case 0x2: /* Rev.B0: the first/only public release */ |
2971 | hp_flags |= MV_HP_ERRATA_XX42A0; | ||
2972 | break; | ||
2973 | case 0x1: | ||
2974 | hp_flags |= MV_HP_ERRATA_60X1C0; | 3007 | hp_flags |= MV_HP_ERRATA_60X1C0; |
2975 | break; | 3008 | break; |
2976 | default: | 3009 | default: |
@@ -2982,7 +3015,7 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx) | |||
2982 | break; | 3015 | break; |
2983 | case chip_soc: | 3016 | case chip_soc: |
2984 | hpriv->ops = &mv_soc_ops; | 3017 | hpriv->ops = &mv_soc_ops; |
2985 | hp_flags |= MV_HP_ERRATA_60X1C0; | 3018 | hp_flags |= MV_HP_FLAG_SOC | MV_HP_ERRATA_60X1C0; |
2986 | break; | 3019 | break; |
2987 | 3020 | ||
2988 | default: | 3021 | default: |
@@ -3026,16 +3059,16 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx) | |||
3026 | if (rc) | 3059 | if (rc) |
3027 | goto done; | 3060 | goto done; |
3028 | 3061 | ||
3029 | if (HAS_PCI(host)) { | 3062 | if (IS_SOC(hpriv)) { |
3030 | hpriv->main_irq_cause_addr = mmio + PCI_HC_MAIN_IRQ_CAUSE_OFS; | ||
3031 | hpriv->main_irq_mask_addr = mmio + PCI_HC_MAIN_IRQ_MASK_OFS; | ||
3032 | } else { | ||
3033 | hpriv->main_irq_cause_addr = mmio + SOC_HC_MAIN_IRQ_CAUSE_OFS; | 3063 | hpriv->main_irq_cause_addr = mmio + SOC_HC_MAIN_IRQ_CAUSE_OFS; |
3034 | hpriv->main_irq_mask_addr = mmio + SOC_HC_MAIN_IRQ_MASK_OFS; | 3064 | hpriv->main_irq_mask_addr = mmio + SOC_HC_MAIN_IRQ_MASK_OFS; |
3065 | } else { | ||
3066 | hpriv->main_irq_cause_addr = mmio + PCI_HC_MAIN_IRQ_CAUSE_OFS; | ||
3067 | hpriv->main_irq_mask_addr = mmio + PCI_HC_MAIN_IRQ_MASK_OFS; | ||
3035 | } | 3068 | } |
3036 | 3069 | ||
3037 | /* global interrupt mask: 0 == mask everything */ | 3070 | /* global interrupt mask: 0 == mask everything */ |
3038 | writel(0, hpriv->main_irq_mask_addr); | 3071 | mv_set_main_irq_mask(host, ~0, 0); |
3039 | 3072 | ||
3040 | n_hc = mv_get_hc_count(host->ports[0]->flags); | 3073 | n_hc = mv_get_hc_count(host->ports[0]->flags); |
3041 | 3074 | ||
@@ -3057,7 +3090,7 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx) | |||
3057 | mv_port_init(&ap->ioaddr, port_mmio); | 3090 | mv_port_init(&ap->ioaddr, port_mmio); |
3058 | 3091 | ||
3059 | #ifdef CONFIG_PCI | 3092 | #ifdef CONFIG_PCI |
3060 | if (HAS_PCI(host)) { | 3093 | if (!IS_SOC(hpriv)) { |
3061 | unsigned int offset = port_mmio - mmio; | 3094 | unsigned int offset = port_mmio - mmio; |
3062 | ata_port_pbar_desc(ap, MV_PRIMARY_BAR, -1, "mmio"); | 3095 | ata_port_pbar_desc(ap, MV_PRIMARY_BAR, -1, "mmio"); |
3063 | ata_port_pbar_desc(ap, MV_PRIMARY_BAR, offset, "port"); | 3096 | ata_port_pbar_desc(ap, MV_PRIMARY_BAR, offset, "port"); |
@@ -3077,31 +3110,18 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx) | |||
3077 | writelfl(0, hc_mmio + HC_IRQ_CAUSE_OFS); | 3110 | writelfl(0, hc_mmio + HC_IRQ_CAUSE_OFS); |
3078 | } | 3111 | } |
3079 | 3112 | ||
3080 | if (HAS_PCI(host)) { | 3113 | if (!IS_SOC(hpriv)) { |
3081 | /* Clear any currently outstanding host interrupt conditions */ | 3114 | /* Clear any currently outstanding host interrupt conditions */ |
3082 | writelfl(0, mmio + hpriv->irq_cause_ofs); | 3115 | writelfl(0, mmio + hpriv->irq_cause_ofs); |
3083 | 3116 | ||
3084 | /* and unmask interrupt generation for host regs */ | 3117 | /* and unmask interrupt generation for host regs */ |
3085 | writelfl(hpriv->unmask_all_irqs, mmio + hpriv->irq_mask_ofs); | 3118 | writelfl(hpriv->unmask_all_irqs, mmio + hpriv->irq_mask_ofs); |
3086 | if (IS_GEN_I(hpriv)) | 3119 | |
3087 | writelfl(~HC_MAIN_MASKED_IRQS_5, | 3120 | /* |
3088 | hpriv->main_irq_mask_addr); | 3121 | * enable only global host interrupts for now. |
3089 | else | 3122 | * The per-port interrupts get done later as ports are set up. |
3090 | writelfl(~HC_MAIN_MASKED_IRQS, | 3123 | */ |
3091 | hpriv->main_irq_mask_addr); | 3124 | mv_set_main_irq_mask(host, 0, PCI_ERR); |
3092 | |||
3093 | VPRINTK("HC MAIN IRQ cause/mask=0x%08x/0x%08x " | ||
3094 | "PCI int cause/mask=0x%08x/0x%08x\n", | ||
3095 | readl(hpriv->main_irq_cause_addr), | ||
3096 | readl(hpriv->main_irq_mask_addr), | ||
3097 | readl(mmio + hpriv->irq_cause_ofs), | ||
3098 | readl(mmio + hpriv->irq_mask_ofs)); | ||
3099 | } else { | ||
3100 | writelfl(~HC_MAIN_MASKED_IRQS_SOC, | ||
3101 | hpriv->main_irq_mask_addr); | ||
3102 | VPRINTK("HC MAIN IRQ cause/mask=0x%08x/0x%08x\n", | ||
3103 | readl(hpriv->main_irq_cause_addr), | ||
3104 | readl(hpriv->main_irq_mask_addr)); | ||
3105 | } | 3125 | } |
3106 | done: | 3126 | done: |
3107 | return rc; | 3127 | return rc; |
diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c index 5a10dc5048ad..030665ba76b7 100644 --- a/drivers/ata/sata_promise.c +++ b/drivers/ata/sata_promise.c | |||
@@ -53,7 +53,15 @@ enum { | |||
53 | PDC_MMIO_BAR = 3, | 53 | PDC_MMIO_BAR = 3, |
54 | PDC_MAX_PRD = LIBATA_MAX_PRD - 1, /* -1 for ASIC PRD bug workaround */ | 54 | PDC_MAX_PRD = LIBATA_MAX_PRD - 1, /* -1 for ASIC PRD bug workaround */ |
55 | 55 | ||
56 | /* register offsets */ | 56 | /* host register offsets (from host->iomap[PDC_MMIO_BAR]) */ |
57 | PDC_INT_SEQMASK = 0x40, /* Mask of asserted SEQ INTs */ | ||
58 | PDC_FLASH_CTL = 0x44, /* Flash control register */ | ||
59 | PDC_SATA_PLUG_CSR = 0x6C, /* SATA Plug control/status reg */ | ||
60 | PDC2_SATA_PLUG_CSR = 0x60, /* SATAII Plug control/status reg */ | ||
61 | PDC_TBG_MODE = 0x41C, /* TBG mode (not SATAII) */ | ||
62 | PDC_SLEW_CTL = 0x470, /* slew rate control reg (not SATAII) */ | ||
63 | |||
64 | /* per-port ATA register offsets (from ap->ioaddr.cmd_addr) */ | ||
57 | PDC_FEATURE = 0x04, /* Feature/Error reg (per port) */ | 65 | PDC_FEATURE = 0x04, /* Feature/Error reg (per port) */ |
58 | PDC_SECTOR_COUNT = 0x08, /* Sector count reg (per port) */ | 66 | PDC_SECTOR_COUNT = 0x08, /* Sector count reg (per port) */ |
59 | PDC_SECTOR_NUMBER = 0x0C, /* Sector number reg (per port) */ | 67 | PDC_SECTOR_NUMBER = 0x0C, /* Sector number reg (per port) */ |
@@ -63,14 +71,11 @@ enum { | |||
63 | PDC_COMMAND = 0x1C, /* Command/status reg (per port) */ | 71 | PDC_COMMAND = 0x1C, /* Command/status reg (per port) */ |
64 | PDC_ALTSTATUS = 0x38, /* Alternate-status/device-control reg (per port) */ | 72 | PDC_ALTSTATUS = 0x38, /* Alternate-status/device-control reg (per port) */ |
65 | PDC_PKT_SUBMIT = 0x40, /* Command packet pointer addr */ | 73 | PDC_PKT_SUBMIT = 0x40, /* Command packet pointer addr */ |
66 | PDC_INT_SEQMASK = 0x40, /* Mask of asserted SEQ INTs */ | ||
67 | PDC_FLASH_CTL = 0x44, /* Flash control register */ | ||
68 | PDC_GLOBAL_CTL = 0x48, /* Global control/status (per port) */ | 74 | PDC_GLOBAL_CTL = 0x48, /* Global control/status (per port) */ |
69 | PDC_CTLSTAT = 0x60, /* IDE control and status (per port) */ | 75 | PDC_CTLSTAT = 0x60, /* IDE control and status (per port) */ |
70 | PDC_SATA_PLUG_CSR = 0x6C, /* SATA Plug control/status reg */ | 76 | |
71 | PDC2_SATA_PLUG_CSR = 0x60, /* SATAII Plug control/status reg */ | 77 | /* per-port SATA register offsets (from ap->ioaddr.scr_addr) */ |
72 | PDC_TBG_MODE = 0x41C, /* TBG mode (not SATAII) */ | 78 | PDC_PHYMODE4 = 0x14, |
73 | PDC_SLEW_CTL = 0x470, /* slew rate control reg (not SATAII) */ | ||
74 | 79 | ||
75 | /* PDC_GLOBAL_CTL bit definitions */ | 80 | /* PDC_GLOBAL_CTL bit definitions */ |
76 | PDC_PH_ERR = (1 << 8), /* PCI error while loading packet */ | 81 | PDC_PH_ERR = (1 << 8), /* PCI error while loading packet */ |
@@ -134,7 +139,7 @@ struct pdc_port_priv { | |||
134 | 139 | ||
135 | static int pdc_sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val); | 140 | static int pdc_sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val); |
136 | static int pdc_sata_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val); | 141 | static int pdc_sata_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val); |
137 | static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); | 142 | static int pdc_ata_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); |
138 | static int pdc_common_port_start(struct ata_port *ap); | 143 | static int pdc_common_port_start(struct ata_port *ap); |
139 | static int pdc_sata_port_start(struct ata_port *ap); | 144 | static int pdc_sata_port_start(struct ata_port *ap); |
140 | static void pdc_qc_prep(struct ata_queued_cmd *qc); | 145 | static void pdc_qc_prep(struct ata_queued_cmd *qc); |
@@ -332,12 +337,12 @@ static int pdc_sata_port_start(struct ata_port *ap) | |||
332 | 337 | ||
333 | /* fix up PHYMODE4 align timing */ | 338 | /* fix up PHYMODE4 align timing */ |
334 | if (ap->flags & PDC_FLAG_GEN_II) { | 339 | if (ap->flags & PDC_FLAG_GEN_II) { |
335 | void __iomem *mmio = ap->ioaddr.scr_addr; | 340 | void __iomem *sata_mmio = ap->ioaddr.scr_addr; |
336 | unsigned int tmp; | 341 | unsigned int tmp; |
337 | 342 | ||
338 | tmp = readl(mmio + 0x014); | 343 | tmp = readl(sata_mmio + PDC_PHYMODE4); |
339 | tmp = (tmp & ~3) | 1; /* set bits 1:0 = 0:1 */ | 344 | tmp = (tmp & ~3) | 1; /* set bits 1:0 = 0:1 */ |
340 | writel(tmp, mmio + 0x014); | 345 | writel(tmp, sata_mmio + PDC_PHYMODE4); |
341 | } | 346 | } |
342 | 347 | ||
343 | return 0; | 348 | return 0; |
@@ -345,32 +350,32 @@ static int pdc_sata_port_start(struct ata_port *ap) | |||
345 | 350 | ||
346 | static void pdc_reset_port(struct ata_port *ap) | 351 | static void pdc_reset_port(struct ata_port *ap) |
347 | { | 352 | { |
348 | void __iomem *mmio = ap->ioaddr.cmd_addr + PDC_CTLSTAT; | 353 | void __iomem *ata_ctlstat_mmio = ap->ioaddr.cmd_addr + PDC_CTLSTAT; |
349 | unsigned int i; | 354 | unsigned int i; |
350 | u32 tmp; | 355 | u32 tmp; |
351 | 356 | ||
352 | for (i = 11; i > 0; i--) { | 357 | for (i = 11; i > 0; i--) { |
353 | tmp = readl(mmio); | 358 | tmp = readl(ata_ctlstat_mmio); |
354 | if (tmp & PDC_RESET) | 359 | if (tmp & PDC_RESET) |
355 | break; | 360 | break; |
356 | 361 | ||
357 | udelay(100); | 362 | udelay(100); |
358 | 363 | ||
359 | tmp |= PDC_RESET; | 364 | tmp |= PDC_RESET; |
360 | writel(tmp, mmio); | 365 | writel(tmp, ata_ctlstat_mmio); |
361 | } | 366 | } |
362 | 367 | ||
363 | tmp &= ~PDC_RESET; | 368 | tmp &= ~PDC_RESET; |
364 | writel(tmp, mmio); | 369 | writel(tmp, ata_ctlstat_mmio); |
365 | readl(mmio); /* flush */ | 370 | readl(ata_ctlstat_mmio); /* flush */ |
366 | } | 371 | } |
367 | 372 | ||
368 | static int pdc_pata_cable_detect(struct ata_port *ap) | 373 | static int pdc_pata_cable_detect(struct ata_port *ap) |
369 | { | 374 | { |
370 | u8 tmp; | 375 | u8 tmp; |
371 | void __iomem *mmio = ap->ioaddr.cmd_addr + PDC_CTLSTAT + 0x03; | 376 | void __iomem *ata_mmio = ap->ioaddr.cmd_addr; |
372 | 377 | ||
373 | tmp = readb(mmio); | 378 | tmp = readb(ata_mmio + PDC_CTLSTAT + 3); |
374 | if (tmp & 0x01) | 379 | if (tmp & 0x01) |
375 | return ATA_CBL_PATA40; | 380 | return ATA_CBL_PATA40; |
376 | return ATA_CBL_PATA80; | 381 | return ATA_CBL_PATA80; |
@@ -557,31 +562,25 @@ static void pdc_qc_prep(struct ata_queued_cmd *qc) | |||
557 | switch (qc->tf.protocol) { | 562 | switch (qc->tf.protocol) { |
558 | case ATA_PROT_DMA: | 563 | case ATA_PROT_DMA: |
559 | pdc_fill_sg(qc); | 564 | pdc_fill_sg(qc); |
560 | /* fall through */ | 565 | /*FALLTHROUGH*/ |
561 | |||
562 | case ATA_PROT_NODATA: | 566 | case ATA_PROT_NODATA: |
563 | i = pdc_pkt_header(&qc->tf, qc->ap->prd_dma, | 567 | i = pdc_pkt_header(&qc->tf, qc->ap->prd_dma, |
564 | qc->dev->devno, pp->pkt); | 568 | qc->dev->devno, pp->pkt); |
565 | |||
566 | if (qc->tf.flags & ATA_TFLAG_LBA48) | 569 | if (qc->tf.flags & ATA_TFLAG_LBA48) |
567 | i = pdc_prep_lba48(&qc->tf, pp->pkt, i); | 570 | i = pdc_prep_lba48(&qc->tf, pp->pkt, i); |
568 | else | 571 | else |
569 | i = pdc_prep_lba28(&qc->tf, pp->pkt, i); | 572 | i = pdc_prep_lba28(&qc->tf, pp->pkt, i); |
570 | |||
571 | pdc_pkt_footer(&qc->tf, pp->pkt, i); | 573 | pdc_pkt_footer(&qc->tf, pp->pkt, i); |
572 | break; | 574 | break; |
573 | |||
574 | case ATAPI_PROT_PIO: | 575 | case ATAPI_PROT_PIO: |
575 | pdc_fill_sg(qc); | 576 | pdc_fill_sg(qc); |
576 | break; | 577 | break; |
577 | |||
578 | case ATAPI_PROT_DMA: | 578 | case ATAPI_PROT_DMA: |
579 | pdc_fill_sg(qc); | 579 | pdc_fill_sg(qc); |
580 | /*FALLTHROUGH*/ | 580 | /*FALLTHROUGH*/ |
581 | case ATAPI_PROT_NODATA: | 581 | case ATAPI_PROT_NODATA: |
582 | pdc_atapi_pkt(qc); | 582 | pdc_atapi_pkt(qc); |
583 | break; | 583 | break; |
584 | |||
585 | default: | 584 | default: |
586 | break; | 585 | break; |
587 | } | 586 | } |
@@ -611,7 +610,7 @@ static unsigned int pdc_sata_ata_port_to_ata_no(const struct ata_port *ap) | |||
611 | unsigned int nr_ports = pdc_sata_nr_ports(ap); | 610 | unsigned int nr_ports = pdc_sata_nr_ports(ap); |
612 | unsigned int i; | 611 | unsigned int i; |
613 | 612 | ||
614 | for(i = 0; i < nr_ports && host->ports[i] != ap; ++i) | 613 | for (i = 0; i < nr_ports && host->ports[i] != ap; ++i) |
615 | ; | 614 | ; |
616 | BUG_ON(i >= nr_ports); | 615 | BUG_ON(i >= nr_ports); |
617 | return pdc_port_no_to_ata_no(i, pdc_is_sataii_tx4(ap->flags)); | 616 | return pdc_port_no_to_ata_no(i, pdc_is_sataii_tx4(ap->flags)); |
@@ -624,14 +623,14 @@ static unsigned int pdc_sata_hotplug_offset(const struct ata_port *ap) | |||
624 | 623 | ||
625 | static void pdc_freeze(struct ata_port *ap) | 624 | static void pdc_freeze(struct ata_port *ap) |
626 | { | 625 | { |
627 | void __iomem *mmio = ap->ioaddr.cmd_addr; | 626 | void __iomem *ata_mmio = ap->ioaddr.cmd_addr; |
628 | u32 tmp; | 627 | u32 tmp; |
629 | 628 | ||
630 | tmp = readl(mmio + PDC_CTLSTAT); | 629 | tmp = readl(ata_mmio + PDC_CTLSTAT); |
631 | tmp |= PDC_IRQ_DISABLE; | 630 | tmp |= PDC_IRQ_DISABLE; |
632 | tmp &= ~PDC_DMA_ENABLE; | 631 | tmp &= ~PDC_DMA_ENABLE; |
633 | writel(tmp, mmio + PDC_CTLSTAT); | 632 | writel(tmp, ata_mmio + PDC_CTLSTAT); |
634 | readl(mmio + PDC_CTLSTAT); /* flush */ | 633 | readl(ata_mmio + PDC_CTLSTAT); /* flush */ |
635 | } | 634 | } |
636 | 635 | ||
637 | static void pdc_sata_freeze(struct ata_port *ap) | 636 | static void pdc_sata_freeze(struct ata_port *ap) |
@@ -659,17 +658,17 @@ static void pdc_sata_freeze(struct ata_port *ap) | |||
659 | 658 | ||
660 | static void pdc_thaw(struct ata_port *ap) | 659 | static void pdc_thaw(struct ata_port *ap) |
661 | { | 660 | { |
662 | void __iomem *mmio = ap->ioaddr.cmd_addr; | 661 | void __iomem *ata_mmio = ap->ioaddr.cmd_addr; |
663 | u32 tmp; | 662 | u32 tmp; |
664 | 663 | ||
665 | /* clear IRQ */ | 664 | /* clear IRQ */ |
666 | readl(mmio + PDC_INT_SEQMASK); | 665 | readl(ata_mmio + PDC_COMMAND); |
667 | 666 | ||
668 | /* turn IRQ back on */ | 667 | /* turn IRQ back on */ |
669 | tmp = readl(mmio + PDC_CTLSTAT); | 668 | tmp = readl(ata_mmio + PDC_CTLSTAT); |
670 | tmp &= ~PDC_IRQ_DISABLE; | 669 | tmp &= ~PDC_IRQ_DISABLE; |
671 | writel(tmp, mmio + PDC_CTLSTAT); | 670 | writel(tmp, ata_mmio + PDC_CTLSTAT); |
672 | readl(mmio + PDC_CTLSTAT); /* flush */ | 671 | readl(ata_mmio + PDC_CTLSTAT); /* flush */ |
673 | } | 672 | } |
674 | 673 | ||
675 | static void pdc_sata_thaw(struct ata_port *ap) | 674 | static void pdc_sata_thaw(struct ata_port *ap) |
@@ -743,11 +742,11 @@ static void pdc_error_intr(struct ata_port *ap, struct ata_queued_cmd *qc, | |||
743 | ata_port_abort(ap); | 742 | ata_port_abort(ap); |
744 | } | 743 | } |
745 | 744 | ||
746 | static inline unsigned int pdc_host_intr(struct ata_port *ap, | 745 | static unsigned int pdc_host_intr(struct ata_port *ap, |
747 | struct ata_queued_cmd *qc) | 746 | struct ata_queued_cmd *qc) |
748 | { | 747 | { |
749 | unsigned int handled = 0; | 748 | unsigned int handled = 0; |
750 | void __iomem *port_mmio = ap->ioaddr.cmd_addr; | 749 | void __iomem *ata_mmio = ap->ioaddr.cmd_addr; |
751 | u32 port_status, err_mask; | 750 | u32 port_status, err_mask; |
752 | 751 | ||
753 | err_mask = PDC_ERR_MASK; | 752 | err_mask = PDC_ERR_MASK; |
@@ -755,7 +754,7 @@ static inline unsigned int pdc_host_intr(struct ata_port *ap, | |||
755 | err_mask &= ~PDC1_ERR_MASK; | 754 | err_mask &= ~PDC1_ERR_MASK; |
756 | else | 755 | else |
757 | err_mask &= ~PDC2_ERR_MASK; | 756 | err_mask &= ~PDC2_ERR_MASK; |
758 | port_status = readl(port_mmio + PDC_GLOBAL_CTL); | 757 | port_status = readl(ata_mmio + PDC_GLOBAL_CTL); |
759 | if (unlikely(port_status & err_mask)) { | 758 | if (unlikely(port_status & err_mask)) { |
760 | pdc_error_intr(ap, qc, port_status, err_mask); | 759 | pdc_error_intr(ap, qc, port_status, err_mask); |
761 | return 1; | 760 | return 1; |
@@ -770,7 +769,6 @@ static inline unsigned int pdc_host_intr(struct ata_port *ap, | |||
770 | ata_qc_complete(qc); | 769 | ata_qc_complete(qc); |
771 | handled = 1; | 770 | handled = 1; |
772 | break; | 771 | break; |
773 | |||
774 | default: | 772 | default: |
775 | ap->stats.idle_irq++; | 773 | ap->stats.idle_irq++; |
776 | break; | 774 | break; |
@@ -781,10 +779,9 @@ static inline unsigned int pdc_host_intr(struct ata_port *ap, | |||
781 | 779 | ||
782 | static void pdc_irq_clear(struct ata_port *ap) | 780 | static void pdc_irq_clear(struct ata_port *ap) |
783 | { | 781 | { |
784 | struct ata_host *host = ap->host; | 782 | void __iomem *ata_mmio = ap->ioaddr.cmd_addr; |
785 | void __iomem *mmio = host->iomap[PDC_MMIO_BAR]; | ||
786 | 783 | ||
787 | readl(mmio + PDC_INT_SEQMASK); | 784 | readl(ata_mmio + PDC_COMMAND); |
788 | } | 785 | } |
789 | 786 | ||
790 | static irqreturn_t pdc_interrupt(int irq, void *dev_instance) | 787 | static irqreturn_t pdc_interrupt(int irq, void *dev_instance) |
@@ -794,7 +791,7 @@ static irqreturn_t pdc_interrupt(int irq, void *dev_instance) | |||
794 | u32 mask = 0; | 791 | u32 mask = 0; |
795 | unsigned int i, tmp; | 792 | unsigned int i, tmp; |
796 | unsigned int handled = 0; | 793 | unsigned int handled = 0; |
797 | void __iomem *mmio_base; | 794 | void __iomem *host_mmio; |
798 | unsigned int hotplug_offset, ata_no; | 795 | unsigned int hotplug_offset, ata_no; |
799 | u32 hotplug_status; | 796 | u32 hotplug_status; |
800 | int is_sataii_tx4; | 797 | int is_sataii_tx4; |
@@ -806,7 +803,7 @@ static irqreturn_t pdc_interrupt(int irq, void *dev_instance) | |||
806 | return IRQ_NONE; | 803 | return IRQ_NONE; |
807 | } | 804 | } |
808 | 805 | ||
809 | mmio_base = host->iomap[PDC_MMIO_BAR]; | 806 | host_mmio = host->iomap[PDC_MMIO_BAR]; |
810 | 807 | ||
811 | spin_lock(&host->lock); | 808 | spin_lock(&host->lock); |
812 | 809 | ||
@@ -815,26 +812,26 @@ static irqreturn_t pdc_interrupt(int irq, void *dev_instance) | |||
815 | hotplug_offset = PDC2_SATA_PLUG_CSR; | 812 | hotplug_offset = PDC2_SATA_PLUG_CSR; |
816 | else | 813 | else |
817 | hotplug_offset = PDC_SATA_PLUG_CSR; | 814 | hotplug_offset = PDC_SATA_PLUG_CSR; |
818 | hotplug_status = readl(mmio_base + hotplug_offset); | 815 | hotplug_status = readl(host_mmio + hotplug_offset); |
819 | if (hotplug_status & 0xff) | 816 | if (hotplug_status & 0xff) |
820 | writel(hotplug_status | 0xff, mmio_base + hotplug_offset); | 817 | writel(hotplug_status | 0xff, host_mmio + hotplug_offset); |
821 | hotplug_status &= 0xff; /* clear uninteresting bits */ | 818 | hotplug_status &= 0xff; /* clear uninteresting bits */ |
822 | 819 | ||
823 | /* reading should also clear interrupts */ | 820 | /* reading should also clear interrupts */ |
824 | mask = readl(mmio_base + PDC_INT_SEQMASK); | 821 | mask = readl(host_mmio + PDC_INT_SEQMASK); |
825 | 822 | ||
826 | if (mask == 0xffffffff && hotplug_status == 0) { | 823 | if (mask == 0xffffffff && hotplug_status == 0) { |
827 | VPRINTK("QUICK EXIT 2\n"); | 824 | VPRINTK("QUICK EXIT 2\n"); |
828 | goto done_irq; | 825 | goto done_irq; |
829 | } | 826 | } |
830 | 827 | ||
831 | mask &= 0xffff; /* only 16 tags possible */ | 828 | mask &= 0xffff; /* only 16 SEQIDs possible */ |
832 | if (mask == 0 && hotplug_status == 0) { | 829 | if (mask == 0 && hotplug_status == 0) { |
833 | VPRINTK("QUICK EXIT 3\n"); | 830 | VPRINTK("QUICK EXIT 3\n"); |
834 | goto done_irq; | 831 | goto done_irq; |
835 | } | 832 | } |
836 | 833 | ||
837 | writel(mask, mmio_base + PDC_INT_SEQMASK); | 834 | writel(mask, host_mmio + PDC_INT_SEQMASK); |
838 | 835 | ||
839 | is_sataii_tx4 = pdc_is_sataii_tx4(host->ports[0]->flags); | 836 | is_sataii_tx4 = pdc_is_sataii_tx4(host->ports[0]->flags); |
840 | 837 | ||
@@ -875,23 +872,24 @@ done_irq: | |||
875 | return IRQ_RETVAL(handled); | 872 | return IRQ_RETVAL(handled); |
876 | } | 873 | } |
877 | 874 | ||
878 | static inline void pdc_packet_start(struct ata_queued_cmd *qc) | 875 | static void pdc_packet_start(struct ata_queued_cmd *qc) |
879 | { | 876 | { |
880 | struct ata_port *ap = qc->ap; | 877 | struct ata_port *ap = qc->ap; |
881 | struct pdc_port_priv *pp = ap->private_data; | 878 | struct pdc_port_priv *pp = ap->private_data; |
882 | void __iomem *mmio = ap->host->iomap[PDC_MMIO_BAR]; | 879 | void __iomem *host_mmio = ap->host->iomap[PDC_MMIO_BAR]; |
880 | void __iomem *ata_mmio = ap->ioaddr.cmd_addr; | ||
883 | unsigned int port_no = ap->port_no; | 881 | unsigned int port_no = ap->port_no; |
884 | u8 seq = (u8) (port_no + 1); | 882 | u8 seq = (u8) (port_no + 1); |
885 | 883 | ||
886 | VPRINTK("ENTER, ap %p\n", ap); | 884 | VPRINTK("ENTER, ap %p\n", ap); |
887 | 885 | ||
888 | writel(0x00000001, mmio + (seq * 4)); | 886 | writel(0x00000001, host_mmio + (seq * 4)); |
889 | readl(mmio + (seq * 4)); /* flush */ | 887 | readl(host_mmio + (seq * 4)); /* flush */ |
890 | 888 | ||
891 | pp->pkt[2] = seq; | 889 | pp->pkt[2] = seq; |
892 | wmb(); /* flush PRD, pkt writes */ | 890 | wmb(); /* flush PRD, pkt writes */ |
893 | writel(pp->pkt_dma, ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT); | 891 | writel(pp->pkt_dma, ata_mmio + PDC_PKT_SUBMIT); |
894 | readl(ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT); /* flush */ | 892 | readl(ata_mmio + PDC_PKT_SUBMIT); /* flush */ |
895 | } | 893 | } |
896 | 894 | ||
897 | static unsigned int pdc_qc_issue(struct ata_queued_cmd *qc) | 895 | static unsigned int pdc_qc_issue(struct ata_queued_cmd *qc) |
@@ -909,11 +907,9 @@ static unsigned int pdc_qc_issue(struct ata_queued_cmd *qc) | |||
909 | case ATA_PROT_DMA: | 907 | case ATA_PROT_DMA: |
910 | pdc_packet_start(qc); | 908 | pdc_packet_start(qc); |
911 | return 0; | 909 | return 0; |
912 | |||
913 | default: | 910 | default: |
914 | break; | 911 | break; |
915 | } | 912 | } |
916 | |||
917 | return ata_sff_qc_issue(qc); | 913 | return ata_sff_qc_issue(qc); |
918 | } | 914 | } |
919 | 915 | ||
@@ -987,7 +983,7 @@ static void pdc_ata_setup_port(struct ata_port *ap, | |||
987 | 983 | ||
988 | static void pdc_host_init(struct ata_host *host) | 984 | static void pdc_host_init(struct ata_host *host) |
989 | { | 985 | { |
990 | void __iomem *mmio = host->iomap[PDC_MMIO_BAR]; | 986 | void __iomem *host_mmio = host->iomap[PDC_MMIO_BAR]; |
991 | int is_gen2 = host->ports[0]->flags & PDC_FLAG_GEN_II; | 987 | int is_gen2 = host->ports[0]->flags & PDC_FLAG_GEN_II; |
992 | int hotplug_offset; | 988 | int hotplug_offset; |
993 | u32 tmp; | 989 | u32 tmp; |
@@ -1004,38 +1000,38 @@ static void pdc_host_init(struct ata_host *host) | |||
1004 | */ | 1000 | */ |
1005 | 1001 | ||
1006 | /* enable BMR_BURST, maybe change FIFO_SHD to 8 dwords */ | 1002 | /* enable BMR_BURST, maybe change FIFO_SHD to 8 dwords */ |
1007 | tmp = readl(mmio + PDC_FLASH_CTL); | 1003 | tmp = readl(host_mmio + PDC_FLASH_CTL); |
1008 | tmp |= 0x02000; /* bit 13 (enable bmr burst) */ | 1004 | tmp |= 0x02000; /* bit 13 (enable bmr burst) */ |
1009 | if (!is_gen2) | 1005 | if (!is_gen2) |
1010 | tmp |= 0x10000; /* bit 16 (fifo threshold at 8 dw) */ | 1006 | tmp |= 0x10000; /* bit 16 (fifo threshold at 8 dw) */ |
1011 | writel(tmp, mmio + PDC_FLASH_CTL); | 1007 | writel(tmp, host_mmio + PDC_FLASH_CTL); |
1012 | 1008 | ||
1013 | /* clear plug/unplug flags for all ports */ | 1009 | /* clear plug/unplug flags for all ports */ |
1014 | tmp = readl(mmio + hotplug_offset); | 1010 | tmp = readl(host_mmio + hotplug_offset); |
1015 | writel(tmp | 0xff, mmio + hotplug_offset); | 1011 | writel(tmp | 0xff, host_mmio + hotplug_offset); |
1016 | 1012 | ||
1017 | /* unmask plug/unplug ints */ | 1013 | /* unmask plug/unplug ints */ |
1018 | tmp = readl(mmio + hotplug_offset); | 1014 | tmp = readl(host_mmio + hotplug_offset); |
1019 | writel(tmp & ~0xff0000, mmio + hotplug_offset); | 1015 | writel(tmp & ~0xff0000, host_mmio + hotplug_offset); |
1020 | 1016 | ||
1021 | /* don't initialise TBG or SLEW on 2nd generation chips */ | 1017 | /* don't initialise TBG or SLEW on 2nd generation chips */ |
1022 | if (is_gen2) | 1018 | if (is_gen2) |
1023 | return; | 1019 | return; |
1024 | 1020 | ||
1025 | /* reduce TBG clock to 133 Mhz. */ | 1021 | /* reduce TBG clock to 133 Mhz. */ |
1026 | tmp = readl(mmio + PDC_TBG_MODE); | 1022 | tmp = readl(host_mmio + PDC_TBG_MODE); |
1027 | tmp &= ~0x30000; /* clear bit 17, 16*/ | 1023 | tmp &= ~0x30000; /* clear bit 17, 16*/ |
1028 | tmp |= 0x10000; /* set bit 17:16 = 0:1 */ | 1024 | tmp |= 0x10000; /* set bit 17:16 = 0:1 */ |
1029 | writel(tmp, mmio + PDC_TBG_MODE); | 1025 | writel(tmp, host_mmio + PDC_TBG_MODE); |
1030 | 1026 | ||
1031 | readl(mmio + PDC_TBG_MODE); /* flush */ | 1027 | readl(host_mmio + PDC_TBG_MODE); /* flush */ |
1032 | msleep(10); | 1028 | msleep(10); |
1033 | 1029 | ||
1034 | /* adjust slew rate control register. */ | 1030 | /* adjust slew rate control register. */ |
1035 | tmp = readl(mmio + PDC_SLEW_CTL); | 1031 | tmp = readl(host_mmio + PDC_SLEW_CTL); |
1036 | tmp &= 0xFFFFF03F; /* clear bit 11 ~ 6 */ | 1032 | tmp &= 0xFFFFF03F; /* clear bit 11 ~ 6 */ |
1037 | tmp |= 0x00000900; /* set bit 11-9 = 100b , bit 8-6 = 100 */ | 1033 | tmp |= 0x00000900; /* set bit 11-9 = 100b , bit 8-6 = 100 */ |
1038 | writel(tmp, mmio + PDC_SLEW_CTL); | 1034 | writel(tmp, host_mmio + PDC_SLEW_CTL); |
1039 | } | 1035 | } |
1040 | 1036 | ||
1041 | static int pdc_ata_init_one(struct pci_dev *pdev, | 1037 | static int pdc_ata_init_one(struct pci_dev *pdev, |
@@ -1045,7 +1041,7 @@ static int pdc_ata_init_one(struct pci_dev *pdev, | |||
1045 | const struct ata_port_info *pi = &pdc_port_info[ent->driver_data]; | 1041 | const struct ata_port_info *pi = &pdc_port_info[ent->driver_data]; |
1046 | const struct ata_port_info *ppi[PDC_MAX_PORTS]; | 1042 | const struct ata_port_info *ppi[PDC_MAX_PORTS]; |
1047 | struct ata_host *host; | 1043 | struct ata_host *host; |
1048 | void __iomem *base; | 1044 | void __iomem *host_mmio; |
1049 | int n_ports, i, rc; | 1045 | int n_ports, i, rc; |
1050 | int is_sataii_tx4; | 1046 | int is_sataii_tx4; |
1051 | 1047 | ||
@@ -1062,7 +1058,7 @@ static int pdc_ata_init_one(struct pci_dev *pdev, | |||
1062 | pcim_pin_device(pdev); | 1058 | pcim_pin_device(pdev); |
1063 | if (rc) | 1059 | if (rc) |
1064 | return rc; | 1060 | return rc; |
1065 | base = pcim_iomap_table(pdev)[PDC_MMIO_BAR]; | 1061 | host_mmio = pcim_iomap_table(pdev)[PDC_MMIO_BAR]; |
1066 | 1062 | ||
1067 | /* determine port configuration and setup host */ | 1063 | /* determine port configuration and setup host */ |
1068 | n_ports = 2; | 1064 | n_ports = 2; |
@@ -1072,7 +1068,7 @@ static int pdc_ata_init_one(struct pci_dev *pdev, | |||
1072 | ppi[i] = pi; | 1068 | ppi[i] = pi; |
1073 | 1069 | ||
1074 | if (pi->flags & PDC_FLAG_SATA_PATA) { | 1070 | if (pi->flags & PDC_FLAG_SATA_PATA) { |
1075 | u8 tmp = readb(base + PDC_FLASH_CTL+1); | 1071 | u8 tmp = readb(host_mmio + PDC_FLASH_CTL + 1); |
1076 | if (!(tmp & 0x80)) | 1072 | if (!(tmp & 0x80)) |
1077 | ppi[n_ports++] = pi + 1; | 1073 | ppi[n_ports++] = pi + 1; |
1078 | } | 1074 | } |
@@ -1088,13 +1084,13 @@ static int pdc_ata_init_one(struct pci_dev *pdev, | |||
1088 | for (i = 0; i < host->n_ports; i++) { | 1084 | for (i = 0; i < host->n_ports; i++) { |
1089 | struct ata_port *ap = host->ports[i]; | 1085 | struct ata_port *ap = host->ports[i]; |
1090 | unsigned int ata_no = pdc_port_no_to_ata_no(i, is_sataii_tx4); | 1086 | unsigned int ata_no = pdc_port_no_to_ata_no(i, is_sataii_tx4); |
1091 | unsigned int port_offset = 0x200 + ata_no * 0x80; | 1087 | unsigned int ata_offset = 0x200 + ata_no * 0x80; |
1092 | unsigned int scr_offset = 0x400 + ata_no * 0x100; | 1088 | unsigned int scr_offset = 0x400 + ata_no * 0x100; |
1093 | 1089 | ||
1094 | pdc_ata_setup_port(ap, base + port_offset, base + scr_offset); | 1090 | pdc_ata_setup_port(ap, host_mmio + ata_offset, host_mmio + scr_offset); |
1095 | 1091 | ||
1096 | ata_port_pbar_desc(ap, PDC_MMIO_BAR, -1, "mmio"); | 1092 | ata_port_pbar_desc(ap, PDC_MMIO_BAR, -1, "mmio"); |
1097 | ata_port_pbar_desc(ap, PDC_MMIO_BAR, port_offset, "port"); | 1093 | ata_port_pbar_desc(ap, PDC_MMIO_BAR, ata_offset, "ata"); |
1098 | } | 1094 | } |
1099 | 1095 | ||
1100 | /* initialize adapter */ | 1096 | /* initialize adapter */ |
diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c index 27a110110077..8ee6b5b4ede7 100644 --- a/drivers/ata/sata_sil24.c +++ b/drivers/ata/sata_sil24.c | |||
@@ -899,14 +899,25 @@ static bool sil24_qc_fill_rtf(struct ata_queued_cmd *qc) | |||
899 | 899 | ||
900 | static void sil24_pmp_attach(struct ata_port *ap) | 900 | static void sil24_pmp_attach(struct ata_port *ap) |
901 | { | 901 | { |
902 | u32 *gscr = ap->link.device->gscr; | ||
903 | |||
902 | sil24_config_pmp(ap, 1); | 904 | sil24_config_pmp(ap, 1); |
903 | sil24_init_port(ap); | 905 | sil24_init_port(ap); |
906 | |||
907 | if (sata_pmp_gscr_vendor(gscr) == 0x11ab && | ||
908 | sata_pmp_gscr_devid(gscr) == 0x4140) { | ||
909 | ata_port_printk(ap, KERN_INFO, | ||
910 | "disabling NCQ support due to sil24-mv4140 quirk\n"); | ||
911 | ap->flags &= ~ATA_FLAG_NCQ; | ||
912 | } | ||
904 | } | 913 | } |
905 | 914 | ||
906 | static void sil24_pmp_detach(struct ata_port *ap) | 915 | static void sil24_pmp_detach(struct ata_port *ap) |
907 | { | 916 | { |
908 | sil24_init_port(ap); | 917 | sil24_init_port(ap); |
909 | sil24_config_pmp(ap, 0); | 918 | sil24_config_pmp(ap, 0); |
919 | |||
920 | ap->flags |= ATA_FLAG_NCQ; | ||
910 | } | 921 | } |
911 | 922 | ||
912 | static int sil24_pmp_hardreset(struct ata_link *link, unsigned int *class, | 923 | static int sil24_pmp_hardreset(struct ata_link *link, unsigned int *class, |
diff --git a/drivers/atm/eni.h b/drivers/atm/eni.h index d04fefb0841f..e4c9525e60b3 100644 --- a/drivers/atm/eni.h +++ b/drivers/atm/eni.h | |||
@@ -18,7 +18,6 @@ | |||
18 | #include "midway.h" | 18 | #include "midway.h" |
19 | 19 | ||
20 | 20 | ||
21 | #define KERNEL_OFFSET 0xC0000000 /* kernel 0x0 is at phys 0xC0000000 */ | ||
22 | #define DEV_LABEL "eni" | 21 | #define DEV_LABEL "eni" |
23 | 22 | ||
24 | #define UBR_BUFFER (128*1024) /* UBR buffer size */ | 23 | #define UBR_BUFFER (128*1024) /* UBR buffer size */ |
diff --git a/drivers/atm/fore200e.h b/drivers/atm/fore200e.h index 183841cc8fdf..8dd4aa76c3bd 100644 --- a/drivers/atm/fore200e.h +++ b/drivers/atm/fore200e.h | |||
@@ -1,4 +1,3 @@ | |||
1 | /* $Id: fore200e.h,v 1.4 2000/04/14 10:10:34 davem Exp $ */ | ||
2 | #ifndef _FORE200E_H | 1 | #ifndef _FORE200E_H |
3 | #define _FORE200E_H | 2 | #define _FORE200E_H |
4 | 3 | ||
diff --git a/drivers/atm/fore200e_mkfirm.c b/drivers/atm/fore200e_mkfirm.c index 2ebe1a1e6f8b..520e14b488ff 100644 --- a/drivers/atm/fore200e_mkfirm.c +++ b/drivers/atm/fore200e_mkfirm.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | $Id: fore200e_mkfirm.c,v 1.1 2000/02/21 16:04:32 davem Exp $ | ||
3 | |||
4 | mkfirm.c: generates a C readable file from a binary firmware image | 2 | mkfirm.c: generates a C readable file from a binary firmware image |
5 | 3 | ||
6 | Christophe Lizzi (lizzi@{csti.fr, cnam.fr}), June 1999. | 4 | Christophe Lizzi (lizzi@{csti.fr, cnam.fr}), June 1999. |
diff --git a/drivers/atm/he.h b/drivers/atm/he.h index 1dc277547a73..fe6cd15a78a4 100644 --- a/drivers/atm/he.h +++ b/drivers/atm/he.h | |||
@@ -1,5 +1,3 @@ | |||
1 | /* $Id: he.h,v 1.4 2003/05/06 22:48:00 chas Exp $ */ | ||
2 | |||
3 | /* | 1 | /* |
4 | 2 | ||
5 | he.h | 3 | he.h |
diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c index 28d77b5195de..3a504e94a4d9 100644 --- a/drivers/atm/idt77252.c +++ b/drivers/atm/idt77252.c | |||
@@ -1,8 +1,4 @@ | |||
1 | /******************************************************************* | 1 | /******************************************************************* |
2 | * ident "$Id: idt77252.c,v 1.2 2001/11/11 08:13:54 ecd Exp $" | ||
3 | * | ||
4 | * $Author: ecd $ | ||
5 | * $Date: 2001/11/11 08:13:54 $ | ||
6 | * | 2 | * |
7 | * Copyright (c) 2000 ATecoM GmbH | 3 | * Copyright (c) 2000 ATecoM GmbH |
8 | * | 4 | * |
@@ -29,9 +25,6 @@ | |||
29 | * 675 Mass Ave, Cambridge, MA 02139, USA. | 25 | * 675 Mass Ave, Cambridge, MA 02139, USA. |
30 | * | 26 | * |
31 | *******************************************************************/ | 27 | *******************************************************************/ |
32 | static char const rcsid[] = | ||
33 | "$Id: idt77252.c,v 1.2 2001/11/11 08:13:54 ecd Exp $"; | ||
34 | |||
35 | 28 | ||
36 | #include <linux/module.h> | 29 | #include <linux/module.h> |
37 | #include <linux/pci.h> | 30 | #include <linux/pci.h> |
diff --git a/drivers/atm/idt77252.h b/drivers/atm/idt77252.h index 6f2b4a5875fb..e83eaf120da0 100644 --- a/drivers/atm/idt77252.h +++ b/drivers/atm/idt77252.h | |||
@@ -1,8 +1,4 @@ | |||
1 | /******************************************************************* | 1 | /******************************************************************* |
2 | * ident "$Id: idt77252.h,v 1.2 2001/11/11 08:13:54 ecd Exp $" | ||
3 | * | ||
4 | * $Author: ecd $ | ||
5 | * $Date: 2001/11/11 08:13:54 $ | ||
6 | * | 2 | * |
7 | * Copyright (c) 2000 ATecoM GmbH | 3 | * Copyright (c) 2000 ATecoM GmbH |
8 | * | 4 | * |
diff --git a/drivers/atm/iphase.h b/drivers/atm/iphase.h index 133eefcc0475..b2cd20f549cb 100644 --- a/drivers/atm/iphase.h +++ b/drivers/atm/iphase.h | |||
@@ -1025,7 +1025,8 @@ typedef struct iadev_t { | |||
1025 | spinlock_t rx_lock, misc_lock; | 1025 | spinlock_t rx_lock, misc_lock; |
1026 | struct atm_vcc **rx_open; /* list of all open VCs */ | 1026 | struct atm_vcc **rx_open; /* list of all open VCs */ |
1027 | u16 num_rx_desc, rx_buf_sz, rxing; | 1027 | u16 num_rx_desc, rx_buf_sz, rxing; |
1028 | u32 rx_pkt_ram, rx_tmp_cnt, rx_tmp_jif; | 1028 | u32 rx_pkt_ram, rx_tmp_cnt; |
1029 | unsigned long rx_tmp_jif; | ||
1029 | void __iomem *RX_DESC_BASE_ADDR; | 1030 | void __iomem *RX_DESC_BASE_ADDR; |
1030 | u32 drop_rxpkt, drop_rxcell, rx_cell_cnt, rx_pkt_cnt; | 1031 | u32 drop_rxpkt, drop_rxcell, rx_cell_cnt, rx_pkt_cnt; |
1031 | struct atm_dev *next_board; /* other iphase devices */ | 1032 | struct atm_dev *next_board; /* other iphase devices */ |
diff --git a/drivers/atm/nicstarmac.copyright b/drivers/atm/nicstarmac.copyright index 2e15b39fac4f..180531a83c62 100644 --- a/drivers/atm/nicstarmac.copyright +++ b/drivers/atm/nicstarmac.copyright | |||
@@ -13,7 +13,7 @@ | |||
13 | * | 13 | * |
14 | * Modified to work with the IDT7721 nicstar -- AAL5 (tested) only. | 14 | * Modified to work with the IDT7721 nicstar -- AAL5 (tested) only. |
15 | * | 15 | * |
16 | * R. D. Rechenmacher <ron@fnal.gov>, Aug. 6, 1997 $Revision: 1.1 $ $Date: 1999/08/20 11:00:11 $ | 16 | * R. D. Rechenmacher <ron@fnal.gov>, Aug. 6, 1997 |
17 | * | 17 | * |
18 | * Linux driver for the IDT77201 NICStAR PCI ATM controller. | 18 | * Linux driver for the IDT77201 NICStAR PCI ATM controller. |
19 | * PHY component is expected to be 155 Mbps S/UNI-Lite or IDT 77155; | 19 | * PHY component is expected to be 155 Mbps S/UNI-Lite or IDT 77155; |
diff --git a/drivers/base/core.c b/drivers/base/core.c index be288b5e4180..ee0a51a3a41d 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -760,6 +760,22 @@ static void device_remove_class_symlinks(struct device *dev) | |||
760 | } | 760 | } |
761 | 761 | ||
762 | /** | 762 | /** |
763 | * dev_set_name - set a device name | ||
764 | * @dev: device | ||
765 | * @fmt: format string for the device's name | ||
766 | */ | ||
767 | int dev_set_name(struct device *dev, const char *fmt, ...) | ||
768 | { | ||
769 | va_list vargs; | ||
770 | |||
771 | va_start(vargs, fmt); | ||
772 | vsnprintf(dev->bus_id, sizeof(dev->bus_id), fmt, vargs); | ||
773 | va_end(vargs); | ||
774 | return 0; | ||
775 | } | ||
776 | EXPORT_SYMBOL_GPL(dev_set_name); | ||
777 | |||
778 | /** | ||
763 | * device_add - add device to device hierarchy. | 779 | * device_add - add device to device hierarchy. |
764 | * @dev: device. | 780 | * @dev: device. |
765 | * | 781 | * |
@@ -1084,11 +1100,13 @@ static void device_create_release(struct device *dev) | |||
1084 | } | 1100 | } |
1085 | 1101 | ||
1086 | /** | 1102 | /** |
1087 | * device_create - creates a device and registers it with sysfs | 1103 | * device_create_vargs - creates a device and registers it with sysfs |
1088 | * @class: pointer to the struct class that this device should be registered to | 1104 | * @class: pointer to the struct class that this device should be registered to |
1089 | * @parent: pointer to the parent struct device of this new device, if any | 1105 | * @parent: pointer to the parent struct device of this new device, if any |
1090 | * @devt: the dev_t for the char device to be added | 1106 | * @devt: the dev_t for the char device to be added |
1107 | * @drvdata: the data to be added to the device for callbacks | ||
1091 | * @fmt: string for the device's name | 1108 | * @fmt: string for the device's name |
1109 | * @args: va_list for the device's name | ||
1092 | * | 1110 | * |
1093 | * This function can be used by char device classes. A struct device | 1111 | * This function can be used by char device classes. A struct device |
1094 | * will be created in sysfs, registered to the specified class. | 1112 | * will be created in sysfs, registered to the specified class. |
@@ -1104,10 +1122,10 @@ static void device_create_release(struct device *dev) | |||
1104 | * Note: the struct class passed to this function must have previously | 1122 | * Note: the struct class passed to this function must have previously |
1105 | * been created with a call to class_create(). | 1123 | * been created with a call to class_create(). |
1106 | */ | 1124 | */ |
1107 | struct device *device_create(struct class *class, struct device *parent, | 1125 | struct device *device_create_vargs(struct class *class, struct device *parent, |
1108 | dev_t devt, const char *fmt, ...) | 1126 | dev_t devt, void *drvdata, const char *fmt, |
1127 | va_list args) | ||
1109 | { | 1128 | { |
1110 | va_list args; | ||
1111 | struct device *dev = NULL; | 1129 | struct device *dev = NULL; |
1112 | int retval = -ENODEV; | 1130 | int retval = -ENODEV; |
1113 | 1131 | ||
@@ -1124,10 +1142,9 @@ struct device *device_create(struct class *class, struct device *parent, | |||
1124 | dev->class = class; | 1142 | dev->class = class; |
1125 | dev->parent = parent; | 1143 | dev->parent = parent; |
1126 | dev->release = device_create_release; | 1144 | dev->release = device_create_release; |
1145 | dev_set_drvdata(dev, drvdata); | ||
1127 | 1146 | ||
1128 | va_start(args, fmt); | ||
1129 | vsnprintf(dev->bus_id, BUS_ID_SIZE, fmt, args); | 1147 | vsnprintf(dev->bus_id, BUS_ID_SIZE, fmt, args); |
1130 | va_end(args); | ||
1131 | retval = device_register(dev); | 1148 | retval = device_register(dev); |
1132 | if (retval) | 1149 | if (retval) |
1133 | goto error; | 1150 | goto error; |
@@ -1138,6 +1155,78 @@ error: | |||
1138 | kfree(dev); | 1155 | kfree(dev); |
1139 | return ERR_PTR(retval); | 1156 | return ERR_PTR(retval); |
1140 | } | 1157 | } |
1158 | EXPORT_SYMBOL_GPL(device_create_vargs); | ||
1159 | |||
1160 | /** | ||
1161 | * device_create_drvdata - creates a device and registers it with sysfs | ||
1162 | * @class: pointer to the struct class that this device should be registered to | ||
1163 | * @parent: pointer to the parent struct device of this new device, if any | ||
1164 | * @devt: the dev_t for the char device to be added | ||
1165 | * @drvdata: the data to be added to the device for callbacks | ||
1166 | * @fmt: string for the device's name | ||
1167 | * | ||
1168 | * This function can be used by char device classes. A struct device | ||
1169 | * will be created in sysfs, registered to the specified class. | ||
1170 | * | ||
1171 | * A "dev" file will be created, showing the dev_t for the device, if | ||
1172 | * the dev_t is not 0,0. | ||
1173 | * If a pointer to a parent struct device is passed in, the newly created | ||
1174 | * struct device will be a child of that device in sysfs. | ||
1175 | * The pointer to the struct device will be returned from the call. | ||
1176 | * Any further sysfs files that might be required can be created using this | ||
1177 | * pointer. | ||
1178 | * | ||
1179 | * Note: the struct class passed to this function must have previously | ||
1180 | * been created with a call to class_create(). | ||
1181 | */ | ||
1182 | struct device *device_create_drvdata(struct class *class, | ||
1183 | struct device *parent, | ||
1184 | dev_t devt, | ||
1185 | void *drvdata, | ||
1186 | const char *fmt, ...) | ||
1187 | { | ||
1188 | va_list vargs; | ||
1189 | struct device *dev; | ||
1190 | |||
1191 | va_start(vargs, fmt); | ||
1192 | dev = device_create_vargs(class, parent, devt, drvdata, fmt, vargs); | ||
1193 | va_end(vargs); | ||
1194 | return dev; | ||
1195 | } | ||
1196 | EXPORT_SYMBOL_GPL(device_create_drvdata); | ||
1197 | |||
1198 | /** | ||
1199 | * device_create - creates a device and registers it with sysfs | ||
1200 | * @class: pointer to the struct class that this device should be registered to | ||
1201 | * @parent: pointer to the parent struct device of this new device, if any | ||
1202 | * @devt: the dev_t for the char device to be added | ||
1203 | * @fmt: string for the device's name | ||
1204 | * | ||
1205 | * This function can be used by char device classes. A struct device | ||
1206 | * will be created in sysfs, registered to the specified class. | ||
1207 | * | ||
1208 | * A "dev" file will be created, showing the dev_t for the device, if | ||
1209 | * the dev_t is not 0,0. | ||
1210 | * If a pointer to a parent struct device is passed in, the newly created | ||
1211 | * struct device will be a child of that device in sysfs. | ||
1212 | * The pointer to the struct device will be returned from the call. | ||
1213 | * Any further sysfs files that might be required can be created using this | ||
1214 | * pointer. | ||
1215 | * | ||
1216 | * Note: the struct class passed to this function must have previously | ||
1217 | * been created with a call to class_create(). | ||
1218 | */ | ||
1219 | struct device *device_create(struct class *class, struct device *parent, | ||
1220 | dev_t devt, const char *fmt, ...) | ||
1221 | { | ||
1222 | va_list vargs; | ||
1223 | struct device *dev; | ||
1224 | |||
1225 | va_start(vargs, fmt); | ||
1226 | dev = device_create_vargs(class, parent, devt, NULL, fmt, vargs); | ||
1227 | va_end(vargs); | ||
1228 | return dev; | ||
1229 | } | ||
1141 | EXPORT_SYMBOL_GPL(device_create); | 1230 | EXPORT_SYMBOL_GPL(device_create); |
1142 | 1231 | ||
1143 | static int __match_devt(struct device *dev, void *data) | 1232 | static int __match_devt(struct device *dev, void *data) |
@@ -1218,13 +1307,11 @@ int device_rename(struct device *dev, char *new_name) | |||
1218 | } | 1307 | } |
1219 | #else | 1308 | #else |
1220 | if (dev->class) { | 1309 | if (dev->class) { |
1221 | sysfs_remove_link(&dev->class->subsys.kobj, old_device_name); | ||
1222 | error = sysfs_create_link(&dev->class->subsys.kobj, &dev->kobj, | 1310 | error = sysfs_create_link(&dev->class->subsys.kobj, &dev->kobj, |
1223 | dev->bus_id); | 1311 | dev->bus_id); |
1224 | if (error) { | 1312 | if (error) |
1225 | dev_err(dev, "%s: sysfs_create_symlink failed (%d)\n", | 1313 | goto out; |
1226 | __func__, error); | 1314 | sysfs_remove_link(&dev->class->subsys.kobj, old_device_name); |
1227 | } | ||
1228 | } | 1315 | } |
1229 | #endif | 1316 | #endif |
1230 | 1317 | ||
diff --git a/drivers/block/brd.c b/drivers/block/brd.c index a196ef7f147f..24b97b0bef99 100644 --- a/drivers/block/brd.c +++ b/drivers/block/brd.c | |||
@@ -397,6 +397,7 @@ module_param(max_part, int, 0); | |||
397 | MODULE_PARM_DESC(max_part, "Maximum number of partitions per RAM disk"); | 397 | MODULE_PARM_DESC(max_part, "Maximum number of partitions per RAM disk"); |
398 | MODULE_LICENSE("GPL"); | 398 | MODULE_LICENSE("GPL"); |
399 | MODULE_ALIAS_BLOCKDEV_MAJOR(RAMDISK_MAJOR); | 399 | MODULE_ALIAS_BLOCKDEV_MAJOR(RAMDISK_MAJOR); |
400 | MODULE_ALIAS("rd"); | ||
400 | 401 | ||
401 | #ifndef MODULE | 402 | #ifndef MODULE |
402 | /* Legacy boot options - nonmodular */ | 403 | /* Legacy boot options - nonmodular */ |
@@ -447,6 +448,7 @@ static struct brd_device *brd_alloc(int i) | |||
447 | disk->fops = &brd_fops; | 448 | disk->fops = &brd_fops; |
448 | disk->private_data = brd; | 449 | disk->private_data = brd; |
449 | disk->queue = brd->brd_queue; | 450 | disk->queue = brd->brd_queue; |
451 | disk->flags |= GENHD_FL_SUPPRESS_PARTITION_INFO; | ||
450 | sprintf(disk->disk_name, "ram%d", i); | 452 | sprintf(disk->disk_name, "ram%d", i); |
451 | set_capacity(disk, rd_size * 2); | 453 | set_capacity(disk, rd_size * 2); |
452 | 454 | ||
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index e336b05fe4a7..5f1e1cc6165a 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
@@ -53,15 +53,16 @@ | |||
53 | #include <linux/scatterlist.h> | 53 | #include <linux/scatterlist.h> |
54 | 54 | ||
55 | #define CCISS_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin)) | 55 | #define CCISS_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin)) |
56 | #define DRIVER_NAME "HP CISS Driver (v 3.6.14)" | 56 | #define DRIVER_NAME "HP CISS Driver (v 3.6.20)" |
57 | #define DRIVER_VERSION CCISS_DRIVER_VERSION(3,6,14) | 57 | #define DRIVER_VERSION CCISS_DRIVER_VERSION(3, 6, 20) |
58 | 58 | ||
59 | /* Embedded module documentation macros - see modules.h */ | 59 | /* Embedded module documentation macros - see modules.h */ |
60 | MODULE_AUTHOR("Hewlett-Packard Company"); | 60 | MODULE_AUTHOR("Hewlett-Packard Company"); |
61 | MODULE_DESCRIPTION("Driver for HP Controller SA5xxx SA6xxx version 3.6.14"); | 61 | MODULE_DESCRIPTION("Driver for HP Smart Array Controllers"); |
62 | MODULE_SUPPORTED_DEVICE("HP SA5i SA5i+ SA532 SA5300 SA5312 SA641 SA642 SA6400" | 62 | MODULE_SUPPORTED_DEVICE("HP SA5i SA5i+ SA532 SA5300 SA5312 SA641 SA642 SA6400" |
63 | " SA6i P600 P800 P400 P400i E200 E200i E500"); | 63 | " SA6i P600 P800 P400 P400i E200 E200i E500 P700m" |
64 | MODULE_VERSION("3.6.14"); | 64 | " Smart Array G2 Series SAS/SATA Controllers"); |
65 | MODULE_VERSION("3.6.20"); | ||
65 | MODULE_LICENSE("GPL"); | 66 | MODULE_LICENSE("GPL"); |
66 | 67 | ||
67 | #include "cciss_cmd.h" | 68 | #include "cciss_cmd.h" |
@@ -90,6 +91,11 @@ static const struct pci_device_id cciss_pci_device_id[] = { | |||
90 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD, 0x103C, 0x3215}, | 91 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD, 0x103C, 0x3215}, |
91 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC, 0x103C, 0x3237}, | 92 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC, 0x103C, 0x3237}, |
92 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC, 0x103C, 0x323D}, | 93 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC, 0x103C, 0x323D}, |
94 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3241}, | ||
95 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3243}, | ||
96 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3245}, | ||
97 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3247}, | ||
98 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3249}, | ||
93 | {PCI_VENDOR_ID_HP, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, | 99 | {PCI_VENDOR_ID_HP, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, |
94 | PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0}, | 100 | PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0}, |
95 | {0,} | 101 | {0,} |
@@ -123,6 +129,11 @@ static struct board_type products[] = { | |||
123 | {0x3215103C, "Smart Array E200i", &SA5_access, 120}, | 129 | {0x3215103C, "Smart Array E200i", &SA5_access, 120}, |
124 | {0x3237103C, "Smart Array E500", &SA5_access, 512}, | 130 | {0x3237103C, "Smart Array E500", &SA5_access, 512}, |
125 | {0x323D103C, "Smart Array P700m", &SA5_access, 512}, | 131 | {0x323D103C, "Smart Array P700m", &SA5_access, 512}, |
132 | {0x3241103C, "Smart Array P212", &SA5_access, 384}, | ||
133 | {0x3243103C, "Smart Array P410", &SA5_access, 384}, | ||
134 | {0x3245103C, "Smart Array P410i", &SA5_access, 384}, | ||
135 | {0x3247103C, "Smart Array P411", &SA5_access, 384}, | ||
136 | {0x3249103C, "Smart Array P812", &SA5_access, 384}, | ||
126 | {0xFFFF103C, "Unknown Smart Array", &SA5_access, 120}, | 137 | {0xFFFF103C, "Unknown Smart Array", &SA5_access, 120}, |
127 | }; | 138 | }; |
128 | 139 | ||
diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c index ebfe038d859e..f1c8feb5510b 100644 --- a/drivers/block/viodasd.c +++ b/drivers/block/viodasd.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * Authors: Dave Boutcher <boutcher@us.ibm.com> | 3 | * Authors: Dave Boutcher <boutcher@us.ibm.com> |
4 | * Ryan Arnold <ryanarn@us.ibm.com> | 4 | * Ryan Arnold <ryanarn@us.ibm.com> |
5 | * Colin Devilbiss <devilbis@us.ibm.com> | 5 | * Colin Devilbiss <devilbis@us.ibm.com> |
6 | * Stephen Rothwell <sfr@au1.ibm.com> | 6 | * Stephen Rothwell |
7 | * | 7 | * |
8 | * (C) Copyright 2000-2004 IBM Corporation | 8 | * (C) Copyright 2000-2004 IBM Corporation |
9 | * | 9 | * |
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 84e064ffee52..dd7ea203f940 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c | |||
@@ -260,6 +260,10 @@ static int virtblk_probe(struct virtio_device *vdev) | |||
260 | if (virtio_has_feature(vdev, VIRTIO_BLK_F_BARRIER)) | 260 | if (virtio_has_feature(vdev, VIRTIO_BLK_F_BARRIER)) |
261 | blk_queue_ordered(vblk->disk->queue, QUEUE_ORDERED_TAG, NULL); | 261 | blk_queue_ordered(vblk->disk->queue, QUEUE_ORDERED_TAG, NULL); |
262 | 262 | ||
263 | /* If disk is read-only in the host, the guest should obey */ | ||
264 | if (virtio_has_feature(vdev, VIRTIO_BLK_F_RO)) | ||
265 | set_disk_ro(vblk->disk, 1); | ||
266 | |||
263 | /* Host must always specify the capacity. */ | 267 | /* Host must always specify the capacity. */ |
264 | vdev->config->get(vdev, offsetof(struct virtio_blk_config, capacity), | 268 | vdev->config->get(vdev, offsetof(struct virtio_blk_config, capacity), |
265 | &cap, sizeof(cap)); | 269 | &cap, sizeof(cap)); |
@@ -311,6 +315,7 @@ static void virtblk_remove(struct virtio_device *vdev) | |||
311 | /* Stop all the virtqueues. */ | 315 | /* Stop all the virtqueues. */ |
312 | vdev->config->reset(vdev); | 316 | vdev->config->reset(vdev); |
313 | 317 | ||
318 | del_gendisk(vblk->disk); | ||
314 | blk_cleanup_queue(vblk->disk->queue); | 319 | blk_cleanup_queue(vblk->disk->queue); |
315 | put_disk(vblk->disk); | 320 | put_disk(vblk->disk); |
316 | mempool_destroy(vblk->pool); | 321 | mempool_destroy(vblk->pool); |
@@ -325,7 +330,7 @@ static struct virtio_device_id id_table[] = { | |||
325 | 330 | ||
326 | static unsigned int features[] = { | 331 | static unsigned int features[] = { |
327 | VIRTIO_BLK_F_BARRIER, VIRTIO_BLK_F_SEG_MAX, VIRTIO_BLK_F_SIZE_MAX, | 332 | VIRTIO_BLK_F_BARRIER, VIRTIO_BLK_F_SEG_MAX, VIRTIO_BLK_F_SIZE_MAX, |
328 | VIRTIO_BLK_F_GEOMETRY, | 333 | VIRTIO_BLK_F_GEOMETRY, VIRTIO_BLK_F_RO, |
329 | }; | 334 | }; |
330 | 335 | ||
331 | static struct virtio_driver virtio_blk = { | 336 | static struct virtio_driver virtio_blk = { |
diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c index 5245a4a0ba74..9d0dfe6e0d63 100644 --- a/drivers/cdrom/viocd.c +++ b/drivers/cdrom/viocd.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * Authors: Dave Boutcher <boutcher@us.ibm.com> | 6 | * Authors: Dave Boutcher <boutcher@us.ibm.com> |
7 | * Ryan Arnold <ryanarn@us.ibm.com> | 7 | * Ryan Arnold <ryanarn@us.ibm.com> |
8 | * Colin Devilbiss <devilbis@us.ibm.com> | 8 | * Colin Devilbiss <devilbis@us.ibm.com> |
9 | * Stephen Rothwell <sfr@au1.ibm.com> | 9 | * Stephen Rothwell |
10 | * | 10 | * |
11 | * (C) Copyright 2000-2004 IBM Corporation | 11 | * (C) Copyright 2000-2004 IBM Corporation |
12 | * | 12 | * |
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 595a925c62a9..2d854bb9373e 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -118,8 +118,8 @@ config COMPUTONE | |||
118 | order to become a dial-in server. If you have a card like that, say | 118 | order to become a dial-in server. If you have a card like that, say |
119 | Y here and read <file:Documentation/computone.txt>. | 119 | Y here and read <file:Documentation/computone.txt>. |
120 | 120 | ||
121 | To compile this driver as modules, choose M here: the | 121 | To compile this driver as module, choose M here: the |
122 | modules will be called ip2 and ip2main. | 122 | module will be called ip2. |
123 | 123 | ||
124 | config ROCKETPORT | 124 | config ROCKETPORT |
125 | tristate "Comtrol RocketPort support" | 125 | tristate "Comtrol RocketPort support" |
@@ -749,7 +749,7 @@ config NVRAM | |||
749 | if RTC_LIB=n | 749 | if RTC_LIB=n |
750 | 750 | ||
751 | config RTC | 751 | config RTC |
752 | tristate "Enhanced Real Time Clock Support" | 752 | tristate "Enhanced Real Time Clock Support (legacy PC RTC driver)" |
753 | depends on !PPC && !PARISC && !IA64 && !M68K && !SPARC && !FRV \ | 753 | depends on !PPC && !PARISC && !IA64 && !M68K && !SPARC && !FRV \ |
754 | && !ARM && !SUPERH && !S390 && !AVR32 | 754 | && !ARM && !SUPERH && !S390 && !AVR32 |
755 | ---help--- | 755 | ---help--- |
@@ -1036,9 +1036,9 @@ config HPET | |||
1036 | non-periodic and/or periodic. | 1036 | non-periodic and/or periodic. |
1037 | 1037 | ||
1038 | config HPET_RTC_IRQ | 1038 | config HPET_RTC_IRQ |
1039 | bool "HPET Control RTC IRQ" if !HPET_EMULATE_RTC | 1039 | bool |
1040 | default n | 1040 | default HPET_EMULATE_RTC |
1041 | depends on HPET | 1041 | depends on RTC && HPET |
1042 | help | 1042 | help |
1043 | If you say Y here, you will disable RTC_IRQ in drivers/char/rtc.c. It | 1043 | If you say Y here, you will disable RTC_IRQ in drivers/char/rtc.c. It |
1044 | is assumed the platform called hpet_alloc with the RTC IRQ values for | 1044 | is assumed the platform called hpet_alloc with the RTC IRQ values for |
diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c index 55c97f623242..07b4d8ff56e5 100644 --- a/drivers/char/agp/ati-agp.c +++ b/drivers/char/agp/ati-agp.c | |||
@@ -458,6 +458,10 @@ static struct agp_device_ids ati_agp_device_ids[] __devinitdata = | |||
458 | .chipset_name = "IGP9100/M", | 458 | .chipset_name = "IGP9100/M", |
459 | }, | 459 | }, |
460 | { | 460 | { |
461 | .device_id = PCI_DEVICE_ID_ATI_RS350_133, | ||
462 | .chipset_name = "IGP9000/M", | ||
463 | }, | ||
464 | { | ||
461 | .device_id = PCI_DEVICE_ID_ATI_RS350_200, | 465 | .device_id = PCI_DEVICE_ID_ATI_RS350_200, |
462 | .chipset_name = "IGP9100/M", | 466 | .chipset_name = "IGP9100/M", |
463 | }, | 467 | }, |
diff --git a/drivers/char/drm/drm.h b/drivers/char/drm/drm.h index 6874f31ca8ca..3a05c6d5ebe1 100644 --- a/drivers/char/drm/drm.h +++ b/drivers/char/drm/drm.h | |||
@@ -471,7 +471,6 @@ struct drm_irq_busid { | |||
471 | enum drm_vblank_seq_type { | 471 | enum drm_vblank_seq_type { |
472 | _DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */ | 472 | _DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */ |
473 | _DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */ | 473 | _DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */ |
474 | _DRM_VBLANK_FLIP = 0x8000000, /**< Scheduled buffer swap should flip */ | ||
475 | _DRM_VBLANK_NEXTONMISS = 0x10000000, /**< If missed, wait for next vblank */ | 474 | _DRM_VBLANK_NEXTONMISS = 0x10000000, /**< If missed, wait for next vblank */ |
476 | _DRM_VBLANK_SECONDARY = 0x20000000, /**< Secondary display controller */ | 475 | _DRM_VBLANK_SECONDARY = 0x20000000, /**< Secondary display controller */ |
477 | _DRM_VBLANK_SIGNAL = 0x40000000 /**< Send signal instead of blocking */ | 476 | _DRM_VBLANK_SIGNAL = 0x40000000 /**< Send signal instead of blocking */ |
@@ -504,21 +503,6 @@ union drm_wait_vblank { | |||
504 | struct drm_wait_vblank_reply reply; | 503 | struct drm_wait_vblank_reply reply; |
505 | }; | 504 | }; |
506 | 505 | ||
507 | enum drm_modeset_ctl_cmd { | ||
508 | _DRM_PRE_MODESET = 1, | ||
509 | _DRM_POST_MODESET = 2, | ||
510 | }; | ||
511 | |||
512 | /** | ||
513 | * DRM_IOCTL_MODESET_CTL ioctl argument type | ||
514 | * | ||
515 | * \sa drmModesetCtl(). | ||
516 | */ | ||
517 | struct drm_modeset_ctl { | ||
518 | unsigned long arg; | ||
519 | enum drm_modeset_ctl_cmd cmd; | ||
520 | }; | ||
521 | |||
522 | /** | 506 | /** |
523 | * DRM_IOCTL_AGP_ENABLE ioctl argument type. | 507 | * DRM_IOCTL_AGP_ENABLE ioctl argument type. |
524 | * | 508 | * |
@@ -603,7 +587,6 @@ struct drm_set_version { | |||
603 | #define DRM_IOCTL_GET_CLIENT DRM_IOWR(0x05, struct drm_client) | 587 | #define DRM_IOCTL_GET_CLIENT DRM_IOWR(0x05, struct drm_client) |
604 | #define DRM_IOCTL_GET_STATS DRM_IOR( 0x06, struct drm_stats) | 588 | #define DRM_IOCTL_GET_STATS DRM_IOR( 0x06, struct drm_stats) |
605 | #define DRM_IOCTL_SET_VERSION DRM_IOWR(0x07, struct drm_set_version) | 589 | #define DRM_IOCTL_SET_VERSION DRM_IOWR(0x07, struct drm_set_version) |
606 | #define DRM_IOCTL_MODESET_CTL DRM_IOW(0x08, struct drm_modeset_ctl) | ||
607 | 590 | ||
608 | #define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, struct drm_unique) | 591 | #define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, struct drm_unique) |
609 | #define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, struct drm_auth) | 592 | #define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, struct drm_auth) |
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h index 213b3ca3468e..0764b662b339 100644 --- a/drivers/char/drm/drmP.h +++ b/drivers/char/drm/drmP.h | |||
@@ -100,8 +100,10 @@ struct drm_device; | |||
100 | #define DRIVER_HAVE_DMA 0x20 | 100 | #define DRIVER_HAVE_DMA 0x20 |
101 | #define DRIVER_HAVE_IRQ 0x40 | 101 | #define DRIVER_HAVE_IRQ 0x40 |
102 | #define DRIVER_IRQ_SHARED 0x80 | 102 | #define DRIVER_IRQ_SHARED 0x80 |
103 | #define DRIVER_IRQ_VBL 0x100 | ||
103 | #define DRIVER_DMA_QUEUE 0x200 | 104 | #define DRIVER_DMA_QUEUE 0x200 |
104 | #define DRIVER_FB_DMA 0x400 | 105 | #define DRIVER_FB_DMA 0x400 |
106 | #define DRIVER_IRQ_VBL2 0x800 | ||
105 | 107 | ||
106 | /***********************************************************************/ | 108 | /***********************************************************************/ |
107 | /** \name Begin the DRM... */ | 109 | /** \name Begin the DRM... */ |
@@ -577,52 +579,10 @@ struct drm_driver { | |||
577 | int (*context_dtor) (struct drm_device *dev, int context); | 579 | int (*context_dtor) (struct drm_device *dev, int context); |
578 | int (*kernel_context_switch) (struct drm_device *dev, int old, | 580 | int (*kernel_context_switch) (struct drm_device *dev, int old, |
579 | int new); | 581 | int new); |
580 | void (*kernel_context_switch_unlock) (struct drm_device * dev); | 582 | void (*kernel_context_switch_unlock) (struct drm_device *dev); |
581 | /** | 583 | int (*vblank_wait) (struct drm_device *dev, unsigned int *sequence); |
582 | * get_vblank_counter - get raw hardware vblank counter | 584 | int (*vblank_wait2) (struct drm_device *dev, unsigned int *sequence); |
583 | * @dev: DRM device | 585 | int (*dri_library_name) (struct drm_device *dev, char *buf); |
584 | * @crtc: counter to fetch | ||
585 | * | ||
586 | * Driver callback for fetching a raw hardware vblank counter | ||
587 | * for @crtc. If a device doesn't have a hardware counter, the | ||
588 | * driver can simply return the value of drm_vblank_count and | ||
589 | * make the enable_vblank() and disable_vblank() hooks into no-ops, | ||
590 | * leaving interrupts enabled at all times. | ||
591 | * | ||
592 | * Wraparound handling and loss of events due to modesetting is dealt | ||
593 | * with in the DRM core code. | ||
594 | * | ||
595 | * RETURNS | ||
596 | * Raw vblank counter value. | ||
597 | */ | ||
598 | u32 (*get_vblank_counter) (struct drm_device *dev, int crtc); | ||
599 | |||
600 | /** | ||
601 | * enable_vblank - enable vblank interrupt events | ||
602 | * @dev: DRM device | ||
603 | * @crtc: which irq to enable | ||
604 | * | ||
605 | * Enable vblank interrupts for @crtc. If the device doesn't have | ||
606 | * a hardware vblank counter, this routine should be a no-op, since | ||
607 | * interrupts will have to stay on to keep the count accurate. | ||
608 | * | ||
609 | * RETURNS | ||
610 | * Zero on success, appropriate errno if the given @crtc's vblank | ||
611 | * interrupt cannot be enabled. | ||
612 | */ | ||
613 | int (*enable_vblank) (struct drm_device *dev, int crtc); | ||
614 | |||
615 | /** | ||
616 | * disable_vblank - disable vblank interrupt events | ||
617 | * @dev: DRM device | ||
618 | * @crtc: which irq to enable | ||
619 | * | ||
620 | * Disable vblank interrupts for @crtc. If the device doesn't have | ||
621 | * a hardware vblank counter, this routine should be a no-op, since | ||
622 | * interrupts will have to stay on to keep the count accurate. | ||
623 | */ | ||
624 | void (*disable_vblank) (struct drm_device *dev, int crtc); | ||
625 | int (*dri_library_name) (struct drm_device *dev, char * buf); | ||
626 | 586 | ||
627 | /** | 587 | /** |
628 | * Called by \c drm_device_is_agp. Typically used to determine if a | 588 | * Called by \c drm_device_is_agp. Typically used to determine if a |
@@ -641,7 +601,7 @@ struct drm_driver { | |||
641 | 601 | ||
642 | irqreturn_t(*irq_handler) (DRM_IRQ_ARGS); | 602 | irqreturn_t(*irq_handler) (DRM_IRQ_ARGS); |
643 | void (*irq_preinstall) (struct drm_device *dev); | 603 | void (*irq_preinstall) (struct drm_device *dev); |
644 | int (*irq_postinstall) (struct drm_device *dev); | 604 | void (*irq_postinstall) (struct drm_device *dev); |
645 | void (*irq_uninstall) (struct drm_device *dev); | 605 | void (*irq_uninstall) (struct drm_device *dev); |
646 | void (*reclaim_buffers) (struct drm_device *dev, | 606 | void (*reclaim_buffers) (struct drm_device *dev, |
647 | struct drm_file * file_priv); | 607 | struct drm_file * file_priv); |
@@ -770,21 +730,13 @@ struct drm_device { | |||
770 | /** \name VBLANK IRQ support */ | 730 | /** \name VBLANK IRQ support */ |
771 | /*@{ */ | 731 | /*@{ */ |
772 | 732 | ||
773 | wait_queue_head_t *vbl_queue; /**< VBLANK wait queue */ | 733 | wait_queue_head_t vbl_queue; /**< VBLANK wait queue */ |
774 | atomic_t *_vblank_count; /**< number of VBLANK interrupts (driver must alloc the right number of counters) */ | 734 | atomic_t vbl_received; |
735 | atomic_t vbl_received2; /**< number of secondary VBLANK interrupts */ | ||
775 | spinlock_t vbl_lock; | 736 | spinlock_t vbl_lock; |
776 | struct list_head *vbl_sigs; /**< signal list to send on VBLANK */ | 737 | struct list_head vbl_sigs; /**< signal list to send on VBLANK */ |
777 | atomic_t vbl_signal_pending; /* number of signals pending on all crtcs*/ | 738 | struct list_head vbl_sigs2; /**< signals to send on secondary VBLANK */ |
778 | atomic_t *vblank_refcount; /* number of users of vblank interrupts per crtc */ | 739 | unsigned int vbl_pending; |
779 | u32 *last_vblank; /* protected by dev->vbl_lock, used */ | ||
780 | /* for wraparound handling */ | ||
781 | u32 *vblank_offset; /* used to track how many vblanks */ | ||
782 | int *vblank_enabled; /* so we don't call enable more than | ||
783 | once per disable */ | ||
784 | u32 *vblank_premodeset; /* were lost during modeset */ | ||
785 | struct timer_list vblank_disable_timer; | ||
786 | |||
787 | unsigned long max_vblank_count; /**< size of vblank counter register */ | ||
788 | spinlock_t tasklet_lock; /**< For drm_locked_tasklet */ | 740 | spinlock_t tasklet_lock; /**< For drm_locked_tasklet */ |
789 | void (*locked_tasklet_func)(struct drm_device *dev); | 741 | void (*locked_tasklet_func)(struct drm_device *dev); |
790 | 742 | ||
@@ -804,7 +756,6 @@ struct drm_device { | |||
804 | #ifdef __alpha__ | 756 | #ifdef __alpha__ |
805 | struct pci_controller *hose; | 757 | struct pci_controller *hose; |
806 | #endif | 758 | #endif |
807 | int num_crtcs; /**< Number of CRTCs on this device */ | ||
808 | struct drm_sg_mem *sg; /**< Scatter gather memory */ | 759 | struct drm_sg_mem *sg; /**< Scatter gather memory */ |
809 | void *dev_private; /**< device private data */ | 760 | void *dev_private; /**< device private data */ |
810 | struct drm_sigdata sigdata; /**< For block_all_signals */ | 761 | struct drm_sigdata sigdata; /**< For block_all_signals */ |
@@ -1039,19 +990,11 @@ extern void drm_driver_irq_preinstall(struct drm_device *dev); | |||
1039 | extern void drm_driver_irq_postinstall(struct drm_device *dev); | 990 | extern void drm_driver_irq_postinstall(struct drm_device *dev); |
1040 | extern void drm_driver_irq_uninstall(struct drm_device *dev); | 991 | extern void drm_driver_irq_uninstall(struct drm_device *dev); |
1041 | 992 | ||
1042 | extern int drm_vblank_init(struct drm_device *dev, int num_crtcs); | 993 | extern int drm_wait_vblank(struct drm_device *dev, void *data, |
1043 | extern int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *filp); | ||
1044 | extern int drm_vblank_wait(struct drm_device * dev, unsigned int *vbl_seq); | ||
1045 | extern void drm_locked_tasklet(struct drm_device *dev, void(*func)(struct drm_device*)); | ||
1046 | extern u32 drm_vblank_count(struct drm_device *dev, int crtc); | ||
1047 | extern void drm_update_vblank_count(struct drm_device *dev, int crtc); | ||
1048 | extern void drm_handle_vblank(struct drm_device *dev, int crtc); | ||
1049 | extern int drm_vblank_get(struct drm_device *dev, int crtc); | ||
1050 | extern void drm_vblank_put(struct drm_device *dev, int crtc); | ||
1051 | |||
1052 | /* Modesetting support */ | ||
1053 | extern int drm_modeset_ctl(struct drm_device *dev, void *data, | ||
1054 | struct drm_file *file_priv); | 994 | struct drm_file *file_priv); |
995 | extern int drm_vblank_wait(struct drm_device *dev, unsigned int *vbl_seq); | ||
996 | extern void drm_vbl_send_signals(struct drm_device *dev); | ||
997 | extern void drm_locked_tasklet(struct drm_device *dev, void(*func)(struct drm_device*)); | ||
1055 | 998 | ||
1056 | /* AGP/GART support (drm_agpsupport.h) */ | 999 | /* AGP/GART support (drm_agpsupport.h) */ |
1057 | extern struct drm_agp_head *drm_agp_init(struct drm_device *dev); | 1000 | extern struct drm_agp_head *drm_agp_init(struct drm_device *dev); |
diff --git a/drivers/char/drm/drm_fops.c b/drivers/char/drm/drm_fops.c index 68f0da801ed8..d2e6da85f58a 100644 --- a/drivers/char/drm/drm_fops.c +++ b/drivers/char/drm/drm_fops.c | |||
@@ -323,7 +323,6 @@ int drm_release(struct inode *inode, struct file *filp) | |||
323 | struct drm_file *file_priv = filp->private_data; | 323 | struct drm_file *file_priv = filp->private_data; |
324 | struct drm_device *dev = file_priv->minor->dev; | 324 | struct drm_device *dev = file_priv->minor->dev; |
325 | int retcode = 0; | 325 | int retcode = 0; |
326 | unsigned long irqflags; | ||
327 | 326 | ||
328 | lock_kernel(); | 327 | lock_kernel(); |
329 | 328 | ||
@@ -355,11 +354,9 @@ int drm_release(struct inode *inode, struct file *filp) | |||
355 | */ | 354 | */ |
356 | 355 | ||
357 | do{ | 356 | do{ |
358 | spin_lock_irqsave(&dev->lock.spinlock, | 357 | spin_lock_bh(&dev->lock.spinlock); |
359 | irqflags); | ||
360 | locked = dev->lock.idle_has_lock; | 358 | locked = dev->lock.idle_has_lock; |
361 | spin_unlock_irqrestore(&dev->lock.spinlock, | 359 | spin_unlock_bh(&dev->lock.spinlock); |
362 | irqflags); | ||
363 | if (locked) | 360 | if (locked) |
364 | break; | 361 | break; |
365 | schedule(); | 362 | schedule(); |
diff --git a/drivers/char/drm/drm_irq.c b/drivers/char/drm/drm_irq.c index 286f9d61e7d5..089c015c01d1 100644 --- a/drivers/char/drm/drm_irq.c +++ b/drivers/char/drm/drm_irq.c | |||
@@ -71,117 +71,6 @@ int drm_irq_by_busid(struct drm_device *dev, void *data, | |||
71 | return 0; | 71 | return 0; |
72 | } | 72 | } |
73 | 73 | ||
74 | static void vblank_disable_fn(unsigned long arg) | ||
75 | { | ||
76 | struct drm_device *dev = (struct drm_device *)arg; | ||
77 | unsigned long irqflags; | ||
78 | int i; | ||
79 | |||
80 | for (i = 0; i < dev->num_crtcs; i++) { | ||
81 | spin_lock_irqsave(&dev->vbl_lock, irqflags); | ||
82 | if (atomic_read(&dev->vblank_refcount[i]) == 0 && | ||
83 | dev->vblank_enabled[i]) { | ||
84 | dev->driver->disable_vblank(dev, i); | ||
85 | dev->vblank_enabled[i] = 0; | ||
86 | } | ||
87 | spin_unlock_irqrestore(&dev->vbl_lock, irqflags); | ||
88 | } | ||
89 | } | ||
90 | |||
91 | static void drm_vblank_cleanup(struct drm_device *dev) | ||
92 | { | ||
93 | /* Bail if the driver didn't call drm_vblank_init() */ | ||
94 | if (dev->num_crtcs == 0) | ||
95 | return; | ||
96 | |||
97 | del_timer(&dev->vblank_disable_timer); | ||
98 | |||
99 | vblank_disable_fn((unsigned long)dev); | ||
100 | |||
101 | drm_free(dev->vbl_queue, sizeof(*dev->vbl_queue) * dev->num_crtcs, | ||
102 | DRM_MEM_DRIVER); | ||
103 | drm_free(dev->vbl_sigs, sizeof(*dev->vbl_sigs) * dev->num_crtcs, | ||
104 | DRM_MEM_DRIVER); | ||
105 | drm_free(dev->_vblank_count, sizeof(*dev->_vblank_count) * | ||
106 | dev->num_crtcs, DRM_MEM_DRIVER); | ||
107 | drm_free(dev->vblank_refcount, sizeof(*dev->vblank_refcount) * | ||
108 | dev->num_crtcs, DRM_MEM_DRIVER); | ||
109 | drm_free(dev->vblank_enabled, sizeof(*dev->vblank_enabled) * | ||
110 | dev->num_crtcs, DRM_MEM_DRIVER); | ||
111 | drm_free(dev->last_vblank, sizeof(*dev->last_vblank) * dev->num_crtcs, | ||
112 | DRM_MEM_DRIVER); | ||
113 | drm_free(dev->vblank_premodeset, sizeof(*dev->vblank_premodeset) * | ||
114 | dev->num_crtcs, DRM_MEM_DRIVER); | ||
115 | drm_free(dev->vblank_offset, sizeof(*dev->vblank_offset) * dev->num_crtcs, | ||
116 | DRM_MEM_DRIVER); | ||
117 | |||
118 | dev->num_crtcs = 0; | ||
119 | } | ||
120 | |||
121 | int drm_vblank_init(struct drm_device *dev, int num_crtcs) | ||
122 | { | ||
123 | int i, ret = -ENOMEM; | ||
124 | |||
125 | setup_timer(&dev->vblank_disable_timer, vblank_disable_fn, | ||
126 | (unsigned long)dev); | ||
127 | spin_lock_init(&dev->vbl_lock); | ||
128 | atomic_set(&dev->vbl_signal_pending, 0); | ||
129 | dev->num_crtcs = num_crtcs; | ||
130 | |||
131 | dev->vbl_queue = drm_alloc(sizeof(wait_queue_head_t) * num_crtcs, | ||
132 | DRM_MEM_DRIVER); | ||
133 | if (!dev->vbl_queue) | ||
134 | goto err; | ||
135 | |||
136 | dev->vbl_sigs = drm_alloc(sizeof(struct list_head) * num_crtcs, | ||
137 | DRM_MEM_DRIVER); | ||
138 | if (!dev->vbl_sigs) | ||
139 | goto err; | ||
140 | |||
141 | dev->_vblank_count = drm_alloc(sizeof(atomic_t) * num_crtcs, | ||
142 | DRM_MEM_DRIVER); | ||
143 | if (!dev->_vblank_count) | ||
144 | goto err; | ||
145 | |||
146 | dev->vblank_refcount = drm_alloc(sizeof(atomic_t) * num_crtcs, | ||
147 | DRM_MEM_DRIVER); | ||
148 | if (!dev->vblank_refcount) | ||
149 | goto err; | ||
150 | |||
151 | dev->vblank_enabled = drm_calloc(num_crtcs, sizeof(int), | ||
152 | DRM_MEM_DRIVER); | ||
153 | if (!dev->vblank_enabled) | ||
154 | goto err; | ||
155 | |||
156 | dev->last_vblank = drm_calloc(num_crtcs, sizeof(u32), DRM_MEM_DRIVER); | ||
157 | if (!dev->last_vblank) | ||
158 | goto err; | ||
159 | |||
160 | dev->vblank_premodeset = drm_calloc(num_crtcs, sizeof(u32), | ||
161 | DRM_MEM_DRIVER); | ||
162 | if (!dev->vblank_premodeset) | ||
163 | goto err; | ||
164 | |||
165 | dev->vblank_offset = drm_calloc(num_crtcs, sizeof(u32), DRM_MEM_DRIVER); | ||
166 | if (!dev->vblank_offset) | ||
167 | goto err; | ||
168 | |||
169 | /* Zero per-crtc vblank stuff */ | ||
170 | for (i = 0; i < num_crtcs; i++) { | ||
171 | init_waitqueue_head(&dev->vbl_queue[i]); | ||
172 | INIT_LIST_HEAD(&dev->vbl_sigs[i]); | ||
173 | atomic_set(&dev->_vblank_count[i], 0); | ||
174 | atomic_set(&dev->vblank_refcount[i], 0); | ||
175 | } | ||
176 | |||
177 | return 0; | ||
178 | |||
179 | err: | ||
180 | drm_vblank_cleanup(dev); | ||
181 | return ret; | ||
182 | } | ||
183 | EXPORT_SYMBOL(drm_vblank_init); | ||
184 | |||
185 | /** | 74 | /** |
186 | * Install IRQ handler. | 75 | * Install IRQ handler. |
187 | * | 76 | * |
@@ -220,6 +109,17 @@ static int drm_irq_install(struct drm_device * dev) | |||
220 | 109 | ||
221 | DRM_DEBUG("irq=%d\n", dev->irq); | 110 | DRM_DEBUG("irq=%d\n", dev->irq); |
222 | 111 | ||
112 | if (drm_core_check_feature(dev, DRIVER_IRQ_VBL)) { | ||
113 | init_waitqueue_head(&dev->vbl_queue); | ||
114 | |||
115 | spin_lock_init(&dev->vbl_lock); | ||
116 | |||
117 | INIT_LIST_HEAD(&dev->vbl_sigs); | ||
118 | INIT_LIST_HEAD(&dev->vbl_sigs2); | ||
119 | |||
120 | dev->vbl_pending = 0; | ||
121 | } | ||
122 | |||
223 | /* Before installing handler */ | 123 | /* Before installing handler */ |
224 | dev->driver->irq_preinstall(dev); | 124 | dev->driver->irq_preinstall(dev); |
225 | 125 | ||
@@ -237,14 +137,9 @@ static int drm_irq_install(struct drm_device * dev) | |||
237 | } | 137 | } |
238 | 138 | ||
239 | /* After installing handler */ | 139 | /* After installing handler */ |
240 | ret = dev->driver->irq_postinstall(dev); | 140 | dev->driver->irq_postinstall(dev); |
241 | if (ret < 0) { | ||
242 | mutex_lock(&dev->struct_mutex); | ||
243 | dev->irq_enabled = 0; | ||
244 | mutex_unlock(&dev->struct_mutex); | ||
245 | } | ||
246 | 141 | ||
247 | return ret; | 142 | return 0; |
248 | } | 143 | } |
249 | 144 | ||
250 | /** | 145 | /** |
@@ -275,8 +170,6 @@ int drm_irq_uninstall(struct drm_device * dev) | |||
275 | 170 | ||
276 | free_irq(dev->irq, dev); | 171 | free_irq(dev->irq, dev); |
277 | 172 | ||
278 | drm_vblank_cleanup(dev); | ||
279 | |||
280 | dev->locked_tasklet_func = NULL; | 173 | dev->locked_tasklet_func = NULL; |
281 | 174 | ||
282 | return 0; | 175 | return 0; |
@@ -321,148 +214,6 @@ int drm_control(struct drm_device *dev, void *data, | |||
321 | } | 214 | } |
322 | 215 | ||
323 | /** | 216 | /** |
324 | * drm_vblank_count - retrieve "cooked" vblank counter value | ||
325 | * @dev: DRM device | ||
326 | * @crtc: which counter to retrieve | ||
327 | * | ||
328 | * Fetches the "cooked" vblank count value that represents the number of | ||
329 | * vblank events since the system was booted, including lost events due to | ||
330 | * modesetting activity. | ||
331 | */ | ||
332 | u32 drm_vblank_count(struct drm_device *dev, int crtc) | ||
333 | { | ||
334 | return atomic_read(&dev->_vblank_count[crtc]) + | ||
335 | dev->vblank_offset[crtc]; | ||
336 | } | ||
337 | EXPORT_SYMBOL(drm_vblank_count); | ||
338 | |||
339 | /** | ||
340 | * drm_update_vblank_count - update the master vblank counter | ||
341 | * @dev: DRM device | ||
342 | * @crtc: counter to update | ||
343 | * | ||
344 | * Call back into the driver to update the appropriate vblank counter | ||
345 | * (specified by @crtc). Deal with wraparound, if it occurred, and | ||
346 | * update the last read value so we can deal with wraparound on the next | ||
347 | * call if necessary. | ||
348 | */ | ||
349 | void drm_update_vblank_count(struct drm_device *dev, int crtc) | ||
350 | { | ||
351 | unsigned long irqflags; | ||
352 | u32 cur_vblank, diff; | ||
353 | |||
354 | /* | ||
355 | * Interrupts were disabled prior to this call, so deal with counter | ||
356 | * wrap if needed. | ||
357 | * NOTE! It's possible we lost a full dev->max_vblank_count events | ||
358 | * here if the register is small or we had vblank interrupts off for | ||
359 | * a long time. | ||
360 | */ | ||
361 | cur_vblank = dev->driver->get_vblank_counter(dev, crtc); | ||
362 | spin_lock_irqsave(&dev->vbl_lock, irqflags); | ||
363 | if (cur_vblank < dev->last_vblank[crtc]) { | ||
364 | diff = dev->max_vblank_count - | ||
365 | dev->last_vblank[crtc]; | ||
366 | diff += cur_vblank; | ||
367 | } else { | ||
368 | diff = cur_vblank - dev->last_vblank[crtc]; | ||
369 | } | ||
370 | dev->last_vblank[crtc] = cur_vblank; | ||
371 | spin_unlock_irqrestore(&dev->vbl_lock, irqflags); | ||
372 | |||
373 | atomic_add(diff, &dev->_vblank_count[crtc]); | ||
374 | } | ||
375 | EXPORT_SYMBOL(drm_update_vblank_count); | ||
376 | |||
377 | /** | ||
378 | * drm_vblank_get - get a reference count on vblank events | ||
379 | * @dev: DRM device | ||
380 | * @crtc: which CRTC to own | ||
381 | * | ||
382 | * Acquire a reference count on vblank events to avoid having them disabled | ||
383 | * while in use. Note callers will probably want to update the master counter | ||
384 | * using drm_update_vblank_count() above before calling this routine so that | ||
385 | * wakeups occur on the right vblank event. | ||
386 | * | ||
387 | * RETURNS | ||
388 | * Zero on success, nonzero on failure. | ||
389 | */ | ||
390 | int drm_vblank_get(struct drm_device *dev, int crtc) | ||
391 | { | ||
392 | unsigned long irqflags; | ||
393 | int ret = 0; | ||
394 | |||
395 | spin_lock_irqsave(&dev->vbl_lock, irqflags); | ||
396 | /* Going from 0->1 means we have to enable interrupts again */ | ||
397 | if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1 && | ||
398 | !dev->vblank_enabled[crtc]) { | ||
399 | ret = dev->driver->enable_vblank(dev, crtc); | ||
400 | if (ret) | ||
401 | atomic_dec(&dev->vblank_refcount[crtc]); | ||
402 | else | ||
403 | dev->vblank_enabled[crtc] = 1; | ||
404 | } | ||
405 | spin_unlock_irqrestore(&dev->vbl_lock, irqflags); | ||
406 | |||
407 | return ret; | ||
408 | } | ||
409 | EXPORT_SYMBOL(drm_vblank_get); | ||
410 | |||
411 | /** | ||
412 | * drm_vblank_put - give up ownership of vblank events | ||
413 | * @dev: DRM device | ||
414 | * @crtc: which counter to give up | ||
415 | * | ||
416 | * Release ownership of a given vblank counter, turning off interrupts | ||
417 | * if possible. | ||
418 | */ | ||
419 | void drm_vblank_put(struct drm_device *dev, int crtc) | ||
420 | { | ||
421 | /* Last user schedules interrupt disable */ | ||
422 | if (atomic_dec_and_test(&dev->vblank_refcount[crtc])) | ||
423 | mod_timer(&dev->vblank_disable_timer, jiffies + 5*DRM_HZ); | ||
424 | } | ||
425 | EXPORT_SYMBOL(drm_vblank_put); | ||
426 | |||
427 | /** | ||
428 | * drm_modeset_ctl - handle vblank event counter changes across mode switch | ||
429 | * @DRM_IOCTL_ARGS: standard ioctl arguments | ||
430 | * | ||
431 | * Applications should call the %_DRM_PRE_MODESET and %_DRM_POST_MODESET | ||
432 | * ioctls around modesetting so that any lost vblank events are accounted for. | ||
433 | */ | ||
434 | int drm_modeset_ctl(struct drm_device *dev, void *data, | ||
435 | struct drm_file *file_priv) | ||
436 | { | ||
437 | struct drm_modeset_ctl *modeset = data; | ||
438 | int crtc, ret = 0; | ||
439 | u32 new; | ||
440 | |||
441 | crtc = modeset->arg; | ||
442 | if (crtc >= dev->num_crtcs) { | ||
443 | ret = -EINVAL; | ||
444 | goto out; | ||
445 | } | ||
446 | |||
447 | switch (modeset->cmd) { | ||
448 | case _DRM_PRE_MODESET: | ||
449 | dev->vblank_premodeset[crtc] = | ||
450 | dev->driver->get_vblank_counter(dev, crtc); | ||
451 | break; | ||
452 | case _DRM_POST_MODESET: | ||
453 | new = dev->driver->get_vblank_counter(dev, crtc); | ||
454 | dev->vblank_offset[crtc] = dev->vblank_premodeset[crtc] - new; | ||
455 | break; | ||
456 | default: | ||
457 | ret = -EINVAL; | ||
458 | break; | ||
459 | } | ||
460 | |||
461 | out: | ||
462 | return ret; | ||
463 | } | ||
464 | |||
465 | /** | ||
466 | * Wait for VBLANK. | 217 | * Wait for VBLANK. |
467 | * | 218 | * |
468 | * \param inode device inode. | 219 | * \param inode device inode. |
@@ -481,13 +232,12 @@ out: | |||
481 | * | 232 | * |
482 | * If a signal is not requested, then calls vblank_wait(). | 233 | * If a signal is not requested, then calls vblank_wait(). |
483 | */ | 234 | */ |
484 | int drm_wait_vblank(struct drm_device *dev, void *data, | 235 | int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_priv) |
485 | struct drm_file *file_priv) | ||
486 | { | 236 | { |
487 | union drm_wait_vblank *vblwait = data; | 237 | union drm_wait_vblank *vblwait = data; |
488 | struct timeval now; | 238 | struct timeval now; |
489 | int ret = 0; | 239 | int ret = 0; |
490 | unsigned int flags, seq, crtc; | 240 | unsigned int flags, seq; |
491 | 241 | ||
492 | if ((!dev->irq) || (!dev->irq_enabled)) | 242 | if ((!dev->irq) || (!dev->irq_enabled)) |
493 | return -EINVAL; | 243 | return -EINVAL; |
@@ -501,13 +251,13 @@ int drm_wait_vblank(struct drm_device *dev, void *data, | |||
501 | } | 251 | } |
502 | 252 | ||
503 | flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK; | 253 | flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK; |
504 | crtc = flags & _DRM_VBLANK_SECONDARY ? 1 : 0; | ||
505 | 254 | ||
506 | if (crtc >= dev->num_crtcs) | 255 | if (!drm_core_check_feature(dev, (flags & _DRM_VBLANK_SECONDARY) ? |
256 | DRIVER_IRQ_VBL2 : DRIVER_IRQ_VBL)) | ||
507 | return -EINVAL; | 257 | return -EINVAL; |
508 | 258 | ||
509 | drm_update_vblank_count(dev, crtc); | 259 | seq = atomic_read((flags & _DRM_VBLANK_SECONDARY) ? &dev->vbl_received2 |
510 | seq = drm_vblank_count(dev, crtc); | 260 | : &dev->vbl_received); |
511 | 261 | ||
512 | switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) { | 262 | switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) { |
513 | case _DRM_VBLANK_RELATIVE: | 263 | case _DRM_VBLANK_RELATIVE: |
@@ -526,7 +276,8 @@ int drm_wait_vblank(struct drm_device *dev, void *data, | |||
526 | 276 | ||
527 | if (flags & _DRM_VBLANK_SIGNAL) { | 277 | if (flags & _DRM_VBLANK_SIGNAL) { |
528 | unsigned long irqflags; | 278 | unsigned long irqflags; |
529 | struct list_head *vbl_sigs = &dev->vbl_sigs[crtc]; | 279 | struct list_head *vbl_sigs = (flags & _DRM_VBLANK_SECONDARY) |
280 | ? &dev->vbl_sigs2 : &dev->vbl_sigs; | ||
530 | struct drm_vbl_sig *vbl_sig; | 281 | struct drm_vbl_sig *vbl_sig; |
531 | 282 | ||
532 | spin_lock_irqsave(&dev->vbl_lock, irqflags); | 283 | spin_lock_irqsave(&dev->vbl_lock, irqflags); |
@@ -547,26 +298,22 @@ int drm_wait_vblank(struct drm_device *dev, void *data, | |||
547 | } | 298 | } |
548 | } | 299 | } |
549 | 300 | ||
550 | if (atomic_read(&dev->vbl_signal_pending) >= 100) { | 301 | if (dev->vbl_pending >= 100) { |
551 | spin_unlock_irqrestore(&dev->vbl_lock, irqflags); | 302 | spin_unlock_irqrestore(&dev->vbl_lock, irqflags); |
552 | return -EBUSY; | 303 | return -EBUSY; |
553 | } | 304 | } |
554 | 305 | ||
306 | dev->vbl_pending++; | ||
307 | |||
555 | spin_unlock_irqrestore(&dev->vbl_lock, irqflags); | 308 | spin_unlock_irqrestore(&dev->vbl_lock, irqflags); |
556 | 309 | ||
557 | vbl_sig = drm_calloc(1, sizeof(struct drm_vbl_sig), | 310 | if (! |
558 | DRM_MEM_DRIVER); | 311 | (vbl_sig = |
559 | if (!vbl_sig) | 312 | drm_alloc(sizeof(struct drm_vbl_sig), DRM_MEM_DRIVER))) { |
560 | return -ENOMEM; | 313 | return -ENOMEM; |
561 | |||
562 | ret = drm_vblank_get(dev, crtc); | ||
563 | if (ret) { | ||
564 | drm_free(vbl_sig, sizeof(struct drm_vbl_sig), | ||
565 | DRM_MEM_DRIVER); | ||
566 | return ret; | ||
567 | } | 314 | } |
568 | 315 | ||
569 | atomic_inc(&dev->vbl_signal_pending); | 316 | memset((void *)vbl_sig, 0, sizeof(*vbl_sig)); |
570 | 317 | ||
571 | vbl_sig->sequence = vblwait->request.sequence; | 318 | vbl_sig->sequence = vblwait->request.sequence; |
572 | vbl_sig->info.si_signo = vblwait->request.signal; | 319 | vbl_sig->info.si_signo = vblwait->request.signal; |
@@ -580,20 +327,17 @@ int drm_wait_vblank(struct drm_device *dev, void *data, | |||
580 | 327 | ||
581 | vblwait->reply.sequence = seq; | 328 | vblwait->reply.sequence = seq; |
582 | } else { | 329 | } else { |
583 | unsigned long cur_vblank; | 330 | if (flags & _DRM_VBLANK_SECONDARY) { |
584 | 331 | if (dev->driver->vblank_wait2) | |
585 | ret = drm_vblank_get(dev, crtc); | 332 | ret = dev->driver->vblank_wait2(dev, &vblwait->request.sequence); |
586 | if (ret) | 333 | } else if (dev->driver->vblank_wait) |
587 | return ret; | 334 | ret = |
588 | DRM_WAIT_ON(ret, dev->vbl_queue[crtc], 3 * DRM_HZ, | 335 | dev->driver->vblank_wait(dev, |
589 | (((cur_vblank = drm_vblank_count(dev, crtc)) | 336 | &vblwait->request.sequence); |
590 | - vblwait->request.sequence) <= (1 << 23))); | ||
591 | drm_vblank_put(dev, crtc); | ||
592 | do_gettimeofday(&now); | ||
593 | 337 | ||
338 | do_gettimeofday(&now); | ||
594 | vblwait->reply.tval_sec = now.tv_sec; | 339 | vblwait->reply.tval_sec = now.tv_sec; |
595 | vblwait->reply.tval_usec = now.tv_usec; | 340 | vblwait->reply.tval_usec = now.tv_usec; |
596 | vblwait->reply.sequence = cur_vblank; | ||
597 | } | 341 | } |
598 | 342 | ||
599 | done: | 343 | done: |
@@ -604,57 +348,44 @@ int drm_wait_vblank(struct drm_device *dev, void *data, | |||
604 | * Send the VBLANK signals. | 348 | * Send the VBLANK signals. |
605 | * | 349 | * |
606 | * \param dev DRM device. | 350 | * \param dev DRM device. |
607 | * \param crtc CRTC where the vblank event occurred | ||
608 | * | 351 | * |
609 | * Sends a signal for each task in drm_device::vbl_sigs and empties the list. | 352 | * Sends a signal for each task in drm_device::vbl_sigs and empties the list. |
610 | * | 353 | * |
611 | * If a signal is not requested, then calls vblank_wait(). | 354 | * If a signal is not requested, then calls vblank_wait(). |
612 | */ | 355 | */ |
613 | static void drm_vbl_send_signals(struct drm_device * dev, int crtc) | 356 | void drm_vbl_send_signals(struct drm_device * dev) |
614 | { | 357 | { |
615 | struct drm_vbl_sig *vbl_sig, *tmp; | ||
616 | struct list_head *vbl_sigs; | ||
617 | unsigned int vbl_seq; | ||
618 | unsigned long flags; | 358 | unsigned long flags; |
359 | int i; | ||
619 | 360 | ||
620 | spin_lock_irqsave(&dev->vbl_lock, flags); | 361 | spin_lock_irqsave(&dev->vbl_lock, flags); |
621 | 362 | ||
622 | vbl_sigs = &dev->vbl_sigs[crtc]; | 363 | for (i = 0; i < 2; i++) { |
623 | vbl_seq = drm_vblank_count(dev, crtc); | 364 | struct drm_vbl_sig *vbl_sig, *tmp; |
365 | struct list_head *vbl_sigs = i ? &dev->vbl_sigs2 : &dev->vbl_sigs; | ||
366 | unsigned int vbl_seq = atomic_read(i ? &dev->vbl_received2 : | ||
367 | &dev->vbl_received); | ||
624 | 368 | ||
625 | list_for_each_entry_safe(vbl_sig, tmp, vbl_sigs, head) { | 369 | list_for_each_entry_safe(vbl_sig, tmp, vbl_sigs, head) { |
626 | if ((vbl_seq - vbl_sig->sequence) <= (1 << 23)) { | 370 | if ((vbl_seq - vbl_sig->sequence) <= (1 << 23)) { |
627 | vbl_sig->info.si_code = vbl_seq; | 371 | vbl_sig->info.si_code = vbl_seq; |
628 | send_sig_info(vbl_sig->info.si_signo, | 372 | send_sig_info(vbl_sig->info.si_signo, |
629 | &vbl_sig->info, vbl_sig->task); | 373 | &vbl_sig->info, vbl_sig->task); |
630 | 374 | ||
631 | list_del(&vbl_sig->head); | 375 | list_del(&vbl_sig->head); |
632 | 376 | ||
633 | drm_free(vbl_sig, sizeof(*vbl_sig), | 377 | drm_free(vbl_sig, sizeof(*vbl_sig), |
634 | DRM_MEM_DRIVER); | 378 | DRM_MEM_DRIVER); |
635 | atomic_dec(&dev->vbl_signal_pending); | 379 | |
636 | drm_vblank_put(dev, crtc); | 380 | dev->vbl_pending--; |
637 | } | 381 | } |
382 | } | ||
638 | } | 383 | } |
639 | 384 | ||
640 | spin_unlock_irqrestore(&dev->vbl_lock, flags); | 385 | spin_unlock_irqrestore(&dev->vbl_lock, flags); |
641 | } | 386 | } |
642 | 387 | ||
643 | /** | 388 | EXPORT_SYMBOL(drm_vbl_send_signals); |
644 | * drm_handle_vblank - handle a vblank event | ||
645 | * @dev: DRM device | ||
646 | * @crtc: where this event occurred | ||
647 | * | ||
648 | * Drivers should call this routine in their vblank interrupt handlers to | ||
649 | * update the vblank counter and send any signals that may be pending. | ||
650 | */ | ||
651 | void drm_handle_vblank(struct drm_device *dev, int crtc) | ||
652 | { | ||
653 | drm_update_vblank_count(dev, crtc); | ||
654 | DRM_WAKEUP(&dev->vbl_queue[crtc]); | ||
655 | drm_vbl_send_signals(dev, crtc); | ||
656 | } | ||
657 | EXPORT_SYMBOL(drm_handle_vblank); | ||
658 | 389 | ||
659 | /** | 390 | /** |
660 | * Tasklet wrapper function. | 391 | * Tasklet wrapper function. |
diff --git a/drivers/char/drm/drm_lock.c b/drivers/char/drm/drm_lock.c index 12dcdd1832f0..0998723cde79 100644 --- a/drivers/char/drm/drm_lock.c +++ b/drivers/char/drm/drm_lock.c | |||
@@ -53,7 +53,6 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv) | |||
53 | DECLARE_WAITQUEUE(entry, current); | 53 | DECLARE_WAITQUEUE(entry, current); |
54 | struct drm_lock *lock = data; | 54 | struct drm_lock *lock = data; |
55 | int ret = 0; | 55 | int ret = 0; |
56 | unsigned long irqflags; | ||
57 | 56 | ||
58 | ++file_priv->lock_count; | 57 | ++file_priv->lock_count; |
59 | 58 | ||
@@ -72,9 +71,9 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv) | |||
72 | return -EINVAL; | 71 | return -EINVAL; |
73 | 72 | ||
74 | add_wait_queue(&dev->lock.lock_queue, &entry); | 73 | add_wait_queue(&dev->lock.lock_queue, &entry); |
75 | spin_lock_irqsave(&dev->lock.spinlock, irqflags); | 74 | spin_lock_bh(&dev->lock.spinlock); |
76 | dev->lock.user_waiters++; | 75 | dev->lock.user_waiters++; |
77 | spin_unlock_irqrestore(&dev->lock.spinlock, irqflags); | 76 | spin_unlock_bh(&dev->lock.spinlock); |
78 | for (;;) { | 77 | for (;;) { |
79 | __set_current_state(TASK_INTERRUPTIBLE); | 78 | __set_current_state(TASK_INTERRUPTIBLE); |
80 | if (!dev->lock.hw_lock) { | 79 | if (!dev->lock.hw_lock) { |
@@ -96,9 +95,9 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv) | |||
96 | break; | 95 | break; |
97 | } | 96 | } |
98 | } | 97 | } |
99 | spin_lock_irqsave(&dev->lock.spinlock, irqflags); | 98 | spin_lock_bh(&dev->lock.spinlock); |
100 | dev->lock.user_waiters--; | 99 | dev->lock.user_waiters--; |
101 | spin_unlock_irqrestore(&dev->lock.spinlock, irqflags); | 100 | spin_unlock_bh(&dev->lock.spinlock); |
102 | __set_current_state(TASK_RUNNING); | 101 | __set_current_state(TASK_RUNNING); |
103 | remove_wait_queue(&dev->lock.lock_queue, &entry); | 102 | remove_wait_queue(&dev->lock.lock_queue, &entry); |
104 | 103 | ||
@@ -199,9 +198,8 @@ int drm_lock_take(struct drm_lock_data *lock_data, | |||
199 | { | 198 | { |
200 | unsigned int old, new, prev; | 199 | unsigned int old, new, prev; |
201 | volatile unsigned int *lock = &lock_data->hw_lock->lock; | 200 | volatile unsigned int *lock = &lock_data->hw_lock->lock; |
202 | unsigned long irqflags; | ||
203 | 201 | ||
204 | spin_lock_irqsave(&lock_data->spinlock, irqflags); | 202 | spin_lock_bh(&lock_data->spinlock); |
205 | do { | 203 | do { |
206 | old = *lock; | 204 | old = *lock; |
207 | if (old & _DRM_LOCK_HELD) | 205 | if (old & _DRM_LOCK_HELD) |
@@ -213,7 +211,7 @@ int drm_lock_take(struct drm_lock_data *lock_data, | |||
213 | } | 211 | } |
214 | prev = cmpxchg(lock, old, new); | 212 | prev = cmpxchg(lock, old, new); |
215 | } while (prev != old); | 213 | } while (prev != old); |
216 | spin_unlock_irqrestore(&lock_data->spinlock, irqflags); | 214 | spin_unlock_bh(&lock_data->spinlock); |
217 | 215 | ||
218 | if (_DRM_LOCKING_CONTEXT(old) == context) { | 216 | if (_DRM_LOCKING_CONTEXT(old) == context) { |
219 | if (old & _DRM_LOCK_HELD) { | 217 | if (old & _DRM_LOCK_HELD) { |
@@ -274,16 +272,15 @@ int drm_lock_free(struct drm_lock_data *lock_data, unsigned int context) | |||
274 | { | 272 | { |
275 | unsigned int old, new, prev; | 273 | unsigned int old, new, prev; |
276 | volatile unsigned int *lock = &lock_data->hw_lock->lock; | 274 | volatile unsigned int *lock = &lock_data->hw_lock->lock; |
277 | unsigned long irqflags; | ||
278 | 275 | ||
279 | spin_lock_irqsave(&lock_data->spinlock, irqflags); | 276 | spin_lock_bh(&lock_data->spinlock); |
280 | if (lock_data->kernel_waiters != 0) { | 277 | if (lock_data->kernel_waiters != 0) { |
281 | drm_lock_transfer(lock_data, 0); | 278 | drm_lock_transfer(lock_data, 0); |
282 | lock_data->idle_has_lock = 1; | 279 | lock_data->idle_has_lock = 1; |
283 | spin_unlock_irqrestore(&lock_data->spinlock, irqflags); | 280 | spin_unlock_bh(&lock_data->spinlock); |
284 | return 1; | 281 | return 1; |
285 | } | 282 | } |
286 | spin_unlock_irqrestore(&lock_data->spinlock, irqflags); | 283 | spin_unlock_bh(&lock_data->spinlock); |
287 | 284 | ||
288 | do { | 285 | do { |
289 | old = *lock; | 286 | old = *lock; |
@@ -347,20 +344,19 @@ static int drm_notifier(void *priv) | |||
347 | void drm_idlelock_take(struct drm_lock_data *lock_data) | 344 | void drm_idlelock_take(struct drm_lock_data *lock_data) |
348 | { | 345 | { |
349 | int ret = 0; | 346 | int ret = 0; |
350 | unsigned long irqflags; | ||
351 | 347 | ||
352 | spin_lock_irqsave(&lock_data->spinlock, irqflags); | 348 | spin_lock_bh(&lock_data->spinlock); |
353 | lock_data->kernel_waiters++; | 349 | lock_data->kernel_waiters++; |
354 | if (!lock_data->idle_has_lock) { | 350 | if (!lock_data->idle_has_lock) { |
355 | 351 | ||
356 | spin_unlock_irqrestore(&lock_data->spinlock, irqflags); | 352 | spin_unlock_bh(&lock_data->spinlock); |
357 | ret = drm_lock_take(lock_data, DRM_KERNEL_CONTEXT); | 353 | ret = drm_lock_take(lock_data, DRM_KERNEL_CONTEXT); |
358 | spin_lock_irqsave(&lock_data->spinlock, irqflags); | 354 | spin_lock_bh(&lock_data->spinlock); |
359 | 355 | ||
360 | if (ret == 1) | 356 | if (ret == 1) |
361 | lock_data->idle_has_lock = 1; | 357 | lock_data->idle_has_lock = 1; |
362 | } | 358 | } |
363 | spin_unlock_irqrestore(&lock_data->spinlock, irqflags); | 359 | spin_unlock_bh(&lock_data->spinlock); |
364 | } | 360 | } |
365 | EXPORT_SYMBOL(drm_idlelock_take); | 361 | EXPORT_SYMBOL(drm_idlelock_take); |
366 | 362 | ||
@@ -368,9 +364,8 @@ void drm_idlelock_release(struct drm_lock_data *lock_data) | |||
368 | { | 364 | { |
369 | unsigned int old, prev; | 365 | unsigned int old, prev; |
370 | volatile unsigned int *lock = &lock_data->hw_lock->lock; | 366 | volatile unsigned int *lock = &lock_data->hw_lock->lock; |
371 | unsigned long irqflags; | ||
372 | 367 | ||
373 | spin_lock_irqsave(&lock_data->spinlock, irqflags); | 368 | spin_lock_bh(&lock_data->spinlock); |
374 | if (--lock_data->kernel_waiters == 0) { | 369 | if (--lock_data->kernel_waiters == 0) { |
375 | if (lock_data->idle_has_lock) { | 370 | if (lock_data->idle_has_lock) { |
376 | do { | 371 | do { |
@@ -381,7 +376,7 @@ void drm_idlelock_release(struct drm_lock_data *lock_data) | |||
381 | lock_data->idle_has_lock = 0; | 376 | lock_data->idle_has_lock = 0; |
382 | } | 377 | } |
383 | } | 378 | } |
384 | spin_unlock_irqrestore(&lock_data->spinlock, irqflags); | 379 | spin_unlock_bh(&lock_data->spinlock); |
385 | } | 380 | } |
386 | EXPORT_SYMBOL(drm_idlelock_release); | 381 | EXPORT_SYMBOL(drm_idlelock_release); |
387 | 382 | ||
diff --git a/drivers/char/drm/drm_sysfs.c b/drivers/char/drm/drm_sysfs.c index 9a32169e88fb..af211a0ef179 100644 --- a/drivers/char/drm/drm_sysfs.c +++ b/drivers/char/drm/drm_sysfs.c | |||
@@ -34,8 +34,6 @@ static int drm_sysfs_suspend(struct device *dev, pm_message_t state) | |||
34 | struct drm_minor *drm_minor = to_drm_minor(dev); | 34 | struct drm_minor *drm_minor = to_drm_minor(dev); |
35 | struct drm_device *drm_dev = drm_minor->dev; | 35 | struct drm_device *drm_dev = drm_minor->dev; |
36 | 36 | ||
37 | printk(KERN_ERR "%s\n", __func__); | ||
38 | |||
39 | if (drm_dev->driver->suspend) | 37 | if (drm_dev->driver->suspend) |
40 | return drm_dev->driver->suspend(drm_dev, state); | 38 | return drm_dev->driver->suspend(drm_dev, state); |
41 | 39 | ||
diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c index f47e46e3529f..88974342933c 100644 --- a/drivers/char/drm/i915_dma.c +++ b/drivers/char/drm/i915_dma.c | |||
@@ -415,13 +415,10 @@ static void i915_emit_breadcrumb(struct drm_device *dev) | |||
415 | drm_i915_private_t *dev_priv = dev->dev_private; | 415 | drm_i915_private_t *dev_priv = dev->dev_private; |
416 | RING_LOCALS; | 416 | RING_LOCALS; |
417 | 417 | ||
418 | if (++dev_priv->counter > BREADCRUMB_MASK) { | 418 | dev_priv->sarea_priv->last_enqueue = ++dev_priv->counter; |
419 | dev_priv->counter = 1; | ||
420 | DRM_DEBUG("Breadcrumb counter wrapped around\n"); | ||
421 | } | ||
422 | 419 | ||
423 | if (dev_priv->sarea_priv) | 420 | if (dev_priv->counter > 0x7FFFFFFFUL) |
424 | dev_priv->sarea_priv->last_enqueue = dev_priv->counter; | 421 | dev_priv->sarea_priv->last_enqueue = dev_priv->counter = 1; |
425 | 422 | ||
426 | BEGIN_LP_RING(4); | 423 | BEGIN_LP_RING(4); |
427 | OUT_RING(CMD_STORE_DWORD_IDX); | 424 | OUT_RING(CMD_STORE_DWORD_IDX); |
@@ -431,26 +428,6 @@ static void i915_emit_breadcrumb(struct drm_device *dev) | |||
431 | ADVANCE_LP_RING(); | 428 | ADVANCE_LP_RING(); |
432 | } | 429 | } |
433 | 430 | ||
434 | int i915_emit_mi_flush(struct drm_device *dev, uint32_t flush) | ||
435 | { | ||
436 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
437 | uint32_t flush_cmd = CMD_MI_FLUSH; | ||
438 | RING_LOCALS; | ||
439 | |||
440 | flush_cmd |= flush; | ||
441 | |||
442 | i915_kernel_lost_context(dev); | ||
443 | |||
444 | BEGIN_LP_RING(4); | ||
445 | OUT_RING(flush_cmd); | ||
446 | OUT_RING(0); | ||
447 | OUT_RING(0); | ||
448 | OUT_RING(0); | ||
449 | ADVANCE_LP_RING(); | ||
450 | |||
451 | return 0; | ||
452 | } | ||
453 | |||
454 | static int i915_dispatch_cmdbuffer(struct drm_device * dev, | 431 | static int i915_dispatch_cmdbuffer(struct drm_device * dev, |
455 | drm_i915_cmdbuffer_t * cmd) | 432 | drm_i915_cmdbuffer_t * cmd) |
456 | { | 433 | { |
@@ -534,74 +511,52 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev, | |||
534 | return 0; | 511 | return 0; |
535 | } | 512 | } |
536 | 513 | ||
537 | static void i915_do_dispatch_flip(struct drm_device * dev, int plane, int sync) | 514 | static int i915_dispatch_flip(struct drm_device * dev) |
538 | { | 515 | { |
539 | drm_i915_private_t *dev_priv = dev->dev_private; | 516 | drm_i915_private_t *dev_priv = dev->dev_private; |
540 | u32 num_pages, current_page, next_page, dspbase; | ||
541 | int shift = 2 * plane, x, y; | ||
542 | RING_LOCALS; | 517 | RING_LOCALS; |
543 | 518 | ||
544 | /* Calculate display base offset */ | 519 | DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n", |
545 | num_pages = dev_priv->sarea_priv->third_handle ? 3 : 2; | 520 | __FUNCTION__, |
546 | current_page = (dev_priv->sarea_priv->pf_current_page >> shift) & 0x3; | 521 | dev_priv->current_page, |
547 | next_page = (current_page + 1) % num_pages; | 522 | dev_priv->sarea_priv->pf_current_page); |
548 | 523 | ||
549 | switch (next_page) { | 524 | i915_kernel_lost_context(dev); |
550 | default: | 525 | |
551 | case 0: | 526 | BEGIN_LP_RING(2); |
552 | dspbase = dev_priv->sarea_priv->front_offset; | 527 | OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE); |
553 | break; | 528 | OUT_RING(0); |
554 | case 1: | 529 | ADVANCE_LP_RING(); |
555 | dspbase = dev_priv->sarea_priv->back_offset; | ||
556 | break; | ||
557 | case 2: | ||
558 | dspbase = dev_priv->sarea_priv->third_offset; | ||
559 | break; | ||
560 | } | ||
561 | 530 | ||
562 | if (plane == 0) { | 531 | BEGIN_LP_RING(6); |
563 | x = dev_priv->sarea_priv->planeA_x; | 532 | OUT_RING(CMD_OP_DISPLAYBUFFER_INFO | ASYNC_FLIP); |
564 | y = dev_priv->sarea_priv->planeA_y; | 533 | OUT_RING(0); |
534 | if (dev_priv->current_page == 0) { | ||
535 | OUT_RING(dev_priv->back_offset); | ||
536 | dev_priv->current_page = 1; | ||
565 | } else { | 537 | } else { |
566 | x = dev_priv->sarea_priv->planeB_x; | 538 | OUT_RING(dev_priv->front_offset); |
567 | y = dev_priv->sarea_priv->planeB_y; | 539 | dev_priv->current_page = 0; |
568 | } | 540 | } |
541 | OUT_RING(0); | ||
542 | ADVANCE_LP_RING(); | ||
569 | 543 | ||
570 | dspbase += (y * dev_priv->sarea_priv->pitch + x) * dev_priv->cpp; | 544 | BEGIN_LP_RING(2); |
545 | OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_PLANE_A_FLIP); | ||
546 | OUT_RING(0); | ||
547 | ADVANCE_LP_RING(); | ||
571 | 548 | ||
572 | DRM_DEBUG("plane=%d current_page=%d dspbase=0x%x\n", plane, current_page, | 549 | dev_priv->sarea_priv->last_enqueue = dev_priv->counter++; |
573 | dspbase); | ||
574 | 550 | ||
575 | BEGIN_LP_RING(4); | 551 | BEGIN_LP_RING(4); |
576 | OUT_RING(sync ? 0 : | 552 | OUT_RING(CMD_STORE_DWORD_IDX); |
577 | (MI_WAIT_FOR_EVENT | (plane ? MI_WAIT_FOR_PLANE_B_FLIP : | 553 | OUT_RING(20); |
578 | MI_WAIT_FOR_PLANE_A_FLIP))); | 554 | OUT_RING(dev_priv->counter); |
579 | OUT_RING(CMD_OP_DISPLAYBUFFER_INFO | (sync ? 0 : ASYNC_FLIP) | | 555 | OUT_RING(0); |
580 | (plane ? DISPLAY_PLANE_B : DISPLAY_PLANE_A)); | ||
581 | OUT_RING(dev_priv->sarea_priv->pitch * dev_priv->cpp); | ||
582 | OUT_RING(dspbase); | ||
583 | ADVANCE_LP_RING(); | 556 | ADVANCE_LP_RING(); |
584 | 557 | ||
585 | dev_priv->sarea_priv->pf_current_page &= ~(0x3 << shift); | 558 | dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; |
586 | dev_priv->sarea_priv->pf_current_page |= next_page << shift; | 559 | return 0; |
587 | } | ||
588 | |||
589 | void i915_dispatch_flip(struct drm_device * dev, int planes, int sync) | ||
590 | { | ||
591 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
592 | int i; | ||
593 | |||
594 | DRM_DEBUG("planes=0x%x pfCurrentPage=%d\n", | ||
595 | planes, dev_priv->sarea_priv->pf_current_page); | ||
596 | |||
597 | i915_emit_mi_flush(dev, MI_READ_FLUSH | MI_EXE_FLUSH); | ||
598 | |||
599 | for (i = 0; i < 2; i++) | ||
600 | if (planes & (1 << i)) | ||
601 | i915_do_dispatch_flip(dev, i, sync); | ||
602 | |||
603 | i915_emit_breadcrumb(dev); | ||
604 | |||
605 | } | 560 | } |
606 | 561 | ||
607 | static int i915_quiescent(struct drm_device * dev) | 562 | static int i915_quiescent(struct drm_device * dev) |
@@ -624,6 +579,7 @@ static int i915_batchbuffer(struct drm_device *dev, void *data, | |||
624 | struct drm_file *file_priv) | 579 | struct drm_file *file_priv) |
625 | { | 580 | { |
626 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 581 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
582 | u32 *hw_status = dev_priv->hw_status_page; | ||
627 | drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) | 583 | drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) |
628 | dev_priv->sarea_priv; | 584 | dev_priv->sarea_priv; |
629 | drm_i915_batchbuffer_t *batch = data; | 585 | drm_i915_batchbuffer_t *batch = data; |
@@ -646,7 +602,7 @@ static int i915_batchbuffer(struct drm_device *dev, void *data, | |||
646 | 602 | ||
647 | ret = i915_dispatch_batchbuffer(dev, batch); | 603 | ret = i915_dispatch_batchbuffer(dev, batch); |
648 | 604 | ||
649 | sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); | 605 | sarea_priv->last_dispatch = (int)hw_status[5]; |
650 | return ret; | 606 | return ret; |
651 | } | 607 | } |
652 | 608 | ||
@@ -654,6 +610,7 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data, | |||
654 | struct drm_file *file_priv) | 610 | struct drm_file *file_priv) |
655 | { | 611 | { |
656 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 612 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
613 | u32 *hw_status = dev_priv->hw_status_page; | ||
657 | drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) | 614 | drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) |
658 | dev_priv->sarea_priv; | 615 | dev_priv->sarea_priv; |
659 | drm_i915_cmdbuffer_t *cmdbuf = data; | 616 | drm_i915_cmdbuffer_t *cmdbuf = data; |
@@ -678,51 +635,18 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data, | |||
678 | return ret; | 635 | return ret; |
679 | } | 636 | } |
680 | 637 | ||
681 | sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); | 638 | sarea_priv->last_dispatch = (int)hw_status[5]; |
682 | return 0; | ||
683 | } | ||
684 | |||
685 | static int i915_do_cleanup_pageflip(struct drm_device * dev) | ||
686 | { | ||
687 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
688 | int i, planes, num_pages = dev_priv->sarea_priv->third_handle ? 3 : 2; | ||
689 | |||
690 | DRM_DEBUG("\n"); | ||
691 | |||
692 | for (i = 0, planes = 0; i < 2; i++) | ||
693 | if (dev_priv->sarea_priv->pf_current_page & (0x3 << (2 * i))) { | ||
694 | dev_priv->sarea_priv->pf_current_page = | ||
695 | (dev_priv->sarea_priv->pf_current_page & | ||
696 | ~(0x3 << (2 * i))) | ((num_pages - 1) << (2 * i)); | ||
697 | |||
698 | planes |= 1 << i; | ||
699 | } | ||
700 | |||
701 | if (planes) | ||
702 | i915_dispatch_flip(dev, planes, 0); | ||
703 | |||
704 | return 0; | 639 | return 0; |
705 | } | 640 | } |
706 | 641 | ||
707 | static int i915_flip_bufs(struct drm_device *dev, void *data, | 642 | static int i915_flip_bufs(struct drm_device *dev, void *data, |
708 | struct drm_file *file_priv) | 643 | struct drm_file *file_priv) |
709 | { | 644 | { |
710 | drm_i915_flip_t *param = data; | 645 | DRM_DEBUG("%s\n", __FUNCTION__); |
711 | |||
712 | DRM_DEBUG("\n"); | ||
713 | 646 | ||
714 | LOCK_TEST_WITH_RETURN(dev, file_priv); | 647 | LOCK_TEST_WITH_RETURN(dev, file_priv); |
715 | 648 | ||
716 | /* This is really planes */ | 649 | return i915_dispatch_flip(dev); |
717 | if (param->pipes & ~0x3) { | ||
718 | DRM_ERROR("Invalid planes 0x%x, only <= 0x3 is valid\n", | ||
719 | param->pipes); | ||
720 | return -EINVAL; | ||
721 | } | ||
722 | |||
723 | i915_dispatch_flip(dev, param->pipes, 0); | ||
724 | |||
725 | return 0; | ||
726 | } | 650 | } |
727 | 651 | ||
728 | static int i915_getparam(struct drm_device *dev, void *data, | 652 | static int i915_getparam(struct drm_device *dev, void *data, |
@@ -883,8 +807,6 @@ void i915_driver_lastclose(struct drm_device * dev) | |||
883 | if (!dev_priv) | 807 | if (!dev_priv) |
884 | return; | 808 | return; |
885 | 809 | ||
886 | if (drm_getsarea(dev) && dev_priv->sarea_priv) | ||
887 | i915_do_cleanup_pageflip(dev); | ||
888 | if (dev_priv->agp_heap) | 810 | if (dev_priv->agp_heap) |
889 | i915_mem_takedown(&(dev_priv->agp_heap)); | 811 | i915_mem_takedown(&(dev_priv->agp_heap)); |
890 | 812 | ||
diff --git a/drivers/char/drm/i915_drm.h b/drivers/char/drm/i915_drm.h index 0431c00e2289..05c66cf03a9e 100644 --- a/drivers/char/drm/i915_drm.h +++ b/drivers/char/drm/i915_drm.h | |||
@@ -105,29 +105,14 @@ typedef struct _drm_i915_sarea { | |||
105 | unsigned int rotated_tiled; | 105 | unsigned int rotated_tiled; |
106 | unsigned int rotated2_tiled; | 106 | unsigned int rotated2_tiled; |
107 | 107 | ||
108 | int planeA_x; | 108 | int pipeA_x; |
109 | int planeA_y; | 109 | int pipeA_y; |
110 | int planeA_w; | 110 | int pipeA_w; |
111 | int planeA_h; | 111 | int pipeA_h; |
112 | int planeB_x; | 112 | int pipeB_x; |
113 | int planeB_y; | 113 | int pipeB_y; |
114 | int planeB_w; | 114 | int pipeB_w; |
115 | int planeB_h; | 115 | int pipeB_h; |
116 | |||
117 | /* Triple buffering */ | ||
118 | drm_handle_t third_handle; | ||
119 | int third_offset; | ||
120 | int third_size; | ||
121 | unsigned int third_tiled; | ||
122 | |||
123 | /* buffer object handles for the static buffers. May change | ||
124 | * over the lifetime of the client, though it doesn't in our current | ||
125 | * implementation. | ||
126 | */ | ||
127 | unsigned int front_bo_handle; | ||
128 | unsigned int back_bo_handle; | ||
129 | unsigned int third_bo_handle; | ||
130 | unsigned int depth_bo_handle; | ||
131 | } drm_i915_sarea_t; | 116 | } drm_i915_sarea_t; |
132 | 117 | ||
133 | /* Flags for perf_boxes | 118 | /* Flags for perf_boxes |
@@ -161,7 +146,7 @@ typedef struct _drm_i915_sarea { | |||
161 | 146 | ||
162 | #define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t) | 147 | #define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t) |
163 | #define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH) | 148 | #define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH) |
164 | #define DRM_IOCTL_I915_FLIP DRM_IOW( DRM_COMMAND_BASE + DRM_I915_FLIP, drm_i915_flip_t) | 149 | #define DRM_IOCTL_I915_FLIP DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLIP) |
165 | #define DRM_IOCTL_I915_BATCHBUFFER DRM_IOW( DRM_COMMAND_BASE + DRM_I915_BATCHBUFFER, drm_i915_batchbuffer_t) | 150 | #define DRM_IOCTL_I915_BATCHBUFFER DRM_IOW( DRM_COMMAND_BASE + DRM_I915_BATCHBUFFER, drm_i915_batchbuffer_t) |
166 | #define DRM_IOCTL_I915_IRQ_EMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_IRQ_EMIT, drm_i915_irq_emit_t) | 151 | #define DRM_IOCTL_I915_IRQ_EMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_IRQ_EMIT, drm_i915_irq_emit_t) |
167 | #define DRM_IOCTL_I915_IRQ_WAIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_IRQ_WAIT, drm_i915_irq_wait_t) | 152 | #define DRM_IOCTL_I915_IRQ_WAIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_IRQ_WAIT, drm_i915_irq_wait_t) |
@@ -176,18 +161,6 @@ typedef struct _drm_i915_sarea { | |||
176 | #define DRM_IOCTL_I915_GET_VBLANK_PIPE DRM_IOR( DRM_COMMAND_BASE + DRM_I915_GET_VBLANK_PIPE, drm_i915_vblank_pipe_t) | 161 | #define DRM_IOCTL_I915_GET_VBLANK_PIPE DRM_IOR( DRM_COMMAND_BASE + DRM_I915_GET_VBLANK_PIPE, drm_i915_vblank_pipe_t) |
177 | #define DRM_IOCTL_I915_VBLANK_SWAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_VBLANK_SWAP, drm_i915_vblank_swap_t) | 162 | #define DRM_IOCTL_I915_VBLANK_SWAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_VBLANK_SWAP, drm_i915_vblank_swap_t) |
178 | 163 | ||
179 | /* Asynchronous page flipping: | ||
180 | */ | ||
181 | typedef struct drm_i915_flip { | ||
182 | /* | ||
183 | * This is really talking about planes, and we could rename it | ||
184 | * except for the fact that some of the duplicated i915_drm.h files | ||
185 | * out there check for HAVE_I915_FLIP and so might pick up this | ||
186 | * version. | ||
187 | */ | ||
188 | int pipes; | ||
189 | } drm_i915_flip_t; | ||
190 | |||
191 | /* Allow drivers to submit batchbuffers directly to hardware, relying | 164 | /* Allow drivers to submit batchbuffers directly to hardware, relying |
192 | * on the security mechanisms provided by hardware. | 165 | * on the security mechanisms provided by hardware. |
193 | */ | 166 | */ |
diff --git a/drivers/char/drm/i915_drv.c b/drivers/char/drm/i915_drv.c index bb8f1b2fb383..e8f3d682e3b1 100644 --- a/drivers/char/drm/i915_drv.c +++ b/drivers/char/drm/i915_drv.c | |||
@@ -147,7 +147,7 @@ static void i915_save_vga(struct drm_device *dev) | |||
147 | i915_write_indexed(cr_index, cr_data, 0x11, | 147 | i915_write_indexed(cr_index, cr_data, 0x11, |
148 | i915_read_indexed(cr_index, cr_data, 0x11) & | 148 | i915_read_indexed(cr_index, cr_data, 0x11) & |
149 | (~0x80)); | 149 | (~0x80)); |
150 | for (i = 0; i < 0x24; i++) | 150 | for (i = 0; i <= 0x24; i++) |
151 | dev_priv->saveCR[i] = | 151 | dev_priv->saveCR[i] = |
152 | i915_read_indexed(cr_index, cr_data, i); | 152 | i915_read_indexed(cr_index, cr_data, i); |
153 | /* Make sure we don't turn off CR group 0 writes */ | 153 | /* Make sure we don't turn off CR group 0 writes */ |
@@ -156,7 +156,7 @@ static void i915_save_vga(struct drm_device *dev) | |||
156 | /* Attribute controller registers */ | 156 | /* Attribute controller registers */ |
157 | inb(st01); | 157 | inb(st01); |
158 | dev_priv->saveAR_INDEX = inb(VGA_AR_INDEX); | 158 | dev_priv->saveAR_INDEX = inb(VGA_AR_INDEX); |
159 | for (i = 0; i < 20; i++) | 159 | for (i = 0; i <= 0x14; i++) |
160 | dev_priv->saveAR[i] = i915_read_ar(st01, i, 0); | 160 | dev_priv->saveAR[i] = i915_read_ar(st01, i, 0); |
161 | inb(st01); | 161 | inb(st01); |
162 | outb(dev_priv->saveAR_INDEX, VGA_AR_INDEX); | 162 | outb(dev_priv->saveAR_INDEX, VGA_AR_INDEX); |
@@ -206,7 +206,7 @@ static void i915_restore_vga(struct drm_device *dev) | |||
206 | /* CRT controller regs */ | 206 | /* CRT controller regs */ |
207 | /* Enable CR group 0 writes */ | 207 | /* Enable CR group 0 writes */ |
208 | i915_write_indexed(cr_index, cr_data, 0x11, dev_priv->saveCR[0x11]); | 208 | i915_write_indexed(cr_index, cr_data, 0x11, dev_priv->saveCR[0x11]); |
209 | for (i = 0; i < 0x24; i++) | 209 | for (i = 0; i <= 0x24; i++) |
210 | i915_write_indexed(cr_index, cr_data, i, dev_priv->saveCR[i]); | 210 | i915_write_indexed(cr_index, cr_data, i, dev_priv->saveCR[i]); |
211 | 211 | ||
212 | /* Graphics controller regs */ | 212 | /* Graphics controller regs */ |
@@ -223,7 +223,7 @@ static void i915_restore_vga(struct drm_device *dev) | |||
223 | 223 | ||
224 | /* Attribute controller registers */ | 224 | /* Attribute controller registers */ |
225 | inb(st01); | 225 | inb(st01); |
226 | for (i = 0; i < 20; i++) | 226 | for (i = 0; i <= 0x14; i++) |
227 | i915_write_ar(st01, i, dev_priv->saveAR[i], 0); | 227 | i915_write_ar(st01, i, dev_priv->saveAR[i], 0); |
228 | inb(st01); /* switch back to index mode */ | 228 | inb(st01); /* switch back to index mode */ |
229 | outb(dev_priv->saveAR_INDEX | 0x20, VGA_AR_INDEX); | 229 | outb(dev_priv->saveAR_INDEX | 0x20, VGA_AR_INDEX); |
@@ -256,6 +256,9 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state) | |||
256 | pci_save_state(dev->pdev); | 256 | pci_save_state(dev->pdev); |
257 | pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB); | 257 | pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB); |
258 | 258 | ||
259 | /* Display arbitration control */ | ||
260 | dev_priv->saveDSPARB = I915_READ(DSPARB); | ||
261 | |||
259 | /* Pipe & plane A info */ | 262 | /* Pipe & plane A info */ |
260 | dev_priv->savePIPEACONF = I915_READ(PIPEACONF); | 263 | dev_priv->savePIPEACONF = I915_READ(PIPEACONF); |
261 | dev_priv->savePIPEASRC = I915_READ(PIPEASRC); | 264 | dev_priv->savePIPEASRC = I915_READ(PIPEASRC); |
@@ -349,6 +352,7 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state) | |||
349 | dev_priv->saveVGACNTRL = I915_READ(VGACNTRL); | 352 | dev_priv->saveVGACNTRL = I915_READ(VGACNTRL); |
350 | 353 | ||
351 | /* Clock gating state */ | 354 | /* Clock gating state */ |
355 | dev_priv->saveD_STATE = I915_READ(D_STATE); | ||
352 | dev_priv->saveDSPCLK_GATE_D = I915_READ(DSPCLK_GATE_D); | 356 | dev_priv->saveDSPCLK_GATE_D = I915_READ(DSPCLK_GATE_D); |
353 | 357 | ||
354 | /* Cache mode state */ | 358 | /* Cache mode state */ |
@@ -388,6 +392,8 @@ static int i915_resume(struct drm_device *dev) | |||
388 | 392 | ||
389 | pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB); | 393 | pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB); |
390 | 394 | ||
395 | I915_WRITE(DSPARB, dev_priv->saveDSPARB); | ||
396 | |||
391 | /* Pipe & plane A info */ | 397 | /* Pipe & plane A info */ |
392 | /* Prime the clock */ | 398 | /* Prime the clock */ |
393 | if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) { | 399 | if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) { |
@@ -507,6 +513,7 @@ static int i915_resume(struct drm_device *dev) | |||
507 | udelay(150); | 513 | udelay(150); |
508 | 514 | ||
509 | /* Clock gating state */ | 515 | /* Clock gating state */ |
516 | I915_WRITE (D_STATE, dev_priv->saveD_STATE); | ||
510 | I915_WRITE (DSPCLK_GATE_D, dev_priv->saveDSPCLK_GATE_D); | 517 | I915_WRITE (DSPCLK_GATE_D, dev_priv->saveDSPCLK_GATE_D); |
511 | 518 | ||
512 | /* Cache mode state */ | 519 | /* Cache mode state */ |
@@ -533,7 +540,8 @@ static struct drm_driver driver = { | |||
533 | */ | 540 | */ |
534 | .driver_features = | 541 | .driver_features = |
535 | DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | /* DRIVER_USE_MTRR |*/ | 542 | DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | /* DRIVER_USE_MTRR |*/ |
536 | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED, | 543 | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL | |
544 | DRIVER_IRQ_VBL2, | ||
537 | .load = i915_driver_load, | 545 | .load = i915_driver_load, |
538 | .unload = i915_driver_unload, | 546 | .unload = i915_driver_unload, |
539 | .lastclose = i915_driver_lastclose, | 547 | .lastclose = i915_driver_lastclose, |
@@ -541,9 +549,8 @@ static struct drm_driver driver = { | |||
541 | .suspend = i915_suspend, | 549 | .suspend = i915_suspend, |
542 | .resume = i915_resume, | 550 | .resume = i915_resume, |
543 | .device_is_agp = i915_driver_device_is_agp, | 551 | .device_is_agp = i915_driver_device_is_agp, |
544 | .get_vblank_counter = i915_get_vblank_counter, | 552 | .vblank_wait = i915_driver_vblank_wait, |
545 | .enable_vblank = i915_enable_vblank, | 553 | .vblank_wait2 = i915_driver_vblank_wait2, |
546 | .disable_vblank = i915_disable_vblank, | ||
547 | .irq_preinstall = i915_driver_irq_preinstall, | 554 | .irq_preinstall = i915_driver_irq_preinstall, |
548 | .irq_postinstall = i915_driver_irq_postinstall, | 555 | .irq_postinstall = i915_driver_irq_postinstall, |
549 | .irq_uninstall = i915_driver_irq_uninstall, | 556 | .irq_uninstall = i915_driver_irq_uninstall, |
diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h index db7001f22561..1b20f7c0639c 100644 --- a/drivers/char/drm/i915_drv.h +++ b/drivers/char/drm/i915_drv.h | |||
@@ -76,9 +76,8 @@ struct mem_block { | |||
76 | typedef struct _drm_i915_vbl_swap { | 76 | typedef struct _drm_i915_vbl_swap { |
77 | struct list_head head; | 77 | struct list_head head; |
78 | drm_drawable_t drw_id; | 78 | drm_drawable_t drw_id; |
79 | unsigned int plane; | 79 | unsigned int pipe; |
80 | unsigned int sequence; | 80 | unsigned int sequence; |
81 | int flip; | ||
82 | } drm_i915_vbl_swap_t; | 81 | } drm_i915_vbl_swap_t; |
83 | 82 | ||
84 | typedef struct drm_i915_private { | 83 | typedef struct drm_i915_private { |
@@ -91,7 +90,7 @@ typedef struct drm_i915_private { | |||
91 | drm_dma_handle_t *status_page_dmah; | 90 | drm_dma_handle_t *status_page_dmah; |
92 | void *hw_status_page; | 91 | void *hw_status_page; |
93 | dma_addr_t dma_status_page; | 92 | dma_addr_t dma_status_page; |
94 | uint32_t counter; | 93 | unsigned long counter; |
95 | unsigned int status_gfx_addr; | 94 | unsigned int status_gfx_addr; |
96 | drm_local_map_t hws_map; | 95 | drm_local_map_t hws_map; |
97 | 96 | ||
@@ -104,18 +103,13 @@ typedef struct drm_i915_private { | |||
104 | 103 | ||
105 | wait_queue_head_t irq_queue; | 104 | wait_queue_head_t irq_queue; |
106 | atomic_t irq_received; | 105 | atomic_t irq_received; |
107 | atomic_t irq_emited; | 106 | atomic_t irq_emitted; |
108 | 107 | ||
109 | int tex_lru_log_granularity; | 108 | int tex_lru_log_granularity; |
110 | int allow_batchbuffer; | 109 | int allow_batchbuffer; |
111 | struct mem_block *agp_heap; | 110 | struct mem_block *agp_heap; |
112 | unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds; | 111 | unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds; |
113 | int vblank_pipe; | 112 | int vblank_pipe; |
114 | spinlock_t user_irq_lock; | ||
115 | int user_irq_refcount; | ||
116 | int fence_irq_on; | ||
117 | uint32_t irq_enable_reg; | ||
118 | int irq_enabled; | ||
119 | 113 | ||
120 | spinlock_t swaps_lock; | 114 | spinlock_t swaps_lock; |
121 | drm_i915_vbl_swap_t vbl_swaps; | 115 | drm_i915_vbl_swap_t vbl_swaps; |
@@ -125,6 +119,7 @@ typedef struct drm_i915_private { | |||
125 | u8 saveLBB; | 119 | u8 saveLBB; |
126 | u32 saveDSPACNTR; | 120 | u32 saveDSPACNTR; |
127 | u32 saveDSPBCNTR; | 121 | u32 saveDSPBCNTR; |
122 | u32 saveDSPARB; | ||
128 | u32 savePIPEACONF; | 123 | u32 savePIPEACONF; |
129 | u32 savePIPEBCONF; | 124 | u32 savePIPEBCONF; |
130 | u32 savePIPEASRC; | 125 | u32 savePIPEASRC; |
@@ -194,6 +189,7 @@ typedef struct drm_i915_private { | |||
194 | u32 saveIIR; | 189 | u32 saveIIR; |
195 | u32 saveIMR; | 190 | u32 saveIMR; |
196 | u32 saveCACHE_MODE_0; | 191 | u32 saveCACHE_MODE_0; |
192 | u32 saveD_STATE; | ||
197 | u32 saveDSPCLK_GATE_D; | 193 | u32 saveDSPCLK_GATE_D; |
198 | u32 saveMI_ARB_STATE; | 194 | u32 saveMI_ARB_STATE; |
199 | u32 saveSWF0[16]; | 195 | u32 saveSWF0[16]; |
@@ -203,10 +199,10 @@ typedef struct drm_i915_private { | |||
203 | u8 saveSR[8]; | 199 | u8 saveSR[8]; |
204 | u8 saveGR[25]; | 200 | u8 saveGR[25]; |
205 | u8 saveAR_INDEX; | 201 | u8 saveAR_INDEX; |
206 | u8 saveAR[20]; | 202 | u8 saveAR[21]; |
207 | u8 saveDACMASK; | 203 | u8 saveDACMASK; |
208 | u8 saveDACDATA[256*3]; /* 256 3-byte colors */ | 204 | u8 saveDACDATA[256*3]; /* 256 3-byte colors */ |
209 | u8 saveCR[36]; | 205 | u8 saveCR[37]; |
210 | } drm_i915_private_t; | 206 | } drm_i915_private_t; |
211 | 207 | ||
212 | extern struct drm_ioctl_desc i915_ioctls[]; | 208 | extern struct drm_ioctl_desc i915_ioctls[]; |
@@ -222,7 +218,7 @@ extern void i915_driver_preclose(struct drm_device *dev, | |||
222 | extern int i915_driver_device_is_agp(struct drm_device * dev); | 218 | extern int i915_driver_device_is_agp(struct drm_device * dev); |
223 | extern long i915_compat_ioctl(struct file *filp, unsigned int cmd, | 219 | extern long i915_compat_ioctl(struct file *filp, unsigned int cmd, |
224 | unsigned long arg); | 220 | unsigned long arg); |
225 | extern void i915_dispatch_flip(struct drm_device * dev, int pipes, int sync); | 221 | |
226 | /* i915_irq.c */ | 222 | /* i915_irq.c */ |
227 | extern int i915_irq_emit(struct drm_device *dev, void *data, | 223 | extern int i915_irq_emit(struct drm_device *dev, void *data, |
228 | struct drm_file *file_priv); | 224 | struct drm_file *file_priv); |
@@ -233,7 +229,7 @@ extern int i915_driver_vblank_wait(struct drm_device *dev, unsigned int *sequenc | |||
233 | extern int i915_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence); | 229 | extern int i915_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence); |
234 | extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS); | 230 | extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS); |
235 | extern void i915_driver_irq_preinstall(struct drm_device * dev); | 231 | extern void i915_driver_irq_preinstall(struct drm_device * dev); |
236 | extern int i915_driver_irq_postinstall(struct drm_device * dev); | 232 | extern void i915_driver_irq_postinstall(struct drm_device * dev); |
237 | extern void i915_driver_irq_uninstall(struct drm_device * dev); | 233 | extern void i915_driver_irq_uninstall(struct drm_device * dev); |
238 | extern int i915_vblank_pipe_set(struct drm_device *dev, void *data, | 234 | extern int i915_vblank_pipe_set(struct drm_device *dev, void *data, |
239 | struct drm_file *file_priv); | 235 | struct drm_file *file_priv); |
@@ -241,9 +237,6 @@ extern int i915_vblank_pipe_get(struct drm_device *dev, void *data, | |||
241 | struct drm_file *file_priv); | 237 | struct drm_file *file_priv); |
242 | extern int i915_vblank_swap(struct drm_device *dev, void *data, | 238 | extern int i915_vblank_swap(struct drm_device *dev, void *data, |
243 | struct drm_file *file_priv); | 239 | struct drm_file *file_priv); |
244 | extern int i915_enable_vblank(struct drm_device *dev, int crtc); | ||
245 | extern void i915_disable_vblank(struct drm_device *dev, int crtc); | ||
246 | extern u32 i915_get_vblank_counter(struct drm_device *dev, int crtc); | ||
247 | 240 | ||
248 | /* i915_mem.c */ | 241 | /* i915_mem.c */ |
249 | extern int i915_mem_alloc(struct drm_device *dev, void *data, | 242 | extern int i915_mem_alloc(struct drm_device *dev, void *data, |
@@ -388,91 +381,21 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); | |||
388 | 381 | ||
389 | /* Interrupt bits: | 382 | /* Interrupt bits: |
390 | */ | 383 | */ |
391 | #define I915_PIPE_CONTROL_NOTIFY_INTERRUPT (1<<18) | 384 | #define USER_INT_FLAG (1<<1) |
392 | #define I915_DISPLAY_PORT_INTERRUPT (1<<17) | 385 | #define VSYNC_PIPEB_FLAG (1<<5) |
393 | #define I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT (1<<15) | 386 | #define VSYNC_PIPEA_FLAG (1<<7) |
394 | #define I915_GMCH_THERMAL_SENSOR_EVENT_INTERRUPT (1<<14) | 387 | #define HWB_OOM_FLAG (1<<13) /* binner out of memory */ |
395 | #define I915_HWB_OOM_INTERRUPT (1<<13) /* binner out of memory */ | ||
396 | #define I915_SYNC_STATUS_INTERRUPT (1<<12) | ||
397 | #define I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT (1<<11) | ||
398 | #define I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT (1<<10) | ||
399 | #define I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT (1<<9) | ||
400 | #define I915_DISPLAY_PLANE_C_FLIP_PENDING_INTERRUPT (1<<8) | ||
401 | #define I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT (1<<7) | ||
402 | #define I915_DISPLAY_PIPE_A_EVENT_INTERRUPT (1<<6) | ||
403 | #define I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT (1<<5) | ||
404 | #define I915_DISPLAY_PIPE_B_EVENT_INTERRUPT (1<<4) | ||
405 | #define I915_DEBUG_INTERRUPT (1<<2) | ||
406 | #define I915_USER_INTERRUPT (1<<1) | ||
407 | |||
408 | 388 | ||
409 | #define I915REG_HWSTAM 0x02098 | 389 | #define I915REG_HWSTAM 0x02098 |
410 | #define I915REG_INT_IDENTITY_R 0x020a4 | 390 | #define I915REG_INT_IDENTITY_R 0x020a4 |
411 | #define I915REG_INT_MASK_R 0x020a8 | 391 | #define I915REG_INT_MASK_R 0x020a8 |
412 | #define I915REG_INT_ENABLE_R 0x020a0 | 392 | #define I915REG_INT_ENABLE_R 0x020a0 |
413 | #define I915REG_INSTPM 0x020c0 | ||
414 | |||
415 | #define PIPEADSL 0x70000 | ||
416 | #define PIPEBDSL 0x71000 | ||
417 | 393 | ||
418 | #define I915REG_PIPEASTAT 0x70024 | 394 | #define I915REG_PIPEASTAT 0x70024 |
419 | #define I915REG_PIPEBSTAT 0x71024 | 395 | #define I915REG_PIPEBSTAT 0x71024 |
420 | /* | ||
421 | * The two pipe frame counter registers are not synchronized, so | ||
422 | * reading a stable value is somewhat tricky. The following code | ||
423 | * should work: | ||
424 | * | ||
425 | * do { | ||
426 | * high1 = ((INREG(PIPEAFRAMEHIGH) & PIPE_FRAME_HIGH_MASK) >> | ||
427 | * PIPE_FRAME_HIGH_SHIFT; | ||
428 | * low1 = ((INREG(PIPEAFRAMEPIXEL) & PIPE_FRAME_LOW_MASK) >> | ||
429 | * PIPE_FRAME_LOW_SHIFT); | ||
430 | * high2 = ((INREG(PIPEAFRAMEHIGH) & PIPE_FRAME_HIGH_MASK) >> | ||
431 | * PIPE_FRAME_HIGH_SHIFT); | ||
432 | * } while (high1 != high2); | ||
433 | * frame = (high1 << 8) | low1; | ||
434 | */ | ||
435 | #define PIPEAFRAMEHIGH 0x70040 | ||
436 | #define PIPEBFRAMEHIGH 0x71040 | ||
437 | #define PIPE_FRAME_HIGH_MASK 0x0000ffff | ||
438 | #define PIPE_FRAME_HIGH_SHIFT 0 | ||
439 | #define PIPEAFRAMEPIXEL 0x70044 | ||
440 | #define PIPEBFRAMEPIXEL 0x71044 | ||
441 | 396 | ||
442 | #define PIPE_FRAME_LOW_MASK 0xff000000 | 397 | #define I915_VBLANK_INTERRUPT_ENABLE (1UL<<17) |
443 | #define PIPE_FRAME_LOW_SHIFT 24 | 398 | #define I915_VBLANK_CLEAR (1UL<<1) |
444 | /* | ||
445 | * Pixel within the current frame is counted in the PIPEAFRAMEPIXEL register | ||
446 | * and is 24 bits wide. | ||
447 | */ | ||
448 | #define PIPE_PIXEL_MASK 0x00ffffff | ||
449 | #define PIPE_PIXEL_SHIFT 0 | ||
450 | |||
451 | #define I915_FIFO_UNDERRUN_STATUS (1UL<<31) | ||
452 | #define I915_CRC_ERROR_ENABLE (1UL<<29) | ||
453 | #define I915_CRC_DONE_ENABLE (1UL<<28) | ||
454 | #define I915_GMBUS_EVENT_ENABLE (1UL<<27) | ||
455 | #define I915_VSYNC_INTERRUPT_ENABLE (1UL<<25) | ||
456 | #define I915_DISPLAY_LINE_COMPARE_ENABLE (1UL<<24) | ||
457 | #define I915_DPST_EVENT_ENABLE (1UL<<23) | ||
458 | #define I915_LEGACY_BLC_EVENT_ENABLE (1UL<<22) | ||
459 | #define I915_ODD_FIELD_INTERRUPT_ENABLE (1UL<<21) | ||
460 | #define I915_EVEN_FIELD_INTERRUPT_ENABLE (1UL<<20) | ||
461 | #define I915_START_VBLANK_INTERRUPT_ENABLE (1UL<<18) /* 965 or later */ | ||
462 | #define I915_VBLANK_INTERRUPT_ENABLE (1UL<<17) | ||
463 | #define I915_OVERLAY_UPDATED_ENABLE (1UL<<16) | ||
464 | #define I915_CRC_ERROR_INTERRUPT_STATUS (1UL<<13) | ||
465 | #define I915_CRC_DONE_INTERRUPT_STATUS (1UL<<12) | ||
466 | #define I915_GMBUS_INTERRUPT_STATUS (1UL<<11) | ||
467 | #define I915_VSYNC_INTERRUPT_STATUS (1UL<<9) | ||
468 | #define I915_DISPLAY_LINE_COMPARE_STATUS (1UL<<8) | ||
469 | #define I915_DPST_EVENT_STATUS (1UL<<7) | ||
470 | #define I915_LEGACY_BLC_EVENT_STATUS (1UL<<6) | ||
471 | #define I915_ODD_FIELD_INTERRUPT_STATUS (1UL<<5) | ||
472 | #define I915_EVEN_FIELD_INTERRUPT_STATUS (1UL<<4) | ||
473 | #define I915_START_VBLANK_INTERRUPT_STATUS (1UL<<2) /* 965 or later */ | ||
474 | #define I915_VBLANK_INTERRUPT_STATUS (1UL<<1) | ||
475 | #define I915_OVERLAY_UPDATED_STATUS (1UL<<0) | ||
476 | 399 | ||
477 | #define SRX_INDEX 0x3c4 | 400 | #define SRX_INDEX 0x3c4 |
478 | #define SRX_DATA 0x3c5 | 401 | #define SRX_DATA 0x3c5 |
@@ -749,6 +672,8 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); | |||
749 | /** P1 value is 2 greater than this field */ | 672 | /** P1 value is 2 greater than this field */ |
750 | # define VGA0_PD_P1_MASK (0x1f << 0) | 673 | # define VGA0_PD_P1_MASK (0x1f << 0) |
751 | 674 | ||
675 | /* PCI D state control register */ | ||
676 | #define D_STATE 0x6104 | ||
752 | #define DSPCLK_GATE_D 0x6200 | 677 | #define DSPCLK_GATE_D 0x6200 |
753 | 678 | ||
754 | /* I830 CRTC registers */ | 679 | /* I830 CRTC registers */ |
@@ -1059,6 +984,12 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); | |||
1059 | #define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21) | 984 | #define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21) |
1060 | #define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21) | 985 | #define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21) |
1061 | 986 | ||
987 | #define DSPARB 0x70030 | ||
988 | #define DSPARB_CSTART_MASK (0x7f << 7) | ||
989 | #define DSPARB_CSTART_SHIFT 7 | ||
990 | #define DSPARB_BSTART_MASK (0x7f) | ||
991 | #define DSPARB_BSTART_SHIFT 0 | ||
992 | |||
1062 | #define PIPEBCONF 0x71008 | 993 | #define PIPEBCONF 0x71008 |
1063 | #define PIPEBCONF_ENABLE (1<<31) | 994 | #define PIPEBCONF_ENABLE (1<<31) |
1064 | #define PIPEBCONF_DISABLE 0 | 995 | #define PIPEBCONF_DISABLE 0 |
diff --git a/drivers/char/drm/i915_irq.c b/drivers/char/drm/i915_irq.c index 023ce66ef3ab..f7f16e7a8bf3 100644 --- a/drivers/char/drm/i915_irq.c +++ b/drivers/char/drm/i915_irq.c | |||
@@ -38,109 +38,6 @@ | |||
38 | #define MAX_NOPID ((u32)~0) | 38 | #define MAX_NOPID ((u32)~0) |
39 | 39 | ||
40 | /** | 40 | /** |
41 | * i915_get_pipe - return the the pipe associated with a given plane | ||
42 | * @dev: DRM device | ||
43 | * @plane: plane to look for | ||
44 | * | ||
45 | * The Intel Mesa & 2D drivers call the vblank routines with a plane number | ||
46 | * rather than a pipe number, since they may not always be equal. This routine | ||
47 | * maps the given @plane back to a pipe number. | ||
48 | */ | ||
49 | static int | ||
50 | i915_get_pipe(struct drm_device *dev, int plane) | ||
51 | { | ||
52 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | ||
53 | u32 dspcntr; | ||
54 | |||
55 | dspcntr = plane ? I915_READ(DSPBCNTR) : I915_READ(DSPACNTR); | ||
56 | |||
57 | return dspcntr & DISPPLANE_SEL_PIPE_MASK ? 1 : 0; | ||
58 | } | ||
59 | |||
60 | /** | ||
61 | * i915_get_plane - return the the plane associated with a given pipe | ||
62 | * @dev: DRM device | ||
63 | * @pipe: pipe to look for | ||
64 | * | ||
65 | * The Intel Mesa & 2D drivers call the vblank routines with a plane number | ||
66 | * rather than a plane number, since they may not always be equal. This routine | ||
67 | * maps the given @pipe back to a plane number. | ||
68 | */ | ||
69 | static int | ||
70 | i915_get_plane(struct drm_device *dev, int pipe) | ||
71 | { | ||
72 | if (i915_get_pipe(dev, 0) == pipe) | ||
73 | return 0; | ||
74 | return 1; | ||
75 | } | ||
76 | |||
77 | /** | ||
78 | * i915_pipe_enabled - check if a pipe is enabled | ||
79 | * @dev: DRM device | ||
80 | * @pipe: pipe to check | ||
81 | * | ||
82 | * Reading certain registers when the pipe is disabled can hang the chip. | ||
83 | * Use this routine to make sure the PLL is running and the pipe is active | ||
84 | * before reading such registers if unsure. | ||
85 | */ | ||
86 | static int | ||
87 | i915_pipe_enabled(struct drm_device *dev, int pipe) | ||
88 | { | ||
89 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | ||
90 | unsigned long pipeconf = pipe ? PIPEBCONF : PIPEACONF; | ||
91 | |||
92 | if (I915_READ(pipeconf) & PIPEACONF_ENABLE) | ||
93 | return 1; | ||
94 | |||
95 | return 0; | ||
96 | } | ||
97 | |||
98 | /** | ||
99 | * Emit a synchronous flip. | ||
100 | * | ||
101 | * This function must be called with the drawable spinlock held. | ||
102 | */ | ||
103 | static void | ||
104 | i915_dispatch_vsync_flip(struct drm_device *dev, struct drm_drawable_info *drw, | ||
105 | int plane) | ||
106 | { | ||
107 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | ||
108 | drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv; | ||
109 | u16 x1, y1, x2, y2; | ||
110 | int pf_planes = 1 << plane; | ||
111 | |||
112 | /* If the window is visible on the other plane, we have to flip on that | ||
113 | * plane as well. | ||
114 | */ | ||
115 | if (plane == 1) { | ||
116 | x1 = sarea_priv->planeA_x; | ||
117 | y1 = sarea_priv->planeA_y; | ||
118 | x2 = x1 + sarea_priv->planeA_w; | ||
119 | y2 = y1 + sarea_priv->planeA_h; | ||
120 | } else { | ||
121 | x1 = sarea_priv->planeB_x; | ||
122 | y1 = sarea_priv->planeB_y; | ||
123 | x2 = x1 + sarea_priv->planeB_w; | ||
124 | y2 = y1 + sarea_priv->planeB_h; | ||
125 | } | ||
126 | |||
127 | if (x2 > 0 && y2 > 0) { | ||
128 | int i, num_rects = drw->num_rects; | ||
129 | struct drm_clip_rect *rect = drw->rects; | ||
130 | |||
131 | for (i = 0; i < num_rects; i++) | ||
132 | if (!(rect[i].x1 >= x2 || rect[i].y1 >= y2 || | ||
133 | rect[i].x2 <= x1 || rect[i].y2 <= y1)) { | ||
134 | pf_planes = 0x3; | ||
135 | |||
136 | break; | ||
137 | } | ||
138 | } | ||
139 | |||
140 | i915_dispatch_flip(dev, pf_planes, 1); | ||
141 | } | ||
142 | |||
143 | /** | ||
144 | * Emit blits for scheduled buffer swaps. | 41 | * Emit blits for scheduled buffer swaps. |
145 | * | 42 | * |
146 | * This function will be called with the HW lock held. | 43 | * This function will be called with the HW lock held. |
@@ -148,19 +45,20 @@ i915_dispatch_vsync_flip(struct drm_device *dev, struct drm_drawable_info *drw, | |||
148 | static void i915_vblank_tasklet(struct drm_device *dev) | 45 | static void i915_vblank_tasklet(struct drm_device *dev) |
149 | { | 46 | { |
150 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 47 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
48 | unsigned long irqflags; | ||
151 | struct list_head *list, *tmp, hits, *hit; | 49 | struct list_head *list, *tmp, hits, *hit; |
152 | int nhits, nrects, slice[2], upper[2], lower[2], i, num_pages; | 50 | int nhits, nrects, slice[2], upper[2], lower[2], i; |
153 | unsigned counter[2]; | 51 | unsigned counter[2] = { atomic_read(&dev->vbl_received), |
52 | atomic_read(&dev->vbl_received2) }; | ||
154 | struct drm_drawable_info *drw; | 53 | struct drm_drawable_info *drw; |
155 | drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv; | 54 | drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv; |
156 | u32 cpp = dev_priv->cpp, offsets[3]; | 55 | u32 cpp = dev_priv->cpp; |
157 | u32 cmd = (cpp == 4) ? (XY_SRC_COPY_BLT_CMD | | 56 | u32 cmd = (cpp == 4) ? (XY_SRC_COPY_BLT_CMD | |
158 | XY_SRC_COPY_BLT_WRITE_ALPHA | | 57 | XY_SRC_COPY_BLT_WRITE_ALPHA | |
159 | XY_SRC_COPY_BLT_WRITE_RGB) | 58 | XY_SRC_COPY_BLT_WRITE_RGB) |
160 | : XY_SRC_COPY_BLT_CMD; | 59 | : XY_SRC_COPY_BLT_CMD; |
161 | u32 src_pitch = sarea_priv->pitch * cpp; | 60 | u32 src_pitch = sarea_priv->pitch * cpp; |
162 | u32 dst_pitch = sarea_priv->pitch * cpp; | 61 | u32 dst_pitch = sarea_priv->pitch * cpp; |
163 | /* COPY rop (0xcc), map cpp to magic color depth constants */ | ||
164 | u32 ropcpp = (0xcc << 16) | ((cpp - 1) << 24); | 62 | u32 ropcpp = (0xcc << 16) | ((cpp - 1) << 24); |
165 | RING_LOCALS; | 63 | RING_LOCALS; |
166 | 64 | ||
@@ -173,34 +71,24 @@ static void i915_vblank_tasklet(struct drm_device *dev) | |||
173 | src_pitch >>= 2; | 71 | src_pitch >>= 2; |
174 | } | 72 | } |
175 | 73 | ||
176 | counter[0] = drm_vblank_count(dev, 0); | ||
177 | counter[1] = drm_vblank_count(dev, 1); | ||
178 | |||
179 | DRM_DEBUG("\n"); | 74 | DRM_DEBUG("\n"); |
180 | 75 | ||
181 | INIT_LIST_HEAD(&hits); | 76 | INIT_LIST_HEAD(&hits); |
182 | 77 | ||
183 | nhits = nrects = 0; | 78 | nhits = nrects = 0; |
184 | 79 | ||
185 | /* No irqsave/restore necessary. This tasklet may be run in an | 80 | spin_lock_irqsave(&dev_priv->swaps_lock, irqflags); |
186 | * interrupt context or normal context, but we don't have to worry | ||
187 | * about getting interrupted by something acquiring the lock, because | ||
188 | * we are the interrupt context thing that acquires the lock. | ||
189 | */ | ||
190 | spin_lock(&dev_priv->swaps_lock); | ||
191 | 81 | ||
192 | /* Find buffer swaps scheduled for this vertical blank */ | 82 | /* Find buffer swaps scheduled for this vertical blank */ |
193 | list_for_each_safe(list, tmp, &dev_priv->vbl_swaps.head) { | 83 | list_for_each_safe(list, tmp, &dev_priv->vbl_swaps.head) { |
194 | drm_i915_vbl_swap_t *vbl_swap = | 84 | drm_i915_vbl_swap_t *vbl_swap = |
195 | list_entry(list, drm_i915_vbl_swap_t, head); | 85 | list_entry(list, drm_i915_vbl_swap_t, head); |
196 | int pipe = i915_get_pipe(dev, vbl_swap->plane); | ||
197 | 86 | ||
198 | if ((counter[pipe] - vbl_swap->sequence) > (1<<23)) | 87 | if ((counter[vbl_swap->pipe] - vbl_swap->sequence) > (1<<23)) |
199 | continue; | 88 | continue; |
200 | 89 | ||
201 | list_del(list); | 90 | list_del(list); |
202 | dev_priv->swaps_pending--; | 91 | dev_priv->swaps_pending--; |
203 | drm_vblank_put(dev, pipe); | ||
204 | 92 | ||
205 | spin_unlock(&dev_priv->swaps_lock); | 93 | spin_unlock(&dev_priv->swaps_lock); |
206 | spin_lock(&dev->drw_lock); | 94 | spin_lock(&dev->drw_lock); |
@@ -238,23 +126,43 @@ static void i915_vblank_tasklet(struct drm_device *dev) | |||
238 | spin_lock(&dev_priv->swaps_lock); | 126 | spin_lock(&dev_priv->swaps_lock); |
239 | } | 127 | } |
240 | 128 | ||
241 | spin_unlock(&dev_priv->swaps_lock); | 129 | if (nhits == 0) { |
242 | 130 | spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags); | |
243 | if (nhits == 0) | ||
244 | return; | 131 | return; |
132 | } | ||
133 | |||
134 | spin_unlock(&dev_priv->swaps_lock); | ||
245 | 135 | ||
246 | i915_kernel_lost_context(dev); | 136 | i915_kernel_lost_context(dev); |
247 | 137 | ||
248 | upper[0] = upper[1] = 0; | 138 | if (IS_I965G(dev)) { |
249 | slice[0] = max(sarea_priv->planeA_h / nhits, 1); | 139 | BEGIN_LP_RING(4); |
250 | slice[1] = max(sarea_priv->planeB_h / nhits, 1); | 140 | |
251 | lower[0] = sarea_priv->planeA_y + slice[0]; | 141 | OUT_RING(GFX_OP_DRAWRECT_INFO_I965); |
252 | lower[1] = sarea_priv->planeB_y + slice[0]; | 142 | OUT_RING(0); |
143 | OUT_RING(((sarea_priv->width - 1) & 0xffff) | ((sarea_priv->height - 1) << 16)); | ||
144 | OUT_RING(0); | ||
145 | ADVANCE_LP_RING(); | ||
146 | } else { | ||
147 | BEGIN_LP_RING(6); | ||
253 | 148 | ||
254 | offsets[0] = sarea_priv->front_offset; | 149 | OUT_RING(GFX_OP_DRAWRECT_INFO); |
255 | offsets[1] = sarea_priv->back_offset; | 150 | OUT_RING(0); |
256 | offsets[2] = sarea_priv->third_offset; | 151 | OUT_RING(0); |
257 | num_pages = sarea_priv->third_handle ? 3 : 2; | 152 | OUT_RING(sarea_priv->width | sarea_priv->height << 16); |
153 | OUT_RING(sarea_priv->width | sarea_priv->height << 16); | ||
154 | OUT_RING(0); | ||
155 | |||
156 | ADVANCE_LP_RING(); | ||
157 | } | ||
158 | |||
159 | sarea_priv->ctxOwner = DRM_KERNEL_CONTEXT; | ||
160 | |||
161 | upper[0] = upper[1] = 0; | ||
162 | slice[0] = max(sarea_priv->pipeA_h / nhits, 1); | ||
163 | slice[1] = max(sarea_priv->pipeB_h / nhits, 1); | ||
164 | lower[0] = sarea_priv->pipeA_y + slice[0]; | ||
165 | lower[1] = sarea_priv->pipeB_y + slice[0]; | ||
258 | 166 | ||
259 | spin_lock(&dev->drw_lock); | 167 | spin_lock(&dev->drw_lock); |
260 | 168 | ||
@@ -266,8 +174,6 @@ static void i915_vblank_tasklet(struct drm_device *dev) | |||
266 | for (i = 0; i++ < nhits; | 174 | for (i = 0; i++ < nhits; |
267 | upper[0] = lower[0], lower[0] += slice[0], | 175 | upper[0] = lower[0], lower[0] += slice[0], |
268 | upper[1] = lower[1], lower[1] += slice[1]) { | 176 | upper[1] = lower[1], lower[1] += slice[1]) { |
269 | int init_drawrect = 1; | ||
270 | |||
271 | if (i == nhits) | 177 | if (i == nhits) |
272 | lower[0] = lower[1] = sarea_priv->height; | 178 | lower[0] = lower[1] = sarea_priv->height; |
273 | 179 | ||
@@ -275,7 +181,7 @@ static void i915_vblank_tasklet(struct drm_device *dev) | |||
275 | drm_i915_vbl_swap_t *swap_hit = | 181 | drm_i915_vbl_swap_t *swap_hit = |
276 | list_entry(hit, drm_i915_vbl_swap_t, head); | 182 | list_entry(hit, drm_i915_vbl_swap_t, head); |
277 | struct drm_clip_rect *rect; | 183 | struct drm_clip_rect *rect; |
278 | int num_rects, plane, front, back; | 184 | int num_rects, pipe; |
279 | unsigned short top, bottom; | 185 | unsigned short top, bottom; |
280 | 186 | ||
281 | drw = drm_get_drawable_info(dev, swap_hit->drw_id); | 187 | drw = drm_get_drawable_info(dev, swap_hit->drw_id); |
@@ -283,50 +189,10 @@ static void i915_vblank_tasklet(struct drm_device *dev) | |||
283 | if (!drw) | 189 | if (!drw) |
284 | continue; | 190 | continue; |
285 | 191 | ||
286 | plane = swap_hit->plane; | ||
287 | |||
288 | if (swap_hit->flip) { | ||
289 | i915_dispatch_vsync_flip(dev, drw, plane); | ||
290 | continue; | ||
291 | } | ||
292 | |||
293 | if (init_drawrect) { | ||
294 | int width = sarea_priv->width; | ||
295 | int height = sarea_priv->height; | ||
296 | if (IS_I965G(dev)) { | ||
297 | BEGIN_LP_RING(4); | ||
298 | |||
299 | OUT_RING(GFX_OP_DRAWRECT_INFO_I965); | ||
300 | OUT_RING(0); | ||
301 | OUT_RING(((width - 1) & 0xffff) | ((height - 1) << 16)); | ||
302 | OUT_RING(0); | ||
303 | |||
304 | ADVANCE_LP_RING(); | ||
305 | } else { | ||
306 | BEGIN_LP_RING(6); | ||
307 | |||
308 | OUT_RING(GFX_OP_DRAWRECT_INFO); | ||
309 | OUT_RING(0); | ||
310 | OUT_RING(0); | ||
311 | OUT_RING(((width - 1) & 0xffff) | ((height - 1) << 16)); | ||
312 | OUT_RING(0); | ||
313 | OUT_RING(0); | ||
314 | |||
315 | ADVANCE_LP_RING(); | ||
316 | } | ||
317 | |||
318 | sarea_priv->ctxOwner = DRM_KERNEL_CONTEXT; | ||
319 | |||
320 | init_drawrect = 0; | ||
321 | } | ||
322 | |||
323 | rect = drw->rects; | 192 | rect = drw->rects; |
324 | top = upper[plane]; | 193 | pipe = swap_hit->pipe; |
325 | bottom = lower[plane]; | 194 | top = upper[pipe]; |
326 | 195 | bottom = lower[pipe]; | |
327 | front = (dev_priv->sarea_priv->pf_current_page >> | ||
328 | (2 * plane)) & 0x3; | ||
329 | back = (front + 1) % num_pages; | ||
330 | 196 | ||
331 | for (num_rects = drw->num_rects; num_rects--; rect++) { | 197 | for (num_rects = drw->num_rects; num_rects--; rect++) { |
332 | int y1 = max(rect->y1, top); | 198 | int y1 = max(rect->y1, top); |
@@ -341,17 +207,17 @@ static void i915_vblank_tasklet(struct drm_device *dev) | |||
341 | OUT_RING(ropcpp | dst_pitch); | 207 | OUT_RING(ropcpp | dst_pitch); |
342 | OUT_RING((y1 << 16) | rect->x1); | 208 | OUT_RING((y1 << 16) | rect->x1); |
343 | OUT_RING((y2 << 16) | rect->x2); | 209 | OUT_RING((y2 << 16) | rect->x2); |
344 | OUT_RING(offsets[front]); | 210 | OUT_RING(sarea_priv->front_offset); |
345 | OUT_RING((y1 << 16) | rect->x1); | 211 | OUT_RING((y1 << 16) | rect->x1); |
346 | OUT_RING(src_pitch); | 212 | OUT_RING(src_pitch); |
347 | OUT_RING(offsets[back]); | 213 | OUT_RING(sarea_priv->back_offset); |
348 | 214 | ||
349 | ADVANCE_LP_RING(); | 215 | ADVANCE_LP_RING(); |
350 | } | 216 | } |
351 | } | 217 | } |
352 | } | 218 | } |
353 | 219 | ||
354 | spin_unlock(&dev->drw_lock); | 220 | spin_unlock_irqrestore(&dev->drw_lock, irqflags); |
355 | 221 | ||
356 | list_for_each_safe(hit, tmp, &hits) { | 222 | list_for_each_safe(hit, tmp, &hits) { |
357 | drm_i915_vbl_swap_t *swap_hit = | 223 | drm_i915_vbl_swap_t *swap_hit = |
@@ -363,112 +229,67 @@ static void i915_vblank_tasklet(struct drm_device *dev) | |||
363 | } | 229 | } |
364 | } | 230 | } |
365 | 231 | ||
366 | u32 i915_get_vblank_counter(struct drm_device *dev, int plane) | ||
367 | { | ||
368 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | ||
369 | unsigned long high_frame; | ||
370 | unsigned long low_frame; | ||
371 | u32 high1, high2, low, count; | ||
372 | int pipe; | ||
373 | |||
374 | pipe = i915_get_pipe(dev, plane); | ||
375 | high_frame = pipe ? PIPEBFRAMEHIGH : PIPEAFRAMEHIGH; | ||
376 | low_frame = pipe ? PIPEBFRAMEPIXEL : PIPEAFRAMEPIXEL; | ||
377 | |||
378 | if (!i915_pipe_enabled(dev, pipe)) { | ||
379 | printk(KERN_ERR "trying to get vblank count for disabled " | ||
380 | "pipe %d\n", pipe); | ||
381 | return 0; | ||
382 | } | ||
383 | |||
384 | /* | ||
385 | * High & low register fields aren't synchronized, so make sure | ||
386 | * we get a low value that's stable across two reads of the high | ||
387 | * register. | ||
388 | */ | ||
389 | do { | ||
390 | high1 = ((I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >> | ||
391 | PIPE_FRAME_HIGH_SHIFT); | ||
392 | low = ((I915_READ(low_frame) & PIPE_FRAME_LOW_MASK) >> | ||
393 | PIPE_FRAME_LOW_SHIFT); | ||
394 | high2 = ((I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >> | ||
395 | PIPE_FRAME_HIGH_SHIFT); | ||
396 | } while (high1 != high2); | ||
397 | |||
398 | count = (high1 << 8) | low; | ||
399 | |||
400 | /* count may be reset by other driver(e.g. 2D driver), | ||
401 | we have no way to know if it is wrapped or resetted | ||
402 | when count is zero. do a rough guess. | ||
403 | */ | ||
404 | if (count == 0 && dev->last_vblank[pipe] < dev->max_vblank_count/2) | ||
405 | dev->last_vblank[pipe] = 0; | ||
406 | |||
407 | return count; | ||
408 | } | ||
409 | |||
410 | irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | 232 | irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) |
411 | { | 233 | { |
412 | struct drm_device *dev = (struct drm_device *) arg; | 234 | struct drm_device *dev = (struct drm_device *) arg; |
413 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 235 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
414 | u32 iir; | 236 | u16 temp; |
415 | u32 pipea_stats, pipeb_stats; | 237 | u32 pipea_stats, pipeb_stats; |
416 | int vblank = 0; | ||
417 | |||
418 | iir = I915_READ(I915REG_INT_IDENTITY_R); | ||
419 | if (iir == 0) { | ||
420 | DRM_DEBUG ("iir 0x%08x im 0x%08x ie 0x%08x pipea 0x%08x pipeb 0x%08x\n", | ||
421 | iir, | ||
422 | I915_READ(I915REG_INT_MASK_R), | ||
423 | I915_READ(I915REG_INT_ENABLE_R), | ||
424 | I915_READ(I915REG_PIPEASTAT), | ||
425 | I915_READ(I915REG_PIPEBSTAT)); | ||
426 | return IRQ_NONE; | ||
427 | } | ||
428 | 238 | ||
429 | /* | 239 | pipea_stats = I915_READ(I915REG_PIPEASTAT); |
430 | * Clear the PIPE(A|B)STAT regs before the IIR otherwise | 240 | pipeb_stats = I915_READ(I915REG_PIPEBSTAT); |
431 | * we may get extra interrupts. | ||
432 | */ | ||
433 | if (iir & I915_DISPLAY_PIPE_A_EVENT_INTERRUPT) { | ||
434 | pipea_stats = I915_READ(I915REG_PIPEASTAT); | ||
435 | if (pipea_stats & (I915_START_VBLANK_INTERRUPT_STATUS| | ||
436 | I915_VBLANK_INTERRUPT_STATUS)) | ||
437 | { | ||
438 | vblank++; | ||
439 | drm_handle_vblank(dev, i915_get_plane(dev, 0)); | ||
440 | } | ||
441 | I915_WRITE(I915REG_PIPEASTAT, pipea_stats); | ||
442 | } | ||
443 | if (iir & I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) { | ||
444 | pipeb_stats = I915_READ(I915REG_PIPEBSTAT); | ||
445 | if (pipeb_stats & (I915_START_VBLANK_INTERRUPT_STATUS| | ||
446 | I915_VBLANK_INTERRUPT_STATUS)) | ||
447 | { | ||
448 | vblank++; | ||
449 | drm_handle_vblank(dev, i915_get_plane(dev, 1)); | ||
450 | } | ||
451 | I915_WRITE(I915REG_PIPEBSTAT, pipeb_stats); | ||
452 | } | ||
453 | 241 | ||
454 | if (dev_priv->sarea_priv) | 242 | temp = I915_READ16(I915REG_INT_IDENTITY_R); |
455 | dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); | ||
456 | 243 | ||
457 | I915_WRITE(I915REG_INT_IDENTITY_R, iir); | 244 | temp &= (USER_INT_FLAG | VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG); |
458 | (void) I915_READ(I915REG_INT_IDENTITY_R); /* Flush posted write */ | ||
459 | 245 | ||
460 | if (iir & I915_USER_INTERRUPT) { | 246 | DRM_DEBUG("%s flag=%08x\n", __FUNCTION__, temp); |
247 | |||
248 | if (temp == 0) | ||
249 | return IRQ_NONE; | ||
250 | |||
251 | I915_WRITE16(I915REG_INT_IDENTITY_R, temp); | ||
252 | (void) I915_READ16(I915REG_INT_IDENTITY_R); | ||
253 | DRM_READMEMORYBARRIER(); | ||
254 | |||
255 | dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); | ||
256 | |||
257 | if (temp & USER_INT_FLAG) | ||
461 | DRM_WAKEUP(&dev_priv->irq_queue); | 258 | DRM_WAKEUP(&dev_priv->irq_queue); |
462 | } | 259 | |
463 | if (vblank) { | 260 | if (temp & (VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG)) { |
261 | int vblank_pipe = dev_priv->vblank_pipe; | ||
262 | |||
263 | if ((vblank_pipe & | ||
264 | (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B)) | ||
265 | == (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B)) { | ||
266 | if (temp & VSYNC_PIPEA_FLAG) | ||
267 | atomic_inc(&dev->vbl_received); | ||
268 | if (temp & VSYNC_PIPEB_FLAG) | ||
269 | atomic_inc(&dev->vbl_received2); | ||
270 | } else if (((temp & VSYNC_PIPEA_FLAG) && | ||
271 | (vblank_pipe & DRM_I915_VBLANK_PIPE_A)) || | ||
272 | ((temp & VSYNC_PIPEB_FLAG) && | ||
273 | (vblank_pipe & DRM_I915_VBLANK_PIPE_B))) | ||
274 | atomic_inc(&dev->vbl_received); | ||
275 | |||
276 | DRM_WAKEUP(&dev->vbl_queue); | ||
277 | drm_vbl_send_signals(dev); | ||
278 | |||
464 | if (dev_priv->swaps_pending > 0) | 279 | if (dev_priv->swaps_pending > 0) |
465 | drm_locked_tasklet(dev, i915_vblank_tasklet); | 280 | drm_locked_tasklet(dev, i915_vblank_tasklet); |
281 | I915_WRITE(I915REG_PIPEASTAT, | ||
282 | pipea_stats|I915_VBLANK_INTERRUPT_ENABLE| | ||
283 | I915_VBLANK_CLEAR); | ||
284 | I915_WRITE(I915REG_PIPEBSTAT, | ||
285 | pipeb_stats|I915_VBLANK_INTERRUPT_ENABLE| | ||
286 | I915_VBLANK_CLEAR); | ||
466 | } | 287 | } |
467 | 288 | ||
468 | return IRQ_HANDLED; | 289 | return IRQ_HANDLED; |
469 | } | 290 | } |
470 | 291 | ||
471 | static int i915_emit_irq(struct drm_device *dev) | 292 | static int i915_emit_irq(struct drm_device * dev) |
472 | { | 293 | { |
473 | drm_i915_private_t *dev_priv = dev->dev_private; | 294 | drm_i915_private_t *dev_priv = dev->dev_private; |
474 | RING_LOCALS; | 295 | RING_LOCALS; |
@@ -515,12 +336,42 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr) | |||
515 | READ_BREADCRUMB(dev_priv), (int)dev_priv->counter); | 336 | READ_BREADCRUMB(dev_priv), (int)dev_priv->counter); |
516 | } | 337 | } |
517 | 338 | ||
518 | if (dev_priv->sarea_priv) | 339 | dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); |
519 | dev_priv->sarea_priv->last_dispatch = | ||
520 | READ_BREADCRUMB(dev_priv); | ||
521 | return ret; | 340 | return ret; |
522 | } | 341 | } |
523 | 342 | ||
343 | static int i915_driver_vblank_do_wait(struct drm_device *dev, unsigned int *sequence, | ||
344 | atomic_t *counter) | ||
345 | { | ||
346 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
347 | unsigned int cur_vblank; | ||
348 | int ret = 0; | ||
349 | |||
350 | if (!dev_priv) { | ||
351 | DRM_ERROR("called with no initialization\n"); | ||
352 | return -EINVAL; | ||
353 | } | ||
354 | |||
355 | DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, | ||
356 | (((cur_vblank = atomic_read(counter)) | ||
357 | - *sequence) <= (1<<23))); | ||
358 | |||
359 | *sequence = cur_vblank; | ||
360 | |||
361 | return ret; | ||
362 | } | ||
363 | |||
364 | |||
365 | int i915_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence) | ||
366 | { | ||
367 | return i915_driver_vblank_do_wait(dev, sequence, &dev->vbl_received); | ||
368 | } | ||
369 | |||
370 | int i915_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence) | ||
371 | { | ||
372 | return i915_driver_vblank_do_wait(dev, sequence, &dev->vbl_received2); | ||
373 | } | ||
374 | |||
524 | /* Needs the lock as it touches the ring. | 375 | /* Needs the lock as it touches the ring. |
525 | */ | 376 | */ |
526 | int i915_irq_emit(struct drm_device *dev, void *data, | 377 | int i915_irq_emit(struct drm_device *dev, void *data, |
@@ -563,96 +414,18 @@ int i915_irq_wait(struct drm_device *dev, void *data, | |||
563 | return i915_wait_irq(dev, irqwait->irq_seq); | 414 | return i915_wait_irq(dev, irqwait->irq_seq); |
564 | } | 415 | } |
565 | 416 | ||
566 | int i915_enable_vblank(struct drm_device *dev, int plane) | ||
567 | { | ||
568 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | ||
569 | int pipe = i915_get_pipe(dev, plane); | ||
570 | u32 pipestat_reg = 0; | ||
571 | u32 pipestat; | ||
572 | |||
573 | switch (pipe) { | ||
574 | case 0: | ||
575 | pipestat_reg = I915REG_PIPEASTAT; | ||
576 | dev_priv->irq_enable_reg |= I915_DISPLAY_PIPE_A_EVENT_INTERRUPT; | ||
577 | break; | ||
578 | case 1: | ||
579 | pipestat_reg = I915REG_PIPEBSTAT; | ||
580 | dev_priv->irq_enable_reg |= I915_DISPLAY_PIPE_B_EVENT_INTERRUPT; | ||
581 | break; | ||
582 | default: | ||
583 | DRM_ERROR("tried to enable vblank on non-existent pipe %d\n", | ||
584 | pipe); | ||
585 | break; | ||
586 | } | ||
587 | |||
588 | if (pipestat_reg) | ||
589 | { | ||
590 | pipestat = I915_READ (pipestat_reg); | ||
591 | /* | ||
592 | * Older chips didn't have the start vblank interrupt, | ||
593 | * but | ||
594 | */ | ||
595 | if (IS_I965G (dev)) | ||
596 | pipestat |= I915_START_VBLANK_INTERRUPT_ENABLE; | ||
597 | else | ||
598 | pipestat |= I915_VBLANK_INTERRUPT_ENABLE; | ||
599 | /* | ||
600 | * Clear any pending status | ||
601 | */ | ||
602 | pipestat |= (I915_START_VBLANK_INTERRUPT_STATUS | | ||
603 | I915_VBLANK_INTERRUPT_STATUS); | ||
604 | I915_WRITE(pipestat_reg, pipestat); | ||
605 | } | ||
606 | I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); | ||
607 | |||
608 | return 0; | ||
609 | } | ||
610 | |||
611 | void i915_disable_vblank(struct drm_device *dev, int plane) | ||
612 | { | ||
613 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | ||
614 | int pipe = i915_get_pipe(dev, plane); | ||
615 | u32 pipestat_reg = 0; | ||
616 | u32 pipestat; | ||
617 | |||
618 | switch (pipe) { | ||
619 | case 0: | ||
620 | pipestat_reg = I915REG_PIPEASTAT; | ||
621 | dev_priv->irq_enable_reg &= ~I915_DISPLAY_PIPE_A_EVENT_INTERRUPT; | ||
622 | break; | ||
623 | case 1: | ||
624 | pipestat_reg = I915REG_PIPEBSTAT; | ||
625 | dev_priv->irq_enable_reg &= ~I915_DISPLAY_PIPE_B_EVENT_INTERRUPT; | ||
626 | break; | ||
627 | default: | ||
628 | DRM_ERROR("tried to disable vblank on non-existent pipe %d\n", | ||
629 | pipe); | ||
630 | break; | ||
631 | } | ||
632 | |||
633 | I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); | ||
634 | if (pipestat_reg) | ||
635 | { | ||
636 | pipestat = I915_READ (pipestat_reg); | ||
637 | pipestat &= ~(I915_START_VBLANK_INTERRUPT_ENABLE | | ||
638 | I915_VBLANK_INTERRUPT_ENABLE); | ||
639 | /* | ||
640 | * Clear any pending status | ||
641 | */ | ||
642 | pipestat |= (I915_START_VBLANK_INTERRUPT_STATUS | | ||
643 | I915_VBLANK_INTERRUPT_STATUS); | ||
644 | I915_WRITE(pipestat_reg, pipestat); | ||
645 | } | ||
646 | } | ||
647 | |||
648 | static void i915_enable_interrupt (struct drm_device *dev) | 417 | static void i915_enable_interrupt (struct drm_device *dev) |
649 | { | 418 | { |
650 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 419 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
420 | u16 flag; | ||
651 | 421 | ||
652 | dev_priv->irq_enable_reg |= I915_USER_INTERRUPT; | 422 | flag = 0; |
423 | if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A) | ||
424 | flag |= VSYNC_PIPEA_FLAG; | ||
425 | if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B) | ||
426 | flag |= VSYNC_PIPEB_FLAG; | ||
653 | 427 | ||
654 | I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); | 428 | I915_WRITE16(I915REG_INT_ENABLE_R, USER_INT_FLAG | flag); |
655 | dev_priv->irq_enabled = 1; | ||
656 | } | 429 | } |
657 | 430 | ||
658 | /* Set the vblank monitor pipe | 431 | /* Set the vblank monitor pipe |
@@ -675,6 +448,8 @@ int i915_vblank_pipe_set(struct drm_device *dev, void *data, | |||
675 | 448 | ||
676 | dev_priv->vblank_pipe = pipe->pipe; | 449 | dev_priv->vblank_pipe = pipe->pipe; |
677 | 450 | ||
451 | i915_enable_interrupt (dev); | ||
452 | |||
678 | return 0; | 453 | return 0; |
679 | } | 454 | } |
680 | 455 | ||
@@ -692,9 +467,9 @@ int i915_vblank_pipe_get(struct drm_device *dev, void *data, | |||
692 | 467 | ||
693 | flag = I915_READ(I915REG_INT_ENABLE_R); | 468 | flag = I915_READ(I915REG_INT_ENABLE_R); |
694 | pipe->pipe = 0; | 469 | pipe->pipe = 0; |
695 | if (flag & I915_DISPLAY_PIPE_A_EVENT_INTERRUPT) | 470 | if (flag & VSYNC_PIPEA_FLAG) |
696 | pipe->pipe |= DRM_I915_VBLANK_PIPE_A; | 471 | pipe->pipe |= DRM_I915_VBLANK_PIPE_A; |
697 | if (flag & I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) | 472 | if (flag & VSYNC_PIPEB_FLAG) |
698 | pipe->pipe |= DRM_I915_VBLANK_PIPE_B; | 473 | pipe->pipe |= DRM_I915_VBLANK_PIPE_B; |
699 | 474 | ||
700 | return 0; | 475 | return 0; |
@@ -709,30 +484,27 @@ int i915_vblank_swap(struct drm_device *dev, void *data, | |||
709 | drm_i915_private_t *dev_priv = dev->dev_private; | 484 | drm_i915_private_t *dev_priv = dev->dev_private; |
710 | drm_i915_vblank_swap_t *swap = data; | 485 | drm_i915_vblank_swap_t *swap = data; |
711 | drm_i915_vbl_swap_t *vbl_swap; | 486 | drm_i915_vbl_swap_t *vbl_swap; |
712 | unsigned int pipe, seqtype, curseq, plane; | 487 | unsigned int pipe, seqtype, curseq; |
713 | unsigned long irqflags; | 488 | unsigned long irqflags; |
714 | struct list_head *list; | 489 | struct list_head *list; |
715 | int ret; | ||
716 | 490 | ||
717 | if (!dev_priv) { | 491 | if (!dev_priv) { |
718 | DRM_ERROR("%s called with no initialization\n", __func__); | 492 | DRM_ERROR("%s called with no initialization\n", __func__); |
719 | return -EINVAL; | 493 | return -EINVAL; |
720 | } | 494 | } |
721 | 495 | ||
722 | if (!dev_priv->sarea_priv || dev_priv->sarea_priv->rotation) { | 496 | if (dev_priv->sarea_priv->rotation) { |
723 | DRM_DEBUG("Rotation not supported\n"); | 497 | DRM_DEBUG("Rotation not supported\n"); |
724 | return -EINVAL; | 498 | return -EINVAL; |
725 | } | 499 | } |
726 | 500 | ||
727 | if (swap->seqtype & ~(_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE | | 501 | if (swap->seqtype & ~(_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE | |
728 | _DRM_VBLANK_SECONDARY | _DRM_VBLANK_NEXTONMISS | | 502 | _DRM_VBLANK_SECONDARY | _DRM_VBLANK_NEXTONMISS)) { |
729 | _DRM_VBLANK_FLIP)) { | ||
730 | DRM_ERROR("Invalid sequence type 0x%x\n", swap->seqtype); | 503 | DRM_ERROR("Invalid sequence type 0x%x\n", swap->seqtype); |
731 | return -EINVAL; | 504 | return -EINVAL; |
732 | } | 505 | } |
733 | 506 | ||
734 | plane = (swap->seqtype & _DRM_VBLANK_SECONDARY) ? 1 : 0; | 507 | pipe = (swap->seqtype & _DRM_VBLANK_SECONDARY) ? 1 : 0; |
735 | pipe = i915_get_pipe(dev, plane); | ||
736 | 508 | ||
737 | seqtype = swap->seqtype & (_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE); | 509 | seqtype = swap->seqtype & (_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE); |
738 | 510 | ||
@@ -743,11 +515,6 @@ int i915_vblank_swap(struct drm_device *dev, void *data, | |||
743 | 515 | ||
744 | spin_lock_irqsave(&dev->drw_lock, irqflags); | 516 | spin_lock_irqsave(&dev->drw_lock, irqflags); |
745 | 517 | ||
746 | /* It makes no sense to schedule a swap for a drawable that doesn't have | ||
747 | * valid information at this point. E.g. this could mean that the X | ||
748 | * server is too old to push drawable information to the DRM, in which | ||
749 | * case all such swaps would become ineffective. | ||
750 | */ | ||
751 | if (!drm_get_drawable_info(dev, swap->drawable)) { | 518 | if (!drm_get_drawable_info(dev, swap->drawable)) { |
752 | spin_unlock_irqrestore(&dev->drw_lock, irqflags); | 519 | spin_unlock_irqrestore(&dev->drw_lock, irqflags); |
753 | DRM_DEBUG("Invalid drawable ID %d\n", swap->drawable); | 520 | DRM_DEBUG("Invalid drawable ID %d\n", swap->drawable); |
@@ -756,8 +523,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data, | |||
756 | 523 | ||
757 | spin_unlock_irqrestore(&dev->drw_lock, irqflags); | 524 | spin_unlock_irqrestore(&dev->drw_lock, irqflags); |
758 | 525 | ||
759 | drm_update_vblank_count(dev, pipe); | 526 | curseq = atomic_read(pipe ? &dev->vbl_received2 : &dev->vbl_received); |
760 | curseq = drm_vblank_count(dev, pipe); | ||
761 | 527 | ||
762 | if (seqtype == _DRM_VBLANK_RELATIVE) | 528 | if (seqtype == _DRM_VBLANK_RELATIVE) |
763 | swap->sequence += curseq; | 529 | swap->sequence += curseq; |
@@ -771,43 +537,14 @@ int i915_vblank_swap(struct drm_device *dev, void *data, | |||
771 | } | 537 | } |
772 | } | 538 | } |
773 | 539 | ||
774 | if (swap->seqtype & _DRM_VBLANK_FLIP) { | ||
775 | swap->sequence--; | ||
776 | |||
777 | if ((curseq - swap->sequence) <= (1<<23)) { | ||
778 | struct drm_drawable_info *drw; | ||
779 | |||
780 | LOCK_TEST_WITH_RETURN(dev, file_priv); | ||
781 | |||
782 | spin_lock_irqsave(&dev->drw_lock, irqflags); | ||
783 | |||
784 | drw = drm_get_drawable_info(dev, swap->drawable); | ||
785 | |||
786 | if (!drw) { | ||
787 | spin_unlock_irqrestore(&dev->drw_lock, | ||
788 | irqflags); | ||
789 | DRM_DEBUG("Invalid drawable ID %d\n", | ||
790 | swap->drawable); | ||
791 | return -EINVAL; | ||
792 | } | ||
793 | |||
794 | i915_dispatch_vsync_flip(dev, drw, plane); | ||
795 | |||
796 | spin_unlock_irqrestore(&dev->drw_lock, irqflags); | ||
797 | |||
798 | return 0; | ||
799 | } | ||
800 | } | ||
801 | |||
802 | spin_lock_irqsave(&dev_priv->swaps_lock, irqflags); | 540 | spin_lock_irqsave(&dev_priv->swaps_lock, irqflags); |
803 | 541 | ||
804 | list_for_each(list, &dev_priv->vbl_swaps.head) { | 542 | list_for_each(list, &dev_priv->vbl_swaps.head) { |
805 | vbl_swap = list_entry(list, drm_i915_vbl_swap_t, head); | 543 | vbl_swap = list_entry(list, drm_i915_vbl_swap_t, head); |
806 | 544 | ||
807 | if (vbl_swap->drw_id == swap->drawable && | 545 | if (vbl_swap->drw_id == swap->drawable && |
808 | vbl_swap->plane == plane && | 546 | vbl_swap->pipe == pipe && |
809 | vbl_swap->sequence == swap->sequence) { | 547 | vbl_swap->sequence == swap->sequence) { |
810 | vbl_swap->flip = (swap->seqtype & _DRM_VBLANK_FLIP); | ||
811 | spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags); | 548 | spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags); |
812 | DRM_DEBUG("Already scheduled\n"); | 549 | DRM_DEBUG("Already scheduled\n"); |
813 | return 0; | 550 | return 0; |
@@ -830,19 +567,9 @@ int i915_vblank_swap(struct drm_device *dev, void *data, | |||
830 | 567 | ||
831 | DRM_DEBUG("\n"); | 568 | DRM_DEBUG("\n"); |
832 | 569 | ||
833 | ret = drm_vblank_get(dev, pipe); | ||
834 | if (ret) { | ||
835 | drm_free(vbl_swap, sizeof(*vbl_swap), DRM_MEM_DRIVER); | ||
836 | return ret; | ||
837 | } | ||
838 | |||
839 | vbl_swap->drw_id = swap->drawable; | 570 | vbl_swap->drw_id = swap->drawable; |
840 | vbl_swap->plane = plane; | 571 | vbl_swap->pipe = pipe; |
841 | vbl_swap->sequence = swap->sequence; | 572 | vbl_swap->sequence = swap->sequence; |
842 | vbl_swap->flip = (swap->seqtype & _DRM_VBLANK_FLIP); | ||
843 | |||
844 | if (vbl_swap->flip) | ||
845 | swap->sequence++; | ||
846 | 573 | ||
847 | spin_lock_irqsave(&dev_priv->swaps_lock, irqflags); | 574 | spin_lock_irqsave(&dev_priv->swaps_lock, irqflags); |
848 | 575 | ||
@@ -860,57 +587,37 @@ void i915_driver_irq_preinstall(struct drm_device * dev) | |||
860 | { | 587 | { |
861 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 588 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
862 | 589 | ||
863 | I915_WRITE16(I915REG_HWSTAM, 0xeffe); | 590 | I915_WRITE16(I915REG_HWSTAM, 0xfffe); |
864 | I915_WRITE16(I915REG_INT_MASK_R, 0x0); | 591 | I915_WRITE16(I915REG_INT_MASK_R, 0x0); |
865 | I915_WRITE16(I915REG_INT_ENABLE_R, 0x0); | 592 | I915_WRITE16(I915REG_INT_ENABLE_R, 0x0); |
866 | } | 593 | } |
867 | 594 | ||
868 | int i915_driver_irq_postinstall(struct drm_device * dev) | 595 | void i915_driver_irq_postinstall(struct drm_device * dev) |
869 | { | 596 | { |
870 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 597 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
871 | int ret, num_pipes = 2; | ||
872 | 598 | ||
873 | spin_lock_init(&dev_priv->swaps_lock); | 599 | spin_lock_init(&dev_priv->swaps_lock); |
874 | INIT_LIST_HEAD(&dev_priv->vbl_swaps.head); | 600 | INIT_LIST_HEAD(&dev_priv->vbl_swaps.head); |
875 | dev_priv->swaps_pending = 0; | 601 | dev_priv->swaps_pending = 0; |
876 | 602 | ||
877 | dev_priv->user_irq_refcount = 0; | 603 | if (!dev_priv->vblank_pipe) |
878 | dev_priv->irq_enable_reg = 0; | 604 | dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A; |
879 | |||
880 | ret = drm_vblank_init(dev, num_pipes); | ||
881 | if (ret) | ||
882 | return ret; | ||
883 | |||
884 | dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ | ||
885 | |||
886 | i915_enable_interrupt(dev); | 605 | i915_enable_interrupt(dev); |
887 | DRM_INIT_WAITQUEUE(&dev_priv->irq_queue); | 606 | DRM_INIT_WAITQUEUE(&dev_priv->irq_queue); |
888 | |||
889 | /* | ||
890 | * Initialize the hardware status page IRQ location. | ||
891 | */ | ||
892 | |||
893 | I915_WRITE(I915REG_INSTPM, (1 << 5) | (1 << 21)); | ||
894 | return 0; | ||
895 | } | 607 | } |
896 | 608 | ||
897 | void i915_driver_irq_uninstall(struct drm_device * dev) | 609 | void i915_driver_irq_uninstall(struct drm_device * dev) |
898 | { | 610 | { |
899 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 611 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
900 | u32 temp; | 612 | u16 temp; |
901 | 613 | ||
902 | if (!dev_priv) | 614 | if (!dev_priv) |
903 | return; | 615 | return; |
904 | 616 | ||
905 | dev_priv->irq_enabled = 0; | 617 | I915_WRITE16(I915REG_HWSTAM, 0xffff); |
906 | I915_WRITE(I915REG_HWSTAM, 0xffffffff); | 618 | I915_WRITE16(I915REG_INT_MASK_R, 0xffff); |
907 | I915_WRITE(I915REG_INT_MASK_R, 0xffffffff); | 619 | I915_WRITE16(I915REG_INT_ENABLE_R, 0x0); |
908 | I915_WRITE(I915REG_INT_ENABLE_R, 0x0); | 620 | |
909 | 621 | temp = I915_READ16(I915REG_INT_IDENTITY_R); | |
910 | temp = I915_READ(I915REG_PIPEASTAT); | 622 | I915_WRITE16(I915REG_INT_IDENTITY_R, temp); |
911 | I915_WRITE(I915REG_PIPEASTAT, temp); | ||
912 | temp = I915_READ(I915REG_PIPEBSTAT); | ||
913 | I915_WRITE(I915REG_PIPEBSTAT, temp); | ||
914 | temp = I915_READ(I915REG_INT_IDENTITY_R); | ||
915 | I915_WRITE(I915REG_INT_IDENTITY_R, temp); | ||
916 | } | 623 | } |
diff --git a/drivers/char/drm/mga_drv.c b/drivers/char/drm/mga_drv.c index 6b3790939e76..5572939fc7d1 100644 --- a/drivers/char/drm/mga_drv.c +++ b/drivers/char/drm/mga_drv.c | |||
@@ -45,16 +45,15 @@ static struct pci_device_id pciidlist[] = { | |||
45 | static struct drm_driver driver = { | 45 | static struct drm_driver driver = { |
46 | .driver_features = | 46 | .driver_features = |
47 | DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | | 47 | DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | |
48 | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED, | 48 | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | |
49 | DRIVER_IRQ_VBL, | ||
49 | .dev_priv_size = sizeof(drm_mga_buf_priv_t), | 50 | .dev_priv_size = sizeof(drm_mga_buf_priv_t), |
50 | .load = mga_driver_load, | 51 | .load = mga_driver_load, |
51 | .unload = mga_driver_unload, | 52 | .unload = mga_driver_unload, |
52 | .lastclose = mga_driver_lastclose, | 53 | .lastclose = mga_driver_lastclose, |
53 | .dma_quiescent = mga_driver_dma_quiescent, | 54 | .dma_quiescent = mga_driver_dma_quiescent, |
54 | .device_is_agp = mga_driver_device_is_agp, | 55 | .device_is_agp = mga_driver_device_is_agp, |
55 | .get_vblank_counter = mga_get_vblank_counter, | 56 | .vblank_wait = mga_driver_vblank_wait, |
56 | .enable_vblank = mga_enable_vblank, | ||
57 | .disable_vblank = mga_disable_vblank, | ||
58 | .irq_preinstall = mga_driver_irq_preinstall, | 57 | .irq_preinstall = mga_driver_irq_preinstall, |
59 | .irq_postinstall = mga_driver_irq_postinstall, | 58 | .irq_postinstall = mga_driver_irq_postinstall, |
60 | .irq_uninstall = mga_driver_irq_uninstall, | 59 | .irq_uninstall = mga_driver_irq_uninstall, |
diff --git a/drivers/char/drm/mga_drv.h b/drivers/char/drm/mga_drv.h index 8f7291f36363..f6ebd24bd587 100644 --- a/drivers/char/drm/mga_drv.h +++ b/drivers/char/drm/mga_drv.h | |||
@@ -120,7 +120,6 @@ typedef struct drm_mga_private { | |||
120 | u32 clear_cmd; | 120 | u32 clear_cmd; |
121 | u32 maccess; | 121 | u32 maccess; |
122 | 122 | ||
123 | atomic_t vbl_received; /**< Number of vblanks received. */ | ||
124 | wait_queue_head_t fence_queue; | 123 | wait_queue_head_t fence_queue; |
125 | atomic_t last_fence_retired; | 124 | atomic_t last_fence_retired; |
126 | u32 next_fence_to_post; | 125 | u32 next_fence_to_post; |
@@ -182,14 +181,11 @@ extern int mga_warp_install_microcode(drm_mga_private_t * dev_priv); | |||
182 | extern int mga_warp_init(drm_mga_private_t * dev_priv); | 181 | extern int mga_warp_init(drm_mga_private_t * dev_priv); |
183 | 182 | ||
184 | /* mga_irq.c */ | 183 | /* mga_irq.c */ |
185 | extern int mga_enable_vblank(struct drm_device *dev, int crtc); | ||
186 | extern void mga_disable_vblank(struct drm_device *dev, int crtc); | ||
187 | extern u32 mga_get_vblank_counter(struct drm_device *dev, int crtc); | ||
188 | extern int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence); | 184 | extern int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence); |
189 | extern int mga_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence); | 185 | extern int mga_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence); |
190 | extern irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS); | 186 | extern irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS); |
191 | extern void mga_driver_irq_preinstall(struct drm_device * dev); | 187 | extern void mga_driver_irq_preinstall(struct drm_device * dev); |
192 | extern int mga_driver_irq_postinstall(struct drm_device * dev); | 188 | extern void mga_driver_irq_postinstall(struct drm_device * dev); |
193 | extern void mga_driver_irq_uninstall(struct drm_device * dev); | 189 | extern void mga_driver_irq_uninstall(struct drm_device * dev); |
194 | extern long mga_compat_ioctl(struct file *filp, unsigned int cmd, | 190 | extern long mga_compat_ioctl(struct file *filp, unsigned int cmd, |
195 | unsigned long arg); | 191 | unsigned long arg); |
diff --git a/drivers/char/drm/mga_irq.c b/drivers/char/drm/mga_irq.c index 06852fb4b278..9302cb8f0f83 100644 --- a/drivers/char/drm/mga_irq.c +++ b/drivers/char/drm/mga_irq.c | |||
@@ -35,20 +35,6 @@ | |||
35 | #include "mga_drm.h" | 35 | #include "mga_drm.h" |
36 | #include "mga_drv.h" | 36 | #include "mga_drv.h" |
37 | 37 | ||
38 | u32 mga_get_vblank_counter(struct drm_device *dev, int crtc) | ||
39 | { | ||
40 | const drm_mga_private_t *const dev_priv = | ||
41 | (drm_mga_private_t *) dev->dev_private; | ||
42 | |||
43 | if (crtc != 0) { | ||
44 | return 0; | ||
45 | } | ||
46 | |||
47 | |||
48 | return atomic_read(&dev_priv->vbl_received); | ||
49 | } | ||
50 | |||
51 | |||
52 | irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS) | 38 | irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS) |
53 | { | 39 | { |
54 | struct drm_device *dev = (struct drm_device *) arg; | 40 | struct drm_device *dev = (struct drm_device *) arg; |
@@ -61,8 +47,9 @@ irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS) | |||
61 | /* VBLANK interrupt */ | 47 | /* VBLANK interrupt */ |
62 | if (status & MGA_VLINEPEN) { | 48 | if (status & MGA_VLINEPEN) { |
63 | MGA_WRITE(MGA_ICLEAR, MGA_VLINEICLR); | 49 | MGA_WRITE(MGA_ICLEAR, MGA_VLINEICLR); |
64 | atomic_inc(&dev_priv->vbl_received); | 50 | atomic_inc(&dev->vbl_received); |
65 | drm_handle_vblank(dev, 0); | 51 | DRM_WAKEUP(&dev->vbl_queue); |
52 | drm_vbl_send_signals(dev); | ||
66 | handled = 1; | 53 | handled = 1; |
67 | } | 54 | } |
68 | 55 | ||
@@ -91,34 +78,22 @@ irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS) | |||
91 | return IRQ_NONE; | 78 | return IRQ_NONE; |
92 | } | 79 | } |
93 | 80 | ||
94 | int mga_enable_vblank(struct drm_device *dev, int crtc) | 81 | int mga_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence) |
95 | { | 82 | { |
96 | drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; | 83 | unsigned int cur_vblank; |
97 | 84 | int ret = 0; | |
98 | if (crtc != 0) { | ||
99 | DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", | ||
100 | crtc); | ||
101 | return 0; | ||
102 | } | ||
103 | |||
104 | MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN); | ||
105 | return 0; | ||
106 | } | ||
107 | 85 | ||
86 | /* Assume that the user has missed the current sequence number | ||
87 | * by about a day rather than she wants to wait for years | ||
88 | * using vertical blanks... | ||
89 | */ | ||
90 | DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, | ||
91 | (((cur_vblank = atomic_read(&dev->vbl_received)) | ||
92 | - *sequence) <= (1 << 23))); | ||
108 | 93 | ||
109 | void mga_disable_vblank(struct drm_device *dev, int crtc) | 94 | *sequence = cur_vblank; |
110 | { | ||
111 | if (crtc != 0) { | ||
112 | DRM_ERROR("tried to disable vblank on non-existent crtc %d\n", | ||
113 | crtc); | ||
114 | } | ||
115 | 95 | ||
116 | /* Do *NOT* disable the vertical refresh interrupt. MGA doesn't have | 96 | return ret; |
117 | * a nice hardware counter that tracks the number of refreshes when | ||
118 | * the interrupt is disabled, and the kernel doesn't know the refresh | ||
119 | * rate to calculate an estimate. | ||
120 | */ | ||
121 | /* MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN); */ | ||
122 | } | 97 | } |
123 | 98 | ||
124 | int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence) | 99 | int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence) |
@@ -150,22 +125,14 @@ void mga_driver_irq_preinstall(struct drm_device * dev) | |||
150 | MGA_WRITE(MGA_ICLEAR, ~0); | 125 | MGA_WRITE(MGA_ICLEAR, ~0); |
151 | } | 126 | } |
152 | 127 | ||
153 | int mga_driver_irq_postinstall(struct drm_device * dev) | 128 | void mga_driver_irq_postinstall(struct drm_device * dev) |
154 | { | 129 | { |
155 | drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; | 130 | drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; |
156 | int ret; | ||
157 | |||
158 | ret = drm_vblank_init(dev, 1); | ||
159 | if (ret) | ||
160 | return ret; | ||
161 | 131 | ||
162 | DRM_INIT_WAITQUEUE(&dev_priv->fence_queue); | 132 | DRM_INIT_WAITQUEUE(&dev_priv->fence_queue); |
163 | 133 | ||
164 | /* Turn on soft trap interrupt. Vertical blank interrupts are enabled | 134 | /* Turn on vertical blank interrupt and soft trap interrupt. */ |
165 | * in mga_enable_vblank. | 135 | MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN); |
166 | */ | ||
167 | MGA_WRITE(MGA_IEN, MGA_SOFTRAPEN); | ||
168 | return 0; | ||
169 | } | 136 | } |
170 | 137 | ||
171 | void mga_driver_irq_uninstall(struct drm_device * dev) | 138 | void mga_driver_irq_uninstall(struct drm_device * dev) |
diff --git a/drivers/char/drm/r128_drv.c b/drivers/char/drm/r128_drv.c index 2888aa01ebc7..6108e7587e12 100644 --- a/drivers/char/drm/r128_drv.c +++ b/drivers/char/drm/r128_drv.c | |||
@@ -43,13 +43,12 @@ static struct pci_device_id pciidlist[] = { | |||
43 | static struct drm_driver driver = { | 43 | static struct drm_driver driver = { |
44 | .driver_features = | 44 | .driver_features = |
45 | DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | | 45 | DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | |
46 | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED, | 46 | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | |
47 | DRIVER_IRQ_VBL, | ||
47 | .dev_priv_size = sizeof(drm_r128_buf_priv_t), | 48 | .dev_priv_size = sizeof(drm_r128_buf_priv_t), |
48 | .preclose = r128_driver_preclose, | 49 | .preclose = r128_driver_preclose, |
49 | .lastclose = r128_driver_lastclose, | 50 | .lastclose = r128_driver_lastclose, |
50 | .get_vblank_counter = r128_get_vblank_counter, | 51 | .vblank_wait = r128_driver_vblank_wait, |
51 | .enable_vblank = r128_enable_vblank, | ||
52 | .disable_vblank = r128_disable_vblank, | ||
53 | .irq_preinstall = r128_driver_irq_preinstall, | 52 | .irq_preinstall = r128_driver_irq_preinstall, |
54 | .irq_postinstall = r128_driver_irq_postinstall, | 53 | .irq_postinstall = r128_driver_irq_postinstall, |
55 | .irq_uninstall = r128_driver_irq_uninstall, | 54 | .irq_uninstall = r128_driver_irq_uninstall, |
diff --git a/drivers/char/drm/r128_drv.h b/drivers/char/drm/r128_drv.h index 80af9e09e75d..011105e51ac6 100644 --- a/drivers/char/drm/r128_drv.h +++ b/drivers/char/drm/r128_drv.h | |||
@@ -97,8 +97,6 @@ typedef struct drm_r128_private { | |||
97 | u32 crtc_offset; | 97 | u32 crtc_offset; |
98 | u32 crtc_offset_cntl; | 98 | u32 crtc_offset_cntl; |
99 | 99 | ||
100 | atomic_t vbl_received; | ||
101 | |||
102 | u32 color_fmt; | 100 | u32 color_fmt; |
103 | unsigned int front_offset; | 101 | unsigned int front_offset; |
104 | unsigned int front_pitch; | 102 | unsigned int front_pitch; |
@@ -151,12 +149,11 @@ extern int r128_wait_ring(drm_r128_private_t * dev_priv, int n); | |||
151 | extern int r128_do_cce_idle(drm_r128_private_t * dev_priv); | 149 | extern int r128_do_cce_idle(drm_r128_private_t * dev_priv); |
152 | extern int r128_do_cleanup_cce(struct drm_device * dev); | 150 | extern int r128_do_cleanup_cce(struct drm_device * dev); |
153 | 151 | ||
154 | extern int r128_enable_vblank(struct drm_device *dev, int crtc); | 152 | extern int r128_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence); |
155 | extern void r128_disable_vblank(struct drm_device *dev, int crtc); | 153 | |
156 | extern u32 r128_get_vblank_counter(struct drm_device *dev, int crtc); | ||
157 | extern irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS); | 154 | extern irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS); |
158 | extern void r128_driver_irq_preinstall(struct drm_device * dev); | 155 | extern void r128_driver_irq_preinstall(struct drm_device * dev); |
159 | extern int r128_driver_irq_postinstall(struct drm_device * dev); | 156 | extern void r128_driver_irq_postinstall(struct drm_device * dev); |
160 | extern void r128_driver_irq_uninstall(struct drm_device * dev); | 157 | extern void r128_driver_irq_uninstall(struct drm_device * dev); |
161 | extern void r128_driver_lastclose(struct drm_device * dev); | 158 | extern void r128_driver_lastclose(struct drm_device * dev); |
162 | extern void r128_driver_preclose(struct drm_device * dev, | 159 | extern void r128_driver_preclose(struct drm_device * dev, |
diff --git a/drivers/char/drm/r128_irq.c b/drivers/char/drm/r128_irq.c index 5b95bd898f95..c76fdca7662d 100644 --- a/drivers/char/drm/r128_irq.c +++ b/drivers/char/drm/r128_irq.c | |||
@@ -35,16 +35,6 @@ | |||
35 | #include "r128_drm.h" | 35 | #include "r128_drm.h" |
36 | #include "r128_drv.h" | 36 | #include "r128_drv.h" |
37 | 37 | ||
38 | u32 r128_get_vblank_counter(struct drm_device *dev, int crtc) | ||
39 | { | ||
40 | const drm_r128_private_t *dev_priv = dev->dev_private; | ||
41 | |||
42 | if (crtc != 0) | ||
43 | return 0; | ||
44 | |||
45 | return atomic_read(&dev_priv->vbl_received); | ||
46 | } | ||
47 | |||
48 | irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS) | 38 | irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS) |
49 | { | 39 | { |
50 | struct drm_device *dev = (struct drm_device *) arg; | 40 | struct drm_device *dev = (struct drm_device *) arg; |
@@ -56,38 +46,30 @@ irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS) | |||
56 | /* VBLANK interrupt */ | 46 | /* VBLANK interrupt */ |
57 | if (status & R128_CRTC_VBLANK_INT) { | 47 | if (status & R128_CRTC_VBLANK_INT) { |
58 | R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK); | 48 | R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK); |
59 | atomic_inc(&dev_priv->vbl_received); | 49 | atomic_inc(&dev->vbl_received); |
60 | drm_handle_vblank(dev, 0); | 50 | DRM_WAKEUP(&dev->vbl_queue); |
51 | drm_vbl_send_signals(dev); | ||
61 | return IRQ_HANDLED; | 52 | return IRQ_HANDLED; |
62 | } | 53 | } |
63 | return IRQ_NONE; | 54 | return IRQ_NONE; |
64 | } | 55 | } |
65 | 56 | ||
66 | int r128_enable_vblank(struct drm_device *dev, int crtc) | 57 | int r128_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence) |
67 | { | 58 | { |
68 | drm_r128_private_t *dev_priv = dev->dev_private; | 59 | unsigned int cur_vblank; |
69 | 60 | int ret = 0; | |
70 | if (crtc != 0) { | ||
71 | DRM_ERROR("%s: bad crtc %d\n", __FUNCTION__, crtc); | ||
72 | return -EINVAL; | ||
73 | } | ||
74 | 61 | ||
75 | R128_WRITE(R128_GEN_INT_CNTL, R128_CRTC_VBLANK_INT_EN); | 62 | /* Assume that the user has missed the current sequence number |
76 | return 0; | 63 | * by about a day rather than she wants to wait for years |
77 | } | 64 | * using vertical blanks... |
65 | */ | ||
66 | DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, | ||
67 | (((cur_vblank = atomic_read(&dev->vbl_received)) | ||
68 | - *sequence) <= (1 << 23))); | ||
78 | 69 | ||
79 | void r128_disable_vblank(struct drm_device *dev, int crtc) | 70 | *sequence = cur_vblank; |
80 | { | ||
81 | if (crtc != 0) | ||
82 | DRM_ERROR("%s: bad crtc %d\n", __FUNCTION__, crtc); | ||
83 | 71 | ||
84 | /* | 72 | return ret; |
85 | * FIXME: implement proper interrupt disable by using the vblank | ||
86 | * counter register (if available) | ||
87 | * | ||
88 | * R128_WRITE(R128_GEN_INT_CNTL, | ||
89 | * R128_READ(R128_GEN_INT_CNTL) & ~R128_CRTC_VBLANK_INT_EN); | ||
90 | */ | ||
91 | } | 73 | } |
92 | 74 | ||
93 | void r128_driver_irq_preinstall(struct drm_device * dev) | 75 | void r128_driver_irq_preinstall(struct drm_device * dev) |
@@ -100,9 +82,12 @@ void r128_driver_irq_preinstall(struct drm_device * dev) | |||
100 | R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK); | 82 | R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK); |
101 | } | 83 | } |
102 | 84 | ||
103 | int r128_driver_irq_postinstall(struct drm_device * dev) | 85 | void r128_driver_irq_postinstall(struct drm_device * dev) |
104 | { | 86 | { |
105 | return drm_vblank_init(dev, 1); | 87 | drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private; |
88 | |||
89 | /* Turn on VBL interrupt */ | ||
90 | R128_WRITE(R128_GEN_INT_CNTL, R128_CRTC_VBLANK_INT_EN); | ||
106 | } | 91 | } |
107 | 92 | ||
108 | void r128_driver_irq_uninstall(struct drm_device * dev) | 93 | void r128_driver_irq_uninstall(struct drm_device * dev) |
diff --git a/drivers/char/drm/radeon_drv.c b/drivers/char/drm/radeon_drv.c index a2610319624d..349ac3d3b848 100644 --- a/drivers/char/drm/radeon_drv.c +++ b/drivers/char/drm/radeon_drv.c | |||
@@ -59,7 +59,8 @@ static struct pci_device_id pciidlist[] = { | |||
59 | static struct drm_driver driver = { | 59 | static struct drm_driver driver = { |
60 | .driver_features = | 60 | .driver_features = |
61 | DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | | 61 | DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | |
62 | DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED, | 62 | DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED | |
63 | DRIVER_IRQ_VBL | DRIVER_IRQ_VBL2, | ||
63 | .dev_priv_size = sizeof(drm_radeon_buf_priv_t), | 64 | .dev_priv_size = sizeof(drm_radeon_buf_priv_t), |
64 | .load = radeon_driver_load, | 65 | .load = radeon_driver_load, |
65 | .firstopen = radeon_driver_firstopen, | 66 | .firstopen = radeon_driver_firstopen, |
@@ -68,9 +69,8 @@ static struct drm_driver driver = { | |||
68 | .postclose = radeon_driver_postclose, | 69 | .postclose = radeon_driver_postclose, |
69 | .lastclose = radeon_driver_lastclose, | 70 | .lastclose = radeon_driver_lastclose, |
70 | .unload = radeon_driver_unload, | 71 | .unload = radeon_driver_unload, |
71 | .get_vblank_counter = radeon_get_vblank_counter, | 72 | .vblank_wait = radeon_driver_vblank_wait, |
72 | .enable_vblank = radeon_enable_vblank, | 73 | .vblank_wait2 = radeon_driver_vblank_wait2, |
73 | .disable_vblank = radeon_disable_vblank, | ||
74 | .dri_library_name = dri_library_name, | 74 | .dri_library_name = dri_library_name, |
75 | .irq_preinstall = radeon_driver_irq_preinstall, | 75 | .irq_preinstall = radeon_driver_irq_preinstall, |
76 | .irq_postinstall = radeon_driver_irq_postinstall, | 76 | .irq_postinstall = radeon_driver_irq_postinstall, |
diff --git a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h index b791420bd3d9..173ae620223a 100644 --- a/drivers/char/drm/radeon_drv.h +++ b/drivers/char/drm/radeon_drv.h | |||
@@ -304,9 +304,6 @@ typedef struct drm_radeon_private { | |||
304 | 304 | ||
305 | u32 scratch_ages[5]; | 305 | u32 scratch_ages[5]; |
306 | 306 | ||
307 | unsigned int crtc_last_cnt; | ||
308 | unsigned int crtc2_last_cnt; | ||
309 | |||
310 | /* starting from here on, data is preserved accross an open */ | 307 | /* starting from here on, data is preserved accross an open */ |
311 | uint32_t flags; /* see radeon_chip_flags */ | 308 | uint32_t flags; /* see radeon_chip_flags */ |
312 | unsigned long fb_aper_offset; | 309 | unsigned long fb_aper_offset; |
@@ -377,13 +374,13 @@ extern int radeon_irq_emit(struct drm_device *dev, void *data, struct drm_file * | |||
377 | extern int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_priv); | 374 | extern int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_priv); |
378 | 375 | ||
379 | extern void radeon_do_release(struct drm_device * dev); | 376 | extern void radeon_do_release(struct drm_device * dev); |
380 | extern u32 radeon_get_vblank_counter(struct drm_device *dev, int crtc); | 377 | extern int radeon_driver_vblank_wait(struct drm_device * dev, |
381 | extern int radeon_enable_vblank(struct drm_device *dev, int crtc); | 378 | unsigned int *sequence); |
382 | extern void radeon_disable_vblank(struct drm_device *dev, int crtc); | 379 | extern int radeon_driver_vblank_wait2(struct drm_device * dev, |
383 | extern void radeon_do_release(struct drm_device * dev); | 380 | unsigned int *sequence); |
384 | extern irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS); | 381 | extern irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS); |
385 | extern void radeon_driver_irq_preinstall(struct drm_device * dev); | 382 | extern void radeon_driver_irq_preinstall(struct drm_device * dev); |
386 | extern int radeon_driver_irq_postinstall(struct drm_device * dev); | 383 | extern void radeon_driver_irq_postinstall(struct drm_device * dev); |
387 | extern void radeon_driver_irq_uninstall(struct drm_device * dev); | 384 | extern void radeon_driver_irq_uninstall(struct drm_device * dev); |
388 | extern int radeon_vblank_crtc_get(struct drm_device *dev); | 385 | extern int radeon_vblank_crtc_get(struct drm_device *dev); |
389 | extern int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value); | 386 | extern int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value); |
@@ -561,12 +558,6 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev, | |||
561 | ? DRM_READ32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(x) ) \ | 558 | ? DRM_READ32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(x) ) \ |
562 | : RADEON_READ( RADEON_SCRATCH_REG0 + 4*(x) ) ) | 559 | : RADEON_READ( RADEON_SCRATCH_REG0 + 4*(x) ) ) |
563 | 560 | ||
564 | #define RADEON_CRTC_CRNT_FRAME 0x0214 | ||
565 | #define RADEON_CRTC2_CRNT_FRAME 0x0314 | ||
566 | |||
567 | #define RADEON_CRTC_STATUS 0x005c | ||
568 | #define RADEON_CRTC2_STATUS 0x03fc | ||
569 | |||
570 | #define RADEON_GEN_INT_CNTL 0x0040 | 561 | #define RADEON_GEN_INT_CNTL 0x0040 |
571 | # define RADEON_CRTC_VBLANK_MASK (1 << 0) | 562 | # define RADEON_CRTC_VBLANK_MASK (1 << 0) |
572 | # define RADEON_CRTC2_VBLANK_MASK (1 << 9) | 563 | # define RADEON_CRTC2_VBLANK_MASK (1 << 9) |
diff --git a/drivers/char/drm/radeon_irq.c b/drivers/char/drm/radeon_irq.c index 507d6b747a13..009af3814b6f 100644 --- a/drivers/char/drm/radeon_irq.c +++ b/drivers/char/drm/radeon_irq.c | |||
@@ -35,61 +35,12 @@ | |||
35 | #include "radeon_drm.h" | 35 | #include "radeon_drm.h" |
36 | #include "radeon_drv.h" | 36 | #include "radeon_drv.h" |
37 | 37 | ||
38 | static void radeon_irq_set_state(struct drm_device *dev, u32 mask, int state) | 38 | static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t * dev_priv, |
39 | u32 mask) | ||
39 | { | 40 | { |
40 | drm_radeon_private_t *dev_priv = dev->dev_private; | 41 | u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS) & mask; |
41 | |||
42 | if (state) | ||
43 | dev_priv->irq_enable_reg |= mask; | ||
44 | else | ||
45 | dev_priv->irq_enable_reg &= ~mask; | ||
46 | |||
47 | RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg); | ||
48 | } | ||
49 | |||
50 | int radeon_enable_vblank(struct drm_device *dev, int crtc) | ||
51 | { | ||
52 | switch (crtc) { | ||
53 | case 0: | ||
54 | radeon_irq_set_state(dev, RADEON_CRTC_VBLANK_MASK, 1); | ||
55 | break; | ||
56 | case 1: | ||
57 | radeon_irq_set_state(dev, RADEON_CRTC2_VBLANK_MASK, 1); | ||
58 | break; | ||
59 | default: | ||
60 | DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", | ||
61 | crtc); | ||
62 | return EINVAL; | ||
63 | } | ||
64 | |||
65 | return 0; | ||
66 | } | ||
67 | |||
68 | void radeon_disable_vblank(struct drm_device *dev, int crtc) | ||
69 | { | ||
70 | switch (crtc) { | ||
71 | case 0: | ||
72 | radeon_irq_set_state(dev, RADEON_CRTC_VBLANK_MASK, 0); | ||
73 | break; | ||
74 | case 1: | ||
75 | radeon_irq_set_state(dev, RADEON_CRTC2_VBLANK_MASK, 0); | ||
76 | break; | ||
77 | default: | ||
78 | DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", | ||
79 | crtc); | ||
80 | break; | ||
81 | } | ||
82 | } | ||
83 | |||
84 | static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t * dev_priv) | ||
85 | { | ||
86 | u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS) & | ||
87 | (RADEON_SW_INT_TEST | RADEON_CRTC_VBLANK_STAT | | ||
88 | RADEON_CRTC2_VBLANK_STAT); | ||
89 | |||
90 | if (irqs) | 42 | if (irqs) |
91 | RADEON_WRITE(RADEON_GEN_INT_STATUS, irqs); | 43 | RADEON_WRITE(RADEON_GEN_INT_STATUS, irqs); |
92 | |||
93 | return irqs; | 44 | return irqs; |
94 | } | 45 | } |
95 | 46 | ||
@@ -121,21 +72,39 @@ irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS) | |||
121 | /* Only consider the bits we're interested in - others could be used | 72 | /* Only consider the bits we're interested in - others could be used |
122 | * outside the DRM | 73 | * outside the DRM |
123 | */ | 74 | */ |
124 | stat = radeon_acknowledge_irqs(dev_priv); | 75 | stat = radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK | |
76 | RADEON_CRTC_VBLANK_STAT | | ||
77 | RADEON_CRTC2_VBLANK_STAT)); | ||
125 | if (!stat) | 78 | if (!stat) |
126 | return IRQ_NONE; | 79 | return IRQ_NONE; |
127 | 80 | ||
128 | stat &= dev_priv->irq_enable_reg; | 81 | stat &= dev_priv->irq_enable_reg; |
129 | 82 | ||
130 | /* SW interrupt */ | 83 | /* SW interrupt */ |
131 | if (stat & RADEON_SW_INT_TEST) | 84 | if (stat & RADEON_SW_INT_TEST) { |
132 | DRM_WAKEUP(&dev_priv->swi_queue); | 85 | DRM_WAKEUP(&dev_priv->swi_queue); |
86 | } | ||
133 | 87 | ||
134 | /* VBLANK interrupt */ | 88 | /* VBLANK interrupt */ |
135 | if (stat & RADEON_CRTC_VBLANK_STAT) | 89 | if (stat & (RADEON_CRTC_VBLANK_STAT|RADEON_CRTC2_VBLANK_STAT)) { |
136 | drm_handle_vblank(dev, 0); | 90 | int vblank_crtc = dev_priv->vblank_crtc; |
137 | if (stat & RADEON_CRTC2_VBLANK_STAT) | 91 | |
138 | drm_handle_vblank(dev, 1); | 92 | if ((vblank_crtc & |
93 | (DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) == | ||
94 | (DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) { | ||
95 | if (stat & RADEON_CRTC_VBLANK_STAT) | ||
96 | atomic_inc(&dev->vbl_received); | ||
97 | if (stat & RADEON_CRTC2_VBLANK_STAT) | ||
98 | atomic_inc(&dev->vbl_received2); | ||
99 | } else if (((stat & RADEON_CRTC_VBLANK_STAT) && | ||
100 | (vblank_crtc & DRM_RADEON_VBLANK_CRTC1)) || | ||
101 | ((stat & RADEON_CRTC2_VBLANK_STAT) && | ||
102 | (vblank_crtc & DRM_RADEON_VBLANK_CRTC2))) | ||
103 | atomic_inc(&dev->vbl_received); | ||
104 | |||
105 | DRM_WAKEUP(&dev->vbl_queue); | ||
106 | drm_vbl_send_signals(dev); | ||
107 | } | ||
139 | 108 | ||
140 | return IRQ_HANDLED; | 109 | return IRQ_HANDLED; |
141 | } | 110 | } |
@@ -175,27 +144,54 @@ static int radeon_wait_irq(struct drm_device * dev, int swi_nr) | |||
175 | return ret; | 144 | return ret; |
176 | } | 145 | } |
177 | 146 | ||
178 | u32 radeon_get_vblank_counter(struct drm_device *dev, int crtc) | 147 | static int radeon_driver_vblank_do_wait(struct drm_device * dev, |
148 | unsigned int *sequence, int crtc) | ||
179 | { | 149 | { |
180 | drm_radeon_private_t *dev_priv = dev->dev_private; | 150 | drm_radeon_private_t *dev_priv = |
181 | u32 crtc_cnt_reg, crtc_status_reg; | 151 | (drm_radeon_private_t *) dev->dev_private; |
182 | 152 | unsigned int cur_vblank; | |
153 | int ret = 0; | ||
154 | int ack = 0; | ||
155 | atomic_t *counter; | ||
183 | if (!dev_priv) { | 156 | if (!dev_priv) { |
184 | DRM_ERROR("called with no initialization\n"); | 157 | DRM_ERROR("called with no initialization\n"); |
185 | return -EINVAL; | 158 | return -EINVAL; |
186 | } | 159 | } |
187 | 160 | ||
188 | if (crtc == 0) { | 161 | if (crtc == DRM_RADEON_VBLANK_CRTC1) { |
189 | crtc_cnt_reg = RADEON_CRTC_CRNT_FRAME; | 162 | counter = &dev->vbl_received; |
190 | crtc_status_reg = RADEON_CRTC_STATUS; | 163 | ack |= RADEON_CRTC_VBLANK_STAT; |
191 | } else if (crtc == 1) { | 164 | } else if (crtc == DRM_RADEON_VBLANK_CRTC2) { |
192 | crtc_cnt_reg = RADEON_CRTC2_CRNT_FRAME; | 165 | counter = &dev->vbl_received2; |
193 | crtc_status_reg = RADEON_CRTC2_STATUS; | 166 | ack |= RADEON_CRTC2_VBLANK_STAT; |
194 | } else { | 167 | } else |
195 | return -EINVAL; | 168 | return -EINVAL; |
196 | } | ||
197 | 169 | ||
198 | return RADEON_READ(crtc_cnt_reg) + (RADEON_READ(crtc_status_reg) & 1); | 170 | radeon_acknowledge_irqs(dev_priv, ack); |
171 | |||
172 | dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; | ||
173 | |||
174 | /* Assume that the user has missed the current sequence number | ||
175 | * by about a day rather than she wants to wait for years | ||
176 | * using vertical blanks... | ||
177 | */ | ||
178 | DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, | ||
179 | (((cur_vblank = atomic_read(counter)) | ||
180 | - *sequence) <= (1 << 23))); | ||
181 | |||
182 | *sequence = cur_vblank; | ||
183 | |||
184 | return ret; | ||
185 | } | ||
186 | |||
187 | int radeon_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence) | ||
188 | { | ||
189 | return radeon_driver_vblank_do_wait(dev, sequence, DRM_RADEON_VBLANK_CRTC1); | ||
190 | } | ||
191 | |||
192 | int radeon_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence) | ||
193 | { | ||
194 | return radeon_driver_vblank_do_wait(dev, sequence, DRM_RADEON_VBLANK_CRTC2); | ||
199 | } | 195 | } |
200 | 196 | ||
201 | /* Needs the lock as it touches the ring. | 197 | /* Needs the lock as it touches the ring. |
@@ -238,6 +234,21 @@ int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_pr | |||
238 | return radeon_wait_irq(dev, irqwait->irq_seq); | 234 | return radeon_wait_irq(dev, irqwait->irq_seq); |
239 | } | 235 | } |
240 | 236 | ||
237 | static void radeon_enable_interrupt(struct drm_device *dev) | ||
238 | { | ||
239 | drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; | ||
240 | |||
241 | dev_priv->irq_enable_reg = RADEON_SW_INT_ENABLE; | ||
242 | if (dev_priv->vblank_crtc & DRM_RADEON_VBLANK_CRTC1) | ||
243 | dev_priv->irq_enable_reg |= RADEON_CRTC_VBLANK_MASK; | ||
244 | |||
245 | if (dev_priv->vblank_crtc & DRM_RADEON_VBLANK_CRTC2) | ||
246 | dev_priv->irq_enable_reg |= RADEON_CRTC2_VBLANK_MASK; | ||
247 | |||
248 | RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg); | ||
249 | dev_priv->irq_enabled = 1; | ||
250 | } | ||
251 | |||
241 | /* drm_dma.h hooks | 252 | /* drm_dma.h hooks |
242 | */ | 253 | */ |
243 | void radeon_driver_irq_preinstall(struct drm_device * dev) | 254 | void radeon_driver_irq_preinstall(struct drm_device * dev) |
@@ -249,27 +260,20 @@ void radeon_driver_irq_preinstall(struct drm_device * dev) | |||
249 | RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); | 260 | RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); |
250 | 261 | ||
251 | /* Clear bits if they're already high */ | 262 | /* Clear bits if they're already high */ |
252 | radeon_acknowledge_irqs(dev_priv); | 263 | radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK | |
264 | RADEON_CRTC_VBLANK_STAT | | ||
265 | RADEON_CRTC2_VBLANK_STAT)); | ||
253 | } | 266 | } |
254 | 267 | ||
255 | int radeon_driver_irq_postinstall(struct drm_device * dev) | 268 | void radeon_driver_irq_postinstall(struct drm_device * dev) |
256 | { | 269 | { |
257 | drm_radeon_private_t *dev_priv = | 270 | drm_radeon_private_t *dev_priv = |
258 | (drm_radeon_private_t *) dev->dev_private; | 271 | (drm_radeon_private_t *) dev->dev_private; |
259 | int ret; | ||
260 | 272 | ||
261 | atomic_set(&dev_priv->swi_emitted, 0); | 273 | atomic_set(&dev_priv->swi_emitted, 0); |
262 | DRM_INIT_WAITQUEUE(&dev_priv->swi_queue); | 274 | DRM_INIT_WAITQUEUE(&dev_priv->swi_queue); |
263 | 275 | ||
264 | ret = drm_vblank_init(dev, 2); | 276 | radeon_enable_interrupt(dev); |
265 | if (ret) | ||
266 | return ret; | ||
267 | |||
268 | dev->max_vblank_count = 0x001fffff; | ||
269 | |||
270 | radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1); | ||
271 | |||
272 | return 0; | ||
273 | } | 277 | } |
274 | 278 | ||
275 | void radeon_driver_irq_uninstall(struct drm_device * dev) | 279 | void radeon_driver_irq_uninstall(struct drm_device * dev) |
@@ -311,5 +315,6 @@ int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value) | |||
311 | return -EINVAL; | 315 | return -EINVAL; |
312 | } | 316 | } |
313 | dev_priv->vblank_crtc = (unsigned int)value; | 317 | dev_priv->vblank_crtc = (unsigned int)value; |
318 | radeon_enable_interrupt(dev); | ||
314 | return 0; | 319 | return 0; |
315 | } | 320 | } |
diff --git a/drivers/char/drm/via_drv.c b/drivers/char/drm/via_drv.c index 37870a4a3dc7..80c01cdfa37d 100644 --- a/drivers/char/drm/via_drv.c +++ b/drivers/char/drm/via_drv.c | |||
@@ -40,13 +40,11 @@ static struct pci_device_id pciidlist[] = { | |||
40 | static struct drm_driver driver = { | 40 | static struct drm_driver driver = { |
41 | .driver_features = | 41 | .driver_features = |
42 | DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_IRQ | | 42 | DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_IRQ | |
43 | DRIVER_IRQ_SHARED, | 43 | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL, |
44 | .load = via_driver_load, | 44 | .load = via_driver_load, |
45 | .unload = via_driver_unload, | 45 | .unload = via_driver_unload, |
46 | .context_dtor = via_final_context, | 46 | .context_dtor = via_final_context, |
47 | .get_vblank_counter = via_get_vblank_counter, | 47 | .vblank_wait = via_driver_vblank_wait, |
48 | .enable_vblank = via_enable_vblank, | ||
49 | .disable_vblank = via_disable_vblank, | ||
50 | .irq_preinstall = via_driver_irq_preinstall, | 48 | .irq_preinstall = via_driver_irq_preinstall, |
51 | .irq_postinstall = via_driver_irq_postinstall, | 49 | .irq_postinstall = via_driver_irq_postinstall, |
52 | .irq_uninstall = via_driver_irq_uninstall, | 50 | .irq_uninstall = via_driver_irq_uninstall, |
diff --git a/drivers/char/drm/via_drv.h b/drivers/char/drm/via_drv.h index fe67030e39ac..2daae81874cd 100644 --- a/drivers/char/drm/via_drv.h +++ b/drivers/char/drm/via_drv.h | |||
@@ -75,7 +75,6 @@ typedef struct drm_via_private { | |||
75 | struct timeval last_vblank; | 75 | struct timeval last_vblank; |
76 | int last_vblank_valid; | 76 | int last_vblank_valid; |
77 | unsigned usec_per_vblank; | 77 | unsigned usec_per_vblank; |
78 | atomic_t vbl_received; | ||
79 | drm_via_state_t hc_state; | 78 | drm_via_state_t hc_state; |
80 | char pci_buf[VIA_PCI_BUF_SIZE]; | 79 | char pci_buf[VIA_PCI_BUF_SIZE]; |
81 | const uint32_t *fire_offsets[VIA_FIRE_BUF_SIZE]; | 80 | const uint32_t *fire_offsets[VIA_FIRE_BUF_SIZE]; |
@@ -131,13 +130,11 @@ extern int via_init_context(struct drm_device * dev, int context); | |||
131 | extern int via_final_context(struct drm_device * dev, int context); | 130 | extern int via_final_context(struct drm_device * dev, int context); |
132 | 131 | ||
133 | extern int via_do_cleanup_map(struct drm_device * dev); | 132 | extern int via_do_cleanup_map(struct drm_device * dev); |
134 | extern u32 via_get_vblank_counter(struct drm_device *dev, int crtc); | 133 | extern int via_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence); |
135 | extern int via_enable_vblank(struct drm_device *dev, int crtc); | ||
136 | extern void via_disable_vblank(struct drm_device *dev, int crtc); | ||
137 | 134 | ||
138 | extern irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS); | 135 | extern irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS); |
139 | extern void via_driver_irq_preinstall(struct drm_device * dev); | 136 | extern void via_driver_irq_preinstall(struct drm_device * dev); |
140 | extern int via_driver_irq_postinstall(struct drm_device * dev); | 137 | extern void via_driver_irq_postinstall(struct drm_device * dev); |
141 | extern void via_driver_irq_uninstall(struct drm_device * dev); | 138 | extern void via_driver_irq_uninstall(struct drm_device * dev); |
142 | 139 | ||
143 | extern int via_dma_cleanup(struct drm_device * dev); | 140 | extern int via_dma_cleanup(struct drm_device * dev); |
diff --git a/drivers/char/drm/via_irq.c b/drivers/char/drm/via_irq.c index f1ab6fc7c07e..c6bb978a1106 100644 --- a/drivers/char/drm/via_irq.c +++ b/drivers/char/drm/via_irq.c | |||
@@ -92,17 +92,8 @@ static int via_irqmap_unichrome[] = {-1, -1, -1, 0, -1, 1}; | |||
92 | static unsigned time_diff(struct timeval *now, struct timeval *then) | 92 | static unsigned time_diff(struct timeval *now, struct timeval *then) |
93 | { | 93 | { |
94 | return (now->tv_usec >= then->tv_usec) ? | 94 | return (now->tv_usec >= then->tv_usec) ? |
95 | now->tv_usec - then->tv_usec : | 95 | now->tv_usec - then->tv_usec : |
96 | 1000000 - (then->tv_usec - now->tv_usec); | 96 | 1000000 - (then->tv_usec - now->tv_usec); |
97 | } | ||
98 | |||
99 | u32 via_get_vblank_counter(struct drm_device *dev, int crtc) | ||
100 | { | ||
101 | drm_via_private_t *dev_priv = dev->dev_private; | ||
102 | if (crtc != 0) | ||
103 | return 0; | ||
104 | |||
105 | return atomic_read(&dev_priv->vbl_received); | ||
106 | } | 97 | } |
107 | 98 | ||
108 | irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS) | 99 | irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS) |
@@ -117,8 +108,8 @@ irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS) | |||
117 | 108 | ||
118 | status = VIA_READ(VIA_REG_INTERRUPT); | 109 | status = VIA_READ(VIA_REG_INTERRUPT); |
119 | if (status & VIA_IRQ_VBLANK_PENDING) { | 110 | if (status & VIA_IRQ_VBLANK_PENDING) { |
120 | atomic_inc(&dev_priv->vbl_received); | 111 | atomic_inc(&dev->vbl_received); |
121 | if (!(atomic_read(&dev_priv->vbl_received) & 0x0F)) { | 112 | if (!(atomic_read(&dev->vbl_received) & 0x0F)) { |
122 | do_gettimeofday(&cur_vblank); | 113 | do_gettimeofday(&cur_vblank); |
123 | if (dev_priv->last_vblank_valid) { | 114 | if (dev_priv->last_vblank_valid) { |
124 | dev_priv->usec_per_vblank = | 115 | dev_priv->usec_per_vblank = |
@@ -128,11 +119,12 @@ irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS) | |||
128 | dev_priv->last_vblank = cur_vblank; | 119 | dev_priv->last_vblank = cur_vblank; |
129 | dev_priv->last_vblank_valid = 1; | 120 | dev_priv->last_vblank_valid = 1; |
130 | } | 121 | } |
131 | if (!(atomic_read(&dev_priv->vbl_received) & 0xFF)) { | 122 | if (!(atomic_read(&dev->vbl_received) & 0xFF)) { |
132 | DRM_DEBUG("US per vblank is: %u\n", | 123 | DRM_DEBUG("US per vblank is: %u\n", |
133 | dev_priv->usec_per_vblank); | 124 | dev_priv->usec_per_vblank); |
134 | } | 125 | } |
135 | drm_handle_vblank(dev, 0); | 126 | DRM_WAKEUP(&dev->vbl_queue); |
127 | drm_vbl_send_signals(dev); | ||
136 | handled = 1; | 128 | handled = 1; |
137 | } | 129 | } |
138 | 130 | ||
@@ -171,34 +163,31 @@ static __inline__ void viadrv_acknowledge_irqs(drm_via_private_t * dev_priv) | |||
171 | } | 163 | } |
172 | } | 164 | } |
173 | 165 | ||
174 | int via_enable_vblank(struct drm_device *dev, int crtc) | 166 | int via_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence) |
175 | { | 167 | { |
176 | drm_via_private_t *dev_priv = dev->dev_private; | 168 | drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; |
177 | u32 status; | 169 | unsigned int cur_vblank; |
170 | int ret = 0; | ||
178 | 171 | ||
179 | if (crtc != 0) { | 172 | DRM_DEBUG("\n"); |
180 | DRM_ERROR("%s: bad crtc %d\n", __FUNCTION__, crtc); | 173 | if (!dev_priv) { |
174 | DRM_ERROR("called with no initialization\n"); | ||
181 | return -EINVAL; | 175 | return -EINVAL; |
182 | } | 176 | } |
183 | 177 | ||
184 | status = VIA_READ(VIA_REG_INTERRUPT); | 178 | viadrv_acknowledge_irqs(dev_priv); |
185 | VIA_WRITE(VIA_REG_INTERRUPT, status & VIA_IRQ_VBLANK_ENABLE); | ||
186 | 179 | ||
187 | VIA_WRITE8(0x83d4, 0x11); | 180 | /* Assume that the user has missed the current sequence number |
188 | VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30); | 181 | * by about a day rather than she wants to wait for years |
182 | * using vertical blanks... | ||
183 | */ | ||
189 | 184 | ||
190 | return 0; | 185 | DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, |
191 | } | 186 | (((cur_vblank = atomic_read(&dev->vbl_received)) - |
187 | *sequence) <= (1 << 23))); | ||
192 | 188 | ||
193 | void via_disable_vblank(struct drm_device *dev, int crtc) | 189 | *sequence = cur_vblank; |
194 | { | 190 | return ret; |
195 | drm_via_private_t *dev_priv = dev->dev_private; | ||
196 | |||
197 | VIA_WRITE8(0x83d4, 0x11); | ||
198 | VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) & ~0x30); | ||
199 | |||
200 | if (crtc != 0) | ||
201 | DRM_ERROR("%s: bad crtc %d\n", __FUNCTION__, crtc); | ||
202 | } | 191 | } |
203 | 192 | ||
204 | static int | 193 | static int |
@@ -303,25 +292,23 @@ void via_driver_irq_preinstall(struct drm_device * dev) | |||
303 | } | 292 | } |
304 | } | 293 | } |
305 | 294 | ||
306 | int via_driver_irq_postinstall(struct drm_device * dev) | 295 | void via_driver_irq_postinstall(struct drm_device * dev) |
307 | { | 296 | { |
308 | drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; | 297 | drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; |
309 | u32 status; | 298 | u32 status; |
310 | 299 | ||
311 | DRM_DEBUG("via_driver_irq_postinstall\n"); | 300 | DRM_DEBUG("\n"); |
312 | if (!dev_priv) | 301 | if (dev_priv) { |
313 | return -EINVAL; | 302 | status = VIA_READ(VIA_REG_INTERRUPT); |
303 | VIA_WRITE(VIA_REG_INTERRUPT, status | VIA_IRQ_GLOBAL | ||
304 | | dev_priv->irq_enable_mask); | ||
314 | 305 | ||
315 | drm_vblank_init(dev, 1); | 306 | /* Some magic, oh for some data sheets ! */ |
316 | status = VIA_READ(VIA_REG_INTERRUPT); | ||
317 | VIA_WRITE(VIA_REG_INTERRUPT, status | VIA_IRQ_GLOBAL | ||
318 | | dev_priv->irq_enable_mask); | ||
319 | 307 | ||
320 | /* Some magic, oh for some data sheets ! */ | 308 | VIA_WRITE8(0x83d4, 0x11); |
321 | VIA_WRITE8(0x83d4, 0x11); | 309 | VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30); |
322 | VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30); | ||
323 | 310 | ||
324 | return 0; | 311 | } |
325 | } | 312 | } |
326 | 313 | ||
327 | void via_driver_irq_uninstall(struct drm_device * dev) | 314 | void via_driver_irq_uninstall(struct drm_device * dev) |
diff --git a/drivers/char/generic_nvram.c b/drivers/char/generic_nvram.c index 2398e864c28d..a00869c650d5 100644 --- a/drivers/char/generic_nvram.c +++ b/drivers/char/generic_nvram.c | |||
@@ -133,7 +133,7 @@ static struct miscdevice nvram_dev = { | |||
133 | 133 | ||
134 | int __init nvram_init(void) | 134 | int __init nvram_init(void) |
135 | { | 135 | { |
136 | printk(KERN_INFO "Macintosh non-volatile memory driver v%s\n", | 136 | printk(KERN_INFO "Generic non-volatile memory driver v%s\n", |
137 | NVRAM_VERSION); | 137 | NVRAM_VERSION); |
138 | return misc_register(&nvram_dev); | 138 | return misc_register(&nvram_dev); |
139 | } | 139 | } |
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig index 8d6c2089d2a8..efd0b4db7c8e 100644 --- a/drivers/char/hw_random/Kconfig +++ b/drivers/char/hw_random/Kconfig | |||
@@ -112,3 +112,12 @@ config HW_RANDOM_PASEMI | |||
112 | 112 | ||
113 | If unsure, say Y. | 113 | If unsure, say Y. |
114 | 114 | ||
115 | config HW_RANDOM_VIRTIO | ||
116 | tristate "VirtIO Random Number Generator support" | ||
117 | depends on HW_RANDOM && VIRTIO | ||
118 | ---help--- | ||
119 | This driver provides kernel-side support for the virtual Random Number | ||
120 | Generator hardware. | ||
121 | |||
122 | To compile this driver as a module, choose M here: the | ||
123 | module will be called virtio-rng. If unsure, say N. | ||
diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile index c8b7300e2fb1..b4940ddbb35f 100644 --- a/drivers/char/hw_random/Makefile +++ b/drivers/char/hw_random/Makefile | |||
@@ -11,3 +11,4 @@ obj-$(CONFIG_HW_RANDOM_VIA) += via-rng.o | |||
11 | obj-$(CONFIG_HW_RANDOM_IXP4XX) += ixp4xx-rng.o | 11 | obj-$(CONFIG_HW_RANDOM_IXP4XX) += ixp4xx-rng.o |
12 | obj-$(CONFIG_HW_RANDOM_OMAP) += omap-rng.o | 12 | obj-$(CONFIG_HW_RANDOM_OMAP) += omap-rng.o |
13 | obj-$(CONFIG_HW_RANDOM_PASEMI) += pasemi-rng.o | 13 | obj-$(CONFIG_HW_RANDOM_PASEMI) += pasemi-rng.o |
14 | obj-$(CONFIG_HW_RANDOM_VIRTIO) += virtio-rng.o | ||
diff --git a/drivers/char/hw_random/intel-rng.c b/drivers/char/hw_random/intel-rng.c index 5cc651ef75eb..27fdc0866496 100644 --- a/drivers/char/hw_random/intel-rng.c +++ b/drivers/char/hw_random/intel-rng.c | |||
@@ -273,7 +273,7 @@ static int __init intel_rng_hw_init(void *_intel_rng_hw) | |||
273 | if (mfc != INTEL_FWH_MANUFACTURER_CODE || | 273 | if (mfc != INTEL_FWH_MANUFACTURER_CODE || |
274 | (dvc != INTEL_FWH_DEVICE_CODE_8M && | 274 | (dvc != INTEL_FWH_DEVICE_CODE_8M && |
275 | dvc != INTEL_FWH_DEVICE_CODE_4M)) { | 275 | dvc != INTEL_FWH_DEVICE_CODE_4M)) { |
276 | printk(KERN_ERR PFX "FWH not detected\n"); | 276 | printk(KERN_NOTICE PFX "FWH not detected\n"); |
277 | return -ENODEV; | 277 | return -ENODEV; |
278 | } | 278 | } |
279 | 279 | ||
diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c new file mode 100644 index 000000000000..d0e563e4fc39 --- /dev/null +++ b/drivers/char/hw_random/virtio-rng.c | |||
@@ -0,0 +1,155 @@ | |||
1 | /* | ||
2 | * Randomness driver for virtio | ||
3 | * Copyright (C) 2007, 2008 Rusty Russell IBM Corporation | ||
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 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | */ | ||
19 | #include <linux/err.h> | ||
20 | #include <linux/hw_random.h> | ||
21 | #include <linux/scatterlist.h> | ||
22 | #include <linux/spinlock.h> | ||
23 | #include <linux/virtio.h> | ||
24 | #include <linux/virtio_rng.h> | ||
25 | |||
26 | /* The host will fill any buffer we give it with sweet, sweet randomness. We | ||
27 | * give it 64 bytes at a time, and the hwrng framework takes it 4 bytes at a | ||
28 | * time. */ | ||
29 | #define RANDOM_DATA_SIZE 64 | ||
30 | |||
31 | static struct virtqueue *vq; | ||
32 | static u32 *random_data; | ||
33 | static unsigned int data_left; | ||
34 | static DECLARE_COMPLETION(have_data); | ||
35 | |||
36 | static void random_recv_done(struct virtqueue *vq) | ||
37 | { | ||
38 | int len; | ||
39 | |||
40 | /* We never get spurious callbacks. */ | ||
41 | if (!vq->vq_ops->get_buf(vq, &len)) | ||
42 | BUG(); | ||
43 | |||
44 | data_left = len / sizeof(random_data[0]); | ||
45 | complete(&have_data); | ||
46 | } | ||
47 | |||
48 | static void register_buffer(void) | ||
49 | { | ||
50 | struct scatterlist sg; | ||
51 | |||
52 | sg_init_one(&sg, random_data, RANDOM_DATA_SIZE); | ||
53 | /* There should always be room for one buffer. */ | ||
54 | if (vq->vq_ops->add_buf(vq, &sg, 0, 1, random_data) != 0) | ||
55 | BUG(); | ||
56 | vq->vq_ops->kick(vq); | ||
57 | } | ||
58 | |||
59 | /* At least we don't udelay() in a loop like some other drivers. */ | ||
60 | static int virtio_data_present(struct hwrng *rng, int wait) | ||
61 | { | ||
62 | if (data_left) | ||
63 | return 1; | ||
64 | |||
65 | if (!wait) | ||
66 | return 0; | ||
67 | |||
68 | wait_for_completion(&have_data); | ||
69 | return 1; | ||
70 | } | ||
71 | |||
72 | /* virtio_data_present() must have succeeded before this is called. */ | ||
73 | static int virtio_data_read(struct hwrng *rng, u32 *data) | ||
74 | { | ||
75 | BUG_ON(!data_left); | ||
76 | |||
77 | *data = random_data[--data_left]; | ||
78 | |||
79 | if (!data_left) { | ||
80 | init_completion(&have_data); | ||
81 | register_buffer(); | ||
82 | } | ||
83 | return sizeof(*data); | ||
84 | } | ||
85 | |||
86 | static struct hwrng virtio_hwrng = { | ||
87 | .name = "virtio", | ||
88 | .data_present = virtio_data_present, | ||
89 | .data_read = virtio_data_read, | ||
90 | }; | ||
91 | |||
92 | static int virtrng_probe(struct virtio_device *vdev) | ||
93 | { | ||
94 | int err; | ||
95 | |||
96 | /* We expect a single virtqueue. */ | ||
97 | vq = vdev->config->find_vq(vdev, 0, random_recv_done); | ||
98 | if (IS_ERR(vq)) | ||
99 | return PTR_ERR(vq); | ||
100 | |||
101 | err = hwrng_register(&virtio_hwrng); | ||
102 | if (err) { | ||
103 | vdev->config->del_vq(vq); | ||
104 | return err; | ||
105 | } | ||
106 | |||
107 | register_buffer(); | ||
108 | return 0; | ||
109 | } | ||
110 | |||
111 | static void virtrng_remove(struct virtio_device *vdev) | ||
112 | { | ||
113 | vdev->config->reset(vdev); | ||
114 | hwrng_unregister(&virtio_hwrng); | ||
115 | vdev->config->del_vq(vq); | ||
116 | } | ||
117 | |||
118 | static struct virtio_device_id id_table[] = { | ||
119 | { VIRTIO_ID_RNG, VIRTIO_DEV_ANY_ID }, | ||
120 | { 0 }, | ||
121 | }; | ||
122 | |||
123 | static struct virtio_driver virtio_rng = { | ||
124 | .driver.name = KBUILD_MODNAME, | ||
125 | .driver.owner = THIS_MODULE, | ||
126 | .id_table = id_table, | ||
127 | .probe = virtrng_probe, | ||
128 | .remove = __devexit_p(virtrng_remove), | ||
129 | }; | ||
130 | |||
131 | static int __init init(void) | ||
132 | { | ||
133 | int err; | ||
134 | |||
135 | random_data = kmalloc(RANDOM_DATA_SIZE, GFP_KERNEL); | ||
136 | if (!random_data) | ||
137 | return -ENOMEM; | ||
138 | |||
139 | err = register_virtio_driver(&virtio_rng); | ||
140 | if (err) | ||
141 | kfree(random_data); | ||
142 | return err; | ||
143 | } | ||
144 | |||
145 | static void __exit fini(void) | ||
146 | { | ||
147 | kfree(random_data); | ||
148 | unregister_virtio_driver(&virtio_rng); | ||
149 | } | ||
150 | module_init(init); | ||
151 | module_exit(fini); | ||
152 | |||
153 | MODULE_DEVICE_TABLE(virtio, id_table); | ||
154 | MODULE_DESCRIPTION("Virtio random number driver"); | ||
155 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/char/ip2/Makefile b/drivers/char/ip2/Makefile index 6bfe2543ddc2..939618f62fe1 100644 --- a/drivers/char/ip2/Makefile +++ b/drivers/char/ip2/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for the Computone IntelliPort Plus Driver | 2 | # Makefile for the Computone IntelliPort Plus Driver |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-$(CONFIG_COMPUTONE) += ip2.o ip2main.o | 5 | obj-$(CONFIG_COMPUTONE) += ip2.o |
6 | 6 | ||
7 | ip2-objs := ip2base.o | 7 | ip2-objs := ip2base.o ip2main.o |
8 | 8 | ||
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c index 70957acaa960..c12cf8fc4be0 100644 --- a/drivers/char/ip2/ip2main.c +++ b/drivers/char/ip2/ip2main.c | |||
@@ -346,27 +346,6 @@ have_requested_irq( char irq ) | |||
346 | } | 346 | } |
347 | 347 | ||
348 | /******************************************************************************/ | 348 | /******************************************************************************/ |
349 | /* Function: init_module() */ | ||
350 | /* Parameters: None */ | ||
351 | /* Returns: Success (0) */ | ||
352 | /* */ | ||
353 | /* Description: */ | ||
354 | /* This is a required entry point for an installable module. It simply calls */ | ||
355 | /* the driver initialisation function and returns what it returns. */ | ||
356 | /******************************************************************************/ | ||
357 | #ifdef MODULE | ||
358 | static int __init | ||
359 | ip2_init_module(void) | ||
360 | { | ||
361 | #ifdef IP2DEBUG_INIT | ||
362 | printk (KERN_DEBUG "Loading module ...\n" ); | ||
363 | #endif | ||
364 | return 0; | ||
365 | } | ||
366 | module_init(ip2_init_module); | ||
367 | #endif /* MODULE */ | ||
368 | |||
369 | /******************************************************************************/ | ||
370 | /* Function: cleanup_module() */ | 349 | /* Function: cleanup_module() */ |
371 | /* Parameters: None */ | 350 | /* Parameters: None */ |
372 | /* Returns: Nothing */ | 351 | /* Returns: Nothing */ |
@@ -779,8 +758,6 @@ out: | |||
779 | return err; | 758 | return err; |
780 | } | 759 | } |
781 | 760 | ||
782 | EXPORT_SYMBOL(ip2_loadmain); | ||
783 | |||
784 | /******************************************************************************/ | 761 | /******************************************************************************/ |
785 | /* Function: ip2_init_board() */ | 762 | /* Function: ip2_init_board() */ |
786 | /* Parameters: Index of board in configuration structure */ | 763 | /* Parameters: Index of board in configuration structure */ |
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index 7f7e798c1384..d9a0a53c842d 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c | |||
@@ -677,12 +677,7 @@ static void k_deadunicode(struct vc_data *vc, unsigned int value, char up_flag) | |||
677 | 677 | ||
678 | static void k_self(struct vc_data *vc, unsigned char value, char up_flag) | 678 | static void k_self(struct vc_data *vc, unsigned char value, char up_flag) |
679 | { | 679 | { |
680 | unsigned int uni; | 680 | k_unicode(vc, conv_8bit_to_uni(value), up_flag); |
681 | if (kbd->kbdmode == VC_UNICODE) | ||
682 | uni = value; | ||
683 | else | ||
684 | uni = conv_8bit_to_uni(value); | ||
685 | k_unicode(vc, uni, up_flag); | ||
686 | } | 681 | } |
687 | 682 | ||
688 | static void k_dead2(struct vc_data *vc, unsigned char value, char up_flag) | 683 | static void k_dead2(struct vc_data *vc, unsigned char value, char up_flag) |
diff --git a/drivers/char/pcmcia/ipwireless/hardware.c b/drivers/char/pcmcia/ipwireless/hardware.c index fa9d3c945f31..ba6340ae98af 100644 --- a/drivers/char/pcmcia/ipwireless/hardware.c +++ b/drivers/char/pcmcia/ipwireless/hardware.c | |||
@@ -251,10 +251,11 @@ struct ipw_hardware { | |||
251 | int init_loops; | 251 | int init_loops; |
252 | struct timer_list setup_timer; | 252 | struct timer_list setup_timer; |
253 | 253 | ||
254 | /* Flag if hw is ready to send next packet */ | ||
254 | int tx_ready; | 255 | int tx_ready; |
255 | struct list_head tx_queue[NL_NUM_OF_PRIORITIES]; | 256 | /* Count of pending packets to be sent */ |
256 | /* True if any packets are queued for transmission */ | ||
257 | int tx_queued; | 257 | int tx_queued; |
258 | struct list_head tx_queue[NL_NUM_OF_PRIORITIES]; | ||
258 | 259 | ||
259 | int rx_bytes_queued; | 260 | int rx_bytes_queued; |
260 | struct list_head rx_queue; | 261 | struct list_head rx_queue; |
@@ -404,6 +405,8 @@ static int do_send_fragment(struct ipw_hardware *hw, const unsigned char *data, | |||
404 | 405 | ||
405 | spin_lock_irqsave(&hw->spinlock, flags); | 406 | spin_lock_irqsave(&hw->spinlock, flags); |
406 | 407 | ||
408 | hw->tx_ready = 0; | ||
409 | |||
407 | if (hw->hw_version == HW_VERSION_1) { | 410 | if (hw->hw_version == HW_VERSION_1) { |
408 | outw((unsigned short) length, hw->base_port + IODWR); | 411 | outw((unsigned short) length, hw->base_port + IODWR); |
409 | 412 | ||
@@ -492,6 +495,7 @@ static int do_send_packet(struct ipw_hardware *hw, struct ipw_tx_packet *packet) | |||
492 | 495 | ||
493 | spin_lock_irqsave(&hw->spinlock, flags); | 496 | spin_lock_irqsave(&hw->spinlock, flags); |
494 | list_add(&packet->queue, &hw->tx_queue[0]); | 497 | list_add(&packet->queue, &hw->tx_queue[0]); |
498 | hw->tx_queued++; | ||
495 | spin_unlock_irqrestore(&hw->spinlock, flags); | 499 | spin_unlock_irqrestore(&hw->spinlock, flags); |
496 | } else { | 500 | } else { |
497 | if (packet->packet_callback) | 501 | if (packet->packet_callback) |
@@ -949,12 +953,10 @@ static int send_pending_packet(struct ipw_hardware *hw, int priority_limit) | |||
949 | unsigned long flags; | 953 | unsigned long flags; |
950 | 954 | ||
951 | spin_lock_irqsave(&hw->spinlock, flags); | 955 | spin_lock_irqsave(&hw->spinlock, flags); |
952 | if (hw->tx_queued && hw->tx_ready != 0) { | 956 | if (hw->tx_queued && hw->tx_ready) { |
953 | int priority; | 957 | int priority; |
954 | struct ipw_tx_packet *packet = NULL; | 958 | struct ipw_tx_packet *packet = NULL; |
955 | 959 | ||
956 | hw->tx_ready--; | ||
957 | |||
958 | /* Pick a packet */ | 960 | /* Pick a packet */ |
959 | for (priority = 0; priority < priority_limit; priority++) { | 961 | for (priority = 0; priority < priority_limit; priority++) { |
960 | if (!list_empty(&hw->tx_queue[priority])) { | 962 | if (!list_empty(&hw->tx_queue[priority])) { |
@@ -963,6 +965,7 @@ static int send_pending_packet(struct ipw_hardware *hw, int priority_limit) | |||
963 | struct ipw_tx_packet, | 965 | struct ipw_tx_packet, |
964 | queue); | 966 | queue); |
965 | 967 | ||
968 | hw->tx_queued--; | ||
966 | list_del(&packet->queue); | 969 | list_del(&packet->queue); |
967 | 970 | ||
968 | break; | 971 | break; |
@@ -973,6 +976,7 @@ static int send_pending_packet(struct ipw_hardware *hw, int priority_limit) | |||
973 | spin_unlock_irqrestore(&hw->spinlock, flags); | 976 | spin_unlock_irqrestore(&hw->spinlock, flags); |
974 | return 0; | 977 | return 0; |
975 | } | 978 | } |
979 | |||
976 | spin_unlock_irqrestore(&hw->spinlock, flags); | 980 | spin_unlock_irqrestore(&hw->spinlock, flags); |
977 | 981 | ||
978 | /* Send */ | 982 | /* Send */ |
@@ -1063,7 +1067,7 @@ static irqreturn_t ipwireless_handle_v1_interrupt(int irq, | |||
1063 | if (irqn & IR_TXINTR) { | 1067 | if (irqn & IR_TXINTR) { |
1064 | ack |= IR_TXINTR; | 1068 | ack |= IR_TXINTR; |
1065 | spin_lock_irqsave(&hw->spinlock, flags); | 1069 | spin_lock_irqsave(&hw->spinlock, flags); |
1066 | hw->tx_ready++; | 1070 | hw->tx_ready = 1; |
1067 | spin_unlock_irqrestore(&hw->spinlock, flags); | 1071 | spin_unlock_irqrestore(&hw->spinlock, flags); |
1068 | } | 1072 | } |
1069 | /* Received data */ | 1073 | /* Received data */ |
@@ -1170,7 +1174,7 @@ static irqreturn_t ipwireless_handle_v2_v3_interrupt(int irq, | |||
1170 | if (memrxdone & MEMRX_RX_DONE) { | 1174 | if (memrxdone & MEMRX_RX_DONE) { |
1171 | writew(0, &hw->memory_info_regs->memreg_rx_done); | 1175 | writew(0, &hw->memory_info_regs->memreg_rx_done); |
1172 | spin_lock_irqsave(&hw->spinlock, flags); | 1176 | spin_lock_irqsave(&hw->spinlock, flags); |
1173 | hw->tx_ready++; | 1177 | hw->tx_ready = 1; |
1174 | spin_unlock_irqrestore(&hw->spinlock, flags); | 1178 | spin_unlock_irqrestore(&hw->spinlock, flags); |
1175 | tx = 1; | 1179 | tx = 1; |
1176 | } | 1180 | } |
@@ -1234,7 +1238,7 @@ static void send_packet(struct ipw_hardware *hw, int priority, | |||
1234 | 1238 | ||
1235 | spin_lock_irqsave(&hw->spinlock, flags); | 1239 | spin_lock_irqsave(&hw->spinlock, flags); |
1236 | list_add_tail(&packet->queue, &hw->tx_queue[priority]); | 1240 | list_add_tail(&packet->queue, &hw->tx_queue[priority]); |
1237 | hw->tx_queued = 1; | 1241 | hw->tx_queued++; |
1238 | spin_unlock_irqrestore(&hw->spinlock, flags); | 1242 | spin_unlock_irqrestore(&hw->spinlock, flags); |
1239 | 1243 | ||
1240 | flush_packets_to_hw(hw); | 1244 | flush_packets_to_hw(hw); |
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c index 9e9bad8bdcf4..dbce1263bdff 100644 --- a/drivers/char/sysrq.c +++ b/drivers/char/sysrq.c | |||
@@ -402,6 +402,7 @@ static struct sysrq_key_op *sysrq_key_table[36] = { | |||
402 | &sysrq_showstate_blocked_op, /* w */ | 402 | &sysrq_showstate_blocked_op, /* w */ |
403 | /* x: May be registered on ppc/powerpc for xmon */ | 403 | /* x: May be registered on ppc/powerpc for xmon */ |
404 | NULL, /* x */ | 404 | NULL, /* x */ |
405 | /* y: May be registered on sparc64 for global register dump */ | ||
405 | NULL, /* y */ | 406 | NULL, /* y */ |
406 | NULL /* z */ | 407 | NULL /* z */ |
407 | }; | 408 | }; |
diff --git a/drivers/char/viocons.c b/drivers/char/viocons.c index 3d3e1c2b310f..65fb848e1cce 100644 --- a/drivers/char/viocons.c +++ b/drivers/char/viocons.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * Authors: Dave Boutcher <boutcher@us.ibm.com> | 7 | * Authors: Dave Boutcher <boutcher@us.ibm.com> |
8 | * Ryan Arnold <ryanarn@us.ibm.com> | 8 | * Ryan Arnold <ryanarn@us.ibm.com> |
9 | * Colin Devilbiss <devilbis@us.ibm.com> | 9 | * Colin Devilbiss <devilbis@us.ibm.com> |
10 | * Stephen Rothwell <sfr@au1.ibm.com> | 10 | * Stephen Rothwell |
11 | * | 11 | * |
12 | * (C) Copyright 2000, 2001, 2002, 2003, 2004 IBM Corporation | 12 | * (C) Copyright 2000, 2001, 2002, 2003, 2004 IBM Corporation |
13 | * | 13 | * |
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c index 58aad63831f4..c39ddaff5e8f 100644 --- a/drivers/char/viotape.c +++ b/drivers/char/viotape.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * Authors: Dave Boutcher <boutcher@us.ibm.com> | 6 | * Authors: Dave Boutcher <boutcher@us.ibm.com> |
7 | * Ryan Arnold <ryanarn@us.ibm.com> | 7 | * Ryan Arnold <ryanarn@us.ibm.com> |
8 | * Colin Devilbiss <devilbis@us.ibm.com> | 8 | * Colin Devilbiss <devilbis@us.ibm.com> |
9 | * Stephen Rothwell <sfr@au1.ibm.com> | 9 | * Stephen Rothwell |
10 | * | 10 | * |
11 | * (C) Copyright 2000-2004 IBM Corporation | 11 | * (C) Copyright 2000-2004 IBM Corporation |
12 | * | 12 | * |
diff --git a/drivers/char/vt.c b/drivers/char/vt.c index fa1ffbf2c621..935f1c207a1f 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c | |||
@@ -434,7 +434,7 @@ static void update_attr(struct vc_data *vc) | |||
434 | vc->vc_blink, vc->vc_underline, | 434 | vc->vc_blink, vc->vc_underline, |
435 | vc->vc_reverse ^ vc->vc_decscnm, vc->vc_italic); | 435 | vc->vc_reverse ^ vc->vc_decscnm, vc->vc_italic); |
436 | vc->vc_video_erase_char = (build_attr(vc, vc->vc_color, 1, vc->vc_blink, 0, vc->vc_decscnm, 0) << 8) | ' '; | 436 | vc->vc_video_erase_char = (build_attr(vc, vc->vc_color, 1, vc->vc_blink, 0, vc->vc_decscnm, 0) << 8) | ' '; |
437 | vc->vc_scrl_erase_char = (build_attr(vc, vc->vc_def_color, 1, false, false, false, false) << 8) | ' '; | 437 | vc->vc_scrl_erase_char = (build_attr(vc, vc->vc_def_color, 1, false, false, vc->vc_decscnm, false) << 8) | ' '; |
438 | } | 438 | } |
439 | 439 | ||
440 | /* Note: inverting the screen twice should revert to the original state */ | 440 | /* Note: inverting the screen twice should revert to the original state */ |
@@ -909,7 +909,7 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines) | |||
909 | 909 | ||
910 | if (vc->vc_tty) { | 910 | if (vc->vc_tty) { |
911 | struct winsize ws, *cws = &vc->vc_tty->winsize; | 911 | struct winsize ws, *cws = &vc->vc_tty->winsize; |
912 | unsigned long flags; | 912 | struct pid *pgrp = NULL; |
913 | 913 | ||
914 | memset(&ws, 0, sizeof(ws)); | 914 | memset(&ws, 0, sizeof(ws)); |
915 | ws.ws_row = vc->vc_rows; | 915 | ws.ws_row = vc->vc_rows; |
@@ -917,11 +917,14 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines) | |||
917 | ws.ws_ypixel = vc->vc_scan_lines; | 917 | ws.ws_ypixel = vc->vc_scan_lines; |
918 | 918 | ||
919 | mutex_lock(&vc->vc_tty->termios_mutex); | 919 | mutex_lock(&vc->vc_tty->termios_mutex); |
920 | spin_lock_irqsave(&vc->vc_tty->ctrl_lock, flags); | 920 | spin_lock_irq(&vc->vc_tty->ctrl_lock); |
921 | if ((ws.ws_row != cws->ws_row || ws.ws_col != cws->ws_col) && | 921 | if ((ws.ws_row != cws->ws_row || ws.ws_col != cws->ws_col)) |
922 | vc->vc_tty->pgrp) | 922 | pgrp = get_pid(vc->vc_tty->pgrp); |
923 | spin_unlock_irq(&vc->vc_tty->ctrl_lock); | ||
924 | if (pgrp) { | ||
923 | kill_pgrp(vc->vc_tty->pgrp, SIGWINCH, 1); | 925 | kill_pgrp(vc->vc_tty->pgrp, SIGWINCH, 1); |
924 | spin_unlock_irqrestore(&vc->vc_tty->ctrl_lock, flags); | 926 | put_pid(pgrp); |
927 | } | ||
925 | *cws = ws; | 928 | *cws = ws; |
926 | mutex_unlock(&vc->vc_tty->termios_mutex); | 929 | mutex_unlock(&vc->vc_tty->termios_mutex); |
927 | } | 930 | } |
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 7fce038fa57e..1d41496ed2f8 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -412,7 +412,7 @@ static int cpufreq_parse_governor(char *str_governor, unsigned int *policy, | |||
412 | int ret; | 412 | int ret; |
413 | 413 | ||
414 | mutex_unlock(&cpufreq_governor_mutex); | 414 | mutex_unlock(&cpufreq_governor_mutex); |
415 | ret = request_module(name); | 415 | ret = request_module("%s", name); |
416 | mutex_lock(&cpufreq_governor_mutex); | 416 | mutex_lock(&cpufreq_governor_mutex); |
417 | 417 | ||
418 | if (ret == 0) | 418 | if (ret == 0) |
@@ -625,7 +625,7 @@ static ssize_t store_scaling_setspeed(struct cpufreq_policy *policy, | |||
625 | unsigned int freq = 0; | 625 | unsigned int freq = 0; |
626 | unsigned int ret; | 626 | unsigned int ret; |
627 | 627 | ||
628 | if (!policy->governor->store_setspeed) | 628 | if (!policy->governor || !policy->governor->store_setspeed) |
629 | return -EINVAL; | 629 | return -EINVAL; |
630 | 630 | ||
631 | ret = sscanf(buf, "%u", &freq); | 631 | ret = sscanf(buf, "%u", &freq); |
@@ -639,7 +639,7 @@ static ssize_t store_scaling_setspeed(struct cpufreq_policy *policy, | |||
639 | 639 | ||
640 | static ssize_t show_scaling_setspeed(struct cpufreq_policy *policy, char *buf) | 640 | static ssize_t show_scaling_setspeed(struct cpufreq_policy *policy, char *buf) |
641 | { | 641 | { |
642 | if (!policy->governor->show_setspeed) | 642 | if (!policy->governor || !policy->governor->show_setspeed) |
643 | return sprintf(buf, "<unsupported>\n"); | 643 | return sprintf(buf, "<unsupported>\n"); |
644 | 644 | ||
645 | return policy->governor->show_setspeed(policy, buf); | 645 | return policy->governor->show_setspeed(policy, buf); |
@@ -928,13 +928,13 @@ static int cpufreq_add_dev(struct sys_device *sys_dev) | |||
928 | policy->user_policy.policy = policy->policy; | 928 | policy->user_policy.policy = policy->policy; |
929 | policy->user_policy.governor = policy->governor; | 929 | policy->user_policy.governor = policy->governor; |
930 | 930 | ||
931 | unlock_policy_rwsem_write(cpu); | ||
932 | |||
933 | if (ret) { | 931 | if (ret) { |
934 | dprintk("setting policy failed\n"); | 932 | dprintk("setting policy failed\n"); |
935 | goto err_out_unregister; | 933 | goto err_out_unregister; |
936 | } | 934 | } |
937 | 935 | ||
936 | unlock_policy_rwsem_write(cpu); | ||
937 | |||
938 | kobject_uevent(&policy->kobj, KOBJ_ADD); | 938 | kobject_uevent(&policy->kobj, KOBJ_ADD); |
939 | module_put(cpufreq_driver->owner); | 939 | module_put(cpufreq_driver->owner); |
940 | dprintk("initialization complete\n"); | 940 | dprintk("initialization complete\n"); |
diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c index ae6cd60d5c14..b64c6bc445e3 100644 --- a/drivers/cpufreq/freq_table.c +++ b/drivers/cpufreq/freq_table.c | |||
@@ -2,6 +2,11 @@ | |||
2 | * linux/drivers/cpufreq/freq_table.c | 2 | * linux/drivers/cpufreq/freq_table.c |
3 | * | 3 | * |
4 | * Copyright (C) 2002 - 2003 Dominik Brodowski | 4 | * Copyright (C) 2002 - 2003 Dominik Brodowski |
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
5 | */ | 10 | */ |
6 | 11 | ||
7 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index fc555a90bb21..23554b676d6e 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c | |||
@@ -38,6 +38,8 @@ static void cpuidle_kick_cpus(void) | |||
38 | static void cpuidle_kick_cpus(void) {} | 38 | static void cpuidle_kick_cpus(void) {} |
39 | #endif | 39 | #endif |
40 | 40 | ||
41 | static int __cpuidle_register_device(struct cpuidle_device *dev); | ||
42 | |||
41 | /** | 43 | /** |
42 | * cpuidle_idle_call - the main idle loop | 44 | * cpuidle_idle_call - the main idle loop |
43 | * | 45 | * |
@@ -138,6 +140,12 @@ int cpuidle_enable_device(struct cpuidle_device *dev) | |||
138 | if (!dev->state_count) | 140 | if (!dev->state_count) |
139 | return -EINVAL; | 141 | return -EINVAL; |
140 | 142 | ||
143 | if (dev->registered == 0) { | ||
144 | ret = __cpuidle_register_device(dev); | ||
145 | if (ret) | ||
146 | return ret; | ||
147 | } | ||
148 | |||
141 | if ((ret = cpuidle_add_state_sysfs(dev))) | 149 | if ((ret = cpuidle_add_state_sysfs(dev))) |
142 | return ret; | 150 | return ret; |
143 | 151 | ||
@@ -232,10 +240,13 @@ static void poll_idle_init(struct cpuidle_device *dev) {} | |||
232 | #endif /* CONFIG_ARCH_HAS_CPU_RELAX */ | 240 | #endif /* CONFIG_ARCH_HAS_CPU_RELAX */ |
233 | 241 | ||
234 | /** | 242 | /** |
235 | * cpuidle_register_device - registers a CPU's idle PM feature | 243 | * __cpuidle_register_device - internal register function called before register |
244 | * and enable routines | ||
236 | * @dev: the cpu | 245 | * @dev: the cpu |
246 | * | ||
247 | * cpuidle_lock mutex must be held before this is called | ||
237 | */ | 248 | */ |
238 | int cpuidle_register_device(struct cpuidle_device *dev) | 249 | static int __cpuidle_register_device(struct cpuidle_device *dev) |
239 | { | 250 | { |
240 | int ret; | 251 | int ret; |
241 | struct sys_device *sys_dev = get_cpu_sysdev((unsigned long)dev->cpu); | 252 | struct sys_device *sys_dev = get_cpu_sysdev((unsigned long)dev->cpu); |
@@ -247,18 +258,34 @@ int cpuidle_register_device(struct cpuidle_device *dev) | |||
247 | 258 | ||
248 | init_completion(&dev->kobj_unregister); | 259 | init_completion(&dev->kobj_unregister); |
249 | 260 | ||
250 | mutex_lock(&cpuidle_lock); | ||
251 | |||
252 | poll_idle_init(dev); | 261 | poll_idle_init(dev); |
253 | 262 | ||
254 | per_cpu(cpuidle_devices, dev->cpu) = dev; | 263 | per_cpu(cpuidle_devices, dev->cpu) = dev; |
255 | list_add(&dev->device_list, &cpuidle_detected_devices); | 264 | list_add(&dev->device_list, &cpuidle_detected_devices); |
256 | if ((ret = cpuidle_add_sysfs(sys_dev))) { | 265 | if ((ret = cpuidle_add_sysfs(sys_dev))) { |
257 | mutex_unlock(&cpuidle_lock); | ||
258 | module_put(cpuidle_curr_driver->owner); | 266 | module_put(cpuidle_curr_driver->owner); |
259 | return ret; | 267 | return ret; |
260 | } | 268 | } |
261 | 269 | ||
270 | dev->registered = 1; | ||
271 | return 0; | ||
272 | } | ||
273 | |||
274 | /** | ||
275 | * cpuidle_register_device - registers a CPU's idle PM feature | ||
276 | * @dev: the cpu | ||
277 | */ | ||
278 | int cpuidle_register_device(struct cpuidle_device *dev) | ||
279 | { | ||
280 | int ret; | ||
281 | |||
282 | mutex_lock(&cpuidle_lock); | ||
283 | |||
284 | if ((ret = __cpuidle_register_device(dev))) { | ||
285 | mutex_unlock(&cpuidle_lock); | ||
286 | return ret; | ||
287 | } | ||
288 | |||
262 | cpuidle_enable_device(dev); | 289 | cpuidle_enable_device(dev); |
263 | cpuidle_install_idle_handler(); | 290 | cpuidle_install_idle_handler(); |
264 | 291 | ||
@@ -278,6 +305,9 @@ void cpuidle_unregister_device(struct cpuidle_device *dev) | |||
278 | { | 305 | { |
279 | struct sys_device *sys_dev = get_cpu_sysdev((unsigned long)dev->cpu); | 306 | struct sys_device *sys_dev = get_cpu_sysdev((unsigned long)dev->cpu); |
280 | 307 | ||
308 | if (dev->registered == 0) | ||
309 | return; | ||
310 | |||
281 | cpuidle_pause_and_lock(); | 311 | cpuidle_pause_and_lock(); |
282 | 312 | ||
283 | cpuidle_disable_device(dev); | 313 | cpuidle_disable_device(dev); |
diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c index 762b729672e0..0ec0f431e6a1 100644 --- a/drivers/dma/iop-adma.c +++ b/drivers/dma/iop-adma.c | |||
@@ -821,10 +821,10 @@ static int __devinit iop_adma_memcpy_self_test(struct iop_adma_device *device) | |||
821 | 821 | ||
822 | dev_dbg(device->common.dev, "%s\n", __func__); | 822 | dev_dbg(device->common.dev, "%s\n", __func__); |
823 | 823 | ||
824 | src = kzalloc(sizeof(u8) * IOP_ADMA_TEST_SIZE, GFP_KERNEL); | 824 | src = kmalloc(IOP_ADMA_TEST_SIZE, GFP_KERNEL); |
825 | if (!src) | 825 | if (!src) |
826 | return -ENOMEM; | 826 | return -ENOMEM; |
827 | dest = kzalloc(sizeof(u8) * IOP_ADMA_TEST_SIZE, GFP_KERNEL); | 827 | dest = kzalloc(IOP_ADMA_TEST_SIZE, GFP_KERNEL); |
828 | if (!dest) { | 828 | if (!dest) { |
829 | kfree(src); | 829 | kfree(src); |
830 | return -ENOMEM; | 830 | return -ENOMEM; |
@@ -834,8 +834,6 @@ static int __devinit iop_adma_memcpy_self_test(struct iop_adma_device *device) | |||
834 | for (i = 0; i < IOP_ADMA_TEST_SIZE; i++) | 834 | for (i = 0; i < IOP_ADMA_TEST_SIZE; i++) |
835 | ((u8 *) src)[i] = (u8)i; | 835 | ((u8 *) src)[i] = (u8)i; |
836 | 836 | ||
837 | memset(dest, 0, IOP_ADMA_TEST_SIZE); | ||
838 | |||
839 | /* Start copy, using first DMA channel */ | 837 | /* Start copy, using first DMA channel */ |
840 | dma_chan = container_of(device->common.channels.next, | 838 | dma_chan = container_of(device->common.channels.next, |
841 | struct dma_chan, | 839 | struct dma_chan, |
diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c index 065732ddf40c..d49361bfe670 100644 --- a/drivers/edac/mpc85xx_edac.c +++ b/drivers/edac/mpc85xx_edac.c | |||
@@ -20,7 +20,6 @@ | |||
20 | 20 | ||
21 | #include <linux/of_platform.h> | 21 | #include <linux/of_platform.h> |
22 | #include <linux/of_device.h> | 22 | #include <linux/of_device.h> |
23 | #include <asm/mpc85xx.h> | ||
24 | #include "edac_module.h" | 23 | #include "edac_module.h" |
25 | #include "edac_core.h" | 24 | #include "edac_core.h" |
26 | #include "mpc85xx_edac.h" | 25 | #include "mpc85xx_edac.h" |
@@ -43,8 +42,6 @@ static u32 orig_pci_err_en; | |||
43 | static u32 orig_l2_err_disable; | 42 | static u32 orig_l2_err_disable; |
44 | static u32 orig_hid1; | 43 | static u32 orig_hid1; |
45 | 44 | ||
46 | static const char *mpc85xx_ctl_name = "MPC85xx"; | ||
47 | |||
48 | /************************ MC SYSFS parts ***********************************/ | 45 | /************************ MC SYSFS parts ***********************************/ |
49 | 46 | ||
50 | static ssize_t mpc85xx_mc_inject_data_hi_show(struct mem_ctl_info *mci, | 47 | static ssize_t mpc85xx_mc_inject_data_hi_show(struct mem_ctl_info *mci, |
diff --git a/drivers/firewire/fw-cdev.c b/drivers/firewire/fw-cdev.c index 4a541921a14a..dda14015e873 100644 --- a/drivers/firewire/fw-cdev.c +++ b/drivers/firewire/fw-cdev.c | |||
@@ -113,6 +113,11 @@ static int fw_device_op_open(struct inode *inode, struct file *file) | |||
113 | if (device == NULL) | 113 | if (device == NULL) |
114 | return -ENODEV; | 114 | return -ENODEV; |
115 | 115 | ||
116 | if (fw_device_is_shutdown(device)) { | ||
117 | fw_device_put(device); | ||
118 | return -ENODEV; | ||
119 | } | ||
120 | |||
116 | client = kzalloc(sizeof(*client), GFP_KERNEL); | 121 | client = kzalloc(sizeof(*client), GFP_KERNEL); |
117 | if (client == NULL) { | 122 | if (client == NULL) { |
118 | fw_device_put(device); | 123 | fw_device_put(device); |
@@ -901,6 +906,9 @@ fw_device_op_ioctl(struct file *file, | |||
901 | { | 906 | { |
902 | struct client *client = file->private_data; | 907 | struct client *client = file->private_data; |
903 | 908 | ||
909 | if (fw_device_is_shutdown(client->device)) | ||
910 | return -ENODEV; | ||
911 | |||
904 | return dispatch_ioctl(client, cmd, (void __user *) arg); | 912 | return dispatch_ioctl(client, cmd, (void __user *) arg); |
905 | } | 913 | } |
906 | 914 | ||
@@ -911,6 +919,9 @@ fw_device_op_compat_ioctl(struct file *file, | |||
911 | { | 919 | { |
912 | struct client *client = file->private_data; | 920 | struct client *client = file->private_data; |
913 | 921 | ||
922 | if (fw_device_is_shutdown(client->device)) | ||
923 | return -ENODEV; | ||
924 | |||
914 | return dispatch_ioctl(client, cmd, compat_ptr(arg)); | 925 | return dispatch_ioctl(client, cmd, compat_ptr(arg)); |
915 | } | 926 | } |
916 | #endif | 927 | #endif |
@@ -922,6 +933,9 @@ static int fw_device_op_mmap(struct file *file, struct vm_area_struct *vma) | |||
922 | unsigned long size; | 933 | unsigned long size; |
923 | int page_count, retval; | 934 | int page_count, retval; |
924 | 935 | ||
936 | if (fw_device_is_shutdown(client->device)) | ||
937 | return -ENODEV; | ||
938 | |||
925 | /* FIXME: We could support multiple buffers, but we don't. */ | 939 | /* FIXME: We could support multiple buffers, but we don't. */ |
926 | if (client->buffer.pages != NULL) | 940 | if (client->buffer.pages != NULL) |
927 | return -EBUSY; | 941 | return -EBUSY; |
diff --git a/drivers/firmware/edd.c b/drivers/firmware/edd.c index 744011989044..9e4f59dc7f1e 100644 --- a/drivers/firmware/edd.c +++ b/drivers/firmware/edd.c | |||
@@ -753,7 +753,7 @@ edd_init(void) | |||
753 | 753 | ||
754 | if (!edd_num_devices()) { | 754 | if (!edd_num_devices()) { |
755 | printk(KERN_INFO "EDD information not available.\n"); | 755 | printk(KERN_INFO "EDD information not available.\n"); |
756 | return 1; | 756 | return -ENODEV; |
757 | } | 757 | } |
758 | 758 | ||
759 | edd_kset = kset_create_and_add("edd", NULL, firmware_kobj); | 759 | edd_kset = kset_create_and_add("edd", NULL, firmware_kobj); |
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 7f138c6195ff..beaf6b3a37dc 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c | |||
@@ -127,7 +127,7 @@ int __init gpiochip_reserve(int start, int ngpio) | |||
127 | unsigned long flags; | 127 | unsigned long flags; |
128 | int i; | 128 | int i; |
129 | 129 | ||
130 | if (!gpio_is_valid(start) || !gpio_is_valid(start + ngpio)) | 130 | if (!gpio_is_valid(start) || !gpio_is_valid(start + ngpio - 1)) |
131 | return -EINVAL; | 131 | return -EINVAL; |
132 | 132 | ||
133 | spin_lock_irqsave(&gpio_lock, flags); | 133 | spin_lock_irqsave(&gpio_lock, flags); |
@@ -170,7 +170,7 @@ int gpiochip_add(struct gpio_chip *chip) | |||
170 | unsigned id; | 170 | unsigned id; |
171 | int base = chip->base; | 171 | int base = chip->base; |
172 | 172 | ||
173 | if ((!gpio_is_valid(base) || !gpio_is_valid(base + chip->ngpio)) | 173 | if ((!gpio_is_valid(base) || !gpio_is_valid(base + chip->ngpio - 1)) |
174 | && base >= 0) { | 174 | && base >= 0) { |
175 | status = -EINVAL; | 175 | status = -EINVAL; |
176 | goto fail; | 176 | goto fail; |
@@ -207,7 +207,7 @@ fail: | |||
207 | /* failures here can mean systems won't boot... */ | 207 | /* failures here can mean systems won't boot... */ |
208 | if (status) | 208 | if (status) |
209 | pr_err("gpiochip_add: gpios %d..%d (%s) not registered\n", | 209 | pr_err("gpiochip_add: gpios %d..%d (%s) not registered\n", |
210 | chip->base, chip->base + chip->ngpio, | 210 | chip->base, chip->base + chip->ngpio - 1, |
211 | chip->label ? : "generic"); | 211 | chip->label ? : "generic"); |
212 | return status; | 212 | return status; |
213 | } | 213 | } |
diff --git a/drivers/gpio/mcp23s08.c b/drivers/gpio/mcp23s08.c index 7fb5b9d009d4..7f92fdd5f0e2 100644 --- a/drivers/gpio/mcp23s08.c +++ b/drivers/gpio/mcp23s08.c | |||
@@ -168,7 +168,7 @@ static void mcp23s08_dbg_show(struct seq_file *s, struct gpio_chip *chip) | |||
168 | { | 168 | { |
169 | struct mcp23s08 *mcp; | 169 | struct mcp23s08 *mcp; |
170 | char bank; | 170 | char bank; |
171 | unsigned t; | 171 | int t; |
172 | unsigned mask; | 172 | unsigned mask; |
173 | 173 | ||
174 | mcp = container_of(chip, struct mcp23s08, chip); | 174 | mcp = container_of(chip, struct mcp23s08, chip); |
diff --git a/drivers/gpio/pca953x.c b/drivers/gpio/pca953x.c index 93f916720b13..7e40e8a55edf 100644 --- a/drivers/gpio/pca953x.c +++ b/drivers/gpio/pca953x.c | |||
@@ -30,6 +30,7 @@ static const struct i2c_device_id pca953x_id[] = { | |||
30 | { "pca9537", 4, }, | 30 | { "pca9537", 4, }, |
31 | { "pca9538", 8, }, | 31 | { "pca9538", 8, }, |
32 | { "pca9539", 16, }, | 32 | { "pca9539", 16, }, |
33 | { "pca9554", 8, }, | ||
33 | { "pca9555", 16, }, | 34 | { "pca9555", 16, }, |
34 | { "pca9557", 8, }, | 35 | { "pca9557", 8, }, |
35 | /* REVISIT several pca955x parts should work here too */ | 36 | /* REVISIT several pca955x parts should work here too */ |
diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c index f88714b06000..47ac1a7d66e1 100644 --- a/drivers/hid/hid-debug.c +++ b/drivers/hid/hid-debug.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: hid-debug.h,v 1.8 2001/09/25 09:37:57 vojtech Exp $ | ||
3 | * | ||
4 | * (c) 1999 Andreas Gal <gal@cs.uni-magdeburg.de> | 2 | * (c) 1999 Andreas Gal <gal@cs.uni-magdeburg.de> |
5 | * (c) 2000-2001 Vojtech Pavlik <vojtech@ucw.cz> | 3 | * (c) 2000-2001 Vojtech Pavlik <vojtech@ucw.cz> |
6 | * (c) 2007 Jiri Kosina | 4 | * (c) 2007 Jiri Kosina |
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index c3eb3f13e2ca..5c52a20ad344 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: hid-input.c,v 1.2 2002/04/23 00:59:25 rdamazio Exp $ | ||
3 | * | ||
4 | * Copyright (c) 2000-2001 Vojtech Pavlik | 2 | * Copyright (c) 2000-2001 Vojtech Pavlik |
5 | * Copyright (c) 2006-2007 Jiri Kosina | 3 | * Copyright (c) 2006-2007 Jiri Kosina |
6 | * | 4 | * |
@@ -218,8 +216,9 @@ int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, | |||
218 | } | 216 | } |
219 | } | 217 | } |
220 | 218 | ||
221 | if (test_bit(usage->code, hid->pb_pressed_numlock) || | 219 | if (hid->quirks & HID_QUIRK_APPLE_NUMLOCK_EMULATION && ( |
222 | test_bit(LED_NUML, input->led)) { | 220 | test_bit(usage->code, hid->pb_pressed_numlock) || |
221 | test_bit(LED_NUML, input->led))) { | ||
223 | trans = find_translation(powerbook_numlock_keys, usage->code); | 222 | trans = find_translation(powerbook_numlock_keys, usage->code); |
224 | 223 | ||
225 | if (trans) { | 224 | if (trans) { |
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index d3f8d9194f30..1df832a8fcbc 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c | |||
@@ -325,6 +325,10 @@ | |||
325 | #define USB_DEVICE_ID_MGE_UPS 0xffff | 325 | #define USB_DEVICE_ID_MGE_UPS 0xffff |
326 | #define USB_DEVICE_ID_MGE_UPS1 0x0001 | 326 | #define USB_DEVICE_ID_MGE_UPS1 0x0001 |
327 | 327 | ||
328 | #define USB_VENDOR_ID_MICROCHIP 0x04d8 | ||
329 | #define USB_DEVICE_ID_PICKIT1 0x0032 | ||
330 | #define USB_DEVICE_ID_PICKIT2 0x0033 | ||
331 | |||
328 | #define USB_VENDOR_ID_MICROSOFT 0x045e | 332 | #define USB_VENDOR_ID_MICROSOFT 0x045e |
329 | #define USB_DEVICE_ID_SIDEWINDER_GV 0x003b | 333 | #define USB_DEVICE_ID_SIDEWINDER_GV 0x003b |
330 | #define USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0 0x009d | 334 | #define USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0 0x009d |
@@ -371,6 +375,9 @@ | |||
371 | #define USB_VENDOR_ID_SONY 0x054c | 375 | #define USB_VENDOR_ID_SONY 0x054c |
372 | #define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268 | 376 | #define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268 |
373 | 377 | ||
378 | #define USB_VENDOR_ID_SOUNDGRAPH 0x15c2 | ||
379 | #define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD 0x0038 | ||
380 | |||
374 | #define USB_VENDOR_ID_SUN 0x0430 | 381 | #define USB_VENDOR_ID_SUN 0x0430 |
375 | #define USB_DEVICE_ID_RARITAN_KVM_DONGLE 0xcdab | 382 | #define USB_DEVICE_ID_RARITAN_KVM_DONGLE 0xcdab |
376 | 383 | ||
@@ -567,6 +574,7 @@ static const struct hid_blacklist { | |||
567 | { USB_VENDOR_ID_PANJIT, 0x0002, HID_QUIRK_IGNORE }, | 574 | { USB_VENDOR_ID_PANJIT, 0x0002, HID_QUIRK_IGNORE }, |
568 | { USB_VENDOR_ID_PANJIT, 0x0003, HID_QUIRK_IGNORE }, | 575 | { USB_VENDOR_ID_PANJIT, 0x0003, HID_QUIRK_IGNORE }, |
569 | { USB_VENDOR_ID_PANJIT, 0x0004, HID_QUIRK_IGNORE }, | 576 | { USB_VENDOR_ID_PANJIT, 0x0004, HID_QUIRK_IGNORE }, |
577 | { USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD, HID_QUIRK_IGNORE }, | ||
570 | { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO, HID_QUIRK_IGNORE }, | 578 | { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO, HID_QUIRK_IGNORE }, |
571 | { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP, HID_QUIRK_IGNORE }, | 579 | { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP, HID_QUIRK_IGNORE }, |
572 | { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP, HID_QUIRK_IGNORE }, | 580 | { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP, HID_QUIRK_IGNORE }, |
@@ -580,6 +588,9 @@ static const struct hid_blacklist { | |||
580 | { USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_FLAIR, HID_QUIRK_IGNORE }, | 588 | { USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_FLAIR, HID_QUIRK_IGNORE }, |
581 | { USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_302, HID_QUIRK_IGNORE }, | 589 | { USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_302, HID_QUIRK_IGNORE }, |
582 | 590 | ||
591 | { USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICKIT1, HID_QUIRK_IGNORE }, | ||
592 | { USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICKIT2, HID_QUIRK_IGNORE }, | ||
593 | |||
583 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD, HID_QUIRK_LOGITECH_IGNORE_DOUBLED_WHEEL | HID_QUIRK_LOGITECH_EXPANDED_KEYMAP }, | 594 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD, HID_QUIRK_LOGITECH_IGNORE_DOUBLED_WHEEL | HID_QUIRK_LOGITECH_EXPANDED_KEYMAP }, |
584 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500, HID_QUIRK_LOGITECH_IGNORE_DOUBLED_WHEEL | HID_QUIRK_LOGITECH_EXPANDED_KEYMAP }, | 595 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500, HID_QUIRK_LOGITECH_IGNORE_DOUBLED_WHEEL | HID_QUIRK_LOGITECH_EXPANDED_KEYMAP }, |
585 | 596 | ||
@@ -611,28 +622,28 @@ static const struct hid_blacklist { | |||
611 | 622 | ||
612 | { USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, | 623 | { USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, |
613 | 624 | ||
614 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, | 625 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, |
615 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, | 626 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, |
616 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, | 627 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, |
617 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_APPLE_ISO_KEYBOARD}, | 628 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_APPLE_ISO_KEYBOARD}, |
618 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, | 629 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, |
619 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, | 630 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, |
620 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_APPLE_ISO_KEYBOARD}, | 631 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_APPLE_ISO_KEYBOARD}, |
621 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, | 632 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, |
622 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, | 633 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, |
623 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_APPLE_ISO_KEYBOARD}, | 634 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_APPLE_ISO_KEYBOARD}, |
624 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, | 635 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, |
625 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ANSI, HID_QUIRK_APPLE_HAS_FN }, | 636 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ANSI, HID_QUIRK_APPLE_HAS_FN }, |
626 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD }, | 637 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD }, |
627 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_JIS, HID_QUIRK_APPLE_HAS_FN }, | 638 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_JIS, HID_QUIRK_APPLE_HAS_FN }, |
628 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, | 639 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, |
629 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, | 640 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, |
630 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, | 641 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, |
631 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI, HID_QUIRK_APPLE_HAS_FN }, | 642 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN }, |
632 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD }, | 643 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD }, |
633 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS, HID_QUIRK_APPLE_HAS_FN }, | 644 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN }, |
634 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, | 645 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, |
635 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, | 646 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, |
636 | 647 | ||
637 | { USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_W7658, HID_QUIRK_RESET_LEDS }, | 648 | { USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_W7658, HID_QUIRK_RESET_LEDS }, |
638 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KBD, HID_QUIRK_RESET_LEDS }, | 649 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KBD, HID_QUIRK_RESET_LEDS }, |
diff --git a/drivers/hid/usbhid/usbkbd.c b/drivers/hid/usbhid/usbkbd.c index 5d9dbb47e4a8..3cd46d2e53c1 100644 --- a/drivers/hid/usbhid/usbkbd.c +++ b/drivers/hid/usbhid/usbkbd.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: usbkbd.c,v 1.27 2001/12/27 10:37:41 vojtech Exp $ | ||
3 | * | ||
4 | * Copyright (c) 1999-2001 Vojtech Pavlik | 2 | * Copyright (c) 1999-2001 Vojtech Pavlik |
5 | * | 3 | * |
6 | * USB HIDBP Keyboard support | 4 | * USB HIDBP Keyboard support |
diff --git a/drivers/hid/usbhid/usbmouse.c b/drivers/hid/usbhid/usbmouse.c index df0d96d989de..703e9d0e8714 100644 --- a/drivers/hid/usbhid/usbmouse.c +++ b/drivers/hid/usbhid/usbmouse.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: usbmouse.c,v 1.15 2001/12/27 10:37:41 vojtech Exp $ | ||
3 | * | ||
4 | * Copyright (c) 1999-2001 Vojtech Pavlik | 2 | * Copyright (c) 1999-2001 Vojtech Pavlik |
5 | * | 3 | * |
6 | * USB HIDBP Mouse support | 4 | * USB HIDBP Mouse support |
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 4dc76bc45c9d..00ff53348491 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -330,6 +330,20 @@ config SENSORS_CORETEMP | |||
330 | sensor inside your CPU. Supported all are all known variants | 330 | sensor inside your CPU. Supported all are all known variants |
331 | of Intel Core family. | 331 | of Intel Core family. |
332 | 332 | ||
333 | config SENSORS_IBMAEM | ||
334 | tristate "IBM Active Energy Manager temperature/power sensors and control" | ||
335 | select IPMI_SI | ||
336 | depends on IPMI_HANDLER | ||
337 | help | ||
338 | If you say yes here you get support for the temperature and | ||
339 | power sensors and capping hardware in various IBM System X | ||
340 | servers that support Active Energy Manager. This includes | ||
341 | the x3350, x3550, x3650, x3655, x3755, x3850 M2, x3950 M2, | ||
342 | and certain HS2x/LS2x/QS2x blades. | ||
343 | |||
344 | This driver can also be built as a module. If so, the module | ||
345 | will be called ibmaem. | ||
346 | |||
333 | config SENSORS_IBMPEX | 347 | config SENSORS_IBMPEX |
334 | tristate "IBM PowerExecutive temperature/power sensors" | 348 | tristate "IBM PowerExecutive temperature/power sensors" |
335 | select IPMI_SI | 349 | select IPMI_SI |
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 3bdb05a5cbd7..d098677e08de 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile | |||
@@ -41,6 +41,7 @@ obj-$(CONFIG_SENSORS_GL518SM) += gl518sm.o | |||
41 | obj-$(CONFIG_SENSORS_GL520SM) += gl520sm.o | 41 | obj-$(CONFIG_SENSORS_GL520SM) += gl520sm.o |
42 | obj-$(CONFIG_SENSORS_HDAPS) += hdaps.o | 42 | obj-$(CONFIG_SENSORS_HDAPS) += hdaps.o |
43 | obj-$(CONFIG_SENSORS_I5K_AMB) += i5k_amb.o | 43 | obj-$(CONFIG_SENSORS_I5K_AMB) += i5k_amb.o |
44 | obj-$(CONFIG_SENSORS_IBMAEM) += ibmaem.o | ||
44 | obj-$(CONFIG_SENSORS_IBMPEX) += ibmpex.o | 45 | obj-$(CONFIG_SENSORS_IBMPEX) += ibmpex.o |
45 | obj-$(CONFIG_SENSORS_IT87) += it87.o | 46 | obj-$(CONFIG_SENSORS_IT87) += it87.o |
46 | obj-$(CONFIG_SENSORS_K8TEMP) += k8temp.o | 47 | obj-$(CONFIG_SENSORS_K8TEMP) += k8temp.o |
diff --git a/drivers/hwmon/hdaps.c b/drivers/hwmon/hdaps.c index bab5fd2e4dfd..26df06f840eb 100644 --- a/drivers/hwmon/hdaps.c +++ b/drivers/hwmon/hdaps.c | |||
@@ -515,12 +515,14 @@ static struct dmi_system_id __initdata hdaps_whitelist[] = { | |||
515 | HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R50"), | 515 | HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R50"), |
516 | HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R51"), | 516 | HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R51"), |
517 | HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R52"), | 517 | HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R52"), |
518 | HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad R61i"), | ||
518 | HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad T41p"), | 519 | HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad T41p"), |
519 | HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T41"), | 520 | HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T41"), |
520 | HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad T42p"), | 521 | HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad T42p"), |
521 | HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T42"), | 522 | HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T42"), |
522 | HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T43"), | 523 | HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T43"), |
523 | HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T60"), | 524 | HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T60"), |
525 | HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T61"), | ||
524 | HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad X40"), | 526 | HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad X40"), |
525 | HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad X41"), | 527 | HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad X41"), |
526 | HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X60"), | 528 | HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X60"), |
diff --git a/drivers/hwmon/i5k_amb.c b/drivers/hwmon/i5k_amb.c index 6ac5c6f53585..f9e2ed621f7b 100644 --- a/drivers/hwmon/i5k_amb.c +++ b/drivers/hwmon/i5k_amb.c | |||
@@ -111,6 +111,7 @@ struct i5k_amb_data { | |||
111 | void __iomem *amb_mmio; | 111 | void __iomem *amb_mmio; |
112 | struct i5k_device_attribute *attrs; | 112 | struct i5k_device_attribute *attrs; |
113 | unsigned int num_attrs; | 113 | unsigned int num_attrs; |
114 | unsigned long chipset_id; | ||
114 | }; | 115 | }; |
115 | 116 | ||
116 | static ssize_t show_name(struct device *dev, struct device_attribute *devattr, | 117 | static ssize_t show_name(struct device *dev, struct device_attribute *devattr, |
@@ -382,7 +383,8 @@ err: | |||
382 | return res; | 383 | return res; |
383 | } | 384 | } |
384 | 385 | ||
385 | static int __devinit i5k_find_amb_registers(struct i5k_amb_data *data) | 386 | static int __devinit i5k_find_amb_registers(struct i5k_amb_data *data, |
387 | unsigned long devid) | ||
386 | { | 388 | { |
387 | struct pci_dev *pcidev; | 389 | struct pci_dev *pcidev; |
388 | u32 val32; | 390 | u32 val32; |
@@ -390,7 +392,7 @@ static int __devinit i5k_find_amb_registers(struct i5k_amb_data *data) | |||
390 | 392 | ||
391 | /* Find AMB register memory space */ | 393 | /* Find AMB register memory space */ |
392 | pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, | 394 | pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, |
393 | PCI_DEVICE_ID_INTEL_5000_ERR, | 395 | devid, |
394 | NULL); | 396 | NULL); |
395 | if (!pcidev) | 397 | if (!pcidev) |
396 | return -ENODEV; | 398 | return -ENODEV; |
@@ -409,6 +411,8 @@ static int __devinit i5k_find_amb_registers(struct i5k_amb_data *data) | |||
409 | goto out; | 411 | goto out; |
410 | } | 412 | } |
411 | 413 | ||
414 | data->chipset_id = devid; | ||
415 | |||
412 | res = 0; | 416 | res = 0; |
413 | out: | 417 | out: |
414 | pci_dev_put(pcidev); | 418 | pci_dev_put(pcidev); |
@@ -441,10 +445,30 @@ out: | |||
441 | return res; | 445 | return res; |
442 | } | 446 | } |
443 | 447 | ||
448 | static unsigned long i5k_channel_pci_id(struct i5k_amb_data *data, | ||
449 | unsigned long channel) | ||
450 | { | ||
451 | switch (data->chipset_id) { | ||
452 | case PCI_DEVICE_ID_INTEL_5000_ERR: | ||
453 | return PCI_DEVICE_ID_INTEL_5000_FBD0 + channel; | ||
454 | case PCI_DEVICE_ID_INTEL_5400_ERR: | ||
455 | return PCI_DEVICE_ID_INTEL_5400_FBD0 + channel; | ||
456 | default: | ||
457 | BUG(); | ||
458 | } | ||
459 | } | ||
460 | |||
461 | static unsigned long chipset_ids[] = { | ||
462 | PCI_DEVICE_ID_INTEL_5000_ERR, | ||
463 | PCI_DEVICE_ID_INTEL_5400_ERR, | ||
464 | 0 | ||
465 | }; | ||
466 | |||
444 | static int __devinit i5k_amb_probe(struct platform_device *pdev) | 467 | static int __devinit i5k_amb_probe(struct platform_device *pdev) |
445 | { | 468 | { |
446 | struct i5k_amb_data *data; | 469 | struct i5k_amb_data *data; |
447 | struct resource *reso; | 470 | struct resource *reso; |
471 | int i; | ||
448 | int res = -ENODEV; | 472 | int res = -ENODEV; |
449 | 473 | ||
450 | data = kzalloc(sizeof(*data), GFP_KERNEL); | 474 | data = kzalloc(sizeof(*data), GFP_KERNEL); |
@@ -452,19 +476,24 @@ static int __devinit i5k_amb_probe(struct platform_device *pdev) | |||
452 | return -ENOMEM; | 476 | return -ENOMEM; |
453 | 477 | ||
454 | /* Figure out where the AMB registers live */ | 478 | /* Figure out where the AMB registers live */ |
455 | res = i5k_find_amb_registers(data); | 479 | i = 0; |
480 | do { | ||
481 | res = i5k_find_amb_registers(data, chipset_ids[i]); | ||
482 | i++; | ||
483 | } while (res && chipset_ids[i]); | ||
484 | |||
456 | if (res) | 485 | if (res) |
457 | goto err; | 486 | goto err; |
458 | 487 | ||
459 | /* Copy the DIMM presence map for the first two channels */ | 488 | /* Copy the DIMM presence map for the first two channels */ |
460 | res = i5k_channel_probe(&data->amb_present[0], | 489 | res = i5k_channel_probe(&data->amb_present[0], |
461 | PCI_DEVICE_ID_INTEL_5000_FBD0); | 490 | i5k_channel_pci_id(data, 0)); |
462 | if (res) | 491 | if (res) |
463 | goto err; | 492 | goto err; |
464 | 493 | ||
465 | /* Copy the DIMM presence map for the optional second two channels */ | 494 | /* Copy the DIMM presence map for the optional second two channels */ |
466 | i5k_channel_probe(&data->amb_present[2], | 495 | i5k_channel_probe(&data->amb_present[2], |
467 | PCI_DEVICE_ID_INTEL_5000_FBD1); | 496 | i5k_channel_pci_id(data, 1)); |
468 | 497 | ||
469 | /* Set up resource regions */ | 498 | /* Set up resource regions */ |
470 | reso = request_mem_region(data->amb_base, data->amb_len, DRVNAME); | 499 | reso = request_mem_region(data->amb_base, data->amb_len, DRVNAME); |
diff --git a/drivers/hwmon/ibmaem.c b/drivers/hwmon/ibmaem.c new file mode 100644 index 000000000000..c9416e657487 --- /dev/null +++ b/drivers/hwmon/ibmaem.c | |||
@@ -0,0 +1,1111 @@ | |||
1 | /* | ||
2 | * A hwmon driver for the IBM Active Energy Manager temperature/power sensors | ||
3 | * and capping functionality. | ||
4 | * Copyright (C) 2008 IBM | ||
5 | * | ||
6 | * Author: Darrick J. Wong <djwong@us.ibm.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
21 | */ | ||
22 | |||
23 | #include <linux/ipmi.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/hwmon.h> | ||
26 | #include <linux/hwmon-sysfs.h> | ||
27 | #include <linux/jiffies.h> | ||
28 | #include <linux/mutex.h> | ||
29 | #include <linux/kdev_t.h> | ||
30 | #include <linux/spinlock.h> | ||
31 | #include <linux/idr.h> | ||
32 | #include <linux/sched.h> | ||
33 | #include <linux/platform_device.h> | ||
34 | #include <linux/math64.h> | ||
35 | #include <linux/time.h> | ||
36 | |||
37 | #define REFRESH_INTERVAL (HZ) | ||
38 | #define IPMI_TIMEOUT (30 * HZ) | ||
39 | #define DRVNAME "aem" | ||
40 | |||
41 | #define AEM_NETFN 0x2E | ||
42 | |||
43 | #define AEM_FIND_FW_CMD 0x80 | ||
44 | #define AEM_ELEMENT_CMD 0x81 | ||
45 | #define AEM_FW_INSTANCE_CMD 0x82 | ||
46 | |||
47 | #define AEM_READ_ELEMENT_CFG 0x80 | ||
48 | #define AEM_READ_BUFFER 0x81 | ||
49 | #define AEM_READ_REGISTER 0x82 | ||
50 | #define AEM_WRITE_REGISTER 0x83 | ||
51 | #define AEM_SET_REG_MASK 0x84 | ||
52 | #define AEM_CLEAR_REG_MASK 0x85 | ||
53 | #define AEM_READ_ELEMENT_CFG2 0x86 | ||
54 | |||
55 | #define AEM_CONTROL_ELEMENT 0 | ||
56 | #define AEM_ENERGY_ELEMENT 1 | ||
57 | #define AEM_CLOCK_ELEMENT 4 | ||
58 | #define AEM_POWER_CAP_ELEMENT 7 | ||
59 | #define AEM_EXHAUST_ELEMENT 9 | ||
60 | #define AEM_POWER_ELEMENT 10 | ||
61 | |||
62 | #define AEM_MODULE_TYPE_ID 0x0001 | ||
63 | |||
64 | #define AEM2_NUM_ENERGY_REGS 2 | ||
65 | #define AEM2_NUM_PCAP_REGS 6 | ||
66 | #define AEM2_NUM_TEMP_REGS 2 | ||
67 | #define AEM2_NUM_SENSORS 14 | ||
68 | |||
69 | #define AEM1_NUM_ENERGY_REGS 1 | ||
70 | #define AEM1_NUM_SENSORS 3 | ||
71 | |||
72 | /* AEM 2.x has more energy registers */ | ||
73 | #define AEM_NUM_ENERGY_REGS AEM2_NUM_ENERGY_REGS | ||
74 | /* AEM 2.x needs more sensor files */ | ||
75 | #define AEM_NUM_SENSORS AEM2_NUM_SENSORS | ||
76 | |||
77 | #define POWER_CAP 0 | ||
78 | #define POWER_CAP_MAX_HOTPLUG 1 | ||
79 | #define POWER_CAP_MAX 2 | ||
80 | #define POWER_CAP_MIN_WARNING 3 | ||
81 | #define POWER_CAP_MIN 4 | ||
82 | #define POWER_AUX 5 | ||
83 | |||
84 | #define AEM_DEFAULT_POWER_INTERVAL 1000 | ||
85 | #define AEM_MIN_POWER_INTERVAL 200 | ||
86 | #define UJ_PER_MJ 1000L | ||
87 | |||
88 | static DEFINE_IDR(aem_idr); | ||
89 | static DEFINE_SPINLOCK(aem_idr_lock); | ||
90 | |||
91 | static struct device_driver aem_driver = { | ||
92 | .name = DRVNAME, | ||
93 | .bus = &platform_bus_type, | ||
94 | }; | ||
95 | |||
96 | struct aem_ipmi_data { | ||
97 | struct completion read_complete; | ||
98 | struct ipmi_addr address; | ||
99 | ipmi_user_t user; | ||
100 | int interface; | ||
101 | |||
102 | struct kernel_ipmi_msg tx_message; | ||
103 | long tx_msgid; | ||
104 | |||
105 | void *rx_msg_data; | ||
106 | unsigned short rx_msg_len; | ||
107 | unsigned char rx_result; | ||
108 | int rx_recv_type; | ||
109 | |||
110 | struct device *bmc_device; | ||
111 | }; | ||
112 | |||
113 | struct aem_ro_sensor_template { | ||
114 | char *label; | ||
115 | ssize_t (*show)(struct device *dev, | ||
116 | struct device_attribute *devattr, | ||
117 | char *buf); | ||
118 | int index; | ||
119 | }; | ||
120 | |||
121 | struct aem_rw_sensor_template { | ||
122 | char *label; | ||
123 | ssize_t (*show)(struct device *dev, | ||
124 | struct device_attribute *devattr, | ||
125 | char *buf); | ||
126 | ssize_t (*set)(struct device *dev, | ||
127 | struct device_attribute *devattr, | ||
128 | const char *buf, size_t count); | ||
129 | int index; | ||
130 | }; | ||
131 | |||
132 | struct aem_data { | ||
133 | struct list_head list; | ||
134 | |||
135 | struct device *hwmon_dev; | ||
136 | struct platform_device *pdev; | ||
137 | struct mutex lock; | ||
138 | char valid; | ||
139 | unsigned long last_updated; /* In jiffies */ | ||
140 | u8 ver_major; | ||
141 | u8 ver_minor; | ||
142 | u8 module_handle; | ||
143 | int id; | ||
144 | struct aem_ipmi_data ipmi; | ||
145 | |||
146 | /* Function to update sensors */ | ||
147 | void (*update)(struct aem_data *data); | ||
148 | |||
149 | /* | ||
150 | * AEM 1.x sensors: | ||
151 | * Available sensors: | ||
152 | * Energy meter | ||
153 | * Power meter | ||
154 | * | ||
155 | * AEM 2.x sensors: | ||
156 | * Two energy meters | ||
157 | * Two power meters | ||
158 | * Two temperature sensors | ||
159 | * Six power cap registers | ||
160 | */ | ||
161 | |||
162 | /* sysfs attrs */ | ||
163 | struct sensor_device_attribute sensors[AEM_NUM_SENSORS]; | ||
164 | |||
165 | /* energy use in mJ */ | ||
166 | u64 energy[AEM_NUM_ENERGY_REGS]; | ||
167 | |||
168 | /* power sampling interval in ms */ | ||
169 | unsigned long power_period[AEM_NUM_ENERGY_REGS]; | ||
170 | |||
171 | /* Everything past here is for AEM2 only */ | ||
172 | |||
173 | /* power caps in dW */ | ||
174 | u16 pcap[AEM2_NUM_PCAP_REGS]; | ||
175 | |||
176 | /* exhaust temperature in C */ | ||
177 | u8 temp[AEM2_NUM_TEMP_REGS]; | ||
178 | }; | ||
179 | |||
180 | /* Data structures returned by the AEM firmware */ | ||
181 | struct aem_iana_id { | ||
182 | u8 bytes[3]; | ||
183 | }; | ||
184 | static struct aem_iana_id system_x_id = { | ||
185 | .bytes = {0x4D, 0x4F, 0x00} | ||
186 | }; | ||
187 | |||
188 | /* These are used to find AEM1 instances */ | ||
189 | struct aem_find_firmware_req { | ||
190 | struct aem_iana_id id; | ||
191 | u8 rsvd; | ||
192 | __be16 index; | ||
193 | __be16 module_type_id; | ||
194 | } __packed; | ||
195 | |||
196 | struct aem_find_firmware_resp { | ||
197 | struct aem_iana_id id; | ||
198 | u8 num_instances; | ||
199 | } __packed; | ||
200 | |||
201 | /* These are used to find AEM2 instances */ | ||
202 | struct aem_find_instance_req { | ||
203 | struct aem_iana_id id; | ||
204 | u8 instance_number; | ||
205 | __be16 module_type_id; | ||
206 | } __packed; | ||
207 | |||
208 | struct aem_find_instance_resp { | ||
209 | struct aem_iana_id id; | ||
210 | u8 num_instances; | ||
211 | u8 major; | ||
212 | u8 minor; | ||
213 | u8 module_handle; | ||
214 | u16 record_id; | ||
215 | } __packed; | ||
216 | |||
217 | /* These are used to query sensors */ | ||
218 | struct aem_read_sensor_req { | ||
219 | struct aem_iana_id id; | ||
220 | u8 module_handle; | ||
221 | u8 element; | ||
222 | u8 subcommand; | ||
223 | u8 reg; | ||
224 | u8 rx_buf_size; | ||
225 | } __packed; | ||
226 | |||
227 | struct aem_read_sensor_resp { | ||
228 | struct aem_iana_id id; | ||
229 | u8 bytes[0]; | ||
230 | } __packed; | ||
231 | |||
232 | /* Data structures to talk to the IPMI layer */ | ||
233 | struct aem_driver_data { | ||
234 | struct list_head aem_devices; | ||
235 | struct ipmi_smi_watcher bmc_events; | ||
236 | struct ipmi_user_hndl ipmi_hndlrs; | ||
237 | }; | ||
238 | |||
239 | static void aem_register_bmc(int iface, struct device *dev); | ||
240 | static void aem_bmc_gone(int iface); | ||
241 | static void aem_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data); | ||
242 | |||
243 | static void aem_remove_sensors(struct aem_data *data); | ||
244 | static int aem_init_aem1(struct aem_ipmi_data *probe); | ||
245 | static int aem_init_aem2(struct aem_ipmi_data *probe); | ||
246 | static int aem1_find_sensors(struct aem_data *data); | ||
247 | static int aem2_find_sensors(struct aem_data *data); | ||
248 | static void update_aem1_sensors(struct aem_data *data); | ||
249 | static void update_aem2_sensors(struct aem_data *data); | ||
250 | |||
251 | static struct aem_driver_data driver_data = { | ||
252 | .aem_devices = LIST_HEAD_INIT(driver_data.aem_devices), | ||
253 | .bmc_events = { | ||
254 | .owner = THIS_MODULE, | ||
255 | .new_smi = aem_register_bmc, | ||
256 | .smi_gone = aem_bmc_gone, | ||
257 | }, | ||
258 | .ipmi_hndlrs = { | ||
259 | .ipmi_recv_hndl = aem_msg_handler, | ||
260 | }, | ||
261 | }; | ||
262 | |||
263 | /* Functions to talk to the IPMI layer */ | ||
264 | |||
265 | /* Initialize IPMI address, message buffers and user data */ | ||
266 | static int aem_init_ipmi_data(struct aem_ipmi_data *data, int iface, | ||
267 | struct device *bmc) | ||
268 | { | ||
269 | int err; | ||
270 | |||
271 | init_completion(&data->read_complete); | ||
272 | data->bmc_device = bmc; | ||
273 | |||
274 | /* Initialize IPMI address */ | ||
275 | data->address.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; | ||
276 | data->address.channel = IPMI_BMC_CHANNEL; | ||
277 | data->address.data[0] = 0; | ||
278 | data->interface = iface; | ||
279 | |||
280 | /* Initialize message buffers */ | ||
281 | data->tx_msgid = 0; | ||
282 | data->tx_message.netfn = AEM_NETFN; | ||
283 | |||
284 | /* Create IPMI messaging interface user */ | ||
285 | err = ipmi_create_user(data->interface, &driver_data.ipmi_hndlrs, | ||
286 | data, &data->user); | ||
287 | if (err < 0) { | ||
288 | dev_err(bmc, "Unable to register user with IPMI " | ||
289 | "interface %d\n", data->interface); | ||
290 | return -EACCES; | ||
291 | } | ||
292 | |||
293 | return 0; | ||
294 | } | ||
295 | |||
296 | /* Send an IPMI command */ | ||
297 | static int aem_send_message(struct aem_ipmi_data *data) | ||
298 | { | ||
299 | int err; | ||
300 | |||
301 | err = ipmi_validate_addr(&data->address, sizeof(data->address)); | ||
302 | if (err) | ||
303 | goto out; | ||
304 | |||
305 | data->tx_msgid++; | ||
306 | err = ipmi_request_settime(data->user, &data->address, data->tx_msgid, | ||
307 | &data->tx_message, data, 0, 0, 0); | ||
308 | if (err) | ||
309 | goto out1; | ||
310 | |||
311 | return 0; | ||
312 | out1: | ||
313 | dev_err(data->bmc_device, "request_settime=%x\n", err); | ||
314 | return err; | ||
315 | out: | ||
316 | dev_err(data->bmc_device, "validate_addr=%x\n", err); | ||
317 | return err; | ||
318 | } | ||
319 | |||
320 | /* Dispatch IPMI messages to callers */ | ||
321 | static void aem_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) | ||
322 | { | ||
323 | unsigned short rx_len; | ||
324 | struct aem_ipmi_data *data = user_msg_data; | ||
325 | |||
326 | if (msg->msgid != data->tx_msgid) { | ||
327 | dev_err(data->bmc_device, "Mismatch between received msgid " | ||
328 | "(%02x) and transmitted msgid (%02x)!\n", | ||
329 | (int)msg->msgid, | ||
330 | (int)data->tx_msgid); | ||
331 | ipmi_free_recv_msg(msg); | ||
332 | return; | ||
333 | } | ||
334 | |||
335 | data->rx_recv_type = msg->recv_type; | ||
336 | if (msg->msg.data_len > 0) | ||
337 | data->rx_result = msg->msg.data[0]; | ||
338 | else | ||
339 | data->rx_result = IPMI_UNKNOWN_ERR_COMPLETION_CODE; | ||
340 | |||
341 | if (msg->msg.data_len > 1) { | ||
342 | rx_len = msg->msg.data_len - 1; | ||
343 | if (data->rx_msg_len < rx_len) | ||
344 | rx_len = data->rx_msg_len; | ||
345 | data->rx_msg_len = rx_len; | ||
346 | memcpy(data->rx_msg_data, msg->msg.data + 1, data->rx_msg_len); | ||
347 | } else | ||
348 | data->rx_msg_len = 0; | ||
349 | |||
350 | ipmi_free_recv_msg(msg); | ||
351 | complete(&data->read_complete); | ||
352 | } | ||
353 | |||
354 | /* ID functions */ | ||
355 | |||
356 | /* Obtain an id */ | ||
357 | static int aem_idr_get(int *id) | ||
358 | { | ||
359 | int i, err; | ||
360 | |||
361 | again: | ||
362 | if (unlikely(!idr_pre_get(&aem_idr, GFP_KERNEL))) | ||
363 | return -ENOMEM; | ||
364 | |||
365 | spin_lock(&aem_idr_lock); | ||
366 | err = idr_get_new(&aem_idr, NULL, &i); | ||
367 | spin_unlock(&aem_idr_lock); | ||
368 | |||
369 | if (unlikely(err == -EAGAIN)) | ||
370 | goto again; | ||
371 | else if (unlikely(err)) | ||
372 | return err; | ||
373 | |||
374 | *id = i & MAX_ID_MASK; | ||
375 | return 0; | ||
376 | } | ||
377 | |||
378 | /* Release an object ID */ | ||
379 | static void aem_idr_put(int id) | ||
380 | { | ||
381 | spin_lock(&aem_idr_lock); | ||
382 | idr_remove(&aem_idr, id); | ||
383 | spin_unlock(&aem_idr_lock); | ||
384 | } | ||
385 | |||
386 | /* Sensor support functions */ | ||
387 | |||
388 | /* Read a sensor value */ | ||
389 | static int aem_read_sensor(struct aem_data *data, u8 elt, u8 reg, | ||
390 | void *buf, size_t size) | ||
391 | { | ||
392 | int rs_size, res; | ||
393 | struct aem_read_sensor_req rs_req; | ||
394 | struct aem_read_sensor_resp *rs_resp; | ||
395 | struct aem_ipmi_data *ipmi = &data->ipmi; | ||
396 | |||
397 | /* AEM registers are 1, 2, 4 or 8 bytes */ | ||
398 | switch (size) { | ||
399 | case 1: | ||
400 | case 2: | ||
401 | case 4: | ||
402 | case 8: | ||
403 | break; | ||
404 | default: | ||
405 | return -EINVAL; | ||
406 | } | ||
407 | |||
408 | rs_req.id = system_x_id; | ||
409 | rs_req.module_handle = data->module_handle; | ||
410 | rs_req.element = elt; | ||
411 | rs_req.subcommand = AEM_READ_REGISTER; | ||
412 | rs_req.reg = reg; | ||
413 | rs_req.rx_buf_size = size; | ||
414 | |||
415 | ipmi->tx_message.cmd = AEM_ELEMENT_CMD; | ||
416 | ipmi->tx_message.data = (char *)&rs_req; | ||
417 | ipmi->tx_message.data_len = sizeof(rs_req); | ||
418 | |||
419 | rs_size = sizeof(*rs_resp) + size; | ||
420 | rs_resp = kzalloc(rs_size, GFP_KERNEL); | ||
421 | if (!rs_resp) | ||
422 | return -ENOMEM; | ||
423 | |||
424 | ipmi->rx_msg_data = rs_resp; | ||
425 | ipmi->rx_msg_len = rs_size; | ||
426 | |||
427 | aem_send_message(ipmi); | ||
428 | |||
429 | res = wait_for_completion_timeout(&ipmi->read_complete, IPMI_TIMEOUT); | ||
430 | if (!res) | ||
431 | return -ETIMEDOUT; | ||
432 | |||
433 | if (ipmi->rx_result || ipmi->rx_msg_len != rs_size || | ||
434 | memcmp(&rs_resp->id, &system_x_id, sizeof(system_x_id))) { | ||
435 | kfree(rs_resp); | ||
436 | return -ENOENT; | ||
437 | } | ||
438 | |||
439 | switch (size) { | ||
440 | case 1: { | ||
441 | u8 *x = buf; | ||
442 | *x = rs_resp->bytes[0]; | ||
443 | break; | ||
444 | } | ||
445 | case 2: { | ||
446 | u16 *x = buf; | ||
447 | *x = be16_to_cpup((__be16 *)rs_resp->bytes); | ||
448 | break; | ||
449 | } | ||
450 | case 4: { | ||
451 | u32 *x = buf; | ||
452 | *x = be32_to_cpup((__be32 *)rs_resp->bytes); | ||
453 | break; | ||
454 | } | ||
455 | case 8: { | ||
456 | u64 *x = buf; | ||
457 | *x = be64_to_cpup((__be64 *)rs_resp->bytes); | ||
458 | break; | ||
459 | } | ||
460 | } | ||
461 | |||
462 | return 0; | ||
463 | } | ||
464 | |||
465 | /* Update AEM energy registers */ | ||
466 | static void update_aem_energy(struct aem_data *data) | ||
467 | { | ||
468 | aem_read_sensor(data, AEM_ENERGY_ELEMENT, 0, &data->energy[0], 8); | ||
469 | if (data->ver_major < 2) | ||
470 | return; | ||
471 | aem_read_sensor(data, AEM_ENERGY_ELEMENT, 1, &data->energy[1], 8); | ||
472 | } | ||
473 | |||
474 | /* Update all AEM1 sensors */ | ||
475 | static void update_aem1_sensors(struct aem_data *data) | ||
476 | { | ||
477 | mutex_lock(&data->lock); | ||
478 | if (time_before(jiffies, data->last_updated + REFRESH_INTERVAL) && | ||
479 | data->valid) | ||
480 | goto out; | ||
481 | |||
482 | update_aem_energy(data); | ||
483 | out: | ||
484 | mutex_unlock(&data->lock); | ||
485 | } | ||
486 | |||
487 | /* Update all AEM2 sensors */ | ||
488 | static void update_aem2_sensors(struct aem_data *data) | ||
489 | { | ||
490 | int i; | ||
491 | |||
492 | mutex_lock(&data->lock); | ||
493 | if (time_before(jiffies, data->last_updated + REFRESH_INTERVAL) && | ||
494 | data->valid) | ||
495 | goto out; | ||
496 | |||
497 | update_aem_energy(data); | ||
498 | aem_read_sensor(data, AEM_EXHAUST_ELEMENT, 0, &data->temp[0], 1); | ||
499 | aem_read_sensor(data, AEM_EXHAUST_ELEMENT, 1, &data->temp[1], 1); | ||
500 | |||
501 | for (i = POWER_CAP; i <= POWER_AUX; i++) | ||
502 | aem_read_sensor(data, AEM_POWER_CAP_ELEMENT, i, | ||
503 | &data->pcap[i], 2); | ||
504 | out: | ||
505 | mutex_unlock(&data->lock); | ||
506 | } | ||
507 | |||
508 | /* Delete an AEM instance */ | ||
509 | static void aem_delete(struct aem_data *data) | ||
510 | { | ||
511 | list_del(&data->list); | ||
512 | aem_remove_sensors(data); | ||
513 | hwmon_device_unregister(data->hwmon_dev); | ||
514 | ipmi_destroy_user(data->ipmi.user); | ||
515 | dev_set_drvdata(&data->pdev->dev, NULL); | ||
516 | platform_device_unregister(data->pdev); | ||
517 | aem_idr_put(data->id); | ||
518 | kfree(data); | ||
519 | } | ||
520 | |||
521 | /* Probe functions for AEM1 devices */ | ||
522 | |||
523 | /* Retrieve version and module handle for an AEM1 instance */ | ||
524 | static int aem_find_aem1_count(struct aem_ipmi_data *data) | ||
525 | { | ||
526 | int res; | ||
527 | struct aem_find_firmware_req ff_req; | ||
528 | struct aem_find_firmware_resp ff_resp; | ||
529 | |||
530 | ff_req.id = system_x_id; | ||
531 | ff_req.index = 0; | ||
532 | ff_req.module_type_id = cpu_to_be16(AEM_MODULE_TYPE_ID); | ||
533 | |||
534 | data->tx_message.cmd = AEM_FIND_FW_CMD; | ||
535 | data->tx_message.data = (char *)&ff_req; | ||
536 | data->tx_message.data_len = sizeof(ff_req); | ||
537 | |||
538 | data->rx_msg_data = &ff_resp; | ||
539 | data->rx_msg_len = sizeof(ff_resp); | ||
540 | |||
541 | aem_send_message(data); | ||
542 | |||
543 | res = wait_for_completion_timeout(&data->read_complete, IPMI_TIMEOUT); | ||
544 | if (!res) | ||
545 | return -ETIMEDOUT; | ||
546 | |||
547 | if (data->rx_result || data->rx_msg_len != sizeof(ff_resp) || | ||
548 | memcmp(&ff_resp.id, &system_x_id, sizeof(system_x_id))) | ||
549 | return -ENOENT; | ||
550 | |||
551 | return ff_resp.num_instances; | ||
552 | } | ||
553 | |||
554 | /* Find and initialize one AEM1 instance */ | ||
555 | static int aem_init_aem1_inst(struct aem_ipmi_data *probe, u8 module_handle) | ||
556 | { | ||
557 | struct aem_data *data; | ||
558 | int i; | ||
559 | int res = -ENOMEM; | ||
560 | |||
561 | data = kzalloc(sizeof(*data), GFP_KERNEL); | ||
562 | if (!data) | ||
563 | return res; | ||
564 | mutex_init(&data->lock); | ||
565 | |||
566 | /* Copy instance data */ | ||
567 | data->ver_major = 1; | ||
568 | data->ver_minor = 0; | ||
569 | data->module_handle = module_handle; | ||
570 | for (i = 0; i < AEM1_NUM_ENERGY_REGS; i++) | ||
571 | data->power_period[i] = AEM_DEFAULT_POWER_INTERVAL; | ||
572 | |||
573 | /* Create sub-device for this fw instance */ | ||
574 | if (aem_idr_get(&data->id)) | ||
575 | goto id_err; | ||
576 | |||
577 | data->pdev = platform_device_alloc(DRVNAME, data->id); | ||
578 | if (!data->pdev) | ||
579 | goto dev_err; | ||
580 | data->pdev->dev.driver = &aem_driver; | ||
581 | |||
582 | res = platform_device_add(data->pdev); | ||
583 | if (res) | ||
584 | goto ipmi_err; | ||
585 | |||
586 | dev_set_drvdata(&data->pdev->dev, data); | ||
587 | |||
588 | /* Set up IPMI interface */ | ||
589 | if (aem_init_ipmi_data(&data->ipmi, probe->interface, | ||
590 | probe->bmc_device)) | ||
591 | goto ipmi_err; | ||
592 | |||
593 | /* Register with hwmon */ | ||
594 | data->hwmon_dev = hwmon_device_register(&data->pdev->dev); | ||
595 | |||
596 | if (IS_ERR(data->hwmon_dev)) { | ||
597 | dev_err(&data->pdev->dev, "Unable to register hwmon " | ||
598 | "device for IPMI interface %d\n", | ||
599 | probe->interface); | ||
600 | goto hwmon_reg_err; | ||
601 | } | ||
602 | |||
603 | data->update = update_aem1_sensors; | ||
604 | |||
605 | /* Find sensors */ | ||
606 | if (aem1_find_sensors(data)) | ||
607 | goto sensor_err; | ||
608 | |||
609 | /* Add to our list of AEM devices */ | ||
610 | list_add_tail(&data->list, &driver_data.aem_devices); | ||
611 | |||
612 | dev_info(data->ipmi.bmc_device, "Found AEM v%d.%d at 0x%X\n", | ||
613 | data->ver_major, data->ver_minor, | ||
614 | data->module_handle); | ||
615 | return 0; | ||
616 | |||
617 | sensor_err: | ||
618 | hwmon_device_unregister(data->hwmon_dev); | ||
619 | hwmon_reg_err: | ||
620 | ipmi_destroy_user(data->ipmi.user); | ||
621 | ipmi_err: | ||
622 | dev_set_drvdata(&data->pdev->dev, NULL); | ||
623 | platform_device_unregister(data->pdev); | ||
624 | dev_err: | ||
625 | aem_idr_put(data->id); | ||
626 | id_err: | ||
627 | kfree(data); | ||
628 | |||
629 | return res; | ||
630 | } | ||
631 | |||
632 | /* Find and initialize all AEM1 instances */ | ||
633 | static int aem_init_aem1(struct aem_ipmi_data *probe) | ||
634 | { | ||
635 | int num, i, err; | ||
636 | |||
637 | num = aem_find_aem1_count(probe); | ||
638 | for (i = 0; i < num; i++) { | ||
639 | err = aem_init_aem1_inst(probe, i); | ||
640 | if (err) { | ||
641 | dev_err(probe->bmc_device, | ||
642 | "Error %d initializing AEM1 0x%X\n", | ||
643 | err, i); | ||
644 | return err; | ||
645 | } | ||
646 | } | ||
647 | |||
648 | return 0; | ||
649 | } | ||
650 | |||
651 | /* Probe functions for AEM2 devices */ | ||
652 | |||
653 | /* Retrieve version and module handle for an AEM2 instance */ | ||
654 | static int aem_find_aem2(struct aem_ipmi_data *data, | ||
655 | struct aem_find_instance_resp *fi_resp, | ||
656 | int instance_num) | ||
657 | { | ||
658 | int res; | ||
659 | struct aem_find_instance_req fi_req; | ||
660 | |||
661 | fi_req.id = system_x_id; | ||
662 | fi_req.instance_number = instance_num; | ||
663 | fi_req.module_type_id = cpu_to_be16(AEM_MODULE_TYPE_ID); | ||
664 | |||
665 | data->tx_message.cmd = AEM_FW_INSTANCE_CMD; | ||
666 | data->tx_message.data = (char *)&fi_req; | ||
667 | data->tx_message.data_len = sizeof(fi_req); | ||
668 | |||
669 | data->rx_msg_data = fi_resp; | ||
670 | data->rx_msg_len = sizeof(*fi_resp); | ||
671 | |||
672 | aem_send_message(data); | ||
673 | |||
674 | res = wait_for_completion_timeout(&data->read_complete, IPMI_TIMEOUT); | ||
675 | if (!res) | ||
676 | return -ETIMEDOUT; | ||
677 | |||
678 | if (data->rx_result || data->rx_msg_len != sizeof(*fi_resp) || | ||
679 | memcmp(&fi_resp->id, &system_x_id, sizeof(system_x_id))) | ||
680 | return -ENOENT; | ||
681 | |||
682 | return 0; | ||
683 | } | ||
684 | |||
685 | /* Find and initialize one AEM2 instance */ | ||
686 | static int aem_init_aem2_inst(struct aem_ipmi_data *probe, | ||
687 | struct aem_find_instance_resp *fi_resp) | ||
688 | { | ||
689 | struct aem_data *data; | ||
690 | int i; | ||
691 | int res = -ENOMEM; | ||
692 | |||
693 | data = kzalloc(sizeof(*data), GFP_KERNEL); | ||
694 | if (!data) | ||
695 | return res; | ||
696 | mutex_init(&data->lock); | ||
697 | |||
698 | /* Copy instance data */ | ||
699 | data->ver_major = fi_resp->major; | ||
700 | data->ver_minor = fi_resp->minor; | ||
701 | data->module_handle = fi_resp->module_handle; | ||
702 | for (i = 0; i < AEM2_NUM_ENERGY_REGS; i++) | ||
703 | data->power_period[i] = AEM_DEFAULT_POWER_INTERVAL; | ||
704 | |||
705 | /* Create sub-device for this fw instance */ | ||
706 | if (aem_idr_get(&data->id)) | ||
707 | goto id_err; | ||
708 | |||
709 | data->pdev = platform_device_alloc(DRVNAME, data->id); | ||
710 | if (!data->pdev) | ||
711 | goto dev_err; | ||
712 | data->pdev->dev.driver = &aem_driver; | ||
713 | |||
714 | res = platform_device_add(data->pdev); | ||
715 | if (res) | ||
716 | goto ipmi_err; | ||
717 | |||
718 | dev_set_drvdata(&data->pdev->dev, data); | ||
719 | |||
720 | /* Set up IPMI interface */ | ||
721 | if (aem_init_ipmi_data(&data->ipmi, probe->interface, | ||
722 | probe->bmc_device)) | ||
723 | goto ipmi_err; | ||
724 | |||
725 | /* Register with hwmon */ | ||
726 | data->hwmon_dev = hwmon_device_register(&data->pdev->dev); | ||
727 | |||
728 | if (IS_ERR(data->hwmon_dev)) { | ||
729 | dev_err(&data->pdev->dev, "Unable to register hwmon " | ||
730 | "device for IPMI interface %d\n", | ||
731 | probe->interface); | ||
732 | goto hwmon_reg_err; | ||
733 | } | ||
734 | |||
735 | data->update = update_aem2_sensors; | ||
736 | |||
737 | /* Find sensors */ | ||
738 | if (aem2_find_sensors(data)) | ||
739 | goto sensor_err; | ||
740 | |||
741 | /* Add to our list of AEM devices */ | ||
742 | list_add_tail(&data->list, &driver_data.aem_devices); | ||
743 | |||
744 | dev_info(data->ipmi.bmc_device, "Found AEM v%d.%d at 0x%X\n", | ||
745 | data->ver_major, data->ver_minor, | ||
746 | data->module_handle); | ||
747 | return 0; | ||
748 | |||
749 | sensor_err: | ||
750 | hwmon_device_unregister(data->hwmon_dev); | ||
751 | hwmon_reg_err: | ||
752 | ipmi_destroy_user(data->ipmi.user); | ||
753 | ipmi_err: | ||
754 | dev_set_drvdata(&data->pdev->dev, NULL); | ||
755 | platform_device_unregister(data->pdev); | ||
756 | dev_err: | ||
757 | aem_idr_put(data->id); | ||
758 | id_err: | ||
759 | kfree(data); | ||
760 | |||
761 | return res; | ||
762 | } | ||
763 | |||
764 | /* Find and initialize all AEM2 instances */ | ||
765 | static int aem_init_aem2(struct aem_ipmi_data *probe) | ||
766 | { | ||
767 | struct aem_find_instance_resp fi_resp; | ||
768 | int err; | ||
769 | int i = 0; | ||
770 | |||
771 | while (!aem_find_aem2(probe, &fi_resp, i)) { | ||
772 | if (fi_resp.major != 2) { | ||
773 | dev_err(probe->bmc_device, "Unknown AEM v%d; please " | ||
774 | "report this to the maintainer.\n", | ||
775 | fi_resp.major); | ||
776 | i++; | ||
777 | continue; | ||
778 | } | ||
779 | err = aem_init_aem2_inst(probe, &fi_resp); | ||
780 | if (err) { | ||
781 | dev_err(probe->bmc_device, | ||
782 | "Error %d initializing AEM2 0x%X\n", | ||
783 | err, fi_resp.module_handle); | ||
784 | return err; | ||
785 | } | ||
786 | i++; | ||
787 | } | ||
788 | |||
789 | return 0; | ||
790 | } | ||
791 | |||
792 | /* Probe a BMC for AEM firmware instances */ | ||
793 | static void aem_register_bmc(int iface, struct device *dev) | ||
794 | { | ||
795 | struct aem_ipmi_data probe; | ||
796 | |||
797 | if (aem_init_ipmi_data(&probe, iface, dev)) | ||
798 | return; | ||
799 | |||
800 | /* Ignore probe errors; they won't cause problems */ | ||
801 | aem_init_aem1(&probe); | ||
802 | aem_init_aem2(&probe); | ||
803 | |||
804 | ipmi_destroy_user(probe.user); | ||
805 | } | ||
806 | |||
807 | /* Handle BMC deletion */ | ||
808 | static void aem_bmc_gone(int iface) | ||
809 | { | ||
810 | struct aem_data *p1, *next1; | ||
811 | |||
812 | list_for_each_entry_safe(p1, next1, &driver_data.aem_devices, list) | ||
813 | if (p1->ipmi.interface == iface) | ||
814 | aem_delete(p1); | ||
815 | } | ||
816 | |||
817 | /* sysfs support functions */ | ||
818 | |||
819 | /* AEM device name */ | ||
820 | static ssize_t show_name(struct device *dev, struct device_attribute *devattr, | ||
821 | char *buf) | ||
822 | { | ||
823 | struct aem_data *data = dev_get_drvdata(dev); | ||
824 | |||
825 | return sprintf(buf, "%s%d\n", DRVNAME, data->ver_major); | ||
826 | } | ||
827 | static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0); | ||
828 | |||
829 | /* AEM device version */ | ||
830 | static ssize_t show_version(struct device *dev, | ||
831 | struct device_attribute *devattr, | ||
832 | char *buf) | ||
833 | { | ||
834 | struct aem_data *data = dev_get_drvdata(dev); | ||
835 | |||
836 | return sprintf(buf, "%d.%d\n", data->ver_major, data->ver_minor); | ||
837 | } | ||
838 | static SENSOR_DEVICE_ATTR(version, S_IRUGO, show_version, NULL, 0); | ||
839 | |||
840 | /* Display power use */ | ||
841 | static ssize_t aem_show_power(struct device *dev, | ||
842 | struct device_attribute *devattr, | ||
843 | char *buf) | ||
844 | { | ||
845 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
846 | struct aem_data *data = dev_get_drvdata(dev); | ||
847 | u64 before, after, delta, time; | ||
848 | signed long leftover; | ||
849 | struct timespec b, a; | ||
850 | |||
851 | mutex_lock(&data->lock); | ||
852 | update_aem_energy(data); | ||
853 | getnstimeofday(&b); | ||
854 | before = data->energy[attr->index]; | ||
855 | |||
856 | leftover = schedule_timeout_interruptible( | ||
857 | msecs_to_jiffies(data->power_period[attr->index]) | ||
858 | ); | ||
859 | if (leftover) { | ||
860 | mutex_unlock(&data->lock); | ||
861 | return 0; | ||
862 | } | ||
863 | |||
864 | update_aem_energy(data); | ||
865 | getnstimeofday(&a); | ||
866 | after = data->energy[attr->index]; | ||
867 | mutex_unlock(&data->lock); | ||
868 | |||
869 | time = timespec_to_ns(&a) - timespec_to_ns(&b); | ||
870 | delta = (after - before) * UJ_PER_MJ; | ||
871 | |||
872 | return sprintf(buf, "%llu\n", | ||
873 | (unsigned long long)div64_u64(delta * NSEC_PER_SEC, time)); | ||
874 | } | ||
875 | |||
876 | /* Display energy use */ | ||
877 | static ssize_t aem_show_energy(struct device *dev, | ||
878 | struct device_attribute *devattr, | ||
879 | char *buf) | ||
880 | { | ||
881 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
882 | struct aem_data *a = dev_get_drvdata(dev); | ||
883 | a->update(a); | ||
884 | |||
885 | return sprintf(buf, "%llu\n", | ||
886 | (unsigned long long)a->energy[attr->index] * 1000); | ||
887 | } | ||
888 | |||
889 | /* Display power interval registers */ | ||
890 | static ssize_t aem_show_power_period(struct device *dev, | ||
891 | struct device_attribute *devattr, | ||
892 | char *buf) | ||
893 | { | ||
894 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
895 | struct aem_data *a = dev_get_drvdata(dev); | ||
896 | a->update(a); | ||
897 | |||
898 | return sprintf(buf, "%lu\n", a->power_period[attr->index]); | ||
899 | } | ||
900 | |||
901 | /* Set power interval registers */ | ||
902 | static ssize_t aem_set_power_period(struct device *dev, | ||
903 | struct device_attribute *devattr, | ||
904 | const char *buf, size_t count) | ||
905 | { | ||
906 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
907 | struct aem_data *a = dev_get_drvdata(dev); | ||
908 | unsigned long temp; | ||
909 | int res; | ||
910 | |||
911 | res = strict_strtoul(buf, 10, &temp); | ||
912 | if (res) | ||
913 | return res; | ||
914 | |||
915 | if (temp < AEM_MIN_POWER_INTERVAL) | ||
916 | return -EINVAL; | ||
917 | |||
918 | mutex_lock(&a->lock); | ||
919 | a->power_period[attr->index] = temp; | ||
920 | mutex_unlock(&a->lock); | ||
921 | |||
922 | return count; | ||
923 | } | ||
924 | |||
925 | /* Discover sensors on an AEM device */ | ||
926 | static int aem_register_sensors(struct aem_data *data, | ||
927 | struct aem_ro_sensor_template *ro, | ||
928 | struct aem_rw_sensor_template *rw) | ||
929 | { | ||
930 | struct device *dev = &data->pdev->dev; | ||
931 | struct sensor_device_attribute *sensors = data->sensors; | ||
932 | int err; | ||
933 | |||
934 | /* Set up read-only sensors */ | ||
935 | while (ro->label) { | ||
936 | sensors->dev_attr.attr.name = ro->label; | ||
937 | sensors->dev_attr.attr.mode = S_IRUGO; | ||
938 | sensors->dev_attr.show = ro->show; | ||
939 | sensors->index = ro->index; | ||
940 | |||
941 | err = device_create_file(dev, &sensors->dev_attr); | ||
942 | if (err) { | ||
943 | sensors->dev_attr.attr.name = NULL; | ||
944 | goto error; | ||
945 | } | ||
946 | sensors++; | ||
947 | ro++; | ||
948 | } | ||
949 | |||
950 | /* Set up read-write sensors */ | ||
951 | while (rw->label) { | ||
952 | sensors->dev_attr.attr.name = rw->label; | ||
953 | sensors->dev_attr.attr.mode = S_IRUGO | S_IWUSR; | ||
954 | sensors->dev_attr.show = rw->show; | ||
955 | sensors->dev_attr.store = rw->set; | ||
956 | sensors->index = rw->index; | ||
957 | |||
958 | err = device_create_file(dev, &sensors->dev_attr); | ||
959 | if (err) { | ||
960 | sensors->dev_attr.attr.name = NULL; | ||
961 | goto error; | ||
962 | } | ||
963 | sensors++; | ||
964 | rw++; | ||
965 | } | ||
966 | |||
967 | err = device_create_file(dev, &sensor_dev_attr_name.dev_attr); | ||
968 | if (err) | ||
969 | goto error; | ||
970 | err = device_create_file(dev, &sensor_dev_attr_version.dev_attr); | ||
971 | return err; | ||
972 | |||
973 | error: | ||
974 | aem_remove_sensors(data); | ||
975 | return err; | ||
976 | } | ||
977 | |||
978 | /* sysfs support functions for AEM2 sensors */ | ||
979 | |||
980 | /* Display temperature use */ | ||
981 | static ssize_t aem2_show_temp(struct device *dev, | ||
982 | struct device_attribute *devattr, | ||
983 | char *buf) | ||
984 | { | ||
985 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
986 | struct aem_data *a = dev_get_drvdata(dev); | ||
987 | a->update(a); | ||
988 | |||
989 | return sprintf(buf, "%u\n", a->temp[attr->index] * 1000); | ||
990 | } | ||
991 | |||
992 | /* Display power-capping registers */ | ||
993 | static ssize_t aem2_show_pcap_value(struct device *dev, | ||
994 | struct device_attribute *devattr, | ||
995 | char *buf) | ||
996 | { | ||
997 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
998 | struct aem_data *a = dev_get_drvdata(dev); | ||
999 | a->update(a); | ||
1000 | |||
1001 | return sprintf(buf, "%u\n", a->pcap[attr->index] * 100000); | ||
1002 | } | ||
1003 | |||
1004 | /* Remove sensors attached to an AEM device */ | ||
1005 | static void aem_remove_sensors(struct aem_data *data) | ||
1006 | { | ||
1007 | int i; | ||
1008 | |||
1009 | for (i = 0; i < AEM_NUM_SENSORS; i++) { | ||
1010 | if (!data->sensors[i].dev_attr.attr.name) | ||
1011 | continue; | ||
1012 | device_remove_file(&data->pdev->dev, | ||
1013 | &data->sensors[i].dev_attr); | ||
1014 | } | ||
1015 | |||
1016 | device_remove_file(&data->pdev->dev, | ||
1017 | &sensor_dev_attr_name.dev_attr); | ||
1018 | device_remove_file(&data->pdev->dev, | ||
1019 | &sensor_dev_attr_version.dev_attr); | ||
1020 | } | ||
1021 | |||
1022 | /* Sensor probe functions */ | ||
1023 | |||
1024 | /* Description of AEM1 sensors */ | ||
1025 | static struct aem_ro_sensor_template aem1_ro_sensors[] = { | ||
1026 | {"energy1_input", aem_show_energy, 0}, | ||
1027 | {"power1_average", aem_show_power, 0}, | ||
1028 | {NULL, NULL, 0}, | ||
1029 | }; | ||
1030 | |||
1031 | static struct aem_rw_sensor_template aem1_rw_sensors[] = { | ||
1032 | {"power1_average_interval", aem_show_power_period, aem_set_power_period, 0}, | ||
1033 | {NULL, NULL, NULL, 0}, | ||
1034 | }; | ||
1035 | |||
1036 | /* Description of AEM2 sensors */ | ||
1037 | static struct aem_ro_sensor_template aem2_ro_sensors[] = { | ||
1038 | {"energy1_input", aem_show_energy, 0}, | ||
1039 | {"energy2_input", aem_show_energy, 1}, | ||
1040 | {"power1_average", aem_show_power, 0}, | ||
1041 | {"power2_average", aem_show_power, 1}, | ||
1042 | {"temp1_input", aem2_show_temp, 0}, | ||
1043 | {"temp2_input", aem2_show_temp, 1}, | ||
1044 | |||
1045 | {"power4_average", aem2_show_pcap_value, POWER_CAP_MAX_HOTPLUG}, | ||
1046 | {"power5_average", aem2_show_pcap_value, POWER_CAP_MAX}, | ||
1047 | {"power6_average", aem2_show_pcap_value, POWER_CAP_MIN_WARNING}, | ||
1048 | {"power7_average", aem2_show_pcap_value, POWER_CAP_MIN}, | ||
1049 | |||
1050 | {"power3_average", aem2_show_pcap_value, POWER_AUX}, | ||
1051 | {"power_cap", aem2_show_pcap_value, POWER_CAP}, | ||
1052 | {NULL, NULL, 0}, | ||
1053 | }; | ||
1054 | |||
1055 | static struct aem_rw_sensor_template aem2_rw_sensors[] = { | ||
1056 | {"power1_average_interval", aem_show_power_period, aem_set_power_period, 0}, | ||
1057 | {"power2_average_interval", aem_show_power_period, aem_set_power_period, 1}, | ||
1058 | {NULL, NULL, NULL, 0}, | ||
1059 | }; | ||
1060 | |||
1061 | /* Set up AEM1 sensor attrs */ | ||
1062 | static int aem1_find_sensors(struct aem_data *data) | ||
1063 | { | ||
1064 | return aem_register_sensors(data, aem1_ro_sensors, aem1_rw_sensors); | ||
1065 | } | ||
1066 | |||
1067 | /* Set up AEM2 sensor attrs */ | ||
1068 | static int aem2_find_sensors(struct aem_data *data) | ||
1069 | { | ||
1070 | return aem_register_sensors(data, aem2_ro_sensors, aem2_rw_sensors); | ||
1071 | } | ||
1072 | |||
1073 | /* Module init/exit routines */ | ||
1074 | |||
1075 | static int __init aem_init(void) | ||
1076 | { | ||
1077 | int res; | ||
1078 | |||
1079 | res = driver_register(&aem_driver); | ||
1080 | if (res) { | ||
1081 | printk(KERN_ERR "Can't register aem driver\n"); | ||
1082 | return res; | ||
1083 | } | ||
1084 | |||
1085 | res = ipmi_smi_watcher_register(&driver_data.bmc_events); | ||
1086 | if (res) | ||
1087 | goto ipmi_reg_err; | ||
1088 | return 0; | ||
1089 | |||
1090 | ipmi_reg_err: | ||
1091 | driver_unregister(&aem_driver); | ||
1092 | return res; | ||
1093 | |||
1094 | } | ||
1095 | |||
1096 | static void __exit aem_exit(void) | ||
1097 | { | ||
1098 | struct aem_data *p1, *next1; | ||
1099 | |||
1100 | ipmi_smi_watcher_unregister(&driver_data.bmc_events); | ||
1101 | driver_unregister(&aem_driver); | ||
1102 | list_for_each_entry_safe(p1, next1, &driver_data.aem_devices, list) | ||
1103 | aem_delete(p1); | ||
1104 | } | ||
1105 | |||
1106 | MODULE_AUTHOR("Darrick J. Wong <djwong@us.ibm.com>"); | ||
1107 | MODULE_DESCRIPTION("IBM Active Energy Manager power/temp sensor driver"); | ||
1108 | MODULE_LICENSE("GPL"); | ||
1109 | |||
1110 | module_init(aem_init); | ||
1111 | module_exit(aem_exit); | ||
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index b4f3aefa12b6..1607536ff5fb 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig | |||
@@ -1028,6 +1028,7 @@ endif | |||
1028 | 1028 | ||
1029 | config BLK_DEV_HD_ONLY | 1029 | config BLK_DEV_HD_ONLY |
1030 | bool "Old hard disk (MFM/RLL/IDE) driver" | 1030 | bool "Old hard disk (MFM/RLL/IDE) driver" |
1031 | depends on !ARM || ARCH_RPC || ARCH_SHARK || BROKEN | ||
1031 | help | 1032 | help |
1032 | There are two drivers for MFM/RLL/IDE hard disks. Most people use | 1033 | There are two drivers for MFM/RLL/IDE hard disks. Most people use |
1033 | the newer enhanced driver, but this old one is still around for two | 1034 | the newer enhanced driver, but this old one is still around for two |
diff --git a/drivers/ide/arm/bast-ide.c b/drivers/ide/arm/bast-ide.c index 713cef20622e..8e8c28104b45 100644 --- a/drivers/ide/arm/bast-ide.c +++ b/drivers/ide/arm/bast-ide.c | |||
@@ -42,6 +42,7 @@ static int __init bastide_register(unsigned int base, unsigned int aux, int irq) | |||
42 | 42 | ||
43 | hw.io_ports.ctl_addr = aux + (6 * 0x20); | 43 | hw.io_ports.ctl_addr = aux + (6 * 0x20); |
44 | hw.irq = irq; | 44 | hw.irq = irq; |
45 | hw.chipset = ide_generic; | ||
45 | 46 | ||
46 | hwif = ide_find_port(); | 47 | hwif = ide_find_port(); |
47 | if (hwif == NULL) | 48 | if (hwif == NULL) |
diff --git a/drivers/ide/arm/ide_arm.c b/drivers/ide/arm/ide_arm.c index 4263ffd4ab20..2f311da4c963 100644 --- a/drivers/ide/arm/ide_arm.c +++ b/drivers/ide/arm/ide_arm.c | |||
@@ -49,6 +49,7 @@ static int __init ide_arm_init(void) | |||
49 | memset(&hw, 0, sizeof(hw)); | 49 | memset(&hw, 0, sizeof(hw)); |
50 | ide_std_init_ports(&hw, base, ctl); | 50 | ide_std_init_ports(&hw, base, ctl); |
51 | hw.irq = IDE_ARM_IRQ; | 51 | hw.irq = IDE_ARM_IRQ; |
52 | hw.chipset = ide_generic; | ||
52 | 53 | ||
53 | hwif = ide_find_port(); | 54 | hwif = ide_find_port(); |
54 | if (hwif) { | 55 | if (hwif) { |
diff --git a/drivers/ide/arm/palm_bk3710.c b/drivers/ide/arm/palm_bk3710.c index 96378ebfb31f..d024ac8fad14 100644 --- a/drivers/ide/arm/palm_bk3710.c +++ b/drivers/ide/arm/palm_bk3710.c | |||
@@ -409,9 +409,6 @@ static int __devinit palm_bk3710_probe(struct platform_device *pdev) | |||
409 | 409 | ||
410 | ide_device_add(idx, &palm_bk3710_port_info); | 410 | ide_device_add(idx, &palm_bk3710_port_info); |
411 | 411 | ||
412 | if (!hwif->present) | ||
413 | goto out; | ||
414 | |||
415 | return 0; | 412 | return 0; |
416 | out: | 413 | out: |
417 | printk(KERN_WARNING "Palm Chip BK3710 IDE Register Fail\n"); | 414 | printk(KERN_WARNING "Palm Chip BK3710 IDE Register Fail\n"); |
diff --git a/drivers/ide/ide-generic.c b/drivers/ide/ide-generic.c index a6073e248f45..2d92214096ab 100644 --- a/drivers/ide/ide-generic.c +++ b/drivers/ide/ide-generic.c | |||
@@ -22,6 +22,10 @@ | |||
22 | 22 | ||
23 | #define DRV_NAME "ide_generic" | 23 | #define DRV_NAME "ide_generic" |
24 | 24 | ||
25 | static int probe_mask = 0x03; | ||
26 | module_param(probe_mask, int, 0); | ||
27 | MODULE_PARM_DESC(probe_mask, "probe mask for legacy ISA IDE ports"); | ||
28 | |||
25 | static ssize_t store_add(struct class *cls, const char *buf, size_t n) | 29 | static ssize_t store_add(struct class *cls, const char *buf, size_t n) |
26 | { | 30 | { |
27 | ide_hwif_t *hwif; | 31 | ide_hwif_t *hwif; |
@@ -89,6 +93,9 @@ static int __init ide_generic_init(void) | |||
89 | u8 idx[MAX_HWIFS]; | 93 | u8 idx[MAX_HWIFS]; |
90 | int i; | 94 | int i; |
91 | 95 | ||
96 | printk(KERN_INFO DRV_NAME ": please use \"probe_mask=0x3f\" module " | ||
97 | "parameter for probing all legacy ISA IDE ports\n"); | ||
98 | |||
92 | for (i = 0; i < MAX_HWIFS; i++) { | 99 | for (i = 0; i < MAX_HWIFS; i++) { |
93 | ide_hwif_t *hwif; | 100 | ide_hwif_t *hwif; |
94 | unsigned long io_addr = ide_default_io_base(i); | 101 | unsigned long io_addr = ide_default_io_base(i); |
@@ -96,7 +103,7 @@ static int __init ide_generic_init(void) | |||
96 | 103 | ||
97 | idx[i] = 0xff; | 104 | idx[i] = 0xff; |
98 | 105 | ||
99 | if (io_addr) { | 106 | if ((probe_mask & (1 << i)) && io_addr) { |
100 | if (!request_region(io_addr, 8, DRV_NAME)) { | 107 | if (!request_region(io_addr, 8, DRV_NAME)) { |
101 | printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX " | 108 | printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX " |
102 | "not free.\n", | 109 | "not free.\n", |
@@ -125,6 +132,7 @@ static int __init ide_generic_init(void) | |||
125 | memset(&hw, 0, sizeof(hw)); | 132 | memset(&hw, 0, sizeof(hw)); |
126 | ide_std_init_ports(&hw, io_addr, io_addr + 0x206); | 133 | ide_std_init_ports(&hw, io_addr, io_addr + 0x206); |
127 | hw.irq = ide_default_irq(io_addr); | 134 | hw.irq = ide_default_irq(io_addr); |
135 | hw.chipset = ide_generic; | ||
128 | ide_init_port_hw(hwif, &hw); | 136 | ide_init_port_hw(hwif, &hw); |
129 | 137 | ||
130 | idx[i] = i; | 138 | idx[i] = i; |
diff --git a/drivers/ide/ide-pnp.c b/drivers/ide/ide-pnp.c index 6a8953f68e9f..adbd01784162 100644 --- a/drivers/ide/ide-pnp.c +++ b/drivers/ide/ide-pnp.c | |||
@@ -55,6 +55,7 @@ static int idepnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) | |||
55 | memset(&hw, 0, sizeof(hw)); | 55 | memset(&hw, 0, sizeof(hw)); |
56 | ide_std_init_ports(&hw, base, ctl); | 56 | ide_std_init_ports(&hw, base, ctl); |
57 | hw.irq = pnp_irq(dev, 0); | 57 | hw.irq = pnp_irq(dev, 0); |
58 | hw.chipset = ide_generic; | ||
58 | 59 | ||
59 | hwif = ide_find_port(); | 60 | hwif = ide_find_port(); |
60 | if (hwif) { | 61 | if (hwif) { |
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 34b0d4f26b58..380fa0c8cc84 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c | |||
@@ -648,13 +648,12 @@ static int ide_register_port(ide_hwif_t *hwif) | |||
648 | 648 | ||
649 | get_device(&hwif->gendev); | 649 | get_device(&hwif->gendev); |
650 | 650 | ||
651 | hwif->portdev = device_create(ide_port_class, &hwif->gendev, | 651 | hwif->portdev = device_create_drvdata(ide_port_class, &hwif->gendev, |
652 | MKDEV(0, 0), hwif->name); | 652 | MKDEV(0, 0), hwif, hwif->name); |
653 | if (IS_ERR(hwif->portdev)) { | 653 | if (IS_ERR(hwif->portdev)) { |
654 | ret = PTR_ERR(hwif->portdev); | 654 | ret = PTR_ERR(hwif->portdev); |
655 | device_unregister(&hwif->gendev); | 655 | device_unregister(&hwif->gendev); |
656 | } | 656 | } |
657 | dev_set_drvdata(hwif->portdev, hwif); | ||
658 | out: | 657 | out: |
659 | return ret; | 658 | return ret; |
660 | } | 659 | } |
@@ -1334,8 +1333,7 @@ static void ide_port_init_devices(ide_hwif_t *hwif) | |||
1334 | static void ide_init_port(ide_hwif_t *hwif, unsigned int port, | 1333 | static void ide_init_port(ide_hwif_t *hwif, unsigned int port, |
1335 | const struct ide_port_info *d) | 1334 | const struct ide_port_info *d) |
1336 | { | 1335 | { |
1337 | if (d->chipset != ide_etrax100) | 1336 | hwif->channel = port; |
1338 | hwif->channel = port; | ||
1339 | 1337 | ||
1340 | if (d->chipset) | 1338 | if (d->chipset) |
1341 | hwif->chipset = d->chipset; | 1339 | hwif->chipset = d->chipset; |
@@ -1520,7 +1518,7 @@ int ide_device_add_all(u8 *idx, const struct ide_port_info *d) | |||
1520 | continue; | 1518 | continue; |
1521 | } | 1519 | } |
1522 | 1520 | ||
1523 | if (d->chipset != ide_etrax100 && (i & 1) && mate) { | 1521 | if ((i & 1) && mate) { |
1524 | hwif->mate = mate; | 1522 | hwif->mate = mate; |
1525 | mate->mate = hwif; | 1523 | mate->mate = hwif; |
1526 | } | 1524 | } |
@@ -1666,6 +1664,7 @@ static void ide_legacy_init_one(u8 *idx, hw_regs_t *hw, u8 port_no, | |||
1666 | 1664 | ||
1667 | ide_std_init_ports(hw, base, ctl); | 1665 | ide_std_init_ports(hw, base, ctl); |
1668 | hw->irq = irq; | 1666 | hw->irq = irq; |
1667 | hw->chipset = d->chipset; | ||
1669 | 1668 | ||
1670 | hwif = ide_find_port_slot(d); | 1669 | hwif = ide_find_port_slot(d); |
1671 | if (hwif) { | 1670 | if (hwif) { |
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c index 8d6ad812a014..55ec7f798772 100644 --- a/drivers/ide/ide-proc.c +++ b/drivers/ide/ide-proc.c | |||
@@ -63,7 +63,6 @@ static int proc_ide_read_imodel | |||
63 | case ide_pmac: name = "mac-io"; break; | 63 | case ide_pmac: name = "mac-io"; break; |
64 | case ide_au1xxx: name = "au1xxx"; break; | 64 | case ide_au1xxx: name = "au1xxx"; break; |
65 | case ide_palm3710: name = "palm3710"; break; | 65 | case ide_palm3710: name = "palm3710"; break; |
66 | case ide_etrax100: name = "etrax100"; break; | ||
67 | case ide_acorn: name = "acorn"; break; | 66 | case ide_acorn: name = "acorn"; break; |
68 | default: name = "(unknown)"; break; | 67 | default: name = "(unknown)"; break; |
69 | } | 68 | } |
diff --git a/drivers/ide/legacy/buddha.c b/drivers/ide/legacy/buddha.c index 5c730e4dd735..9a1d27ef3f8a 100644 --- a/drivers/ide/legacy/buddha.c +++ b/drivers/ide/legacy/buddha.c | |||
@@ -138,6 +138,8 @@ static void __init buddha_setup_ports(hw_regs_t *hw, unsigned long base, | |||
138 | 138 | ||
139 | hw->irq = IRQ_AMIGA_PORTS; | 139 | hw->irq = IRQ_AMIGA_PORTS; |
140 | hw->ack_intr = ack_intr; | 140 | hw->ack_intr = ack_intr; |
141 | |||
142 | hw->chipset = ide_generic; | ||
141 | } | 143 | } |
142 | 144 | ||
143 | /* | 145 | /* |
diff --git a/drivers/ide/legacy/falconide.c b/drivers/ide/legacy/falconide.c index 9e449a0c623f..af11028b4794 100644 --- a/drivers/ide/legacy/falconide.c +++ b/drivers/ide/legacy/falconide.c | |||
@@ -81,6 +81,8 @@ static void __init falconide_setup_ports(hw_regs_t *hw) | |||
81 | 81 | ||
82 | hw->irq = IRQ_MFP_IDE; | 82 | hw->irq = IRQ_MFP_IDE; |
83 | hw->ack_intr = NULL; | 83 | hw->ack_intr = NULL; |
84 | |||
85 | hw->chipset = ide_generic; | ||
84 | } | 86 | } |
85 | 87 | ||
86 | /* | 88 | /* |
diff --git a/drivers/ide/legacy/gayle.c b/drivers/ide/legacy/gayle.c index a9c2593a898c..fed7d812761c 100644 --- a/drivers/ide/legacy/gayle.c +++ b/drivers/ide/legacy/gayle.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/ide.h> | 16 | #include <linux/ide.h> |
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/zorro.h> | 18 | #include <linux/zorro.h> |
19 | #include <linux/module.h> | ||
19 | 20 | ||
20 | #include <asm/setup.h> | 21 | #include <asm/setup.h> |
21 | #include <asm/amigahw.h> | 22 | #include <asm/amigahw.h> |
@@ -62,7 +63,10 @@ | |||
62 | GAYLE_NUM_HWIFS-1) | 63 | GAYLE_NUM_HWIFS-1) |
63 | #define GAYLE_HAS_CONTROL_REG (!ide_doubler) | 64 | #define GAYLE_HAS_CONTROL_REG (!ide_doubler) |
64 | #define GAYLE_IDEREG_SIZE (ide_doubler ? 0x1000 : 0x2000) | 65 | #define GAYLE_IDEREG_SIZE (ide_doubler ? 0x1000 : 0x2000) |
66 | |||
65 | int ide_doubler = 0; /* support IDE doublers? */ | 67 | int ide_doubler = 0; /* support IDE doublers? */ |
68 | EXPORT_SYMBOL_GPL(ide_doubler); | ||
69 | |||
66 | module_param_named(doubler, ide_doubler, bool, 0); | 70 | module_param_named(doubler, ide_doubler, bool, 0); |
67 | MODULE_PARM_DESC(doubler, "enable support for IDE doublers"); | 71 | MODULE_PARM_DESC(doubler, "enable support for IDE doublers"); |
68 | #endif /* CONFIG_BLK_DEV_IDEDOUBLER */ | 72 | #endif /* CONFIG_BLK_DEV_IDEDOUBLER */ |
@@ -112,6 +116,8 @@ static void __init gayle_setup_ports(hw_regs_t *hw, unsigned long base, | |||
112 | 116 | ||
113 | hw->irq = IRQ_AMIGA_PORTS; | 117 | hw->irq = IRQ_AMIGA_PORTS; |
114 | hw->ack_intr = ack_intr; | 118 | hw->ack_intr = ack_intr; |
119 | |||
120 | hw->chipset = ide_generic; | ||
115 | } | 121 | } |
116 | 122 | ||
117 | /* | 123 | /* |
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c index aa2ea3deac85..f633b6b3c7f3 100644 --- a/drivers/ide/legacy/ide-cs.c +++ b/drivers/ide/legacy/ide-cs.c | |||
@@ -135,13 +135,17 @@ static void ide_detach(struct pcmcia_device *link) | |||
135 | { | 135 | { |
136 | ide_info_t *info = link->priv; | 136 | ide_info_t *info = link->priv; |
137 | ide_hwif_t *hwif = info->hwif; | 137 | ide_hwif_t *hwif = info->hwif; |
138 | unsigned long data_addr, ctl_addr; | ||
138 | 139 | ||
139 | DEBUG(0, "ide_detach(0x%p)\n", link); | 140 | DEBUG(0, "ide_detach(0x%p)\n", link); |
140 | 141 | ||
142 | data_addr = hwif->io_ports.data_addr; | ||
143 | ctl_addr = hwif->io_ports.ctl_addr; | ||
144 | |||
141 | ide_release(link); | 145 | ide_release(link); |
142 | 146 | ||
143 | release_region(hwif->io_ports.ctl_addr, 1); | 147 | release_region(ctl_addr, 1); |
144 | release_region(hwif->io_ports.data_addr, 8); | 148 | release_region(data_addr, 8); |
145 | 149 | ||
146 | kfree(info); | 150 | kfree(info); |
147 | } /* ide_detach */ | 151 | } /* ide_detach */ |
@@ -194,6 +198,16 @@ static ide_hwif_t *idecs_register(unsigned long io, unsigned long ctl, | |||
194 | if (hwif->present) | 198 | if (hwif->present) |
195 | return hwif; | 199 | return hwif; |
196 | 200 | ||
201 | /* retry registration in case device is still spinning up */ | ||
202 | for (i = 0; i < 10; i++) { | ||
203 | msleep(100); | ||
204 | ide_port_scan(hwif); | ||
205 | if (hwif->present) | ||
206 | return hwif; | ||
207 | } | ||
208 | |||
209 | return hwif; | ||
210 | |||
197 | out_release: | 211 | out_release: |
198 | release_region(ctl, 1); | 212 | release_region(ctl, 1); |
199 | release_region(io, 8); | 213 | release_region(io, 8); |
@@ -222,7 +236,7 @@ static int ide_config(struct pcmcia_device *link) | |||
222 | cistpl_cftable_entry_t dflt; | 236 | cistpl_cftable_entry_t dflt; |
223 | } *stk = NULL; | 237 | } *stk = NULL; |
224 | cistpl_cftable_entry_t *cfg; | 238 | cistpl_cftable_entry_t *cfg; |
225 | int i, pass, last_ret = 0, last_fn = 0, is_kme = 0; | 239 | int pass, last_ret = 0, last_fn = 0, is_kme = 0; |
226 | unsigned long io_base, ctl_base; | 240 | unsigned long io_base, ctl_base; |
227 | ide_hwif_t *hwif; | 241 | ide_hwif_t *hwif; |
228 | 242 | ||
@@ -319,30 +333,15 @@ static int ide_config(struct pcmcia_device *link) | |||
319 | if (is_kme) | 333 | if (is_kme) |
320 | outb(0x81, ctl_base+1); | 334 | outb(0x81, ctl_base+1); |
321 | 335 | ||
322 | /* retry registration in case device is still spinning up */ | 336 | hwif = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ, link); |
323 | for (i = 0; i < 10; i++) { | 337 | if (hwif == NULL && link->io.NumPorts1 == 0x20) { |
324 | hwif = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ, link); | ||
325 | if (hwif) | ||
326 | break; | ||
327 | if (link->io.NumPorts1 == 0x20) { | ||
328 | outb(0x02, ctl_base + 0x10); | 338 | outb(0x02, ctl_base + 0x10); |
329 | hwif = idecs_register(io_base + 0x10, ctl_base + 0x10, | 339 | hwif = idecs_register(io_base + 0x10, ctl_base + 0x10, |
330 | link->irq.AssignedIRQ, link); | 340 | link->irq.AssignedIRQ, link); |
331 | if (hwif) { | ||
332 | io_base += 0x10; | ||
333 | ctl_base += 0x10; | ||
334 | break; | ||
335 | } | ||
336 | } | ||
337 | msleep(100); | ||
338 | } | 341 | } |
339 | 342 | ||
340 | if (hwif == NULL) { | 343 | if (hwif == NULL) |
341 | printk(KERN_NOTICE "ide-cs: ide_register() at 0x%3lx & 0x%3lx" | ||
342 | ", irq %u failed\n", io_base, ctl_base, | ||
343 | link->irq.AssignedIRQ); | ||
344 | goto failed; | 344 | goto failed; |
345 | } | ||
346 | 345 | ||
347 | info->ndev = 1; | 346 | info->ndev = 1; |
348 | sprintf(info->node.dev_name, "hd%c", 'a' + hwif->index * 2); | 347 | sprintf(info->node.dev_name, "hd%c", 'a' + hwif->index * 2); |
diff --git a/drivers/ide/legacy/macide.c b/drivers/ide/legacy/macide.c index caa2632dd08e..2e84290d0bcc 100644 --- a/drivers/ide/legacy/macide.c +++ b/drivers/ide/legacy/macide.c | |||
@@ -78,6 +78,8 @@ static void __init macide_setup_ports(hw_regs_t *hw, unsigned long base, | |||
78 | 78 | ||
79 | hw->irq = irq; | 79 | hw->irq = irq; |
80 | hw->ack_intr = ack_intr; | 80 | hw->ack_intr = ack_intr; |
81 | |||
82 | hw->chipset = ide_generic; | ||
81 | } | 83 | } |
82 | 84 | ||
83 | static const char *mac_ide_name[] = | 85 | static const char *mac_ide_name[] = |
diff --git a/drivers/ide/legacy/q40ide.c b/drivers/ide/legacy/q40ide.c index 6f535d00e638..8ff6e2d20834 100644 --- a/drivers/ide/legacy/q40ide.c +++ b/drivers/ide/legacy/q40ide.c | |||
@@ -70,6 +70,8 @@ static void q40_ide_setup_ports(hw_regs_t *hw, unsigned long base, | |||
70 | 70 | ||
71 | hw->irq = irq; | 71 | hw->irq = irq; |
72 | hw->ack_intr = ack_intr; | 72 | hw->ack_intr = ack_intr; |
73 | |||
74 | hw->chipset = ide_generic; | ||
73 | } | 75 | } |
74 | 76 | ||
75 | static void q40ide_input_data(ide_drive_t *drive, struct request *rq, | 77 | static void q40ide_input_data(ide_drive_t *drive, struct request *rq, |
diff --git a/drivers/ide/pci/cmd640.c b/drivers/ide/pci/cmd640.c index aaf38109eaec..b38a1980dcd5 100644 --- a/drivers/ide/pci/cmd640.c +++ b/drivers/ide/pci/cmd640.c | |||
@@ -747,9 +747,11 @@ static int __init cmd640x_init(void) | |||
747 | 747 | ||
748 | ide_std_init_ports(&hw[0], 0x1f0, 0x3f6); | 748 | ide_std_init_ports(&hw[0], 0x1f0, 0x3f6); |
749 | hw[0].irq = 14; | 749 | hw[0].irq = 14; |
750 | hw[0].chipset = ide_cmd640; | ||
750 | 751 | ||
751 | ide_std_init_ports(&hw[1], 0x170, 0x376); | 752 | ide_std_init_ports(&hw[1], 0x170, 0x376); |
752 | hw[1].irq = 15; | 753 | hw[1].irq = 15; |
754 | hw[1].chipset = ide_cmd640; | ||
753 | 755 | ||
754 | printk(KERN_INFO "cmd640: buggy cmd640%c interface on %s, config=0x%02x" | 756 | printk(KERN_INFO "cmd640: buggy cmd640%c interface on %s, config=0x%02x" |
755 | "\n", 'a' + cmd640_chip_version - 1, bus_type, cfr); | 757 | "\n", 'a' + cmd640_chip_version - 1, bus_type, cfr); |
diff --git a/drivers/ide/pci/delkin_cb.c b/drivers/ide/pci/delkin_cb.c index b9e457996d0e..af0f30051d5a 100644 --- a/drivers/ide/pci/delkin_cb.c +++ b/drivers/ide/pci/delkin_cb.c | |||
@@ -47,13 +47,18 @@ static const struct ide_port_ops delkin_cb_port_ops = { | |||
47 | .quirkproc = ide_undecoded_slave, | 47 | .quirkproc = ide_undecoded_slave, |
48 | }; | 48 | }; |
49 | 49 | ||
50 | static const struct ide_port_info delkin_cb_port_info = { | ||
51 | .port_ops = &delkin_cb_port_ops, | ||
52 | .host_flags = IDE_HFLAG_IO_32BIT | IDE_HFLAG_UNMASK_IRQS | | ||
53 | IDE_HFLAG_NO_DMA, | ||
54 | }; | ||
55 | |||
50 | static int __devinit | 56 | static int __devinit |
51 | delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id) | 57 | delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id) |
52 | { | 58 | { |
53 | unsigned long base; | 59 | unsigned long base; |
54 | hw_regs_t hw; | 60 | hw_regs_t hw; |
55 | ide_hwif_t *hwif = NULL; | 61 | ide_hwif_t *hwif = NULL; |
56 | ide_drive_t *drive; | ||
57 | int i, rc; | 62 | int i, rc; |
58 | u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; | 63 | u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; |
59 | 64 | ||
@@ -79,6 +84,7 @@ delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id) | |||
79 | memset(&hw, 0, sizeof(hw)); | 84 | memset(&hw, 0, sizeof(hw)); |
80 | ide_std_init_ports(&hw, base + 0x10, base + 0x1e); | 85 | ide_std_init_ports(&hw, base + 0x10, base + 0x1e); |
81 | hw.irq = dev->irq; | 86 | hw.irq = dev->irq; |
87 | hw.dev = &dev->dev; | ||
82 | hw.chipset = ide_pci; /* this enables IRQ sharing */ | 88 | hw.chipset = ide_pci; /* this enables IRQ sharing */ |
83 | 89 | ||
84 | hwif = ide_find_port(); | 90 | hwif = ide_find_port(); |
@@ -89,26 +95,16 @@ delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id) | |||
89 | 95 | ||
90 | ide_init_port_data(hwif, i); | 96 | ide_init_port_data(hwif, i); |
91 | ide_init_port_hw(hwif, &hw); | 97 | ide_init_port_hw(hwif, &hw); |
92 | hwif->port_ops = &delkin_cb_port_ops; | ||
93 | 98 | ||
94 | idx[0] = i; | 99 | idx[0] = i; |
95 | 100 | ||
96 | ide_device_add(idx, NULL); | 101 | ide_device_add(idx, &delkin_cb_port_info); |
97 | |||
98 | if (!hwif->present) | ||
99 | goto out_disable; | ||
100 | 102 | ||
101 | pci_set_drvdata(dev, hwif); | 103 | pci_set_drvdata(dev, hwif); |
102 | hwif->dev = &dev->dev; | 104 | |
103 | drive = &hwif->drives[0]; | ||
104 | if (drive->present) { | ||
105 | drive->io_32bit = 1; | ||
106 | drive->unmask = 1; | ||
107 | } | ||
108 | return 0; | 105 | return 0; |
109 | 106 | ||
110 | out_disable: | 107 | out_disable: |
111 | printk(KERN_ERR "delkin_cb: no IDE devices found\n"); | ||
112 | pci_release_regions(dev); | 108 | pci_release_regions(dev); |
113 | pci_disable_device(dev); | 109 | pci_disable_device(dev); |
114 | return -ENODEV; | 110 | return -ENODEV; |
@@ -139,14 +135,12 @@ static struct pci_driver driver = { | |||
139 | .remove = delkin_cb_remove, | 135 | .remove = delkin_cb_remove, |
140 | }; | 136 | }; |
141 | 137 | ||
142 | static int | 138 | static int __init delkin_cb_init(void) |
143 | delkin_cb_init (void) | ||
144 | { | 139 | { |
145 | return pci_register_driver(&driver); | 140 | return pci_register_driver(&driver); |
146 | } | 141 | } |
147 | 142 | ||
148 | static void | 143 | static void __exit delkin_cb_exit(void) |
149 | delkin_cb_exit (void) | ||
150 | { | 144 | { |
151 | pci_unregister_driver(&driver); | 145 | pci_unregister_driver(&driver); |
152 | } | 146 | } |
diff --git a/drivers/ide/pci/opti621.c b/drivers/ide/pci/opti621.c index 6e99080497bf..725c80508d90 100644 --- a/drivers/ide/pci/opti621.c +++ b/drivers/ide/pci/opti621.c | |||
@@ -81,8 +81,6 @@ | |||
81 | * 0.5 doesn't work. | 81 | * 0.5 doesn't work. |
82 | */ | 82 | */ |
83 | 83 | ||
84 | #define OPTI621_DEBUG /* define for debug messages */ | ||
85 | |||
86 | #include <linux/types.h> | 84 | #include <linux/types.h> |
87 | #include <linux/module.h> | 85 | #include <linux/module.h> |
88 | #include <linux/kernel.h> | 86 | #include <linux/kernel.h> |
@@ -92,28 +90,6 @@ | |||
92 | 90 | ||
93 | #include <asm/io.h> | 91 | #include <asm/io.h> |
94 | 92 | ||
95 | //#define OPTI621_MAX_PIO 3 | ||
96 | /* In fact, I do not have any PIO 4 drive | ||
97 | * (address: 25 ns, data: 70 ns, recovery: 35 ns), | ||
98 | * but OPTi 82C621 is programmable and it can do (minimal values): | ||
99 | * on 40MHz PCI bus (pulse 25 ns): | ||
100 | * address: 25 ns, data: 25 ns, recovery: 50 ns; | ||
101 | * on 20MHz PCI bus (pulse 50 ns): | ||
102 | * address: 50 ns, data: 50 ns, recovery: 100 ns. | ||
103 | */ | ||
104 | |||
105 | /* #define READ_PREFETCH 0 */ | ||
106 | /* Uncomment for disable read prefetch. | ||
107 | * There is some readprefetch capatibility in hdparm, | ||
108 | * but when I type hdparm -P 1 /dev/hda, I got errors | ||
109 | * and till reset drive is inaccessible. | ||
110 | * This (hw) read prefetch is safe on my drive. | ||
111 | */ | ||
112 | |||
113 | #ifndef READ_PREFETCH | ||
114 | #define READ_PREFETCH 0x40 /* read prefetch is enabled */ | ||
115 | #endif /* else read prefetch is disabled */ | ||
116 | |||
117 | #define READ_REG 0 /* index of Read cycle timing register */ | 93 | #define READ_REG 0 /* index of Read cycle timing register */ |
118 | #define WRITE_REG 1 /* index of Write cycle timing register */ | 94 | #define WRITE_REG 1 /* index of Write cycle timing register */ |
119 | #define CNTRL_REG 3 /* index of Control register */ | 95 | #define CNTRL_REG 3 /* index of Control register */ |
@@ -122,51 +98,8 @@ | |||
122 | 98 | ||
123 | static int reg_base; | 99 | static int reg_base; |
124 | 100 | ||
125 | #define PIO_NOT_EXIST 254 | ||
126 | #define PIO_DONT_KNOW 255 | ||
127 | |||
128 | static DEFINE_SPINLOCK(opti621_lock); | 101 | static DEFINE_SPINLOCK(opti621_lock); |
129 | 102 | ||
130 | /* there are stored pio numbers from other calls of opti621_set_pio_mode */ | ||
131 | static void compute_pios(ide_drive_t *drive, const u8 pio) | ||
132 | /* Store values into drive->drive_data | ||
133 | * second_contr - 0 for primary controller, 1 for secondary | ||
134 | * slave_drive - 0 -> pio is for master, 1 -> pio is for slave | ||
135 | * pio - PIO mode for selected drive (for other we don't know) | ||
136 | */ | ||
137 | { | ||
138 | int d; | ||
139 | ide_hwif_t *hwif = HWIF(drive); | ||
140 | |||
141 | drive->drive_data = pio; | ||
142 | |||
143 | for (d = 0; d < 2; ++d) { | ||
144 | drive = &hwif->drives[d]; | ||
145 | if (drive->present) { | ||
146 | if (drive->drive_data == PIO_DONT_KNOW) | ||
147 | drive->drive_data = ide_get_best_pio_mode(drive, 255, 3); | ||
148 | #ifdef OPTI621_DEBUG | ||
149 | printk("%s: Selected PIO mode %d\n", | ||
150 | drive->name, drive->drive_data); | ||
151 | #endif | ||
152 | } else { | ||
153 | drive->drive_data = PIO_NOT_EXIST; | ||
154 | } | ||
155 | } | ||
156 | } | ||
157 | |||
158 | static int cmpt_clk(int time, int bus_speed) | ||
159 | /* Returns (rounded up) time in clocks for time in ns, | ||
160 | * with bus_speed in MHz. | ||
161 | * Example: bus_speed = 40 MHz, time = 80 ns | ||
162 | * 1000/40 = 25 ns (clk value), | ||
163 | * 80/25 = 3.2, rounded up to 4 (I hope ;-)). | ||
164 | * Use idebus=xx to select right frequency. | ||
165 | */ | ||
166 | { | ||
167 | return ((time*bus_speed+999)/1000); | ||
168 | } | ||
169 | |||
170 | /* Write value to register reg, base of register | 103 | /* Write value to register reg, base of register |
171 | * is at reg_base (0x1f0 primary, 0x170 secondary, | 104 | * is at reg_base (0x1f0 primary, 0x170 secondary, |
172 | * if not changed by PCI configuration). | 105 | * if not changed by PCI configuration). |
@@ -199,83 +132,29 @@ static u8 read_reg(int reg) | |||
199 | return ret; | 132 | return ret; |
200 | } | 133 | } |
201 | 134 | ||
202 | typedef struct pio_clocks_s { | ||
203 | int address_time; /* Address setup (clocks) */ | ||
204 | int data_time; /* Active/data pulse (clocks) */ | ||
205 | int recovery_time; /* Recovery time (clocks) */ | ||
206 | } pio_clocks_t; | ||
207 | |||
208 | static void compute_clocks(int pio, pio_clocks_t *clks) | ||
209 | { | ||
210 | if (pio != PIO_NOT_EXIST) { | ||
211 | int adr_setup, data_pls; | ||
212 | int bus_speed = ide_pci_clk ? ide_pci_clk : system_bus_clock(); | ||
213 | |||
214 | adr_setup = ide_pio_timings[pio].setup_time; | ||
215 | data_pls = ide_pio_timings[pio].active_time; | ||
216 | clks->address_time = cmpt_clk(adr_setup, bus_speed); | ||
217 | clks->data_time = cmpt_clk(data_pls, bus_speed); | ||
218 | clks->recovery_time = cmpt_clk(ide_pio_timings[pio].cycle_time | ||
219 | - adr_setup-data_pls, bus_speed); | ||
220 | if (clks->address_time < 1) | ||
221 | clks->address_time = 1; | ||
222 | if (clks->address_time > 4) | ||
223 | clks->address_time = 4; | ||
224 | if (clks->data_time < 1) | ||
225 | clks->data_time = 1; | ||
226 | if (clks->data_time > 16) | ||
227 | clks->data_time = 16; | ||
228 | if (clks->recovery_time < 2) | ||
229 | clks->recovery_time = 2; | ||
230 | if (clks->recovery_time > 17) | ||
231 | clks->recovery_time = 17; | ||
232 | } else { | ||
233 | clks->address_time = 1; | ||
234 | clks->data_time = 1; | ||
235 | clks->recovery_time = 2; | ||
236 | /* minimal values */ | ||
237 | } | ||
238 | } | ||
239 | |||
240 | static void opti621_set_pio_mode(ide_drive_t *drive, const u8 pio) | 135 | static void opti621_set_pio_mode(ide_drive_t *drive, const u8 pio) |
241 | { | 136 | { |
242 | /* primary and secondary drives share some registers, | 137 | ide_hwif_t *hwif = drive->hwif; |
243 | * so we have to program both drives | 138 | ide_drive_t *pair = ide_get_paired_drive(drive); |
244 | */ | ||
245 | unsigned long flags; | 139 | unsigned long flags; |
246 | u8 pio1 = 0, pio2 = 0; | 140 | u8 tim, misc, addr_pio = pio, clk; |
247 | pio_clocks_t first, second; | 141 | |
248 | int ax, drdy; | 142 | /* DRDY is default 2 (by OPTi Databook) */ |
249 | u8 cycle1, cycle2, misc; | 143 | static const u8 addr_timings[2][5] = { |
250 | ide_hwif_t *hwif = HWIF(drive); | 144 | { 0x20, 0x10, 0x00, 0x00, 0x00 }, /* 33 MHz */ |
251 | 145 | { 0x10, 0x10, 0x00, 0x00, 0x00 }, /* 25 MHz */ | |
252 | /* sets drive->drive_data for both drives */ | 146 | }; |
253 | compute_pios(drive, pio); | 147 | static const u8 data_rec_timings[2][5] = { |
254 | pio1 = hwif->drives[0].drive_data; | 148 | { 0x5b, 0x45, 0x32, 0x21, 0x20 }, /* 33 MHz */ |
255 | pio2 = hwif->drives[1].drive_data; | 149 | { 0x48, 0x34, 0x21, 0x10, 0x10 } /* 25 MHz */ |
256 | 150 | }; | |
257 | compute_clocks(pio1, &first); | 151 | |
258 | compute_clocks(pio2, &second); | 152 | drive->drive_data = XFER_PIO_0 + pio; |
259 | 153 | ||
260 | /* ax = max(a1,a2) */ | 154 | if (pair->present) { |
261 | ax = (first.address_time < second.address_time) ? second.address_time : first.address_time; | 155 | if (pair->drive_data && pair->drive_data < drive->drive_data) |
262 | 156 | addr_pio = pair->drive_data - XFER_PIO_0; | |
263 | drdy = 2; /* DRDY is default 2 (by OPTi Databook) */ | 157 | } |
264 | |||
265 | cycle1 = ((first.data_time-1)<<4) | (first.recovery_time-2); | ||
266 | cycle2 = ((second.data_time-1)<<4) | (second.recovery_time-2); | ||
267 | misc = READ_PREFETCH | ((ax-1)<<4) | ((drdy-2)<<1); | ||
268 | |||
269 | #ifdef OPTI621_DEBUG | ||
270 | printk("%s: master: address: %d, data: %d, " | ||
271 | "recovery: %d, drdy: %d [clk]\n", | ||
272 | hwif->name, ax, first.data_time, | ||
273 | first.recovery_time, drdy); | ||
274 | printk("%s: slave: address: %d, data: %d, " | ||
275 | "recovery: %d, drdy: %d [clk]\n", | ||
276 | hwif->name, ax, second.data_time, | ||
277 | second.recovery_time, drdy); | ||
278 | #endif | ||
279 | 158 | ||
280 | spin_lock_irqsave(&opti621_lock, flags); | 159 | spin_lock_irqsave(&opti621_lock, flags); |
281 | 160 | ||
@@ -289,24 +168,21 @@ static void opti621_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
289 | (void)inb(reg_base + CNTRL_REG); | 168 | (void)inb(reg_base + CNTRL_REG); |
290 | /* if reads 0xc0, no interface exist? */ | 169 | /* if reads 0xc0, no interface exist? */ |
291 | read_reg(CNTRL_REG); | 170 | read_reg(CNTRL_REG); |
292 | /* read version, probably 0 */ | ||
293 | read_reg(STRAP_REG); | ||
294 | 171 | ||
295 | /* program primary drive */ | 172 | /* check CLK speed */ |
296 | /* select Index-0 for Register-A */ | 173 | clk = read_reg(STRAP_REG) & 1; |
297 | write_reg(0, MISC_REG); | 174 | |
298 | /* set read cycle timings */ | 175 | printk(KERN_INFO "%s: CLK = %d MHz\n", hwif->name, clk ? 25 : 33); |
299 | write_reg(cycle1, READ_REG); | ||
300 | /* set write cycle timings */ | ||
301 | write_reg(cycle1, WRITE_REG); | ||
302 | 176 | ||
303 | /* program secondary drive */ | 177 | tim = data_rec_timings[clk][pio]; |
304 | /* select Index-1 for Register-B */ | 178 | misc = addr_timings[clk][addr_pio]; |
305 | write_reg(1, MISC_REG); | 179 | |
180 | /* select Index-0/1 for Register-A/B */ | ||
181 | write_reg(drive->select.b.unit, MISC_REG); | ||
306 | /* set read cycle timings */ | 182 | /* set read cycle timings */ |
307 | write_reg(cycle2, READ_REG); | 183 | write_reg(tim, READ_REG); |
308 | /* set write cycle timings */ | 184 | /* set write cycle timings */ |
309 | write_reg(cycle2, WRITE_REG); | 185 | write_reg(tim, WRITE_REG); |
310 | 186 | ||
311 | /* use Register-A for drive 0 */ | 187 | /* use Register-A for drive 0 */ |
312 | /* use Register-B for drive 1 */ | 188 | /* use Register-B for drive 1 */ |
@@ -319,45 +195,26 @@ static void opti621_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
319 | spin_unlock_irqrestore(&opti621_lock, flags); | 195 | spin_unlock_irqrestore(&opti621_lock, flags); |
320 | } | 196 | } |
321 | 197 | ||
322 | static void __devinit opti621_port_init_devs(ide_hwif_t *hwif) | ||
323 | { | ||
324 | hwif->drives[0].drive_data = PIO_DONT_KNOW; | ||
325 | hwif->drives[1].drive_data = PIO_DONT_KNOW; | ||
326 | } | ||
327 | |||
328 | static const struct ide_port_ops opti621_port_ops = { | 198 | static const struct ide_port_ops opti621_port_ops = { |
329 | .port_init_devs = opti621_port_init_devs, | ||
330 | .set_pio_mode = opti621_set_pio_mode, | 199 | .set_pio_mode = opti621_set_pio_mode, |
331 | }; | 200 | }; |
332 | 201 | ||
333 | static const struct ide_port_info opti621_chipsets[] __devinitdata = { | 202 | static const struct ide_port_info opti621_chipset __devinitdata = { |
334 | { /* 0 */ | 203 | .name = "OPTI621/X", |
335 | .name = "OPTI621", | 204 | .enablebits = { {0x45, 0x80, 0x00}, {0x40, 0x08, 0x00} }, |
336 | .enablebits = { {0x45, 0x80, 0x00}, {0x40, 0x08, 0x00} }, | 205 | .port_ops = &opti621_port_ops, |
337 | .port_ops = &opti621_port_ops, | 206 | .host_flags = IDE_HFLAG_NO_DMA, |
338 | .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA, | 207 | .pio_mask = ATA_PIO4, |
339 | .pio_mask = ATA_PIO3, | ||
340 | .swdma_mask = ATA_SWDMA2, | ||
341 | .mwdma_mask = ATA_MWDMA2, | ||
342 | }, { /* 1 */ | ||
343 | .name = "OPTI621X", | ||
344 | .enablebits = { {0x45, 0x80, 0x00}, {0x40, 0x08, 0x00} }, | ||
345 | .port_ops = &opti621_port_ops, | ||
346 | .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA, | ||
347 | .pio_mask = ATA_PIO3, | ||
348 | .swdma_mask = ATA_SWDMA2, | ||
349 | .mwdma_mask = ATA_MWDMA2, | ||
350 | } | ||
351 | }; | 208 | }; |
352 | 209 | ||
353 | static int __devinit opti621_init_one(struct pci_dev *dev, const struct pci_device_id *id) | 210 | static int __devinit opti621_init_one(struct pci_dev *dev, const struct pci_device_id *id) |
354 | { | 211 | { |
355 | return ide_setup_pci_device(dev, &opti621_chipsets[id->driver_data]); | 212 | return ide_setup_pci_device(dev, &opti621_chipset); |
356 | } | 213 | } |
357 | 214 | ||
358 | static const struct pci_device_id opti621_pci_tbl[] = { | 215 | static const struct pci_device_id opti621_pci_tbl[] = { |
359 | { PCI_VDEVICE(OPTI, PCI_DEVICE_ID_OPTI_82C621), 0 }, | 216 | { PCI_VDEVICE(OPTI, PCI_DEVICE_ID_OPTI_82C621), 0 }, |
360 | { PCI_VDEVICE(OPTI, PCI_DEVICE_ID_OPTI_82C825), 1 }, | 217 | { PCI_VDEVICE(OPTI, PCI_DEVICE_ID_OPTI_82C825), 0 }, |
361 | { 0, }, | 218 | { 0, }, |
362 | }; | 219 | }; |
363 | MODULE_DEVICE_TABLE(pci, opti621_pci_tbl); | 220 | MODULE_DEVICE_TABLE(pci, opti621_pci_tbl); |
diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c index 4b0b85d8faf5..e127eb25ab63 100644 --- a/drivers/ide/pci/sis5513.c +++ b/drivers/ide/pci/sis5513.c | |||
@@ -569,6 +569,11 @@ static int __devinit sis5513_init_one(struct pci_dev *dev, const struct pci_devi | |||
569 | { | 569 | { |
570 | struct ide_port_info d = sis5513_chipset; | 570 | struct ide_port_info d = sis5513_chipset; |
571 | u8 udma_rates[] = { 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x7f, 0x7f }; | 571 | u8 udma_rates[] = { 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x7f, 0x7f }; |
572 | int rc; | ||
573 | |||
574 | rc = pci_enable_device(dev); | ||
575 | if (rc) | ||
576 | return rc; | ||
572 | 577 | ||
573 | if (sis_find_family(dev) == 0) | 578 | if (sis_find_family(dev) == 0) |
574 | return -ENOTSUPP; | 579 | return -ENOTSUPP; |
diff --git a/drivers/ide/ppc/mpc8xx.c b/drivers/ide/ppc/mpc8xx.c index f0e638dcc3ab..236f9c38e519 100644 --- a/drivers/ide/ppc/mpc8xx.c +++ b/drivers/ide/ppc/mpc8xx.c | |||
@@ -303,6 +303,8 @@ static int __init m8xx_ide_init_ports(hw_regs_t *hw, unsigned long data_port) | |||
303 | pcmp->pcmc_per = 0x100000 >> (16 * _slot_); | 303 | pcmp->pcmc_per = 0x100000 >> (16 * _slot_); |
304 | #endif /* CONFIG_IDE_8xx_PCCARD */ | 304 | #endif /* CONFIG_IDE_8xx_PCCARD */ |
305 | 305 | ||
306 | hw->chipset = ide_generic; | ||
307 | |||
306 | return 0; | 308 | return 0; |
307 | } | 309 | } |
308 | #endif /* CONFIG_IDE_8xx_PCCARD || CONFIG_IDE_8xx_DIRECT */ | 310 | #endif /* CONFIG_IDE_8xx_PCCARD || CONFIG_IDE_8xx_DIRECT */ |
@@ -377,6 +379,8 @@ static int __init m8xx_ide_init_ports(hw_regs_t *hw, unsigned long data_port) | |||
377 | ((immap_t *) IMAP_ADDR)->im_siu_conf.sc_siel |= | 379 | ((immap_t *) IMAP_ADDR)->im_siu_conf.sc_siel |= |
378 | (0x80000000 >> ioport_dsc[data_port].irq); | 380 | (0x80000000 >> ioport_dsc[data_port].irq); |
379 | 381 | ||
382 | hw->chipset = ide_generic; | ||
383 | |||
380 | return 0; | 384 | return 0; |
381 | } | 385 | } |
382 | #endif /* CONFIG_IDE_8xx_DIRECT */ | 386 | #endif /* CONFIG_IDE_8xx_DIRECT */ |
diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c index 48aa019127bc..ba2d58727964 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/ppc/pmac.c | |||
@@ -59,7 +59,6 @@ typedef struct pmac_ide_hwif { | |||
59 | int irq; | 59 | int irq; |
60 | int kind; | 60 | int kind; |
61 | int aapl_bus_id; | 61 | int aapl_bus_id; |
62 | unsigned cable_80 : 1; | ||
63 | unsigned mediabay : 1; | 62 | unsigned mediabay : 1; |
64 | unsigned broken_dma : 1; | 63 | unsigned broken_dma : 1; |
65 | unsigned broken_dma_warn : 1; | 64 | unsigned broken_dma_warn : 1; |
@@ -918,10 +917,40 @@ pmac_ide_do_resume(ide_hwif_t *hwif) | |||
918 | return 0; | 917 | return 0; |
919 | } | 918 | } |
920 | 919 | ||
920 | static u8 pmac_ide_cable_detect(ide_hwif_t *hwif) | ||
921 | { | ||
922 | pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)ide_get_hwifdata(hwif); | ||
923 | struct device_node *np = pmif->node; | ||
924 | const char *cable = of_get_property(np, "cable-type", NULL); | ||
925 | |||
926 | /* Get cable type from device-tree. */ | ||
927 | if (cable && !strncmp(cable, "80-", 3)) | ||
928 | return ATA_CBL_PATA80; | ||
929 | |||
930 | /* | ||
931 | * G5's seem to have incorrect cable type in device-tree. | ||
932 | * Let's assume they have a 80 conductor cable, this seem | ||
933 | * to be always the case unless the user mucked around. | ||
934 | */ | ||
935 | if (of_device_is_compatible(np, "K2-UATA") || | ||
936 | of_device_is_compatible(np, "shasta-ata")) | ||
937 | return ATA_CBL_PATA80; | ||
938 | |||
939 | return ATA_CBL_PATA40; | ||
940 | } | ||
941 | |||
921 | static const struct ide_port_ops pmac_ide_ata6_port_ops = { | 942 | static const struct ide_port_ops pmac_ide_ata6_port_ops = { |
922 | .set_pio_mode = pmac_ide_set_pio_mode, | 943 | .set_pio_mode = pmac_ide_set_pio_mode, |
923 | .set_dma_mode = pmac_ide_set_dma_mode, | 944 | .set_dma_mode = pmac_ide_set_dma_mode, |
924 | .selectproc = pmac_ide_kauai_selectproc, | 945 | .selectproc = pmac_ide_kauai_selectproc, |
946 | .cable_detect = pmac_ide_cable_detect, | ||
947 | }; | ||
948 | |||
949 | static const struct ide_port_ops pmac_ide_ata4_port_ops = { | ||
950 | .set_pio_mode = pmac_ide_set_pio_mode, | ||
951 | .set_dma_mode = pmac_ide_set_dma_mode, | ||
952 | .selectproc = pmac_ide_selectproc, | ||
953 | .cable_detect = pmac_ide_cable_detect, | ||
925 | }; | 954 | }; |
926 | 955 | ||
927 | static const struct ide_port_ops pmac_ide_port_ops = { | 956 | static const struct ide_port_ops pmac_ide_port_ops = { |
@@ -949,10 +978,7 @@ static const struct ide_port_info pmac_port_info = { | |||
949 | 978 | ||
950 | /* | 979 | /* |
951 | * Setup, register & probe an IDE channel driven by this driver, this is | 980 | * Setup, register & probe an IDE channel driven by this driver, this is |
952 | * called by one of the 2 probe functions (macio or PCI). Note that a channel | 981 | * called by one of the 2 probe functions (macio or PCI). |
953 | * that ends up beeing free of any device is not kept around by this driver | ||
954 | * (it is kept in 2.4). This introduce an interface numbering change on some | ||
955 | * rare machines unfortunately, but it's better this way. | ||
956 | */ | 982 | */ |
957 | static int __devinit | 983 | static int __devinit |
958 | pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif, hw_regs_t *hw) | 984 | pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif, hw_regs_t *hw) |
@@ -962,7 +988,6 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif, hw_regs_t *hw) | |||
962 | u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; | 988 | u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; |
963 | struct ide_port_info d = pmac_port_info; | 989 | struct ide_port_info d = pmac_port_info; |
964 | 990 | ||
965 | pmif->cable_80 = 0; | ||
966 | pmif->broken_dma = pmif->broken_dma_warn = 0; | 991 | pmif->broken_dma = pmif->broken_dma_warn = 0; |
967 | if (of_device_is_compatible(np, "shasta-ata")) { | 992 | if (of_device_is_compatible(np, "shasta-ata")) { |
968 | pmif->kind = controller_sh_ata6; | 993 | pmif->kind = controller_sh_ata6; |
@@ -979,6 +1004,7 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif, hw_regs_t *hw) | |||
979 | } else if (of_device_is_compatible(np, "keylargo-ata")) { | 1004 | } else if (of_device_is_compatible(np, "keylargo-ata")) { |
980 | if (strcmp(np->name, "ata-4") == 0) { | 1005 | if (strcmp(np->name, "ata-4") == 0) { |
981 | pmif->kind = controller_kl_ata4; | 1006 | pmif->kind = controller_kl_ata4; |
1007 | d.port_ops = &pmac_ide_ata4_port_ops; | ||
982 | d.udma_mask = ATA_UDMA4; | 1008 | d.udma_mask = ATA_UDMA4; |
983 | } else | 1009 | } else |
984 | pmif->kind = controller_kl_ata3; | 1010 | pmif->kind = controller_kl_ata3; |
@@ -992,22 +1018,6 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif, hw_regs_t *hw) | |||
992 | bidp = of_get_property(np, "AAPL,bus-id", NULL); | 1018 | bidp = of_get_property(np, "AAPL,bus-id", NULL); |
993 | pmif->aapl_bus_id = bidp ? *bidp : 0; | 1019 | pmif->aapl_bus_id = bidp ? *bidp : 0; |
994 | 1020 | ||
995 | /* Get cable type from device-tree */ | ||
996 | if (pmif->kind == controller_kl_ata4 || pmif->kind == controller_un_ata6 | ||
997 | || pmif->kind == controller_k2_ata6 | ||
998 | || pmif->kind == controller_sh_ata6) { | ||
999 | const char* cable = of_get_property(np, "cable-type", NULL); | ||
1000 | if (cable && !strncmp(cable, "80-", 3)) | ||
1001 | pmif->cable_80 = 1; | ||
1002 | } | ||
1003 | /* G5's seem to have incorrect cable type in device-tree. Let's assume | ||
1004 | * they have a 80 conductor cable, this seem to be always the case unless | ||
1005 | * the user mucked around | ||
1006 | */ | ||
1007 | if (of_device_is_compatible(np, "K2-UATA") || | ||
1008 | of_device_is_compatible(np, "shasta-ata")) | ||
1009 | pmif->cable_80 = 1; | ||
1010 | |||
1011 | /* On Kauai-type controllers, we make sure the FCR is correct */ | 1021 | /* On Kauai-type controllers, we make sure the FCR is correct */ |
1012 | if (pmif->kauai_fcr) | 1022 | if (pmif->kauai_fcr) |
1013 | writel(KAUAI_FCR_UATA_MAGIC | | 1023 | writel(KAUAI_FCR_UATA_MAGIC | |
@@ -1053,7 +1063,6 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif, hw_regs_t *hw) | |||
1053 | 1063 | ||
1054 | hwif->hwif_data = pmif; | 1064 | hwif->hwif_data = pmif; |
1055 | ide_init_port_hw(hwif, hw); | 1065 | ide_init_port_hw(hwif, hw); |
1056 | hwif->cbl = pmif->cable_80 ? ATA_CBL_PATA80 : ATA_CBL_PATA40; | ||
1057 | 1066 | ||
1058 | printk(KERN_INFO "ide%d: Found Apple %s controller, bus ID %d%s, irq %d\n", | 1067 | printk(KERN_INFO "ide%d: Found Apple %s controller, bus ID %d%s, irq %d\n", |
1059 | hwif->index, model_name[pmif->kind], pmif->aapl_bus_id, | 1068 | hwif->index, model_name[pmif->kind], pmif->aapl_bus_id, |
@@ -1070,11 +1079,6 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif, hw_regs_t *hw) | |||
1070 | } | 1079 | } |
1071 | } | 1080 | } |
1072 | 1081 | ||
1073 | #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC | ||
1074 | if (pmif->cable_80 == 0) | ||
1075 | d.udma_mask &= ATA_UDMA2; | ||
1076 | #endif | ||
1077 | |||
1078 | idx[0] = hwif->index; | 1082 | idx[0] = hwif->index; |
1079 | 1083 | ||
1080 | ide_device_add(idx, &d); | 1084 | ide_device_add(idx, &d); |
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c index 16b9d0ad154e..a5ceff287a28 100644 --- a/drivers/ieee1394/sbp2.c +++ b/drivers/ieee1394/sbp2.c | |||
@@ -1539,15 +1539,13 @@ static void sbp2_prep_command_orb_sg(struct sbp2_command_orb *orb, | |||
1539 | 1539 | ||
1540 | static void sbp2_create_command_orb(struct sbp2_lu *lu, | 1540 | static void sbp2_create_command_orb(struct sbp2_lu *lu, |
1541 | struct sbp2_command_info *cmd, | 1541 | struct sbp2_command_info *cmd, |
1542 | unchar *scsi_cmd, | 1542 | struct scsi_cmnd *SCpnt) |
1543 | unsigned int scsi_use_sg, | ||
1544 | unsigned int scsi_request_bufflen, | ||
1545 | struct scatterlist *sg, | ||
1546 | enum dma_data_direction dma_dir) | ||
1547 | { | 1543 | { |
1548 | struct sbp2_fwhost_info *hi = lu->hi; | 1544 | struct sbp2_fwhost_info *hi = lu->hi; |
1549 | struct sbp2_command_orb *orb = &cmd->command_orb; | 1545 | struct sbp2_command_orb *orb = &cmd->command_orb; |
1550 | u32 orb_direction; | 1546 | u32 orb_direction; |
1547 | unsigned int scsi_request_bufflen = scsi_bufflen(SCpnt); | ||
1548 | enum dma_data_direction dma_dir = SCpnt->sc_data_direction; | ||
1551 | 1549 | ||
1552 | /* | 1550 | /* |
1553 | * Set-up our command ORB. | 1551 | * Set-up our command ORB. |
@@ -1580,13 +1578,14 @@ static void sbp2_create_command_orb(struct sbp2_lu *lu, | |||
1580 | orb->data_descriptor_lo = 0x0; | 1578 | orb->data_descriptor_lo = 0x0; |
1581 | orb->misc |= ORB_SET_DIRECTION(1); | 1579 | orb->misc |= ORB_SET_DIRECTION(1); |
1582 | } else | 1580 | } else |
1583 | sbp2_prep_command_orb_sg(orb, hi, cmd, scsi_use_sg, sg, | 1581 | sbp2_prep_command_orb_sg(orb, hi, cmd, scsi_sg_count(SCpnt), |
1582 | scsi_sglist(SCpnt), | ||
1584 | orb_direction, dma_dir); | 1583 | orb_direction, dma_dir); |
1585 | 1584 | ||
1586 | sbp2util_cpu_to_be32_buffer(orb, sizeof(*orb)); | 1585 | sbp2util_cpu_to_be32_buffer(orb, sizeof(*orb)); |
1587 | 1586 | ||
1588 | memset(orb->cdb, 0, 12); | 1587 | memset(orb->cdb, 0, sizeof(orb->cdb)); |
1589 | memcpy(orb->cdb, scsi_cmd, COMMAND_SIZE(*scsi_cmd)); | 1588 | memcpy(orb->cdb, SCpnt->cmnd, SCpnt->cmd_len); |
1590 | } | 1589 | } |
1591 | 1590 | ||
1592 | static void sbp2_link_orb_command(struct sbp2_lu *lu, | 1591 | static void sbp2_link_orb_command(struct sbp2_lu *lu, |
@@ -1669,16 +1668,13 @@ static void sbp2_link_orb_command(struct sbp2_lu *lu, | |||
1669 | static int sbp2_send_command(struct sbp2_lu *lu, struct scsi_cmnd *SCpnt, | 1668 | static int sbp2_send_command(struct sbp2_lu *lu, struct scsi_cmnd *SCpnt, |
1670 | void (*done)(struct scsi_cmnd *)) | 1669 | void (*done)(struct scsi_cmnd *)) |
1671 | { | 1670 | { |
1672 | unchar *scsi_cmd = (unchar *)SCpnt->cmnd; | ||
1673 | struct sbp2_command_info *cmd; | 1671 | struct sbp2_command_info *cmd; |
1674 | 1672 | ||
1675 | cmd = sbp2util_allocate_command_orb(lu, SCpnt, done); | 1673 | cmd = sbp2util_allocate_command_orb(lu, SCpnt, done); |
1676 | if (!cmd) | 1674 | if (!cmd) |
1677 | return -EIO; | 1675 | return -EIO; |
1678 | 1676 | ||
1679 | sbp2_create_command_orb(lu, cmd, scsi_cmd, scsi_sg_count(SCpnt), | 1677 | sbp2_create_command_orb(lu, cmd, SCpnt); |
1680 | scsi_bufflen(SCpnt), scsi_sglist(SCpnt), | ||
1681 | SCpnt->sc_data_direction); | ||
1682 | sbp2_link_orb_command(lu, cmd); | 1678 | sbp2_link_orb_command(lu, cmd); |
1683 | 1679 | ||
1684 | return 0; | 1680 | return 0; |
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c index fbe16d5250a4..1adf2efd3cb3 100644 --- a/drivers/infiniband/core/mad.c +++ b/drivers/infiniband/core/mad.c | |||
@@ -747,7 +747,9 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv, | |||
747 | break; | 747 | break; |
748 | case IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_CONSUMED: | 748 | case IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_CONSUMED: |
749 | kmem_cache_free(ib_mad_cache, mad_priv); | 749 | kmem_cache_free(ib_mad_cache, mad_priv); |
750 | break; | 750 | kfree(local); |
751 | ret = 1; | ||
752 | goto out; | ||
751 | case IB_MAD_RESULT_SUCCESS: | 753 | case IB_MAD_RESULT_SUCCESS: |
752 | /* Treat like an incoming receive MAD */ | 754 | /* Treat like an incoming receive MAD */ |
753 | port_priv = ib_get_mad_port(mad_agent_priv->agent.device, | 755 | port_priv = ib_get_mad_port(mad_agent_priv->agent.device, |
diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c index fe78f7d25099..a1768dbb0720 100644 --- a/drivers/infiniband/core/umem.c +++ b/drivers/infiniband/core/umem.c | |||
@@ -150,7 +150,7 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr, | |||
150 | ret = 0; | 150 | ret = 0; |
151 | while (npages) { | 151 | while (npages) { |
152 | ret = get_user_pages(current, current->mm, cur_base, | 152 | ret = get_user_pages(current, current->mm, cur_base, |
153 | min_t(int, npages, | 153 | min_t(unsigned long, npages, |
154 | PAGE_SIZE / sizeof (struct page *)), | 154 | PAGE_SIZE / sizeof (struct page *)), |
155 | 1, !umem->writable, page_list, vma_list); | 155 | 1, !umem->writable, page_list, vma_list); |
156 | 156 | ||
diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c index 3aa2db54eae4..840ede9ae965 100644 --- a/drivers/infiniband/core/user_mad.c +++ b/drivers/infiniband/core/user_mad.c | |||
@@ -1005,8 +1005,9 @@ static int ib_umad_init_port(struct ib_device *device, int port_num, | |||
1005 | if (cdev_add(port->cdev, base_dev + port->dev_num, 1)) | 1005 | if (cdev_add(port->cdev, base_dev + port->dev_num, 1)) |
1006 | goto err_cdev; | 1006 | goto err_cdev; |
1007 | 1007 | ||
1008 | port->dev = device_create(umad_class, device->dma_device, | 1008 | port->dev = device_create_drvdata(umad_class, device->dma_device, |
1009 | port->cdev->dev, "umad%d", port->dev_num); | 1009 | port->cdev->dev, port, |
1010 | "umad%d", port->dev_num); | ||
1010 | if (IS_ERR(port->dev)) | 1011 | if (IS_ERR(port->dev)) |
1011 | goto err_cdev; | 1012 | goto err_cdev; |
1012 | 1013 | ||
@@ -1024,15 +1025,12 @@ static int ib_umad_init_port(struct ib_device *device, int port_num, | |||
1024 | if (cdev_add(port->sm_cdev, base_dev + port->dev_num + IB_UMAD_MAX_PORTS, 1)) | 1025 | if (cdev_add(port->sm_cdev, base_dev + port->dev_num + IB_UMAD_MAX_PORTS, 1)) |
1025 | goto err_sm_cdev; | 1026 | goto err_sm_cdev; |
1026 | 1027 | ||
1027 | port->sm_dev = device_create(umad_class, device->dma_device, | 1028 | port->sm_dev = device_create_drvdata(umad_class, device->dma_device, |
1028 | port->sm_cdev->dev, | 1029 | port->sm_cdev->dev, port, |
1029 | "issm%d", port->dev_num); | 1030 | "issm%d", port->dev_num); |
1030 | if (IS_ERR(port->sm_dev)) | 1031 | if (IS_ERR(port->sm_dev)) |
1031 | goto err_sm_cdev; | 1032 | goto err_sm_cdev; |
1032 | 1033 | ||
1033 | dev_set_drvdata(port->dev, port); | ||
1034 | dev_set_drvdata(port->sm_dev, port); | ||
1035 | |||
1036 | if (device_create_file(port->sm_dev, &dev_attr_ibdev)) | 1034 | if (device_create_file(port->sm_dev, &dev_attr_ibdev)) |
1037 | goto err_sm_dev; | 1035 | goto err_sm_dev; |
1038 | if (device_create_file(port->sm_dev, &dev_attr_port)) | 1036 | if (device_create_file(port->sm_dev, &dev_attr_port)) |
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index cc1afa28c181..f806da184b51 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c | |||
@@ -755,14 +755,15 @@ static void ib_uverbs_add_one(struct ib_device *device) | |||
755 | if (cdev_add(uverbs_dev->cdev, IB_UVERBS_BASE_DEV + uverbs_dev->devnum, 1)) | 755 | if (cdev_add(uverbs_dev->cdev, IB_UVERBS_BASE_DEV + uverbs_dev->devnum, 1)) |
756 | goto err_cdev; | 756 | goto err_cdev; |
757 | 757 | ||
758 | uverbs_dev->dev = device_create(uverbs_class, device->dma_device, | 758 | uverbs_dev->dev = device_create_drvdata(uverbs_class, |
759 | uverbs_dev->cdev->dev, | 759 | device->dma_device, |
760 | "uverbs%d", uverbs_dev->devnum); | 760 | uverbs_dev->cdev->dev, |
761 | uverbs_dev, | ||
762 | "uverbs%d", | ||
763 | uverbs_dev->devnum); | ||
761 | if (IS_ERR(uverbs_dev->dev)) | 764 | if (IS_ERR(uverbs_dev->dev)) |
762 | goto err_cdev; | 765 | goto err_cdev; |
763 | 766 | ||
764 | dev_set_drvdata(uverbs_dev->dev, uverbs_dev); | ||
765 | |||
766 | if (device_create_file(uverbs_dev->dev, &dev_attr_ibdev)) | 767 | if (device_create_file(uverbs_dev->dev, &dev_attr_ibdev)) |
767 | goto err_class; | 768 | goto err_class; |
768 | if (device_create_file(uverbs_dev->dev, &dev_attr_abi_version)) | 769 | if (device_create_file(uverbs_dev->dev, &dev_attr_abi_version)) |
diff --git a/drivers/infiniband/hw/amso1100/c2_rnic.c b/drivers/infiniband/hw/amso1100/c2_rnic.c index 9a054c6941a4..b1441aeb60c2 100644 --- a/drivers/infiniband/hw/amso1100/c2_rnic.c +++ b/drivers/infiniband/hw/amso1100/c2_rnic.c | |||
@@ -455,8 +455,7 @@ int __devinit c2_rnic_init(struct c2_dev *c2dev) | |||
455 | IB_DEVICE_CURR_QP_STATE_MOD | | 455 | IB_DEVICE_CURR_QP_STATE_MOD | |
456 | IB_DEVICE_SYS_IMAGE_GUID | | 456 | IB_DEVICE_SYS_IMAGE_GUID | |
457 | IB_DEVICE_ZERO_STAG | | 457 | IB_DEVICE_ZERO_STAG | |
458 | IB_DEVICE_MEM_WINDOW | | 458 | IB_DEVICE_MEM_WINDOW); |
459 | IB_DEVICE_SEND_W_INV); | ||
460 | 459 | ||
461 | /* Allocate the qptr_array */ | 460 | /* Allocate the qptr_array */ |
462 | c2dev->qptr_array = vmalloc(C2_MAX_CQS * sizeof(void *)); | 461 | c2dev->qptr_array = vmalloc(C2_MAX_CQS * sizeof(void *)); |
diff --git a/drivers/infiniband/hw/cxgb3/iwch_qp.c b/drivers/infiniband/hw/cxgb3/iwch_qp.c index 79dbe5beae52..992613799228 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_qp.c +++ b/drivers/infiniband/hw/cxgb3/iwch_qp.c | |||
@@ -229,7 +229,7 @@ int iwch_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, | |||
229 | struct ib_send_wr **bad_wr) | 229 | struct ib_send_wr **bad_wr) |
230 | { | 230 | { |
231 | int err = 0; | 231 | int err = 0; |
232 | u8 t3_wr_flit_cnt; | 232 | u8 uninitialized_var(t3_wr_flit_cnt); |
233 | enum t3_wr_opcode t3_wr_opcode = 0; | 233 | enum t3_wr_opcode t3_wr_opcode = 0; |
234 | enum t3_wr_flags t3_wr_flags; | 234 | enum t3_wr_flags t3_wr_flags; |
235 | struct iwch_qp *qhp; | 235 | struct iwch_qp *qhp; |
diff --git a/drivers/infiniband/hw/ehca/ehca_reqs.c b/drivers/infiniband/hw/ehca/ehca_reqs.c index bbe0436f4f75..f093b0033daf 100644 --- a/drivers/infiniband/hw/ehca/ehca_reqs.c +++ b/drivers/infiniband/hw/ehca/ehca_reqs.c | |||
@@ -421,8 +421,10 @@ int ehca_post_send(struct ib_qp *qp, | |||
421 | int ret = 0; | 421 | int ret = 0; |
422 | unsigned long flags; | 422 | unsigned long flags; |
423 | 423 | ||
424 | if (unlikely(my_qp->state != IB_QPS_RTS)) { | 424 | /* Reject WR if QP is in RESET, INIT or RTR state */ |
425 | ehca_err(qp->device, "QP not in RTS state qpn=%x", qp->qp_num); | 425 | if (unlikely(my_qp->state < IB_QPS_RTS)) { |
426 | ehca_err(qp->device, "Invalid QP state qp_state=%d qpn=%x", | ||
427 | my_qp->state, qp->qp_num); | ||
426 | return -EINVAL; | 428 | return -EINVAL; |
427 | } | 429 | } |
428 | 430 | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_kernel.h b/drivers/infiniband/hw/ipath/ipath_kernel.h index 59a8b254b97f..0bd8bcb184a1 100644 --- a/drivers/infiniband/hw/ipath/ipath_kernel.h +++ b/drivers/infiniband/hw/ipath/ipath_kernel.h | |||
@@ -232,6 +232,11 @@ struct ipath_sdma_desc { | |||
232 | #define IPATH_SDMA_TXREQ_S_ABORTED 2 | 232 | #define IPATH_SDMA_TXREQ_S_ABORTED 2 |
233 | #define IPATH_SDMA_TXREQ_S_SHUTDOWN 3 | 233 | #define IPATH_SDMA_TXREQ_S_SHUTDOWN 3 |
234 | 234 | ||
235 | #define IPATH_SDMA_STATUS_SCORE_BOARD_DRAIN_IN_PROG (1ull << 63) | ||
236 | #define IPATH_SDMA_STATUS_ABORT_IN_PROG (1ull << 62) | ||
237 | #define IPATH_SDMA_STATUS_INTERNAL_SDMA_ENABLE (1ull << 61) | ||
238 | #define IPATH_SDMA_STATUS_SCB_EMPTY (1ull << 30) | ||
239 | |||
235 | /* max dwords in small buffer packet */ | 240 | /* max dwords in small buffer packet */ |
236 | #define IPATH_SMALLBUF_DWORDS (dd->ipath_piosize2k >> 2) | 241 | #define IPATH_SMALLBUF_DWORDS (dd->ipath_piosize2k >> 2) |
237 | 242 | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_mad.c b/drivers/infiniband/hw/ipath/ipath_mad.c index 1ff46ae7dd99..5f9315d77a43 100644 --- a/drivers/infiniband/hw/ipath/ipath_mad.c +++ b/drivers/infiniband/hw/ipath/ipath_mad.c | |||
@@ -1492,6 +1492,10 @@ static int process_subn(struct ib_device *ibdev, int mad_flags, | |||
1492 | goto bail; | 1492 | goto bail; |
1493 | } | 1493 | } |
1494 | 1494 | ||
1495 | case IB_MGMT_METHOD_TRAP: | ||
1496 | case IB_MGMT_METHOD_REPORT: | ||
1497 | case IB_MGMT_METHOD_REPORT_RESP: | ||
1498 | case IB_MGMT_METHOD_TRAP_REPRESS: | ||
1495 | case IB_MGMT_METHOD_GET_RESP: | 1499 | case IB_MGMT_METHOD_GET_RESP: |
1496 | /* | 1500 | /* |
1497 | * The ib_mad module will call us to process responses | 1501 | * The ib_mad module will call us to process responses |
diff --git a/drivers/infiniband/hw/ipath/ipath_sdma.c b/drivers/infiniband/hw/ipath/ipath_sdma.c index 3697449c1ba4..eaba03273e4f 100644 --- a/drivers/infiniband/hw/ipath/ipath_sdma.c +++ b/drivers/infiniband/hw/ipath/ipath_sdma.c | |||
@@ -263,14 +263,10 @@ static void sdma_abort_task(unsigned long opaque) | |||
263 | hwstatus = ipath_read_kreg64(dd, | 263 | hwstatus = ipath_read_kreg64(dd, |
264 | dd->ipath_kregs->kr_senddmastatus); | 264 | dd->ipath_kregs->kr_senddmastatus); |
265 | 265 | ||
266 | if (/* ScoreBoardDrainInProg */ | 266 | if ((hwstatus & (IPATH_SDMA_STATUS_SCORE_BOARD_DRAIN_IN_PROG | |
267 | test_bit(63, &hwstatus) || | 267 | IPATH_SDMA_STATUS_ABORT_IN_PROG | |
268 | /* AbortInProg */ | 268 | IPATH_SDMA_STATUS_INTERNAL_SDMA_ENABLE)) || |
269 | test_bit(62, &hwstatus) || | 269 | !(hwstatus & IPATH_SDMA_STATUS_SCB_EMPTY)) { |
270 | /* InternalSDmaEnable */ | ||
271 | test_bit(61, &hwstatus) || | ||
272 | /* ScbEmpty */ | ||
273 | !test_bit(30, &hwstatus)) { | ||
274 | if (dd->ipath_sdma_reset_wait > 0) { | 270 | if (dd->ipath_sdma_reset_wait > 0) { |
275 | /* not done shutting down sdma */ | 271 | /* not done shutting down sdma */ |
276 | --dd->ipath_sdma_reset_wait; | 272 | --dd->ipath_sdma_reset_wait; |
@@ -345,7 +341,7 @@ resched: | |||
345 | * state change | 341 | * state change |
346 | */ | 342 | */ |
347 | if (jiffies > dd->ipath_sdma_abort_jiffies) { | 343 | if (jiffies > dd->ipath_sdma_abort_jiffies) { |
348 | ipath_dbg("looping with status 0x%016llx\n", | 344 | ipath_dbg("looping with status 0x%08lx\n", |
349 | dd->ipath_sdma_status); | 345 | dd->ipath_sdma_status); |
350 | dd->ipath_sdma_abort_jiffies = jiffies + 5 * HZ; | 346 | dd->ipath_sdma_abort_jiffies = jiffies + 5 * HZ; |
351 | } | 347 | } |
@@ -615,7 +611,7 @@ void ipath_restart_sdma(struct ipath_devdata *dd) | |||
615 | } | 611 | } |
616 | spin_unlock_irqrestore(&dd->ipath_sdma_lock, flags); | 612 | spin_unlock_irqrestore(&dd->ipath_sdma_lock, flags); |
617 | if (!needed) { | 613 | if (!needed) { |
618 | ipath_dbg("invalid attempt to restart SDMA, status 0x%016llx\n", | 614 | ipath_dbg("invalid attempt to restart SDMA, status 0x%08lx\n", |
619 | dd->ipath_sdma_status); | 615 | dd->ipath_sdma_status); |
620 | goto bail; | 616 | goto bail; |
621 | } | 617 | } |
diff --git a/drivers/infiniband/hw/ipath/ipath_uc.c b/drivers/infiniband/hw/ipath/ipath_uc.c index 7fd18e833907..0596ec16fcbd 100644 --- a/drivers/infiniband/hw/ipath/ipath_uc.c +++ b/drivers/infiniband/hw/ipath/ipath_uc.c | |||
@@ -407,12 +407,11 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, | |||
407 | dev->n_pkt_drops++; | 407 | dev->n_pkt_drops++; |
408 | goto done; | 408 | goto done; |
409 | } | 409 | } |
410 | /* XXX Need to free SGEs */ | 410 | wc.opcode = IB_WC_RECV; |
411 | last_imm: | 411 | last_imm: |
412 | ipath_copy_sge(&qp->r_sge, data, tlen); | 412 | ipath_copy_sge(&qp->r_sge, data, tlen); |
413 | wc.wr_id = qp->r_wr_id; | 413 | wc.wr_id = qp->r_wr_id; |
414 | wc.status = IB_WC_SUCCESS; | 414 | wc.status = IB_WC_SUCCESS; |
415 | wc.opcode = IB_WC_RECV; | ||
416 | wc.qp = &qp->ibqp; | 415 | wc.qp = &qp->ibqp; |
417 | wc.src_qp = qp->remote_qpn; | 416 | wc.src_qp = qp->remote_qpn; |
418 | wc.slid = qp->remote_ah_attr.dlid; | 417 | wc.slid = qp->remote_ah_attr.dlid; |
@@ -514,6 +513,7 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, | |||
514 | goto done; | 513 | goto done; |
515 | } | 514 | } |
516 | wc.byte_len = qp->r_len; | 515 | wc.byte_len = qp->r_len; |
516 | wc.opcode = IB_WC_RECV_RDMA_WITH_IMM; | ||
517 | goto last_imm; | 517 | goto last_imm; |
518 | 518 | ||
519 | case OP(RDMA_WRITE_LAST): | 519 | case OP(RDMA_WRITE_LAST): |
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.c b/drivers/infiniband/hw/ipath/ipath_verbs.c index 5d830d87ebca..38c44dec51ca 100644 --- a/drivers/infiniband/hw/ipath/ipath_verbs.c +++ b/drivers/infiniband/hw/ipath/ipath_verbs.c | |||
@@ -1495,7 +1495,8 @@ static int ipath_query_device(struct ib_device *ibdev, | |||
1495 | 1495 | ||
1496 | props->device_cap_flags = IB_DEVICE_BAD_PKEY_CNTR | | 1496 | props->device_cap_flags = IB_DEVICE_BAD_PKEY_CNTR | |
1497 | IB_DEVICE_BAD_QKEY_CNTR | IB_DEVICE_SHUTDOWN_PORT | | 1497 | IB_DEVICE_BAD_QKEY_CNTR | IB_DEVICE_SHUTDOWN_PORT | |
1498 | IB_DEVICE_SYS_IMAGE_GUID; | 1498 | IB_DEVICE_SYS_IMAGE_GUID | IB_DEVICE_RC_RNR_NAK_GEN | |
1499 | IB_DEVICE_PORT_ACTIVE_EVENT | IB_DEVICE_SRQ_RESIZE; | ||
1499 | props->page_size_cap = PAGE_SIZE; | 1500 | props->page_size_cap = PAGE_SIZE; |
1500 | props->vendor_id = dev->dd->ipath_vendorid; | 1501 | props->vendor_id = dev->dd->ipath_vendorid; |
1501 | props->vendor_part_id = dev->dd->ipath_deviceid; | 1502 | props->vendor_part_id = dev->dd->ipath_deviceid; |
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index 8e02ecfec188..a80df22deae8 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c | |||
@@ -333,6 +333,9 @@ static int set_kernel_sq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap, | |||
333 | cap->max_inline_data + sizeof (struct mlx4_wqe_inline_seg)) + | 333 | cap->max_inline_data + sizeof (struct mlx4_wqe_inline_seg)) + |
334 | send_wqe_overhead(type, qp->flags); | 334 | send_wqe_overhead(type, qp->flags); |
335 | 335 | ||
336 | if (s > dev->dev->caps.max_sq_desc_sz) | ||
337 | return -EINVAL; | ||
338 | |||
336 | /* | 339 | /* |
337 | * Hermon supports shrinking WQEs, such that a single work | 340 | * Hermon supports shrinking WQEs, such that a single work |
338 | * request can include multiple units of 1 << wqe_shift. This | 341 | * request can include multiple units of 1 << wqe_shift. This |
@@ -372,9 +375,6 @@ static int set_kernel_sq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap, | |||
372 | qp->sq.wqe_shift = ilog2(roundup_pow_of_two(s)); | 375 | qp->sq.wqe_shift = ilog2(roundup_pow_of_two(s)); |
373 | 376 | ||
374 | for (;;) { | 377 | for (;;) { |
375 | if (1 << qp->sq.wqe_shift > dev->dev->caps.max_sq_desc_sz) | ||
376 | return -EINVAL; | ||
377 | |||
378 | qp->sq_max_wqes_per_wr = DIV_ROUND_UP(s, 1U << qp->sq.wqe_shift); | 378 | qp->sq_max_wqes_per_wr = DIV_ROUND_UP(s, 1U << qp->sq.wqe_shift); |
379 | 379 | ||
380 | /* | 380 | /* |
@@ -395,7 +395,8 @@ static int set_kernel_sq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap, | |||
395 | ++qp->sq.wqe_shift; | 395 | ++qp->sq.wqe_shift; |
396 | } | 396 | } |
397 | 397 | ||
398 | qp->sq.max_gs = ((qp->sq_max_wqes_per_wr << qp->sq.wqe_shift) - | 398 | qp->sq.max_gs = (min(dev->dev->caps.max_sq_desc_sz, |
399 | (qp->sq_max_wqes_per_wr << qp->sq.wqe_shift)) - | ||
399 | send_wqe_overhead(type, qp->flags)) / | 400 | send_wqe_overhead(type, qp->flags)) / |
400 | sizeof (struct mlx4_wqe_data_seg); | 401 | sizeof (struct mlx4_wqe_data_seg); |
401 | 402 | ||
@@ -411,7 +412,9 @@ static int set_kernel_sq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap, | |||
411 | 412 | ||
412 | cap->max_send_wr = qp->sq.max_post = | 413 | cap->max_send_wr = qp->sq.max_post = |
413 | (qp->sq.wqe_cnt - qp->sq_spare_wqes) / qp->sq_max_wqes_per_wr; | 414 | (qp->sq.wqe_cnt - qp->sq_spare_wqes) / qp->sq_max_wqes_per_wr; |
414 | cap->max_send_sge = qp->sq.max_gs; | 415 | cap->max_send_sge = min(qp->sq.max_gs, |
416 | min(dev->dev->caps.max_sq_sg, | ||
417 | dev->dev->caps.max_rq_sg)); | ||
415 | /* We don't support inline sends for kernel QPs (yet) */ | 418 | /* We don't support inline sends for kernel QPs (yet) */ |
416 | cap->max_inline_data = 0; | 419 | cap->max_inline_data = 0; |
417 | 420 | ||
@@ -1457,7 +1460,7 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, | |||
1457 | unsigned ind; | 1460 | unsigned ind; |
1458 | int uninitialized_var(stamp); | 1461 | int uninitialized_var(stamp); |
1459 | int uninitialized_var(size); | 1462 | int uninitialized_var(size); |
1460 | unsigned seglen; | 1463 | unsigned uninitialized_var(seglen); |
1461 | int i; | 1464 | int i; |
1462 | 1465 | ||
1463 | spin_lock_irqsave(&qp->sq.lock, flags); | 1466 | spin_lock_irqsave(&qp->sq.lock, flags); |
diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c index 9ebadd6e0cfb..200cf13fc9bb 100644 --- a/drivers/infiniband/hw/mthca/mthca_main.c +++ b/drivers/infiniband/hw/mthca/mthca_main.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include "mthca_cmd.h" | 45 | #include "mthca_cmd.h" |
46 | #include "mthca_profile.h" | 46 | #include "mthca_profile.h" |
47 | #include "mthca_memfree.h" | 47 | #include "mthca_memfree.h" |
48 | #include "mthca_wqe.h" | ||
48 | 49 | ||
49 | MODULE_AUTHOR("Roland Dreier"); | 50 | MODULE_AUTHOR("Roland Dreier"); |
50 | MODULE_DESCRIPTION("Mellanox InfiniBand HCA low-level driver"); | 51 | MODULE_DESCRIPTION("Mellanox InfiniBand HCA low-level driver"); |
@@ -200,7 +201,18 @@ static int mthca_dev_lim(struct mthca_dev *mdev, struct mthca_dev_lim *dev_lim) | |||
200 | mdev->limits.gid_table_len = dev_lim->max_gids; | 201 | mdev->limits.gid_table_len = dev_lim->max_gids; |
201 | mdev->limits.pkey_table_len = dev_lim->max_pkeys; | 202 | mdev->limits.pkey_table_len = dev_lim->max_pkeys; |
202 | mdev->limits.local_ca_ack_delay = dev_lim->local_ca_ack_delay; | 203 | mdev->limits.local_ca_ack_delay = dev_lim->local_ca_ack_delay; |
203 | mdev->limits.max_sg = dev_lim->max_sg; | 204 | /* |
205 | * Need to allow for worst case send WQE overhead and check | ||
206 | * whether max_desc_sz imposes a lower limit than max_sg; UD | ||
207 | * send has the biggest overhead. | ||
208 | */ | ||
209 | mdev->limits.max_sg = min_t(int, dev_lim->max_sg, | ||
210 | (dev_lim->max_desc_sz - | ||
211 | sizeof (struct mthca_next_seg) - | ||
212 | (mthca_is_memfree(mdev) ? | ||
213 | sizeof (struct mthca_arbel_ud_seg) : | ||
214 | sizeof (struct mthca_tavor_ud_seg))) / | ||
215 | sizeof (struct mthca_data_seg)); | ||
204 | mdev->limits.max_wqes = dev_lim->max_qp_sz; | 216 | mdev->limits.max_wqes = dev_lim->max_qp_sz; |
205 | mdev->limits.max_qp_init_rdma = dev_lim->max_requester_per_qp; | 217 | mdev->limits.max_qp_init_rdma = dev_lim->max_requester_per_qp; |
206 | mdev->limits.reserved_qps = dev_lim->reserved_qps; | 218 | mdev->limits.reserved_qps = dev_lim->reserved_qps; |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index d00a2c174aee..3f663fb852c1 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c | |||
@@ -194,7 +194,13 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast, | |||
194 | /* Set the cached Q_Key before we attach if it's the broadcast group */ | 194 | /* Set the cached Q_Key before we attach if it's the broadcast group */ |
195 | if (!memcmp(mcast->mcmember.mgid.raw, priv->dev->broadcast + 4, | 195 | if (!memcmp(mcast->mcmember.mgid.raw, priv->dev->broadcast + 4, |
196 | sizeof (union ib_gid))) { | 196 | sizeof (union ib_gid))) { |
197 | spin_lock_irq(&priv->lock); | ||
198 | if (!priv->broadcast) { | ||
199 | spin_unlock_irq(&priv->lock); | ||
200 | return -EAGAIN; | ||
201 | } | ||
197 | priv->qkey = be32_to_cpu(priv->broadcast->mcmember.qkey); | 202 | priv->qkey = be32_to_cpu(priv->broadcast->mcmember.qkey); |
203 | spin_unlock_irq(&priv->lock); | ||
198 | priv->tx_wr.wr.ud.remote_qkey = priv->qkey; | 204 | priv->tx_wr.wr.ud.remote_qkey = priv->qkey; |
199 | } | 205 | } |
200 | 206 | ||
diff --git a/drivers/input/keyboard/aaed2000_kbd.c b/drivers/input/keyboard/aaed2000_kbd.c index a293e8b3f508..8a77bfcd05bc 100644 --- a/drivers/input/keyboard/aaed2000_kbd.c +++ b/drivers/input/keyboard/aaed2000_kbd.c | |||
@@ -183,4 +183,4 @@ module_exit(aaedkbd_exit); | |||
183 | 183 | ||
184 | MODULE_AUTHOR("Nicolas Bellido Y Ortega"); | 184 | MODULE_AUTHOR("Nicolas Bellido Y Ortega"); |
185 | MODULE_DESCRIPTION("AAED-2000 Keyboard Driver"); | 185 | MODULE_DESCRIPTION("AAED-2000 Keyboard Driver"); |
186 | MODULE_LICENSE("GPLv2"); | 186 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index 4a95adc4cc78..af58a6f1e898 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c | |||
@@ -807,6 +807,8 @@ static int atkbd_activate(struct atkbd *atkbd) | |||
807 | static void atkbd_cleanup(struct serio *serio) | 807 | static void atkbd_cleanup(struct serio *serio) |
808 | { | 808 | { |
809 | struct atkbd *atkbd = serio_get_drvdata(serio); | 809 | struct atkbd *atkbd = serio_get_drvdata(serio); |
810 | |||
811 | atkbd_disable(atkbd); | ||
810 | ps2_command(&atkbd->ps2dev, NULL, ATKBD_CMD_RESET_BAT); | 812 | ps2_command(&atkbd->ps2dev, NULL, ATKBD_CMD_RESET_BAT); |
811 | } | 813 | } |
812 | 814 | ||
diff --git a/drivers/input/keyboard/corgikbd.c b/drivers/input/keyboard/corgikbd.c index 29fbec6218b9..1aa46ae12630 100644 --- a/drivers/input/keyboard/corgikbd.c +++ b/drivers/input/keyboard/corgikbd.c | |||
@@ -412,5 +412,5 @@ module_exit(corgikbd_exit); | |||
412 | 412 | ||
413 | MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>"); | 413 | MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>"); |
414 | MODULE_DESCRIPTION("Corgi Keyboard Driver"); | 414 | MODULE_DESCRIPTION("Corgi Keyboard Driver"); |
415 | MODULE_LICENSE("GPLv2"); | 415 | MODULE_LICENSE("GPL v2"); |
416 | MODULE_ALIAS("platform:corgi-keyboard"); | 416 | MODULE_ALIAS("platform:corgi-keyboard"); |
diff --git a/drivers/input/keyboard/jornada680_kbd.c b/drivers/input/keyboard/jornada680_kbd.c index 9387da343f97..781fc6102860 100644 --- a/drivers/input/keyboard/jornada680_kbd.c +++ b/drivers/input/keyboard/jornada680_kbd.c | |||
@@ -275,5 +275,5 @@ module_exit(jornada680kbd_exit); | |||
275 | 275 | ||
276 | MODULE_AUTHOR("Kristoffer Ericson <kristoffer.ericson@gmail.com>"); | 276 | MODULE_AUTHOR("Kristoffer Ericson <kristoffer.ericson@gmail.com>"); |
277 | MODULE_DESCRIPTION("HP Jornada 620/660/680/690 Keyboard Driver"); | 277 | MODULE_DESCRIPTION("HP Jornada 620/660/680/690 Keyboard Driver"); |
278 | MODULE_LICENSE("GPLv2"); | 278 | MODULE_LICENSE("GPL v2"); |
279 | MODULE_ALIAS("platform:jornada680_kbd"); | 279 | MODULE_ALIAS("platform:jornada680_kbd"); |
diff --git a/drivers/input/keyboard/jornada720_kbd.c b/drivers/input/keyboard/jornada720_kbd.c index a1164a0c7736..ce650af6d649 100644 --- a/drivers/input/keyboard/jornada720_kbd.c +++ b/drivers/input/keyboard/jornada720_kbd.c | |||
@@ -29,7 +29,7 @@ | |||
29 | 29 | ||
30 | MODULE_AUTHOR("Kristoffer Ericson <Kristoffer.Ericson@gmail.com>"); | 30 | MODULE_AUTHOR("Kristoffer Ericson <Kristoffer.Ericson@gmail.com>"); |
31 | MODULE_DESCRIPTION("HP Jornada 710/720/728 keyboard driver"); | 31 | MODULE_DESCRIPTION("HP Jornada 710/720/728 keyboard driver"); |
32 | MODULE_LICENSE("GPLv2"); | 32 | MODULE_LICENSE("GPL v2"); |
33 | 33 | ||
34 | static unsigned short jornada_std_keymap[128] = { /* ROW */ | 34 | static unsigned short jornada_std_keymap[128] = { /* ROW */ |
35 | 0, KEY_ESC, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6, KEY_F7, /* #1 */ | 35 | 0, KEY_ESC, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6, KEY_F7, /* #1 */ |
diff --git a/drivers/input/keyboard/pxa27x_keypad.c b/drivers/input/keyboard/pxa27x_keypad.c index 3dea0c5077a9..45767e73f071 100644 --- a/drivers/input/keyboard/pxa27x_keypad.c +++ b/drivers/input/keyboard/pxa27x_keypad.c | |||
@@ -136,6 +136,9 @@ static void pxa27x_keypad_build_keycode(struct pxa27x_keypad *keypad) | |||
136 | set_bit(code, input_dev->keybit); | 136 | set_bit(code, input_dev->keybit); |
137 | } | 137 | } |
138 | 138 | ||
139 | for (i = 0; i < pdata->direct_key_num; i++) | ||
140 | set_bit(pdata->direct_key_map[i], input_dev->keybit); | ||
141 | |||
139 | keypad->rotary_up_key[0] = pdata->rotary0_up_key; | 142 | keypad->rotary_up_key[0] = pdata->rotary0_up_key; |
140 | keypad->rotary_up_key[1] = pdata->rotary1_up_key; | 143 | keypad->rotary_up_key[1] = pdata->rotary1_up_key; |
141 | keypad->rotary_down_key[0] = pdata->rotary0_down_key; | 144 | keypad->rotary_down_key[0] = pdata->rotary0_down_key; |
@@ -143,17 +146,21 @@ static void pxa27x_keypad_build_keycode(struct pxa27x_keypad *keypad) | |||
143 | keypad->rotary_rel_code[0] = pdata->rotary0_rel_code; | 146 | keypad->rotary_rel_code[0] = pdata->rotary0_rel_code; |
144 | keypad->rotary_rel_code[1] = pdata->rotary1_rel_code; | 147 | keypad->rotary_rel_code[1] = pdata->rotary1_rel_code; |
145 | 148 | ||
146 | if (pdata->rotary0_up_key && pdata->rotary0_down_key) { | 149 | if (pdata->enable_rotary0) { |
147 | set_bit(pdata->rotary0_up_key, input_dev->keybit); | 150 | if (pdata->rotary0_up_key && pdata->rotary0_down_key) { |
148 | set_bit(pdata->rotary0_down_key, input_dev->keybit); | 151 | set_bit(pdata->rotary0_up_key, input_dev->keybit); |
149 | } else | 152 | set_bit(pdata->rotary0_down_key, input_dev->keybit); |
150 | set_bit(pdata->rotary0_rel_code, input_dev->relbit); | 153 | } else |
151 | 154 | set_bit(pdata->rotary0_rel_code, input_dev->relbit); | |
152 | if (pdata->rotary1_up_key && pdata->rotary1_down_key) { | 155 | } |
153 | set_bit(pdata->rotary1_up_key, input_dev->keybit); | 156 | |
154 | set_bit(pdata->rotary1_down_key, input_dev->keybit); | 157 | if (pdata->enable_rotary1) { |
155 | } else | 158 | if (pdata->rotary1_up_key && pdata->rotary1_down_key) { |
156 | set_bit(pdata->rotary1_rel_code, input_dev->relbit); | 159 | set_bit(pdata->rotary1_up_key, input_dev->keybit); |
160 | set_bit(pdata->rotary1_down_key, input_dev->keybit); | ||
161 | } else | ||
162 | set_bit(pdata->rotary1_rel_code, input_dev->relbit); | ||
163 | } | ||
157 | } | 164 | } |
158 | 165 | ||
159 | static inline unsigned int lookup_matrix_keycode( | 166 | static inline unsigned int lookup_matrix_keycode( |
@@ -484,8 +491,13 @@ static int __devinit pxa27x_keypad_probe(struct platform_device *pdev) | |||
484 | keypad->input_dev = input_dev; | 491 | keypad->input_dev = input_dev; |
485 | input_set_drvdata(input_dev, keypad); | 492 | input_set_drvdata(input_dev, keypad); |
486 | 493 | ||
487 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) | | 494 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); |
488 | BIT_MASK(EV_REL); | 495 | if ((keypad->pdata->enable_rotary0 && |
496 | keypad->pdata->rotary0_rel_code) || | ||
497 | (keypad->pdata->enable_rotary1 && | ||
498 | keypad->pdata->rotary1_rel_code)) { | ||
499 | input_dev->evbit[0] |= BIT_MASK(EV_REL); | ||
500 | } | ||
489 | 501 | ||
490 | pxa27x_keypad_build_keycode(keypad); | 502 | pxa27x_keypad_build_keycode(keypad); |
491 | platform_set_drvdata(pdev, keypad); | 503 | platform_set_drvdata(pdev, keypad); |
diff --git a/drivers/input/keyboard/spitzkbd.c b/drivers/input/keyboard/spitzkbd.c index 61e401bc9109..1aa37181c40f 100644 --- a/drivers/input/keyboard/spitzkbd.c +++ b/drivers/input/keyboard/spitzkbd.c | |||
@@ -494,5 +494,5 @@ module_exit(spitzkbd_exit); | |||
494 | 494 | ||
495 | MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>"); | 495 | MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>"); |
496 | MODULE_DESCRIPTION("Spitz Keyboard Driver"); | 496 | MODULE_DESCRIPTION("Spitz Keyboard Driver"); |
497 | MODULE_LICENSE("GPLv2"); | 497 | MODULE_LICENSE("GPL v2"); |
498 | MODULE_ALIAS("platform:spitz-keyboard"); | 498 | MODULE_ALIAS("platform:spitz-keyboard"); |
diff --git a/drivers/input/misc/apanel.c b/drivers/input/misc/apanel.c index 9531d8c7444f..d82f7f727f7a 100644 --- a/drivers/input/misc/apanel.c +++ b/drivers/input/misc/apanel.c | |||
@@ -20,7 +20,6 @@ | |||
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/ioport.h> | 21 | #include <linux/ioport.h> |
22 | #include <linux/io.h> | 22 | #include <linux/io.h> |
23 | #include <linux/module.h> | ||
24 | #include <linux/input-polldev.h> | 23 | #include <linux/input-polldev.h> |
25 | #include <linux/i2c.h> | 24 | #include <linux/i2c.h> |
26 | #include <linux/workqueue.h> | 25 | #include <linux/workqueue.h> |
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 5ece9f56babc..9aafa96cb746 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h | |||
@@ -331,6 +331,13 @@ static struct dmi_system_id __initdata i8042_dmi_dritek_table[] = { | |||
331 | }, | 331 | }, |
332 | }, | 332 | }, |
333 | { | 333 | { |
334 | .ident = "Acer TravelMate 660", | ||
335 | .matches = { | ||
336 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
337 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 660"), | ||
338 | }, | ||
339 | }, | ||
340 | { | ||
334 | .ident = "Acer TravelMate 2490", | 341 | .ident = "Acer TravelMate 2490", |
335 | .matches = { | 342 | .matches = { |
336 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 343 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index 65a74cfc187b..592ff55b62d0 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c | |||
@@ -885,6 +885,20 @@ static long i8042_panic_blink(long count) | |||
885 | 885 | ||
886 | #undef DELAY | 886 | #undef DELAY |
887 | 887 | ||
888 | #ifdef CONFIG_X86 | ||
889 | static void i8042_dritek_enable(void) | ||
890 | { | ||
891 | char param = 0x90; | ||
892 | int error; | ||
893 | |||
894 | error = i8042_command(¶m, 0x1059); | ||
895 | if (error) | ||
896 | printk(KERN_WARNING | ||
897 | "Failed to enable DRITEK extension: %d\n", | ||
898 | error); | ||
899 | } | ||
900 | #endif | ||
901 | |||
888 | #ifdef CONFIG_PM | 902 | #ifdef CONFIG_PM |
889 | /* | 903 | /* |
890 | * Here we try to restore the original BIOS settings. We only want to | 904 | * Here we try to restore the original BIOS settings. We only want to |
@@ -942,6 +956,12 @@ static int i8042_resume(struct platform_device *dev) | |||
942 | return -EIO; | 956 | return -EIO; |
943 | } | 957 | } |
944 | 958 | ||
959 | |||
960 | #ifdef CONFIG_X86 | ||
961 | if (i8042_dritek) | ||
962 | i8042_dritek_enable(); | ||
963 | #endif | ||
964 | |||
945 | if (i8042_mux_present) { | 965 | if (i8042_mux_present) { |
946 | if (i8042_set_mux_mode(1, NULL) || i8042_enable_mux_ports()) | 966 | if (i8042_set_mux_mode(1, NULL) || i8042_enable_mux_ports()) |
947 | printk(KERN_WARNING | 967 | printk(KERN_WARNING |
@@ -1160,6 +1180,11 @@ static int __devinit i8042_probe(struct platform_device *dev) | |||
1160 | if (error) | 1180 | if (error) |
1161 | return error; | 1181 | return error; |
1162 | 1182 | ||
1183 | #ifdef CONFIG_X86 | ||
1184 | if (i8042_dritek) | ||
1185 | i8042_dritek_enable(); | ||
1186 | #endif | ||
1187 | |||
1163 | if (!i8042_noaux) { | 1188 | if (!i8042_noaux) { |
1164 | error = i8042_setup_aux(); | 1189 | error = i8042_setup_aux(); |
1165 | if (error && error != -ENODEV && error != -EBUSY) | 1190 | if (error && error != -ENODEV && error != -EBUSY) |
@@ -1171,14 +1196,6 @@ static int __devinit i8042_probe(struct platform_device *dev) | |||
1171 | if (error) | 1196 | if (error) |
1172 | goto out_fail; | 1197 | goto out_fail; |
1173 | } | 1198 | } |
1174 | #ifdef CONFIG_X86 | ||
1175 | if (i8042_dritek) { | ||
1176 | char param = 0x90; | ||
1177 | error = i8042_command(¶m, 0x1059); | ||
1178 | if (error) | ||
1179 | goto out_fail; | ||
1180 | } | ||
1181 | #endif | ||
1182 | /* | 1199 | /* |
1183 | * Ok, everything is ready, let's register all serio ports | 1200 | * Ok, everything is ready, let's register all serio ports |
1184 | */ | 1201 | */ |
diff --git a/drivers/input/tablet/gtco.c b/drivers/input/tablet/gtco.c index c5a8661a1baa..1e748e46d12e 100644 --- a/drivers/input/tablet/gtco.c +++ b/drivers/input/tablet/gtco.c | |||
@@ -830,7 +830,7 @@ static int gtco_probe(struct usb_interface *usbinterface, | |||
830 | struct gtco *gtco; | 830 | struct gtco *gtco; |
831 | struct input_dev *input_dev; | 831 | struct input_dev *input_dev; |
832 | struct hid_descriptor *hid_desc; | 832 | struct hid_descriptor *hid_desc; |
833 | char *report = NULL; | 833 | char *report; |
834 | int result = 0, retry; | 834 | int result = 0, retry; |
835 | int error; | 835 | int error; |
836 | struct usb_endpoint_descriptor *endpoint; | 836 | struct usb_endpoint_descriptor *endpoint; |
@@ -916,12 +916,16 @@ static int gtco_probe(struct usb_interface *usbinterface, | |||
916 | le16_to_cpu(hid_desc->wDescriptorLength), | 916 | le16_to_cpu(hid_desc->wDescriptorLength), |
917 | 5000); /* 5 secs */ | 917 | 5000); /* 5 secs */ |
918 | 918 | ||
919 | if (result == le16_to_cpu(hid_desc->wDescriptorLength)) | 919 | dbg("usb_control_msg result: %d", result); |
920 | if (result == le16_to_cpu(hid_desc->wDescriptorLength)) { | ||
921 | parse_hid_report_descriptor(gtco, report, result); | ||
920 | break; | 922 | break; |
923 | } | ||
921 | } | 924 | } |
922 | 925 | ||
926 | kfree(report); | ||
927 | |||
923 | /* If we didn't get the report, fail */ | 928 | /* If we didn't get the report, fail */ |
924 | dbg("usb_control_msg result: :%d", result); | ||
925 | if (result != le16_to_cpu(hid_desc->wDescriptorLength)) { | 929 | if (result != le16_to_cpu(hid_desc->wDescriptorLength)) { |
926 | err("Failed to get HID Report Descriptor of size: %d", | 930 | err("Failed to get HID Report Descriptor of size: %d", |
927 | hid_desc->wDescriptorLength); | 931 | hid_desc->wDescriptorLength); |
@@ -929,12 +933,6 @@ static int gtco_probe(struct usb_interface *usbinterface, | |||
929 | goto err_free_urb; | 933 | goto err_free_urb; |
930 | } | 934 | } |
931 | 935 | ||
932 | /* Now we parse the report */ | ||
933 | parse_hid_report_descriptor(gtco, report, result); | ||
934 | |||
935 | /* Now we delete it */ | ||
936 | kfree(report); | ||
937 | |||
938 | /* Create a device file node */ | 936 | /* Create a device file node */ |
939 | usb_make_path(gtco->usbdev, gtco->usbpath, sizeof(gtco->usbpath)); | 937 | usb_make_path(gtco->usbdev, gtco->usbpath, sizeof(gtco->usbpath)); |
940 | strlcat(gtco->usbpath, "/input0", sizeof(gtco->usbpath)); | 938 | strlcat(gtco->usbpath, "/input0", sizeof(gtco->usbpath)); |
@@ -988,7 +986,6 @@ static int gtco_probe(struct usb_interface *usbinterface, | |||
988 | usb_buffer_free(gtco->usbdev, REPORT_MAX_SIZE, | 986 | usb_buffer_free(gtco->usbdev, REPORT_MAX_SIZE, |
989 | gtco->buffer, gtco->buf_dma); | 987 | gtco->buffer, gtco->buf_dma); |
990 | err_free_devs: | 988 | err_free_devs: |
991 | kfree(report); | ||
992 | input_free_device(input_dev); | 989 | input_free_device(input_dev); |
993 | kfree(gtco); | 990 | kfree(gtco); |
994 | return error; | 991 | return error; |
diff --git a/drivers/input/touchscreen/jornada720_ts.c b/drivers/input/touchscreen/jornada720_ts.c index 742242111bf1..1aca108b1031 100644 --- a/drivers/input/touchscreen/jornada720_ts.c +++ b/drivers/input/touchscreen/jornada720_ts.c | |||
@@ -24,7 +24,7 @@ | |||
24 | 24 | ||
25 | MODULE_AUTHOR("Kristoffer Ericson <kristoffer.ericson@gmail.com>"); | 25 | MODULE_AUTHOR("Kristoffer Ericson <kristoffer.ericson@gmail.com>"); |
26 | MODULE_DESCRIPTION("HP Jornada 710/720/728 touchscreen driver"); | 26 | MODULE_DESCRIPTION("HP Jornada 710/720/728 touchscreen driver"); |
27 | MODULE_LICENSE("GPLv2"); | 27 | MODULE_LICENSE("GPL v2"); |
28 | 28 | ||
29 | struct jornada_ts { | 29 | struct jornada_ts { |
30 | struct input_dev *dev; | 30 | struct input_dev *dev; |
diff --git a/drivers/input/touchscreen/wm9713.c b/drivers/input/touchscreen/wm9713.c index 01278bd7e65c..838458792ea0 100644 --- a/drivers/input/touchscreen/wm9713.c +++ b/drivers/input/touchscreen/wm9713.c | |||
@@ -85,6 +85,15 @@ module_param(delay, int, 0); | |||
85 | MODULE_PARM_DESC(delay, "Set adc sample delay."); | 85 | MODULE_PARM_DESC(delay, "Set adc sample delay."); |
86 | 86 | ||
87 | /* | 87 | /* |
88 | * Set five_wire = 1 to use a 5 wire touchscreen. | ||
89 | * | ||
90 | * NOTE: Five wire mode does not allow for readback of pressure. | ||
91 | */ | ||
92 | static int five_wire; | ||
93 | module_param(five_wire, int, 0); | ||
94 | MODULE_PARM_DESC(five_wire, "Set to '1' to use 5-wire touchscreen."); | ||
95 | |||
96 | /* | ||
88 | * Set adc mask function. | 97 | * Set adc mask function. |
89 | * | 98 | * |
90 | * Sources of glitch noise, such as signals driving an LCD display, may feed | 99 | * Sources of glitch noise, such as signals driving an LCD display, may feed |
@@ -162,6 +171,19 @@ static void wm9713_phy_init(struct wm97xx *wm) | |||
162 | 64000 / rpu); | 171 | 64000 / rpu); |
163 | } | 172 | } |
164 | 173 | ||
174 | /* Five wire panel? */ | ||
175 | if (five_wire) { | ||
176 | dig3 |= WM9713_45W; | ||
177 | dev_info(wm->dev, "setting 5-wire touchscreen mode."); | ||
178 | |||
179 | if (pil) { | ||
180 | dev_warn(wm->dev, | ||
181 | "Pressure measurement not supported in 5 " | ||
182 | "wire mode, disabling\n"); | ||
183 | pil = 0; | ||
184 | } | ||
185 | } | ||
186 | |||
165 | /* touchpanel pressure */ | 187 | /* touchpanel pressure */ |
166 | if (pil == 2) { | 188 | if (pil == 2) { |
167 | dig3 |= WM9712_PIL; | 189 | dig3 |= WM9712_PIL; |
diff --git a/drivers/input/touchscreen/wm97xx-core.c b/drivers/input/touchscreen/wm97xx-core.c index e9c7ea46b6e3..cdc24ad314e0 100644 --- a/drivers/input/touchscreen/wm97xx-core.c +++ b/drivers/input/touchscreen/wm97xx-core.c | |||
@@ -608,6 +608,17 @@ static int wm97xx_probe(struct device *dev) | |||
608 | goto alloc_err; | 608 | goto alloc_err; |
609 | } | 609 | } |
610 | 610 | ||
611 | /* set up physical characteristics */ | ||
612 | wm->codec->phy_init(wm); | ||
613 | |||
614 | /* load gpio cache */ | ||
615 | wm->gpio[0] = wm97xx_reg_read(wm, AC97_GPIO_CFG); | ||
616 | wm->gpio[1] = wm97xx_reg_read(wm, AC97_GPIO_POLARITY); | ||
617 | wm->gpio[2] = wm97xx_reg_read(wm, AC97_GPIO_STICKY); | ||
618 | wm->gpio[3] = wm97xx_reg_read(wm, AC97_GPIO_WAKEUP); | ||
619 | wm->gpio[4] = wm97xx_reg_read(wm, AC97_GPIO_STATUS); | ||
620 | wm->gpio[5] = wm97xx_reg_read(wm, AC97_MISC_AFE); | ||
621 | |||
611 | wm->input_dev = input_allocate_device(); | 622 | wm->input_dev = input_allocate_device(); |
612 | if (wm->input_dev == NULL) { | 623 | if (wm->input_dev == NULL) { |
613 | ret = -ENOMEM; | 624 | ret = -ENOMEM; |
@@ -616,6 +627,7 @@ static int wm97xx_probe(struct device *dev) | |||
616 | 627 | ||
617 | /* set up touch configuration */ | 628 | /* set up touch configuration */ |
618 | wm->input_dev->name = "wm97xx touchscreen"; | 629 | wm->input_dev->name = "wm97xx touchscreen"; |
630 | wm->input_dev->phys = "wm97xx"; | ||
619 | wm->input_dev->open = wm97xx_ts_input_open; | 631 | wm->input_dev->open = wm97xx_ts_input_open; |
620 | wm->input_dev->close = wm97xx_ts_input_close; | 632 | wm->input_dev->close = wm97xx_ts_input_close; |
621 | set_bit(EV_ABS, wm->input_dev->evbit); | 633 | set_bit(EV_ABS, wm->input_dev->evbit); |
@@ -634,17 +646,6 @@ static int wm97xx_probe(struct device *dev) | |||
634 | if (ret < 0) | 646 | if (ret < 0) |
635 | goto dev_alloc_err; | 647 | goto dev_alloc_err; |
636 | 648 | ||
637 | /* set up physical characteristics */ | ||
638 | wm->codec->phy_init(wm); | ||
639 | |||
640 | /* load gpio cache */ | ||
641 | wm->gpio[0] = wm97xx_reg_read(wm, AC97_GPIO_CFG); | ||
642 | wm->gpio[1] = wm97xx_reg_read(wm, AC97_GPIO_POLARITY); | ||
643 | wm->gpio[2] = wm97xx_reg_read(wm, AC97_GPIO_STICKY); | ||
644 | wm->gpio[3] = wm97xx_reg_read(wm, AC97_GPIO_WAKEUP); | ||
645 | wm->gpio[4] = wm97xx_reg_read(wm, AC97_GPIO_STATUS); | ||
646 | wm->gpio[5] = wm97xx_reg_read(wm, AC97_MISC_AFE); | ||
647 | |||
648 | /* register our battery device */ | 649 | /* register our battery device */ |
649 | wm->battery_dev = platform_device_alloc("wm97xx-battery", -1); | 650 | wm->battery_dev = platform_device_alloc("wm97xx-battery", -1); |
650 | if (!wm->battery_dev) { | 651 | if (!wm->battery_dev) { |
@@ -801,7 +802,7 @@ void wm97xx_unregister_mach_ops(struct wm97xx *wm) | |||
801 | EXPORT_SYMBOL_GPL(wm97xx_unregister_mach_ops); | 802 | EXPORT_SYMBOL_GPL(wm97xx_unregister_mach_ops); |
802 | 803 | ||
803 | static struct device_driver wm97xx_driver = { | 804 | static struct device_driver wm97xx_driver = { |
804 | .name = "ac97", | 805 | .name = "wm97xx-ts", |
805 | .bus = &ac97_bus_type, | 806 | .bus = &ac97_bus_type, |
806 | .owner = THIS_MODULE, | 807 | .owner = THIS_MODULE, |
807 | .probe = wm97xx_probe, | 808 | .probe = wm97xx_probe, |
diff --git a/drivers/isdn/capi/capiutil.c b/drivers/isdn/capi/capiutil.c index ebef4ce1b00c..29419a8d31dc 100644 --- a/drivers/isdn/capi/capiutil.c +++ b/drivers/isdn/capi/capiutil.c | |||
@@ -948,17 +948,17 @@ int __init cdebug_init(void) | |||
948 | { | 948 | { |
949 | g_cmsg= kmalloc(sizeof(_cmsg), GFP_KERNEL); | 949 | g_cmsg= kmalloc(sizeof(_cmsg), GFP_KERNEL); |
950 | if (!g_cmsg) | 950 | if (!g_cmsg) |
951 | return ENOMEM; | 951 | return -ENOMEM; |
952 | g_debbuf = kmalloc(sizeof(_cdebbuf), GFP_KERNEL); | 952 | g_debbuf = kmalloc(sizeof(_cdebbuf), GFP_KERNEL); |
953 | if (!g_debbuf) { | 953 | if (!g_debbuf) { |
954 | kfree(g_cmsg); | 954 | kfree(g_cmsg); |
955 | return ENOMEM; | 955 | return -ENOMEM; |
956 | } | 956 | } |
957 | g_debbuf->buf = kmalloc(CDEBUG_GSIZE, GFP_KERNEL); | 957 | g_debbuf->buf = kmalloc(CDEBUG_GSIZE, GFP_KERNEL); |
958 | if (!g_debbuf->buf) { | 958 | if (!g_debbuf->buf) { |
959 | kfree(g_cmsg); | 959 | kfree(g_cmsg); |
960 | kfree(g_debbuf); | 960 | kfree(g_debbuf); |
961 | return ENOMEM;; | 961 | return -ENOMEM;; |
962 | } | 962 | } |
963 | g_debbuf->size = CDEBUG_GSIZE; | 963 | g_debbuf->size = CDEBUG_GSIZE; |
964 | g_debbuf->buf[0] = 0; | 964 | g_debbuf->buf[0] = 0; |
diff --git a/drivers/isdn/hardware/eicon/divasmain.c b/drivers/isdn/hardware/eicon/divasmain.c index 5fcbdccd7a53..16a874bb1561 100644 --- a/drivers/isdn/hardware/eicon/divasmain.c +++ b/drivers/isdn/hardware/eicon/divasmain.c | |||
@@ -806,7 +806,6 @@ static int DIVA_INIT_FUNCTION divas_init(void) | |||
806 | 806 | ||
807 | if (!create_divas_proc()) { | 807 | if (!create_divas_proc()) { |
808 | #ifdef MODULE | 808 | #ifdef MODULE |
809 | remove_divas_proc(); | ||
810 | divas_unregister_chrdev(); | 809 | divas_unregister_chrdev(); |
811 | divasfunc_exit(); | 810 | divasfunc_exit(); |
812 | #endif | 811 | #endif |
diff --git a/drivers/isdn/hardware/eicon/divasproc.c b/drivers/isdn/hardware/eicon/divasproc.c index fae895828a17..040827288ec9 100644 --- a/drivers/isdn/hardware/eicon/divasproc.c +++ b/drivers/isdn/hardware/eicon/divasproc.c | |||
@@ -125,8 +125,8 @@ static const struct file_operations divas_fops = { | |||
125 | 125 | ||
126 | int create_divas_proc(void) | 126 | int create_divas_proc(void) |
127 | { | 127 | { |
128 | proc_create(divas_proc_name, S_IFREG | S_IRUGO, proc_net_eicon, | 128 | divas_proc_entry = proc_create(divas_proc_name, S_IFREG | S_IRUGO, |
129 | &divas_fops); | 129 | proc_net_eicon, &divas_fops); |
130 | if (!divas_proc_entry) | 130 | if (!divas_proc_entry) |
131 | return (0); | 131 | return (0); |
132 | 132 | ||
diff --git a/drivers/isdn/hysdn/Kconfig b/drivers/isdn/hysdn/Kconfig index c6d8a7042988..c9e4231968ef 100644 --- a/drivers/isdn/hysdn/Kconfig +++ b/drivers/isdn/hysdn/Kconfig | |||
@@ -3,7 +3,7 @@ | |||
3 | # | 3 | # |
4 | config HYSDN | 4 | config HYSDN |
5 | tristate "Hypercope HYSDN cards (Champ, Ergo, Metro) support (module only)" | 5 | tristate "Hypercope HYSDN cards (Champ, Ergo, Metro) support (module only)" |
6 | depends on m && PROC_FS && PCI && BROKEN_ON_SMP | 6 | depends on m && PROC_FS && PCI |
7 | help | 7 | help |
8 | Say Y here if you have one of Hypercope's active PCI ISDN cards | 8 | Say Y here if you have one of Hypercope's active PCI ISDN cards |
9 | Champ, Ergo and Metro. You will then get a module called hysdn. | 9 | Champ, Ergo and Metro. You will then get a module called hysdn. |
diff --git a/drivers/isdn/hysdn/boardergo.c b/drivers/isdn/hysdn/boardergo.c index 6cdbad3a9926..3eb096f0ae1b 100644 --- a/drivers/isdn/hysdn/boardergo.c +++ b/drivers/isdn/hysdn/boardergo.c | |||
@@ -64,10 +64,11 @@ ergo_interrupt(int intno, void *dev_id) | |||
64 | } /* ergo_interrupt */ | 64 | } /* ergo_interrupt */ |
65 | 65 | ||
66 | /******************************************************************************/ | 66 | /******************************************************************************/ |
67 | /* ergo_irq_bh is the function called by the immediate kernel task list after */ | 67 | /* ergo_irq_bh will be called as part of the kernel clearing its shared work */ |
68 | /* being activated with queue_task and no interrupts active. This task is the */ | 68 | /* queue sometime after a call to schedule_work has been made passing our */ |
69 | /* only one handling data transfer from or to the card after booting. The task */ | 69 | /* work_struct. This task is the only one handling data transfer from or to */ |
70 | /* may be queued from everywhere (interrupts included). */ | 70 | /* the card after booting. The task may be queued from everywhere */ |
71 | /* (interrupts included). */ | ||
71 | /******************************************************************************/ | 72 | /******************************************************************************/ |
72 | static void | 73 | static void |
73 | ergo_irq_bh(struct work_struct *ugli_api) | 74 | ergo_irq_bh(struct work_struct *ugli_api) |
@@ -90,7 +91,6 @@ ergo_irq_bh(struct work_struct *ugli_api) | |||
90 | card->hw_lock = 1; /* we now lock the hardware */ | 91 | card->hw_lock = 1; /* we now lock the hardware */ |
91 | 92 | ||
92 | do { | 93 | do { |
93 | sti(); /* reenable other ints */ | ||
94 | again = 0; /* assume loop not to be repeated */ | 94 | again = 0; /* assume loop not to be repeated */ |
95 | 95 | ||
96 | if (!dpr->ToHyFlag) { | 96 | if (!dpr->ToHyFlag) { |
@@ -110,7 +110,6 @@ ergo_irq_bh(struct work_struct *ugli_api) | |||
110 | again = 1; /* restart loop */ | 110 | again = 1; /* restart loop */ |
111 | } | 111 | } |
112 | } /* a message has arrived for us */ | 112 | } /* a message has arrived for us */ |
113 | cli(); /* no further ints */ | ||
114 | if (again) { | 113 | if (again) { |
115 | dpr->ToHyInt = 1; | 114 | dpr->ToHyInt = 1; |
116 | dpr->ToPcInt = 1; /* interrupt to E1 for all cards */ | 115 | dpr->ToPcInt = 1; /* interrupt to E1 for all cards */ |
@@ -242,7 +241,6 @@ ergo_writebootimg(struct HYSDN_CARD *card, unsigned char *buf, | |||
242 | byteout(card->iobase + PCI9050_USER_IO, PCI9050_E1_RUN); /* start E1 processor */ | 241 | byteout(card->iobase + PCI9050_USER_IO, PCI9050_E1_RUN); /* start E1 processor */ |
243 | /* the interrupts are still masked */ | 242 | /* the interrupts are still masked */ |
244 | 243 | ||
245 | sti(); | ||
246 | msleep_interruptible(20); /* Timeout 20ms */ | 244 | msleep_interruptible(20); /* Timeout 20ms */ |
247 | 245 | ||
248 | if (((tDpramBootSpooler *) card->dpram)->Len != DPRAM_SPOOLER_DATA_SIZE) { | 246 | if (((tDpramBootSpooler *) card->dpram)->Len != DPRAM_SPOOLER_DATA_SIZE) { |
@@ -276,7 +274,6 @@ ergo_writebootseq(struct HYSDN_CARD *card, unsigned char *buf, int len) | |||
276 | dst = sp->Data; /* point to data in spool structure */ | 274 | dst = sp->Data; /* point to data in spool structure */ |
277 | buflen = sp->Len; /* maximum len of spooled data */ | 275 | buflen = sp->Len; /* maximum len of spooled data */ |
278 | wr_mirror = sp->WrPtr; /* only once read */ | 276 | wr_mirror = sp->WrPtr; /* only once read */ |
279 | sti(); | ||
280 | 277 | ||
281 | /* try until all bytes written or error */ | 278 | /* try until all bytes written or error */ |
282 | i = 0x1000; /* timeout value */ | 279 | i = 0x1000; /* timeout value */ |
@@ -380,7 +377,6 @@ ergo_waitpofready(struct HYSDN_CARD *card) | |||
380 | #endif /* CONFIG_HYSDN_CAPI */ | 377 | #endif /* CONFIG_HYSDN_CAPI */ |
381 | return (0); /* success */ | 378 | return (0); /* success */ |
382 | } /* data has arrived */ | 379 | } /* data has arrived */ |
383 | sti(); | ||
384 | msleep_interruptible(50); /* Timeout 50ms */ | 380 | msleep_interruptible(50); /* Timeout 50ms */ |
385 | } /* wait until timeout */ | 381 | } /* wait until timeout */ |
386 | 382 | ||
diff --git a/drivers/isdn/hysdn/hycapi.c b/drivers/isdn/hysdn/hycapi.c index d3999a8e9f88..53f6ad1235db 100644 --- a/drivers/isdn/hysdn/hycapi.c +++ b/drivers/isdn/hysdn/hycapi.c | |||
@@ -462,11 +462,11 @@ static int hycapi_read_proc(char *page, char **start, off_t off, | |||
462 | default: s = "???"; break; | 462 | default: s = "???"; break; |
463 | } | 463 | } |
464 | len += sprintf(page+len, "%-16s %s\n", "type", s); | 464 | len += sprintf(page+len, "%-16s %s\n", "type", s); |
465 | if ((s = cinfo->version[VER_DRIVER]) != 0) | 465 | if ((s = cinfo->version[VER_DRIVER]) != NULL) |
466 | len += sprintf(page+len, "%-16s %s\n", "ver_driver", s); | 466 | len += sprintf(page+len, "%-16s %s\n", "ver_driver", s); |
467 | if ((s = cinfo->version[VER_CARDTYPE]) != 0) | 467 | if ((s = cinfo->version[VER_CARDTYPE]) != NULL) |
468 | len += sprintf(page+len, "%-16s %s\n", "ver_cardtype", s); | 468 | len += sprintf(page+len, "%-16s %s\n", "ver_cardtype", s); |
469 | if ((s = cinfo->version[VER_SERIAL]) != 0) | 469 | if ((s = cinfo->version[VER_SERIAL]) != NULL) |
470 | len += sprintf(page+len, "%-16s %s\n", "ver_serial", s); | 470 | len += sprintf(page+len, "%-16s %s\n", "ver_serial", s); |
471 | 471 | ||
472 | len += sprintf(page+len, "%-16s %s\n", "cardname", cinfo->cardname); | 472 | len += sprintf(page+len, "%-16s %s\n", "cardname", cinfo->cardname); |
diff --git a/drivers/isdn/hysdn/hysdn_procconf.c b/drivers/isdn/hysdn/hysdn_procconf.c index 15906d005b05..484299b031f8 100644 --- a/drivers/isdn/hysdn/hysdn_procconf.c +++ b/drivers/isdn/hysdn/hysdn_procconf.c | |||
@@ -207,30 +207,17 @@ hysdn_conf_write(struct file *file, const char __user *buf, size_t count, loff_t | |||
207 | /* read conf file -> output card info data */ | 207 | /* read conf file -> output card info data */ |
208 | /*******************************************/ | 208 | /*******************************************/ |
209 | static ssize_t | 209 | static ssize_t |
210 | hysdn_conf_read(struct file *file, char __user *buf, size_t count, loff_t * off) | 210 | hysdn_conf_read(struct file *file, char __user *buf, size_t count, loff_t *off) |
211 | { | 211 | { |
212 | char *cp; | 212 | char *cp; |
213 | int i; | ||
214 | 213 | ||
215 | if (file->f_mode & FMODE_READ) { | 214 | if (!(file->f_mode & FMODE_READ)) |
216 | if (!(cp = file->private_data)) | 215 | return -EPERM; /* no permission to read */ |
217 | return (-EFAULT); /* should never happen */ | 216 | |
218 | i = strlen(cp); /* get total string length */ | 217 | if (!(cp = file->private_data)) |
219 | if (*off < i) { | 218 | return -EFAULT; /* should never happen */ |
220 | /* still bytes to transfer */ | 219 | |
221 | cp += *off; /* point to desired data offset */ | 220 | return simple_read_from_buffer(buf, count, off, cp, strlen(cp)); |
222 | i -= *off; /* remaining length */ | ||
223 | if (i > count) | ||
224 | i = count; /* limit length to transfer */ | ||
225 | if (copy_to_user(buf, cp, i)) | ||
226 | return (-EFAULT); /* copy error */ | ||
227 | *off += i; /* adjust offset */ | ||
228 | } else | ||
229 | return (0); | ||
230 | } else | ||
231 | return (-EPERM); /* no permission to read */ | ||
232 | |||
233 | return (i); | ||
234 | } /* hysdn_conf_read */ | 221 | } /* hysdn_conf_read */ |
235 | 222 | ||
236 | /******************/ | 223 | /******************/ |
diff --git a/drivers/isdn/sc/ioctl.c b/drivers/isdn/sc/ioctl.c index 7817d2244921..1081091bbfaf 100644 --- a/drivers/isdn/sc/ioctl.c +++ b/drivers/isdn/sc/ioctl.c | |||
@@ -226,6 +226,7 @@ int sc_ioctl(int card, scs_ioctl *data) | |||
226 | */ | 226 | */ |
227 | if (copy_from_user(spid, data->dataptr, SCIOC_SPIDSIZE)) { | 227 | if (copy_from_user(spid, data->dataptr, SCIOC_SPIDSIZE)) { |
228 | kfree(rcvmsg); | 228 | kfree(rcvmsg); |
229 | kfree(spid); | ||
229 | return -EFAULT; | 230 | return -EFAULT; |
230 | } | 231 | } |
231 | 232 | ||
diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index b3c54be74556..559a40861c39 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c | |||
@@ -103,13 +103,11 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) | |||
103 | { | 103 | { |
104 | int rc; | 104 | int rc; |
105 | 105 | ||
106 | led_cdev->dev = device_create(leds_class, parent, 0, "%s", | 106 | led_cdev->dev = device_create_drvdata(leds_class, parent, 0, led_cdev, |
107 | led_cdev->name); | 107 | "%s", led_cdev->name); |
108 | if (IS_ERR(led_cdev->dev)) | 108 | if (IS_ERR(led_cdev->dev)) |
109 | return PTR_ERR(led_cdev->dev); | 109 | return PTR_ERR(led_cdev->dev); |
110 | 110 | ||
111 | dev_set_drvdata(led_cdev->dev, led_cdev); | ||
112 | |||
113 | /* register the attributes */ | 111 | /* register the attributes */ |
114 | rc = device_create_file(led_cdev->dev, &dev_attr_brightness); | 112 | rc = device_create_file(led_cdev->dev, &dev_attr_brightness); |
115 | if (rc) | 113 | if (rc) |
diff --git a/drivers/lguest/lguest_device.c b/drivers/lguest/lguest_device.c index 8080249957af..1a8de57289eb 100644 --- a/drivers/lguest/lguest_device.c +++ b/drivers/lguest/lguest_device.c | |||
@@ -20,14 +20,11 @@ | |||
20 | /* The pointer to our (page) of device descriptions. */ | 20 | /* The pointer to our (page) of device descriptions. */ |
21 | static void *lguest_devices; | 21 | static void *lguest_devices; |
22 | 22 | ||
23 | /* Unique numbering for lguest devices. */ | ||
24 | static unsigned int dev_index; | ||
25 | |||
26 | /* For Guests, device memory can be used as normal memory, so we cast away the | 23 | /* For Guests, device memory can be used as normal memory, so we cast away the |
27 | * __iomem to quieten sparse. */ | 24 | * __iomem to quieten sparse. */ |
28 | static inline void *lguest_map(unsigned long phys_addr, unsigned long pages) | 25 | static inline void *lguest_map(unsigned long phys_addr, unsigned long pages) |
29 | { | 26 | { |
30 | return (__force void *)ioremap(phys_addr, PAGE_SIZE*pages); | 27 | return (__force void *)ioremap_cache(phys_addr, PAGE_SIZE*pages); |
31 | } | 28 | } |
32 | 29 | ||
33 | static inline void lguest_unmap(void *addr) | 30 | static inline void lguest_unmap(void *addr) |
@@ -325,8 +322,10 @@ static struct device lguest_root = { | |||
325 | * As Andrew Tridgell says, "Untested code is buggy code". | 322 | * As Andrew Tridgell says, "Untested code is buggy code". |
326 | * | 323 | * |
327 | * It's worth reading this carefully: we start with a pointer to the new device | 324 | * It's worth reading this carefully: we start with a pointer to the new device |
328 | * descriptor in the "lguest_devices" page. */ | 325 | * descriptor in the "lguest_devices" page, and the offset into the device |
329 | static void add_lguest_device(struct lguest_device_desc *d) | 326 | * descriptor page so we can uniquely identify it if things go badly wrong. */ |
327 | static void add_lguest_device(struct lguest_device_desc *d, | ||
328 | unsigned int offset) | ||
330 | { | 329 | { |
331 | struct lguest_device *ldev; | 330 | struct lguest_device *ldev; |
332 | 331 | ||
@@ -334,18 +333,14 @@ static void add_lguest_device(struct lguest_device_desc *d) | |||
334 | * it. */ | 333 | * it. */ |
335 | ldev = kzalloc(sizeof(*ldev), GFP_KERNEL); | 334 | ldev = kzalloc(sizeof(*ldev), GFP_KERNEL); |
336 | if (!ldev) { | 335 | if (!ldev) { |
337 | printk(KERN_EMERG "Cannot allocate lguest dev %u\n", | 336 | printk(KERN_EMERG "Cannot allocate lguest dev %u type %u\n", |
338 | dev_index++); | 337 | offset, d->type); |
339 | return; | 338 | return; |
340 | } | 339 | } |
341 | 340 | ||
342 | /* This devices' parent is the lguest/ dir. */ | 341 | /* This devices' parent is the lguest/ dir. */ |
343 | ldev->vdev.dev.parent = &lguest_root; | 342 | ldev->vdev.dev.parent = &lguest_root; |
344 | /* We have a unique device index thanks to the dev_index counter. */ | 343 | /* We have a unique device index thanks to the dev_index counter. */ |
345 | ldev->vdev.index = dev_index++; | ||
346 | /* The device type comes straight from the descriptor. There's also a | ||
347 | * device vendor field in the virtio_device struct, which we leave as | ||
348 | * 0. */ | ||
349 | ldev->vdev.id.device = d->type; | 344 | ldev->vdev.id.device = d->type; |
350 | /* We have a simple set of routines for querying the device's | 345 | /* We have a simple set of routines for querying the device's |
351 | * configuration information and setting its status. */ | 346 | * configuration information and setting its status. */ |
@@ -357,8 +352,8 @@ static void add_lguest_device(struct lguest_device_desc *d) | |||
357 | * virtio_device and calls device_register(). This makes the bus | 352 | * virtio_device and calls device_register(). This makes the bus |
358 | * infrastructure look for a matching driver. */ | 353 | * infrastructure look for a matching driver. */ |
359 | if (register_virtio_device(&ldev->vdev) != 0) { | 354 | if (register_virtio_device(&ldev->vdev) != 0) { |
360 | printk(KERN_ERR "Failed to register lguest device %u\n", | 355 | printk(KERN_ERR "Failed to register lguest dev %u type %u\n", |
361 | ldev->vdev.index); | 356 | offset, d->type); |
362 | kfree(ldev); | 357 | kfree(ldev); |
363 | } | 358 | } |
364 | } | 359 | } |
@@ -379,7 +374,7 @@ static void scan_devices(void) | |||
379 | break; | 374 | break; |
380 | 375 | ||
381 | printk("Device at %i has size %u\n", i, desc_size(d)); | 376 | printk("Device at %i has size %u\n", i, desc_size(d)); |
382 | add_lguest_device(d); | 377 | add_lguest_device(d, i); |
383 | } | 378 | } |
384 | } | 379 | } |
385 | 380 | ||
diff --git a/drivers/macintosh/mediabay.c b/drivers/macintosh/mediabay.c index 82add26cc665..c34bdf852e32 100644 --- a/drivers/macintosh/mediabay.c +++ b/drivers/macintosh/mediabay.c | |||
@@ -556,7 +556,8 @@ static void media_bay_step(int i) | |||
556 | printk("mediabay %d, registering IDE...\n", i); | 556 | printk("mediabay %d, registering IDE...\n", i); |
557 | pmu_suspend(); | 557 | pmu_suspend(); |
558 | ide_port_scan(bay->cd_port); | 558 | ide_port_scan(bay->cd_port); |
559 | bay->cd_index = bay->cd_port->index; | 559 | if (bay->cd_port->present) |
560 | bay->cd_index = bay->cd_port->index; | ||
560 | pmu_resume(); | 561 | pmu_resume(); |
561 | } | 562 | } |
562 | if (bay->cd_index == -1) { | 563 | if (bay->cd_index == -1) { |
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index c14dacdacfac..b26927ce889c 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c | |||
@@ -203,17 +203,6 @@ static void bitmap_checkfree(struct bitmap *bitmap, unsigned long page) | |||
203 | * bitmap file handling - read and write the bitmap file and its superblock | 203 | * bitmap file handling - read and write the bitmap file and its superblock |
204 | */ | 204 | */ |
205 | 205 | ||
206 | /* copy the pathname of a file to a buffer */ | ||
207 | char *file_path(struct file *file, char *buf, int count) | ||
208 | { | ||
209 | if (!buf) | ||
210 | return NULL; | ||
211 | |||
212 | buf = d_path(&file->f_path, buf, count); | ||
213 | |||
214 | return IS_ERR(buf) ? NULL : buf; | ||
215 | } | ||
216 | |||
217 | /* | 206 | /* |
218 | * basic page I/O operations | 207 | * basic page I/O operations |
219 | */ | 208 | */ |
@@ -721,11 +710,13 @@ static void bitmap_file_kick(struct bitmap *bitmap) | |||
721 | if (bitmap->file) { | 710 | if (bitmap->file) { |
722 | path = kmalloc(PAGE_SIZE, GFP_KERNEL); | 711 | path = kmalloc(PAGE_SIZE, GFP_KERNEL); |
723 | if (path) | 712 | if (path) |
724 | ptr = file_path(bitmap->file, path, PAGE_SIZE); | 713 | ptr = d_path(&bitmap->file->f_path, path, |
714 | PAGE_SIZE); | ||
715 | |||
725 | 716 | ||
726 | printk(KERN_ALERT | 717 | printk(KERN_ALERT |
727 | "%s: kicking failed bitmap file %s from array!\n", | 718 | "%s: kicking failed bitmap file %s from array!\n", |
728 | bmname(bitmap), ptr ? ptr : ""); | 719 | bmname(bitmap), IS_ERR(ptr) ? "" : ptr); |
729 | 720 | ||
730 | kfree(path); | 721 | kfree(path); |
731 | } else | 722 | } else |
diff --git a/drivers/md/md.c b/drivers/md/md.c index 83eb78b00137..7cf512a34ccf 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -74,6 +74,8 @@ static DEFINE_SPINLOCK(pers_lock); | |||
74 | 74 | ||
75 | static void md_print_devices(void); | 75 | static void md_print_devices(void); |
76 | 76 | ||
77 | static DECLARE_WAIT_QUEUE_HEAD(resync_wait); | ||
78 | |||
77 | #define MD_BUG(x...) { printk("md: bug in file %s, line %d\n", __FILE__, __LINE__); md_print_devices(); } | 79 | #define MD_BUG(x...) { printk("md: bug in file %s, line %d\n", __FILE__, __LINE__); md_print_devices(); } |
78 | 80 | ||
79 | /* | 81 | /* |
@@ -274,6 +276,7 @@ static mddev_t * mddev_find(dev_t unit) | |||
274 | atomic_set(&new->active, 1); | 276 | atomic_set(&new->active, 1); |
275 | spin_lock_init(&new->write_lock); | 277 | spin_lock_init(&new->write_lock); |
276 | init_waitqueue_head(&new->sb_wait); | 278 | init_waitqueue_head(&new->sb_wait); |
279 | init_waitqueue_head(&new->recovery_wait); | ||
277 | new->reshape_position = MaxSector; | 280 | new->reshape_position = MaxSector; |
278 | new->resync_max = MaxSector; | 281 | new->resync_max = MaxSector; |
279 | new->level = LEVEL_NONE; | 282 | new->level = LEVEL_NONE; |
@@ -3013,6 +3016,36 @@ degraded_show(mddev_t *mddev, char *page) | |||
3013 | static struct md_sysfs_entry md_degraded = __ATTR_RO(degraded); | 3016 | static struct md_sysfs_entry md_degraded = __ATTR_RO(degraded); |
3014 | 3017 | ||
3015 | static ssize_t | 3018 | static ssize_t |
3019 | sync_force_parallel_show(mddev_t *mddev, char *page) | ||
3020 | { | ||
3021 | return sprintf(page, "%d\n", mddev->parallel_resync); | ||
3022 | } | ||
3023 | |||
3024 | static ssize_t | ||
3025 | sync_force_parallel_store(mddev_t *mddev, const char *buf, size_t len) | ||
3026 | { | ||
3027 | long n; | ||
3028 | |||
3029 | if (strict_strtol(buf, 10, &n)) | ||
3030 | return -EINVAL; | ||
3031 | |||
3032 | if (n != 0 && n != 1) | ||
3033 | return -EINVAL; | ||
3034 | |||
3035 | mddev->parallel_resync = n; | ||
3036 | |||
3037 | if (mddev->sync_thread) | ||
3038 | wake_up(&resync_wait); | ||
3039 | |||
3040 | return len; | ||
3041 | } | ||
3042 | |||
3043 | /* force parallel resync, even with shared block devices */ | ||
3044 | static struct md_sysfs_entry md_sync_force_parallel = | ||
3045 | __ATTR(sync_force_parallel, S_IRUGO|S_IWUSR, | ||
3046 | sync_force_parallel_show, sync_force_parallel_store); | ||
3047 | |||
3048 | static ssize_t | ||
3016 | sync_speed_show(mddev_t *mddev, char *page) | 3049 | sync_speed_show(mddev_t *mddev, char *page) |
3017 | { | 3050 | { |
3018 | unsigned long resync, dt, db; | 3051 | unsigned long resync, dt, db; |
@@ -3187,6 +3220,7 @@ static struct attribute *md_redundancy_attrs[] = { | |||
3187 | &md_sync_min.attr, | 3220 | &md_sync_min.attr, |
3188 | &md_sync_max.attr, | 3221 | &md_sync_max.attr, |
3189 | &md_sync_speed.attr, | 3222 | &md_sync_speed.attr, |
3223 | &md_sync_force_parallel.attr, | ||
3190 | &md_sync_completed.attr, | 3224 | &md_sync_completed.attr, |
3191 | &md_max_sync.attr, | 3225 | &md_max_sync.attr, |
3192 | &md_suspend_lo.attr, | 3226 | &md_suspend_lo.attr, |
@@ -3691,6 +3725,8 @@ static int do_md_stop(mddev_t * mddev, int mode) | |||
3691 | 3725 | ||
3692 | module_put(mddev->pers->owner); | 3726 | module_put(mddev->pers->owner); |
3693 | mddev->pers = NULL; | 3727 | mddev->pers = NULL; |
3728 | /* tell userspace to handle 'inactive' */ | ||
3729 | sysfs_notify(&mddev->kobj, NULL, "array_state"); | ||
3694 | 3730 | ||
3695 | set_capacity(disk, 0); | 3731 | set_capacity(disk, 0); |
3696 | mddev->changed = 1; | 3732 | mddev->changed = 1; |
@@ -3987,8 +4023,8 @@ static int get_bitmap_file(mddev_t * mddev, void __user * arg) | |||
3987 | if (!buf) | 4023 | if (!buf) |
3988 | goto out; | 4024 | goto out; |
3989 | 4025 | ||
3990 | ptr = file_path(mddev->bitmap->file, buf, sizeof(file->pathname)); | 4026 | ptr = d_path(&mddev->bitmap->file->f_path, buf, sizeof(file->pathname)); |
3991 | if (!ptr) | 4027 | if (IS_ERR(ptr)) |
3992 | goto out; | 4028 | goto out; |
3993 | 4029 | ||
3994 | strcpy(file->pathname, ptr); | 4030 | strcpy(file->pathname, ptr); |
@@ -5399,7 +5435,7 @@ void md_done_sync(mddev_t *mddev, int blocks, int ok) | |||
5399 | atomic_sub(blocks, &mddev->recovery_active); | 5435 | atomic_sub(blocks, &mddev->recovery_active); |
5400 | wake_up(&mddev->recovery_wait); | 5436 | wake_up(&mddev->recovery_wait); |
5401 | if (!ok) { | 5437 | if (!ok) { |
5402 | set_bit(MD_RECOVERY_ERR, &mddev->recovery); | 5438 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); |
5403 | md_wakeup_thread(mddev->thread); | 5439 | md_wakeup_thread(mddev->thread); |
5404 | // stop recovery, signal do_sync .... | 5440 | // stop recovery, signal do_sync .... |
5405 | } | 5441 | } |
@@ -5435,8 +5471,11 @@ void md_write_start(mddev_t *mddev, struct bio *bi) | |||
5435 | md_wakeup_thread(mddev->thread); | 5471 | md_wakeup_thread(mddev->thread); |
5436 | } | 5472 | } |
5437 | spin_unlock_irq(&mddev->write_lock); | 5473 | spin_unlock_irq(&mddev->write_lock); |
5474 | sysfs_notify(&mddev->kobj, NULL, "array_state"); | ||
5438 | } | 5475 | } |
5439 | wait_event(mddev->sb_wait, mddev->flags==0); | 5476 | wait_event(mddev->sb_wait, |
5477 | !test_bit(MD_CHANGE_CLEAN, &mddev->flags) && | ||
5478 | !test_bit(MD_CHANGE_PENDING, &mddev->flags)); | ||
5440 | } | 5479 | } |
5441 | 5480 | ||
5442 | void md_write_end(mddev_t *mddev) | 5481 | void md_write_end(mddev_t *mddev) |
@@ -5471,13 +5510,17 @@ void md_allow_write(mddev_t *mddev) | |||
5471 | mddev->safemode = 1; | 5510 | mddev->safemode = 1; |
5472 | spin_unlock_irq(&mddev->write_lock); | 5511 | spin_unlock_irq(&mddev->write_lock); |
5473 | md_update_sb(mddev, 0); | 5512 | md_update_sb(mddev, 0); |
5513 | |||
5514 | sysfs_notify(&mddev->kobj, NULL, "array_state"); | ||
5515 | /* wait for the dirty state to be recorded in the metadata */ | ||
5516 | wait_event(mddev->sb_wait, | ||
5517 | !test_bit(MD_CHANGE_CLEAN, &mddev->flags) && | ||
5518 | !test_bit(MD_CHANGE_PENDING, &mddev->flags)); | ||
5474 | } else | 5519 | } else |
5475 | spin_unlock_irq(&mddev->write_lock); | 5520 | spin_unlock_irq(&mddev->write_lock); |
5476 | } | 5521 | } |
5477 | EXPORT_SYMBOL_GPL(md_allow_write); | 5522 | EXPORT_SYMBOL_GPL(md_allow_write); |
5478 | 5523 | ||
5479 | static DECLARE_WAIT_QUEUE_HEAD(resync_wait); | ||
5480 | |||
5481 | #define SYNC_MARKS 10 | 5524 | #define SYNC_MARKS 10 |
5482 | #define SYNC_MARK_STEP (3*HZ) | 5525 | #define SYNC_MARK_STEP (3*HZ) |
5483 | void md_do_sync(mddev_t *mddev) | 5526 | void md_do_sync(mddev_t *mddev) |
@@ -5541,8 +5584,9 @@ void md_do_sync(mddev_t *mddev) | |||
5541 | for_each_mddev(mddev2, tmp) { | 5584 | for_each_mddev(mddev2, tmp) { |
5542 | if (mddev2 == mddev) | 5585 | if (mddev2 == mddev) |
5543 | continue; | 5586 | continue; |
5544 | if (mddev2->curr_resync && | 5587 | if (!mddev->parallel_resync |
5545 | match_mddev_units(mddev,mddev2)) { | 5588 | && mddev2->curr_resync |
5589 | && match_mddev_units(mddev, mddev2)) { | ||
5546 | DEFINE_WAIT(wq); | 5590 | DEFINE_WAIT(wq); |
5547 | if (mddev < mddev2 && mddev->curr_resync == 2) { | 5591 | if (mddev < mddev2 && mddev->curr_resync == 2) { |
5548 | /* arbitrarily yield */ | 5592 | /* arbitrarily yield */ |
@@ -5622,7 +5666,6 @@ void md_do_sync(mddev_t *mddev) | |||
5622 | window/2,(unsigned long long) max_sectors/2); | 5666 | window/2,(unsigned long long) max_sectors/2); |
5623 | 5667 | ||
5624 | atomic_set(&mddev->recovery_active, 0); | 5668 | atomic_set(&mddev->recovery_active, 0); |
5625 | init_waitqueue_head(&mddev->recovery_wait); | ||
5626 | last_check = 0; | 5669 | last_check = 0; |
5627 | 5670 | ||
5628 | if (j>2) { | 5671 | if (j>2) { |
@@ -5647,7 +5690,7 @@ void md_do_sync(mddev_t *mddev) | |||
5647 | sectors = mddev->pers->sync_request(mddev, j, &skipped, | 5690 | sectors = mddev->pers->sync_request(mddev, j, &skipped, |
5648 | currspeed < speed_min(mddev)); | 5691 | currspeed < speed_min(mddev)); |
5649 | if (sectors == 0) { | 5692 | if (sectors == 0) { |
5650 | set_bit(MD_RECOVERY_ERR, &mddev->recovery); | 5693 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); |
5651 | goto out; | 5694 | goto out; |
5652 | } | 5695 | } |
5653 | 5696 | ||
@@ -5670,8 +5713,7 @@ void md_do_sync(mddev_t *mddev) | |||
5670 | 5713 | ||
5671 | last_check = io_sectors; | 5714 | last_check = io_sectors; |
5672 | 5715 | ||
5673 | if (test_bit(MD_RECOVERY_INTR, &mddev->recovery) || | 5716 | if (test_bit(MD_RECOVERY_INTR, &mddev->recovery)) |
5674 | test_bit(MD_RECOVERY_ERR, &mddev->recovery)) | ||
5675 | break; | 5717 | break; |
5676 | 5718 | ||
5677 | repeat: | 5719 | repeat: |
@@ -5725,8 +5767,7 @@ void md_do_sync(mddev_t *mddev) | |||
5725 | /* tell personality that we are finished */ | 5767 | /* tell personality that we are finished */ |
5726 | mddev->pers->sync_request(mddev, max_sectors, &skipped, 1); | 5768 | mddev->pers->sync_request(mddev, max_sectors, &skipped, 1); |
5727 | 5769 | ||
5728 | if (!test_bit(MD_RECOVERY_ERR, &mddev->recovery) && | 5770 | if (!test_bit(MD_RECOVERY_CHECK, &mddev->recovery) && |
5729 | !test_bit(MD_RECOVERY_CHECK, &mddev->recovery) && | ||
5730 | mddev->curr_resync > 2) { | 5771 | mddev->curr_resync > 2) { |
5731 | if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) { | 5772 | if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) { |
5732 | if (test_bit(MD_RECOVERY_INTR, &mddev->recovery)) { | 5773 | if (test_bit(MD_RECOVERY_INTR, &mddev->recovery)) { |
@@ -5795,7 +5836,10 @@ static int remove_and_add_spares(mddev_t *mddev) | |||
5795 | } | 5836 | } |
5796 | 5837 | ||
5797 | if (mddev->degraded) { | 5838 | if (mddev->degraded) { |
5798 | rdev_for_each(rdev, rtmp, mddev) | 5839 | rdev_for_each(rdev, rtmp, mddev) { |
5840 | if (rdev->raid_disk >= 0 && | ||
5841 | !test_bit(In_sync, &rdev->flags)) | ||
5842 | spares++; | ||
5799 | if (rdev->raid_disk < 0 | 5843 | if (rdev->raid_disk < 0 |
5800 | && !test_bit(Faulty, &rdev->flags)) { | 5844 | && !test_bit(Faulty, &rdev->flags)) { |
5801 | rdev->recovery_offset = 0; | 5845 | rdev->recovery_offset = 0; |
@@ -5813,6 +5857,7 @@ static int remove_and_add_spares(mddev_t *mddev) | |||
5813 | } else | 5857 | } else |
5814 | break; | 5858 | break; |
5815 | } | 5859 | } |
5860 | } | ||
5816 | } | 5861 | } |
5817 | return spares; | 5862 | return spares; |
5818 | } | 5863 | } |
@@ -5826,7 +5871,7 @@ static int remove_and_add_spares(mddev_t *mddev) | |||
5826 | * to do that as needed. | 5871 | * to do that as needed. |
5827 | * When it is determined that resync is needed, we set MD_RECOVERY_RUNNING in | 5872 | * When it is determined that resync is needed, we set MD_RECOVERY_RUNNING in |
5828 | * "->recovery" and create a thread at ->sync_thread. | 5873 | * "->recovery" and create a thread at ->sync_thread. |
5829 | * When the thread finishes it sets MD_RECOVERY_DONE (and might set MD_RECOVERY_ERR) | 5874 | * When the thread finishes it sets MD_RECOVERY_DONE |
5830 | * and wakeups up this thread which will reap the thread and finish up. | 5875 | * and wakeups up this thread which will reap the thread and finish up. |
5831 | * This thread also removes any faulty devices (with nr_pending == 0). | 5876 | * This thread also removes any faulty devices (with nr_pending == 0). |
5832 | * | 5877 | * |
@@ -5901,8 +5946,7 @@ void md_check_recovery(mddev_t *mddev) | |||
5901 | /* resync has finished, collect result */ | 5946 | /* resync has finished, collect result */ |
5902 | md_unregister_thread(mddev->sync_thread); | 5947 | md_unregister_thread(mddev->sync_thread); |
5903 | mddev->sync_thread = NULL; | 5948 | mddev->sync_thread = NULL; |
5904 | if (!test_bit(MD_RECOVERY_ERR, &mddev->recovery) && | 5949 | if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery)) { |
5905 | !test_bit(MD_RECOVERY_INTR, &mddev->recovery)) { | ||
5906 | /* success...*/ | 5950 | /* success...*/ |
5907 | /* activate any spares */ | 5951 | /* activate any spares */ |
5908 | mddev->pers->spare_active(mddev); | 5952 | mddev->pers->spare_active(mddev); |
@@ -5926,7 +5970,6 @@ void md_check_recovery(mddev_t *mddev) | |||
5926 | * might be left set | 5970 | * might be left set |
5927 | */ | 5971 | */ |
5928 | clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery); | 5972 | clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery); |
5929 | clear_bit(MD_RECOVERY_ERR, &mddev->recovery); | ||
5930 | clear_bit(MD_RECOVERY_INTR, &mddev->recovery); | 5973 | clear_bit(MD_RECOVERY_INTR, &mddev->recovery); |
5931 | clear_bit(MD_RECOVERY_DONE, &mddev->recovery); | 5974 | clear_bit(MD_RECOVERY_DONE, &mddev->recovery); |
5932 | 5975 | ||
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c index 4f4d1f383842..e968116e0de9 100644 --- a/drivers/md/multipath.c +++ b/drivers/md/multipath.c | |||
@@ -327,7 +327,8 @@ static int multipath_remove_disk(mddev_t *mddev, int number) | |||
327 | if (rdev) { | 327 | if (rdev) { |
328 | if (test_bit(In_sync, &rdev->flags) || | 328 | if (test_bit(In_sync, &rdev->flags) || |
329 | atomic_read(&rdev->nr_pending)) { | 329 | atomic_read(&rdev->nr_pending)) { |
330 | printk(KERN_ERR "hot-remove-disk, slot %d is identified" " but is still operational!\n", number); | 330 | printk(KERN_ERR "hot-remove-disk, slot %d is identified" |
331 | " but is still operational!\n", number); | ||
331 | err = -EBUSY; | 332 | err = -EBUSY; |
332 | goto abort; | 333 | goto abort; |
333 | } | 334 | } |
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index ac409b7d83f5..c610b947218a 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
@@ -773,7 +773,7 @@ static int make_request(struct request_queue *q, struct bio * bio) | |||
773 | r1bio_t *r1_bio; | 773 | r1bio_t *r1_bio; |
774 | struct bio *read_bio; | 774 | struct bio *read_bio; |
775 | int i, targets = 0, disks; | 775 | int i, targets = 0, disks; |
776 | struct bitmap *bitmap = mddev->bitmap; | 776 | struct bitmap *bitmap; |
777 | unsigned long flags; | 777 | unsigned long flags; |
778 | struct bio_list bl; | 778 | struct bio_list bl; |
779 | struct page **behind_pages = NULL; | 779 | struct page **behind_pages = NULL; |
@@ -802,6 +802,8 @@ static int make_request(struct request_queue *q, struct bio * bio) | |||
802 | 802 | ||
803 | wait_barrier(conf); | 803 | wait_barrier(conf); |
804 | 804 | ||
805 | bitmap = mddev->bitmap; | ||
806 | |||
805 | disk_stat_inc(mddev->gendisk, ios[rw]); | 807 | disk_stat_inc(mddev->gendisk, ios[rw]); |
806 | disk_stat_add(mddev->gendisk, sectors[rw], bio_sectors(bio)); | 808 | disk_stat_add(mddev->gendisk, sectors[rw], bio_sectors(bio)); |
807 | 809 | ||
@@ -1025,7 +1027,7 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev) | |||
1025 | /* | 1027 | /* |
1026 | * if recovery is running, make sure it aborts. | 1028 | * if recovery is running, make sure it aborts. |
1027 | */ | 1029 | */ |
1028 | set_bit(MD_RECOVERY_ERR, &mddev->recovery); | 1030 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); |
1029 | } else | 1031 | } else |
1030 | set_bit(Faulty, &rdev->flags); | 1032 | set_bit(Faulty, &rdev->flags); |
1031 | set_bit(MD_CHANGE_DEVS, &mddev->flags); | 1033 | set_bit(MD_CHANGE_DEVS, &mddev->flags); |
@@ -1146,6 +1148,14 @@ static int raid1_remove_disk(mddev_t *mddev, int number) | |||
1146 | err = -EBUSY; | 1148 | err = -EBUSY; |
1147 | goto abort; | 1149 | goto abort; |
1148 | } | 1150 | } |
1151 | /* Only remove non-faulty devices is recovery | ||
1152 | * is not possible. | ||
1153 | */ | ||
1154 | if (!test_bit(Faulty, &rdev->flags) && | ||
1155 | mddev->degraded < conf->raid_disks) { | ||
1156 | err = -EBUSY; | ||
1157 | goto abort; | ||
1158 | } | ||
1149 | p->rdev = NULL; | 1159 | p->rdev = NULL; |
1150 | synchronize_rcu(); | 1160 | synchronize_rcu(); |
1151 | if (atomic_read(&rdev->nr_pending)) { | 1161 | if (atomic_read(&rdev->nr_pending)) { |
@@ -1282,6 +1292,7 @@ static void sync_request_write(mddev_t *mddev, r1bio_t *r1_bio) | |||
1282 | rdev_dec_pending(conf->mirrors[i].rdev, mddev); | 1292 | rdev_dec_pending(conf->mirrors[i].rdev, mddev); |
1283 | } else { | 1293 | } else { |
1284 | /* fixup the bio for reuse */ | 1294 | /* fixup the bio for reuse */ |
1295 | int size; | ||
1285 | sbio->bi_vcnt = vcnt; | 1296 | sbio->bi_vcnt = vcnt; |
1286 | sbio->bi_size = r1_bio->sectors << 9; | 1297 | sbio->bi_size = r1_bio->sectors << 9; |
1287 | sbio->bi_idx = 0; | 1298 | sbio->bi_idx = 0; |
@@ -1295,10 +1306,20 @@ static void sync_request_write(mddev_t *mddev, r1bio_t *r1_bio) | |||
1295 | sbio->bi_sector = r1_bio->sector + | 1306 | sbio->bi_sector = r1_bio->sector + |
1296 | conf->mirrors[i].rdev->data_offset; | 1307 | conf->mirrors[i].rdev->data_offset; |
1297 | sbio->bi_bdev = conf->mirrors[i].rdev->bdev; | 1308 | sbio->bi_bdev = conf->mirrors[i].rdev->bdev; |
1298 | for (j = 0; j < vcnt ; j++) | 1309 | size = sbio->bi_size; |
1299 | memcpy(page_address(sbio->bi_io_vec[j].bv_page), | 1310 | for (j = 0; j < vcnt ; j++) { |
1311 | struct bio_vec *bi; | ||
1312 | bi = &sbio->bi_io_vec[j]; | ||
1313 | bi->bv_offset = 0; | ||
1314 | if (size > PAGE_SIZE) | ||
1315 | bi->bv_len = PAGE_SIZE; | ||
1316 | else | ||
1317 | bi->bv_len = size; | ||
1318 | size -= PAGE_SIZE; | ||
1319 | memcpy(page_address(bi->bv_page), | ||
1300 | page_address(pbio->bi_io_vec[j].bv_page), | 1320 | page_address(pbio->bi_io_vec[j].bv_page), |
1301 | PAGE_SIZE); | 1321 | PAGE_SIZE); |
1322 | } | ||
1302 | 1323 | ||
1303 | } | 1324 | } |
1304 | } | 1325 | } |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 8536ede1e712..1de17da34a95 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -1020,7 +1020,7 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev) | |||
1020 | /* | 1020 | /* |
1021 | * if recovery is running, make sure it aborts. | 1021 | * if recovery is running, make sure it aborts. |
1022 | */ | 1022 | */ |
1023 | set_bit(MD_RECOVERY_ERR, &mddev->recovery); | 1023 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); |
1024 | } | 1024 | } |
1025 | set_bit(Faulty, &rdev->flags); | 1025 | set_bit(Faulty, &rdev->flags); |
1026 | set_bit(MD_CHANGE_DEVS, &mddev->flags); | 1026 | set_bit(MD_CHANGE_DEVS, &mddev->flags); |
@@ -1171,6 +1171,14 @@ static int raid10_remove_disk(mddev_t *mddev, int number) | |||
1171 | err = -EBUSY; | 1171 | err = -EBUSY; |
1172 | goto abort; | 1172 | goto abort; |
1173 | } | 1173 | } |
1174 | /* Only remove faulty devices in recovery | ||
1175 | * is not possible. | ||
1176 | */ | ||
1177 | if (!test_bit(Faulty, &rdev->flags) && | ||
1178 | enough(conf)) { | ||
1179 | err = -EBUSY; | ||
1180 | goto abort; | ||
1181 | } | ||
1174 | p->rdev = NULL; | 1182 | p->rdev = NULL; |
1175 | synchronize_rcu(); | 1183 | synchronize_rcu(); |
1176 | if (atomic_read(&rdev->nr_pending)) { | 1184 | if (atomic_read(&rdev->nr_pending)) { |
@@ -1237,6 +1245,7 @@ static void end_sync_write(struct bio *bio, int error) | |||
1237 | 1245 | ||
1238 | if (!uptodate) | 1246 | if (!uptodate) |
1239 | md_error(mddev, conf->mirrors[d].rdev); | 1247 | md_error(mddev, conf->mirrors[d].rdev); |
1248 | |||
1240 | update_head_pos(i, r10_bio); | 1249 | update_head_pos(i, r10_bio); |
1241 | 1250 | ||
1242 | while (atomic_dec_and_test(&r10_bio->remaining)) { | 1251 | while (atomic_dec_and_test(&r10_bio->remaining)) { |
@@ -1844,7 +1853,8 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i | |||
1844 | if (rb2) | 1853 | if (rb2) |
1845 | atomic_dec(&rb2->remaining); | 1854 | atomic_dec(&rb2->remaining); |
1846 | r10_bio = rb2; | 1855 | r10_bio = rb2; |
1847 | if (!test_and_set_bit(MD_RECOVERY_ERR, &mddev->recovery)) | 1856 | if (!test_and_set_bit(MD_RECOVERY_INTR, |
1857 | &mddev->recovery)) | ||
1848 | printk(KERN_INFO "raid10: %s: insufficient working devices for recovery.\n", | 1858 | printk(KERN_INFO "raid10: %s: insufficient working devices for recovery.\n", |
1849 | mdname(mddev)); | 1859 | mdname(mddev)); |
1850 | break; | 1860 | break; |
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 93fde48c0f42..c37e256b1176 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -94,6 +94,8 @@ | |||
94 | #define __inline__ | 94 | #define __inline__ |
95 | #endif | 95 | #endif |
96 | 96 | ||
97 | #define printk_rl(args...) ((void) (printk_ratelimit() && printk(args))) | ||
98 | |||
97 | #if !RAID6_USE_EMPTY_ZERO_PAGE | 99 | #if !RAID6_USE_EMPTY_ZERO_PAGE |
98 | /* In .bss so it's zeroed */ | 100 | /* In .bss so it's zeroed */ |
99 | const char raid6_empty_zero_page[PAGE_SIZE] __attribute__((aligned(256))); | 101 | const char raid6_empty_zero_page[PAGE_SIZE] __attribute__((aligned(256))); |
@@ -1143,10 +1145,12 @@ static void raid5_end_read_request(struct bio * bi, int error) | |||
1143 | set_bit(R5_UPTODATE, &sh->dev[i].flags); | 1145 | set_bit(R5_UPTODATE, &sh->dev[i].flags); |
1144 | if (test_bit(R5_ReadError, &sh->dev[i].flags)) { | 1146 | if (test_bit(R5_ReadError, &sh->dev[i].flags)) { |
1145 | rdev = conf->disks[i].rdev; | 1147 | rdev = conf->disks[i].rdev; |
1146 | printk(KERN_INFO "raid5:%s: read error corrected (%lu sectors at %llu on %s)\n", | 1148 | printk_rl(KERN_INFO "raid5:%s: read error corrected" |
1147 | mdname(conf->mddev), STRIPE_SECTORS, | 1149 | " (%lu sectors at %llu on %s)\n", |
1148 | (unsigned long long)(sh->sector + rdev->data_offset), | 1150 | mdname(conf->mddev), STRIPE_SECTORS, |
1149 | bdevname(rdev->bdev, b)); | 1151 | (unsigned long long)(sh->sector |
1152 | + rdev->data_offset), | ||
1153 | bdevname(rdev->bdev, b)); | ||
1150 | clear_bit(R5_ReadError, &sh->dev[i].flags); | 1154 | clear_bit(R5_ReadError, &sh->dev[i].flags); |
1151 | clear_bit(R5_ReWrite, &sh->dev[i].flags); | 1155 | clear_bit(R5_ReWrite, &sh->dev[i].flags); |
1152 | } | 1156 | } |
@@ -1160,16 +1164,22 @@ static void raid5_end_read_request(struct bio * bi, int error) | |||
1160 | clear_bit(R5_UPTODATE, &sh->dev[i].flags); | 1164 | clear_bit(R5_UPTODATE, &sh->dev[i].flags); |
1161 | atomic_inc(&rdev->read_errors); | 1165 | atomic_inc(&rdev->read_errors); |
1162 | if (conf->mddev->degraded) | 1166 | if (conf->mddev->degraded) |
1163 | printk(KERN_WARNING "raid5:%s: read error not correctable (sector %llu on %s).\n", | 1167 | printk_rl(KERN_WARNING |
1164 | mdname(conf->mddev), | 1168 | "raid5:%s: read error not correctable " |
1165 | (unsigned long long)(sh->sector + rdev->data_offset), | 1169 | "(sector %llu on %s).\n", |
1166 | bdn); | 1170 | mdname(conf->mddev), |
1171 | (unsigned long long)(sh->sector | ||
1172 | + rdev->data_offset), | ||
1173 | bdn); | ||
1167 | else if (test_bit(R5_ReWrite, &sh->dev[i].flags)) | 1174 | else if (test_bit(R5_ReWrite, &sh->dev[i].flags)) |
1168 | /* Oh, no!!! */ | 1175 | /* Oh, no!!! */ |
1169 | printk(KERN_WARNING "raid5:%s: read error NOT corrected!! (sector %llu on %s).\n", | 1176 | printk_rl(KERN_WARNING |
1170 | mdname(conf->mddev), | 1177 | "raid5:%s: read error NOT corrected!! " |
1171 | (unsigned long long)(sh->sector + rdev->data_offset), | 1178 | "(sector %llu on %s).\n", |
1172 | bdn); | 1179 | mdname(conf->mddev), |
1180 | (unsigned long long)(sh->sector | ||
1181 | + rdev->data_offset), | ||
1182 | bdn); | ||
1173 | else if (atomic_read(&rdev->read_errors) | 1183 | else if (atomic_read(&rdev->read_errors) |
1174 | > conf->max_nr_stripes) | 1184 | > conf->max_nr_stripes) |
1175 | printk(KERN_WARNING | 1185 | printk(KERN_WARNING |
@@ -1258,7 +1268,7 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev) | |||
1258 | /* | 1268 | /* |
1259 | * if recovery was running, make sure it aborts. | 1269 | * if recovery was running, make sure it aborts. |
1260 | */ | 1270 | */ |
1261 | set_bit(MD_RECOVERY_ERR, &mddev->recovery); | 1271 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); |
1262 | } | 1272 | } |
1263 | set_bit(Faulty, &rdev->flags); | 1273 | set_bit(Faulty, &rdev->flags); |
1264 | printk (KERN_ALERT | 1274 | printk (KERN_ALERT |
@@ -1992,6 +2002,7 @@ static int __handle_issuing_new_read_requests5(struct stripe_head *sh, | |||
1992 | * have quiesced. | 2002 | * have quiesced. |
1993 | */ | 2003 | */ |
1994 | if ((s->uptodate == disks - 1) && | 2004 | if ((s->uptodate == disks - 1) && |
2005 | (s->failed && disk_idx == s->failed_num) && | ||
1995 | !test_bit(STRIPE_OP_CHECK, &sh->ops.pending)) { | 2006 | !test_bit(STRIPE_OP_CHECK, &sh->ops.pending)) { |
1996 | set_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending); | 2007 | set_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending); |
1997 | set_bit(R5_Wantcompute, &dev->flags); | 2008 | set_bit(R5_Wantcompute, &dev->flags); |
@@ -2077,7 +2088,9 @@ static void handle_issuing_new_read_requests6(struct stripe_head *sh, | |||
2077 | /* we would like to get this block, possibly | 2088 | /* we would like to get this block, possibly |
2078 | * by computing it, but we might not be able to | 2089 | * by computing it, but we might not be able to |
2079 | */ | 2090 | */ |
2080 | if (s->uptodate == disks-1) { | 2091 | if ((s->uptodate == disks - 1) && |
2092 | (s->failed && (i == r6s->failed_num[0] || | ||
2093 | i == r6s->failed_num[1]))) { | ||
2081 | pr_debug("Computing stripe %llu block %d\n", | 2094 | pr_debug("Computing stripe %llu block %d\n", |
2082 | (unsigned long long)sh->sector, i); | 2095 | (unsigned long long)sh->sector, i); |
2083 | compute_block_1(sh, i, 0); | 2096 | compute_block_1(sh, i, 0); |
@@ -2635,6 +2648,7 @@ static void handle_stripe5(struct stripe_head *sh) | |||
2635 | struct r5dev *dev; | 2648 | struct r5dev *dev; |
2636 | unsigned long pending = 0; | 2649 | unsigned long pending = 0; |
2637 | mdk_rdev_t *blocked_rdev = NULL; | 2650 | mdk_rdev_t *blocked_rdev = NULL; |
2651 | int prexor; | ||
2638 | 2652 | ||
2639 | memset(&s, 0, sizeof(s)); | 2653 | memset(&s, 0, sizeof(s)); |
2640 | pr_debug("handling stripe %llu, state=%#lx cnt=%d, pd_idx=%d " | 2654 | pr_debug("handling stripe %llu, state=%#lx cnt=%d, pd_idx=%d " |
@@ -2764,9 +2778,11 @@ static void handle_stripe5(struct stripe_head *sh) | |||
2764 | /* leave prexor set until postxor is done, allows us to distinguish | 2778 | /* leave prexor set until postxor is done, allows us to distinguish |
2765 | * a rmw from a rcw during biodrain | 2779 | * a rmw from a rcw during biodrain |
2766 | */ | 2780 | */ |
2781 | prexor = 0; | ||
2767 | if (test_bit(STRIPE_OP_PREXOR, &sh->ops.complete) && | 2782 | if (test_bit(STRIPE_OP_PREXOR, &sh->ops.complete) && |
2768 | test_bit(STRIPE_OP_POSTXOR, &sh->ops.complete)) { | 2783 | test_bit(STRIPE_OP_POSTXOR, &sh->ops.complete)) { |
2769 | 2784 | ||
2785 | prexor = 1; | ||
2770 | clear_bit(STRIPE_OP_PREXOR, &sh->ops.complete); | 2786 | clear_bit(STRIPE_OP_PREXOR, &sh->ops.complete); |
2771 | clear_bit(STRIPE_OP_PREXOR, &sh->ops.ack); | 2787 | clear_bit(STRIPE_OP_PREXOR, &sh->ops.ack); |
2772 | clear_bit(STRIPE_OP_PREXOR, &sh->ops.pending); | 2788 | clear_bit(STRIPE_OP_PREXOR, &sh->ops.pending); |
@@ -2800,6 +2816,8 @@ static void handle_stripe5(struct stripe_head *sh) | |||
2800 | if (!test_and_set_bit( | 2816 | if (!test_and_set_bit( |
2801 | STRIPE_OP_IO, &sh->ops.pending)) | 2817 | STRIPE_OP_IO, &sh->ops.pending)) |
2802 | sh->ops.count++; | 2818 | sh->ops.count++; |
2819 | if (prexor) | ||
2820 | continue; | ||
2803 | if (!test_bit(R5_Insync, &dev->flags) || | 2821 | if (!test_bit(R5_Insync, &dev->flags) || |
2804 | (i == sh->pd_idx && s.failed == 0)) | 2822 | (i == sh->pd_idx && s.failed == 0)) |
2805 | set_bit(STRIPE_INSYNC, &sh->state); | 2823 | set_bit(STRIPE_INSYNC, &sh->state); |
@@ -4564,6 +4582,14 @@ static int raid5_remove_disk(mddev_t *mddev, int number) | |||
4564 | err = -EBUSY; | 4582 | err = -EBUSY; |
4565 | goto abort; | 4583 | goto abort; |
4566 | } | 4584 | } |
4585 | /* Only remove non-faulty devices if recovery | ||
4586 | * isn't possible. | ||
4587 | */ | ||
4588 | if (!test_bit(Faulty, &rdev->flags) && | ||
4589 | mddev->degraded <= conf->max_degraded) { | ||
4590 | err = -EBUSY; | ||
4591 | goto abort; | ||
4592 | } | ||
4567 | p->rdev = NULL; | 4593 | p->rdev = NULL; |
4568 | synchronize_rcu(); | 4594 | synchronize_rcu(); |
4569 | if (atomic_read(&rdev->nr_pending)) { | 4595 | if (atomic_read(&rdev->nr_pending)) { |
diff --git a/drivers/media/Makefile b/drivers/media/Makefile index cc11c4c0e7e7..09a829d8a7e7 100644 --- a/drivers/media/Makefile +++ b/drivers/media/Makefile | |||
@@ -2,12 +2,7 @@ | |||
2 | # Makefile for the kernel multimedia device drivers. | 2 | # Makefile for the kernel multimedia device drivers. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y := common/ | 5 | obj-y += common/ video/ |
6 | |||
7 | obj-$(CONFIG_VIDEO_MEDIA) += common/ | ||
8 | |||
9 | # Since hybrid devices are here, should be compiled if DVB and/or V4L | ||
10 | obj-$(CONFIG_VIDEO_MEDIA) += video/ | ||
11 | 6 | ||
12 | obj-$(CONFIG_VIDEO_DEV) += radio/ | 7 | obj-$(CONFIG_VIDEO_DEV) += radio/ |
13 | obj-$(CONFIG_DVB_CORE) += dvb/ | 8 | obj-$(CONFIG_DVB_CORE) += dvb/ |
diff --git a/drivers/media/common/tuners/Kconfig b/drivers/media/common/tuners/Kconfig index d6206540476b..85482960d012 100644 --- a/drivers/media/common/tuners/Kconfig +++ b/drivers/media/common/tuners/Kconfig | |||
@@ -21,6 +21,7 @@ config MEDIA_TUNER | |||
21 | tristate | 21 | tristate |
22 | default VIDEO_MEDIA && I2C | 22 | default VIDEO_MEDIA && I2C |
23 | depends on VIDEO_MEDIA && I2C | 23 | depends on VIDEO_MEDIA && I2C |
24 | select FW_LOADER if !MEDIA_TUNER_CUSTOMIZE && HOTPLUG | ||
24 | select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMIZE && HOTPLUG | 25 | select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMIZE && HOTPLUG |
25 | select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMIZE && HOTPLUG | 26 | select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMIZE && HOTPLUG |
26 | select MEDIA_TUNER_MT20XX if !MEDIA_TUNER_CUSTOMIZE | 27 | select MEDIA_TUNER_MT20XX if !MEDIA_TUNER_CUSTOMIZE |
diff --git a/drivers/media/common/tuners/mxl5005s.c b/drivers/media/common/tuners/mxl5005s.c index 5d05b5390f66..0dc2bef9f6a3 100644 --- a/drivers/media/common/tuners/mxl5005s.c +++ b/drivers/media/common/tuners/mxl5005s.c | |||
@@ -101,7 +101,7 @@ enum { | |||
101 | MXL_QAM, | 101 | MXL_QAM, |
102 | MXL_ANALOG_CABLE, | 102 | MXL_ANALOG_CABLE, |
103 | MXL_ANALOG_OTA | 103 | MXL_ANALOG_OTA |
104 | } tuner_modu_type; | 104 | }; |
105 | 105 | ||
106 | /* MXL5005 Tuner Register Struct */ | 106 | /* MXL5005 Tuner Register Struct */ |
107 | struct TunerReg { | 107 | struct TunerReg { |
@@ -194,7 +194,7 @@ enum { | |||
194 | RFSYN_DIVM, /* 88 */ | 194 | RFSYN_DIVM, /* 88 */ |
195 | DN_BYPASS_AGC_I2C /* 89 */ | 195 | DN_BYPASS_AGC_I2C /* 89 */ |
196 | #endif | 196 | #endif |
197 | } MXL5005_ControlName; | 197 | }; |
198 | 198 | ||
199 | /* | 199 | /* |
200 | * The following context is source code provided by MaxLinear. | 200 | * The following context is source code provided by MaxLinear. |
diff --git a/drivers/media/common/tuners/tda18271-common.c b/drivers/media/common/tuners/tda18271-common.c index 42b5f5d4bfe6..f1894fec32b9 100644 --- a/drivers/media/common/tuners/tda18271-common.c +++ b/drivers/media/common/tuners/tda18271-common.c | |||
@@ -648,11 +648,11 @@ int tda18271_calc_rf_cal(struct dvb_frontend *fe, u32 *freq) | |||
648 | unsigned char *regs = priv->tda18271_regs; | 648 | unsigned char *regs = priv->tda18271_regs; |
649 | u8 val; | 649 | u8 val; |
650 | 650 | ||
651 | tda18271_lookup_map(fe, RF_CAL, freq, &val); | 651 | int ret = tda18271_lookup_map(fe, RF_CAL, freq, &val); |
652 | 652 | ||
653 | regs[R_EB14] = val; | 653 | regs[R_EB14] = val; |
654 | 654 | ||
655 | return 0; | 655 | return ret; |
656 | } | 656 | } |
657 | 657 | ||
658 | /* | 658 | /* |
diff --git a/drivers/media/common/tuners/tda827x.c b/drivers/media/common/tuners/tda827x.c index d30d2c9094d9..8555d9cf9051 100644 --- a/drivers/media/common/tuners/tda827x.c +++ b/drivers/media/common/tuners/tda827x.c | |||
@@ -418,13 +418,13 @@ static void tda827xa_lna_gain(struct dvb_frontend *fe, int high, | |||
418 | unsigned char buf[] = {0x22, 0x01}; | 418 | unsigned char buf[] = {0x22, 0x01}; |
419 | int arg; | 419 | int arg; |
420 | int gp_func; | 420 | int gp_func; |
421 | struct i2c_msg msg = { .addr = priv->cfg->switch_addr, .flags = 0, | 421 | struct i2c_msg msg = { .flags = 0, .buf = buf, .len = sizeof(buf) }; |
422 | .buf = buf, .len = sizeof(buf) }; | ||
423 | 422 | ||
424 | if (NULL == priv->cfg) { | 423 | if (NULL == priv->cfg) { |
425 | dprintk("tda827x_config not defined, cannot set LNA gain!\n"); | 424 | dprintk("tda827x_config not defined, cannot set LNA gain!\n"); |
426 | return; | 425 | return; |
427 | } | 426 | } |
427 | msg.addr = priv->cfg->switch_addr; | ||
428 | if (priv->cfg->config) { | 428 | if (priv->cfg->config) { |
429 | if (high) | 429 | if (high) |
430 | dprintk("setting LNA to high gain\n"); | 430 | dprintk("setting LNA to high gain\n"); |
diff --git a/drivers/media/common/tuners/tea5761.c b/drivers/media/common/tuners/tea5761.c index b93cdef9ac73..b23dadeecd05 100644 --- a/drivers/media/common/tuners/tea5761.c +++ b/drivers/media/common/tuners/tea5761.c | |||
@@ -295,7 +295,7 @@ struct dvb_frontend *tea5761_attach(struct dvb_frontend *fe, | |||
295 | { | 295 | { |
296 | struct tea5761_priv *priv = NULL; | 296 | struct tea5761_priv *priv = NULL; |
297 | 297 | ||
298 | if (tea5761_autodetection(i2c_adap, i2c_addr) == EINVAL) | 298 | if (tea5761_autodetection(i2c_adap, i2c_addr) != 0) |
299 | return NULL; | 299 | return NULL; |
300 | 300 | ||
301 | priv = kzalloc(sizeof(struct tea5761_priv), GFP_KERNEL); | 301 | priv = kzalloc(sizeof(struct tea5761_priv), GFP_KERNEL); |
diff --git a/drivers/media/common/tuners/tuner-i2c.h b/drivers/media/common/tuners/tuner-i2c.h index 3ad6c8e0b04c..cb1c7141f0c6 100644 --- a/drivers/media/common/tuners/tuner-i2c.h +++ b/drivers/media/common/tuners/tuner-i2c.h | |||
@@ -170,4 +170,12 @@ __fail: \ | |||
170 | __ret; \ | 170 | __ret; \ |
171 | }) | 171 | }) |
172 | 172 | ||
173 | #define hybrid_tuner_report_instance_count(state) \ | ||
174 | ({ \ | ||
175 | int __ret = 0; \ | ||
176 | if (state) \ | ||
177 | __ret = state->i2c_props.count; \ | ||
178 | __ret; \ | ||
179 | }) | ||
180 | |||
173 | #endif /* __TUNER_I2C_H__ */ | 181 | #endif /* __TUNER_I2C_H__ */ |
diff --git a/drivers/media/common/tuners/tuner-simple.c b/drivers/media/common/tuners/tuner-simple.c index be8d903171b7..266c255cf0d8 100644 --- a/drivers/media/common/tuners/tuner-simple.c +++ b/drivers/media/common/tuners/tuner-simple.c | |||
@@ -1018,8 +1018,10 @@ struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe, | |||
1018 | fe->ops.i2c_gate_ctrl(fe, 1); | 1018 | fe->ops.i2c_gate_ctrl(fe, 1); |
1019 | 1019 | ||
1020 | if (1 != i2c_transfer(i2c_adap, &msg, 1)) | 1020 | if (1 != i2c_transfer(i2c_adap, &msg, 1)) |
1021 | tuner_warn("unable to probe %s, proceeding anyway.", | 1021 | printk(KERN_WARNING "tuner-simple %d-%04x: " |
1022 | tuners[type].name); | 1022 | "unable to probe %s, proceeding anyway.", |
1023 | i2c_adapter_id(i2c_adap), i2c_addr, | ||
1024 | tuners[type].name); | ||
1023 | 1025 | ||
1024 | if (fe->ops.i2c_gate_ctrl) | 1026 | if (fe->ops.i2c_gate_ctrl) |
1025 | fe->ops.i2c_gate_ctrl(fe, 0); | 1027 | fe->ops.i2c_gate_ctrl(fe, 0); |
diff --git a/drivers/media/common/tuners/tuner-xc2028.c b/drivers/media/common/tuners/tuner-xc2028.c index 9e9003cffc7f..0cbde17bfbb7 100644 --- a/drivers/media/common/tuners/tuner-xc2028.c +++ b/drivers/media/common/tuners/tuner-xc2028.c | |||
@@ -46,7 +46,7 @@ module_param_string(firmware_name, firmware_name, sizeof(firmware_name), 0); | |||
46 | MODULE_PARM_DESC(firmware_name, "Firmware file name. Allows overriding the " | 46 | MODULE_PARM_DESC(firmware_name, "Firmware file name. Allows overriding the " |
47 | "default firmware name\n"); | 47 | "default firmware name\n"); |
48 | 48 | ||
49 | static LIST_HEAD(xc2028_list); | 49 | static LIST_HEAD(hybrid_tuner_instance_list); |
50 | static DEFINE_MUTEX(xc2028_list_mutex); | 50 | static DEFINE_MUTEX(xc2028_list_mutex); |
51 | 51 | ||
52 | /* struct for storing firmware table */ | 52 | /* struct for storing firmware table */ |
@@ -68,12 +68,11 @@ struct firmware_properties { | |||
68 | }; | 68 | }; |
69 | 69 | ||
70 | struct xc2028_data { | 70 | struct xc2028_data { |
71 | struct list_head xc2028_list; | 71 | struct list_head hybrid_tuner_instance_list; |
72 | struct tuner_i2c_props i2c_props; | 72 | struct tuner_i2c_props i2c_props; |
73 | int (*tuner_callback) (void *dev, | 73 | int (*tuner_callback) (void *dev, |
74 | int command, int arg); | 74 | int command, int arg); |
75 | void *video_dev; | 75 | void *video_dev; |
76 | int count; | ||
77 | __u32 frequency; | 76 | __u32 frequency; |
78 | 77 | ||
79 | struct firmware_description *firm; | 78 | struct firmware_description *firm; |
@@ -1072,20 +1071,19 @@ static int xc2028_dvb_release(struct dvb_frontend *fe) | |||
1072 | 1071 | ||
1073 | mutex_lock(&xc2028_list_mutex); | 1072 | mutex_lock(&xc2028_list_mutex); |
1074 | 1073 | ||
1075 | priv->count--; | 1074 | /* only perform final cleanup if this is the last instance */ |
1076 | 1075 | if (hybrid_tuner_report_instance_count(priv) == 1) { | |
1077 | if (!priv->count) { | ||
1078 | list_del(&priv->xc2028_list); | ||
1079 | |||
1080 | kfree(priv->ctrl.fname); | 1076 | kfree(priv->ctrl.fname); |
1081 | |||
1082 | free_firmware(priv); | 1077 | free_firmware(priv); |
1083 | kfree(priv); | ||
1084 | fe->tuner_priv = NULL; | ||
1085 | } | 1078 | } |
1086 | 1079 | ||
1080 | if (priv) | ||
1081 | hybrid_tuner_release_state(priv); | ||
1082 | |||
1087 | mutex_unlock(&xc2028_list_mutex); | 1083 | mutex_unlock(&xc2028_list_mutex); |
1088 | 1084 | ||
1085 | fe->tuner_priv = NULL; | ||
1086 | |||
1089 | return 0; | 1087 | return 0; |
1090 | } | 1088 | } |
1091 | 1089 | ||
@@ -1150,7 +1148,7 @@ struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe, | |||
1150 | struct xc2028_config *cfg) | 1148 | struct xc2028_config *cfg) |
1151 | { | 1149 | { |
1152 | struct xc2028_data *priv; | 1150 | struct xc2028_data *priv; |
1153 | void *video_dev; | 1151 | int instance; |
1154 | 1152 | ||
1155 | if (debug) | 1153 | if (debug) |
1156 | printk(KERN_DEBUG "xc2028: Xcv2028/3028 init called!\n"); | 1154 | printk(KERN_DEBUG "xc2028: Xcv2028/3028 init called!\n"); |
@@ -1163,48 +1161,40 @@ struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe, | |||
1163 | return NULL; | 1161 | return NULL; |
1164 | } | 1162 | } |
1165 | 1163 | ||
1166 | video_dev = cfg->i2c_adap->algo_data; | ||
1167 | |||
1168 | if (debug) | ||
1169 | printk(KERN_DEBUG "xc2028: video_dev =%p\n", video_dev); | ||
1170 | |||
1171 | mutex_lock(&xc2028_list_mutex); | 1164 | mutex_lock(&xc2028_list_mutex); |
1172 | 1165 | ||
1173 | list_for_each_entry(priv, &xc2028_list, xc2028_list) { | 1166 | instance = hybrid_tuner_request_state(struct xc2028_data, priv, |
1174 | if (&priv->i2c_props.adap->dev == &cfg->i2c_adap->dev) { | 1167 | hybrid_tuner_instance_list, |
1175 | video_dev = NULL; | 1168 | cfg->i2c_adap, cfg->i2c_addr, |
1176 | if (debug) | 1169 | "xc2028"); |
1177 | printk(KERN_DEBUG "xc2028: reusing device\n"); | 1170 | switch (instance) { |
1178 | 1171 | case 0: | |
1179 | break; | 1172 | /* memory allocation failure */ |
1180 | } | 1173 | goto fail; |
1181 | } | 1174 | break; |
1182 | 1175 | case 1: | |
1183 | if (video_dev) { | 1176 | /* new tuner instance */ |
1184 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | ||
1185 | if (priv == NULL) { | ||
1186 | mutex_unlock(&xc2028_list_mutex); | ||
1187 | return NULL; | ||
1188 | } | ||
1189 | |||
1190 | priv->i2c_props.addr = cfg->i2c_addr; | ||
1191 | priv->i2c_props.adap = cfg->i2c_adap; | ||
1192 | priv->i2c_props.name = "xc2028"; | ||
1193 | |||
1194 | priv->video_dev = video_dev; | ||
1195 | priv->tuner_callback = cfg->callback; | 1177 | priv->tuner_callback = cfg->callback; |
1196 | priv->ctrl.max_len = 13; | 1178 | priv->ctrl.max_len = 13; |
1197 | 1179 | ||
1198 | mutex_init(&priv->lock); | 1180 | mutex_init(&priv->lock); |
1199 | 1181 | ||
1200 | list_add_tail(&priv->xc2028_list, &xc2028_list); | 1182 | /* analog side (tuner-core) uses i2c_adap->algo_data. |
1201 | } | 1183 | * digital side is not guaranteed to have algo_data defined. |
1202 | 1184 | * | |
1203 | fe->tuner_priv = priv; | 1185 | * digital side will always have fe->dvb defined. |
1204 | priv->count++; | 1186 | * analog side (tuner-core) doesn't (yet) define fe->dvb. |
1187 | */ | ||
1188 | priv->video_dev = ((fe->dvb) && (fe->dvb->priv)) ? | ||
1189 | fe->dvb->priv : cfg->i2c_adap->algo_data; | ||
1205 | 1190 | ||
1206 | if (debug) | 1191 | fe->tuner_priv = priv; |
1207 | printk(KERN_DEBUG "xc2028: usage count is %i\n", priv->count); | 1192 | break; |
1193 | case 2: | ||
1194 | /* existing tuner instance */ | ||
1195 | fe->tuner_priv = priv; | ||
1196 | break; | ||
1197 | } | ||
1208 | 1198 | ||
1209 | memcpy(&fe->ops.tuner_ops, &xc2028_dvb_tuner_ops, | 1199 | memcpy(&fe->ops.tuner_ops, &xc2028_dvb_tuner_ops, |
1210 | sizeof(xc2028_dvb_tuner_ops)); | 1200 | sizeof(xc2028_dvb_tuner_ops)); |
@@ -1217,6 +1207,11 @@ struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe, | |||
1217 | mutex_unlock(&xc2028_list_mutex); | 1207 | mutex_unlock(&xc2028_list_mutex); |
1218 | 1208 | ||
1219 | return fe; | 1209 | return fe; |
1210 | fail: | ||
1211 | mutex_unlock(&xc2028_list_mutex); | ||
1212 | |||
1213 | xc2028_dvb_release(fe); | ||
1214 | return NULL; | ||
1220 | } | 1215 | } |
1221 | 1216 | ||
1222 | EXPORT_SYMBOL(xc2028_attach); | 1217 | EXPORT_SYMBOL(xc2028_attach); |
diff --git a/drivers/media/dvb/b2c2/flexcop-usb.c b/drivers/media/dvb/b2c2/flexcop-usb.c index 449fb5c3d0b1..ae0d76a5d51d 100644 --- a/drivers/media/dvb/b2c2/flexcop-usb.c +++ b/drivers/media/dvb/b2c2/flexcop-usb.c | |||
@@ -379,7 +379,7 @@ static void flexcop_usb_transfer_exit(struct flexcop_usb *fc_usb) | |||
379 | 379 | ||
380 | static int flexcop_usb_transfer_init(struct flexcop_usb *fc_usb) | 380 | static int flexcop_usb_transfer_init(struct flexcop_usb *fc_usb) |
381 | { | 381 | { |
382 | u16 frame_size = fc_usb->uintf->cur_altsetting->endpoint[0].desc.wMaxPacketSize; | 382 | u16 frame_size = le16_to_cpu(fc_usb->uintf->cur_altsetting->endpoint[0].desc.wMaxPacketSize); |
383 | int bufsize = B2C2_USB_NUM_ISO_URB * B2C2_USB_FRAMES_PER_ISO * frame_size,i,j,ret; | 383 | int bufsize = B2C2_USB_NUM_ISO_URB * B2C2_USB_FRAMES_PER_ISO * frame_size,i,j,ret; |
384 | int buffer_offset = 0; | 384 | int buffer_offset = 0; |
385 | 385 | ||
diff --git a/drivers/media/dvb/cinergyT2/cinergyT2.c b/drivers/media/dvb/cinergyT2/cinergyT2.c index f5010e8671b8..a824f3719f81 100644 --- a/drivers/media/dvb/cinergyT2/cinergyT2.c +++ b/drivers/media/dvb/cinergyT2/cinergyT2.c | |||
@@ -82,22 +82,22 @@ enum cinergyt2_ep1_cmd { | |||
82 | 82 | ||
83 | struct dvbt_set_parameters_msg { | 83 | struct dvbt_set_parameters_msg { |
84 | uint8_t cmd; | 84 | uint8_t cmd; |
85 | uint32_t freq; | 85 | __le32 freq; |
86 | uint8_t bandwidth; | 86 | uint8_t bandwidth; |
87 | uint16_t tps; | 87 | __le16 tps; |
88 | uint8_t flags; | 88 | uint8_t flags; |
89 | } __attribute__((packed)); | 89 | } __attribute__((packed)); |
90 | 90 | ||
91 | struct dvbt_get_status_msg { | 91 | struct dvbt_get_status_msg { |
92 | uint32_t freq; | 92 | __le32 freq; |
93 | uint8_t bandwidth; | 93 | uint8_t bandwidth; |
94 | uint16_t tps; | 94 | __le16 tps; |
95 | uint8_t flags; | 95 | uint8_t flags; |
96 | uint16_t gain; | 96 | __le16 gain; |
97 | uint8_t snr; | 97 | uint8_t snr; |
98 | uint32_t viterbi_error_rate; | 98 | __le32 viterbi_error_rate; |
99 | uint32_t rs_error_rate; | 99 | __le32 rs_error_rate; |
100 | uint32_t uncorrected_block_count; | 100 | __le32 uncorrected_block_count; |
101 | uint8_t lock_bits; | 101 | uint8_t lock_bits; |
102 | uint8_t prev_lock_bits; | 102 | uint8_t prev_lock_bits; |
103 | } __attribute__((packed)); | 103 | } __attribute__((packed)); |
@@ -136,6 +136,7 @@ struct cinergyt2 { | |||
136 | wait_queue_head_t poll_wq; | 136 | wait_queue_head_t poll_wq; |
137 | int pending_fe_events; | 137 | int pending_fe_events; |
138 | int disconnect_pending; | 138 | int disconnect_pending; |
139 | unsigned int uncorrected_block_count; | ||
139 | atomic_t inuse; | 140 | atomic_t inuse; |
140 | 141 | ||
141 | void *streambuf; | 142 | void *streambuf; |
@@ -147,7 +148,7 @@ struct cinergyt2 { | |||
147 | char phys[64]; | 148 | char phys[64]; |
148 | struct delayed_work rc_query_work; | 149 | struct delayed_work rc_query_work; |
149 | int rc_input_event; | 150 | int rc_input_event; |
150 | u32 rc_last_code; | 151 | __le32 rc_last_code; |
151 | unsigned long last_event_jiffies; | 152 | unsigned long last_event_jiffies; |
152 | #endif | 153 | #endif |
153 | }; | 154 | }; |
@@ -160,7 +161,7 @@ enum { | |||
160 | 161 | ||
161 | struct cinergyt2_rc_event { | 162 | struct cinergyt2_rc_event { |
162 | char type; | 163 | char type; |
163 | uint32_t value; | 164 | __le32 value; |
164 | } __attribute__((packed)); | 165 | } __attribute__((packed)); |
165 | 166 | ||
166 | static const uint32_t rc_keys[] = { | 167 | static const uint32_t rc_keys[] = { |
@@ -619,8 +620,11 @@ static int cinergyt2_ioctl (struct inode *inode, struct file *file, | |||
619 | { | 620 | { |
620 | uint32_t unc_count; | 621 | uint32_t unc_count; |
621 | 622 | ||
622 | unc_count = stat->uncorrected_block_count; | 623 | if (mutex_lock_interruptible(&cinergyt2->sem)) |
623 | stat->uncorrected_block_count = 0; | 624 | return -ERESTARTSYS; |
625 | unc_count = cinergyt2->uncorrected_block_count; | ||
626 | cinergyt2->uncorrected_block_count = 0; | ||
627 | mutex_unlock(&cinergyt2->sem); | ||
624 | 628 | ||
625 | /* UNC are already converted to host byte order... */ | 629 | /* UNC are already converted to host byte order... */ |
626 | return put_user(unc_count,(__u32 __user *) arg); | 630 | return put_user(unc_count,(__u32 __user *) arg); |
@@ -769,7 +773,7 @@ static void cinergyt2_query_rc (struct work_struct *work) | |||
769 | input_sync(cinergyt2->rc_input_dev); | 773 | input_sync(cinergyt2->rc_input_dev); |
770 | cinergyt2->rc_input_event = KEY_MAX; | 774 | cinergyt2->rc_input_event = KEY_MAX; |
771 | } | 775 | } |
772 | cinergyt2->rc_last_code = ~0; | 776 | cinergyt2->rc_last_code = cpu_to_le32(~0); |
773 | } | 777 | } |
774 | goto out; | 778 | goto out; |
775 | } | 779 | } |
@@ -780,7 +784,7 @@ static void cinergyt2_query_rc (struct work_struct *work) | |||
780 | n, le32_to_cpu(rc_events[n].value), rc_events[n].type); | 784 | n, le32_to_cpu(rc_events[n].value), rc_events[n].type); |
781 | 785 | ||
782 | if (rc_events[n].type == CINERGYT2_RC_EVENT_TYPE_NEC && | 786 | if (rc_events[n].type == CINERGYT2_RC_EVENT_TYPE_NEC && |
783 | rc_events[n].value == ~0) { | 787 | rc_events[n].value == cpu_to_le32(~0)) { |
784 | /* keyrepeat bit -> just repeat last rc_input_event */ | 788 | /* keyrepeat bit -> just repeat last rc_input_event */ |
785 | } else { | 789 | } else { |
786 | cinergyt2->rc_input_event = KEY_MAX; | 790 | cinergyt2->rc_input_event = KEY_MAX; |
@@ -795,7 +799,7 @@ static void cinergyt2_query_rc (struct work_struct *work) | |||
795 | 799 | ||
796 | if (cinergyt2->rc_input_event != KEY_MAX) { | 800 | if (cinergyt2->rc_input_event != KEY_MAX) { |
797 | if (rc_events[n].value == cinergyt2->rc_last_code && | 801 | if (rc_events[n].value == cinergyt2->rc_last_code && |
798 | cinergyt2->rc_last_code != ~0) { | 802 | cinergyt2->rc_last_code != cpu_to_le32(~0)) { |
799 | /* emit a key-up so the double event is recognized */ | 803 | /* emit a key-up so the double event is recognized */ |
800 | dprintk(1, "rc_input_event=%d UP\n", cinergyt2->rc_input_event); | 804 | dprintk(1, "rc_input_event=%d UP\n", cinergyt2->rc_input_event); |
801 | input_report_key(cinergyt2->rc_input_dev, | 805 | input_report_key(cinergyt2->rc_input_dev, |
@@ -829,7 +833,7 @@ static int cinergyt2_register_rc(struct cinergyt2 *cinergyt2) | |||
829 | usb_make_path(cinergyt2->udev, cinergyt2->phys, sizeof(cinergyt2->phys)); | 833 | usb_make_path(cinergyt2->udev, cinergyt2->phys, sizeof(cinergyt2->phys)); |
830 | strlcat(cinergyt2->phys, "/input0", sizeof(cinergyt2->phys)); | 834 | strlcat(cinergyt2->phys, "/input0", sizeof(cinergyt2->phys)); |
831 | cinergyt2->rc_input_event = KEY_MAX; | 835 | cinergyt2->rc_input_event = KEY_MAX; |
832 | cinergyt2->rc_last_code = ~0; | 836 | cinergyt2->rc_last_code = cpu_to_le32(~0); |
833 | INIT_DELAYED_WORK(&cinergyt2->rc_query_work, cinergyt2_query_rc); | 837 | INIT_DELAYED_WORK(&cinergyt2->rc_query_work, cinergyt2_query_rc); |
834 | 838 | ||
835 | input_dev->name = DRIVER_NAME " remote control"; | 839 | input_dev->name = DRIVER_NAME " remote control"; |
@@ -840,8 +844,8 @@ static int cinergyt2_register_rc(struct cinergyt2 *cinergyt2) | |||
840 | input_dev->keycodesize = 0; | 844 | input_dev->keycodesize = 0; |
841 | input_dev->keycodemax = 0; | 845 | input_dev->keycodemax = 0; |
842 | input_dev->id.bustype = BUS_USB; | 846 | input_dev->id.bustype = BUS_USB; |
843 | input_dev->id.vendor = cinergyt2->udev->descriptor.idVendor; | 847 | input_dev->id.vendor = le16_to_cpu(cinergyt2->udev->descriptor.idVendor); |
844 | input_dev->id.product = cinergyt2->udev->descriptor.idProduct; | 848 | input_dev->id.product = le16_to_cpu(cinergyt2->udev->descriptor.idProduct); |
845 | input_dev->id.version = 1; | 849 | input_dev->id.version = 1; |
846 | input_dev->dev.parent = &cinergyt2->udev->dev; | 850 | input_dev->dev.parent = &cinergyt2->udev->dev; |
847 | 851 | ||
@@ -889,18 +893,16 @@ static void cinergyt2_query (struct work_struct *work) | |||
889 | char cmd [] = { CINERGYT2_EP1_GET_TUNER_STATUS }; | 893 | char cmd [] = { CINERGYT2_EP1_GET_TUNER_STATUS }; |
890 | struct dvbt_get_status_msg *s = &cinergyt2->status; | 894 | struct dvbt_get_status_msg *s = &cinergyt2->status; |
891 | uint8_t lock_bits; | 895 | uint8_t lock_bits; |
892 | uint32_t unc; | ||
893 | 896 | ||
894 | if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem)) | 897 | if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem)) |
895 | return; | 898 | return; |
896 | 899 | ||
897 | unc = s->uncorrected_block_count; | ||
898 | lock_bits = s->lock_bits; | 900 | lock_bits = s->lock_bits; |
899 | 901 | ||
900 | cinergyt2_command(cinergyt2, cmd, sizeof(cmd), (char *) s, sizeof(*s)); | 902 | cinergyt2_command(cinergyt2, cmd, sizeof(cmd), (char *) s, sizeof(*s)); |
901 | 903 | ||
902 | unc += le32_to_cpu(s->uncorrected_block_count); | 904 | cinergyt2->uncorrected_block_count += |
903 | s->uncorrected_block_count = unc; | 905 | le32_to_cpu(s->uncorrected_block_count); |
904 | 906 | ||
905 | if (lock_bits != s->lock_bits) { | 907 | if (lock_bits != s->lock_bits) { |
906 | wake_up_interruptible(&cinergyt2->poll_wq); | 908 | wake_up_interruptible(&cinergyt2->poll_wq); |
diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c index 56d871cfd7fc..c2334aef4143 100644 --- a/drivers/media/dvb/dvb-core/dvb_net.c +++ b/drivers/media/dvb/dvb-core/dvb_net.c | |||
@@ -168,7 +168,7 @@ struct dvb_net_priv { | |||
168 | * stolen from eth.c out of the linux kernel, hacked for dvb-device | 168 | * stolen from eth.c out of the linux kernel, hacked for dvb-device |
169 | * by Michael Holzt <kju@debian.org> | 169 | * by Michael Holzt <kju@debian.org> |
170 | */ | 170 | */ |
171 | static unsigned short dvb_net_eth_type_trans(struct sk_buff *skb, | 171 | static __be16 dvb_net_eth_type_trans(struct sk_buff *skb, |
172 | struct net_device *dev) | 172 | struct net_device *dev) |
173 | { | 173 | { |
174 | struct ethhdr *eth; | 174 | struct ethhdr *eth; |
@@ -277,10 +277,10 @@ static int handle_one_ule_extension( struct dvb_net_priv *p ) | |||
277 | if(ext_len >= 0) { | 277 | if(ext_len >= 0) { |
278 | p->ule_next_hdr += ext_len; | 278 | p->ule_next_hdr += ext_len; |
279 | if (!p->ule_bridged) { | 279 | if (!p->ule_bridged) { |
280 | p->ule_sndu_type = ntohs(*(unsigned short *)p->ule_next_hdr); | 280 | p->ule_sndu_type = ntohs(*(__be16 *)p->ule_next_hdr); |
281 | p->ule_next_hdr += 2; | 281 | p->ule_next_hdr += 2; |
282 | } else { | 282 | } else { |
283 | p->ule_sndu_type = ntohs(*(unsigned short *)(p->ule_next_hdr + ((p->ule_dbit ? 2 : 3) * ETH_ALEN))); | 283 | p->ule_sndu_type = ntohs(*(__be16 *)(p->ule_next_hdr + ((p->ule_dbit ? 2 : 3) * ETH_ALEN))); |
284 | /* This assures the extension handling loop will terminate. */ | 284 | /* This assures the extension handling loop will terminate. */ |
285 | } | 285 | } |
286 | } | 286 | } |
@@ -294,7 +294,7 @@ static int handle_one_ule_extension( struct dvb_net_priv *p ) | |||
294 | if (ule_optional_ext_handlers[htype]) | 294 | if (ule_optional_ext_handlers[htype]) |
295 | (void)ule_optional_ext_handlers[htype]( p ); | 295 | (void)ule_optional_ext_handlers[htype]( p ); |
296 | p->ule_next_hdr += ext_len; | 296 | p->ule_next_hdr += ext_len; |
297 | p->ule_sndu_type = ntohs( *(unsigned short *)(p->ule_next_hdr-2) ); | 297 | p->ule_sndu_type = ntohs( *(__be16 *)(p->ule_next_hdr-2) ); |
298 | /* | 298 | /* |
299 | * note: the length of the next header type is included in the | 299 | * note: the length of the next header type is included in the |
300 | * length of THIS optional extension header | 300 | * length of THIS optional extension header |
@@ -594,8 +594,8 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) | |||
594 | /* Check for complete payload. */ | 594 | /* Check for complete payload. */ |
595 | if (priv->ule_sndu_remain <= 0) { | 595 | if (priv->ule_sndu_remain <= 0) { |
596 | /* Check CRC32, we've got it in our skb already. */ | 596 | /* Check CRC32, we've got it in our skb already. */ |
597 | unsigned short ulen = htons(priv->ule_sndu_len); | 597 | __be16 ulen = htons(priv->ule_sndu_len); |
598 | unsigned short utype = htons(priv->ule_sndu_type); | 598 | __be16 utype = htons(priv->ule_sndu_type); |
599 | const u8 *tail; | 599 | const u8 *tail; |
600 | struct kvec iov[3] = { | 600 | struct kvec iov[3] = { |
601 | { &ulen, sizeof ulen }, | 601 | { &ulen, sizeof ulen }, |
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index cf4584e48b6d..f00a0eb40420 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config DVB_USB | 1 | config DVB_USB |
2 | tristate "Support for various USB DVB devices" | 2 | tristate "Support for various USB DVB devices" |
3 | depends on DVB_CORE && USB && I2C | 3 | depends on DVB_CORE && USB && I2C && INPUT |
4 | depends on HOTPLUG # due to FW_LOADER | 4 | depends on HOTPLUG # due to FW_LOADER |
5 | select FW_LOADER | 5 | select FW_LOADER |
6 | help | 6 | help |
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index 346223856f59..c4d40fe01d57 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c | |||
@@ -111,8 +111,8 @@ static int bristol_tuner_attach(struct dvb_usb_adapter *adap) | |||
111 | struct i2c_adapter *tun_i2c = dib3000mc_get_tuner_i2c_master(adap->fe, 1); | 111 | struct i2c_adapter *tun_i2c = dib3000mc_get_tuner_i2c_master(adap->fe, 1); |
112 | s8 a; | 112 | s8 a; |
113 | int if1=1220; | 113 | int if1=1220; |
114 | if (adap->dev->udev->descriptor.idVendor == USB_VID_HAUPPAUGE && | 114 | if (adap->dev->udev->descriptor.idVendor == cpu_to_le16(USB_VID_HAUPPAUGE) && |
115 | adap->dev->udev->descriptor.idProduct == USB_PID_HAUPPAUGE_NOVA_T_500_2) { | 115 | adap->dev->udev->descriptor.idProduct == cpu_to_le16(USB_PID_HAUPPAUGE_NOVA_T_500_2)) { |
116 | if (!eeprom_read(prim_i2c,0x59 + adap->id,&a)) if1=1220+a; | 116 | if (!eeprom_read(prim_i2c,0x59 + adap->id,&a)) if1=1220+a; |
117 | } | 117 | } |
118 | return dvb_attach(mt2060_attach,adap->fe, tun_i2c,&bristol_mt2060_config[adap->id], | 118 | return dvb_attach(mt2060_attach,adap->fe, tun_i2c,&bristol_mt2060_config[adap->id], |
@@ -402,8 +402,8 @@ static int stk7700ph_frontend_attach(struct dvb_usb_adapter *adap) | |||
402 | { | 402 | { |
403 | struct usb_device_descriptor *desc = &adap->dev->udev->descriptor; | 403 | struct usb_device_descriptor *desc = &adap->dev->udev->descriptor; |
404 | 404 | ||
405 | if (desc->idVendor == USB_VID_PINNACLE && | 405 | if (desc->idVendor == cpu_to_le16(USB_VID_PINNACLE) && |
406 | desc->idProduct == USB_PID_PINNACLE_EXPRESSCARD_320CX) | 406 | desc->idProduct == cpu_to_le16(USB_PID_PINNACLE_EXPRESSCARD_320CX)) |
407 | dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); | 407 | dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); |
408 | else | 408 | else |
409 | dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); | 409 | dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); |
@@ -845,8 +845,8 @@ static int stk7700p_tuner_attach(struct dvb_usb_adapter *adap) | |||
845 | struct i2c_adapter *tun_i2c; | 845 | struct i2c_adapter *tun_i2c; |
846 | s8 a; | 846 | s8 a; |
847 | int if1=1220; | 847 | int if1=1220; |
848 | if (adap->dev->udev->descriptor.idVendor == USB_VID_HAUPPAUGE && | 848 | if (adap->dev->udev->descriptor.idVendor == cpu_to_le16(USB_VID_HAUPPAUGE) && |
849 | adap->dev->udev->descriptor.idProduct == USB_PID_HAUPPAUGE_NOVA_T_STICK) { | 849 | adap->dev->udev->descriptor.idProduct == cpu_to_le16(USB_PID_HAUPPAUGE_NOVA_T_STICK)) { |
850 | if (!eeprom_read(prim_i2c,0x58,&a)) if1=1220+a; | 850 | if (!eeprom_read(prim_i2c,0x58,&a)) if1=1220+a; |
851 | } | 851 | } |
852 | if (st->is_dib7000pc) | 852 | if (st->is_dib7000pc) |
@@ -990,11 +990,12 @@ static struct dib7000p_config dib7070p_dib7000p_config = { | |||
990 | /* STK7070P */ | 990 | /* STK7070P */ |
991 | static int stk7070p_frontend_attach(struct dvb_usb_adapter *adap) | 991 | static int stk7070p_frontend_attach(struct dvb_usb_adapter *adap) |
992 | { | 992 | { |
993 | if (adap->dev->udev->descriptor.idVendor == USB_VID_PINNACLE && | 993 | struct usb_device_descriptor *p = &adap->dev->udev->descriptor; |
994 | adap->dev->udev->descriptor.idProduct == USB_PID_PINNACLE_PCTV72E) | 994 | if (p->idVendor == cpu_to_le16(USB_VID_PINNACLE) && |
995 | dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); | 995 | p->idProduct == cpu_to_le16(USB_PID_PINNACLE_PCTV72E)) |
996 | dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); | ||
996 | else | 997 | else |
997 | dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); | 998 | dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); |
998 | msleep(10); | 999 | msleep(10); |
999 | dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); | 1000 | dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); |
1000 | dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1); | 1001 | dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1); |
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c b/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c index e1112e39fb63..733a7ff7b207 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c | |||
@@ -127,7 +127,7 @@ int dvb_usb_get_hexline(const struct firmware *fw, struct hexline *hx, | |||
127 | if ((*pos + hx->len + 4) >= fw->size) | 127 | if ((*pos + hx->len + 4) >= fw->size) |
128 | return -EINVAL; | 128 | return -EINVAL; |
129 | 129 | ||
130 | hx->addr = le16_to_cpu( *((u16 *) &b[1]) ); | 130 | hx->addr = b[1] | (b[2] << 8); |
131 | hx->type = b[3]; | 131 | hx->type = b[3]; |
132 | 132 | ||
133 | if (hx->type == 0x04) { | 133 | if (hx->type == 0x04) { |
diff --git a/drivers/media/dvb/dvb-usb/gp8psk.c b/drivers/media/dvb/dvb-usb/gp8psk.c index 9a942afaf0af..2653120673b7 100644 --- a/drivers/media/dvb/dvb-usb/gp8psk.c +++ b/drivers/media/dvb/dvb-usb/gp8psk.c | |||
@@ -146,24 +146,24 @@ static int gp8psk_power_ctrl(struct dvb_usb_device *d, int onoff) | |||
146 | if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM) | 146 | if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM) |
147 | if (! (status & bm8pskFW_Loaded)) /* BCM4500 firmware loaded */ | 147 | if (! (status & bm8pskFW_Loaded)) /* BCM4500 firmware loaded */ |
148 | if(gp8psk_load_bcm4500fw(d)) | 148 | if(gp8psk_load_bcm4500fw(d)) |
149 | return EINVAL; | 149 | return -EINVAL; |
150 | 150 | ||
151 | if (! (status & bmIntersilOn)) /* LNB Power */ | 151 | if (! (status & bmIntersilOn)) /* LNB Power */ |
152 | if (gp8psk_usb_in_op(d, START_INTERSIL, 1, 0, | 152 | if (gp8psk_usb_in_op(d, START_INTERSIL, 1, 0, |
153 | &buf, 1)) | 153 | &buf, 1)) |
154 | return EINVAL; | 154 | return -EINVAL; |
155 | 155 | ||
156 | /* Set DVB mode to 1 */ | 156 | /* Set DVB mode to 1 */ |
157 | if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM) | 157 | if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM) |
158 | if (gp8psk_usb_out_op(d, SET_DVB_MODE, 1, 0, NULL, 0)) | 158 | if (gp8psk_usb_out_op(d, SET_DVB_MODE, 1, 0, NULL, 0)) |
159 | return EINVAL; | 159 | return -EINVAL; |
160 | /* Abort possible TS (if previous tune crashed) */ | 160 | /* Abort possible TS (if previous tune crashed) */ |
161 | if (gp8psk_usb_out_op(d, ARM_TRANSFER, 0, 0, NULL, 0)) | 161 | if (gp8psk_usb_out_op(d, ARM_TRANSFER, 0, 0, NULL, 0)) |
162 | return EINVAL; | 162 | return -EINVAL; |
163 | } else { | 163 | } else { |
164 | /* Turn off LNB power */ | 164 | /* Turn off LNB power */ |
165 | if (gp8psk_usb_in_op(d, START_INTERSIL, 0, 0, &buf, 1)) | 165 | if (gp8psk_usb_in_op(d, START_INTERSIL, 0, 0, &buf, 1)) |
166 | return EINVAL; | 166 | return -EINVAL; |
167 | /* Turn off 8psk power */ | 167 | /* Turn off 8psk power */ |
168 | if (gp8psk_usb_in_op(d, BOOT_8PSK, 0, 0, &buf, 1)) | 168 | if (gp8psk_usb_in_op(d, BOOT_8PSK, 0, 0, &buf, 1)) |
169 | return -EINVAL; | 169 | return -EINVAL; |
diff --git a/drivers/media/dvb/dvb-usb/m920x.c b/drivers/media/dvb/dvb-usb/m920x.c index a12e6f784fda..54626a0dbf68 100644 --- a/drivers/media/dvb/dvb-usb/m920x.c +++ b/drivers/media/dvb/dvb-usb/m920x.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include "qt1010.h" | 16 | #include "qt1010.h" |
17 | #include "tda1004x.h" | 17 | #include "tda1004x.h" |
18 | #include "tda827x.h" | 18 | #include "tda827x.h" |
19 | #include <asm/unaligned.h> | ||
19 | 20 | ||
20 | /* debug */ | 21 | /* debug */ |
21 | static int dvb_usb_m920x_debug; | 22 | static int dvb_usb_m920x_debug; |
@@ -347,13 +348,13 @@ static int m920x_firmware_download(struct usb_device *udev, const struct firmwar | |||
347 | 348 | ||
348 | for (pass = 0; pass < 2; pass++) { | 349 | for (pass = 0; pass < 2; pass++) { |
349 | for (i = 0; i + (sizeof(u16) * 3) < fw->size;) { | 350 | for (i = 0; i + (sizeof(u16) * 3) < fw->size;) { |
350 | value = le16_to_cpu(*(u16 *)(fw->data + i)); | 351 | value = get_unaligned_le16(fw->data + i); |
351 | i += sizeof(u16); | 352 | i += sizeof(u16); |
352 | 353 | ||
353 | index = le16_to_cpu(*(u16 *)(fw->data + i)); | 354 | index = get_unaligned_le16(fw->data + i); |
354 | i += sizeof(u16); | 355 | i += sizeof(u16); |
355 | 356 | ||
356 | size = le16_to_cpu(*(u16 *)(fw->data + i)); | 357 | size = get_unaligned_le16(fw->data + i); |
357 | i += sizeof(u16); | 358 | i += sizeof(u16); |
358 | 359 | ||
359 | if (pass == 1) { | 360 | if (pass == 1) { |
diff --git a/drivers/media/dvb/frontends/dib0070.h b/drivers/media/dvb/frontends/dib0070.h index 786e37d33889..3eedfdf505bc 100644 --- a/drivers/media/dvb/frontends/dib0070.h +++ b/drivers/media/dvb/frontends/dib0070.h | |||
@@ -37,7 +37,20 @@ struct dib0070_config { | |||
37 | u8 flip_chip; | 37 | u8 flip_chip; |
38 | }; | 38 | }; |
39 | 39 | ||
40 | extern struct dvb_frontend * dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg); | 40 | #if defined(CONFIG_DVB_TUNER_DIB0070) || (defined(CONFIG_DVB_TUNER_DIB0070_MODULE) && defined(MODULE)) |
41 | extern struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, | ||
42 | struct i2c_adapter *i2c, | ||
43 | struct dib0070_config *cfg); | ||
44 | #else | ||
45 | static inline struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, | ||
46 | struct i2c_adapter *i2c, | ||
47 | struct dib0070_config *cfg) | ||
48 | { | ||
49 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||
50 | return NULL; | ||
51 | } | ||
52 | #endif | ||
53 | |||
41 | extern void dib0070_ctrl_agc_filter(struct dvb_frontend *, uint8_t open); | 54 | extern void dib0070_ctrl_agc_filter(struct dvb_frontend *, uint8_t open); |
42 | extern u16 dib0070_wbd_offset(struct dvb_frontend *); | 55 | extern u16 dib0070_wbd_offset(struct dvb_frontend *); |
43 | 56 | ||
diff --git a/drivers/media/dvb/frontends/dib7000p.h b/drivers/media/dvb/frontends/dib7000p.h index 081bd81f3da2..07c4d12ed5b7 100644 --- a/drivers/media/dvb/frontends/dib7000p.h +++ b/drivers/media/dvb/frontends/dib7000p.h | |||
@@ -37,7 +37,20 @@ struct dib7000p_config { | |||
37 | 37 | ||
38 | #define DEFAULT_DIB7000P_I2C_ADDRESS 18 | 38 | #define DEFAULT_DIB7000P_I2C_ADDRESS 18 |
39 | 39 | ||
40 | extern struct dvb_frontend * dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg); | 40 | #if defined(CONFIG_DVB_DIB7000P) || (defined(CONFIG_DVB_DIB7000P_MODULE) && defined(MODULE)) |
41 | extern struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, | ||
42 | u8 i2c_addr, | ||
43 | struct dib7000p_config *cfg); | ||
44 | #else | ||
45 | static inline struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, | ||
46 | u8 i2c_addr, | ||
47 | struct dib7000p_config *cfg) | ||
48 | { | ||
49 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||
50 | return NULL; | ||
51 | } | ||
52 | #endif | ||
53 | |||
41 | extern int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[]); | 54 | extern int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[]); |
42 | 55 | ||
43 | extern struct i2c_adapter * dib7000p_get_i2c_master(struct dvb_frontend *, enum dibx000_i2c_interface, int); | 56 | extern struct i2c_adapter * dib7000p_get_i2c_master(struct dvb_frontend *, enum dibx000_i2c_interface, int); |
diff --git a/drivers/media/dvb/frontends/or51132.c b/drivers/media/dvb/frontends/or51132.c index c7b5785f81f2..5ed32544de39 100644 --- a/drivers/media/dvb/frontends/or51132.c +++ b/drivers/media/dvb/frontends/or51132.c | |||
@@ -126,7 +126,7 @@ static int or51132_readreg(struct or51132_state *state, u8 reg) | |||
126 | reg, err); | 126 | reg, err); |
127 | return -EREMOTEIO; | 127 | return -EREMOTEIO; |
128 | } | 128 | } |
129 | return le16_to_cpup((u16*)buf); | 129 | return buf[0] | (buf[1] << 8); |
130 | } | 130 | } |
131 | 131 | ||
132 | static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware *fw) | 132 | static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware *fw) |
@@ -140,9 +140,9 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware | |||
140 | dprintk("Firmware is %Zd bytes\n",fw->size); | 140 | dprintk("Firmware is %Zd bytes\n",fw->size); |
141 | 141 | ||
142 | /* Get size of firmware A and B */ | 142 | /* Get size of firmware A and B */ |
143 | firmwareAsize = le32_to_cpu(*((u32*)fw->data)); | 143 | firmwareAsize = le32_to_cpu(*((__le32*)fw->data)); |
144 | dprintk("FirmwareA is %i bytes\n",firmwareAsize); | 144 | dprintk("FirmwareA is %i bytes\n",firmwareAsize); |
145 | firmwareBsize = le32_to_cpu(*((u32*)(fw->data+4))); | 145 | firmwareBsize = le32_to_cpu(*((__le32*)(fw->data+4))); |
146 | dprintk("FirmwareB is %i bytes\n",firmwareBsize); | 146 | dprintk("FirmwareB is %i bytes\n",firmwareBsize); |
147 | 147 | ||
148 | /* Upload firmware */ | 148 | /* Upload firmware */ |
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c index 747e7f1a6267..f05d43d8b5cf 100644 --- a/drivers/media/dvb/ttpci/av7110.c +++ b/drivers/media/dvb/ttpci/av7110.c | |||
@@ -51,6 +51,7 @@ | |||
51 | #include <linux/crc32.h> | 51 | #include <linux/crc32.h> |
52 | #include <linux/i2c.h> | 52 | #include <linux/i2c.h> |
53 | #include <linux/kthread.h> | 53 | #include <linux/kthread.h> |
54 | #include <asm/unaligned.h> | ||
54 | 55 | ||
55 | #include <asm/system.h> | 56 | #include <asm/system.h> |
56 | 57 | ||
@@ -1461,9 +1462,9 @@ static int check_firmware(struct av7110* av7110) | |||
1461 | ptr += 4; | 1462 | ptr += 4; |
1462 | 1463 | ||
1463 | /* check dpram file */ | 1464 | /* check dpram file */ |
1464 | crc = ntohl(*(u32*) ptr); | 1465 | crc = get_unaligned_be32(ptr); |
1465 | ptr += 4; | 1466 | ptr += 4; |
1466 | len = ntohl(*(u32*) ptr); | 1467 | len = get_unaligned_be32(ptr); |
1467 | ptr += 4; | 1468 | ptr += 4; |
1468 | if (len >= 512) { | 1469 | if (len >= 512) { |
1469 | printk("dvb-ttpci: dpram file is way too big.\n"); | 1470 | printk("dvb-ttpci: dpram file is way too big.\n"); |
@@ -1478,9 +1479,9 @@ static int check_firmware(struct av7110* av7110) | |||
1478 | ptr += len; | 1479 | ptr += len; |
1479 | 1480 | ||
1480 | /* check root file */ | 1481 | /* check root file */ |
1481 | crc = ntohl(*(u32*) ptr); | 1482 | crc = get_unaligned_be32(ptr); |
1482 | ptr += 4; | 1483 | ptr += 4; |
1483 | len = ntohl(*(u32*) ptr); | 1484 | len = get_unaligned_be32(ptr); |
1484 | ptr += 4; | 1485 | ptr += 4; |
1485 | 1486 | ||
1486 | if (len <= 200000 || len >= 300000 || | 1487 | if (len <= 200000 || len >= 300000 || |
diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/dvb/ttpci/av7110_av.c index 3e6b650fbb81..ec55a968f204 100644 --- a/drivers/media/dvb/ttpci/av7110_av.c +++ b/drivers/media/dvb/ttpci/av7110_av.c | |||
@@ -965,8 +965,9 @@ static u8 iframe_header[] = { 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x80, 0x00, 0x | |||
965 | 965 | ||
966 | static int play_iframe(struct av7110 *av7110, char __user *buf, unsigned int len, int nonblock) | 966 | static int play_iframe(struct av7110 *av7110, char __user *buf, unsigned int len, int nonblock) |
967 | { | 967 | { |
968 | int i, n; | 968 | unsigned i, n; |
969 | int progressive = 0; | 969 | int progressive = 0; |
970 | int match = 0; | ||
970 | 971 | ||
971 | dprintk(2, "av7110:%p, \n", av7110); | 972 | dprintk(2, "av7110:%p, \n", av7110); |
972 | 973 | ||
@@ -975,12 +976,31 @@ static int play_iframe(struct av7110 *av7110, char __user *buf, unsigned int len | |||
975 | return -EBUSY; | 976 | return -EBUSY; |
976 | } | 977 | } |
977 | 978 | ||
978 | for (i = 0; i < len - 5; i++) { | 979 | /* search in buf for instances of 00 00 01 b5 1? */ |
979 | /* get progressive flag from picture extension */ | 980 | for (i = 0; i < len; i++) { |
980 | if (buf[i] == 0x00 && buf[i+1] == 0x00 && | 981 | unsigned char c; |
981 | buf[i+2] == 0x01 && (unsigned char)buf[i+3] == 0xb5 && | 982 | if (get_user(c, buf + i)) |
982 | (buf[i+4] & 0xf0) == 0x10) | 983 | return -EFAULT; |
983 | progressive = buf[i+5] & 0x08; | 984 | if (match == 5) { |
985 | progressive = c & 0x08; | ||
986 | match = 0; | ||
987 | } | ||
988 | if (c == 0x00) { | ||
989 | match = (match == 1 || match == 2) ? 2 : 1; | ||
990 | continue; | ||
991 | } | ||
992 | switch (match++) { | ||
993 | case 2: if (c == 0x01) | ||
994 | continue; | ||
995 | break; | ||
996 | case 3: if (c == 0xb5) | ||
997 | continue; | ||
998 | break; | ||
999 | case 4: if ((c & 0xf0) == 0x10) | ||
1000 | continue; | ||
1001 | break; | ||
1002 | } | ||
1003 | match = 0; | ||
984 | } | 1004 | } |
985 | 1005 | ||
986 | /* setting n always > 1, fixes problems when playing stillframes | 1006 | /* setting n always > 1, fixes problems when playing stillframes |
diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c index 732ce4de512e..5d2d81ab2371 100644 --- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c +++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c | |||
@@ -552,7 +552,7 @@ static void ttusb_process_muxpack(struct ttusb *ttusb, const u8 * muxpack, | |||
552 | u16 csum = 0, cc; | 552 | u16 csum = 0, cc; |
553 | int i; | 553 | int i; |
554 | for (i = 0; i < len; i += 2) | 554 | for (i = 0; i < len; i += 2) |
555 | csum ^= le16_to_cpup((u16 *) (muxpack + i)); | 555 | csum ^= le16_to_cpup((__le16 *) (muxpack + i)); |
556 | if (csum) { | 556 | if (csum) { |
557 | printk("%s: muxpack with incorrect checksum, ignoring\n", | 557 | printk("%s: muxpack with incorrect checksum, ignoring\n", |
558 | __func__); | 558 | __func__); |
diff --git a/drivers/media/dvb/ttusb-dec/Kconfig b/drivers/media/dvb/ttusb-dec/Kconfig index 0712899e39a4..a23cc0aa17d3 100644 --- a/drivers/media/dvb/ttusb-dec/Kconfig +++ b/drivers/media/dvb/ttusb-dec/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config DVB_TTUSB_DEC | 1 | config DVB_TTUSB_DEC |
2 | tristate "Technotrend/Hauppauge USB DEC devices" | 2 | tristate "Technotrend/Hauppauge USB DEC devices" |
3 | depends on DVB_CORE && USB | 3 | depends on DVB_CORE && USB && INPUT |
4 | depends on HOTPLUG # due to FW_LOADER | 4 | depends on HOTPLUG # due to FW_LOADER |
5 | select FW_LOADER | 5 | select FW_LOADER |
6 | select CRC32 | 6 | select CRC32 |
diff --git a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c index 42eee04daa5d..fefdc05e84ac 100644 --- a/drivers/media/dvb/ttusb-dec/ttusb_dec.c +++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c | |||
@@ -343,7 +343,7 @@ static int ttusb_dec_get_stb_state (struct ttusb_dec *dec, unsigned int *mode, | |||
343 | u8 c[COMMAND_PACKET_SIZE]; | 343 | u8 c[COMMAND_PACKET_SIZE]; |
344 | int c_length; | 344 | int c_length; |
345 | int result; | 345 | int result; |
346 | unsigned int tmp; | 346 | __be32 tmp; |
347 | 347 | ||
348 | dprintk("%s\n", __func__); | 348 | dprintk("%s\n", __func__); |
349 | 349 | ||
@@ -398,9 +398,9 @@ static void ttusb_dec_set_pids(struct ttusb_dec *dec) | |||
398 | 0x00, 0x00, 0xff, 0xff, | 398 | 0x00, 0x00, 0xff, 0xff, |
399 | 0xff, 0xff, 0xff, 0xff }; | 399 | 0xff, 0xff, 0xff, 0xff }; |
400 | 400 | ||
401 | u16 pcr = htons(dec->pid[DMX_PES_PCR]); | 401 | __be16 pcr = htons(dec->pid[DMX_PES_PCR]); |
402 | u16 audio = htons(dec->pid[DMX_PES_AUDIO]); | 402 | __be16 audio = htons(dec->pid[DMX_PES_AUDIO]); |
403 | u16 video = htons(dec->pid[DMX_PES_VIDEO]); | 403 | __be16 video = htons(dec->pid[DMX_PES_VIDEO]); |
404 | 404 | ||
405 | dprintk("%s\n", __func__); | 405 | dprintk("%s\n", __func__); |
406 | 406 | ||
@@ -435,7 +435,7 @@ static void ttusb_dec_process_pva(struct ttusb_dec *dec, u8 *pva, int length) | |||
435 | case 0x01: { /* VideoStream */ | 435 | case 0x01: { /* VideoStream */ |
436 | int prebytes = pva[5] & 0x03; | 436 | int prebytes = pva[5] & 0x03; |
437 | int postbytes = (pva[5] & 0x0c) >> 2; | 437 | int postbytes = (pva[5] & 0x0c) >> 2; |
438 | u16 v_pes_payload_length; | 438 | __be16 v_pes_payload_length; |
439 | 439 | ||
440 | if (output_pva) { | 440 | if (output_pva) { |
441 | dec->video_filter->feed->cb.ts(pva, length, NULL, 0, | 441 | dec->video_filter->feed->cb.ts(pva, length, NULL, 0, |
@@ -1006,7 +1006,7 @@ static int ttusb_dec_start_sec_feed(struct dvb_demux_feed *dvbdmxfeed) | |||
1006 | 0x00, 0x00, 0x00, 0x00, | 1006 | 0x00, 0x00, 0x00, 0x00, |
1007 | 0x00, 0x00, 0x00, 0x00, | 1007 | 0x00, 0x00, 0x00, 0x00, |
1008 | 0x00 }; | 1008 | 0x00 }; |
1009 | u16 pid; | 1009 | __be16 pid; |
1010 | u8 c[COMMAND_PACKET_SIZE]; | 1010 | u8 c[COMMAND_PACKET_SIZE]; |
1011 | int c_length; | 1011 | int c_length; |
1012 | int result; | 1012 | int result; |
@@ -1278,9 +1278,10 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec) | |||
1278 | u8 *firmware = NULL; | 1278 | u8 *firmware = NULL; |
1279 | size_t firmware_size = 0; | 1279 | size_t firmware_size = 0; |
1280 | u16 firmware_csum = 0; | 1280 | u16 firmware_csum = 0; |
1281 | u16 firmware_csum_ns; | 1281 | __be16 firmware_csum_ns; |
1282 | u32 firmware_size_nl; | 1282 | __be32 firmware_size_nl; |
1283 | u32 crc32_csum, crc32_check, tmp; | 1283 | u32 crc32_csum, crc32_check; |
1284 | __be32 tmp; | ||
1284 | const struct firmware *fw_entry = NULL; | 1285 | const struct firmware *fw_entry = NULL; |
1285 | 1286 | ||
1286 | dprintk("%s\n", __func__); | 1287 | dprintk("%s\n", __func__); |
@@ -1306,7 +1307,7 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec) | |||
1306 | valid. */ | 1307 | valid. */ |
1307 | crc32_csum = crc32(~0L, firmware, 56) ^ ~0L; | 1308 | crc32_csum = crc32(~0L, firmware, 56) ^ ~0L; |
1308 | memcpy(&tmp, &firmware[56], 4); | 1309 | memcpy(&tmp, &firmware[56], 4); |
1309 | crc32_check = htonl(tmp); | 1310 | crc32_check = ntohl(tmp); |
1310 | if (crc32_csum != crc32_check) { | 1311 | if (crc32_csum != crc32_check) { |
1311 | printk("%s: crc32 check of DSP code failed (calculated " | 1312 | printk("%s: crc32 check of DSP code failed (calculated " |
1312 | "0x%08x != 0x%08x in file), file invalid.\n", | 1313 | "0x%08x != 0x%08x in file), file invalid.\n", |
@@ -1627,7 +1628,7 @@ static int ttusb_dec_probe(struct usb_interface *intf, | |||
1627 | 1628 | ||
1628 | usb_set_intfdata(intf, (void *)dec); | 1629 | usb_set_intfdata(intf, (void *)dec); |
1629 | 1630 | ||
1630 | switch (le16_to_cpu(id->idProduct)) { | 1631 | switch (id->idProduct) { |
1631 | case 0x1006: | 1632 | case 0x1006: |
1632 | ttusb_dec_set_model(dec, TTUSB_DEC3000S); | 1633 | ttusb_dec_set_model(dec, TTUSB_DEC3000S); |
1633 | break; | 1634 | break; |
@@ -1652,7 +1653,7 @@ static int ttusb_dec_probe(struct usb_interface *intf, | |||
1652 | ttusb_dec_init_dvb(dec); | 1653 | ttusb_dec_init_dvb(dec); |
1653 | 1654 | ||
1654 | dec->adapter.priv = dec; | 1655 | dec->adapter.priv = dec; |
1655 | switch (le16_to_cpu(id->idProduct)) { | 1656 | switch (id->idProduct) { |
1656 | case 0x1006: | 1657 | case 0x1006: |
1657 | dec->fe = ttusbdecfe_dvbs_attach(&fe_config); | 1658 | dec->fe = ttusbdecfe_dvbs_attach(&fe_config); |
1658 | break; | 1659 | break; |
diff --git a/drivers/media/dvb/ttusb-dec/ttusbdecfe.c b/drivers/media/dvb/ttusb-dec/ttusbdecfe.c index eb5eaeccd7c4..443af24097f3 100644 --- a/drivers/media/dvb/ttusb-dec/ttusbdecfe.c +++ b/drivers/media/dvb/ttusb-dec/ttusbdecfe.c | |||
@@ -86,7 +86,7 @@ static int ttusbdecfe_dvbt_set_frontend(struct dvb_frontend* fe, struct dvb_fron | |||
86 | 0x00, 0x00, 0x00, 0xff, | 86 | 0x00, 0x00, 0x00, 0xff, |
87 | 0x00, 0x00, 0x00, 0xff }; | 87 | 0x00, 0x00, 0x00, 0xff }; |
88 | 88 | ||
89 | u32 freq = htonl(p->frequency / 1000); | 89 | __be32 freq = htonl(p->frequency / 1000); |
90 | memcpy(&b[4], &freq, sizeof (u32)); | 90 | memcpy(&b[4], &freq, sizeof (u32)); |
91 | state->config->send_command(fe, 0x71, sizeof(b), b, NULL, NULL); | 91 | state->config->send_command(fe, 0x71, sizeof(b), b, NULL, NULL); |
92 | 92 | ||
@@ -117,10 +117,10 @@ static int ttusbdecfe_dvbs_set_frontend(struct dvb_frontend* fe, struct dvb_fron | |||
117 | 0x00, 0x00, 0x00, 0x00, | 117 | 0x00, 0x00, 0x00, 0x00, |
118 | 0x00, 0x00, 0x00, 0x00, | 118 | 0x00, 0x00, 0x00, 0x00, |
119 | 0x00, 0x00, 0x00, 0x00 }; | 119 | 0x00, 0x00, 0x00, 0x00 }; |
120 | u32 freq; | 120 | __be32 freq; |
121 | u32 sym_rate; | 121 | __be32 sym_rate; |
122 | u32 band; | 122 | __be32 band; |
123 | u32 lnb_voltage; | 123 | __be32 lnb_voltage; |
124 | 124 | ||
125 | freq = htonl(p->frequency + | 125 | freq = htonl(p->frequency + |
126 | (state->hi_band ? LOF_HI : LOF_LO)); | 126 | (state->hi_band ? LOF_HI : LOF_LO)); |
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index 89d8d37838a3..3b26fbd3e558 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig | |||
@@ -901,7 +901,7 @@ endif # V4L_USB_DRIVERS | |||
901 | 901 | ||
902 | config SOC_CAMERA | 902 | config SOC_CAMERA |
903 | tristate "SoC camera support" | 903 | tristate "SoC camera support" |
904 | depends on VIDEO_V4L2 | 904 | depends on VIDEO_V4L2 && HAS_DMA |
905 | select VIDEOBUF_DMA_SG | 905 | select VIDEOBUF_DMA_SG |
906 | help | 906 | help |
907 | SoC Camera is a common API to several cameras, not connecting | 907 | SoC Camera is a common API to several cameras, not connecting |
diff --git a/drivers/media/video/au0828/Kconfig b/drivers/media/video/au0828/Kconfig index def10d086373..52b2491581a8 100644 --- a/drivers/media/video/au0828/Kconfig +++ b/drivers/media/video/au0828/Kconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | 1 | ||
2 | config VIDEO_AU0828 | 2 | config VIDEO_AU0828 |
3 | tristate "Auvitek AU0828 support" | 3 | tristate "Auvitek AU0828 support" |
4 | depends on VIDEO_DEV && I2C && INPUT && DVB_CORE && USB | 4 | depends on I2C && INPUT && DVB_CORE && USB |
5 | select I2C_ALGOBIT | 5 | select I2C_ALGOBIT |
6 | select VIDEO_TVEEPROM | 6 | select VIDEO_TVEEPROM |
7 | select DVB_AU8522 if !DVB_FE_CUSTOMIZE | 7 | select DVB_AU8522 if !DVB_FE_CUSTOMIZE |
diff --git a/drivers/media/video/au0828/au0828-dvb.c b/drivers/media/video/au0828/au0828-dvb.c index c86a5f17eca8..c6d470590380 100644 --- a/drivers/media/video/au0828/au0828-dvb.c +++ b/drivers/media/video/au0828/au0828-dvb.c | |||
@@ -353,12 +353,6 @@ int au0828_dvb_register(struct au0828_dev *dev) | |||
353 | return -1; | 353 | return -1; |
354 | } | 354 | } |
355 | 355 | ||
356 | /* Put the analog decoder in standby to keep it quiet */ | ||
357 | au0828_call_i2c_clients(dev, TUNER_SET_STANDBY, NULL); | ||
358 | |||
359 | if (dvb->frontend->ops.analog_ops.standby) | ||
360 | dvb->frontend->ops.analog_ops.standby(dvb->frontend); | ||
361 | |||
362 | /* register everything */ | 356 | /* register everything */ |
363 | ret = dvb_register(dev); | 357 | ret = dvb_register(dev); |
364 | if (ret < 0) { | 358 | if (ret < 0) { |
diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c index f20a01cfc73e..8ef0424c26c4 100644 --- a/drivers/media/video/bt8xx/bttv-cards.c +++ b/drivers/media/video/bt8xx/bttv-cards.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/firmware.h> | 34 | #include <linux/firmware.h> |
35 | #include <net/checksum.h> | 35 | #include <net/checksum.h> |
36 | 36 | ||
37 | #include <asm/unaligned.h> | ||
37 | #include <asm/io.h> | 38 | #include <asm/io.h> |
38 | 39 | ||
39 | #include "bttvp.h" | 40 | #include "bttvp.h" |
@@ -3858,7 +3859,7 @@ static void __devinit osprey_eeprom(struct bttv *btv, const u8 ee[256]) | |||
3858 | ee += i; | 3859 | ee += i; |
3859 | 3860 | ||
3860 | /* found a valid descriptor */ | 3861 | /* found a valid descriptor */ |
3861 | type = be16_to_cpup((u16*)(ee+4)); | 3862 | type = get_unaligned_be16((__be16 *)(ee+4)); |
3862 | 3863 | ||
3863 | switch(type) { | 3864 | switch(type) { |
3864 | /* 848 based */ | 3865 | /* 848 based */ |
@@ -3918,7 +3919,7 @@ static void __devinit osprey_eeprom(struct bttv *btv, const u8 ee[256]) | |||
3918 | btv->c.nr, type); | 3919 | btv->c.nr, type); |
3919 | break; | 3920 | break; |
3920 | } | 3921 | } |
3921 | serial = be32_to_cpup((u32*)(ee+6)); | 3922 | serial = get_unaligned_be32((__be32 *)(ee+6)); |
3922 | } | 3923 | } |
3923 | 3924 | ||
3924 | printk(KERN_INFO "bttv%d: osprey eeprom: card=%d '%s' serial=%u\n", | 3925 | printk(KERN_INFO "bttv%d: osprey eeprom: card=%d '%s' serial=%u\n", |
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index 2ca3e9cfb2bb..0165aac533bf 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c | |||
@@ -2613,7 +2613,7 @@ static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf) | |||
2613 | struct bttv_fh *fh = priv; | 2613 | struct bttv_fh *fh = priv; |
2614 | 2614 | ||
2615 | mutex_lock(&fh->cap.vb_lock); | 2615 | mutex_lock(&fh->cap.vb_lock); |
2616 | retval = videobuf_mmap_setup(&fh->cap, gbuffers, gbufsize, | 2616 | retval = __videobuf_mmap_setup(&fh->cap, gbuffers, gbufsize, |
2617 | V4L2_MEMORY_MMAP); | 2617 | V4L2_MEMORY_MMAP); |
2618 | if (retval < 0) { | 2618 | if (retval < 0) { |
2619 | mutex_unlock(&fh->cap.vb_lock); | 2619 | mutex_unlock(&fh->cap.vb_lock); |
diff --git a/drivers/media/video/bt8xx/bttv-risc.c b/drivers/media/video/bt8xx/bttv-risc.c index e5979f77504c..0af586876e72 100644 --- a/drivers/media/video/bt8xx/bttv-risc.c +++ b/drivers/media/video/bt8xx/bttv-risc.c | |||
@@ -48,7 +48,7 @@ bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc, | |||
48 | { | 48 | { |
49 | u32 instructions,line,todo; | 49 | u32 instructions,line,todo; |
50 | struct scatterlist *sg; | 50 | struct scatterlist *sg; |
51 | u32 *rp; | 51 | __le32 *rp; |
52 | int rc; | 52 | int rc; |
53 | 53 | ||
54 | /* estimate risc mem: worst case is one write per page border + | 54 | /* estimate risc mem: worst case is one write per page border + |
@@ -128,7 +128,8 @@ bttv_risc_planar(struct bttv *btv, struct btcx_riscmem *risc, | |||
128 | unsigned int cpadding) | 128 | unsigned int cpadding) |
129 | { | 129 | { |
130 | unsigned int instructions,line,todo,ylen,chroma; | 130 | unsigned int instructions,line,todo,ylen,chroma; |
131 | u32 *rp,ri; | 131 | __le32 *rp; |
132 | u32 ri; | ||
132 | struct scatterlist *ysg; | 133 | struct scatterlist *ysg; |
133 | struct scatterlist *usg; | 134 | struct scatterlist *usg; |
134 | struct scatterlist *vsg; | 135 | struct scatterlist *vsg; |
@@ -244,7 +245,8 @@ bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc, | |||
244 | { | 245 | { |
245 | int dwords,rc,line,maxy,start,end,skip,nskips; | 246 | int dwords,rc,line,maxy,start,end,skip,nskips; |
246 | struct btcx_skiplist *skips; | 247 | struct btcx_skiplist *skips; |
247 | u32 *rp,ri,ra; | 248 | __le32 *rp; |
249 | u32 ri,ra; | ||
248 | u32 addr; | 250 | u32 addr; |
249 | 251 | ||
250 | /* skip list for window clipping */ | 252 | /* skip list for window clipping */ |
diff --git a/drivers/media/video/btcx-risc.c b/drivers/media/video/btcx-risc.c index ce0840ccd594..f42701f82e7f 100644 --- a/drivers/media/video/btcx-risc.c +++ b/drivers/media/video/btcx-risc.c | |||
@@ -63,7 +63,7 @@ int btcx_riscmem_alloc(struct pci_dev *pci, | |||
63 | struct btcx_riscmem *risc, | 63 | struct btcx_riscmem *risc, |
64 | unsigned int size) | 64 | unsigned int size) |
65 | { | 65 | { |
66 | u32 *cpu; | 66 | __le32 *cpu; |
67 | dma_addr_t dma; | 67 | dma_addr_t dma; |
68 | 68 | ||
69 | if (NULL != risc->cpu && risc->size < size) | 69 | if (NULL != risc->cpu && risc->size < size) |
diff --git a/drivers/media/video/btcx-risc.h b/drivers/media/video/btcx-risc.h index 503e6c6d7b69..861bc8112824 100644 --- a/drivers/media/video/btcx-risc.h +++ b/drivers/media/video/btcx-risc.h | |||
@@ -2,8 +2,8 @@ | |||
2 | */ | 2 | */ |
3 | struct btcx_riscmem { | 3 | struct btcx_riscmem { |
4 | unsigned int size; | 4 | unsigned int size; |
5 | u32 *cpu; | 5 | __le32 *cpu; |
6 | u32 *jmp; | 6 | __le32 *jmp; |
7 | dma_addr_t dma; | 7 | dma_addr_t dma; |
8 | }; | 8 | }; |
9 | 9 | ||
diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c index 66864904c99b..9a26751615c6 100644 --- a/drivers/media/video/cx18/cx18-av-core.c +++ b/drivers/media/video/cx18/cx18-av-core.c | |||
@@ -182,14 +182,16 @@ static void input_change(struct cx18 *cx) | |||
182 | if (std == V4L2_STD_NTSC_M_JP) { | 182 | if (std == V4L2_STD_NTSC_M_JP) { |
183 | /* Japan uses EIAJ audio standard */ | 183 | /* Japan uses EIAJ audio standard */ |
184 | cx18_av_write(cx, 0x808, 0xf7); | 184 | cx18_av_write(cx, 0x808, 0xf7); |
185 | cx18_av_write(cx, 0x80b, 0x02); | ||
185 | } else if (std == V4L2_STD_NTSC_M_KR) { | 186 | } else if (std == V4L2_STD_NTSC_M_KR) { |
186 | /* South Korea uses A2 audio standard */ | 187 | /* South Korea uses A2 audio standard */ |
187 | cx18_av_write(cx, 0x808, 0xf8); | 188 | cx18_av_write(cx, 0x808, 0xf8); |
189 | cx18_av_write(cx, 0x80b, 0x03); | ||
188 | } else { | 190 | } else { |
189 | /* Others use the BTSC audio standard */ | 191 | /* Others use the BTSC audio standard */ |
190 | cx18_av_write(cx, 0x808, 0xf6); | 192 | cx18_av_write(cx, 0x808, 0xf6); |
193 | cx18_av_write(cx, 0x80b, 0x01); | ||
191 | } | 194 | } |
192 | cx18_av_write(cx, 0x80b, 0x00); | ||
193 | } else if (std & V4L2_STD_PAL) { | 195 | } else if (std & V4L2_STD_PAL) { |
194 | /* Follow tuner change procedure for PAL */ | 196 | /* Follow tuner change procedure for PAL */ |
195 | cx18_av_write(cx, 0x808, 0xff); | 197 | cx18_av_write(cx, 0x808, 0xff); |
@@ -741,8 +743,8 @@ static void log_audio_status(struct cx18 *cx) | |||
741 | { | 743 | { |
742 | struct cx18_av_state *state = &cx->av_state; | 744 | struct cx18_av_state *state = &cx->av_state; |
743 | u8 download_ctl = cx18_av_read(cx, 0x803); | 745 | u8 download_ctl = cx18_av_read(cx, 0x803); |
744 | u8 mod_det_stat0 = cx18_av_read(cx, 0x805); | 746 | u8 mod_det_stat0 = cx18_av_read(cx, 0x804); |
745 | u8 mod_det_stat1 = cx18_av_read(cx, 0x804); | 747 | u8 mod_det_stat1 = cx18_av_read(cx, 0x805); |
746 | u8 audio_config = cx18_av_read(cx, 0x808); | 748 | u8 audio_config = cx18_av_read(cx, 0x808); |
747 | u8 pref_mode = cx18_av_read(cx, 0x809); | 749 | u8 pref_mode = cx18_av_read(cx, 0x809); |
748 | u8 afc0 = cx18_av_read(cx, 0x80b); | 750 | u8 afc0 = cx18_av_read(cx, 0x80b); |
@@ -760,12 +762,12 @@ static void log_audio_status(struct cx18 *cx) | |||
760 | case 0x12: p = "dual with SAP"; break; | 762 | case 0x12: p = "dual with SAP"; break; |
761 | case 0x14: p = "tri with SAP"; break; | 763 | case 0x14: p = "tri with SAP"; break; |
762 | case 0xfe: p = "forced mode"; break; | 764 | case 0xfe: p = "forced mode"; break; |
763 | default: p = "not defined"; | 765 | default: p = "not defined"; break; |
764 | } | 766 | } |
765 | CX18_INFO("Detected audio mode: %s\n", p); | 767 | CX18_INFO("Detected audio mode: %s\n", p); |
766 | 768 | ||
767 | switch (mod_det_stat1) { | 769 | switch (mod_det_stat1) { |
768 | case 0x00: p = "BTSC"; break; | 770 | case 0x00: p = "not defined"; break; |
769 | case 0x01: p = "EIAJ"; break; | 771 | case 0x01: p = "EIAJ"; break; |
770 | case 0x02: p = "A2-M"; break; | 772 | case 0x02: p = "A2-M"; break; |
771 | case 0x03: p = "A2-BG"; break; | 773 | case 0x03: p = "A2-BG"; break; |
@@ -779,8 +781,13 @@ static void log_audio_status(struct cx18 *cx) | |||
779 | case 0x0b: p = "NICAM-I"; break; | 781 | case 0x0b: p = "NICAM-I"; break; |
780 | case 0x0c: p = "NICAM-L"; break; | 782 | case 0x0c: p = "NICAM-L"; break; |
781 | case 0x0d: p = "BTSC/EIAJ/A2-M Mono (4.5 MHz FMMono)"; break; | 783 | case 0x0d: p = "BTSC/EIAJ/A2-M Mono (4.5 MHz FMMono)"; break; |
784 | case 0x0e: p = "IF FM Radio"; break; | ||
785 | case 0x0f: p = "BTSC"; break; | ||
786 | case 0x10: p = "detected chrominance"; break; | ||
787 | case 0xfd: p = "unknown audio standard"; break; | ||
788 | case 0xfe: p = "forced audio standard"; break; | ||
782 | case 0xff: p = "no detected audio standard"; break; | 789 | case 0xff: p = "no detected audio standard"; break; |
783 | default: p = "not defined"; | 790 | default: p = "not defined"; break; |
784 | } | 791 | } |
785 | CX18_INFO("Detected audio standard: %s\n", p); | 792 | CX18_INFO("Detected audio standard: %s\n", p); |
786 | CX18_INFO("Audio muted: %s\n", | 793 | CX18_INFO("Audio muted: %s\n", |
@@ -789,22 +796,23 @@ static void log_audio_status(struct cx18 *cx) | |||
789 | (download_ctl & 0x10) ? "running" : "stopped"); | 796 | (download_ctl & 0x10) ? "running" : "stopped"); |
790 | 797 | ||
791 | switch (audio_config >> 4) { | 798 | switch (audio_config >> 4) { |
792 | case 0x00: p = "BTSC"; break; | 799 | case 0x00: p = "undefined"; break; |
793 | case 0x01: p = "EIAJ"; break; | 800 | case 0x01: p = "BTSC"; break; |
794 | case 0x02: p = "A2-M"; break; | 801 | case 0x02: p = "EIAJ"; break; |
795 | case 0x03: p = "A2-BG"; break; | 802 | case 0x03: p = "A2-M"; break; |
796 | case 0x04: p = "A2-DK1"; break; | 803 | case 0x04: p = "A2-BG"; break; |
797 | case 0x05: p = "A2-DK2"; break; | 804 | case 0x05: p = "A2-DK1"; break; |
798 | case 0x06: p = "A2-DK3"; break; | 805 | case 0x06: p = "A2-DK2"; break; |
799 | case 0x07: p = "A1 (6.0 MHz FM Mono)"; break; | 806 | case 0x07: p = "A2-DK3"; break; |
800 | case 0x08: p = "AM-L"; break; | 807 | case 0x08: p = "A1 (6.0 MHz FM Mono)"; break; |
801 | case 0x09: p = "NICAM-BG"; break; | 808 | case 0x09: p = "AM-L"; break; |
802 | case 0x0a: p = "NICAM-DK"; break; | 809 | case 0x0a: p = "NICAM-BG"; break; |
803 | case 0x0b: p = "NICAM-I"; break; | 810 | case 0x0b: p = "NICAM-DK"; break; |
804 | case 0x0c: p = "NICAM-L"; break; | 811 | case 0x0c: p = "NICAM-I"; break; |
805 | case 0x0d: p = "FM radio"; break; | 812 | case 0x0d: p = "NICAM-L"; break; |
813 | case 0x0e: p = "FM radio"; break; | ||
806 | case 0x0f: p = "automatic detection"; break; | 814 | case 0x0f: p = "automatic detection"; break; |
807 | default: p = "undefined"; | 815 | default: p = "undefined"; break; |
808 | } | 816 | } |
809 | CX18_INFO("Configured audio standard: %s\n", p); | 817 | CX18_INFO("Configured audio standard: %s\n", p); |
810 | 818 | ||
@@ -815,12 +823,9 @@ static void log_audio_status(struct cx18 *cx) | |||
815 | case 0x02: p = "MONO3 (STEREO forced MONO)"; break; | 823 | case 0x02: p = "MONO3 (STEREO forced MONO)"; break; |
816 | case 0x03: p = "MONO4 (NICAM ANALOG-Language C/Analog Fallback)"; break; | 824 | case 0x03: p = "MONO4 (NICAM ANALOG-Language C/Analog Fallback)"; break; |
817 | case 0x04: p = "STEREO"; break; | 825 | case 0x04: p = "STEREO"; break; |
818 | case 0x05: p = "DUAL1 (AB)"; break; | 826 | case 0x05: p = "DUAL1 (AC)"; break; |
819 | case 0x06: p = "DUAL2 (AC) (FM)"; break; | 827 | case 0x06: p = "DUAL2 (BC)"; break; |
820 | case 0x07: p = "DUAL3 (BC) (FM)"; break; | 828 | case 0x07: p = "DUAL3 (AB)"; break; |
821 | case 0x08: p = "DUAL4 (AC) (AM)"; break; | ||
822 | case 0x09: p = "DUAL5 (BC) (AM)"; break; | ||
823 | case 0x0a: p = "SAP"; break; | ||
824 | default: p = "undefined"; | 829 | default: p = "undefined"; |
825 | } | 830 | } |
826 | CX18_INFO("Configured audio mode: %s\n", p); | 831 | CX18_INFO("Configured audio mode: %s\n", p); |
@@ -835,9 +840,11 @@ static void log_audio_status(struct cx18 *cx) | |||
835 | case 0x06: p = "BTSC"; break; | 840 | case 0x06: p = "BTSC"; break; |
836 | case 0x07: p = "EIAJ"; break; | 841 | case 0x07: p = "EIAJ"; break; |
837 | case 0x08: p = "A2-M"; break; | 842 | case 0x08: p = "A2-M"; break; |
838 | case 0x09: p = "FM Radio"; break; | 843 | case 0x09: p = "FM Radio (4.5 MHz)"; break; |
844 | case 0x0a: p = "FM Radio (5.5 MHz)"; break; | ||
845 | case 0x0b: p = "S-Video"; break; | ||
839 | case 0x0f: p = "automatic standard and mode detection"; break; | 846 | case 0x0f: p = "automatic standard and mode detection"; break; |
840 | default: p = "undefined"; | 847 | default: p = "undefined"; break; |
841 | } | 848 | } |
842 | CX18_INFO("Configured audio system: %s\n", p); | 849 | CX18_INFO("Configured audio system: %s\n", p); |
843 | } | 850 | } |
@@ -857,22 +864,24 @@ static void log_audio_status(struct cx18 *cx) | |||
857 | case 5: p = "language AC"; break; | 864 | case 5: p = "language AC"; break; |
858 | case 6: p = "language BC"; break; | 865 | case 6: p = "language BC"; break; |
859 | case 7: p = "language AB"; break; | 866 | case 7: p = "language AB"; break; |
860 | default: p = "undefined"; | 867 | default: p = "undefined"; break; |
861 | } | 868 | } |
862 | CX18_INFO("Preferred audio mode: %s\n", p); | 869 | CX18_INFO("Preferred audio mode: %s\n", p); |
863 | 870 | ||
864 | if ((audio_config & 0xf) == 0xf) { | 871 | if ((audio_config & 0xf) == 0xf) { |
865 | switch ((afc0 >> 2) & 0x1) { | 872 | switch ((afc0 >> 3) & 0x1) { |
866 | case 0: p = "system DK"; break; | 873 | case 0: p = "system DK"; break; |
867 | case 1: p = "system L"; break; | 874 | case 1: p = "system L"; break; |
868 | } | 875 | } |
869 | CX18_INFO("Selected 65 MHz format: %s\n", p); | 876 | CX18_INFO("Selected 65 MHz format: %s\n", p); |
870 | 877 | ||
871 | switch (afc0 & 0x3) { | 878 | switch (afc0 & 0x7) { |
872 | case 0: p = "BTSC"; break; | 879 | case 0: p = "Chroma"; break; |
873 | case 1: p = "EIAJ"; break; | 880 | case 1: p = "BTSC"; break; |
874 | case 2: p = "A2-M"; break; | 881 | case 2: p = "EIAJ"; break; |
875 | default: p = "undefined"; | 882 | case 3: p = "A2-M"; break; |
883 | case 4: p = "autodetect"; break; | ||
884 | default: p = "undefined"; break; | ||
876 | } | 885 | } |
877 | CX18_INFO("Selected 45 MHz format: %s\n", p); | 886 | CX18_INFO("Selected 45 MHz format: %s\n", p); |
878 | } | 887 | } |
diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c index 553adbf2cd44..baccd079243d 100644 --- a/drivers/media/video/cx18/cx18-cards.c +++ b/drivers/media/video/cx18/cx18-cards.c | |||
@@ -126,7 +126,7 @@ static const struct cx18_card cx18_card_hvr1600_samsung = { | |||
126 | 126 | ||
127 | /* ------------------------------------------------------------------------- */ | 127 | /* ------------------------------------------------------------------------- */ |
128 | 128 | ||
129 | /* Compro VideoMate H900: not working at the moment! */ | 129 | /* Compro VideoMate H900: note that this card is analog only! */ |
130 | 130 | ||
131 | static const struct cx18_card_pci_info cx18_pci_h900[] = { | 131 | static const struct cx18_card_pci_info cx18_pci_h900[] = { |
132 | { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_COMPRO, 0xe100 }, | 132 | { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_COMPRO, 0xe100 }, |
@@ -136,7 +136,7 @@ static const struct cx18_card_pci_info cx18_pci_h900[] = { | |||
136 | static const struct cx18_card cx18_card_h900 = { | 136 | static const struct cx18_card cx18_card_h900 = { |
137 | .type = CX18_CARD_COMPRO_H900, | 137 | .type = CX18_CARD_COMPRO_H900, |
138 | .name = "Compro VideoMate H900", | 138 | .name = "Compro VideoMate H900", |
139 | .comment = "DVB & VBI are not yet supported\n", | 139 | .comment = "VBI is not yet supported\n", |
140 | .v4l2_capabilities = CX18_CAP_ENCODER, | 140 | .v4l2_capabilities = CX18_CAP_ENCODER, |
141 | .hw_audio_ctrl = CX18_HW_CX23418, | 141 | .hw_audio_ctrl = CX18_HW_CX23418, |
142 | .hw_all = CX18_HW_TUNER, | 142 | .hw_all = CX18_HW_TUNER, |
diff --git a/drivers/media/video/cx18/cx18-controls.c b/drivers/media/video/cx18/cx18-controls.c index 2bdac5ebbb0d..87cf41021665 100644 --- a/drivers/media/video/cx18/cx18-controls.c +++ b/drivers/media/video/cx18/cx18-controls.c | |||
@@ -159,7 +159,7 @@ static int cx18_setup_vbi_fmt(struct cx18 *cx, enum v4l2_mpeg_stream_vbi_fmt fmt | |||
159 | { | 159 | { |
160 | if (!(cx->v4l2_cap & V4L2_CAP_SLICED_VBI_CAPTURE)) | 160 | if (!(cx->v4l2_cap & V4L2_CAP_SLICED_VBI_CAPTURE)) |
161 | return -EINVAL; | 161 | return -EINVAL; |
162 | if (atomic_read(&cx->capturing) > 0) | 162 | if (atomic_read(&cx->ana_capturing) > 0) |
163 | return -EBUSY; | 163 | return -EBUSY; |
164 | 164 | ||
165 | /* First try to allocate sliced VBI buffers if needed. */ | 165 | /* First try to allocate sliced VBI buffers if needed. */ |
@@ -235,7 +235,7 @@ int cx18_control_ioctls(struct cx18 *cx, unsigned int cmd, void *arg) | |||
235 | CX18_DEBUG_IOCTL("VIDIOC_S_EXT_CTRLS\n"); | 235 | CX18_DEBUG_IOCTL("VIDIOC_S_EXT_CTRLS\n"); |
236 | if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) { | 236 | if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) { |
237 | struct cx2341x_mpeg_params p = cx->params; | 237 | struct cx2341x_mpeg_params p = cx->params; |
238 | int err = cx2341x_ext_ctrls(&p, atomic_read(&cx->capturing), arg, cmd); | 238 | int err = cx2341x_ext_ctrls(&p, atomic_read(&cx->ana_capturing), arg, cmd); |
239 | 239 | ||
240 | if (err) | 240 | if (err) |
241 | return err; | 241 | return err; |
@@ -295,7 +295,7 @@ int cx18_control_ioctls(struct cx18 *cx, unsigned int cmd, void *arg) | |||
295 | CX18_DEBUG_IOCTL("VIDIOC_TRY_EXT_CTRLS\n"); | 295 | CX18_DEBUG_IOCTL("VIDIOC_TRY_EXT_CTRLS\n"); |
296 | if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) | 296 | if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) |
297 | return cx2341x_ext_ctrls(&cx->params, | 297 | return cx2341x_ext_ctrls(&cx->params, |
298 | atomic_read(&cx->capturing), arg, cmd); | 298 | atomic_read(&cx->ana_capturing), arg, cmd); |
299 | return -EINVAL; | 299 | return -EINVAL; |
300 | } | 300 | } |
301 | 301 | ||
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c index 0dd4e0529970..2b810bb2a4c7 100644 --- a/drivers/media/video/cx18/cx18-driver.c +++ b/drivers/media/video/cx18/cx18-driver.c | |||
@@ -670,7 +670,7 @@ static int __devinit cx18_probe(struct pci_dev *dev, | |||
670 | cx18_init_power(cx, 1); | 670 | cx18_init_power(cx, 1); |
671 | cx18_init_memory(cx); | 671 | cx18_init_memory(cx); |
672 | 672 | ||
673 | cx->scb = (struct cx18_scb *)(cx->enc_mem + SCB_OFFSET); | 673 | cx->scb = (struct cx18_scb __iomem *)(cx->enc_mem + SCB_OFFSET); |
674 | cx18_init_scb(cx); | 674 | cx18_init_scb(cx); |
675 | 675 | ||
676 | cx18_gpio_init(cx); | 676 | cx18_gpio_init(cx); |
@@ -751,17 +751,6 @@ static int __devinit cx18_probe(struct pci_dev *dev, | |||
751 | if (cx->options.radio > 0) | 751 | if (cx->options.radio > 0) |
752 | cx->v4l2_cap |= V4L2_CAP_RADIO; | 752 | cx->v4l2_cap |= V4L2_CAP_RADIO; |
753 | 753 | ||
754 | retval = cx18_streams_setup(cx); | ||
755 | if (retval) { | ||
756 | CX18_ERR("Error %d setting up streams\n", retval); | ||
757 | goto free_irq; | ||
758 | } | ||
759 | retval = cx18_streams_register(cx); | ||
760 | if (retval) { | ||
761 | CX18_ERR("Error %d registering devices\n", retval); | ||
762 | goto free_streams; | ||
763 | } | ||
764 | |||
765 | if (cx->options.tuner > -1) { | 754 | if (cx->options.tuner > -1) { |
766 | struct tuner_setup setup; | 755 | struct tuner_setup setup; |
767 | 756 | ||
@@ -788,7 +777,16 @@ static int __devinit cx18_probe(struct pci_dev *dev, | |||
788 | are not. */ | 777 | are not. */ |
789 | cx->tuner_std = cx->std; | 778 | cx->tuner_std = cx->std; |
790 | 779 | ||
791 | cx18_init_on_first_open(cx); | 780 | retval = cx18_streams_setup(cx); |
781 | if (retval) { | ||
782 | CX18_ERR("Error %d setting up streams\n", retval); | ||
783 | goto free_irq; | ||
784 | } | ||
785 | retval = cx18_streams_register(cx); | ||
786 | if (retval) { | ||
787 | CX18_ERR("Error %d registering devices\n", retval); | ||
788 | goto free_streams; | ||
789 | } | ||
792 | 790 | ||
793 | CX18_INFO("Initialized card #%d: %s\n", cx->num, cx->card_name); | 791 | CX18_INFO("Initialized card #%d: %s\n", cx->num, cx->card_name); |
794 | 792 | ||
@@ -889,7 +887,7 @@ static void cx18_remove(struct pci_dev *pci_dev) | |||
889 | 887 | ||
890 | /* Stop all captures */ | 888 | /* Stop all captures */ |
891 | CX18_DEBUG_INFO("Stopping all streams\n"); | 889 | CX18_DEBUG_INFO("Stopping all streams\n"); |
892 | if (atomic_read(&cx->capturing) > 0) | 890 | if (atomic_read(&cx->tot_capturing) > 0) |
893 | cx18_stop_all_captures(cx); | 891 | cx18_stop_all_captures(cx); |
894 | 892 | ||
895 | /* Interrupts */ | 893 | /* Interrupts */ |
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h index a2a6c58d12fe..de14ab59a206 100644 --- a/drivers/media/video/cx18/cx18-driver.h +++ b/drivers/media/video/cx18/cx18-driver.h | |||
@@ -358,7 +358,7 @@ struct cx18 { | |||
358 | u32 v4l2_cap; /* V4L2 capabilities of card */ | 358 | u32 v4l2_cap; /* V4L2 capabilities of card */ |
359 | u32 hw_flags; /* Hardware description of the board */ | 359 | u32 hw_flags; /* Hardware description of the board */ |
360 | unsigned mdl_offset; | 360 | unsigned mdl_offset; |
361 | struct cx18_scb *scb; /* pointer to SCB */ | 361 | struct cx18_scb __iomem *scb; /* pointer to SCB */ |
362 | 362 | ||
363 | struct cx18_av_state av_state; | 363 | struct cx18_av_state av_state; |
364 | 364 | ||
@@ -380,7 +380,8 @@ struct cx18 { | |||
380 | int stream_buf_size[CX18_MAX_STREAMS]; /* Stream buffer size */ | 380 | int stream_buf_size[CX18_MAX_STREAMS]; /* Stream buffer size */ |
381 | struct cx18_stream streams[CX18_MAX_STREAMS]; /* Stream data */ | 381 | struct cx18_stream streams[CX18_MAX_STREAMS]; /* Stream data */ |
382 | unsigned long i_flags; /* global cx18 flags */ | 382 | unsigned long i_flags; /* global cx18 flags */ |
383 | atomic_t capturing; /* count number of active capture streams */ | 383 | atomic_t ana_capturing; /* count number of active analog capture streams */ |
384 | atomic_t tot_capturing; /* total count number of active capture streams */ | ||
384 | spinlock_t lock; /* lock access to this struct */ | 385 | spinlock_t lock; /* lock access to this struct */ |
385 | int search_pack_header; | 386 | int search_pack_header; |
386 | 387 | ||
@@ -423,6 +424,10 @@ struct cx18 { | |||
423 | struct mutex i2c_bus_lock[2]; | 424 | struct mutex i2c_bus_lock[2]; |
424 | struct i2c_client *i2c_clients[I2C_CLIENTS_MAX]; | 425 | struct i2c_client *i2c_clients[I2C_CLIENTS_MAX]; |
425 | 426 | ||
427 | /* gpio */ | ||
428 | u32 gpio_dir; | ||
429 | u32 gpio_val; | ||
430 | |||
426 | /* v4l2 and User settings */ | 431 | /* v4l2 and User settings */ |
427 | 432 | ||
428 | /* codec settings */ | 433 | /* codec settings */ |
diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/video/cx18/cx18-fileops.c index 0b3141db174b..1e537fe04a23 100644 --- a/drivers/media/video/cx18/cx18-fileops.c +++ b/drivers/media/video/cx18/cx18-fileops.c | |||
@@ -318,7 +318,7 @@ static ssize_t cx18_read(struct cx18_stream *s, char __user *ubuf, | |||
318 | size_t tot_written = 0; | 318 | size_t tot_written = 0; |
319 | int single_frame = 0; | 319 | int single_frame = 0; |
320 | 320 | ||
321 | if (atomic_read(&cx->capturing) == 0 && s->id == -1) { | 321 | if (atomic_read(&cx->ana_capturing) == 0 && s->id == -1) { |
322 | /* shouldn't happen */ | 322 | /* shouldn't happen */ |
323 | CX18_DEBUG_WARN("Stream %s not initialized before read\n", | 323 | CX18_DEBUG_WARN("Stream %s not initialized before read\n", |
324 | s->name); | 324 | s->name); |
@@ -361,7 +361,8 @@ static ssize_t cx18_read(struct cx18_stream *s, char __user *ubuf, | |||
361 | cx18_enqueue(s, buf, &s->q_free); | 361 | cx18_enqueue(s, buf, &s->q_free); |
362 | cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, | 362 | cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, |
363 | s->handle, | 363 | s->handle, |
364 | (void *)&cx->scb->cpu_mdl[buf->id] - cx->enc_mem, | 364 | (void __iomem *)&cx->scb->cpu_mdl[buf->id] - |
365 | cx->enc_mem, | ||
365 | 1, buf->id, s->buf_size); | 366 | 1, buf->id, s->buf_size); |
366 | } else | 367 | } else |
367 | cx18_enqueue(s, buf, &s->q_io); | 368 | cx18_enqueue(s, buf, &s->q_io); |
@@ -581,7 +582,7 @@ int cx18_v4l2_close(struct inode *inode, struct file *filp) | |||
581 | cx18_call_i2c_clients(cx, VIDIOC_S_STD, &cx->std); | 582 | cx18_call_i2c_clients(cx, VIDIOC_S_STD, &cx->std); |
582 | /* Select correct audio input (i.e. TV tuner or Line in) */ | 583 | /* Select correct audio input (i.e. TV tuner or Line in) */ |
583 | cx18_audio_set_io(cx); | 584 | cx18_audio_set_io(cx); |
584 | if (atomic_read(&cx->capturing) > 0) { | 585 | if (atomic_read(&cx->ana_capturing) > 0) { |
585 | /* Undo video mute */ | 586 | /* Undo video mute */ |
586 | cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, s->handle, | 587 | cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, s->handle, |
587 | cx->params.video_mute | | 588 | cx->params.video_mute | |
@@ -627,7 +628,7 @@ static int cx18_serialized_open(struct cx18_stream *s, struct file *filp) | |||
627 | } | 628 | } |
628 | 629 | ||
629 | if (!test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) { | 630 | if (!test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) { |
630 | if (atomic_read(&cx->capturing) > 0) { | 631 | if (atomic_read(&cx->ana_capturing) > 0) { |
631 | /* switching to radio while capture is | 632 | /* switching to radio while capture is |
632 | in progress is not polite */ | 633 | in progress is not polite */ |
633 | cx18_release_stream(s); | 634 | cx18_release_stream(s); |
@@ -694,7 +695,7 @@ int cx18_v4l2_open(struct inode *inode, struct file *filp) | |||
694 | 695 | ||
695 | void cx18_mute(struct cx18 *cx) | 696 | void cx18_mute(struct cx18 *cx) |
696 | { | 697 | { |
697 | if (atomic_read(&cx->capturing)) | 698 | if (atomic_read(&cx->ana_capturing)) |
698 | cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2, | 699 | cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2, |
699 | cx18_find_handle(cx), 1); | 700 | cx18_find_handle(cx), 1); |
700 | CX18_DEBUG_INFO("Mute\n"); | 701 | CX18_DEBUG_INFO("Mute\n"); |
@@ -702,7 +703,7 @@ void cx18_mute(struct cx18 *cx) | |||
702 | 703 | ||
703 | void cx18_unmute(struct cx18 *cx) | 704 | void cx18_unmute(struct cx18 *cx) |
704 | { | 705 | { |
705 | if (atomic_read(&cx->capturing)) { | 706 | if (atomic_read(&cx->ana_capturing)) { |
706 | cx18_msleep_timeout(100, 0); | 707 | cx18_msleep_timeout(100, 0); |
707 | cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2, | 708 | cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2, |
708 | cx18_find_handle(cx), 12); | 709 | cx18_find_handle(cx), 12); |
diff --git a/drivers/media/video/cx18/cx18-gpio.c b/drivers/media/video/cx18/cx18-gpio.c index bb8bc86086d0..ceb63653c926 100644 --- a/drivers/media/video/cx18/cx18-gpio.c +++ b/drivers/media/video/cx18/cx18-gpio.c | |||
@@ -35,9 +35,6 @@ | |||
35 | #define CX18_REG_GPIO_OUT2 0xc78104 | 35 | #define CX18_REG_GPIO_OUT2 0xc78104 |
36 | #define CX18_REG_GPIO_DIR2 0xc7810c | 36 | #define CX18_REG_GPIO_DIR2 0xc7810c |
37 | 37 | ||
38 | static u32 gpio_dir; | ||
39 | static u32 gpio_val; | ||
40 | |||
41 | /* | 38 | /* |
42 | * HVR-1600 GPIO pins, courtesy of Hauppauge: | 39 | * HVR-1600 GPIO pins, courtesy of Hauppauge: |
43 | * | 40 | * |
@@ -49,24 +46,29 @@ static u32 gpio_val; | |||
49 | 46 | ||
50 | static void gpio_write(struct cx18 *cx) | 47 | static void gpio_write(struct cx18 *cx) |
51 | { | 48 | { |
52 | write_reg((gpio_dir & 0xffff) << 16, CX18_REG_GPIO_DIR1); | 49 | u32 dir = cx->gpio_dir; |
53 | write_reg(((gpio_dir & 0xffff) << 16) | (gpio_val & 0xffff), | 50 | u32 val = cx->gpio_val; |
51 | |||
52 | write_reg((dir & 0xffff) << 16, CX18_REG_GPIO_DIR1); | ||
53 | write_reg(((dir & 0xffff) << 16) | (val & 0xffff), | ||
54 | CX18_REG_GPIO_OUT1); | 54 | CX18_REG_GPIO_OUT1); |
55 | write_reg(gpio_dir & 0xffff0000, CX18_REG_GPIO_DIR2); | 55 | write_reg(dir & 0xffff0000, CX18_REG_GPIO_DIR2); |
56 | write_reg((gpio_dir & 0xffff0000) | ((gpio_val & 0xffff0000) >> 16), | 56 | write_reg((dir & 0xffff0000) | ((val & 0xffff0000) >> 16), |
57 | CX18_REG_GPIO_OUT2); | 57 | CX18_REG_GPIO_OUT2); |
58 | } | 58 | } |
59 | 59 | ||
60 | void cx18_gpio_init(struct cx18 *cx) | 60 | void cx18_gpio_init(struct cx18 *cx) |
61 | { | 61 | { |
62 | gpio_dir = cx->card->gpio_init.direction; | 62 | cx->gpio_dir = cx->card->gpio_init.direction; |
63 | gpio_val = cx->card->gpio_init.initial_value; | 63 | cx->gpio_val = cx->card->gpio_init.initial_value; |
64 | 64 | ||
65 | if (gpio_dir == 0) | 65 | if (cx->card->tuners[0].tuner == TUNER_XC2028) { |
66 | return; | 66 | cx->gpio_dir |= 1 << cx->card->xceive_pin; |
67 | cx->gpio_val |= 1 << cx->card->xceive_pin; | ||
68 | } | ||
67 | 69 | ||
68 | gpio_dir |= 1 << cx->card->xceive_pin; | 70 | if (cx->gpio_dir == 0) |
69 | gpio_val |= 1 << cx->card->xceive_pin; | 71 | return; |
70 | 72 | ||
71 | CX18_DEBUG_INFO("GPIO initial dir: %08x/%08x out: %08x/%08x\n", | 73 | CX18_DEBUG_INFO("GPIO initial dir: %08x/%08x out: %08x/%08x\n", |
72 | read_reg(CX18_REG_GPIO_DIR1), read_reg(CX18_REG_GPIO_DIR2), | 74 | read_reg(CX18_REG_GPIO_DIR1), read_reg(CX18_REG_GPIO_DIR2), |
@@ -86,13 +88,12 @@ int cx18_reset_tuner_gpio(void *dev, int cmd, int value) | |||
86 | return 0; | 88 | return 0; |
87 | CX18_DEBUG_INFO("Resetting tuner\n"); | 89 | CX18_DEBUG_INFO("Resetting tuner\n"); |
88 | 90 | ||
89 | gpio_dir |= 1 << cx->card->xceive_pin; | 91 | cx->gpio_val &= ~(1 << cx->card->xceive_pin); |
90 | gpio_val &= ~(1 << cx->card->xceive_pin); | ||
91 | 92 | ||
92 | gpio_write(cx); | 93 | gpio_write(cx); |
93 | schedule_timeout_interruptible(msecs_to_jiffies(1)); | 94 | schedule_timeout_interruptible(msecs_to_jiffies(1)); |
94 | 95 | ||
95 | gpio_val |= 1 << cx->card->xceive_pin; | 96 | cx->gpio_val |= 1 << cx->card->xceive_pin; |
96 | gpio_write(cx); | 97 | gpio_write(cx); |
97 | schedule_timeout_interruptible(msecs_to_jiffies(1)); | 98 | schedule_timeout_interruptible(msecs_to_jiffies(1)); |
98 | return 0; | 99 | return 0; |
diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c index dbdcb86ec5aa..4151f1e5493f 100644 --- a/drivers/media/video/cx18/cx18-ioctl.c +++ b/drivers/media/video/cx18/cx18-ioctl.c | |||
@@ -247,7 +247,7 @@ static int cx18_try_or_set_fmt(struct cx18 *cx, int streamtype, | |||
247 | 247 | ||
248 | if (!set_fmt || (cx->params.width == w && cx->params.height == h)) | 248 | if (!set_fmt || (cx->params.width == w && cx->params.height == h)) |
249 | return 0; | 249 | return 0; |
250 | if (atomic_read(&cx->capturing) > 0) | 250 | if (atomic_read(&cx->ana_capturing) > 0) |
251 | return -EBUSY; | 251 | return -EBUSY; |
252 | 252 | ||
253 | cx->params.width = w; | 253 | cx->params.width = w; |
@@ -264,7 +264,7 @@ static int cx18_try_or_set_fmt(struct cx18 *cx, int streamtype, | |||
264 | if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) { | 264 | if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) { |
265 | if (set_fmt && streamtype == CX18_ENC_STREAM_TYPE_VBI && | 265 | if (set_fmt && streamtype == CX18_ENC_STREAM_TYPE_VBI && |
266 | cx->vbi.sliced_in->service_set && | 266 | cx->vbi.sliced_in->service_set && |
267 | atomic_read(&cx->capturing) > 0) | 267 | atomic_read(&cx->ana_capturing) > 0) |
268 | return -EBUSY; | 268 | return -EBUSY; |
269 | if (set_fmt) { | 269 | if (set_fmt) { |
270 | cx->vbi.sliced_in->service_set = 0; | 270 | cx->vbi.sliced_in->service_set = 0; |
@@ -293,7 +293,7 @@ static int cx18_try_or_set_fmt(struct cx18 *cx, int streamtype, | |||
293 | return 0; | 293 | return 0; |
294 | if (set == 0) | 294 | if (set == 0) |
295 | return -EINVAL; | 295 | return -EINVAL; |
296 | if (atomic_read(&cx->capturing) > 0 && cx->vbi.sliced_in->service_set == 0) | 296 | if (atomic_read(&cx->ana_capturing) > 0 && cx->vbi.sliced_in->service_set == 0) |
297 | return -EBUSY; | 297 | return -EBUSY; |
298 | cx18_av_cmd(cx, VIDIOC_S_FMT, fmt); | 298 | cx18_av_cmd(cx, VIDIOC_S_FMT, fmt); |
299 | memcpy(cx->vbi.sliced_in, vbifmt, sizeof(*cx->vbi.sliced_in)); | 299 | memcpy(cx->vbi.sliced_in, vbifmt, sizeof(*cx->vbi.sliced_in)); |
@@ -581,7 +581,7 @@ int cx18_v4l2_ioctls(struct cx18 *cx, struct file *filp, unsigned cmd, void *arg | |||
581 | break; | 581 | break; |
582 | 582 | ||
583 | if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) || | 583 | if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) || |
584 | atomic_read(&cx->capturing) > 0) { | 584 | atomic_read(&cx->ana_capturing) > 0) { |
585 | /* Switching standard would turn off the radio or mess | 585 | /* Switching standard would turn off the radio or mess |
586 | with already running streams, prevent that by | 586 | with already running streams, prevent that by |
587 | returning EBUSY. */ | 587 | returning EBUSY. */ |
@@ -677,7 +677,7 @@ int cx18_v4l2_ioctls(struct cx18 *cx, struct file *filp, unsigned cmd, void *arg | |||
677 | enc->flags = 0; | 677 | enc->flags = 0; |
678 | if (try) | 678 | if (try) |
679 | return 0; | 679 | return 0; |
680 | if (!atomic_read(&cx->capturing)) | 680 | if (!atomic_read(&cx->ana_capturing)) |
681 | return -EPERM; | 681 | return -EPERM; |
682 | if (test_and_set_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags)) | 682 | if (test_and_set_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags)) |
683 | return 0; | 683 | return 0; |
@@ -689,7 +689,7 @@ int cx18_v4l2_ioctls(struct cx18 *cx, struct file *filp, unsigned cmd, void *arg | |||
689 | enc->flags = 0; | 689 | enc->flags = 0; |
690 | if (try) | 690 | if (try) |
691 | return 0; | 691 | return 0; |
692 | if (!atomic_read(&cx->capturing)) | 692 | if (!atomic_read(&cx->ana_capturing)) |
693 | return -EPERM; | 693 | return -EPERM; |
694 | if (!test_and_clear_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags)) | 694 | if (!test_and_clear_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags)) |
695 | return 0; | 695 | return 0; |
diff --git a/drivers/media/video/cx18/cx18-irq.c b/drivers/media/video/cx18/cx18-irq.c index 6e14f8bda559..25114a5cbd57 100644 --- a/drivers/media/video/cx18/cx18-irq.c +++ b/drivers/media/video/cx18/cx18-irq.c | |||
@@ -75,7 +75,7 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_mailbox *mb) | |||
75 | 75 | ||
76 | cx18_buf_sync_for_device(s, buf); | 76 | cx18_buf_sync_for_device(s, buf); |
77 | cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle, | 77 | cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle, |
78 | (void *)&cx->scb->cpu_mdl[buf->id] - cx->enc_mem, | 78 | (void __iomem *)&cx->scb->cpu_mdl[buf->id] - cx->enc_mem, |
79 | 1, buf->id, s->buf_size); | 79 | 1, buf->id, s->buf_size); |
80 | } else | 80 | } else |
81 | set_bit(CX18_F_B_NEED_BUF_SWAP, &buf->b_flags); | 81 | set_bit(CX18_F_B_NEED_BUF_SWAP, &buf->b_flags); |
@@ -161,13 +161,15 @@ irqreturn_t cx18_irq_handler(int irq, void *dev_id) | |||
161 | */ | 161 | */ |
162 | 162 | ||
163 | if (sw2) { | 163 | if (sw2) { |
164 | if (sw2 & (cx->scb->cpu2hpu_irq_ack | cx->scb->cpu2epu_irq_ack)) | 164 | if (sw2 & (readl(&cx->scb->cpu2hpu_irq_ack) | |
165 | readl(&cx->scb->cpu2epu_irq_ack))) | ||
165 | wake_up(&cx->mb_cpu_waitq); | 166 | wake_up(&cx->mb_cpu_waitq); |
166 | if (sw2 & (cx->scb->apu2hpu_irq_ack | cx->scb->apu2epu_irq_ack)) | 167 | if (sw2 & (readl(&cx->scb->apu2hpu_irq_ack) | |
168 | readl(&cx->scb->apu2epu_irq_ack))) | ||
167 | wake_up(&cx->mb_apu_waitq); | 169 | wake_up(&cx->mb_apu_waitq); |
168 | if (sw2 & cx->scb->epu2hpu_irq_ack) | 170 | if (sw2 & readl(&cx->scb->epu2hpu_irq_ack)) |
169 | wake_up(&cx->mb_epu_waitq); | 171 | wake_up(&cx->mb_epu_waitq); |
170 | if (sw2 & cx->scb->hpu2epu_irq_ack) | 172 | if (sw2 & readl(&cx->scb->hpu2epu_irq_ack)) |
171 | wake_up(&cx->mb_hpu_waitq); | 173 | wake_up(&cx->mb_hpu_waitq); |
172 | } | 174 | } |
173 | 175 | ||
diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c index 0c5f328bca54..2a5ccef9185b 100644 --- a/drivers/media/video/cx18/cx18-mailbox.c +++ b/drivers/media/video/cx18/cx18-mailbox.c | |||
@@ -94,10 +94,10 @@ static const struct cx18_api_info *find_api_info(u32 cmd) | |||
94 | return NULL; | 94 | return NULL; |
95 | } | 95 | } |
96 | 96 | ||
97 | static struct cx18_mailbox *cx18_mb_is_complete(struct cx18 *cx, int rpu, | 97 | static struct cx18_mailbox __iomem *cx18_mb_is_complete(struct cx18 *cx, int rpu, |
98 | u32 *state, u32 *irq, u32 *req) | 98 | u32 *state, u32 *irq, u32 *req) |
99 | { | 99 | { |
100 | struct cx18_mailbox *mb = NULL; | 100 | struct cx18_mailbox __iomem *mb = NULL; |
101 | int wait_count = 0; | 101 | int wait_count = 0; |
102 | u32 ack; | 102 | u32 ack; |
103 | 103 | ||
@@ -142,7 +142,7 @@ static struct cx18_mailbox *cx18_mb_is_complete(struct cx18 *cx, int rpu, | |||
142 | long cx18_mb_ack(struct cx18 *cx, const struct cx18_mailbox *mb) | 142 | long cx18_mb_ack(struct cx18 *cx, const struct cx18_mailbox *mb) |
143 | { | 143 | { |
144 | const struct cx18_api_info *info = find_api_info(mb->cmd); | 144 | const struct cx18_api_info *info = find_api_info(mb->cmd); |
145 | struct cx18_mailbox *ack_mb; | 145 | struct cx18_mailbox __iomem *ack_mb; |
146 | u32 ack_irq; | 146 | u32 ack_irq; |
147 | u8 rpu = CPU; | 147 | u8 rpu = CPU; |
148 | 148 | ||
@@ -182,7 +182,7 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[]) | |||
182 | { | 182 | { |
183 | const struct cx18_api_info *info = find_api_info(cmd); | 183 | const struct cx18_api_info *info = find_api_info(cmd); |
184 | u32 state = 0, irq = 0, req, oldreq, err; | 184 | u32 state = 0, irq = 0, req, oldreq, err; |
185 | struct cx18_mailbox *mb; | 185 | struct cx18_mailbox __iomem *mb; |
186 | wait_queue_head_t *waitq; | 186 | wait_queue_head_t *waitq; |
187 | int timeout = 100; | 187 | int timeout = 100; |
188 | int cnt = 0; | 188 | int cnt = 0; |
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c index 4ca9d847f1b1..1b921a336092 100644 --- a/drivers/media/video/cx18/cx18-streams.c +++ b/drivers/media/video/cx18/cx18-streams.c | |||
@@ -36,12 +36,13 @@ | |||
36 | #define CX18_DSP0_INTERRUPT_MASK 0xd0004C | 36 | #define CX18_DSP0_INTERRUPT_MASK 0xd0004C |
37 | 37 | ||
38 | static struct file_operations cx18_v4l2_enc_fops = { | 38 | static struct file_operations cx18_v4l2_enc_fops = { |
39 | .owner = THIS_MODULE, | 39 | .owner = THIS_MODULE, |
40 | .read = cx18_v4l2_read, | 40 | .read = cx18_v4l2_read, |
41 | .open = cx18_v4l2_open, | 41 | .open = cx18_v4l2_open, |
42 | .ioctl = cx18_v4l2_ioctl, | 42 | .ioctl = cx18_v4l2_ioctl, |
43 | .release = cx18_v4l2_close, | 43 | .compat_ioctl = v4l_compat_ioctl32, |
44 | .poll = cx18_v4l2_enc_poll, | 44 | .release = cx18_v4l2_close, |
45 | .poll = cx18_v4l2_enc_poll, | ||
45 | }; | 46 | }; |
46 | 47 | ||
47 | /* offset from 0 to register ts v4l2 minors on */ | 48 | /* offset from 0 to register ts v4l2 minors on */ |
@@ -443,7 +444,7 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s) | |||
443 | s->handle = data[0]; | 444 | s->handle = data[0]; |
444 | cx18_vapi(cx, CX18_CPU_SET_CHANNEL_TYPE, 2, s->handle, captype); | 445 | cx18_vapi(cx, CX18_CPU_SET_CHANNEL_TYPE, 2, s->handle, captype); |
445 | 446 | ||
446 | if (atomic_read(&cx->capturing) == 0 && !ts) { | 447 | if (atomic_read(&cx->ana_capturing) == 0 && !ts) { |
447 | /* Stuff from Windows, we don't know what it is */ | 448 | /* Stuff from Windows, we don't know what it is */ |
448 | cx18_vapi(cx, CX18_CPU_SET_VER_CROP_LINE, 2, s->handle, 0); | 449 | cx18_vapi(cx, CX18_CPU_SET_VER_CROP_LINE, 2, s->handle, 0); |
449 | cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 3, 1); | 450 | cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 3, 1); |
@@ -466,14 +467,14 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s) | |||
466 | cx2341x_update(cx, cx18_api_func, NULL, &cx->params); | 467 | cx2341x_update(cx, cx18_api_func, NULL, &cx->params); |
467 | } | 468 | } |
468 | 469 | ||
469 | if (atomic_read(&cx->capturing) == 0) { | 470 | if (atomic_read(&cx->tot_capturing) == 0) { |
470 | clear_bit(CX18_F_I_EOS, &cx->i_flags); | 471 | clear_bit(CX18_F_I_EOS, &cx->i_flags); |
471 | write_reg(7, CX18_DSP0_INTERRUPT_MASK); | 472 | write_reg(7, CX18_DSP0_INTERRUPT_MASK); |
472 | } | 473 | } |
473 | 474 | ||
474 | cx18_vapi(cx, CX18_CPU_DE_SET_MDL_ACK, 3, s->handle, | 475 | cx18_vapi(cx, CX18_CPU_DE_SET_MDL_ACK, 3, s->handle, |
475 | (void *)&cx->scb->cpu_mdl_ack[s->type][0] - cx->enc_mem, | 476 | (void __iomem *)&cx->scb->cpu_mdl_ack[s->type][0] - cx->enc_mem, |
476 | (void *)&cx->scb->cpu_mdl_ack[s->type][1] - cx->enc_mem); | 477 | (void __iomem *)&cx->scb->cpu_mdl_ack[s->type][1] - cx->enc_mem); |
477 | 478 | ||
478 | list_for_each(p, &s->q_free.list) { | 479 | list_for_each(p, &s->q_free.list) { |
479 | struct cx18_buffer *buf = list_entry(p, struct cx18_buffer, list); | 480 | struct cx18_buffer *buf = list_entry(p, struct cx18_buffer, list); |
@@ -481,8 +482,8 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s) | |||
481 | writel(buf->dma_handle, &cx->scb->cpu_mdl[buf->id].paddr); | 482 | writel(buf->dma_handle, &cx->scb->cpu_mdl[buf->id].paddr); |
482 | writel(s->buf_size, &cx->scb->cpu_mdl[buf->id].length); | 483 | writel(s->buf_size, &cx->scb->cpu_mdl[buf->id].length); |
483 | cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle, | 484 | cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle, |
484 | (void *)&cx->scb->cpu_mdl[buf->id] - cx->enc_mem, 1, | 485 | (void __iomem *)&cx->scb->cpu_mdl[buf->id] - cx->enc_mem, |
485 | buf->id, s->buf_size); | 486 | 1, buf->id, s->buf_size); |
486 | } | 487 | } |
487 | /* begin_capture */ | 488 | /* begin_capture */ |
488 | if (cx18_vapi(cx, CX18_CPU_CAPTURE_START, 1, s->handle)) { | 489 | if (cx18_vapi(cx, CX18_CPU_CAPTURE_START, 1, s->handle)) { |
@@ -492,7 +493,9 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s) | |||
492 | } | 493 | } |
493 | 494 | ||
494 | /* you're live! sit back and await interrupts :) */ | 495 | /* you're live! sit back and await interrupts :) */ |
495 | atomic_inc(&cx->capturing); | 496 | if (!ts) |
497 | atomic_inc(&cx->ana_capturing); | ||
498 | atomic_inc(&cx->tot_capturing); | ||
496 | return 0; | 499 | return 0; |
497 | } | 500 | } |
498 | 501 | ||
@@ -523,7 +526,7 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end) | |||
523 | 526 | ||
524 | CX18_DEBUG_INFO("Stop Capture\n"); | 527 | CX18_DEBUG_INFO("Stop Capture\n"); |
525 | 528 | ||
526 | if (atomic_read(&cx->capturing) == 0) | 529 | if (atomic_read(&cx->tot_capturing) == 0) |
527 | return 0; | 530 | return 0; |
528 | 531 | ||
529 | if (s->type == CX18_ENC_STREAM_TYPE_MPG) | 532 | if (s->type == CX18_ENC_STREAM_TYPE_MPG) |
@@ -537,7 +540,9 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end) | |||
537 | CX18_INFO("ignoring gop_end: not (yet?) supported by the firmware\n"); | 540 | CX18_INFO("ignoring gop_end: not (yet?) supported by the firmware\n"); |
538 | } | 541 | } |
539 | 542 | ||
540 | atomic_dec(&cx->capturing); | 543 | if (s->type != CX18_ENC_STREAM_TYPE_TS) |
544 | atomic_dec(&cx->ana_capturing); | ||
545 | atomic_dec(&cx->tot_capturing); | ||
541 | 546 | ||
542 | /* Clear capture and no-read bits */ | 547 | /* Clear capture and no-read bits */ |
543 | clear_bit(CX18_F_S_STREAMING, &s->s_flags); | 548 | clear_bit(CX18_F_S_STREAMING, &s->s_flags); |
@@ -545,7 +550,7 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end) | |||
545 | cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle); | 550 | cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle); |
546 | s->handle = 0xffffffff; | 551 | s->handle = 0xffffffff; |
547 | 552 | ||
548 | if (atomic_read(&cx->capturing) > 0) | 553 | if (atomic_read(&cx->tot_capturing) > 0) |
549 | return 0; | 554 | return 0; |
550 | 555 | ||
551 | write_reg(5, CX18_DSP0_INTERRUPT_MASK); | 556 | write_reg(5, CX18_DSP0_INTERRUPT_MASK); |
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c index f24abcd06dea..c4cc2f3b8876 100644 --- a/drivers/media/video/cx23885/cx23885-core.c +++ b/drivers/media/video/cx23885/cx23885-core.c | |||
@@ -823,7 +823,7 @@ static void cx23885_dev_unregister(struct cx23885_dev *dev) | |||
823 | iounmap(dev->lmmio); | 823 | iounmap(dev->lmmio); |
824 | } | 824 | } |
825 | 825 | ||
826 | static u32* cx23885_risc_field(u32 *rp, struct scatterlist *sglist, | 826 | static __le32* cx23885_risc_field(__le32 *rp, struct scatterlist *sglist, |
827 | unsigned int offset, u32 sync_line, | 827 | unsigned int offset, u32 sync_line, |
828 | unsigned int bpl, unsigned int padding, | 828 | unsigned int bpl, unsigned int padding, |
829 | unsigned int lines) | 829 | unsigned int lines) |
@@ -883,7 +883,7 @@ int cx23885_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc, | |||
883 | unsigned int padding, unsigned int lines) | 883 | unsigned int padding, unsigned int lines) |
884 | { | 884 | { |
885 | u32 instructions, fields; | 885 | u32 instructions, fields; |
886 | u32 *rp; | 886 | __le32 *rp; |
887 | int rc; | 887 | int rc; |
888 | 888 | ||
889 | fields = 0; | 889 | fields = 0; |
@@ -924,7 +924,7 @@ static int cx23885_risc_databuffer(struct pci_dev *pci, | |||
924 | unsigned int lines) | 924 | unsigned int lines) |
925 | { | 925 | { |
926 | u32 instructions; | 926 | u32 instructions; |
927 | u32 *rp; | 927 | __le32 *rp; |
928 | int rc; | 928 | int rc; |
929 | 929 | ||
930 | /* estimate risc mem: worst case is one write per page border + | 930 | /* estimate risc mem: worst case is one write per page border + |
@@ -951,7 +951,7 @@ static int cx23885_risc_databuffer(struct pci_dev *pci, | |||
951 | int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc, | 951 | int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc, |
952 | u32 reg, u32 mask, u32 value) | 952 | u32 reg, u32 mask, u32 value) |
953 | { | 953 | { |
954 | u32 *rp; | 954 | __le32 *rp; |
955 | int rc; | 955 | int rc; |
956 | 956 | ||
957 | if ((rc = btcx_riscmem_alloc(pci, risc, 4*16)) < 0) | 957 | if ((rc = btcx_riscmem_alloc(pci, risc, 4*16)) < 0) |
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c index aeba26dc0a37..fa6d398e97b9 100644 --- a/drivers/media/video/cx88/cx88-cards.c +++ b/drivers/media/video/cx88/cx88-cards.c | |||
@@ -1493,10 +1493,16 @@ static const struct cx88_board cx88_boards[] = { | |||
1493 | }, | 1493 | }, |
1494 | }, | 1494 | }, |
1495 | [CX88_BOARD_POWERCOLOR_REAL_ANGEL] = { | 1495 | [CX88_BOARD_POWERCOLOR_REAL_ANGEL] = { |
1496 | .name = "PowerColor Real Angel 330", | 1496 | .name = "PowerColor RA330", /* Long names may confuse LIRC. */ |
1497 | .tuner_type = TUNER_XC2028, | 1497 | .tuner_type = TUNER_XC2028, |
1498 | .tuner_addr = 0x61, | 1498 | .tuner_addr = 0x61, |
1499 | .input = { { | 1499 | .input = { { |
1500 | .type = CX88_VMUX_DEBUG, | ||
1501 | .vmux = 3, /* Due to the way the cx88 driver is written, */ | ||
1502 | .gpio0 = 0x00ff, /* there is no way to deactivate audio pass- */ | ||
1503 | .gpio1 = 0xf39d, /* through without this entry. Furthermore, if */ | ||
1504 | .gpio3 = 0x0000, /* the TV mux entry is first, you get audio */ | ||
1505 | }, { /* from the tuner on boot for a little while. */ | ||
1500 | .type = CX88_VMUX_TELEVISION, | 1506 | .type = CX88_VMUX_TELEVISION, |
1501 | .vmux = 0, | 1507 | .vmux = 0, |
1502 | .gpio0 = 0x00ff, | 1508 | .gpio0 = 0x00ff, |
@@ -2424,8 +2430,9 @@ void cx88_setup_xc3028(struct cx88_core *core, struct xc2028_ctrl *ctl) | |||
2424 | 2430 | ||
2425 | switch (core->boardnr) { | 2431 | switch (core->boardnr) { |
2426 | case CX88_BOARD_POWERCOLOR_REAL_ANGEL: | 2432 | case CX88_BOARD_POWERCOLOR_REAL_ANGEL: |
2427 | /* Doesn't work with firmware version 2.7 */ | 2433 | /* Now works with firmware version 2.7 */ |
2428 | ctl->fname = "xc3028-v25.fw"; | 2434 | if (core->i2c_algo.udelay < 16) |
2435 | core->i2c_algo.udelay = 16; | ||
2429 | break; | 2436 | break; |
2430 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO: | 2437 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO: |
2431 | ctl->scode_table = XC3028_FE_ZARLINK456; | 2438 | ctl->scode_table = XC3028_FE_ZARLINK456; |
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c index c4d1aff1fdb4..60eeda3057e9 100644 --- a/drivers/media/video/cx88/cx88-core.c +++ b/drivers/media/video/cx88/cx88-core.c | |||
@@ -70,7 +70,7 @@ static DEFINE_MUTEX(devlist); | |||
70 | 70 | ||
71 | /* @lpi: lines per IRQ, or 0 to not generate irqs. Note: IRQ to be | 71 | /* @lpi: lines per IRQ, or 0 to not generate irqs. Note: IRQ to be |
72 | generated _after_ lpi lines are transferred. */ | 72 | generated _after_ lpi lines are transferred. */ |
73 | static u32* cx88_risc_field(u32 *rp, struct scatterlist *sglist, | 73 | static __le32* cx88_risc_field(__le32 *rp, struct scatterlist *sglist, |
74 | unsigned int offset, u32 sync_line, | 74 | unsigned int offset, u32 sync_line, |
75 | unsigned int bpl, unsigned int padding, | 75 | unsigned int bpl, unsigned int padding, |
76 | unsigned int lines, unsigned int lpi) | 76 | unsigned int lines, unsigned int lpi) |
@@ -130,7 +130,7 @@ int cx88_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc, | |||
130 | unsigned int bpl, unsigned int padding, unsigned int lines) | 130 | unsigned int bpl, unsigned int padding, unsigned int lines) |
131 | { | 131 | { |
132 | u32 instructions,fields; | 132 | u32 instructions,fields; |
133 | u32 *rp; | 133 | __le32 *rp; |
134 | int rc; | 134 | int rc; |
135 | 135 | ||
136 | fields = 0; | 136 | fields = 0; |
@@ -168,7 +168,7 @@ int cx88_risc_databuffer(struct pci_dev *pci, struct btcx_riscmem *risc, | |||
168 | unsigned int lines, unsigned int lpi) | 168 | unsigned int lines, unsigned int lpi) |
169 | { | 169 | { |
170 | u32 instructions; | 170 | u32 instructions; |
171 | u32 *rp; | 171 | __le32 *rp; |
172 | int rc; | 172 | int rc; |
173 | 173 | ||
174 | /* estimate risc mem: worst case is one write per page border + | 174 | /* estimate risc mem: worst case is one write per page border + |
@@ -193,7 +193,7 @@ int cx88_risc_databuffer(struct pci_dev *pci, struct btcx_riscmem *risc, | |||
193 | int cx88_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc, | 193 | int cx88_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc, |
194 | u32 reg, u32 mask, u32 value) | 194 | u32 reg, u32 mask, u32 value) |
195 | { | 195 | { |
196 | u32 *rp; | 196 | __le32 *rp; |
197 | int rc; | 197 | int rc; |
198 | 198 | ||
199 | if ((rc = btcx_riscmem_alloc(pci, risc, 4*16)) < 0) | 199 | if ((rc = btcx_riscmem_alloc(pci, risc, 4*16)) < 0) |
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index 8996175cc950..fb163ecd9216 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c | |||
@@ -1166,13 +1166,13 @@ static int vidioc_g_register(struct file *file, void *priv, | |||
1166 | 1166 | ||
1167 | reg->val = ret; | 1167 | reg->val = ret; |
1168 | } else { | 1168 | } else { |
1169 | u64 val = 0; | 1169 | __le64 val = 0; |
1170 | ret = em28xx_read_reg_req_len(dev, USB_REQ_GET_STATUS, | 1170 | ret = em28xx_read_reg_req_len(dev, USB_REQ_GET_STATUS, |
1171 | reg->reg, (char *)&val, 2); | 1171 | reg->reg, (char *)&val, 2); |
1172 | if (ret < 0) | 1172 | if (ret < 0) |
1173 | return ret; | 1173 | return ret; |
1174 | 1174 | ||
1175 | reg->val = cpu_to_le64((__u64)val); | 1175 | reg->val = le64_to_cpu(val); |
1176 | } | 1176 | } |
1177 | 1177 | ||
1178 | return 0; | 1178 | return 0; |
@@ -1183,9 +1183,9 @@ static int vidioc_s_register(struct file *file, void *priv, | |||
1183 | { | 1183 | { |
1184 | struct em28xx_fh *fh = priv; | 1184 | struct em28xx_fh *fh = priv; |
1185 | struct em28xx *dev = fh->dev; | 1185 | struct em28xx *dev = fh->dev; |
1186 | u64 buf; | 1186 | __le64 buf; |
1187 | 1187 | ||
1188 | buf = le64_to_cpu((__u64)reg->val); | 1188 | buf = cpu_to_le64(reg->val); |
1189 | 1189 | ||
1190 | return em28xx_write_regs(dev, reg->reg, (char *)&buf, | 1190 | return em28xx_write_regs(dev, reg->reg, (char *)&buf, |
1191 | em28xx_reg_len(reg->reg)); | 1191 | em28xx_reg_len(reg->reg)); |
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h index ba06e813c58c..9d23b1efd36d 100644 --- a/drivers/media/video/ivtv/ivtv-driver.h +++ b/drivers/media/video/ivtv/ivtv-driver.h | |||
@@ -259,6 +259,12 @@ struct ivtv_mailbox_data { | |||
259 | 259 | ||
260 | /* Scatter-Gather array element, used in DMA transfers */ | 260 | /* Scatter-Gather array element, used in DMA transfers */ |
261 | struct ivtv_sg_element { | 261 | struct ivtv_sg_element { |
262 | __le32 src; | ||
263 | __le32 dst; | ||
264 | __le32 size; | ||
265 | }; | ||
266 | |||
267 | struct ivtv_sg_host_element { | ||
262 | u32 src; | 268 | u32 src; |
263 | u32 dst; | 269 | u32 dst; |
264 | u32 size; | 270 | u32 size; |
@@ -349,8 +355,8 @@ struct ivtv_stream { | |||
349 | u16 dma_xfer_cnt; | 355 | u16 dma_xfer_cnt; |
350 | 356 | ||
351 | /* Base Dev SG Array for cx23415/6 */ | 357 | /* Base Dev SG Array for cx23415/6 */ |
352 | struct ivtv_sg_element *sg_pending; | 358 | struct ivtv_sg_host_element *sg_pending; |
353 | struct ivtv_sg_element *sg_processing; | 359 | struct ivtv_sg_host_element *sg_processing; |
354 | struct ivtv_sg_element *sg_dma; | 360 | struct ivtv_sg_element *sg_dma; |
355 | dma_addr_t sg_handle; | 361 | dma_addr_t sg_handle; |
356 | int sg_pending_size; | 362 | int sg_pending_size; |
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c index f2fa434b677b..db813e071ce6 100644 --- a/drivers/media/video/ivtv/ivtv-fileops.c +++ b/drivers/media/video/ivtv/ivtv-fileops.c | |||
@@ -587,7 +587,7 @@ retry: | |||
587 | since we may get here before the stream has been fully set-up */ | 587 | since we may get here before the stream has been fully set-up */ |
588 | if (mode == OUT_YUV && s->q_full.length == 0 && itv->dma_data_req_size) { | 588 | if (mode == OUT_YUV && s->q_full.length == 0 && itv->dma_data_req_size) { |
589 | while (count >= itv->dma_data_req_size) { | 589 | while (count >= itv->dma_data_req_size) { |
590 | if (!ivtv_yuv_udma_stream_frame (itv, (void *)user_buf)) { | 590 | if (!ivtv_yuv_udma_stream_frame (itv, (void __user *)user_buf)) { |
591 | bytes_written += itv->dma_data_req_size; | 591 | bytes_written += itv->dma_data_req_size; |
592 | user_buf += itv->dma_data_req_size; | 592 | user_buf += itv->dma_data_req_size; |
593 | count -= itv->dma_data_req_size; | 593 | count -= itv->dma_data_req_size; |
diff --git a/drivers/media/video/ivtv/ivtv-irq.c b/drivers/media/video/ivtv/ivtv-irq.c index d8ba3a4a8761..fba150a6cd23 100644 --- a/drivers/media/video/ivtv/ivtv-irq.c +++ b/drivers/media/video/ivtv/ivtv-irq.c | |||
@@ -231,14 +231,14 @@ static void dma_post(struct ivtv_stream *s) | |||
231 | struct ivtv_buffer *buf = NULL; | 231 | struct ivtv_buffer *buf = NULL; |
232 | struct list_head *p; | 232 | struct list_head *p; |
233 | u32 offset; | 233 | u32 offset; |
234 | u32 *u32buf; | 234 | __le32 *u32buf; |
235 | int x = 0; | 235 | int x = 0; |
236 | 236 | ||
237 | IVTV_DEBUG_HI_DMA("%s %s completed (%x)\n", ivtv_use_pio(s) ? "PIO" : "DMA", | 237 | IVTV_DEBUG_HI_DMA("%s %s completed (%x)\n", ivtv_use_pio(s) ? "PIO" : "DMA", |
238 | s->name, s->dma_offset); | 238 | s->name, s->dma_offset); |
239 | list_for_each(p, &s->q_dma.list) { | 239 | list_for_each(p, &s->q_dma.list) { |
240 | buf = list_entry(p, struct ivtv_buffer, list); | 240 | buf = list_entry(p, struct ivtv_buffer, list); |
241 | u32buf = (u32 *)buf->buf; | 241 | u32buf = (__le32 *)buf->buf; |
242 | 242 | ||
243 | /* Sync Buffer */ | 243 | /* Sync Buffer */ |
244 | ivtv_buf_sync_for_cpu(s, buf); | 244 | ivtv_buf_sync_for_cpu(s, buf); |
@@ -444,7 +444,7 @@ static void ivtv_dma_enc_start(struct ivtv_stream *s) | |||
444 | } | 444 | } |
445 | 445 | ||
446 | s->dma_xfer_cnt++; | 446 | s->dma_xfer_cnt++; |
447 | memcpy(s->sg_processing, s->sg_pending, sizeof(struct ivtv_sg_element) * s->sg_pending_size); | 447 | memcpy(s->sg_processing, s->sg_pending, sizeof(struct ivtv_sg_host_element) * s->sg_pending_size); |
448 | s->sg_processing_size = s->sg_pending_size; | 448 | s->sg_processing_size = s->sg_pending_size; |
449 | s->sg_pending_size = 0; | 449 | s->sg_pending_size = 0; |
450 | s->sg_processed = 0; | 450 | s->sg_processed = 0; |
@@ -473,7 +473,7 @@ static void ivtv_dma_dec_start(struct ivtv_stream *s) | |||
473 | if (s->q_predma.bytesused) | 473 | if (s->q_predma.bytesused) |
474 | ivtv_queue_move(s, &s->q_predma, NULL, &s->q_dma, s->q_predma.bytesused); | 474 | ivtv_queue_move(s, &s->q_predma, NULL, &s->q_dma, s->q_predma.bytesused); |
475 | s->dma_xfer_cnt++; | 475 | s->dma_xfer_cnt++; |
476 | memcpy(s->sg_processing, s->sg_pending, sizeof(struct ivtv_sg_element) * s->sg_pending_size); | 476 | memcpy(s->sg_processing, s->sg_pending, sizeof(struct ivtv_sg_host_element) * s->sg_pending_size); |
477 | s->sg_processing_size = s->sg_pending_size; | 477 | s->sg_processing_size = s->sg_pending_size; |
478 | s->sg_pending_size = 0; | 478 | s->sg_pending_size = 0; |
479 | s->sg_processed = 0; | 479 | s->sg_processed = 0; |
diff --git a/drivers/media/video/ivtv/ivtv-queue.c b/drivers/media/video/ivtv/ivtv-queue.c index fc8b1eaa333b..71bd13e22e2e 100644 --- a/drivers/media/video/ivtv/ivtv-queue.c +++ b/drivers/media/video/ivtv/ivtv-queue.c | |||
@@ -193,7 +193,7 @@ void ivtv_flush_queues(struct ivtv_stream *s) | |||
193 | int ivtv_stream_alloc(struct ivtv_stream *s) | 193 | int ivtv_stream_alloc(struct ivtv_stream *s) |
194 | { | 194 | { |
195 | struct ivtv *itv = s->itv; | 195 | struct ivtv *itv = s->itv; |
196 | int SGsize = sizeof(struct ivtv_sg_element) * s->buffers; | 196 | int SGsize = sizeof(struct ivtv_sg_host_element) * s->buffers; |
197 | int i; | 197 | int i; |
198 | 198 | ||
199 | if (s->buffers == 0) | 199 | if (s->buffers == 0) |
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c index c47c2b945147..c854285a4371 100644 --- a/drivers/media/video/ivtv/ivtv-streams.c +++ b/drivers/media/video/ivtv/ivtv-streams.c | |||
@@ -44,23 +44,25 @@ | |||
44 | #include "ivtv-streams.h" | 44 | #include "ivtv-streams.h" |
45 | 45 | ||
46 | static const struct file_operations ivtv_v4l2_enc_fops = { | 46 | static const struct file_operations ivtv_v4l2_enc_fops = { |
47 | .owner = THIS_MODULE, | 47 | .owner = THIS_MODULE, |
48 | .read = ivtv_v4l2_read, | 48 | .read = ivtv_v4l2_read, |
49 | .write = ivtv_v4l2_write, | 49 | .write = ivtv_v4l2_write, |
50 | .open = ivtv_v4l2_open, | 50 | .open = ivtv_v4l2_open, |
51 | .ioctl = ivtv_v4l2_ioctl, | 51 | .ioctl = ivtv_v4l2_ioctl, |
52 | .release = ivtv_v4l2_close, | 52 | .compat_ioctl = v4l_compat_ioctl32, |
53 | .poll = ivtv_v4l2_enc_poll, | 53 | .release = ivtv_v4l2_close, |
54 | .poll = ivtv_v4l2_enc_poll, | ||
54 | }; | 55 | }; |
55 | 56 | ||
56 | static const struct file_operations ivtv_v4l2_dec_fops = { | 57 | static const struct file_operations ivtv_v4l2_dec_fops = { |
57 | .owner = THIS_MODULE, | 58 | .owner = THIS_MODULE, |
58 | .read = ivtv_v4l2_read, | 59 | .read = ivtv_v4l2_read, |
59 | .write = ivtv_v4l2_write, | 60 | .write = ivtv_v4l2_write, |
60 | .open = ivtv_v4l2_open, | 61 | .open = ivtv_v4l2_open, |
61 | .ioctl = ivtv_v4l2_ioctl, | 62 | .ioctl = ivtv_v4l2_ioctl, |
62 | .release = ivtv_v4l2_close, | 63 | .compat_ioctl = v4l_compat_ioctl32, |
63 | .poll = ivtv_v4l2_dec_poll, | 64 | .release = ivtv_v4l2_close, |
65 | .poll = ivtv_v4l2_dec_poll, | ||
64 | }; | 66 | }; |
65 | 67 | ||
66 | #define IVTV_V4L2_DEC_MPG_OFFSET 16 /* offset from 0 to register decoder mpg v4l2 minors on */ | 68 | #define IVTV_V4L2_DEC_MPG_OFFSET 16 /* offset from 0 to register decoder mpg v4l2 minors on */ |
diff --git a/drivers/media/video/ivtv/ivtv-version.h b/drivers/media/video/ivtv/ivtv-version.h index 02c5ab071d1b..442f43f11b73 100644 --- a/drivers/media/video/ivtv/ivtv-version.h +++ b/drivers/media/video/ivtv/ivtv-version.h | |||
@@ -22,8 +22,8 @@ | |||
22 | 22 | ||
23 | #define IVTV_DRIVER_NAME "ivtv" | 23 | #define IVTV_DRIVER_NAME "ivtv" |
24 | #define IVTV_DRIVER_VERSION_MAJOR 1 | 24 | #define IVTV_DRIVER_VERSION_MAJOR 1 |
25 | #define IVTV_DRIVER_VERSION_MINOR 2 | 25 | #define IVTV_DRIVER_VERSION_MINOR 3 |
26 | #define IVTV_DRIVER_VERSION_PATCHLEVEL 1 | 26 | #define IVTV_DRIVER_VERSION_PATCHLEVEL 0 |
27 | 27 | ||
28 | #define IVTV_VERSION __stringify(IVTV_DRIVER_VERSION_MAJOR) "." __stringify(IVTV_DRIVER_VERSION_MINOR) "." __stringify(IVTV_DRIVER_VERSION_PATCHLEVEL) | 28 | #define IVTV_VERSION __stringify(IVTV_DRIVER_VERSION_MAJOR) "." __stringify(IVTV_DRIVER_VERSION_MINOR) "." __stringify(IVTV_DRIVER_VERSION_PATCHLEVEL) |
29 | #define IVTV_DRIVER_VERSION KERNEL_VERSION(IVTV_DRIVER_VERSION_MAJOR,IVTV_DRIVER_VERSION_MINOR,IVTV_DRIVER_VERSION_PATCHLEVEL) | 29 | #define IVTV_DRIVER_VERSION KERNEL_VERSION(IVTV_DRIVER_VERSION_MAJOR,IVTV_DRIVER_VERSION_MINOR,IVTV_DRIVER_VERSION_PATCHLEVEL) |
diff --git a/drivers/media/video/ivtv/ivtv-yuv.c b/drivers/media/video/ivtv/ivtv-yuv.c index a9417f6e4087..3092ff1d00a0 100644 --- a/drivers/media/video/ivtv/ivtv-yuv.c +++ b/drivers/media/video/ivtv/ivtv-yuv.c | |||
@@ -1116,7 +1116,7 @@ void ivtv_yuv_setup_stream_frame(struct ivtv *itv) | |||
1116 | } | 1116 | } |
1117 | 1117 | ||
1118 | /* Attempt to dma a frame from a user buffer */ | 1118 | /* Attempt to dma a frame from a user buffer */ |
1119 | int ivtv_yuv_udma_stream_frame(struct ivtv *itv, void *src) | 1119 | int ivtv_yuv_udma_stream_frame(struct ivtv *itv, void __user *src) |
1120 | { | 1120 | { |
1121 | struct yuv_playback_info *yi = &itv->yuv_info; | 1121 | struct yuv_playback_info *yi = &itv->yuv_info; |
1122 | struct ivtv_dma_frame dma_args; | 1122 | struct ivtv_dma_frame dma_args; |
diff --git a/drivers/media/video/ivtv/ivtv-yuv.h b/drivers/media/video/ivtv/ivtv-yuv.h index 2fe5f1250762..ca5173fbf006 100644 --- a/drivers/media/video/ivtv/ivtv-yuv.h +++ b/drivers/media/video/ivtv/ivtv-yuv.h | |||
@@ -35,7 +35,7 @@ extern const u32 yuv_offset[IVTV_YUV_BUFFERS]; | |||
35 | 35 | ||
36 | int ivtv_yuv_filter_check(struct ivtv *itv); | 36 | int ivtv_yuv_filter_check(struct ivtv *itv); |
37 | void ivtv_yuv_setup_stream_frame(struct ivtv *itv); | 37 | void ivtv_yuv_setup_stream_frame(struct ivtv *itv); |
38 | int ivtv_yuv_udma_stream_frame(struct ivtv *itv, void *src); | 38 | int ivtv_yuv_udma_stream_frame(struct ivtv *itv, void __user *src); |
39 | void ivtv_yuv_frame_complete(struct ivtv *itv); | 39 | void ivtv_yuv_frame_complete(struct ivtv *itv); |
40 | int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args); | 40 | int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args); |
41 | void ivtv_yuv_close(struct ivtv *itv); | 41 | void ivtv_yuv_close(struct ivtv *itv); |
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c index 1314522a8130..81431ee41842 100644 --- a/drivers/media/video/saa7134/saa7134-empress.c +++ b/drivers/media/video/saa7134/saa7134-empress.c | |||
@@ -163,8 +163,7 @@ ts_mmap(struct file *file, struct vm_area_struct * vma) | |||
163 | static int empress_querycap(struct file *file, void *priv, | 163 | static int empress_querycap(struct file *file, void *priv, |
164 | struct v4l2_capability *cap) | 164 | struct v4l2_capability *cap) |
165 | { | 165 | { |
166 | struct saa7134_fh *fh = priv; | 166 | struct saa7134_dev *dev = file->private_data; |
167 | struct saa7134_dev *dev = fh->dev; | ||
168 | 167 | ||
169 | strcpy(cap->driver, "saa7134"); | 168 | strcpy(cap->driver, "saa7134"); |
170 | strlcpy(cap->card, saa7134_boards[dev->board].name, | 169 | strlcpy(cap->card, saa7134_boards[dev->board].name, |
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index 198f0afb812e..0d12ace61665 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c | |||
@@ -92,6 +92,7 @@ struct tuner { | |||
92 | unsigned int type; /* chip type id */ | 92 | unsigned int type; /* chip type id */ |
93 | unsigned int config; | 93 | unsigned int config; |
94 | int (*tuner_callback) (void *dev, int command, int arg); | 94 | int (*tuner_callback) (void *dev, int command, int arg); |
95 | const char *name; | ||
95 | }; | 96 | }; |
96 | 97 | ||
97 | /* standard i2c insmod options */ | 98 | /* standard i2c insmod options */ |
@@ -330,13 +331,13 @@ static void tuner_i2c_address_check(struct tuner *t) | |||
330 | tuner_warn("Support for tuners in i2c address range 0x64 thru 0x6f\n"); | 331 | tuner_warn("Support for tuners in i2c address range 0x64 thru 0x6f\n"); |
331 | tuner_warn("will soon be dropped. This message indicates that your\n"); | 332 | tuner_warn("will soon be dropped. This message indicates that your\n"); |
332 | tuner_warn("hardware has a %s tuner at i2c address 0x%02x.\n", | 333 | tuner_warn("hardware has a %s tuner at i2c address 0x%02x.\n", |
333 | t->i2c->name, t->i2c->addr); | 334 | t->name, t->i2c->addr); |
334 | tuner_warn("To ensure continued support for your device, please\n"); | 335 | tuner_warn("To ensure continued support for your device, please\n"); |
335 | tuner_warn("send a copy of this message, along with full dmesg\n"); | 336 | tuner_warn("send a copy of this message, along with full dmesg\n"); |
336 | tuner_warn("output to v4l-dvb-maintainer@linuxtv.org\n"); | 337 | tuner_warn("output to v4l-dvb-maintainer@linuxtv.org\n"); |
337 | tuner_warn("Please use subject line: \"obsolete tuner i2c address.\"\n"); | 338 | tuner_warn("Please use subject line: \"obsolete tuner i2c address.\"\n"); |
338 | tuner_warn("driver: %s, addr: 0x%02x, type: %d (%s)\n", | 339 | tuner_warn("driver: %s, addr: 0x%02x, type: %d (%s)\n", |
339 | t->i2c->adapter->name, t->i2c->addr, t->type, t->i2c->name); | 340 | t->i2c->adapter->name, t->i2c->addr, t->type, t->name); |
340 | tuner_warn("====================== WARNING! ======================\n"); | 341 | tuner_warn("====================== WARNING! ======================\n"); |
341 | } | 342 | } |
342 | 343 | ||
@@ -470,19 +471,17 @@ static void set_type(struct i2c_client *c, unsigned int type, | |||
470 | if ((NULL == analog_ops->set_params) && | 471 | if ((NULL == analog_ops->set_params) && |
471 | (fe_tuner_ops->set_analog_params)) { | 472 | (fe_tuner_ops->set_analog_params)) { |
472 | 473 | ||
473 | strlcpy(t->i2c->name, fe_tuner_ops->info.name, | 474 | t->name = fe_tuner_ops->info.name; |
474 | sizeof(t->i2c->name)); | ||
475 | 475 | ||
476 | t->fe.analog_demod_priv = t; | 476 | t->fe.analog_demod_priv = t; |
477 | memcpy(analog_ops, &tuner_core_ops, | 477 | memcpy(analog_ops, &tuner_core_ops, |
478 | sizeof(struct analog_demod_ops)); | 478 | sizeof(struct analog_demod_ops)); |
479 | 479 | ||
480 | } else { | 480 | } else { |
481 | strlcpy(t->i2c->name, analog_ops->info.name, | 481 | t->name = analog_ops->info.name; |
482 | sizeof(t->i2c->name)); | ||
483 | } | 482 | } |
484 | 483 | ||
485 | tuner_dbg("type set to %s\n", t->i2c->name); | 484 | tuner_dbg("type set to %s\n", t->name); |
486 | 485 | ||
487 | if (t->mode_mask == T_UNINITIALIZED) | 486 | if (t->mode_mask == T_UNINITIALIZED) |
488 | t->mode_mask = new_mode_mask; | 487 | t->mode_mask = new_mode_mask; |
@@ -537,7 +536,7 @@ static void set_addr(struct i2c_client *c, struct tuner_setup *tun_setup) | |||
537 | static inline int check_mode(struct tuner *t, char *cmd) | 536 | static inline int check_mode(struct tuner *t, char *cmd) |
538 | { | 537 | { |
539 | if ((1 << t->mode & t->mode_mask) == 0) { | 538 | if ((1 << t->mode & t->mode_mask) == 0) { |
540 | return EINVAL; | 539 | return -EINVAL; |
541 | } | 540 | } |
542 | 541 | ||
543 | switch (t->mode) { | 542 | switch (t->mode) { |
@@ -731,11 +730,11 @@ static inline int set_mode(struct i2c_client *client, struct tuner *t, int mode, | |||
731 | 730 | ||
732 | t->mode = mode; | 731 | t->mode = mode; |
733 | 732 | ||
734 | if (check_mode(t, cmd) == EINVAL) { | 733 | if (check_mode(t, cmd) == -EINVAL) { |
735 | t->mode = T_STANDBY; | 734 | t->mode = T_STANDBY; |
736 | if (analog_ops->standby) | 735 | if (analog_ops->standby) |
737 | analog_ops->standby(&t->fe); | 736 | analog_ops->standby(&t->fe); |
738 | return EINVAL; | 737 | return -EINVAL; |
739 | } | 738 | } |
740 | return 0; | 739 | return 0; |
741 | } | 740 | } |
@@ -777,13 +776,13 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
777 | break; | 776 | break; |
778 | case AUDC_SET_RADIO: | 777 | case AUDC_SET_RADIO: |
779 | if (set_mode(client, t, V4L2_TUNER_RADIO, "AUDC_SET_RADIO") | 778 | if (set_mode(client, t, V4L2_TUNER_RADIO, "AUDC_SET_RADIO") |
780 | == EINVAL) | 779 | == -EINVAL) |
781 | return 0; | 780 | return 0; |
782 | if (t->radio_freq) | 781 | if (t->radio_freq) |
783 | set_freq(client, t->radio_freq); | 782 | set_freq(client, t->radio_freq); |
784 | break; | 783 | break; |
785 | case TUNER_SET_STANDBY: | 784 | case TUNER_SET_STANDBY: |
786 | if (check_mode(t, "TUNER_SET_STANDBY") == EINVAL) | 785 | if (check_mode(t, "TUNER_SET_STANDBY") == -EINVAL) |
787 | return 0; | 786 | return 0; |
788 | t->mode = T_STANDBY; | 787 | t->mode = T_STANDBY; |
789 | if (analog_ops->standby) | 788 | if (analog_ops->standby) |
@@ -791,9 +790,9 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
791 | break; | 790 | break; |
792 | #ifdef CONFIG_VIDEO_ALLOW_V4L1 | 791 | #ifdef CONFIG_VIDEO_ALLOW_V4L1 |
793 | case VIDIOCSAUDIO: | 792 | case VIDIOCSAUDIO: |
794 | if (check_mode(t, "VIDIOCSAUDIO") == EINVAL) | 793 | if (check_mode(t, "VIDIOCSAUDIO") == -EINVAL) |
795 | return 0; | 794 | return 0; |
796 | if (check_v4l2(t) == EINVAL) | 795 | if (check_v4l2(t) == -EINVAL) |
797 | return 0; | 796 | return 0; |
798 | 797 | ||
799 | /* Should be implemented, since bttv calls it */ | 798 | /* Should be implemented, since bttv calls it */ |
@@ -811,10 +810,10 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
811 | }; | 810 | }; |
812 | struct video_channel *vc = arg; | 811 | struct video_channel *vc = arg; |
813 | 812 | ||
814 | if (check_v4l2(t) == EINVAL) | 813 | if (check_v4l2(t) == -EINVAL) |
815 | return 0; | 814 | return 0; |
816 | 815 | ||
817 | if (set_mode(client,t,V4L2_TUNER_ANALOG_TV, "VIDIOCSCHAN")==EINVAL) | 816 | if (set_mode(client,t,V4L2_TUNER_ANALOG_TV, "VIDIOCSCHAN")==-EINVAL) |
818 | return 0; | 817 | return 0; |
819 | 818 | ||
820 | if (vc->norm < ARRAY_SIZE(map)) | 819 | if (vc->norm < ARRAY_SIZE(map)) |
@@ -828,9 +827,9 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
828 | { | 827 | { |
829 | unsigned long *v = arg; | 828 | unsigned long *v = arg; |
830 | 829 | ||
831 | if (check_mode(t, "VIDIOCSFREQ") == EINVAL) | 830 | if (check_mode(t, "VIDIOCSFREQ") == -EINVAL) |
832 | return 0; | 831 | return 0; |
833 | if (check_v4l2(t) == EINVAL) | 832 | if (check_v4l2(t) == -EINVAL) |
834 | return 0; | 833 | return 0; |
835 | 834 | ||
836 | set_freq(client, *v); | 835 | set_freq(client, *v); |
@@ -840,9 +839,9 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
840 | { | 839 | { |
841 | struct video_tuner *vt = arg; | 840 | struct video_tuner *vt = arg; |
842 | 841 | ||
843 | if (check_mode(t, "VIDIOCGTUNER") == EINVAL) | 842 | if (check_mode(t, "VIDIOCGTUNER") == -EINVAL) |
844 | return 0; | 843 | return 0; |
845 | if (check_v4l2(t) == EINVAL) | 844 | if (check_v4l2(t) == -EINVAL) |
846 | return 0; | 845 | return 0; |
847 | 846 | ||
848 | if (V4L2_TUNER_RADIO == t->mode) { | 847 | if (V4L2_TUNER_RADIO == t->mode) { |
@@ -884,9 +883,9 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
884 | { | 883 | { |
885 | struct video_audio *va = arg; | 884 | struct video_audio *va = arg; |
886 | 885 | ||
887 | if (check_mode(t, "VIDIOCGAUDIO") == EINVAL) | 886 | if (check_mode(t, "VIDIOCGAUDIO") == -EINVAL) |
888 | return 0; | 887 | return 0; |
889 | if (check_v4l2(t) == EINVAL) | 888 | if (check_v4l2(t) == -EINVAL) |
890 | return 0; | 889 | return 0; |
891 | 890 | ||
892 | if (V4L2_TUNER_RADIO == t->mode) { | 891 | if (V4L2_TUNER_RADIO == t->mode) { |
@@ -926,7 +925,7 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
926 | v4l2_std_id *id = arg; | 925 | v4l2_std_id *id = arg; |
927 | 926 | ||
928 | if (set_mode (client, t, V4L2_TUNER_ANALOG_TV, "VIDIOC_S_STD") | 927 | if (set_mode (client, t, V4L2_TUNER_ANALOG_TV, "VIDIOC_S_STD") |
929 | == EINVAL) | 928 | == -EINVAL) |
930 | return 0; | 929 | return 0; |
931 | 930 | ||
932 | switch_v4l2(); | 931 | switch_v4l2(); |
@@ -942,7 +941,7 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
942 | struct v4l2_frequency *f = arg; | 941 | struct v4l2_frequency *f = arg; |
943 | 942 | ||
944 | if (set_mode (client, t, f->type, "VIDIOC_S_FREQUENCY") | 943 | if (set_mode (client, t, f->type, "VIDIOC_S_FREQUENCY") |
945 | == EINVAL) | 944 | == -EINVAL) |
946 | return 0; | 945 | return 0; |
947 | switch_v4l2(); | 946 | switch_v4l2(); |
948 | set_freq(client,f->frequency); | 947 | set_freq(client,f->frequency); |
@@ -953,7 +952,7 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
953 | { | 952 | { |
954 | struct v4l2_frequency *f = arg; | 953 | struct v4l2_frequency *f = arg; |
955 | 954 | ||
956 | if (check_mode(t, "VIDIOC_G_FREQUENCY") == EINVAL) | 955 | if (check_mode(t, "VIDIOC_G_FREQUENCY") == -EINVAL) |
957 | return 0; | 956 | return 0; |
958 | switch_v4l2(); | 957 | switch_v4l2(); |
959 | f->type = t->mode; | 958 | f->type = t->mode; |
@@ -974,7 +973,7 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
974 | { | 973 | { |
975 | struct v4l2_tuner *tuner = arg; | 974 | struct v4l2_tuner *tuner = arg; |
976 | 975 | ||
977 | if (check_mode(t, "VIDIOC_G_TUNER") == EINVAL) | 976 | if (check_mode(t, "VIDIOC_G_TUNER") == -EINVAL) |
978 | return 0; | 977 | return 0; |
979 | switch_v4l2(); | 978 | switch_v4l2(); |
980 | 979 | ||
@@ -1021,7 +1020,7 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
1021 | { | 1020 | { |
1022 | struct v4l2_tuner *tuner = arg; | 1021 | struct v4l2_tuner *tuner = arg; |
1023 | 1022 | ||
1024 | if (check_mode(t, "VIDIOC_S_TUNER") == EINVAL) | 1023 | if (check_mode(t, "VIDIOC_S_TUNER") == -EINVAL) |
1025 | return 0; | 1024 | return 0; |
1026 | 1025 | ||
1027 | switch_v4l2(); | 1026 | switch_v4l2(); |
@@ -1115,6 +1114,7 @@ static int tuner_probe(struct i2c_client *client, | |||
1115 | if (NULL == t) | 1114 | if (NULL == t) |
1116 | return -ENOMEM; | 1115 | return -ENOMEM; |
1117 | t->i2c = client; | 1116 | t->i2c = client; |
1117 | t->name = "(tuner unset)"; | ||
1118 | i2c_set_clientdata(client, t); | 1118 | i2c_set_clientdata(client, t); |
1119 | t->type = UNSET; | 1119 | t->type = UNSET; |
1120 | t->audmode = V4L2_TUNER_MODE_STEREO; | 1120 | t->audmode = V4L2_TUNER_MODE_STEREO; |
@@ -1272,12 +1272,6 @@ static int tuner_remove(struct i2c_client *client) | |||
1272 | 1272 | ||
1273 | list_del(&t->list); | 1273 | list_del(&t->list); |
1274 | kfree(t); | 1274 | kfree(t); |
1275 | |||
1276 | /* The probing code has overwritten the device name, restore it so | ||
1277 | that reloading the driver will work. Ideally the device name | ||
1278 | should not be overwritten in the first place, but for now that | ||
1279 | will do. */ | ||
1280 | strlcpy(client->name, "tuner", I2C_NAME_SIZE); | ||
1281 | return 0; | 1275 | return 0; |
1282 | } | 1276 | } |
1283 | 1277 | ||
diff --git a/drivers/media/video/usbvideo/quickcam_messenger.c b/drivers/media/video/usbvideo/quickcam_messenger.c index 32e536edf09d..3d26a30abe1e 100644 --- a/drivers/media/video/usbvideo/quickcam_messenger.c +++ b/drivers/media/video/usbvideo/quickcam_messenger.c | |||
@@ -210,7 +210,7 @@ static int qcm_stv_setb(struct usb_device *dev, u16 reg, u8 val) | |||
210 | return ret; | 210 | return ret; |
211 | } | 211 | } |
212 | 212 | ||
213 | static int qcm_stv_setw(struct usb_device *dev, u16 reg, u16 val) | 213 | static int qcm_stv_setw(struct usb_device *dev, u16 reg, __le16 val) |
214 | { | 214 | { |
215 | int ret; | 215 | int ret; |
216 | 216 | ||
diff --git a/drivers/media/video/videobuf-core.c b/drivers/media/video/videobuf-core.c index 982f4463896c..0a88c44ace00 100644 --- a/drivers/media/video/videobuf-core.c +++ b/drivers/media/video/videobuf-core.c | |||
@@ -331,7 +331,7 @@ int videobuf_mmap_free(struct videobuf_queue *q) | |||
331 | } | 331 | } |
332 | 332 | ||
333 | /* Locking: Caller holds q->vb_lock */ | 333 | /* Locking: Caller holds q->vb_lock */ |
334 | static int __videobuf_mmap_setup(struct videobuf_queue *q, | 334 | int __videobuf_mmap_setup(struct videobuf_queue *q, |
335 | unsigned int bcount, unsigned int bsize, | 335 | unsigned int bcount, unsigned int bsize, |
336 | enum v4l2_memory memory) | 336 | enum v4l2_memory memory) |
337 | { | 337 | { |
@@ -1129,6 +1129,7 @@ EXPORT_SYMBOL_GPL(videobuf_read_stream); | |||
1129 | EXPORT_SYMBOL_GPL(videobuf_read_one); | 1129 | EXPORT_SYMBOL_GPL(videobuf_read_one); |
1130 | EXPORT_SYMBOL_GPL(videobuf_poll_stream); | 1130 | EXPORT_SYMBOL_GPL(videobuf_poll_stream); |
1131 | 1131 | ||
1132 | EXPORT_SYMBOL_GPL(__videobuf_mmap_setup); | ||
1132 | EXPORT_SYMBOL_GPL(videobuf_mmap_setup); | 1133 | EXPORT_SYMBOL_GPL(videobuf_mmap_setup); |
1133 | EXPORT_SYMBOL_GPL(videobuf_mmap_free); | 1134 | EXPORT_SYMBOL_GPL(videobuf_mmap_free); |
1134 | EXPORT_SYMBOL_GPL(videobuf_mmap_mapper); | 1135 | EXPORT_SYMBOL_GPL(videobuf_mmap_mapper); |
diff --git a/drivers/media/video/zoran.h b/drivers/media/video/zoran.h index 81cc3b00a079..46b7ad477ceb 100644 --- a/drivers/media/video/zoran.h +++ b/drivers/media/video/zoran.h | |||
@@ -285,7 +285,7 @@ struct zoran_mapping { | |||
285 | 285 | ||
286 | struct zoran_jpg_buffer { | 286 | struct zoran_jpg_buffer { |
287 | struct zoran_mapping *map; | 287 | struct zoran_mapping *map; |
288 | u32 *frag_tab; /* addresses of frag table */ | 288 | __le32 *frag_tab; /* addresses of frag table */ |
289 | u32 frag_tab_bus; /* same value cached to save time in ISR */ | 289 | u32 frag_tab_bus; /* same value cached to save time in ISR */ |
290 | enum zoran_buffer_state state; /* non-zero if corresponding buffer is in use in grab queue */ | 290 | enum zoran_buffer_state state; /* non-zero if corresponding buffer is in use in grab queue */ |
291 | struct zoran_sync bs; /* DONE: info to return to application */ | 291 | struct zoran_sync bs; /* DONE: info to return to application */ |
@@ -450,7 +450,7 @@ struct zoran { | |||
450 | unsigned long jpg_queued_num; /* count of frames queued since grab/play started */ | 450 | unsigned long jpg_queued_num; /* count of frames queued since grab/play started */ |
451 | 451 | ||
452 | /* zr36057's code buffer table */ | 452 | /* zr36057's code buffer table */ |
453 | u32 *stat_com; /* stat_com[i] is indexed by dma_head/tail & BUZ_MASK_STAT_COM */ | 453 | __le32 *stat_com; /* stat_com[i] is indexed by dma_head/tail & BUZ_MASK_STAT_COM */ |
454 | 454 | ||
455 | /* (value & BUZ_MASK_FRAME) corresponds to index in pend[] queue */ | 455 | /* (value & BUZ_MASK_FRAME) corresponds to index in pend[] queue */ |
456 | int jpg_pend[BUZ_MAX_FRAME]; | 456 | int jpg_pend[BUZ_MAX_FRAME]; |
diff --git a/drivers/media/video/zoran_device.c b/drivers/media/video/zoran_device.c index 37629ffd34c3..88d369708e4c 100644 --- a/drivers/media/video/zoran_device.c +++ b/drivers/media/video/zoran_device.c | |||
@@ -1320,7 +1320,7 @@ error_handler (struct zoran *zr, | |||
1320 | if (i) { | 1320 | if (i) { |
1321 | /* Rotate stat_comm entries to make current entry first */ | 1321 | /* Rotate stat_comm entries to make current entry first */ |
1322 | int j; | 1322 | int j; |
1323 | u32 bus_addr[BUZ_NUM_STAT_COM]; | 1323 | __le32 bus_addr[BUZ_NUM_STAT_COM]; |
1324 | 1324 | ||
1325 | /* Here we are copying the stat_com array, which | 1325 | /* Here we are copying the stat_com array, which |
1326 | * is already in little endian format, so | 1326 | * is already in little endian format, so |
diff --git a/drivers/media/video/zoran_driver.c b/drivers/media/video/zoran_driver.c index 345c77e46837..5394d7a5cfee 100644 --- a/drivers/media/video/zoran_driver.c +++ b/drivers/media/video/zoran_driver.c | |||
@@ -495,7 +495,7 @@ jpg_fbuffer_alloc (struct file *file) | |||
495 | jpg_fbuffer_free(file); | 495 | jpg_fbuffer_free(file); |
496 | return -ENOBUFS; | 496 | return -ENOBUFS; |
497 | } | 497 | } |
498 | fh->jpg_buffers.buffer[i].frag_tab = (u32 *) mem; | 498 | fh->jpg_buffers.buffer[i].frag_tab = (__le32 *) mem; |
499 | fh->jpg_buffers.buffer[i].frag_tab_bus = | 499 | fh->jpg_buffers.buffer[i].frag_tab_bus = |
500 | virt_to_bus((void *) mem); | 500 | virt_to_bus((void *) mem); |
501 | 501 | ||
@@ -1167,7 +1167,7 @@ zoran_close_end_session (struct file *file) | |||
1167 | 1167 | ||
1168 | /* v4l capture */ | 1168 | /* v4l capture */ |
1169 | if (fh->v4l_buffers.active != ZORAN_FREE) { | 1169 | if (fh->v4l_buffers.active != ZORAN_FREE) { |
1170 | long flags; | 1170 | unsigned long flags; |
1171 | 1171 | ||
1172 | spin_lock_irqsave(&zr->spinlock, flags); | 1172 | spin_lock_irqsave(&zr->spinlock, flags); |
1173 | zr36057_set_memgrab(zr, 0); | 1173 | zr36057_set_memgrab(zr, 0); |
@@ -3436,7 +3436,7 @@ zoran_do_ioctl (struct inode *inode, | |||
3436 | 3436 | ||
3437 | /* unload capture */ | 3437 | /* unload capture */ |
3438 | if (zr->v4l_memgrab_active) { | 3438 | if (zr->v4l_memgrab_active) { |
3439 | long flags; | 3439 | unsigned long flags; |
3440 | 3440 | ||
3441 | spin_lock_irqsave(&zr->spinlock, flags); | 3441 | spin_lock_irqsave(&zr->spinlock, flags); |
3442 | zr36057_set_memgrab(zr, 0); | 3442 | zr36057_set_memgrab(zr, 0); |
@@ -4375,7 +4375,7 @@ zoran_vm_close (struct vm_area_struct *vma) | |||
4375 | mutex_lock(&zr->resource_lock); | 4375 | mutex_lock(&zr->resource_lock); |
4376 | 4376 | ||
4377 | if (fh->v4l_buffers.active != ZORAN_FREE) { | 4377 | if (fh->v4l_buffers.active != ZORAN_FREE) { |
4378 | long flags; | 4378 | unsigned long flags; |
4379 | 4379 | ||
4380 | spin_lock_irqsave(&zr->spinlock, flags); | 4380 | spin_lock_irqsave(&zr->spinlock, flags); |
4381 | zr36057_set_memgrab(zr, 0); | 4381 | zr36057_set_memgrab(zr, 0); |
@@ -4506,7 +4506,7 @@ zoran_mmap (struct file *file, | |||
4506 | if (todo > fraglen) | 4506 | if (todo > fraglen) |
4507 | todo = fraglen; | 4507 | todo = fraglen; |
4508 | pos = | 4508 | pos = |
4509 | le32_to_cpu((unsigned long) fh->jpg_buffers. | 4509 | le32_to_cpu(fh->jpg_buffers. |
4510 | buffer[i].frag_tab[2 * j]); | 4510 | buffer[i].frag_tab[2 * j]); |
4511 | /* should just be pos on i386 */ | 4511 | /* should just be pos on i386 */ |
4512 | page = virt_to_phys(bus_to_virt(pos)) | 4512 | page = virt_to_phys(bus_to_virt(pos)) |
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c index 3cdd4e962115..1e24ab4ac38c 100644 --- a/drivers/message/fusion/mptfc.c +++ b/drivers/message/fusion/mptfc.c | |||
@@ -1238,8 +1238,6 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1238 | sh->max_id = ioc->pfacts->MaxDevices; | 1238 | sh->max_id = ioc->pfacts->MaxDevices; |
1239 | sh->max_lun = max_lun; | 1239 | sh->max_lun = max_lun; |
1240 | 1240 | ||
1241 | sh->this_id = ioc->pfacts[0].PortSCSIID; | ||
1242 | |||
1243 | /* Required entry. | 1241 | /* Required entry. |
1244 | */ | 1242 | */ |
1245 | sh->unique_id = ioc->id; | 1243 | sh->unique_id = ioc->id; |
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index 468480771f13..4d492ba232b0 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c | |||
@@ -3193,8 +3193,6 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
3193 | 3193 | ||
3194 | sh->transportt = mptsas_transport_template; | 3194 | sh->transportt = mptsas_transport_template; |
3195 | 3195 | ||
3196 | sh->this_id = ioc->pfacts[0].PortSCSIID; | ||
3197 | |||
3198 | /* Required entry. | 3196 | /* Required entry. |
3199 | */ | 3197 | */ |
3200 | sh->unique_id = ioc->id; | 3198 | sh->unique_id = ioc->id; |
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index b109bd8a4d19..c68ef00c2f92 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c | |||
@@ -2451,12 +2451,6 @@ mptscsih_slave_configure(struct scsi_device *sdev) | |||
2451 | ioc->name, sdev->sdtr, sdev->wdtr, | 2451 | ioc->name, sdev->sdtr, sdev->wdtr, |
2452 | sdev->ppr, sdev->inquiry_len)); | 2452 | sdev->ppr, sdev->inquiry_len)); |
2453 | 2453 | ||
2454 | if (sdev->id > sh->max_id) { | ||
2455 | /* error case, should never happen */ | ||
2456 | scsi_adjust_queue_depth(sdev, 0, 1); | ||
2457 | goto slave_configure_exit; | ||
2458 | } | ||
2459 | |||
2460 | vdevice->configured_lun = 1; | 2454 | vdevice->configured_lun = 1; |
2461 | mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH); | 2455 | mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH); |
2462 | 2456 | ||
@@ -2470,8 +2464,6 @@ mptscsih_slave_configure(struct scsi_device *sdev) | |||
2470 | ioc->name, vtarget->negoFlags, vtarget->maxOffset, | 2464 | ioc->name, vtarget->negoFlags, vtarget->maxOffset, |
2471 | vtarget->minSyncFactor)); | 2465 | vtarget->minSyncFactor)); |
2472 | 2466 | ||
2473 | slave_configure_exit: | ||
2474 | |||
2475 | dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT | 2467 | dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT |
2476 | "tagged %d, simple %d, ordered %d\n", | 2468 | "tagged %d, simple %d, ordered %d\n", |
2477 | ioc->name,sdev->tagged_supported, sdev->simple_tags, | 2469 | ioc->name,sdev->tagged_supported, sdev->simple_tags, |
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 2566479937c9..ae96bd6242f2 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig | |||
@@ -24,7 +24,7 @@ config MFD_ASIC3 | |||
24 | 24 | ||
25 | config HTC_EGPIO | 25 | config HTC_EGPIO |
26 | bool "HTC EGPIO support" | 26 | bool "HTC EGPIO support" |
27 | depends on GENERIC_HARDIRQS && HAVE_GPIO_LIB | 27 | depends on GENERIC_HARDIRQS && HAVE_GPIO_LIB && ARM |
28 | help | 28 | help |
29 | This driver supports the CPLD egpio chip present on | 29 | This driver supports the CPLD egpio chip present on |
30 | several HTC phones. It provides basic support for input | 30 | several HTC phones. It provides basic support for input |
diff --git a/drivers/misc/fujitsu-laptop.c b/drivers/misc/fujitsu-laptop.c index e2e7c05a147b..6d14e8fe1537 100644 --- a/drivers/misc/fujitsu-laptop.c +++ b/drivers/misc/fujitsu-laptop.c | |||
@@ -352,3 +352,9 @@ MODULE_AUTHOR("Jonathan Woithe"); | |||
352 | MODULE_DESCRIPTION("Fujitsu laptop extras support"); | 352 | MODULE_DESCRIPTION("Fujitsu laptop extras support"); |
353 | MODULE_VERSION(FUJITSU_DRIVER_VERSION); | 353 | MODULE_VERSION(FUJITSU_DRIVER_VERSION); |
354 | MODULE_LICENSE("GPL"); | 354 | MODULE_LICENSE("GPL"); |
355 | |||
356 | static struct pnp_device_id pnp_ids[] = { | ||
357 | { .id = "FUJ02bf" }, | ||
358 | { .id = "" } | ||
359 | }; | ||
360 | MODULE_DEVICE_TABLE(pnp, pnp_ids); | ||
diff --git a/drivers/misc/kgdbts.c b/drivers/misc/kgdbts.c index fa394104339c..e4ff50b95a5e 100644 --- a/drivers/misc/kgdbts.c +++ b/drivers/misc/kgdbts.c | |||
@@ -102,7 +102,6 @@ | |||
102 | #include <linux/nmi.h> | 102 | #include <linux/nmi.h> |
103 | #include <linux/delay.h> | 103 | #include <linux/delay.h> |
104 | #include <linux/kthread.h> | 104 | #include <linux/kthread.h> |
105 | #include <linux/delay.h> | ||
106 | 105 | ||
107 | #define v1printk(a...) do { \ | 106 | #define v1printk(a...) do { \ |
108 | if (verbose) \ | 107 | if (verbose) \ |
@@ -119,7 +118,6 @@ | |||
119 | } while (0) | 118 | } while (0) |
120 | #define MAX_CONFIG_LEN 40 | 119 | #define MAX_CONFIG_LEN 40 |
121 | 120 | ||
122 | static const char hexchars[] = "0123456789abcdef"; | ||
123 | static struct kgdb_io kgdbts_io_ops; | 121 | static struct kgdb_io kgdbts_io_ops; |
124 | static char get_buf[BUFMAX]; | 122 | static char get_buf[BUFMAX]; |
125 | static int get_buf_cnt; | 123 | static int get_buf_cnt; |
@@ -131,6 +129,8 @@ static int repeat_test; | |||
131 | static int test_complete; | 129 | static int test_complete; |
132 | static int send_ack; | 130 | static int send_ack; |
133 | static int final_ack; | 131 | static int final_ack; |
132 | static int force_hwbrks; | ||
133 | static int hwbreaks_ok; | ||
134 | static int hw_break_val; | 134 | static int hw_break_val; |
135 | static int hw_break_val2; | 135 | static int hw_break_val2; |
136 | #if defined(CONFIG_ARM) || defined(CONFIG_MIPS) || defined(CONFIG_SPARC) | 136 | #if defined(CONFIG_ARM) || defined(CONFIG_MIPS) || defined(CONFIG_SPARC) |
@@ -234,12 +234,12 @@ static void break_helper(char *bp_type, char *arg, unsigned long vaddr) | |||
234 | 234 | ||
235 | static void sw_break(char *arg) | 235 | static void sw_break(char *arg) |
236 | { | 236 | { |
237 | break_helper("Z0", arg, 0); | 237 | break_helper(force_hwbrks ? "Z1" : "Z0", arg, 0); |
238 | } | 238 | } |
239 | 239 | ||
240 | static void sw_rem_break(char *arg) | 240 | static void sw_rem_break(char *arg) |
241 | { | 241 | { |
242 | break_helper("z0", arg, 0); | 242 | break_helper(force_hwbrks ? "z1" : "z0", arg, 0); |
243 | } | 243 | } |
244 | 244 | ||
245 | static void hw_break(char *arg) | 245 | static void hw_break(char *arg) |
@@ -619,8 +619,8 @@ static void fill_get_buf(char *buf) | |||
619 | count++; | 619 | count++; |
620 | } | 620 | } |
621 | strcat(get_buf, "#"); | 621 | strcat(get_buf, "#"); |
622 | get_buf[count + 2] = hexchars[checksum >> 4]; | 622 | get_buf[count + 2] = hex_asc_hi(checksum); |
623 | get_buf[count + 3] = hexchars[checksum & 0xf]; | 623 | get_buf[count + 3] = hex_asc_lo(checksum); |
624 | get_buf[count + 4] = '\0'; | 624 | get_buf[count + 4] = '\0'; |
625 | v2printk("get%i: %s\n", ts.idx, get_buf); | 625 | v2printk("get%i: %s\n", ts.idx, get_buf); |
626 | } | 626 | } |
@@ -781,6 +781,8 @@ static void run_breakpoint_test(int is_hw_breakpoint) | |||
781 | return; | 781 | return; |
782 | 782 | ||
783 | eprintk("kgdbts: ERROR %s test failed\n", ts.name); | 783 | eprintk("kgdbts: ERROR %s test failed\n", ts.name); |
784 | if (is_hw_breakpoint) | ||
785 | hwbreaks_ok = 0; | ||
784 | } | 786 | } |
785 | 787 | ||
786 | static void run_hw_break_test(int is_write_test) | 788 | static void run_hw_break_test(int is_write_test) |
@@ -798,9 +800,11 @@ static void run_hw_break_test(int is_write_test) | |||
798 | kgdb_breakpoint(); | 800 | kgdb_breakpoint(); |
799 | hw_break_val_access(); | 801 | hw_break_val_access(); |
800 | if (is_write_test) { | 802 | if (is_write_test) { |
801 | if (test_complete == 2) | 803 | if (test_complete == 2) { |
802 | eprintk("kgdbts: ERROR %s broke on access\n", | 804 | eprintk("kgdbts: ERROR %s broke on access\n", |
803 | ts.name); | 805 | ts.name); |
806 | hwbreaks_ok = 0; | ||
807 | } | ||
804 | hw_break_val_write(); | 808 | hw_break_val_write(); |
805 | } | 809 | } |
806 | kgdb_breakpoint(); | 810 | kgdb_breakpoint(); |
@@ -809,6 +813,7 @@ static void run_hw_break_test(int is_write_test) | |||
809 | return; | 813 | return; |
810 | 814 | ||
811 | eprintk("kgdbts: ERROR %s test failed\n", ts.name); | 815 | eprintk("kgdbts: ERROR %s test failed\n", ts.name); |
816 | hwbreaks_ok = 0; | ||
812 | } | 817 | } |
813 | 818 | ||
814 | static void run_nmi_sleep_test(int nmi_sleep) | 819 | static void run_nmi_sleep_test(int nmi_sleep) |
@@ -912,6 +917,7 @@ static void kgdbts_run_tests(void) | |||
912 | 917 | ||
913 | /* All HW break point tests */ | 918 | /* All HW break point tests */ |
914 | if (arch_kgdb_ops.flags & KGDB_HW_BREAKPOINT) { | 919 | if (arch_kgdb_ops.flags & KGDB_HW_BREAKPOINT) { |
920 | hwbreaks_ok = 1; | ||
915 | v1printk("kgdbts:RUN hw breakpoint test\n"); | 921 | v1printk("kgdbts:RUN hw breakpoint test\n"); |
916 | run_breakpoint_test(1); | 922 | run_breakpoint_test(1); |
917 | v1printk("kgdbts:RUN hw write breakpoint test\n"); | 923 | v1printk("kgdbts:RUN hw write breakpoint test\n"); |
@@ -925,6 +931,19 @@ static void kgdbts_run_tests(void) | |||
925 | run_nmi_sleep_test(nmi_sleep); | 931 | run_nmi_sleep_test(nmi_sleep); |
926 | } | 932 | } |
927 | 933 | ||
934 | #ifdef CONFIG_DEBUG_RODATA | ||
935 | /* Until there is an api to write to read-only text segments, use | ||
936 | * HW breakpoints for the remainder of any tests, else print a | ||
937 | * failure message if hw breakpoints do not work. | ||
938 | */ | ||
939 | if (!(arch_kgdb_ops.flags & KGDB_HW_BREAKPOINT && hwbreaks_ok)) { | ||
940 | eprintk("kgdbts: HW breakpoints do not work," | ||
941 | "skipping remaining tests\n"); | ||
942 | return; | ||
943 | } | ||
944 | force_hwbrks = 1; | ||
945 | #endif /* CONFIG_DEBUG_RODATA */ | ||
946 | |||
928 | /* If the do_fork test is run it will be the last test that is | 947 | /* If the do_fork test is run it will be the last test that is |
929 | * executed because a kernel thread will be spawned at the very | 948 | * executed because a kernel thread will be spawned at the very |
930 | * end to unregister the debug hooks. | 949 | * end to unregister the debug hooks. |
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c index 3f28f6eabdbf..b5969298f3d3 100644 --- a/drivers/misc/thinkpad_acpi.c +++ b/drivers/misc/thinkpad_acpi.c | |||
@@ -1293,7 +1293,7 @@ static void tpacpi_input_send_radiosw(void) | |||
1293 | mutex_lock(&tpacpi_inputdev_send_mutex); | 1293 | mutex_lock(&tpacpi_inputdev_send_mutex); |
1294 | 1294 | ||
1295 | input_report_switch(tpacpi_inputdev, | 1295 | input_report_switch(tpacpi_inputdev, |
1296 | SW_RADIO, !!wlsw); | 1296 | SW_RFKILL_ALL, !!wlsw); |
1297 | input_sync(tpacpi_inputdev); | 1297 | input_sync(tpacpi_inputdev); |
1298 | 1298 | ||
1299 | mutex_unlock(&tpacpi_inputdev_send_mutex); | 1299 | mutex_unlock(&tpacpi_inputdev_send_mutex); |
@@ -1921,6 +1921,29 @@ static struct attribute *hotkey_mask_attributes[] __initdata = { | |||
1921 | &dev_attr_hotkey_wakeup_hotunplug_complete.attr, | 1921 | &dev_attr_hotkey_wakeup_hotunplug_complete.attr, |
1922 | }; | 1922 | }; |
1923 | 1923 | ||
1924 | static void hotkey_exit(void) | ||
1925 | { | ||
1926 | #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL | ||
1927 | hotkey_poll_stop_sync(); | ||
1928 | #endif | ||
1929 | |||
1930 | if (hotkey_dev_attributes) | ||
1931 | delete_attr_set(hotkey_dev_attributes, &tpacpi_pdev->dev.kobj); | ||
1932 | |||
1933 | kfree(hotkey_keycode_map); | ||
1934 | |||
1935 | if (tp_features.hotkey) { | ||
1936 | dbg_printk(TPACPI_DBG_EXIT, | ||
1937 | "restoring original hot key mask\n"); | ||
1938 | /* no short-circuit boolean operator below! */ | ||
1939 | if ((hotkey_mask_set(hotkey_orig_mask) | | ||
1940 | hotkey_status_set(hotkey_orig_status)) != 0) | ||
1941 | printk(TPACPI_ERR | ||
1942 | "failed to restore hot key mask " | ||
1943 | "to BIOS defaults\n"); | ||
1944 | } | ||
1945 | } | ||
1946 | |||
1924 | static int __init hotkey_init(struct ibm_init_struct *iibm) | 1947 | static int __init hotkey_init(struct ibm_init_struct *iibm) |
1925 | { | 1948 | { |
1926 | /* Requirements for changing the default keymaps: | 1949 | /* Requirements for changing the default keymaps: |
@@ -2060,226 +2083,220 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
2060 | vdbg_printk(TPACPI_DBG_INIT, "hotkeys are %s\n", | 2083 | vdbg_printk(TPACPI_DBG_INIT, "hotkeys are %s\n", |
2061 | str_supported(tp_features.hotkey)); | 2084 | str_supported(tp_features.hotkey)); |
2062 | 2085 | ||
2063 | if (tp_features.hotkey) { | 2086 | if (!tp_features.hotkey) |
2064 | hotkey_dev_attributes = create_attr_set(13, NULL); | 2087 | return 1; |
2065 | if (!hotkey_dev_attributes) | ||
2066 | return -ENOMEM; | ||
2067 | res = add_many_to_attr_set(hotkey_dev_attributes, | ||
2068 | hotkey_attributes, | ||
2069 | ARRAY_SIZE(hotkey_attributes)); | ||
2070 | if (res) | ||
2071 | return res; | ||
2072 | 2088 | ||
2073 | /* mask not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p, | 2089 | hotkey_dev_attributes = create_attr_set(13, NULL); |
2074 | A30, R30, R31, T20-22, X20-21, X22-24. Detected by checking | 2090 | if (!hotkey_dev_attributes) |
2075 | for HKEY interface version 0x100 */ | 2091 | return -ENOMEM; |
2076 | if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) { | 2092 | res = add_many_to_attr_set(hotkey_dev_attributes, |
2077 | if ((hkeyv >> 8) != 1) { | 2093 | hotkey_attributes, |
2078 | printk(TPACPI_ERR "unknown version of the " | 2094 | ARRAY_SIZE(hotkey_attributes)); |
2079 | "HKEY interface: 0x%x\n", hkeyv); | 2095 | if (res) |
2080 | printk(TPACPI_ERR "please report this to %s\n", | 2096 | goto err_exit; |
2081 | TPACPI_MAIL); | 2097 | |
2082 | } else { | 2098 | /* mask not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p, |
2083 | /* | 2099 | A30, R30, R31, T20-22, X20-21, X22-24. Detected by checking |
2084 | * MHKV 0x100 in A31, R40, R40e, | 2100 | for HKEY interface version 0x100 */ |
2085 | * T4x, X31, and later | 2101 | if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) { |
2086 | */ | 2102 | if ((hkeyv >> 8) != 1) { |
2087 | tp_features.hotkey_mask = 1; | 2103 | printk(TPACPI_ERR "unknown version of the " |
2088 | } | 2104 | "HKEY interface: 0x%x\n", hkeyv); |
2105 | printk(TPACPI_ERR "please report this to %s\n", | ||
2106 | TPACPI_MAIL); | ||
2107 | } else { | ||
2108 | /* | ||
2109 | * MHKV 0x100 in A31, R40, R40e, | ||
2110 | * T4x, X31, and later | ||
2111 | */ | ||
2112 | tp_features.hotkey_mask = 1; | ||
2089 | } | 2113 | } |
2114 | } | ||
2090 | 2115 | ||
2091 | vdbg_printk(TPACPI_DBG_INIT, "hotkey masks are %s\n", | 2116 | vdbg_printk(TPACPI_DBG_INIT, "hotkey masks are %s\n", |
2092 | str_supported(tp_features.hotkey_mask)); | 2117 | str_supported(tp_features.hotkey_mask)); |
2093 | 2118 | ||
2094 | if (tp_features.hotkey_mask) { | 2119 | if (tp_features.hotkey_mask) { |
2095 | if (!acpi_evalf(hkey_handle, &hotkey_all_mask, | 2120 | if (!acpi_evalf(hkey_handle, &hotkey_all_mask, |
2096 | "MHKA", "qd")) { | 2121 | "MHKA", "qd")) { |
2097 | printk(TPACPI_ERR | 2122 | printk(TPACPI_ERR |
2098 | "missing MHKA handler, " | 2123 | "missing MHKA handler, " |
2099 | "please report this to %s\n", | 2124 | "please report this to %s\n", |
2100 | TPACPI_MAIL); | 2125 | TPACPI_MAIL); |
2101 | /* FN+F12, FN+F4, FN+F3 */ | 2126 | /* FN+F12, FN+F4, FN+F3 */ |
2102 | hotkey_all_mask = 0x080cU; | 2127 | hotkey_all_mask = 0x080cU; |
2103 | } | ||
2104 | } | 2128 | } |
2129 | } | ||
2105 | 2130 | ||
2106 | /* hotkey_source_mask *must* be zero for | 2131 | /* hotkey_source_mask *must* be zero for |
2107 | * the first hotkey_mask_get */ | 2132 | * the first hotkey_mask_get */ |
2108 | res = hotkey_status_get(&hotkey_orig_status); | 2133 | res = hotkey_status_get(&hotkey_orig_status); |
2109 | if (!res && tp_features.hotkey_mask) { | 2134 | if (res) |
2110 | res = hotkey_mask_get(); | 2135 | goto err_exit; |
2111 | hotkey_orig_mask = hotkey_mask; | 2136 | |
2112 | if (!res) { | 2137 | if (tp_features.hotkey_mask) { |
2113 | res = add_many_to_attr_set( | 2138 | res = hotkey_mask_get(); |
2114 | hotkey_dev_attributes, | 2139 | if (res) |
2115 | hotkey_mask_attributes, | 2140 | goto err_exit; |
2116 | ARRAY_SIZE(hotkey_mask_attributes)); | 2141 | |
2117 | } | 2142 | hotkey_orig_mask = hotkey_mask; |
2118 | } | 2143 | res = add_many_to_attr_set( |
2144 | hotkey_dev_attributes, | ||
2145 | hotkey_mask_attributes, | ||
2146 | ARRAY_SIZE(hotkey_mask_attributes)); | ||
2147 | if (res) | ||
2148 | goto err_exit; | ||
2149 | } | ||
2119 | 2150 | ||
2120 | #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL | 2151 | #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL |
2121 | if (tp_features.hotkey_mask) { | 2152 | if (tp_features.hotkey_mask) { |
2122 | hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK | 2153 | hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK |
2123 | & ~hotkey_all_mask; | 2154 | & ~hotkey_all_mask; |
2124 | } else { | 2155 | } else { |
2125 | hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK; | 2156 | hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK; |
2126 | } | 2157 | } |
2127 | 2158 | ||
2128 | vdbg_printk(TPACPI_DBG_INIT, | 2159 | vdbg_printk(TPACPI_DBG_INIT, |
2129 | "hotkey source mask 0x%08x, polling freq %d\n", | 2160 | "hotkey source mask 0x%08x, polling freq %d\n", |
2130 | hotkey_source_mask, hotkey_poll_freq); | 2161 | hotkey_source_mask, hotkey_poll_freq); |
2131 | #endif | 2162 | #endif |
2132 | 2163 | ||
2133 | /* Not all thinkpads have a hardware radio switch */ | 2164 | /* Not all thinkpads have a hardware radio switch */ |
2134 | if (!res && acpi_evalf(hkey_handle, &status, "WLSW", "qd")) { | 2165 | if (acpi_evalf(hkey_handle, &status, "WLSW", "qd")) { |
2135 | tp_features.hotkey_wlsw = 1; | 2166 | tp_features.hotkey_wlsw = 1; |
2136 | printk(TPACPI_INFO | 2167 | printk(TPACPI_INFO |
2137 | "radio switch found; radios are %s\n", | 2168 | "radio switch found; radios are %s\n", |
2138 | enabled(status, 0)); | 2169 | enabled(status, 0)); |
2139 | res = add_to_attr_set(hotkey_dev_attributes, | 2170 | res = add_to_attr_set(hotkey_dev_attributes, |
2140 | &dev_attr_hotkey_radio_sw.attr); | 2171 | &dev_attr_hotkey_radio_sw.attr); |
2141 | } | 2172 | } |
2142 | 2173 | ||
2143 | /* For X41t, X60t, X61t Tablets... */ | 2174 | /* For X41t, X60t, X61t Tablets... */ |
2144 | if (!res && acpi_evalf(hkey_handle, &status, "MHKG", "qd")) { | 2175 | if (!res && acpi_evalf(hkey_handle, &status, "MHKG", "qd")) { |
2145 | tp_features.hotkey_tablet = 1; | 2176 | tp_features.hotkey_tablet = 1; |
2146 | printk(TPACPI_INFO | 2177 | printk(TPACPI_INFO |
2147 | "possible tablet mode switch found; " | 2178 | "possible tablet mode switch found; " |
2148 | "ThinkPad in %s mode\n", | 2179 | "ThinkPad in %s mode\n", |
2149 | (status & TP_HOTKEY_TABLET_MASK)? | 2180 | (status & TP_HOTKEY_TABLET_MASK)? |
2150 | "tablet" : "laptop"); | 2181 | "tablet" : "laptop"); |
2151 | res = add_to_attr_set(hotkey_dev_attributes, | 2182 | res = add_to_attr_set(hotkey_dev_attributes, |
2152 | &dev_attr_hotkey_tablet_mode.attr); | 2183 | &dev_attr_hotkey_tablet_mode.attr); |
2153 | } | 2184 | } |
2154 | 2185 | ||
2155 | if (!res) | 2186 | if (!res) |
2156 | res = register_attr_set_with_sysfs( | 2187 | res = register_attr_set_with_sysfs( |
2157 | hotkey_dev_attributes, | 2188 | hotkey_dev_attributes, |
2158 | &tpacpi_pdev->dev.kobj); | 2189 | &tpacpi_pdev->dev.kobj); |
2159 | if (res) | 2190 | if (res) |
2160 | return res; | 2191 | goto err_exit; |
2161 | 2192 | ||
2162 | /* Set up key map */ | 2193 | /* Set up key map */ |
2163 | 2194 | ||
2164 | hotkey_keycode_map = kmalloc(TPACPI_HOTKEY_MAP_SIZE, | 2195 | hotkey_keycode_map = kmalloc(TPACPI_HOTKEY_MAP_SIZE, |
2165 | GFP_KERNEL); | 2196 | GFP_KERNEL); |
2166 | if (!hotkey_keycode_map) { | 2197 | if (!hotkey_keycode_map) { |
2167 | printk(TPACPI_ERR | 2198 | printk(TPACPI_ERR |
2168 | "failed to allocate memory for key map\n"); | 2199 | "failed to allocate memory for key map\n"); |
2169 | return -ENOMEM; | 2200 | res = -ENOMEM; |
2170 | } | 2201 | goto err_exit; |
2202 | } | ||
2171 | 2203 | ||
2172 | if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) { | 2204 | if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) { |
2173 | dbg_printk(TPACPI_DBG_INIT, | 2205 | dbg_printk(TPACPI_DBG_INIT, |
2174 | "using Lenovo default hot key map\n"); | 2206 | "using Lenovo default hot key map\n"); |
2175 | memcpy(hotkey_keycode_map, &lenovo_keycode_map, | 2207 | memcpy(hotkey_keycode_map, &lenovo_keycode_map, |
2176 | TPACPI_HOTKEY_MAP_SIZE); | 2208 | TPACPI_HOTKEY_MAP_SIZE); |
2209 | } else { | ||
2210 | dbg_printk(TPACPI_DBG_INIT, | ||
2211 | "using IBM default hot key map\n"); | ||
2212 | memcpy(hotkey_keycode_map, &ibm_keycode_map, | ||
2213 | TPACPI_HOTKEY_MAP_SIZE); | ||
2214 | } | ||
2215 | |||
2216 | set_bit(EV_KEY, tpacpi_inputdev->evbit); | ||
2217 | set_bit(EV_MSC, tpacpi_inputdev->evbit); | ||
2218 | set_bit(MSC_SCAN, tpacpi_inputdev->mscbit); | ||
2219 | tpacpi_inputdev->keycodesize = TPACPI_HOTKEY_MAP_TYPESIZE; | ||
2220 | tpacpi_inputdev->keycodemax = TPACPI_HOTKEY_MAP_LEN; | ||
2221 | tpacpi_inputdev->keycode = hotkey_keycode_map; | ||
2222 | for (i = 0; i < TPACPI_HOTKEY_MAP_LEN; i++) { | ||
2223 | if (hotkey_keycode_map[i] != KEY_RESERVED) { | ||
2224 | set_bit(hotkey_keycode_map[i], | ||
2225 | tpacpi_inputdev->keybit); | ||
2177 | } else { | 2226 | } else { |
2178 | dbg_printk(TPACPI_DBG_INIT, | 2227 | if (i < sizeof(hotkey_reserved_mask)*8) |
2179 | "using IBM default hot key map\n"); | 2228 | hotkey_reserved_mask |= 1 << i; |
2180 | memcpy(hotkey_keycode_map, &ibm_keycode_map, | ||
2181 | TPACPI_HOTKEY_MAP_SIZE); | ||
2182 | } | ||
2183 | |||
2184 | set_bit(EV_KEY, tpacpi_inputdev->evbit); | ||
2185 | set_bit(EV_MSC, tpacpi_inputdev->evbit); | ||
2186 | set_bit(MSC_SCAN, tpacpi_inputdev->mscbit); | ||
2187 | tpacpi_inputdev->keycodesize = TPACPI_HOTKEY_MAP_TYPESIZE; | ||
2188 | tpacpi_inputdev->keycodemax = TPACPI_HOTKEY_MAP_LEN; | ||
2189 | tpacpi_inputdev->keycode = hotkey_keycode_map; | ||
2190 | for (i = 0; i < TPACPI_HOTKEY_MAP_LEN; i++) { | ||
2191 | if (hotkey_keycode_map[i] != KEY_RESERVED) { | ||
2192 | set_bit(hotkey_keycode_map[i], | ||
2193 | tpacpi_inputdev->keybit); | ||
2194 | } else { | ||
2195 | if (i < sizeof(hotkey_reserved_mask)*8) | ||
2196 | hotkey_reserved_mask |= 1 << i; | ||
2197 | } | ||
2198 | } | ||
2199 | |||
2200 | if (tp_features.hotkey_wlsw) { | ||
2201 | set_bit(EV_SW, tpacpi_inputdev->evbit); | ||
2202 | set_bit(SW_RADIO, tpacpi_inputdev->swbit); | ||
2203 | } | ||
2204 | if (tp_features.hotkey_tablet) { | ||
2205 | set_bit(EV_SW, tpacpi_inputdev->evbit); | ||
2206 | set_bit(SW_TABLET_MODE, tpacpi_inputdev->swbit); | ||
2207 | } | 2229 | } |
2230 | } | ||
2208 | 2231 | ||
2209 | /* Do not issue duplicate brightness change events to | 2232 | if (tp_features.hotkey_wlsw) { |
2210 | * userspace */ | 2233 | set_bit(EV_SW, tpacpi_inputdev->evbit); |
2211 | if (!tp_features.bright_acpimode) | 2234 | set_bit(SW_RFKILL_ALL, tpacpi_inputdev->swbit); |
2212 | /* update bright_acpimode... */ | 2235 | } |
2213 | tpacpi_check_std_acpi_brightness_support(); | 2236 | if (tp_features.hotkey_tablet) { |
2214 | 2237 | set_bit(EV_SW, tpacpi_inputdev->evbit); | |
2215 | if (tp_features.bright_acpimode) { | 2238 | set_bit(SW_TABLET_MODE, tpacpi_inputdev->swbit); |
2216 | printk(TPACPI_INFO | 2239 | } |
2217 | "This ThinkPad has standard ACPI backlight " | ||
2218 | "brightness control, supported by the ACPI " | ||
2219 | "video driver\n"); | ||
2220 | printk(TPACPI_NOTICE | ||
2221 | "Disabling thinkpad-acpi brightness events " | ||
2222 | "by default...\n"); | ||
2223 | |||
2224 | /* The hotkey_reserved_mask change below is not | ||
2225 | * necessary while the keys are at KEY_RESERVED in the | ||
2226 | * default map, but better safe than sorry, leave it | ||
2227 | * here as a marker of what we have to do, especially | ||
2228 | * when we finally become able to set this at runtime | ||
2229 | * on response to X.org requests */ | ||
2230 | hotkey_reserved_mask |= | ||
2231 | (1 << TP_ACPI_HOTKEYSCAN_FNHOME) | ||
2232 | | (1 << TP_ACPI_HOTKEYSCAN_FNEND); | ||
2233 | } | ||
2234 | 2240 | ||
2235 | dbg_printk(TPACPI_DBG_INIT, | 2241 | /* Do not issue duplicate brightness change events to |
2236 | "enabling hot key handling\n"); | 2242 | * userspace */ |
2237 | res = hotkey_status_set(1); | 2243 | if (!tp_features.bright_acpimode) |
2238 | if (res) | 2244 | /* update bright_acpimode... */ |
2239 | return res; | 2245 | tpacpi_check_std_acpi_brightness_support(); |
2240 | res = hotkey_mask_set(((hotkey_all_mask | hotkey_source_mask) | ||
2241 | & ~hotkey_reserved_mask) | ||
2242 | | hotkey_orig_mask); | ||
2243 | if (res < 0 && res != -ENXIO) | ||
2244 | return res; | ||
2245 | 2246 | ||
2246 | dbg_printk(TPACPI_DBG_INIT, | 2247 | if (tp_features.bright_acpimode) { |
2247 | "legacy hot key reporting over procfs %s\n", | 2248 | printk(TPACPI_INFO |
2248 | (hotkey_report_mode < 2) ? | 2249 | "This ThinkPad has standard ACPI backlight " |
2249 | "enabled" : "disabled"); | 2250 | "brightness control, supported by the ACPI " |
2251 | "video driver\n"); | ||
2252 | printk(TPACPI_NOTICE | ||
2253 | "Disabling thinkpad-acpi brightness events " | ||
2254 | "by default...\n"); | ||
2255 | |||
2256 | /* The hotkey_reserved_mask change below is not | ||
2257 | * necessary while the keys are at KEY_RESERVED in the | ||
2258 | * default map, but better safe than sorry, leave it | ||
2259 | * here as a marker of what we have to do, especially | ||
2260 | * when we finally become able to set this at runtime | ||
2261 | * on response to X.org requests */ | ||
2262 | hotkey_reserved_mask |= | ||
2263 | (1 << TP_ACPI_HOTKEYSCAN_FNHOME) | ||
2264 | | (1 << TP_ACPI_HOTKEYSCAN_FNEND); | ||
2265 | } | ||
2266 | |||
2267 | dbg_printk(TPACPI_DBG_INIT, "enabling hot key handling\n"); | ||
2268 | res = hotkey_status_set(1); | ||
2269 | if (res) { | ||
2270 | hotkey_exit(); | ||
2271 | return res; | ||
2272 | } | ||
2273 | res = hotkey_mask_set(((hotkey_all_mask | hotkey_source_mask) | ||
2274 | & ~hotkey_reserved_mask) | ||
2275 | | hotkey_orig_mask); | ||
2276 | if (res < 0 && res != -ENXIO) { | ||
2277 | hotkey_exit(); | ||
2278 | return res; | ||
2279 | } | ||
2250 | 2280 | ||
2251 | tpacpi_inputdev->open = &hotkey_inputdev_open; | 2281 | dbg_printk(TPACPI_DBG_INIT, |
2252 | tpacpi_inputdev->close = &hotkey_inputdev_close; | 2282 | "legacy hot key reporting over procfs %s\n", |
2283 | (hotkey_report_mode < 2) ? | ||
2284 | "enabled" : "disabled"); | ||
2253 | 2285 | ||
2254 | hotkey_poll_setup_safe(1); | 2286 | tpacpi_inputdev->open = &hotkey_inputdev_open; |
2255 | tpacpi_input_send_radiosw(); | 2287 | tpacpi_inputdev->close = &hotkey_inputdev_close; |
2256 | tpacpi_input_send_tabletsw(); | ||
2257 | } | ||
2258 | 2288 | ||
2259 | return (tp_features.hotkey)? 0 : 1; | 2289 | hotkey_poll_setup_safe(1); |
2260 | } | 2290 | tpacpi_input_send_radiosw(); |
2291 | tpacpi_input_send_tabletsw(); | ||
2261 | 2292 | ||
2262 | static void hotkey_exit(void) | 2293 | return 0; |
2263 | { | ||
2264 | #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL | ||
2265 | hotkey_poll_stop_sync(); | ||
2266 | #endif | ||
2267 | 2294 | ||
2268 | if (tp_features.hotkey) { | 2295 | err_exit: |
2269 | dbg_printk(TPACPI_DBG_EXIT, | 2296 | delete_attr_set(hotkey_dev_attributes, &tpacpi_pdev->dev.kobj); |
2270 | "restoring original hot key mask\n"); | 2297 | hotkey_dev_attributes = NULL; |
2271 | /* no short-circuit boolean operator below! */ | ||
2272 | if ((hotkey_mask_set(hotkey_orig_mask) | | ||
2273 | hotkey_status_set(hotkey_orig_status)) != 0) | ||
2274 | printk(TPACPI_ERR | ||
2275 | "failed to restore hot key mask " | ||
2276 | "to BIOS defaults\n"); | ||
2277 | } | ||
2278 | 2298 | ||
2279 | if (hotkey_dev_attributes) { | 2299 | return (res < 0)? res : 1; |
2280 | delete_attr_set(hotkey_dev_attributes, &tpacpi_pdev->dev.kobj); | ||
2281 | hotkey_dev_attributes = NULL; | ||
2282 | } | ||
2283 | } | 2300 | } |
2284 | 2301 | ||
2285 | static void hotkey_notify(struct ibm_struct *ibm, u32 event) | 2302 | static void hotkey_notify(struct ibm_struct *ibm, u32 event) |
@@ -3319,7 +3336,7 @@ static struct tpacpi_led_classdev tpacpi_led_thinklight = { | |||
3319 | 3336 | ||
3320 | static int __init light_init(struct ibm_init_struct *iibm) | 3337 | static int __init light_init(struct ibm_init_struct *iibm) |
3321 | { | 3338 | { |
3322 | int rc = 0; | 3339 | int rc; |
3323 | 3340 | ||
3324 | vdbg_printk(TPACPI_DBG_INIT, "initializing light subdriver\n"); | 3341 | vdbg_printk(TPACPI_DBG_INIT, "initializing light subdriver\n"); |
3325 | 3342 | ||
@@ -3337,20 +3354,23 @@ static int __init light_init(struct ibm_init_struct *iibm) | |||
3337 | tp_features.light_status = | 3354 | tp_features.light_status = |
3338 | acpi_evalf(ec_handle, NULL, "KBLT", "qv"); | 3355 | acpi_evalf(ec_handle, NULL, "KBLT", "qv"); |
3339 | 3356 | ||
3340 | vdbg_printk(TPACPI_DBG_INIT, "light is %s\n", | 3357 | vdbg_printk(TPACPI_DBG_INIT, "light is %s, light status is %s\n", |
3341 | str_supported(tp_features.light)); | 3358 | str_supported(tp_features.light), |
3359 | str_supported(tp_features.light_status)); | ||
3342 | 3360 | ||
3343 | if (tp_features.light) { | 3361 | if (!tp_features.light) |
3344 | rc = led_classdev_register(&tpacpi_pdev->dev, | 3362 | return 1; |
3345 | &tpacpi_led_thinklight.led_classdev); | 3363 | |
3346 | } | 3364 | rc = led_classdev_register(&tpacpi_pdev->dev, |
3365 | &tpacpi_led_thinklight.led_classdev); | ||
3347 | 3366 | ||
3348 | if (rc < 0) { | 3367 | if (rc < 0) { |
3349 | tp_features.light = 0; | 3368 | tp_features.light = 0; |
3350 | tp_features.light_status = 0; | 3369 | tp_features.light_status = 0; |
3351 | } else { | 3370 | } else { |
3352 | rc = (tp_features.light)? 0 : 1; | 3371 | rc = 0; |
3353 | } | 3372 | } |
3373 | |||
3354 | return rc; | 3374 | return rc; |
3355 | } | 3375 | } |
3356 | 3376 | ||
@@ -3821,7 +3841,7 @@ TPACPI_HANDLE(led, ec, "SLED", /* 570 */ | |||
3821 | #define TPACPI_LED_NUMLEDS 8 | 3841 | #define TPACPI_LED_NUMLEDS 8 |
3822 | static struct tpacpi_led_classdev *tpacpi_leds; | 3842 | static struct tpacpi_led_classdev *tpacpi_leds; |
3823 | static enum led_status_t tpacpi_led_state_cache[TPACPI_LED_NUMLEDS]; | 3843 | static enum led_status_t tpacpi_led_state_cache[TPACPI_LED_NUMLEDS]; |
3824 | static const char const *tpacpi_led_names[TPACPI_LED_NUMLEDS] = { | 3844 | static const char * const tpacpi_led_names[TPACPI_LED_NUMLEDS] = { |
3825 | /* there's a limit of 19 chars + NULL before 2.6.26 */ | 3845 | /* there's a limit of 19 chars + NULL before 2.6.26 */ |
3826 | "tpacpi::power", | 3846 | "tpacpi::power", |
3827 | "tpacpi:orange:batt", | 3847 | "tpacpi:orange:batt", |
@@ -3833,7 +3853,7 @@ static const char const *tpacpi_led_names[TPACPI_LED_NUMLEDS] = { | |||
3833 | "tpacpi::standby", | 3853 | "tpacpi::standby", |
3834 | }; | 3854 | }; |
3835 | 3855 | ||
3836 | static int led_get_status(unsigned int led) | 3856 | static int led_get_status(const unsigned int led) |
3837 | { | 3857 | { |
3838 | int status; | 3858 | int status; |
3839 | enum led_status_t led_s; | 3859 | enum led_status_t led_s; |
@@ -3857,41 +3877,42 @@ static int led_get_status(unsigned int led) | |||
3857 | /* not reached */ | 3877 | /* not reached */ |
3858 | } | 3878 | } |
3859 | 3879 | ||
3860 | static int led_set_status(unsigned int led, enum led_status_t ledstatus) | 3880 | static int led_set_status(const unsigned int led, |
3881 | const enum led_status_t ledstatus) | ||
3861 | { | 3882 | { |
3862 | /* off, on, blink. Index is led_status_t */ | 3883 | /* off, on, blink. Index is led_status_t */ |
3863 | static const int const led_sled_arg1[] = { 0, 1, 3 }; | 3884 | static const unsigned int led_sled_arg1[] = { 0, 1, 3 }; |
3864 | static const int const led_exp_hlbl[] = { 0, 0, 1 }; /* led# * */ | 3885 | static const unsigned int led_led_arg1[] = { 0, 0x80, 0xc0 }; |
3865 | static const int const led_exp_hlcl[] = { 0, 1, 1 }; /* led# * */ | ||
3866 | static const int const led_led_arg1[] = { 0, 0x80, 0xc0 }; | ||
3867 | 3886 | ||
3868 | int rc = 0; | 3887 | int rc = 0; |
3869 | 3888 | ||
3870 | switch (led_supported) { | 3889 | switch (led_supported) { |
3871 | case TPACPI_LED_570: | 3890 | case TPACPI_LED_570: |
3872 | /* 570 */ | 3891 | /* 570 */ |
3873 | led = 1 << led; | 3892 | if (led > 7) |
3874 | if (!acpi_evalf(led_handle, NULL, NULL, "vdd", | 3893 | return -EINVAL; |
3875 | led, led_sled_arg1[ledstatus])) | 3894 | if (!acpi_evalf(led_handle, NULL, NULL, "vdd", |
3876 | rc = -EIO; | 3895 | (1 << led), led_sled_arg1[ledstatus])) |
3877 | break; | 3896 | rc = -EIO; |
3897 | break; | ||
3878 | case TPACPI_LED_OLD: | 3898 | case TPACPI_LED_OLD: |
3879 | /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20 */ | 3899 | /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20 */ |
3880 | led = 1 << led; | 3900 | if (led > 7) |
3881 | rc = ec_write(TPACPI_LED_EC_HLMS, led); | 3901 | return -EINVAL; |
3882 | if (rc >= 0) | 3902 | rc = ec_write(TPACPI_LED_EC_HLMS, (1 << led)); |
3883 | rc = ec_write(TPACPI_LED_EC_HLBL, | 3903 | if (rc >= 0) |
3884 | led * led_exp_hlbl[ledstatus]); | 3904 | rc = ec_write(TPACPI_LED_EC_HLBL, |
3885 | if (rc >= 0) | 3905 | (ledstatus == TPACPI_LED_BLINK) << led); |
3886 | rc = ec_write(TPACPI_LED_EC_HLCL, | 3906 | if (rc >= 0) |
3887 | led * led_exp_hlcl[ledstatus]); | 3907 | rc = ec_write(TPACPI_LED_EC_HLCL, |
3888 | break; | 3908 | (ledstatus != TPACPI_LED_OFF) << led); |
3909 | break; | ||
3889 | case TPACPI_LED_NEW: | 3910 | case TPACPI_LED_NEW: |
3890 | /* all others */ | 3911 | /* all others */ |
3891 | if (!acpi_evalf(led_handle, NULL, NULL, "vdd", | 3912 | if (!acpi_evalf(led_handle, NULL, NULL, "vdd", |
3892 | led, led_led_arg1[ledstatus])) | 3913 | led, led_led_arg1[ledstatus])) |
3893 | rc = -EIO; | 3914 | rc = -EIO; |
3894 | break; | 3915 | break; |
3895 | default: | 3916 | default: |
3896 | rc = -ENXIO; | 3917 | rc = -ENXIO; |
3897 | } | 3918 | } |
@@ -3978,7 +3999,6 @@ static void led_exit(void) | |||
3978 | } | 3999 | } |
3979 | 4000 | ||
3980 | kfree(tpacpi_leds); | 4001 | kfree(tpacpi_leds); |
3981 | tpacpi_leds = NULL; | ||
3982 | } | 4002 | } |
3983 | 4003 | ||
3984 | static int __init led_init(struct ibm_init_struct *iibm) | 4004 | static int __init led_init(struct ibm_init_struct *iibm) |
@@ -4802,7 +4822,6 @@ static void brightness_exit(void) | |||
4802 | vdbg_printk(TPACPI_DBG_EXIT, | 4822 | vdbg_printk(TPACPI_DBG_EXIT, |
4803 | "calling backlight_device_unregister()\n"); | 4823 | "calling backlight_device_unregister()\n"); |
4804 | backlight_device_unregister(ibm_backlight_device); | 4824 | backlight_device_unregister(ibm_backlight_device); |
4805 | ibm_backlight_device = NULL; | ||
4806 | } | 4825 | } |
4807 | } | 4826 | } |
4808 | 4827 | ||
@@ -5764,11 +5783,16 @@ static int __init fan_init(struct ibm_init_struct *iibm) | |||
5764 | fan_control_access_mode != TPACPI_FAN_WR_NONE) { | 5783 | fan_control_access_mode != TPACPI_FAN_WR_NONE) { |
5765 | rc = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj, | 5784 | rc = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj, |
5766 | &fan_attr_group); | 5785 | &fan_attr_group); |
5767 | if (!(rc < 0)) | ||
5768 | rc = driver_create_file(&tpacpi_hwmon_pdriver.driver, | ||
5769 | &driver_attr_fan_watchdog); | ||
5770 | if (rc < 0) | 5786 | if (rc < 0) |
5771 | return rc; | 5787 | return rc; |
5788 | |||
5789 | rc = driver_create_file(&tpacpi_hwmon_pdriver.driver, | ||
5790 | &driver_attr_fan_watchdog); | ||
5791 | if (rc < 0) { | ||
5792 | sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj, | ||
5793 | &fan_attr_group); | ||
5794 | return rc; | ||
5795 | } | ||
5772 | return 0; | 5796 | return 0; |
5773 | } else | 5797 | } else |
5774 | return 1; | 5798 | return 1; |
diff --git a/drivers/mmc/card/Kconfig b/drivers/mmc/card/Kconfig index aa8a4e461942..dd0f398ee2f5 100644 --- a/drivers/mmc/card/Kconfig +++ b/drivers/mmc/card/Kconfig | |||
@@ -39,3 +39,15 @@ config SDIO_UART | |||
39 | SDIO function driver for SDIO cards that implements the UART | 39 | SDIO function driver for SDIO cards that implements the UART |
40 | class, as well as the GPS class which appears like a UART. | 40 | class, as well as the GPS class which appears like a UART. |
41 | 41 | ||
42 | config MMC_TEST | ||
43 | tristate "MMC host test driver" | ||
44 | default n | ||
45 | help | ||
46 | Development driver that performs a series of reads and writes | ||
47 | to a memory card in order to expose certain well known bugs | ||
48 | in host controllers. The tests are executed by writing to the | ||
49 | "test" file in sysfs under each card. Note that whatever is | ||
50 | on your card will be overwritten by these tests. | ||
51 | |||
52 | This driver is only of interest to those developing or | ||
53 | testing a host driver. Most people should say N here. | ||
diff --git a/drivers/mmc/card/Makefile b/drivers/mmc/card/Makefile index fc5a784cfa1a..0d407514f67d 100644 --- a/drivers/mmc/card/Makefile +++ b/drivers/mmc/card/Makefile | |||
@@ -8,6 +8,7 @@ endif | |||
8 | 8 | ||
9 | obj-$(CONFIG_MMC_BLOCK) += mmc_block.o | 9 | obj-$(CONFIG_MMC_BLOCK) += mmc_block.o |
10 | mmc_block-objs := block.o queue.o | 10 | mmc_block-objs := block.o queue.o |
11 | obj-$(CONFIG_MMC_TEST) += mmc_test.o | ||
11 | 12 | ||
12 | obj-$(CONFIG_SDIO_UART) += sdio_uart.o | 13 | obj-$(CONFIG_SDIO_UART) += sdio_uart.o |
13 | 14 | ||
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 91ded3e82401..f9ad960d7c1a 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c | |||
@@ -46,7 +46,7 @@ | |||
46 | #define MMC_SHIFT 3 | 46 | #define MMC_SHIFT 3 |
47 | #define MMC_NUM_MINORS (256 >> MMC_SHIFT) | 47 | #define MMC_NUM_MINORS (256 >> MMC_SHIFT) |
48 | 48 | ||
49 | static unsigned long dev_use[MMC_NUM_MINORS/(8*sizeof(unsigned long))]; | 49 | static DECLARE_BITMAP(dev_use, MMC_NUM_MINORS); |
50 | 50 | ||
51 | /* | 51 | /* |
52 | * There is one mmc_blk_data per slot. | 52 | * There is one mmc_blk_data per slot. |
diff --git a/drivers/mmc/card/mmc_test.c b/drivers/mmc/card/mmc_test.c new file mode 100644 index 000000000000..ffadee549a41 --- /dev/null +++ b/drivers/mmc/card/mmc_test.c | |||
@@ -0,0 +1,892 @@ | |||
1 | /* | ||
2 | * linux/drivers/mmc/card/mmc_test.c | ||
3 | * | ||
4 | * Copyright 2007 Pierre Ossman | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or (at | ||
9 | * your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <linux/mmc/core.h> | ||
13 | #include <linux/mmc/card.h> | ||
14 | #include <linux/mmc/host.h> | ||
15 | #include <linux/mmc/mmc.h> | ||
16 | |||
17 | #include <linux/scatterlist.h> | ||
18 | |||
19 | #define RESULT_OK 0 | ||
20 | #define RESULT_FAIL 1 | ||
21 | #define RESULT_UNSUP_HOST 2 | ||
22 | #define RESULT_UNSUP_CARD 3 | ||
23 | |||
24 | #define BUFFER_SIZE (PAGE_SIZE * 4) | ||
25 | |||
26 | struct mmc_test_card { | ||
27 | struct mmc_card *card; | ||
28 | |||
29 | u8 *buffer; | ||
30 | }; | ||
31 | |||
32 | /*******************************************************************/ | ||
33 | /* Helper functions */ | ||
34 | /*******************************************************************/ | ||
35 | |||
36 | static int mmc_test_set_blksize(struct mmc_test_card *test, unsigned size) | ||
37 | { | ||
38 | struct mmc_command cmd; | ||
39 | int ret; | ||
40 | |||
41 | cmd.opcode = MMC_SET_BLOCKLEN; | ||
42 | cmd.arg = size; | ||
43 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | ||
44 | ret = mmc_wait_for_cmd(test->card->host, &cmd, 0); | ||
45 | if (ret) | ||
46 | return ret; | ||
47 | |||
48 | return 0; | ||
49 | } | ||
50 | |||
51 | static int __mmc_test_transfer(struct mmc_test_card *test, int write, | ||
52 | unsigned broken_xfer, u8 *buffer, unsigned addr, | ||
53 | unsigned blocks, unsigned blksz) | ||
54 | { | ||
55 | int ret, busy; | ||
56 | |||
57 | struct mmc_request mrq; | ||
58 | struct mmc_command cmd; | ||
59 | struct mmc_command stop; | ||
60 | struct mmc_data data; | ||
61 | |||
62 | struct scatterlist sg; | ||
63 | |||
64 | memset(&mrq, 0, sizeof(struct mmc_request)); | ||
65 | |||
66 | mrq.cmd = &cmd; | ||
67 | mrq.data = &data; | ||
68 | |||
69 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
70 | |||
71 | if (broken_xfer) { | ||
72 | if (blocks > 1) { | ||
73 | cmd.opcode = write ? | ||
74 | MMC_WRITE_BLOCK : MMC_READ_SINGLE_BLOCK; | ||
75 | } else { | ||
76 | cmd.opcode = MMC_SEND_STATUS; | ||
77 | } | ||
78 | } else { | ||
79 | if (blocks > 1) { | ||
80 | cmd.opcode = write ? | ||
81 | MMC_WRITE_MULTIPLE_BLOCK : MMC_READ_MULTIPLE_BLOCK; | ||
82 | } else { | ||
83 | cmd.opcode = write ? | ||
84 | MMC_WRITE_BLOCK : MMC_READ_SINGLE_BLOCK; | ||
85 | } | ||
86 | } | ||
87 | |||
88 | if (broken_xfer && blocks == 1) | ||
89 | cmd.arg = test->card->rca << 16; | ||
90 | else | ||
91 | cmd.arg = addr; | ||
92 | cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; | ||
93 | |||
94 | memset(&stop, 0, sizeof(struct mmc_command)); | ||
95 | |||
96 | if (!broken_xfer && (blocks > 1)) { | ||
97 | stop.opcode = MMC_STOP_TRANSMISSION; | ||
98 | stop.arg = 0; | ||
99 | stop.flags = MMC_RSP_R1B | MMC_CMD_AC; | ||
100 | |||
101 | mrq.stop = &stop; | ||
102 | } | ||
103 | |||
104 | memset(&data, 0, sizeof(struct mmc_data)); | ||
105 | |||
106 | data.blksz = blksz; | ||
107 | data.blocks = blocks; | ||
108 | data.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ; | ||
109 | data.sg = &sg; | ||
110 | data.sg_len = 1; | ||
111 | |||
112 | sg_init_one(&sg, buffer, blocks * blksz); | ||
113 | |||
114 | mmc_set_data_timeout(&data, test->card); | ||
115 | |||
116 | mmc_wait_for_req(test->card->host, &mrq); | ||
117 | |||
118 | ret = 0; | ||
119 | |||
120 | if (broken_xfer) { | ||
121 | if (!ret && cmd.error) | ||
122 | ret = cmd.error; | ||
123 | if (!ret && data.error == 0) | ||
124 | ret = RESULT_FAIL; | ||
125 | if (!ret && data.error != -ETIMEDOUT) | ||
126 | ret = data.error; | ||
127 | if (!ret && stop.error) | ||
128 | ret = stop.error; | ||
129 | if (blocks > 1) { | ||
130 | if (!ret && data.bytes_xfered > blksz) | ||
131 | ret = RESULT_FAIL; | ||
132 | } else { | ||
133 | if (!ret && data.bytes_xfered > 0) | ||
134 | ret = RESULT_FAIL; | ||
135 | } | ||
136 | } else { | ||
137 | if (!ret && cmd.error) | ||
138 | ret = cmd.error; | ||
139 | if (!ret && data.error) | ||
140 | ret = data.error; | ||
141 | if (!ret && stop.error) | ||
142 | ret = stop.error; | ||
143 | if (!ret && data.bytes_xfered != blocks * blksz) | ||
144 | ret = RESULT_FAIL; | ||
145 | } | ||
146 | |||
147 | if (ret == -EINVAL) | ||
148 | ret = RESULT_UNSUP_HOST; | ||
149 | |||
150 | busy = 0; | ||
151 | do { | ||
152 | int ret2; | ||
153 | |||
154 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
155 | |||
156 | cmd.opcode = MMC_SEND_STATUS; | ||
157 | cmd.arg = test->card->rca << 16; | ||
158 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | ||
159 | |||
160 | ret2 = mmc_wait_for_cmd(test->card->host, &cmd, 0); | ||
161 | if (ret2) | ||
162 | break; | ||
163 | |||
164 | if (!busy && !(cmd.resp[0] & R1_READY_FOR_DATA)) { | ||
165 | busy = 1; | ||
166 | printk(KERN_INFO "%s: Warning: Host did not " | ||
167 | "wait for busy state to end.\n", | ||
168 | mmc_hostname(test->card->host)); | ||
169 | } | ||
170 | } while (!(cmd.resp[0] & R1_READY_FOR_DATA)); | ||
171 | |||
172 | return ret; | ||
173 | } | ||
174 | |||
175 | static int mmc_test_transfer(struct mmc_test_card *test, int write, | ||
176 | u8 *buffer, unsigned addr, unsigned blocks, unsigned blksz) | ||
177 | { | ||
178 | return __mmc_test_transfer(test, write, 0, buffer, | ||
179 | addr, blocks, blksz); | ||
180 | } | ||
181 | |||
182 | static int mmc_test_prepare_verify(struct mmc_test_card *test, int write) | ||
183 | { | ||
184 | int ret, i; | ||
185 | |||
186 | ret = mmc_test_set_blksize(test, 512); | ||
187 | if (ret) | ||
188 | return ret; | ||
189 | |||
190 | if (write) | ||
191 | memset(test->buffer, 0xDF, BUFFER_SIZE); | ||
192 | else { | ||
193 | for (i = 0;i < BUFFER_SIZE;i++) | ||
194 | test->buffer[i] = i; | ||
195 | } | ||
196 | |||
197 | for (i = 0;i < BUFFER_SIZE / 512;i++) { | ||
198 | ret = mmc_test_transfer(test, 1, test->buffer + i * 512, | ||
199 | i * 512, 1, 512); | ||
200 | if (ret) | ||
201 | return ret; | ||
202 | } | ||
203 | |||
204 | return 0; | ||
205 | } | ||
206 | |||
207 | static int mmc_test_prepare_verify_write(struct mmc_test_card *test) | ||
208 | { | ||
209 | return mmc_test_prepare_verify(test, 1); | ||
210 | } | ||
211 | |||
212 | static int mmc_test_prepare_verify_read(struct mmc_test_card *test) | ||
213 | { | ||
214 | return mmc_test_prepare_verify(test, 0); | ||
215 | } | ||
216 | |||
217 | static int mmc_test_verified_transfer(struct mmc_test_card *test, int write, | ||
218 | u8 *buffer, unsigned addr, unsigned blocks, unsigned blksz) | ||
219 | { | ||
220 | int ret, i, sectors; | ||
221 | |||
222 | /* | ||
223 | * It is assumed that the above preparation has been done. | ||
224 | */ | ||
225 | |||
226 | memset(test->buffer, 0, BUFFER_SIZE); | ||
227 | |||
228 | if (write) { | ||
229 | for (i = 0;i < blocks * blksz;i++) | ||
230 | buffer[i] = i; | ||
231 | } | ||
232 | |||
233 | ret = mmc_test_set_blksize(test, blksz); | ||
234 | if (ret) | ||
235 | return ret; | ||
236 | |||
237 | ret = mmc_test_transfer(test, write, buffer, addr, blocks, blksz); | ||
238 | if (ret) | ||
239 | return ret; | ||
240 | |||
241 | if (write) { | ||
242 | ret = mmc_test_set_blksize(test, 512); | ||
243 | if (ret) | ||
244 | return ret; | ||
245 | |||
246 | sectors = (blocks * blksz + 511) / 512; | ||
247 | if ((sectors * 512) == (blocks * blksz)) | ||
248 | sectors++; | ||
249 | |||
250 | if ((sectors * 512) > BUFFER_SIZE) | ||
251 | return -EINVAL; | ||
252 | |||
253 | memset(test->buffer, 0, sectors * 512); | ||
254 | |||
255 | for (i = 0;i < sectors;i++) { | ||
256 | ret = mmc_test_transfer(test, 0, | ||
257 | test->buffer + i * 512, | ||
258 | addr + i * 512, 1, 512); | ||
259 | if (ret) | ||
260 | return ret; | ||
261 | } | ||
262 | |||
263 | for (i = 0;i < blocks * blksz;i++) { | ||
264 | if (test->buffer[i] != (u8)i) | ||
265 | return RESULT_FAIL; | ||
266 | } | ||
267 | |||
268 | for (;i < sectors * 512;i++) { | ||
269 | if (test->buffer[i] != 0xDF) | ||
270 | return RESULT_FAIL; | ||
271 | } | ||
272 | } else { | ||
273 | for (i = 0;i < blocks * blksz;i++) { | ||
274 | if (buffer[i] != (u8)i) | ||
275 | return RESULT_FAIL; | ||
276 | } | ||
277 | } | ||
278 | |||
279 | return 0; | ||
280 | } | ||
281 | |||
282 | static int mmc_test_cleanup_verify(struct mmc_test_card *test) | ||
283 | { | ||
284 | int ret, i; | ||
285 | |||
286 | ret = mmc_test_set_blksize(test, 512); | ||
287 | if (ret) | ||
288 | return ret; | ||
289 | |||
290 | memset(test->buffer, 0, BUFFER_SIZE); | ||
291 | |||
292 | for (i = 0;i < BUFFER_SIZE / 512;i++) { | ||
293 | ret = mmc_test_transfer(test, 1, test->buffer + i * 512, | ||
294 | i * 512, 1, 512); | ||
295 | if (ret) | ||
296 | return ret; | ||
297 | } | ||
298 | |||
299 | return 0; | ||
300 | } | ||
301 | |||
302 | /*******************************************************************/ | ||
303 | /* Tests */ | ||
304 | /*******************************************************************/ | ||
305 | |||
306 | struct mmc_test_case { | ||
307 | const char *name; | ||
308 | |||
309 | int (*prepare)(struct mmc_test_card *); | ||
310 | int (*run)(struct mmc_test_card *); | ||
311 | int (*cleanup)(struct mmc_test_card *); | ||
312 | }; | ||
313 | |||
314 | static int mmc_test_basic_write(struct mmc_test_card *test) | ||
315 | { | ||
316 | int ret; | ||
317 | |||
318 | ret = mmc_test_set_blksize(test, 512); | ||
319 | if (ret) | ||
320 | return ret; | ||
321 | |||
322 | ret = mmc_test_transfer(test, 1, test->buffer, 0, 1, 512); | ||
323 | if (ret) | ||
324 | return ret; | ||
325 | |||
326 | return 0; | ||
327 | } | ||
328 | |||
329 | static int mmc_test_basic_read(struct mmc_test_card *test) | ||
330 | { | ||
331 | int ret; | ||
332 | |||
333 | ret = mmc_test_set_blksize(test, 512); | ||
334 | if (ret) | ||
335 | return ret; | ||
336 | |||
337 | ret = mmc_test_transfer(test, 0, test->buffer, 0, 1, 512); | ||
338 | if (ret) | ||
339 | return ret; | ||
340 | |||
341 | return 0; | ||
342 | } | ||
343 | |||
344 | static int mmc_test_verify_write(struct mmc_test_card *test) | ||
345 | { | ||
346 | int ret; | ||
347 | |||
348 | ret = mmc_test_verified_transfer(test, 1, test->buffer, 0, 1, 512); | ||
349 | if (ret) | ||
350 | return ret; | ||
351 | |||
352 | return 0; | ||
353 | } | ||
354 | |||
355 | static int mmc_test_verify_read(struct mmc_test_card *test) | ||
356 | { | ||
357 | int ret; | ||
358 | |||
359 | ret = mmc_test_verified_transfer(test, 0, test->buffer, 0, 1, 512); | ||
360 | if (ret) | ||
361 | return ret; | ||
362 | |||
363 | return 0; | ||
364 | } | ||
365 | |||
366 | static int mmc_test_multi_write(struct mmc_test_card *test) | ||
367 | { | ||
368 | int ret; | ||
369 | unsigned int size; | ||
370 | |||
371 | if (test->card->host->max_blk_count == 1) | ||
372 | return RESULT_UNSUP_HOST; | ||
373 | |||
374 | size = PAGE_SIZE * 2; | ||
375 | size = min(size, test->card->host->max_req_size); | ||
376 | size = min(size, test->card->host->max_seg_size); | ||
377 | size = min(size, test->card->host->max_blk_count * 512); | ||
378 | |||
379 | if (size < 1024) | ||
380 | return RESULT_UNSUP_HOST; | ||
381 | |||
382 | ret = mmc_test_verified_transfer(test, 1, test->buffer, 0, | ||
383 | size / 512, 512); | ||
384 | if (ret) | ||
385 | return ret; | ||
386 | |||
387 | return 0; | ||
388 | } | ||
389 | |||
390 | static int mmc_test_multi_read(struct mmc_test_card *test) | ||
391 | { | ||
392 | int ret; | ||
393 | unsigned int size; | ||
394 | |||
395 | if (test->card->host->max_blk_count == 1) | ||
396 | return RESULT_UNSUP_HOST; | ||
397 | |||
398 | size = PAGE_SIZE * 2; | ||
399 | size = min(size, test->card->host->max_req_size); | ||
400 | size = min(size, test->card->host->max_seg_size); | ||
401 | size = min(size, test->card->host->max_blk_count * 512); | ||
402 | |||
403 | if (size < 1024) | ||
404 | return RESULT_UNSUP_HOST; | ||
405 | |||
406 | ret = mmc_test_verified_transfer(test, 0, test->buffer, 0, | ||
407 | size / 512, 512); | ||
408 | if (ret) | ||
409 | return ret; | ||
410 | |||
411 | return 0; | ||
412 | } | ||
413 | |||
414 | static int mmc_test_pow2_write(struct mmc_test_card *test) | ||
415 | { | ||
416 | int ret, i; | ||
417 | |||
418 | if (!test->card->csd.write_partial) | ||
419 | return RESULT_UNSUP_CARD; | ||
420 | |||
421 | for (i = 1; i < 512;i <<= 1) { | ||
422 | ret = mmc_test_verified_transfer(test, 1, | ||
423 | test->buffer, 0, 1, i); | ||
424 | if (ret) | ||
425 | return ret; | ||
426 | } | ||
427 | |||
428 | return 0; | ||
429 | } | ||
430 | |||
431 | static int mmc_test_pow2_read(struct mmc_test_card *test) | ||
432 | { | ||
433 | int ret, i; | ||
434 | |||
435 | if (!test->card->csd.read_partial) | ||
436 | return RESULT_UNSUP_CARD; | ||
437 | |||
438 | for (i = 1; i < 512;i <<= 1) { | ||
439 | ret = mmc_test_verified_transfer(test, 0, | ||
440 | test->buffer, 0, 1, i); | ||
441 | if (ret) | ||
442 | return ret; | ||
443 | } | ||
444 | |||
445 | return 0; | ||
446 | } | ||
447 | |||
448 | static int mmc_test_weird_write(struct mmc_test_card *test) | ||
449 | { | ||
450 | int ret, i; | ||
451 | |||
452 | if (!test->card->csd.write_partial) | ||
453 | return RESULT_UNSUP_CARD; | ||
454 | |||
455 | for (i = 3; i < 512;i += 7) { | ||
456 | ret = mmc_test_verified_transfer(test, 1, | ||
457 | test->buffer, 0, 1, i); | ||
458 | if (ret) | ||
459 | return ret; | ||
460 | } | ||
461 | |||
462 | return 0; | ||
463 | } | ||
464 | |||
465 | static int mmc_test_weird_read(struct mmc_test_card *test) | ||
466 | { | ||
467 | int ret, i; | ||
468 | |||
469 | if (!test->card->csd.read_partial) | ||
470 | return RESULT_UNSUP_CARD; | ||
471 | |||
472 | for (i = 3; i < 512;i += 7) { | ||
473 | ret = mmc_test_verified_transfer(test, 0, | ||
474 | test->buffer, 0, 1, i); | ||
475 | if (ret) | ||
476 | return ret; | ||
477 | } | ||
478 | |||
479 | return 0; | ||
480 | } | ||
481 | |||
482 | static int mmc_test_align_write(struct mmc_test_card *test) | ||
483 | { | ||
484 | int ret, i; | ||
485 | |||
486 | for (i = 1;i < 4;i++) { | ||
487 | ret = mmc_test_verified_transfer(test, 1, test->buffer + i, | ||
488 | 0, 1, 512); | ||
489 | if (ret) | ||
490 | return ret; | ||
491 | } | ||
492 | |||
493 | return 0; | ||
494 | } | ||
495 | |||
496 | static int mmc_test_align_read(struct mmc_test_card *test) | ||
497 | { | ||
498 | int ret, i; | ||
499 | |||
500 | for (i = 1;i < 4;i++) { | ||
501 | ret = mmc_test_verified_transfer(test, 0, test->buffer + i, | ||
502 | 0, 1, 512); | ||
503 | if (ret) | ||
504 | return ret; | ||
505 | } | ||
506 | |||
507 | return 0; | ||
508 | } | ||
509 | |||
510 | static int mmc_test_align_multi_write(struct mmc_test_card *test) | ||
511 | { | ||
512 | int ret, i; | ||
513 | unsigned int size; | ||
514 | |||
515 | if (test->card->host->max_blk_count == 1) | ||
516 | return RESULT_UNSUP_HOST; | ||
517 | |||
518 | size = PAGE_SIZE * 2; | ||
519 | size = min(size, test->card->host->max_req_size); | ||
520 | size = min(size, test->card->host->max_seg_size); | ||
521 | size = min(size, test->card->host->max_blk_count * 512); | ||
522 | |||
523 | if (size < 1024) | ||
524 | return RESULT_UNSUP_HOST; | ||
525 | |||
526 | for (i = 1;i < 4;i++) { | ||
527 | ret = mmc_test_verified_transfer(test, 1, test->buffer + i, | ||
528 | 0, size / 512, 512); | ||
529 | if (ret) | ||
530 | return ret; | ||
531 | } | ||
532 | |||
533 | return 0; | ||
534 | } | ||
535 | |||
536 | static int mmc_test_align_multi_read(struct mmc_test_card *test) | ||
537 | { | ||
538 | int ret, i; | ||
539 | unsigned int size; | ||
540 | |||
541 | if (test->card->host->max_blk_count == 1) | ||
542 | return RESULT_UNSUP_HOST; | ||
543 | |||
544 | size = PAGE_SIZE * 2; | ||
545 | size = min(size, test->card->host->max_req_size); | ||
546 | size = min(size, test->card->host->max_seg_size); | ||
547 | size = min(size, test->card->host->max_blk_count * 512); | ||
548 | |||
549 | if (size < 1024) | ||
550 | return RESULT_UNSUP_HOST; | ||
551 | |||
552 | for (i = 1;i < 4;i++) { | ||
553 | ret = mmc_test_verified_transfer(test, 0, test->buffer + i, | ||
554 | 0, size / 512, 512); | ||
555 | if (ret) | ||
556 | return ret; | ||
557 | } | ||
558 | |||
559 | return 0; | ||
560 | } | ||
561 | |||
562 | static int mmc_test_xfersize_write(struct mmc_test_card *test) | ||
563 | { | ||
564 | int ret; | ||
565 | |||
566 | ret = mmc_test_set_blksize(test, 512); | ||
567 | if (ret) | ||
568 | return ret; | ||
569 | |||
570 | ret = __mmc_test_transfer(test, 1, 1, test->buffer, 0, 1, 512); | ||
571 | if (ret) | ||
572 | return ret; | ||
573 | |||
574 | return 0; | ||
575 | } | ||
576 | |||
577 | static int mmc_test_xfersize_read(struct mmc_test_card *test) | ||
578 | { | ||
579 | int ret; | ||
580 | |||
581 | ret = mmc_test_set_blksize(test, 512); | ||
582 | if (ret) | ||
583 | return ret; | ||
584 | |||
585 | ret = __mmc_test_transfer(test, 0, 1, test->buffer, 0, 1, 512); | ||
586 | if (ret) | ||
587 | return ret; | ||
588 | |||
589 | return 0; | ||
590 | } | ||
591 | |||
592 | static int mmc_test_multi_xfersize_write(struct mmc_test_card *test) | ||
593 | { | ||
594 | int ret; | ||
595 | |||
596 | if (test->card->host->max_blk_count == 1) | ||
597 | return RESULT_UNSUP_HOST; | ||
598 | |||
599 | ret = mmc_test_set_blksize(test, 512); | ||
600 | if (ret) | ||
601 | return ret; | ||
602 | |||
603 | ret = __mmc_test_transfer(test, 1, 1, test->buffer, 0, 2, 512); | ||
604 | if (ret) | ||
605 | return ret; | ||
606 | |||
607 | return 0; | ||
608 | } | ||
609 | |||
610 | static int mmc_test_multi_xfersize_read(struct mmc_test_card *test) | ||
611 | { | ||
612 | int ret; | ||
613 | |||
614 | if (test->card->host->max_blk_count == 1) | ||
615 | return RESULT_UNSUP_HOST; | ||
616 | |||
617 | ret = mmc_test_set_blksize(test, 512); | ||
618 | if (ret) | ||
619 | return ret; | ||
620 | |||
621 | ret = __mmc_test_transfer(test, 0, 1, test->buffer, 0, 2, 512); | ||
622 | if (ret) | ||
623 | return ret; | ||
624 | |||
625 | return 0; | ||
626 | } | ||
627 | |||
628 | static const struct mmc_test_case mmc_test_cases[] = { | ||
629 | { | ||
630 | .name = "Basic write (no data verification)", | ||
631 | .run = mmc_test_basic_write, | ||
632 | }, | ||
633 | |||
634 | { | ||
635 | .name = "Basic read (no data verification)", | ||
636 | .run = mmc_test_basic_read, | ||
637 | }, | ||
638 | |||
639 | { | ||
640 | .name = "Basic write (with data verification)", | ||
641 | .prepare = mmc_test_prepare_verify_write, | ||
642 | .run = mmc_test_verify_write, | ||
643 | .cleanup = mmc_test_cleanup_verify, | ||
644 | }, | ||
645 | |||
646 | { | ||
647 | .name = "Basic read (with data verification)", | ||
648 | .prepare = mmc_test_prepare_verify_read, | ||
649 | .run = mmc_test_verify_read, | ||
650 | .cleanup = mmc_test_cleanup_verify, | ||
651 | }, | ||
652 | |||
653 | { | ||
654 | .name = "Multi-block write", | ||
655 | .prepare = mmc_test_prepare_verify_write, | ||
656 | .run = mmc_test_multi_write, | ||
657 | .cleanup = mmc_test_cleanup_verify, | ||
658 | }, | ||
659 | |||
660 | { | ||
661 | .name = "Multi-block read", | ||
662 | .prepare = mmc_test_prepare_verify_read, | ||
663 | .run = mmc_test_multi_read, | ||
664 | .cleanup = mmc_test_cleanup_verify, | ||
665 | }, | ||
666 | |||
667 | { | ||
668 | .name = "Power of two block writes", | ||
669 | .prepare = mmc_test_prepare_verify_write, | ||
670 | .run = mmc_test_pow2_write, | ||
671 | .cleanup = mmc_test_cleanup_verify, | ||
672 | }, | ||
673 | |||
674 | { | ||
675 | .name = "Power of two block reads", | ||
676 | .prepare = mmc_test_prepare_verify_read, | ||
677 | .run = mmc_test_pow2_read, | ||
678 | .cleanup = mmc_test_cleanup_verify, | ||
679 | }, | ||
680 | |||
681 | { | ||
682 | .name = "Weird sized block writes", | ||
683 | .prepare = mmc_test_prepare_verify_write, | ||
684 | .run = mmc_test_weird_write, | ||
685 | .cleanup = mmc_test_cleanup_verify, | ||
686 | }, | ||
687 | |||
688 | { | ||
689 | .name = "Weird sized block reads", | ||
690 | .prepare = mmc_test_prepare_verify_read, | ||
691 | .run = mmc_test_weird_read, | ||
692 | .cleanup = mmc_test_cleanup_verify, | ||
693 | }, | ||
694 | |||
695 | { | ||
696 | .name = "Badly aligned write", | ||
697 | .prepare = mmc_test_prepare_verify_write, | ||
698 | .run = mmc_test_align_write, | ||
699 | .cleanup = mmc_test_cleanup_verify, | ||
700 | }, | ||
701 | |||
702 | { | ||
703 | .name = "Badly aligned read", | ||
704 | .prepare = mmc_test_prepare_verify_read, | ||
705 | .run = mmc_test_align_read, | ||
706 | .cleanup = mmc_test_cleanup_verify, | ||
707 | }, | ||
708 | |||
709 | { | ||
710 | .name = "Badly aligned multi-block write", | ||
711 | .prepare = mmc_test_prepare_verify_write, | ||
712 | .run = mmc_test_align_multi_write, | ||
713 | .cleanup = mmc_test_cleanup_verify, | ||
714 | }, | ||
715 | |||
716 | { | ||
717 | .name = "Badly aligned multi-block read", | ||
718 | .prepare = mmc_test_prepare_verify_read, | ||
719 | .run = mmc_test_align_multi_read, | ||
720 | .cleanup = mmc_test_cleanup_verify, | ||
721 | }, | ||
722 | |||
723 | { | ||
724 | .name = "Correct xfer_size at write (start failure)", | ||
725 | .run = mmc_test_xfersize_write, | ||
726 | }, | ||
727 | |||
728 | { | ||
729 | .name = "Correct xfer_size at read (start failure)", | ||
730 | .run = mmc_test_xfersize_read, | ||
731 | }, | ||
732 | |||
733 | { | ||
734 | .name = "Correct xfer_size at write (midway failure)", | ||
735 | .run = mmc_test_multi_xfersize_write, | ||
736 | }, | ||
737 | |||
738 | { | ||
739 | .name = "Correct xfer_size at read (midway failure)", | ||
740 | .run = mmc_test_multi_xfersize_read, | ||
741 | }, | ||
742 | }; | ||
743 | |||
744 | static struct mutex mmc_test_lock; | ||
745 | |||
746 | static void mmc_test_run(struct mmc_test_card *test) | ||
747 | { | ||
748 | int i, ret; | ||
749 | |||
750 | printk(KERN_INFO "%s: Starting tests of card %s...\n", | ||
751 | mmc_hostname(test->card->host), mmc_card_id(test->card)); | ||
752 | |||
753 | mmc_claim_host(test->card->host); | ||
754 | |||
755 | for (i = 0;i < ARRAY_SIZE(mmc_test_cases);i++) { | ||
756 | printk(KERN_INFO "%s: Test case %d. %s...\n", | ||
757 | mmc_hostname(test->card->host), i + 1, | ||
758 | mmc_test_cases[i].name); | ||
759 | |||
760 | if (mmc_test_cases[i].prepare) { | ||
761 | ret = mmc_test_cases[i].prepare(test); | ||
762 | if (ret) { | ||
763 | printk(KERN_INFO "%s: Result: Prepare " | ||
764 | "stage failed! (%d)\n", | ||
765 | mmc_hostname(test->card->host), | ||
766 | ret); | ||
767 | continue; | ||
768 | } | ||
769 | } | ||
770 | |||
771 | ret = mmc_test_cases[i].run(test); | ||
772 | switch (ret) { | ||
773 | case RESULT_OK: | ||
774 | printk(KERN_INFO "%s: Result: OK\n", | ||
775 | mmc_hostname(test->card->host)); | ||
776 | break; | ||
777 | case RESULT_FAIL: | ||
778 | printk(KERN_INFO "%s: Result: FAILED\n", | ||
779 | mmc_hostname(test->card->host)); | ||
780 | break; | ||
781 | case RESULT_UNSUP_HOST: | ||
782 | printk(KERN_INFO "%s: Result: UNSUPPORTED " | ||
783 | "(by host)\n", | ||
784 | mmc_hostname(test->card->host)); | ||
785 | break; | ||
786 | case RESULT_UNSUP_CARD: | ||
787 | printk(KERN_INFO "%s: Result: UNSUPPORTED " | ||
788 | "(by card)\n", | ||
789 | mmc_hostname(test->card->host)); | ||
790 | break; | ||
791 | default: | ||
792 | printk(KERN_INFO "%s: Result: ERROR (%d)\n", | ||
793 | mmc_hostname(test->card->host), ret); | ||
794 | } | ||
795 | |||
796 | if (mmc_test_cases[i].cleanup) { | ||
797 | ret = mmc_test_cases[i].cleanup(test); | ||
798 | if (ret) { | ||
799 | printk(KERN_INFO "%s: Warning: Cleanup " | ||
800 | "stage failed! (%d)\n", | ||
801 | mmc_hostname(test->card->host), | ||
802 | ret); | ||
803 | } | ||
804 | } | ||
805 | } | ||
806 | |||
807 | mmc_release_host(test->card->host); | ||
808 | |||
809 | printk(KERN_INFO "%s: Tests completed.\n", | ||
810 | mmc_hostname(test->card->host)); | ||
811 | } | ||
812 | |||
813 | static ssize_t mmc_test_show(struct device *dev, | ||
814 | struct device_attribute *attr, char *buf) | ||
815 | { | ||
816 | mutex_lock(&mmc_test_lock); | ||
817 | mutex_unlock(&mmc_test_lock); | ||
818 | |||
819 | return 0; | ||
820 | } | ||
821 | |||
822 | static ssize_t mmc_test_store(struct device *dev, | ||
823 | struct device_attribute *attr, const char *buf, size_t count) | ||
824 | { | ||
825 | struct mmc_card *card; | ||
826 | struct mmc_test_card *test; | ||
827 | |||
828 | card = container_of(dev, struct mmc_card, dev); | ||
829 | |||
830 | test = kzalloc(sizeof(struct mmc_test_card), GFP_KERNEL); | ||
831 | if (!test) | ||
832 | return -ENOMEM; | ||
833 | |||
834 | test->card = card; | ||
835 | |||
836 | test->buffer = kzalloc(BUFFER_SIZE, GFP_KERNEL); | ||
837 | if (test->buffer) { | ||
838 | mutex_lock(&mmc_test_lock); | ||
839 | mmc_test_run(test); | ||
840 | mutex_unlock(&mmc_test_lock); | ||
841 | } | ||
842 | |||
843 | kfree(test->buffer); | ||
844 | kfree(test); | ||
845 | |||
846 | return count; | ||
847 | } | ||
848 | |||
849 | static DEVICE_ATTR(test, S_IWUSR | S_IRUGO, mmc_test_show, mmc_test_store); | ||
850 | |||
851 | static int mmc_test_probe(struct mmc_card *card) | ||
852 | { | ||
853 | int ret; | ||
854 | |||
855 | mutex_init(&mmc_test_lock); | ||
856 | |||
857 | ret = device_create_file(&card->dev, &dev_attr_test); | ||
858 | if (ret) | ||
859 | return ret; | ||
860 | |||
861 | return 0; | ||
862 | } | ||
863 | |||
864 | static void mmc_test_remove(struct mmc_card *card) | ||
865 | { | ||
866 | device_remove_file(&card->dev, &dev_attr_test); | ||
867 | } | ||
868 | |||
869 | static struct mmc_driver mmc_driver = { | ||
870 | .drv = { | ||
871 | .name = "mmc_test", | ||
872 | }, | ||
873 | .probe = mmc_test_probe, | ||
874 | .remove = mmc_test_remove, | ||
875 | }; | ||
876 | |||
877 | static int __init mmc_test_init(void) | ||
878 | { | ||
879 | return mmc_register_driver(&mmc_driver); | ||
880 | } | ||
881 | |||
882 | static void __exit mmc_test_exit(void) | ||
883 | { | ||
884 | mmc_unregister_driver(&mmc_driver); | ||
885 | } | ||
886 | |||
887 | module_init(mmc_test_init); | ||
888 | module_exit(mmc_test_exit); | ||
889 | |||
890 | MODULE_LICENSE("GPL"); | ||
891 | MODULE_DESCRIPTION("Multimedia Card (MMC) host test driver"); | ||
892 | MODULE_AUTHOR("Pierre Ossman"); | ||
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 3b3cd0e74715..dead61754ad7 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig | |||
@@ -119,7 +119,7 @@ config MMC_TIFM_SD | |||
119 | 119 | ||
120 | config MMC_SPI | 120 | config MMC_SPI |
121 | tristate "MMC/SD over SPI" | 121 | tristate "MMC/SD over SPI" |
122 | depends on MMC && SPI_MASTER && !HIGHMEM | 122 | depends on MMC && SPI_MASTER && !HIGHMEM && HAS_DMA |
123 | select CRC7 | 123 | select CRC7 |
124 | select CRC_ITU_T | 124 | select CRC_ITU_T |
125 | help | 125 | help |
diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index a28fc2f68ce2..8979ad330a4d 100644 --- a/drivers/mmc/host/at91_mci.c +++ b/drivers/mmc/host/at91_mci.c | |||
@@ -663,9 +663,12 @@ static void at91_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
663 | gpio_set_value(host->board->vcc_pin, 0); | 663 | gpio_set_value(host->board->vcc_pin, 0); |
664 | break; | 664 | break; |
665 | case MMC_POWER_UP: | 665 | case MMC_POWER_UP: |
666 | case MMC_POWER_ON: | ||
667 | gpio_set_value(host->board->vcc_pin, 1); | 666 | gpio_set_value(host->board->vcc_pin, 1); |
668 | break; | 667 | break; |
668 | case MMC_POWER_ON: | ||
669 | break; | ||
670 | default: | ||
671 | WARN_ON(1); | ||
669 | } | 672 | } |
670 | } | 673 | } |
671 | } | 674 | } |
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c index 14759e9f42ad..549517c35675 100644 --- a/drivers/mmc/host/omap.c +++ b/drivers/mmc/host/omap.c | |||
@@ -1003,7 +1003,7 @@ static void mmc_omap_dma_cb(int lch, u16 ch_status, void *data) | |||
1003 | 1003 | ||
1004 | static int mmc_omap_get_dma_channel(struct mmc_omap_host *host, struct mmc_data *data) | 1004 | static int mmc_omap_get_dma_channel(struct mmc_omap_host *host, struct mmc_data *data) |
1005 | { | 1005 | { |
1006 | const char *dev_name; | 1006 | const char *dma_dev_name; |
1007 | int sync_dev, dma_ch, is_read, r; | 1007 | int sync_dev, dma_ch, is_read, r; |
1008 | 1008 | ||
1009 | is_read = !(data->flags & MMC_DATA_WRITE); | 1009 | is_read = !(data->flags & MMC_DATA_WRITE); |
@@ -1018,21 +1018,21 @@ static int mmc_omap_get_dma_channel(struct mmc_omap_host *host, struct mmc_data | |||
1018 | if (is_read) { | 1018 | if (is_read) { |
1019 | if (host->id == 1) { | 1019 | if (host->id == 1) { |
1020 | sync_dev = OMAP_DMA_MMC_RX; | 1020 | sync_dev = OMAP_DMA_MMC_RX; |
1021 | dev_name = "MMC1 read"; | 1021 | dma_dev_name = "MMC1 read"; |
1022 | } else { | 1022 | } else { |
1023 | sync_dev = OMAP_DMA_MMC2_RX; | 1023 | sync_dev = OMAP_DMA_MMC2_RX; |
1024 | dev_name = "MMC2 read"; | 1024 | dma_dev_name = "MMC2 read"; |
1025 | } | 1025 | } |
1026 | } else { | 1026 | } else { |
1027 | if (host->id == 1) { | 1027 | if (host->id == 1) { |
1028 | sync_dev = OMAP_DMA_MMC_TX; | 1028 | sync_dev = OMAP_DMA_MMC_TX; |
1029 | dev_name = "MMC1 write"; | 1029 | dma_dev_name = "MMC1 write"; |
1030 | } else { | 1030 | } else { |
1031 | sync_dev = OMAP_DMA_MMC2_TX; | 1031 | sync_dev = OMAP_DMA_MMC2_TX; |
1032 | dev_name = "MMC2 write"; | 1032 | dma_dev_name = "MMC2 write"; |
1033 | } | 1033 | } |
1034 | } | 1034 | } |
1035 | r = omap_request_dma(sync_dev, dev_name, mmc_omap_dma_cb, | 1035 | r = omap_request_dma(sync_dev, dma_dev_name, mmc_omap_dma_cb, |
1036 | host, &dma_ch); | 1036 | host, &dma_ch); |
1037 | if (r != 0) { | 1037 | if (r != 0) { |
1038 | dev_dbg(mmc_dev(host->mmc), "omap_request_dma() failed with %d\n", r); | 1038 | dev_dbg(mmc_dev(host->mmc), "omap_request_dma() failed with %d\n", r); |
diff --git a/drivers/mmc/host/wbsd.c b/drivers/mmc/host/wbsd.c index be624a049c67..c303e7f57ab4 100644 --- a/drivers/mmc/host/wbsd.c +++ b/drivers/mmc/host/wbsd.c | |||
@@ -1457,17 +1457,7 @@ static int __devinit wbsd_request_irq(struct wbsd_host *host, int irq) | |||
1457 | int ret; | 1457 | int ret; |
1458 | 1458 | ||
1459 | /* | 1459 | /* |
1460 | * Allocate interrupt. | 1460 | * Set up tasklets. Must be done before requesting interrupt. |
1461 | */ | ||
1462 | |||
1463 | ret = request_irq(irq, wbsd_irq, IRQF_SHARED, DRIVER_NAME, host); | ||
1464 | if (ret) | ||
1465 | return ret; | ||
1466 | |||
1467 | host->irq = irq; | ||
1468 | |||
1469 | /* | ||
1470 | * Set up tasklets. | ||
1471 | */ | 1461 | */ |
1472 | tasklet_init(&host->card_tasklet, wbsd_tasklet_card, | 1462 | tasklet_init(&host->card_tasklet, wbsd_tasklet_card, |
1473 | (unsigned long)host); | 1463 | (unsigned long)host); |
@@ -1480,6 +1470,15 @@ static int __devinit wbsd_request_irq(struct wbsd_host *host, int irq) | |||
1480 | tasklet_init(&host->finish_tasklet, wbsd_tasklet_finish, | 1470 | tasklet_init(&host->finish_tasklet, wbsd_tasklet_finish, |
1481 | (unsigned long)host); | 1471 | (unsigned long)host); |
1482 | 1472 | ||
1473 | /* | ||
1474 | * Allocate interrupt. | ||
1475 | */ | ||
1476 | ret = request_irq(irq, wbsd_irq, IRQF_SHARED, DRIVER_NAME, host); | ||
1477 | if (ret) | ||
1478 | return ret; | ||
1479 | |||
1480 | host->irq = irq; | ||
1481 | |||
1483 | return 0; | 1482 | return 0; |
1484 | } | 1483 | } |
1485 | 1484 | ||
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index 25efd331ef28..b402269301f6 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c | |||
@@ -346,8 +346,10 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len, | |||
346 | mutex_lock(&flash->lock); | 346 | mutex_lock(&flash->lock); |
347 | 347 | ||
348 | /* Wait until finished previous write command. */ | 348 | /* Wait until finished previous write command. */ |
349 | if (wait_till_ready(flash)) | 349 | if (wait_till_ready(flash)) { |
350 | mutex_unlock(&flash->lock); | ||
350 | return 1; | 351 | return 1; |
352 | } | ||
351 | 353 | ||
352 | write_enable(flash); | 354 | write_enable(flash); |
353 | 355 | ||
diff --git a/drivers/mtd/maps/ck804xrom.c b/drivers/mtd/maps/ck804xrom.c index 59d8fb49270a..effaf7cdefab 100644 --- a/drivers/mtd/maps/ck804xrom.c +++ b/drivers/mtd/maps/ck804xrom.c | |||
@@ -331,15 +331,15 @@ static void __devexit ck804xrom_remove_one (struct pci_dev *pdev) | |||
331 | } | 331 | } |
332 | 332 | ||
333 | static struct pci_device_id ck804xrom_pci_tbl[] = { | 333 | static struct pci_device_id ck804xrom_pci_tbl[] = { |
334 | { PCI_VENDOR_ID_NVIDIA, 0x0051, PCI_ANY_ID, PCI_ANY_ID, DEV_CK804 }, | 334 | { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 0x0051), .driver_data = DEV_CK804 }, |
335 | { PCI_VENDOR_ID_NVIDIA, 0x0360, PCI_ANY_ID, PCI_ANY_ID, DEV_MCP55 }, | 335 | { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 0x0360), .driver_data = DEV_MCP55 }, |
336 | { PCI_VENDOR_ID_NVIDIA, 0x0361, PCI_ANY_ID, PCI_ANY_ID, DEV_MCP55 }, | 336 | { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 0x0361), .driver_data = DEV_MCP55 }, |
337 | { PCI_VENDOR_ID_NVIDIA, 0x0362, PCI_ANY_ID, PCI_ANY_ID, DEV_MCP55 }, | 337 | { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 0x0362), .driver_data = DEV_MCP55 }, |
338 | { PCI_VENDOR_ID_NVIDIA, 0x0363, PCI_ANY_ID, PCI_ANY_ID, DEV_MCP55 }, | 338 | { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 0x0363), .driver_data = DEV_MCP55 }, |
339 | { PCI_VENDOR_ID_NVIDIA, 0x0364, PCI_ANY_ID, PCI_ANY_ID, DEV_MCP55 }, | 339 | { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 0x0364), .driver_data = DEV_MCP55 }, |
340 | { PCI_VENDOR_ID_NVIDIA, 0x0365, PCI_ANY_ID, PCI_ANY_ID, DEV_MCP55 }, | 340 | { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 0x0365), .driver_data = DEV_MCP55 }, |
341 | { PCI_VENDOR_ID_NVIDIA, 0x0366, PCI_ANY_ID, PCI_ANY_ID, DEV_MCP55 }, | 341 | { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 0x0366), .driver_data = DEV_MCP55 }, |
342 | { PCI_VENDOR_ID_NVIDIA, 0x0367, PCI_ANY_ID, PCI_ANY_ID, DEV_MCP55 }, | 342 | { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 0x0367), .driver_data = DEV_MCP55 }, |
343 | { 0, } | 343 | { 0, } |
344 | }; | 344 | }; |
345 | 345 | ||
diff --git a/drivers/mtd/maps/omap_nor.c b/drivers/mtd/maps/omap_nor.c index 240b0e2d095d..c12d8056bebd 100644 --- a/drivers/mtd/maps/omap_nor.c +++ b/drivers/mtd/maps/omap_nor.c | |||
@@ -110,7 +110,7 @@ static int __init omapflash_probe(struct platform_device *pdev) | |||
110 | err = parse_mtd_partitions(info->mtd, part_probes, &info->parts, 0); | 110 | err = parse_mtd_partitions(info->mtd, part_probes, &info->parts, 0); |
111 | if (err > 0) | 111 | if (err > 0) |
112 | add_mtd_partitions(info->mtd, info->parts, err); | 112 | add_mtd_partitions(info->mtd, info->parts, err); |
113 | else if (err < 0 && pdata->parts) | 113 | else if (err <= 0 && pdata->parts) |
114 | add_mtd_partitions(info->mtd, pdata->parts, pdata->nr_parts); | 114 | add_mtd_partitions(info->mtd, pdata->parts, pdata->nr_parts); |
115 | else | 115 | else |
116 | #endif | 116 | #endif |
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index fceb468ccdec..fe2bc7e42119 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c | |||
@@ -1216,7 +1216,7 @@ static int pxa3xx_nand_resume(struct platform_device *pdev) | |||
1216 | 1216 | ||
1217 | clk_enable(info->clk); | 1217 | clk_enable(info->clk); |
1218 | 1218 | ||
1219 | return pxa3xx_nand_config_flash(info); | 1219 | return pxa3xx_nand_config_flash(info, info->flash_info); |
1220 | } | 1220 | } |
1221 | #else | 1221 | #else |
1222 | #define pxa3xx_nand_suspend NULL | 1222 | #define pxa3xx_nand_suspend NULL |
diff --git a/drivers/mtd/onenand/generic.c b/drivers/mtd/onenand/generic.c index 3d44d040a47d..ad81ab8e95e2 100644 --- a/drivers/mtd/onenand/generic.c +++ b/drivers/mtd/onenand/generic.c | |||
@@ -76,7 +76,7 @@ static int __devinit generic_onenand_probe(struct device *dev) | |||
76 | err = parse_mtd_partitions(&info->mtd, part_probes, &info->parts, 0); | 76 | err = parse_mtd_partitions(&info->mtd, part_probes, &info->parts, 0); |
77 | if (err > 0) | 77 | if (err > 0) |
78 | add_mtd_partitions(&info->mtd, info->parts, err); | 78 | add_mtd_partitions(&info->mtd, info->parts, err); |
79 | else if (err < 0 && pdata->parts) | 79 | else if (err <= 0 && pdata->parts) |
80 | add_mtd_partitions(&info->mtd, pdata->parts, pdata->nr_parts); | 80 | add_mtd_partitions(&info->mtd, pdata->parts, pdata->nr_parts); |
81 | else | 81 | else |
82 | #endif | 82 | #endif |
diff --git a/drivers/mtd/redboot.c b/drivers/mtd/redboot.c index 47474903263c..c5030f94f04e 100644 --- a/drivers/mtd/redboot.c +++ b/drivers/mtd/redboot.c | |||
@@ -295,5 +295,5 @@ module_init(redboot_parser_init); | |||
295 | module_exit(redboot_parser_exit); | 295 | module_exit(redboot_parser_exit); |
296 | 296 | ||
297 | MODULE_LICENSE("GPL"); | 297 | MODULE_LICENSE("GPL"); |
298 | MODULE_AUTHOR("Red Hat, Inc. - David Woodhouse <dwmw2@cambridge.redhat.com>"); | 298 | MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>"); |
299 | MODULE_DESCRIPTION("Parsing code for RedBoot Flash Image System (FIS) tables"); | 299 | MODULE_DESCRIPTION("Parsing code for RedBoot Flash Image System (FIS) tables"); |
diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c index e6c545fe5f58..b9d097c9f6bb 100644 --- a/drivers/net/3c509.c +++ b/drivers/net/3c509.c | |||
@@ -413,7 +413,7 @@ static int __devinit el3_pnp_probe(struct pnp_dev *pdev, | |||
413 | { | 413 | { |
414 | short i; | 414 | short i; |
415 | int ioaddr, irq, if_port; | 415 | int ioaddr, irq, if_port; |
416 | u16 phys_addr[3]; | 416 | __be16 phys_addr[3]; |
417 | struct net_device *dev = NULL; | 417 | struct net_device *dev = NULL; |
418 | int err; | 418 | int err; |
419 | 419 | ||
@@ -605,7 +605,7 @@ static int __init el3_mca_probe(struct device *device) | |||
605 | 605 | ||
606 | short i; | 606 | short i; |
607 | int ioaddr, irq, if_port; | 607 | int ioaddr, irq, if_port; |
608 | u16 phys_addr[3]; | 608 | __be16 phys_addr[3]; |
609 | struct net_device *dev = NULL; | 609 | struct net_device *dev = NULL; |
610 | u_char pos4, pos5; | 610 | u_char pos4, pos5; |
611 | struct mca_device *mdev = to_mca_device(device); | 611 | struct mca_device *mdev = to_mca_device(device); |
@@ -635,14 +635,13 @@ static int __init el3_mca_probe(struct device *device) | |||
635 | printk(KERN_DEBUG "3c529: irq %d ioaddr 0x%x ifport %d\n", irq, ioaddr, if_port); | 635 | printk(KERN_DEBUG "3c529: irq %d ioaddr 0x%x ifport %d\n", irq, ioaddr, if_port); |
636 | } | 636 | } |
637 | EL3WINDOW(0); | 637 | EL3WINDOW(0); |
638 | for (i = 0; i < 3; i++) { | 638 | for (i = 0; i < 3; i++) |
639 | phys_addr[i] = htons(read_eeprom(ioaddr, i)); | 639 | phys_addr[i] = htons(read_eeprom(ioaddr, i)); |
640 | } | ||
641 | 640 | ||
642 | dev = alloc_etherdev(sizeof (struct el3_private)); | 641 | dev = alloc_etherdev(sizeof (struct el3_private)); |
643 | if (dev == NULL) { | 642 | if (dev == NULL) { |
644 | release_region(ioaddr, EL3_IO_EXTENT); | 643 | release_region(ioaddr, EL3_IO_EXTENT); |
645 | return -ENOMEM; | 644 | return -ENOMEM; |
646 | } | 645 | } |
647 | 646 | ||
648 | netdev_boot_setup_check(dev); | 647 | netdev_boot_setup_check(dev); |
@@ -668,7 +667,7 @@ static int __init el3_eisa_probe (struct device *device) | |||
668 | { | 667 | { |
669 | short i; | 668 | short i; |
670 | int ioaddr, irq, if_port; | 669 | int ioaddr, irq, if_port; |
671 | u16 phys_addr[3]; | 670 | __be16 phys_addr[3]; |
672 | struct net_device *dev = NULL; | 671 | struct net_device *dev = NULL; |
673 | struct eisa_device *edev; | 672 | struct eisa_device *edev; |
674 | int err; | 673 | int err; |
@@ -1063,7 +1062,6 @@ el3_rx(struct net_device *dev) | |||
1063 | struct sk_buff *skb; | 1062 | struct sk_buff *skb; |
1064 | 1063 | ||
1065 | skb = dev_alloc_skb(pkt_len+5); | 1064 | skb = dev_alloc_skb(pkt_len+5); |
1066 | dev->stats.rx_bytes += pkt_len; | ||
1067 | if (el3_debug > 4) | 1065 | if (el3_debug > 4) |
1068 | printk("Receiving packet size %d status %4.4x.\n", | 1066 | printk("Receiving packet size %d status %4.4x.\n", |
1069 | pkt_len, rx_status); | 1067 | pkt_len, rx_status); |
@@ -1078,6 +1076,7 @@ el3_rx(struct net_device *dev) | |||
1078 | skb->protocol = eth_type_trans(skb,dev); | 1076 | skb->protocol = eth_type_trans(skb,dev); |
1079 | netif_rx(skb); | 1077 | netif_rx(skb); |
1080 | dev->last_rx = jiffies; | 1078 | dev->last_rx = jiffies; |
1079 | dev->stats.rx_bytes += pkt_len; | ||
1081 | dev->stats.rx_packets++; | 1080 | dev->stats.rx_packets++; |
1082 | continue; | 1081 | continue; |
1083 | } | 1082 | } |
diff --git a/drivers/net/7990.c b/drivers/net/7990.c index 750a46f4bc58..ad6b8a5b6574 100644 --- a/drivers/net/7990.c +++ b/drivers/net/7990.c | |||
@@ -506,6 +506,7 @@ int lance_open (struct net_device *dev) | |||
506 | 506 | ||
507 | return res; | 507 | return res; |
508 | } | 508 | } |
509 | EXPORT_SYMBOL_GPL(lance_open); | ||
509 | 510 | ||
510 | int lance_close (struct net_device *dev) | 511 | int lance_close (struct net_device *dev) |
511 | { | 512 | { |
@@ -521,6 +522,7 @@ int lance_close (struct net_device *dev) | |||
521 | 522 | ||
522 | return 0; | 523 | return 0; |
523 | } | 524 | } |
525 | EXPORT_SYMBOL_GPL(lance_close); | ||
524 | 526 | ||
525 | void lance_tx_timeout(struct net_device *dev) | 527 | void lance_tx_timeout(struct net_device *dev) |
526 | { | 528 | { |
@@ -529,7 +531,7 @@ void lance_tx_timeout(struct net_device *dev) | |||
529 | dev->trans_start = jiffies; | 531 | dev->trans_start = jiffies; |
530 | netif_wake_queue (dev); | 532 | netif_wake_queue (dev); |
531 | } | 533 | } |
532 | 534 | EXPORT_SYMBOL_GPL(lance_tx_timeout); | |
533 | 535 | ||
534 | int lance_start_xmit (struct sk_buff *skb, struct net_device *dev) | 536 | int lance_start_xmit (struct sk_buff *skb, struct net_device *dev) |
535 | { | 537 | { |
@@ -586,6 +588,7 @@ int lance_start_xmit (struct sk_buff *skb, struct net_device *dev) | |||
586 | 588 | ||
587 | return 0; | 589 | return 0; |
588 | } | 590 | } |
591 | EXPORT_SYMBOL_GPL(lance_start_xmit); | ||
589 | 592 | ||
590 | /* taken from the depca driver via a2065.c */ | 593 | /* taken from the depca driver via a2065.c */ |
591 | static void lance_load_multicast (struct net_device *dev) | 594 | static void lance_load_multicast (struct net_device *dev) |
@@ -654,6 +657,7 @@ void lance_set_multicast (struct net_device *dev) | |||
654 | if (!stopped) | 657 | if (!stopped) |
655 | netif_start_queue (dev); | 658 | netif_start_queue (dev); |
656 | } | 659 | } |
660 | EXPORT_SYMBOL_GPL(lance_set_multicast); | ||
657 | 661 | ||
658 | #ifdef CONFIG_NET_POLL_CONTROLLER | 662 | #ifdef CONFIG_NET_POLL_CONTROLLER |
659 | void lance_poll(struct net_device *dev) | 663 | void lance_poll(struct net_device *dev) |
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 9f6cc8a56073..f4182cfffe9d 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
@@ -1353,7 +1353,7 @@ config APRICOT | |||
1353 | 1353 | ||
1354 | config B44 | 1354 | config B44 |
1355 | tristate "Broadcom 440x/47xx ethernet support" | 1355 | tristate "Broadcom 440x/47xx ethernet support" |
1356 | depends on SSB_POSSIBLE | 1356 | depends on SSB_POSSIBLE && HAS_DMA |
1357 | select SSB | 1357 | select SSB |
1358 | select MII | 1358 | select MII |
1359 | help | 1359 | help |
@@ -2426,7 +2426,7 @@ config CHELSIO_T3 | |||
2426 | 2426 | ||
2427 | config EHEA | 2427 | config EHEA |
2428 | tristate "eHEA Ethernet support" | 2428 | tristate "eHEA Ethernet support" |
2429 | depends on IBMEBUS && INET && SPARSEMEM && MEMORY_HOTPLUG | 2429 | depends on IBMEBUS && INET && SPARSEMEM |
2430 | select INET_LRO | 2430 | select INET_LRO |
2431 | ---help--- | 2431 | ---help--- |
2432 | This driver supports the IBM pSeries eHEA ethernet adapter. | 2432 | This driver supports the IBM pSeries eHEA ethernet adapter. |
diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c index 9c2394d49428..99e0b4cdc56f 100644 --- a/drivers/net/atlx/atl1.c +++ b/drivers/net/atlx/atl1.c | |||
@@ -637,22 +637,6 @@ static s32 atl1_phy_leave_power_saving(struct atl1_hw *hw) | |||
637 | } | 637 | } |
638 | 638 | ||
639 | /* | 639 | /* |
640 | * Force the PHY into power saving mode using vendor magic. | ||
641 | */ | ||
642 | #ifdef CONFIG_PM | ||
643 | static void atl1_phy_enter_power_saving(struct atl1_hw *hw) | ||
644 | { | ||
645 | atl1_write_phy_reg(hw, MII_DBG_ADDR, 0); | ||
646 | atl1_write_phy_reg(hw, MII_DBG_DATA, 0x124E); | ||
647 | atl1_write_phy_reg(hw, MII_DBG_ADDR, 2); | ||
648 | atl1_write_phy_reg(hw, MII_DBG_DATA, 0x3000); | ||
649 | atl1_write_phy_reg(hw, MII_DBG_ADDR, 3); | ||
650 | atl1_write_phy_reg(hw, MII_DBG_DATA, 0); | ||
651 | |||
652 | } | ||
653 | #endif | ||
654 | |||
655 | /* | ||
656 | * Resets the PHY and make all config validate | 640 | * Resets the PHY and make all config validate |
657 | * hw - Struct containing variables accessed by shared code | 641 | * hw - Struct containing variables accessed by shared code |
658 | * | 642 | * |
@@ -2023,6 +2007,7 @@ rrd_ok: | |||
2023 | /* Good Receive */ | 2007 | /* Good Receive */ |
2024 | pci_unmap_page(adapter->pdev, buffer_info->dma, | 2008 | pci_unmap_page(adapter->pdev, buffer_info->dma, |
2025 | buffer_info->length, PCI_DMA_FROMDEVICE); | 2009 | buffer_info->length, PCI_DMA_FROMDEVICE); |
2010 | buffer_info->dma = 0; | ||
2026 | skb = buffer_info->skb; | 2011 | skb = buffer_info->skb; |
2027 | length = le16_to_cpu(rrd->xsz.xsum_sz.pkt_size); | 2012 | length = le16_to_cpu(rrd->xsz.xsum_sz.pkt_size); |
2028 | 2013 | ||
@@ -2135,7 +2120,7 @@ static int atl1_tso(struct atl1_adapter *adapter, struct sk_buff *skb, | |||
2135 | return -1; | 2120 | return -1; |
2136 | } | 2121 | } |
2137 | 2122 | ||
2138 | if (skb->protocol == ntohs(ETH_P_IP)) { | 2123 | if (skb->protocol == htons(ETH_P_IP)) { |
2139 | struct iphdr *iph = ip_hdr(skb); | 2124 | struct iphdr *iph = ip_hdr(skb); |
2140 | 2125 | ||
2141 | real_len = (((unsigned char *)iph - skb->data) + | 2126 | real_len = (((unsigned char *)iph - skb->data) + |
@@ -2859,7 +2844,6 @@ disable_wol: | |||
2859 | ctrl |= PCIE_PHYMISC_FORCE_RCV_DET; | 2844 | ctrl |= PCIE_PHYMISC_FORCE_RCV_DET; |
2860 | iowrite32(ctrl, hw->hw_addr + REG_PCIE_PHYMISC); | 2845 | iowrite32(ctrl, hw->hw_addr + REG_PCIE_PHYMISC); |
2861 | ioread32(hw->hw_addr + REG_PCIE_PHYMISC); | 2846 | ioread32(hw->hw_addr + REG_PCIE_PHYMISC); |
2862 | atl1_phy_enter_power_saving(hw); | ||
2863 | hw->phy_configured = false; | 2847 | hw->phy_configured = false; |
2864 | pci_enable_wake(pdev, pci_choose_state(pdev, state), 0); | 2848 | pci_enable_wake(pdev, pci_choose_state(pdev, state), 0); |
2865 | exit: | 2849 | exit: |
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c index 3634b5fd7919..7023d77bf380 100644 --- a/drivers/net/au1000_eth.c +++ b/drivers/net/au1000_eth.c | |||
@@ -1239,12 +1239,7 @@ static int au1000_rx(struct net_device *dev) | |||
1239 | */ | 1239 | */ |
1240 | static irqreturn_t au1000_interrupt(int irq, void *dev_id) | 1240 | static irqreturn_t au1000_interrupt(int irq, void *dev_id) |
1241 | { | 1241 | { |
1242 | struct net_device *dev = (struct net_device *) dev_id; | 1242 | struct net_device *dev = dev_id; |
1243 | |||
1244 | if (dev == NULL) { | ||
1245 | printk(KERN_ERR "%s: isr: null dev ptr\n", dev->name); | ||
1246 | return IRQ_RETVAL(1); | ||
1247 | } | ||
1248 | 1243 | ||
1249 | /* Handle RX interrupts first to minimize chance of overrun */ | 1244 | /* Handle RX interrupts first to minimize chance of overrun */ |
1250 | 1245 | ||
diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c index 89c0018132ec..41443435ab1c 100644 --- a/drivers/net/bfin_mac.c +++ b/drivers/net/bfin_mac.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include <linux/crc32.h> | 22 | #include <linux/crc32.h> |
23 | #include <linux/device.h> | 23 | #include <linux/device.h> |
24 | #include <linux/spinlock.h> | 24 | #include <linux/spinlock.h> |
25 | #include <linux/ethtool.h> | ||
26 | #include <linux/mii.h> | 25 | #include <linux/mii.h> |
27 | #include <linux/phy.h> | 26 | #include <linux/phy.h> |
28 | #include <linux/netdevice.h> | 27 | #include <linux/netdevice.h> |
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 4b46e68183e0..367b6d462708 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c | |||
@@ -5724,14 +5724,12 @@ bnx2_reset_task(struct work_struct *work) | |||
5724 | if (!netif_running(bp->dev)) | 5724 | if (!netif_running(bp->dev)) |
5725 | return; | 5725 | return; |
5726 | 5726 | ||
5727 | bp->in_reset_task = 1; | ||
5728 | bnx2_netif_stop(bp); | 5727 | bnx2_netif_stop(bp); |
5729 | 5728 | ||
5730 | bnx2_init_nic(bp); | 5729 | bnx2_init_nic(bp); |
5731 | 5730 | ||
5732 | atomic_set(&bp->intr_sem, 1); | 5731 | atomic_set(&bp->intr_sem, 1); |
5733 | bnx2_netif_start(bp); | 5732 | bnx2_netif_start(bp); |
5734 | bp->in_reset_task = 0; | ||
5735 | } | 5733 | } |
5736 | 5734 | ||
5737 | static void | 5735 | static void |
@@ -5907,12 +5905,7 @@ bnx2_close(struct net_device *dev) | |||
5907 | struct bnx2 *bp = netdev_priv(dev); | 5905 | struct bnx2 *bp = netdev_priv(dev); |
5908 | u32 reset_code; | 5906 | u32 reset_code; |
5909 | 5907 | ||
5910 | /* Calling flush_scheduled_work() may deadlock because | 5908 | cancel_work_sync(&bp->reset_task); |
5911 | * linkwatch_event() may be on the workqueue and it will try to get | ||
5912 | * the rtnl_lock which we are holding. | ||
5913 | */ | ||
5914 | while (bp->in_reset_task) | ||
5915 | msleep(1); | ||
5916 | 5909 | ||
5917 | bnx2_disable_int_sync(bp); | 5910 | bnx2_disable_int_sync(bp); |
5918 | bnx2_napi_disable(bp); | 5911 | bnx2_napi_disable(bp); |
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h index 1eaf5bb3d9c2..2377cc13bf61 100644 --- a/drivers/net/bnx2.h +++ b/drivers/net/bnx2.h | |||
@@ -6656,7 +6656,6 @@ struct bnx2 { | |||
6656 | int current_interval; | 6656 | int current_interval; |
6657 | struct timer_list timer; | 6657 | struct timer_list timer; |
6658 | struct work_struct reset_task; | 6658 | struct work_struct reset_task; |
6659 | int in_reset_task; | ||
6660 | 6659 | ||
6661 | /* Used to synchronize phy accesses. */ | 6660 | /* Used to synchronize phy accesses. */ |
6662 | spinlock_t phy_lock; | 6661 | spinlock_t phy_lock; |
diff --git a/drivers/net/bnx2x.c b/drivers/net/bnx2x.c index 7bdb5af35951..70cba64732ca 100644 --- a/drivers/net/bnx2x.c +++ b/drivers/net/bnx2x.c | |||
@@ -6,7 +6,8 @@ | |||
6 | * it under the terms of the GNU General Public License as published by | 6 | * it under the terms of the GNU General Public License as published by |
7 | * the Free Software Foundation. | 7 | * the Free Software Foundation. |
8 | * | 8 | * |
9 | * Written by: Eliezer Tamir <eliezert@broadcom.com> | 9 | * Maintained by: Eilon Greenstein <eilong@broadcom.com> |
10 | * Written by: Eliezer Tamir | ||
10 | * Based on code from Michael Chan's bnx2 driver | 11 | * Based on code from Michael Chan's bnx2 driver |
11 | * UDP CSUM errata workaround by Arik Gendelman | 12 | * UDP CSUM errata workaround by Arik Gendelman |
12 | * Slowpath rework by Vladislav Zolotarov | 13 | * Slowpath rework by Vladislav Zolotarov |
@@ -74,7 +75,7 @@ static char version[] __devinitdata = | |||
74 | "Broadcom NetXtreme II 5771X 10Gigabit Ethernet Driver " | 75 | "Broadcom NetXtreme II 5771X 10Gigabit Ethernet Driver " |
75 | DRV_MODULE_NAME " " DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; | 76 | DRV_MODULE_NAME " " DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; |
76 | 77 | ||
77 | MODULE_AUTHOR("Eliezer Tamir <eliezert@broadcom.com>"); | 78 | MODULE_AUTHOR("Eliezer Tamir"); |
78 | MODULE_DESCRIPTION("Broadcom NetXtreme II BCM57710 Driver"); | 79 | MODULE_DESCRIPTION("Broadcom NetXtreme II BCM57710 Driver"); |
79 | MODULE_LICENSE("GPL"); | 80 | MODULE_LICENSE("GPL"); |
80 | MODULE_VERSION(DRV_MODULE_VERSION); | 81 | MODULE_VERSION(DRV_MODULE_VERSION); |
diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h index 4f0c0d31e7c1..8e68d06510a6 100644 --- a/drivers/net/bnx2x.h +++ b/drivers/net/bnx2x.h | |||
@@ -6,7 +6,8 @@ | |||
6 | * it under the terms of the GNU General Public License as published by | 6 | * it under the terms of the GNU General Public License as published by |
7 | * the Free Software Foundation. | 7 | * the Free Software Foundation. |
8 | * | 8 | * |
9 | * Written by: Eliezer Tamir <eliezert@broadcom.com> | 9 | * Maintained by: Eilon Greenstein <eilong@broadcom.com> |
10 | * Written by: Eliezer Tamir | ||
10 | * Based on code from Michael Chan's bnx2 driver | 11 | * Based on code from Michael Chan's bnx2 driver |
11 | */ | 12 | */ |
12 | 13 | ||
diff --git a/drivers/net/bnx2x_init.h b/drivers/net/bnx2x_init.h index dcaecc53bdb1..370686eef97c 100644 --- a/drivers/net/bnx2x_init.h +++ b/drivers/net/bnx2x_init.h | |||
@@ -6,7 +6,8 @@ | |||
6 | * it under the terms of the GNU General Public License as published by | 6 | * it under the terms of the GNU General Public License as published by |
7 | * the Free Software Foundation. | 7 | * the Free Software Foundation. |
8 | * | 8 | * |
9 | * Written by: Eliezer Tamir <eliezert@broadcom.com> | 9 | * Maintained by: Eilon Greenstein <eilong@broadcom.com> |
10 | * Written by: Eliezer Tamir | ||
10 | */ | 11 | */ |
11 | 12 | ||
12 | #ifndef BNX2X_INIT_H | 13 | #ifndef BNX2X_INIT_H |
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index 68c41a00d93d..08f3d396bcd6 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c | |||
@@ -1437,8 +1437,16 @@ int bond_create_sysfs(void) | |||
1437 | * configure multiple bonding devices. | 1437 | * configure multiple bonding devices. |
1438 | */ | 1438 | */ |
1439 | if (ret == -EEXIST) { | 1439 | if (ret == -EEXIST) { |
1440 | netdev_class = NULL; | 1440 | /* Is someone being kinky and naming a device bonding_master? */ |
1441 | return 0; | 1441 | if (__dev_get_by_name(&init_net, |
1442 | class_attr_bonding_masters.attr.name)) | ||
1443 | printk(KERN_ERR | ||
1444 | "network device named %s already exists in sysfs", | ||
1445 | class_attr_bonding_masters.attr.name); | ||
1446 | else { | ||
1447 | netdev_class = NULL; | ||
1448 | return 0; | ||
1449 | } | ||
1442 | } | 1450 | } |
1443 | 1451 | ||
1444 | return ret; | 1452 | return ret; |
diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c index 93e13636f8dd..83768df27806 100644 --- a/drivers/net/cassini.c +++ b/drivers/net/cassini.c | |||
@@ -142,8 +142,8 @@ | |||
142 | 142 | ||
143 | #define DRV_MODULE_NAME "cassini" | 143 | #define DRV_MODULE_NAME "cassini" |
144 | #define PFX DRV_MODULE_NAME ": " | 144 | #define PFX DRV_MODULE_NAME ": " |
145 | #define DRV_MODULE_VERSION "1.5" | 145 | #define DRV_MODULE_VERSION "1.6" |
146 | #define DRV_MODULE_RELDATE "4 Jan 2008" | 146 | #define DRV_MODULE_RELDATE "21 May 2008" |
147 | 147 | ||
148 | #define CAS_DEF_MSG_ENABLE \ | 148 | #define CAS_DEF_MSG_ENABLE \ |
149 | (NETIF_MSG_DRV | \ | 149 | (NETIF_MSG_DRV | \ |
@@ -2136,9 +2136,12 @@ end_copy_pkt: | |||
2136 | if (addr) | 2136 | if (addr) |
2137 | cas_page_unmap(addr); | 2137 | cas_page_unmap(addr); |
2138 | } | 2138 | } |
2139 | skb->csum = csum_unfold(~csum); | ||
2140 | skb->ip_summed = CHECKSUM_COMPLETE; | ||
2141 | skb->protocol = eth_type_trans(skb, cp->dev); | 2139 | skb->protocol = eth_type_trans(skb, cp->dev); |
2140 | if (skb->protocol == htons(ETH_P_IP)) { | ||
2141 | skb->csum = csum_unfold(~csum); | ||
2142 | skb->ip_summed = CHECKSUM_COMPLETE; | ||
2143 | } else | ||
2144 | skb->ip_summed = CHECKSUM_NONE; | ||
2142 | return len; | 2145 | return len; |
2143 | } | 2146 | } |
2144 | 2147 | ||
diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c index 2b5740b3d182..7f3f62e1b113 100644 --- a/drivers/net/cpmac.c +++ b/drivers/net/cpmac.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/platform_device.h> | 38 | #include <linux/platform_device.h> |
39 | #include <linux/dma-mapping.h> | 39 | #include <linux/dma-mapping.h> |
40 | #include <asm/gpio.h> | 40 | #include <asm/gpio.h> |
41 | #include <asm/atomic.h> | ||
41 | 42 | ||
42 | MODULE_AUTHOR("Eugene Konev <ejka@imfi.kspu.ru>"); | 43 | MODULE_AUTHOR("Eugene Konev <ejka@imfi.kspu.ru>"); |
43 | MODULE_DESCRIPTION("TI AR7 ethernet driver (CPMAC)"); | 44 | MODULE_DESCRIPTION("TI AR7 ethernet driver (CPMAC)"); |
@@ -187,6 +188,7 @@ struct cpmac_desc { | |||
187 | #define CPMAC_EOQ 0x1000 | 188 | #define CPMAC_EOQ 0x1000 |
188 | struct sk_buff *skb; | 189 | struct sk_buff *skb; |
189 | struct cpmac_desc *next; | 190 | struct cpmac_desc *next; |
191 | struct cpmac_desc *prev; | ||
190 | dma_addr_t mapping; | 192 | dma_addr_t mapping; |
191 | dma_addr_t data_mapping; | 193 | dma_addr_t data_mapping; |
192 | }; | 194 | }; |
@@ -208,6 +210,7 @@ struct cpmac_priv { | |||
208 | struct work_struct reset_work; | 210 | struct work_struct reset_work; |
209 | struct platform_device *pdev; | 211 | struct platform_device *pdev; |
210 | struct napi_struct napi; | 212 | struct napi_struct napi; |
213 | atomic_t reset_pending; | ||
211 | }; | 214 | }; |
212 | 215 | ||
213 | static irqreturn_t cpmac_irq(int, void *); | 216 | static irqreturn_t cpmac_irq(int, void *); |
@@ -241,6 +244,16 @@ static void cpmac_dump_desc(struct net_device *dev, struct cpmac_desc *desc) | |||
241 | printk("\n"); | 244 | printk("\n"); |
242 | } | 245 | } |
243 | 246 | ||
247 | static void cpmac_dump_all_desc(struct net_device *dev) | ||
248 | { | ||
249 | struct cpmac_priv *priv = netdev_priv(dev); | ||
250 | struct cpmac_desc *dump = priv->rx_head; | ||
251 | do { | ||
252 | cpmac_dump_desc(dev, dump); | ||
253 | dump = dump->next; | ||
254 | } while (dump != priv->rx_head); | ||
255 | } | ||
256 | |||
244 | static void cpmac_dump_skb(struct net_device *dev, struct sk_buff *skb) | 257 | static void cpmac_dump_skb(struct net_device *dev, struct sk_buff *skb) |
245 | { | 258 | { |
246 | int i; | 259 | int i; |
@@ -412,21 +425,42 @@ static struct sk_buff *cpmac_rx_one(struct cpmac_priv *priv, | |||
412 | static int cpmac_poll(struct napi_struct *napi, int budget) | 425 | static int cpmac_poll(struct napi_struct *napi, int budget) |
413 | { | 426 | { |
414 | struct sk_buff *skb; | 427 | struct sk_buff *skb; |
415 | struct cpmac_desc *desc; | 428 | struct cpmac_desc *desc, *restart; |
416 | int received = 0; | ||
417 | struct cpmac_priv *priv = container_of(napi, struct cpmac_priv, napi); | 429 | struct cpmac_priv *priv = container_of(napi, struct cpmac_priv, napi); |
430 | int received = 0, processed = 0; | ||
418 | 431 | ||
419 | spin_lock(&priv->rx_lock); | 432 | spin_lock(&priv->rx_lock); |
420 | if (unlikely(!priv->rx_head)) { | 433 | if (unlikely(!priv->rx_head)) { |
421 | if (netif_msg_rx_err(priv) && net_ratelimit()) | 434 | if (netif_msg_rx_err(priv) && net_ratelimit()) |
422 | printk(KERN_WARNING "%s: rx: polling, but no queue\n", | 435 | printk(KERN_WARNING "%s: rx: polling, but no queue\n", |
423 | priv->dev->name); | 436 | priv->dev->name); |
437 | spin_unlock(&priv->rx_lock); | ||
424 | netif_rx_complete(priv->dev, napi); | 438 | netif_rx_complete(priv->dev, napi); |
425 | return 0; | 439 | return 0; |
426 | } | 440 | } |
427 | 441 | ||
428 | desc = priv->rx_head; | 442 | desc = priv->rx_head; |
443 | restart = NULL; | ||
429 | while (((desc->dataflags & CPMAC_OWN) == 0) && (received < budget)) { | 444 | while (((desc->dataflags & CPMAC_OWN) == 0) && (received < budget)) { |
445 | processed++; | ||
446 | |||
447 | if ((desc->dataflags & CPMAC_EOQ) != 0) { | ||
448 | /* The last update to eoq->hw_next didn't happen | ||
449 | * soon enough, and the receiver stopped here. | ||
450 | *Remember this descriptor so we can restart | ||
451 | * the receiver after freeing some space. | ||
452 | */ | ||
453 | if (unlikely(restart)) { | ||
454 | if (netif_msg_rx_err(priv)) | ||
455 | printk(KERN_ERR "%s: poll found a" | ||
456 | " duplicate EOQ: %p and %p\n", | ||
457 | priv->dev->name, restart, desc); | ||
458 | goto fatal_error; | ||
459 | } | ||
460 | |||
461 | restart = desc->next; | ||
462 | } | ||
463 | |||
430 | skb = cpmac_rx_one(priv, desc); | 464 | skb = cpmac_rx_one(priv, desc); |
431 | if (likely(skb)) { | 465 | if (likely(skb)) { |
432 | netif_receive_skb(skb); | 466 | netif_receive_skb(skb); |
@@ -435,19 +469,90 @@ static int cpmac_poll(struct napi_struct *napi, int budget) | |||
435 | desc = desc->next; | 469 | desc = desc->next; |
436 | } | 470 | } |
437 | 471 | ||
472 | if (desc != priv->rx_head) { | ||
473 | /* We freed some buffers, but not the whole ring, | ||
474 | * add what we did free to the rx list */ | ||
475 | desc->prev->hw_next = (u32)0; | ||
476 | priv->rx_head->prev->hw_next = priv->rx_head->mapping; | ||
477 | } | ||
478 | |||
479 | /* Optimization: If we did not actually process an EOQ (perhaps because | ||
480 | * of quota limits), check to see if the tail of the queue has EOQ set. | ||
481 | * We should immediately restart in that case so that the receiver can | ||
482 | * restart and run in parallel with more packet processing. | ||
483 | * This lets us handle slightly larger bursts before running | ||
484 | * out of ring space (assuming dev->weight < ring_size) */ | ||
485 | |||
486 | if (!restart && | ||
487 | (priv->rx_head->prev->dataflags & (CPMAC_OWN|CPMAC_EOQ)) | ||
488 | == CPMAC_EOQ && | ||
489 | (priv->rx_head->dataflags & CPMAC_OWN) != 0) { | ||
490 | /* reset EOQ so the poll loop (above) doesn't try to | ||
491 | * restart this when it eventually gets to this descriptor. | ||
492 | */ | ||
493 | priv->rx_head->prev->dataflags &= ~CPMAC_EOQ; | ||
494 | restart = priv->rx_head; | ||
495 | } | ||
496 | |||
497 | if (restart) { | ||
498 | priv->dev->stats.rx_errors++; | ||
499 | priv->dev->stats.rx_fifo_errors++; | ||
500 | if (netif_msg_rx_err(priv) && net_ratelimit()) | ||
501 | printk(KERN_WARNING "%s: rx dma ring overrun\n", | ||
502 | priv->dev->name); | ||
503 | |||
504 | if (unlikely((restart->dataflags & CPMAC_OWN) == 0)) { | ||
505 | if (netif_msg_drv(priv)) | ||
506 | printk(KERN_ERR "%s: cpmac_poll is trying to " | ||
507 | "restart rx from a descriptor that's " | ||
508 | "not free: %p\n", | ||
509 | priv->dev->name, restart); | ||
510 | goto fatal_error; | ||
511 | } | ||
512 | |||
513 | cpmac_write(priv->regs, CPMAC_RX_PTR(0), restart->mapping); | ||
514 | } | ||
515 | |||
438 | priv->rx_head = desc; | 516 | priv->rx_head = desc; |
439 | spin_unlock(&priv->rx_lock); | 517 | spin_unlock(&priv->rx_lock); |
440 | if (unlikely(netif_msg_rx_status(priv))) | 518 | if (unlikely(netif_msg_rx_status(priv))) |
441 | printk(KERN_DEBUG "%s: poll processed %d packets\n", | 519 | printk(KERN_DEBUG "%s: poll processed %d packets\n", |
442 | priv->dev->name, received); | 520 | priv->dev->name, received); |
443 | if (desc->dataflags & CPMAC_OWN) { | 521 | if (processed == 0) { |
522 | /* we ran out of packets to read, | ||
523 | * revert to interrupt-driven mode */ | ||
444 | netif_rx_complete(priv->dev, napi); | 524 | netif_rx_complete(priv->dev, napi); |
445 | cpmac_write(priv->regs, CPMAC_RX_PTR(0), (u32)desc->mapping); | ||
446 | cpmac_write(priv->regs, CPMAC_RX_INT_ENABLE, 1); | 525 | cpmac_write(priv->regs, CPMAC_RX_INT_ENABLE, 1); |
447 | return 0; | 526 | return 0; |
448 | } | 527 | } |
449 | 528 | ||
450 | return 1; | 529 | return 1; |
530 | |||
531 | fatal_error: | ||
532 | /* Something went horribly wrong. | ||
533 | * Reset hardware to try to recover rather than wedging. */ | ||
534 | |||
535 | if (netif_msg_drv(priv)) { | ||
536 | printk(KERN_ERR "%s: cpmac_poll is confused. " | ||
537 | "Resetting hardware\n", priv->dev->name); | ||
538 | cpmac_dump_all_desc(priv->dev); | ||
539 | printk(KERN_DEBUG "%s: RX_PTR(0)=0x%08x RX_ACK(0)=0x%08x\n", | ||
540 | priv->dev->name, | ||
541 | cpmac_read(priv->regs, CPMAC_RX_PTR(0)), | ||
542 | cpmac_read(priv->regs, CPMAC_RX_ACK(0))); | ||
543 | } | ||
544 | |||
545 | spin_unlock(&priv->rx_lock); | ||
546 | netif_rx_complete(priv->dev, napi); | ||
547 | netif_stop_queue(priv->dev); | ||
548 | napi_disable(&priv->napi); | ||
549 | |||
550 | atomic_inc(&priv->reset_pending); | ||
551 | cpmac_hw_stop(priv->dev); | ||
552 | if (!schedule_work(&priv->reset_work)) | ||
553 | atomic_dec(&priv->reset_pending); | ||
554 | return 0; | ||
555 | |||
451 | } | 556 | } |
452 | 557 | ||
453 | static int cpmac_start_xmit(struct sk_buff *skb, struct net_device *dev) | 558 | static int cpmac_start_xmit(struct sk_buff *skb, struct net_device *dev) |
@@ -456,6 +561,9 @@ static int cpmac_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
456 | struct cpmac_desc *desc; | 561 | struct cpmac_desc *desc; |
457 | struct cpmac_priv *priv = netdev_priv(dev); | 562 | struct cpmac_priv *priv = netdev_priv(dev); |
458 | 563 | ||
564 | if (unlikely(atomic_read(&priv->reset_pending))) | ||
565 | return NETDEV_TX_BUSY; | ||
566 | |||
459 | if (unlikely(skb_padto(skb, ETH_ZLEN))) | 567 | if (unlikely(skb_padto(skb, ETH_ZLEN))) |
460 | return NETDEV_TX_OK; | 568 | return NETDEV_TX_OK; |
461 | 569 | ||
@@ -621,8 +729,10 @@ static void cpmac_clear_rx(struct net_device *dev) | |||
621 | desc->dataflags = CPMAC_OWN; | 729 | desc->dataflags = CPMAC_OWN; |
622 | dev->stats.rx_dropped++; | 730 | dev->stats.rx_dropped++; |
623 | } | 731 | } |
732 | desc->hw_next = desc->next->mapping; | ||
624 | desc = desc->next; | 733 | desc = desc->next; |
625 | } | 734 | } |
735 | priv->rx_head->prev->hw_next = 0; | ||
626 | } | 736 | } |
627 | 737 | ||
628 | static void cpmac_clear_tx(struct net_device *dev) | 738 | static void cpmac_clear_tx(struct net_device *dev) |
@@ -635,14 +745,14 @@ static void cpmac_clear_tx(struct net_device *dev) | |||
635 | priv->desc_ring[i].dataflags = 0; | 745 | priv->desc_ring[i].dataflags = 0; |
636 | if (priv->desc_ring[i].skb) { | 746 | if (priv->desc_ring[i].skb) { |
637 | dev_kfree_skb_any(priv->desc_ring[i].skb); | 747 | dev_kfree_skb_any(priv->desc_ring[i].skb); |
638 | if (netif_subqueue_stopped(dev, i)) | 748 | priv->desc_ring[i].skb = NULL; |
639 | netif_wake_subqueue(dev, i); | ||
640 | } | 749 | } |
641 | } | 750 | } |
642 | } | 751 | } |
643 | 752 | ||
644 | static void cpmac_hw_error(struct work_struct *work) | 753 | static void cpmac_hw_error(struct work_struct *work) |
645 | { | 754 | { |
755 | int i; | ||
646 | struct cpmac_priv *priv = | 756 | struct cpmac_priv *priv = |
647 | container_of(work, struct cpmac_priv, reset_work); | 757 | container_of(work, struct cpmac_priv, reset_work); |
648 | 758 | ||
@@ -651,8 +761,48 @@ static void cpmac_hw_error(struct work_struct *work) | |||
651 | spin_unlock(&priv->rx_lock); | 761 | spin_unlock(&priv->rx_lock); |
652 | cpmac_clear_tx(priv->dev); | 762 | cpmac_clear_tx(priv->dev); |
653 | cpmac_hw_start(priv->dev); | 763 | cpmac_hw_start(priv->dev); |
654 | napi_enable(&priv->napi); | 764 | barrier(); |
655 | netif_start_queue(priv->dev); | 765 | atomic_dec(&priv->reset_pending); |
766 | |||
767 | for (i = 0; i < CPMAC_QUEUES; i++) | ||
768 | netif_wake_subqueue(priv->dev, i); | ||
769 | netif_wake_queue(priv->dev); | ||
770 | cpmac_write(priv->regs, CPMAC_MAC_INT_ENABLE, 3); | ||
771 | } | ||
772 | |||
773 | static void cpmac_check_status(struct net_device *dev) | ||
774 | { | ||
775 | struct cpmac_priv *priv = netdev_priv(dev); | ||
776 | |||
777 | u32 macstatus = cpmac_read(priv->regs, CPMAC_MAC_STATUS); | ||
778 | int rx_channel = (macstatus >> 8) & 7; | ||
779 | int rx_code = (macstatus >> 12) & 15; | ||
780 | int tx_channel = (macstatus >> 16) & 7; | ||
781 | int tx_code = (macstatus >> 20) & 15; | ||
782 | |||
783 | if (rx_code || tx_code) { | ||
784 | if (netif_msg_drv(priv) && net_ratelimit()) { | ||
785 | /* Can't find any documentation on what these | ||
786 | *error codes actually are. So just log them and hope.. | ||
787 | */ | ||
788 | if (rx_code) | ||
789 | printk(KERN_WARNING "%s: host error %d on rx " | ||
790 | "channel %d (macstatus %08x), resetting\n", | ||
791 | dev->name, rx_code, rx_channel, macstatus); | ||
792 | if (tx_code) | ||
793 | printk(KERN_WARNING "%s: host error %d on tx " | ||
794 | "channel %d (macstatus %08x), resetting\n", | ||
795 | dev->name, tx_code, tx_channel, macstatus); | ||
796 | } | ||
797 | |||
798 | netif_stop_queue(dev); | ||
799 | cpmac_hw_stop(dev); | ||
800 | if (schedule_work(&priv->reset_work)) | ||
801 | atomic_inc(&priv->reset_pending); | ||
802 | if (unlikely(netif_msg_hw(priv))) | ||
803 | cpmac_dump_regs(dev); | ||
804 | } | ||
805 | cpmac_write(priv->regs, CPMAC_MAC_INT_CLEAR, 0xff); | ||
656 | } | 806 | } |
657 | 807 | ||
658 | static irqreturn_t cpmac_irq(int irq, void *dev_id) | 808 | static irqreturn_t cpmac_irq(int irq, void *dev_id) |
@@ -683,49 +833,32 @@ static irqreturn_t cpmac_irq(int irq, void *dev_id) | |||
683 | 833 | ||
684 | cpmac_write(priv->regs, CPMAC_MAC_EOI_VECTOR, 0); | 834 | cpmac_write(priv->regs, CPMAC_MAC_EOI_VECTOR, 0); |
685 | 835 | ||
686 | if (unlikely(status & (MAC_INT_HOST | MAC_INT_STATUS))) { | 836 | if (unlikely(status & (MAC_INT_HOST | MAC_INT_STATUS))) |
687 | if (netif_msg_drv(priv) && net_ratelimit()) | 837 | cpmac_check_status(dev); |
688 | printk(KERN_ERR "%s: hw error, resetting...\n", | ||
689 | dev->name); | ||
690 | netif_stop_queue(dev); | ||
691 | napi_disable(&priv->napi); | ||
692 | cpmac_hw_stop(dev); | ||
693 | schedule_work(&priv->reset_work); | ||
694 | if (unlikely(netif_msg_hw(priv))) | ||
695 | cpmac_dump_regs(dev); | ||
696 | } | ||
697 | 838 | ||
698 | return IRQ_HANDLED; | 839 | return IRQ_HANDLED; |
699 | } | 840 | } |
700 | 841 | ||
701 | static void cpmac_tx_timeout(struct net_device *dev) | 842 | static void cpmac_tx_timeout(struct net_device *dev) |
702 | { | 843 | { |
703 | struct cpmac_priv *priv = netdev_priv(dev); | ||
704 | int i; | 844 | int i; |
845 | struct cpmac_priv *priv = netdev_priv(dev); | ||
705 | 846 | ||
706 | spin_lock(&priv->lock); | 847 | spin_lock(&priv->lock); |
707 | dev->stats.tx_errors++; | 848 | dev->stats.tx_errors++; |
708 | spin_unlock(&priv->lock); | 849 | spin_unlock(&priv->lock); |
709 | if (netif_msg_tx_err(priv) && net_ratelimit()) | 850 | if (netif_msg_tx_err(priv) && net_ratelimit()) |
710 | printk(KERN_WARNING "%s: transmit timeout\n", dev->name); | 851 | printk(KERN_WARNING "%s: transmit timeout\n", dev->name); |
711 | /* | 852 | |
712 | * FIXME: waking up random queue is not the best thing to | 853 | atomic_inc(&priv->reset_pending); |
713 | * do... on the other hand why we got here at all? | 854 | barrier(); |
714 | */ | 855 | cpmac_clear_tx(dev); |
715 | #ifdef CONFIG_NETDEVICES_MULTIQUEUE | 856 | barrier(); |
857 | atomic_dec(&priv->reset_pending); | ||
858 | |||
859 | netif_wake_queue(priv->dev); | ||
716 | for (i = 0; i < CPMAC_QUEUES; i++) | 860 | for (i = 0; i < CPMAC_QUEUES; i++) |
717 | if (priv->desc_ring[i].skb) { | 861 | netif_wake_subqueue(dev, i); |
718 | priv->desc_ring[i].dataflags = 0; | ||
719 | dev_kfree_skb_any(priv->desc_ring[i].skb); | ||
720 | netif_wake_subqueue(dev, i); | ||
721 | break; | ||
722 | } | ||
723 | #else | ||
724 | priv->desc_ring[0].dataflags = 0; | ||
725 | if (priv->desc_ring[0].skb) | ||
726 | dev_kfree_skb_any(priv->desc_ring[0].skb); | ||
727 | netif_wake_queue(dev); | ||
728 | #endif | ||
729 | } | 862 | } |
730 | 863 | ||
731 | static int cpmac_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | 864 | static int cpmac_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) |
@@ -901,9 +1034,12 @@ static int cpmac_open(struct net_device *dev) | |||
901 | desc->buflen = CPMAC_SKB_SIZE; | 1034 | desc->buflen = CPMAC_SKB_SIZE; |
902 | desc->dataflags = CPMAC_OWN; | 1035 | desc->dataflags = CPMAC_OWN; |
903 | desc->next = &priv->rx_head[(i + 1) % priv->ring_size]; | 1036 | desc->next = &priv->rx_head[(i + 1) % priv->ring_size]; |
1037 | desc->next->prev = desc; | ||
904 | desc->hw_next = (u32)desc->next->mapping; | 1038 | desc->hw_next = (u32)desc->next->mapping; |
905 | } | 1039 | } |
906 | 1040 | ||
1041 | priv->rx_head->prev->hw_next = (u32)0; | ||
1042 | |||
907 | if ((res = request_irq(dev->irq, cpmac_irq, IRQF_SHARED, | 1043 | if ((res = request_irq(dev->irq, cpmac_irq, IRQF_SHARED, |
908 | dev->name, dev))) { | 1044 | dev->name, dev))) { |
909 | if (netif_msg_drv(priv)) | 1045 | if (netif_msg_drv(priv)) |
@@ -912,6 +1048,7 @@ static int cpmac_open(struct net_device *dev) | |||
912 | goto fail_irq; | 1048 | goto fail_irq; |
913 | } | 1049 | } |
914 | 1050 | ||
1051 | atomic_set(&priv->reset_pending, 0); | ||
915 | INIT_WORK(&priv->reset_work, cpmac_hw_error); | 1052 | INIT_WORK(&priv->reset_work, cpmac_hw_error); |
916 | cpmac_hw_start(dev); | 1053 | cpmac_hw_start(dev); |
917 | 1054 | ||
@@ -1007,21 +1144,10 @@ static int __devinit cpmac_probe(struct platform_device *pdev) | |||
1007 | 1144 | ||
1008 | if (phy_id == PHY_MAX_ADDR) { | 1145 | if (phy_id == PHY_MAX_ADDR) { |
1009 | if (external_switch || dumb_switch) { | 1146 | if (external_switch || dumb_switch) { |
1010 | struct fixed_phy_status status = {}; | 1147 | mdio_bus_id = 0; /* fixed phys bus */ |
1011 | 1148 | phy_id = pdev->id; | |
1012 | /* | ||
1013 | * FIXME: this should be in the platform code! | ||
1014 | * Since there is not platform code at all (that is, | ||
1015 | * no mainline users of that driver), place it here | ||
1016 | * for now. | ||
1017 | */ | ||
1018 | phy_id = 0; | ||
1019 | status.link = 1; | ||
1020 | status.duplex = 1; | ||
1021 | status.speed = 100; | ||
1022 | fixed_phy_add(PHY_POLL, phy_id, &status); | ||
1023 | } else { | 1149 | } else { |
1024 | printk(KERN_ERR "cpmac: no PHY present\n"); | 1150 | dev_err(&pdev->dev, "no PHY present\n"); |
1025 | return -ENODEV; | 1151 | return -ENODEV; |
1026 | } | 1152 | } |
1027 | } | 1153 | } |
@@ -1064,10 +1190,8 @@ static int __devinit cpmac_probe(struct platform_device *pdev) | |||
1064 | priv->msg_enable = netif_msg_init(debug_level, 0xff); | 1190 | priv->msg_enable = netif_msg_init(debug_level, 0xff); |
1065 | memcpy(dev->dev_addr, pdata->dev_addr, sizeof(dev->dev_addr)); | 1191 | memcpy(dev->dev_addr, pdata->dev_addr, sizeof(dev->dev_addr)); |
1066 | 1192 | ||
1067 | snprintf(priv->phy_name, BUS_ID_SIZE, PHY_ID_FMT, mdio_bus_id, phy_id); | 1193 | priv->phy = phy_connect(dev, cpmac_mii.phy_map[phy_id]->dev.bus_id, |
1068 | 1194 | &cpmac_adjust_link, 0, PHY_INTERFACE_MODE_MII); | |
1069 | priv->phy = phy_connect(dev, priv->phy_name, &cpmac_adjust_link, 0, | ||
1070 | PHY_INTERFACE_MODE_MII); | ||
1071 | if (IS_ERR(priv->phy)) { | 1195 | if (IS_ERR(priv->phy)) { |
1072 | if (netif_msg_drv(priv)) | 1196 | if (netif_msg_drv(priv)) |
1073 | printk(KERN_ERR "%s: Could not attach to PHY\n", | 1197 | printk(KERN_ERR "%s: Could not attach to PHY\n", |
diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c index 348371fda597..fba87abe78ee 100644 --- a/drivers/net/cs89x0.c +++ b/drivers/net/cs89x0.c | |||
@@ -1394,7 +1394,11 @@ net_open(struct net_device *dev) | |||
1394 | #endif | 1394 | #endif |
1395 | if (!result) { | 1395 | if (!result) { |
1396 | printk(KERN_ERR "%s: EEPROM is configured for unavailable media\n", dev->name); | 1396 | printk(KERN_ERR "%s: EEPROM is configured for unavailable media\n", dev->name); |
1397 | release_irq: | 1397 | release_dma: |
1398 | #if ALLOW_DMA | ||
1399 | free_dma(dev->dma); | ||
1400 | #endif | ||
1401 | release_irq: | ||
1398 | #if ALLOW_DMA | 1402 | #if ALLOW_DMA |
1399 | release_dma_buff(lp); | 1403 | release_dma_buff(lp); |
1400 | #endif | 1404 | #endif |
@@ -1442,12 +1446,12 @@ net_open(struct net_device *dev) | |||
1442 | if ((result = detect_bnc(dev)) != DETECTED_NONE) | 1446 | if ((result = detect_bnc(dev)) != DETECTED_NONE) |
1443 | break; | 1447 | break; |
1444 | printk(KERN_ERR "%s: no media detected\n", dev->name); | 1448 | printk(KERN_ERR "%s: no media detected\n", dev->name); |
1445 | goto release_irq; | 1449 | goto release_dma; |
1446 | } | 1450 | } |
1447 | switch(result) { | 1451 | switch(result) { |
1448 | case DETECTED_NONE: | 1452 | case DETECTED_NONE: |
1449 | printk(KERN_ERR "%s: no network cable attached to configured media\n", dev->name); | 1453 | printk(KERN_ERR "%s: no network cable attached to configured media\n", dev->name); |
1450 | goto release_irq; | 1454 | goto release_dma; |
1451 | case DETECTED_RJ45H: | 1455 | case DETECTED_RJ45H: |
1452 | printk(KERN_INFO "%s: using half-duplex 10Base-T (RJ-45)\n", dev->name); | 1456 | printk(KERN_INFO "%s: using half-duplex 10Base-T (RJ-45)\n", dev->name); |
1453 | break; | 1457 | break; |
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c index d45bcd2660af..864295e081b6 100644 --- a/drivers/net/dm9000.c +++ b/drivers/net/dm9000.c | |||
@@ -903,7 +903,7 @@ dm9000_stop(struct net_device *ndev) | |||
903 | if (netif_msg_ifdown(db)) | 903 | if (netif_msg_ifdown(db)) |
904 | dev_dbg(db->dev, "shutting down %s\n", ndev->name); | 904 | dev_dbg(db->dev, "shutting down %s\n", ndev->name); |
905 | 905 | ||
906 | cancel_delayed_work(&db->phy_poll); | 906 | cancel_delayed_work_sync(&db->phy_poll); |
907 | 907 | ||
908 | netif_stop_queue(ndev); | 908 | netif_stop_queue(ndev); |
909 | netif_carrier_off(ndev); | 909 | netif_carrier_off(ndev); |
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 8cbb40f3a506..cab1835173cd 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c | |||
@@ -4201,8 +4201,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev, | |||
4201 | struct e1000_adapter *adapter; | 4201 | struct e1000_adapter *adapter; |
4202 | struct e1000_hw *hw; | 4202 | struct e1000_hw *hw; |
4203 | const struct e1000_info *ei = e1000_info_tbl[ent->driver_data]; | 4203 | const struct e1000_info *ei = e1000_info_tbl[ent->driver_data]; |
4204 | unsigned long mmio_start, mmio_len; | 4204 | resource_size_t mmio_start, mmio_len; |
4205 | unsigned long flash_start, flash_len; | 4205 | resource_size_t flash_start, flash_len; |
4206 | 4206 | ||
4207 | static int cards_found; | 4207 | static int cards_found; |
4208 | int i, err, pci_using_dac; | 4208 | int i, err, pci_using_dac; |
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index d1b6d4e7495d..075fd547421e 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c | |||
@@ -1766,16 +1766,20 @@ static int ehea_set_mac_addr(struct net_device *dev, void *sa) | |||
1766 | mutex_lock(&ehea_bcmc_regs.lock); | 1766 | mutex_lock(&ehea_bcmc_regs.lock); |
1767 | 1767 | ||
1768 | /* Deregister old MAC in pHYP */ | 1768 | /* Deregister old MAC in pHYP */ |
1769 | ret = ehea_broadcast_reg_helper(port, H_DEREG_BCMC); | 1769 | if (port->state == EHEA_PORT_UP) { |
1770 | if (ret) | 1770 | ret = ehea_broadcast_reg_helper(port, H_DEREG_BCMC); |
1771 | goto out_upregs; | 1771 | if (ret) |
1772 | goto out_upregs; | ||
1773 | } | ||
1772 | 1774 | ||
1773 | port->mac_addr = cb0->port_mac_addr << 16; | 1775 | port->mac_addr = cb0->port_mac_addr << 16; |
1774 | 1776 | ||
1775 | /* Register new MAC in pHYP */ | 1777 | /* Register new MAC in pHYP */ |
1776 | ret = ehea_broadcast_reg_helper(port, H_REG_BCMC); | 1778 | if (port->state == EHEA_PORT_UP) { |
1777 | if (ret) | 1779 | ret = ehea_broadcast_reg_helper(port, H_REG_BCMC); |
1778 | goto out_upregs; | 1780 | if (ret) |
1781 | goto out_upregs; | ||
1782 | } | ||
1779 | 1783 | ||
1780 | ret = 0; | 1784 | ret = 0; |
1781 | 1785 | ||
@@ -2213,8 +2217,6 @@ static void ehea_vlan_rx_register(struct net_device *dev, | |||
2213 | goto out; | 2217 | goto out; |
2214 | } | 2218 | } |
2215 | 2219 | ||
2216 | memset(cb1->vlan_filter, 0, sizeof(cb1->vlan_filter)); | ||
2217 | |||
2218 | hret = ehea_h_modify_ehea_port(adapter->handle, port->logical_port_id, | 2220 | hret = ehea_h_modify_ehea_port(adapter->handle, port->logical_port_id, |
2219 | H_PORT_CB1, H_PORT_CB1_ALL, cb1); | 2221 | H_PORT_CB1, H_PORT_CB1_ALL, cb1); |
2220 | if (hret != H_SUCCESS) | 2222 | if (hret != H_SUCCESS) |
@@ -2603,7 +2605,8 @@ static int ehea_stop(struct net_device *dev) | |||
2603 | if (netif_msg_ifdown(port)) | 2605 | if (netif_msg_ifdown(port)) |
2604 | ehea_info("disabling port %s", dev->name); | 2606 | ehea_info("disabling port %s", dev->name); |
2605 | 2607 | ||
2606 | flush_scheduled_work(); | 2608 | cancel_work_sync(&port->reset_task); |
2609 | |||
2607 | mutex_lock(&port->port_lock); | 2610 | mutex_lock(&port->port_lock); |
2608 | netif_stop_queue(dev); | 2611 | netif_stop_queue(dev); |
2609 | port_napi_disable(port); | 2612 | port_napi_disable(port); |
@@ -3178,11 +3181,12 @@ out_err: | |||
3178 | 3181 | ||
3179 | static void ehea_shutdown_single_port(struct ehea_port *port) | 3182 | static void ehea_shutdown_single_port(struct ehea_port *port) |
3180 | { | 3183 | { |
3184 | struct ehea_adapter *adapter = port->adapter; | ||
3181 | unregister_netdev(port->netdev); | 3185 | unregister_netdev(port->netdev); |
3182 | ehea_unregister_port(port); | 3186 | ehea_unregister_port(port); |
3183 | kfree(port->mc_list); | 3187 | kfree(port->mc_list); |
3184 | free_netdev(port->netdev); | 3188 | free_netdev(port->netdev); |
3185 | port->adapter->active_ports--; | 3189 | adapter->active_ports--; |
3186 | } | 3190 | } |
3187 | 3191 | ||
3188 | static int ehea_setup_ports(struct ehea_adapter *adapter) | 3192 | static int ehea_setup_ports(struct ehea_adapter *adapter) |
diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c index 5f9c42e7a7f1..329edd9c08fc 100644 --- a/drivers/net/fec_mpc52xx.c +++ b/drivers/net/fec_mpc52xx.c | |||
@@ -78,7 +78,7 @@ module_param_array_named(mac, mpc52xx_fec_mac_addr, byte, NULL, 0); | |||
78 | MODULE_PARM_DESC(mac, "six hex digits, ie. 0x1,0x2,0xc0,0x01,0xba,0xbe"); | 78 | MODULE_PARM_DESC(mac, "six hex digits, ie. 0x1,0x2,0xc0,0x01,0xba,0xbe"); |
79 | 79 | ||
80 | #define MPC52xx_MESSAGES_DEFAULT ( NETIF_MSG_DRV | NETIF_MSG_PROBE | \ | 80 | #define MPC52xx_MESSAGES_DEFAULT ( NETIF_MSG_DRV | NETIF_MSG_PROBE | \ |
81 | NETIF_MSG_LINK | NETIF_MSG_IFDOWN | NETIF_MSG_IFDOWN ) | 81 | NETIF_MSG_LINK | NETIF_MSG_IFDOWN | NETIF_MSG_IFUP) |
82 | static int debug = -1; /* the above default */ | 82 | static int debug = -1; /* the above default */ |
83 | module_param(debug, int, 0); | 83 | module_param(debug, int, 0); |
84 | MODULE_PARM_DESC(debug, "debugging messages level"); | 84 | MODULE_PARM_DESC(debug, "debugging messages level"); |
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 35f66d4a4595..2cb244763292 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c | |||
@@ -3273,6 +3273,20 @@ static void nv_link_irq(struct net_device *dev) | |||
3273 | dprintk(KERN_DEBUG "%s: link change notification done.\n", dev->name); | 3273 | dprintk(KERN_DEBUG "%s: link change notification done.\n", dev->name); |
3274 | } | 3274 | } |
3275 | 3275 | ||
3276 | static void nv_msi_workaround(struct fe_priv *np) | ||
3277 | { | ||
3278 | |||
3279 | /* Need to toggle the msi irq mask within the ethernet device, | ||
3280 | * otherwise, future interrupts will not be detected. | ||
3281 | */ | ||
3282 | if (np->msi_flags & NV_MSI_ENABLED) { | ||
3283 | u8 __iomem *base = np->base; | ||
3284 | |||
3285 | writel(0, base + NvRegMSIIrqMask); | ||
3286 | writel(NVREG_MSI_VECTOR_0_ENABLED, base + NvRegMSIIrqMask); | ||
3287 | } | ||
3288 | } | ||
3289 | |||
3276 | static irqreturn_t nv_nic_irq(int foo, void *data) | 3290 | static irqreturn_t nv_nic_irq(int foo, void *data) |
3277 | { | 3291 | { |
3278 | struct net_device *dev = (struct net_device *) data; | 3292 | struct net_device *dev = (struct net_device *) data; |
@@ -3295,6 +3309,8 @@ static irqreturn_t nv_nic_irq(int foo, void *data) | |||
3295 | if (!(events & np->irqmask)) | 3309 | if (!(events & np->irqmask)) |
3296 | break; | 3310 | break; |
3297 | 3311 | ||
3312 | nv_msi_workaround(np); | ||
3313 | |||
3298 | spin_lock(&np->lock); | 3314 | spin_lock(&np->lock); |
3299 | nv_tx_done(dev); | 3315 | nv_tx_done(dev); |
3300 | spin_unlock(&np->lock); | 3316 | spin_unlock(&np->lock); |
@@ -3410,6 +3426,8 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data) | |||
3410 | if (!(events & np->irqmask)) | 3426 | if (!(events & np->irqmask)) |
3411 | break; | 3427 | break; |
3412 | 3428 | ||
3429 | nv_msi_workaround(np); | ||
3430 | |||
3413 | spin_lock(&np->lock); | 3431 | spin_lock(&np->lock); |
3414 | nv_tx_done_optimized(dev, TX_WORK_PER_LOOP); | 3432 | nv_tx_done_optimized(dev, TX_WORK_PER_LOOP); |
3415 | spin_unlock(&np->lock); | 3433 | spin_unlock(&np->lock); |
@@ -3750,6 +3768,8 @@ static irqreturn_t nv_nic_irq_test(int foo, void *data) | |||
3750 | if (!(events & NVREG_IRQ_TIMER)) | 3768 | if (!(events & NVREG_IRQ_TIMER)) |
3751 | return IRQ_RETVAL(0); | 3769 | return IRQ_RETVAL(0); |
3752 | 3770 | ||
3771 | nv_msi_workaround(np); | ||
3772 | |||
3753 | spin_lock(&np->lock); | 3773 | spin_lock(&np->lock); |
3754 | np->intr_test = 1; | 3774 | np->intr_test = 1; |
3755 | spin_unlock(&np->lock); | 3775 | spin_unlock(&np->lock); |
@@ -5823,6 +5843,7 @@ static int nv_resume(struct pci_dev *pdev) | |||
5823 | writel(txreg, base + NvRegTransmitPoll); | 5843 | writel(txreg, base + NvRegTransmitPoll); |
5824 | 5844 | ||
5825 | rc = nv_open(dev); | 5845 | rc = nv_open(dev); |
5846 | nv_set_multicast(dev); | ||
5826 | out: | 5847 | out: |
5827 | return rc; | 5848 | return rc; |
5828 | } | 5849 | } |
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c index 67b4b0728fce..a5baaf59ff66 100644 --- a/drivers/net/fs_enet/fs_enet-main.c +++ b/drivers/net/fs_enet/fs_enet-main.c | |||
@@ -1093,7 +1093,7 @@ err: | |||
1093 | if (registered) | 1093 | if (registered) |
1094 | unregister_netdev(ndev); | 1094 | unregister_netdev(ndev); |
1095 | 1095 | ||
1096 | if (fep != NULL) { | 1096 | if (fep && fep->ops) { |
1097 | (*fep->ops->free_bd)(ndev); | 1097 | (*fep->ops->free_bd)(ndev); |
1098 | (*fep->ops->cleanup_data)(ndev); | 1098 | (*fep->ops->cleanup_data)(ndev); |
1099 | } | 1099 | } |
diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c index dde9c7e6408a..00bc7fbb6b37 100644 --- a/drivers/net/hamradio/baycom_epp.c +++ b/drivers/net/hamradio/baycom_epp.c | |||
@@ -959,7 +959,7 @@ static int epp_close(struct net_device *dev) | |||
959 | unsigned char tmp[1]; | 959 | unsigned char tmp[1]; |
960 | 960 | ||
961 | bc->work_running = 0; | 961 | bc->work_running = 0; |
962 | flush_scheduled_work(); | 962 | cancel_delayed_work_sync(&bc->run_work); |
963 | bc->stat = EPP_DCDBIT; | 963 | bc->stat = EPP_DCDBIT; |
964 | tmp[0] = 0; | 964 | tmp[0] = 0; |
965 | pp->ops->epp_write_addr(pp, tmp, 1, 0); | 965 | pp->ops->epp_write_addr(pp, tmp, 1, 0); |
diff --git a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c index f90515935833..45ae9d1191d7 100644 --- a/drivers/net/hamradio/scc.c +++ b/drivers/net/hamradio/scc.c | |||
@@ -1340,9 +1340,10 @@ static unsigned int scc_set_param(struct scc_channel *scc, unsigned int cmd, uns | |||
1340 | case PARAM_RTS: | 1340 | case PARAM_RTS: |
1341 | if ( !(scc->wreg[R5] & RTS) ) | 1341 | if ( !(scc->wreg[R5] & RTS) ) |
1342 | { | 1342 | { |
1343 | if (arg != TX_OFF) | 1343 | if (arg != TX_OFF) { |
1344 | scc_key_trx(scc, TX_ON); | 1344 | scc_key_trx(scc, TX_ON); |
1345 | scc_start_tx_timer(scc, t_txdelay, scc->kiss.txdelay); | 1345 | scc_start_tx_timer(scc, t_txdelay, scc->kiss.txdelay); |
1346 | } | ||
1346 | } else { | 1347 | } else { |
1347 | if (arg == TX_OFF) | 1348 | if (arg == TX_OFF) |
1348 | { | 1349 | { |
diff --git a/drivers/net/ipg.c b/drivers/net/ipg.c index 9b358f61ed7f..679a0826780e 100644 --- a/drivers/net/ipg.c +++ b/drivers/net/ipg.c | |||
@@ -577,12 +577,12 @@ static void ipg_nic_set_multicast_list(struct net_device *dev) | |||
577 | /* NIC to be configured in promiscuous mode. */ | 577 | /* NIC to be configured in promiscuous mode. */ |
578 | receivemode = IPG_RM_RECEIVEALLFRAMES; | 578 | receivemode = IPG_RM_RECEIVEALLFRAMES; |
579 | } else if ((dev->flags & IFF_ALLMULTI) || | 579 | } else if ((dev->flags & IFF_ALLMULTI) || |
580 | (dev->flags & IFF_MULTICAST & | 580 | ((dev->flags & IFF_MULTICAST) && |
581 | (dev->mc_count > IPG_MULTICAST_HASHTABLE_SIZE))) { | 581 | (dev->mc_count > IPG_MULTICAST_HASHTABLE_SIZE))) { |
582 | /* NIC to be configured to receive all multicast | 582 | /* NIC to be configured to receive all multicast |
583 | * frames. */ | 583 | * frames. */ |
584 | receivemode |= IPG_RM_RECEIVEMULTICAST; | 584 | receivemode |= IPG_RM_RECEIVEMULTICAST; |
585 | } else if (dev->flags & IFF_MULTICAST & (dev->mc_count > 0)) { | 585 | } else if ((dev->flags & IFF_MULTICAST) && (dev->mc_count > 0)) { |
586 | /* NIC to be configured to receive selected | 586 | /* NIC to be configured to receive selected |
587 | * multicast addresses. */ | 587 | * multicast addresses. */ |
588 | receivemode |= IPG_RM_RECEIVEMULTICASTHASH; | 588 | receivemode |= IPG_RM_RECEIVEMULTICASTHASH; |
diff --git a/drivers/net/irda/Kconfig b/drivers/net/irda/Kconfig index ce816ba9c40d..e6317557a531 100644 --- a/drivers/net/irda/Kconfig +++ b/drivers/net/irda/Kconfig | |||
@@ -329,6 +329,7 @@ config PXA_FICP | |||
329 | config MCS_FIR | 329 | config MCS_FIR |
330 | tristate "MosChip MCS7780 IrDA-USB dongle" | 330 | tristate "MosChip MCS7780 IrDA-USB dongle" |
331 | depends on IRDA && USB && EXPERIMENTAL | 331 | depends on IRDA && USB && EXPERIMENTAL |
332 | select CRC32 | ||
332 | help | 333 | help |
333 | Say Y or M here if you want to build support for the MosChip | 334 | Say Y or M here if you want to build support for the MosChip |
334 | MCS7780 IrDA-USB bridge device driver. | 335 | MCS7780 IrDA-USB bridge device driver. |
diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c index 9081234ab458..6f50ed7b183f 100644 --- a/drivers/net/irda/irda-usb.c +++ b/drivers/net/irda/irda-usb.c | |||
@@ -1120,7 +1120,7 @@ static int stir421x_patch_device(struct irda_usb_cb *self) | |||
1120 | } | 1120 | } |
1121 | } | 1121 | } |
1122 | 1122 | ||
1123 | if (self->usbdev->descriptor.bcdDevice == fw_version) { | 1123 | if (self->usbdev->descriptor.bcdDevice == cpu_to_le16(fw_version)) { |
1124 | /* | 1124 | /* |
1125 | * If we're here, we've found a correct patch | 1125 | * If we're here, we've found a correct patch |
1126 | * The actual image starts after the "STMP" keyword | 1126 | * The actual image starts after the "STMP" keyword |
diff --git a/drivers/net/irda/irda-usb.h b/drivers/net/irda/irda-usb.h index e846c38224a3..a0ca9c1fe196 100644 --- a/drivers/net/irda/irda-usb.h +++ b/drivers/net/irda/irda-usb.h | |||
@@ -117,11 +117,11 @@ | |||
117 | struct irda_class_desc { | 117 | struct irda_class_desc { |
118 | __u8 bLength; | 118 | __u8 bLength; |
119 | __u8 bDescriptorType; | 119 | __u8 bDescriptorType; |
120 | __u16 bcdSpecRevision; | 120 | __le16 bcdSpecRevision; |
121 | __u8 bmDataSize; | 121 | __u8 bmDataSize; |
122 | __u8 bmWindowSize; | 122 | __u8 bmWindowSize; |
123 | __u8 bmMinTurnaroundTime; | 123 | __u8 bmMinTurnaroundTime; |
124 | __u16 wBaudRate; | 124 | __le16 wBaudRate; |
125 | __u8 bmAdditionalBOFs; | 125 | __u8 bmAdditionalBOFs; |
126 | __u8 bIrdaRateSniff; | 126 | __u8 bIrdaRateSniff; |
127 | __u8 bMaxUnicastList; | 127 | __u8 bMaxUnicastList; |
diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c index 6321b059ce13..2f38e847e2cd 100644 --- a/drivers/net/ixgbe/ixgbe_82598.c +++ b/drivers/net/ixgbe/ixgbe_82598.c | |||
@@ -58,8 +58,8 @@ static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw); | |||
58 | 58 | ||
59 | static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw) | 59 | static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw) |
60 | { | 60 | { |
61 | hw->mac.num_rx_queues = IXGBE_82598_MAX_TX_QUEUES; | 61 | hw->mac.num_rx_queues = IXGBE_82598_MAX_RX_QUEUES; |
62 | hw->mac.num_tx_queues = IXGBE_82598_MAX_RX_QUEUES; | 62 | hw->mac.num_tx_queues = IXGBE_82598_MAX_TX_QUEUES; |
63 | hw->mac.num_rx_addrs = IXGBE_82598_RAR_ENTRIES; | 63 | hw->mac.num_rx_addrs = IXGBE_82598_RAR_ENTRIES; |
64 | 64 | ||
65 | /* PHY ops are filled in by default properly for Fiber only */ | 65 | /* PHY ops are filled in by default properly for Fiber only */ |
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index c91b12ea26ad..e0d76c75aea0 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c | |||
@@ -75,7 +75,7 @@ | |||
75 | #include "myri10ge_mcp.h" | 75 | #include "myri10ge_mcp.h" |
76 | #include "myri10ge_mcp_gen_header.h" | 76 | #include "myri10ge_mcp_gen_header.h" |
77 | 77 | ||
78 | #define MYRI10GE_VERSION_STR "1.3.2-1.287" | 78 | #define MYRI10GE_VERSION_STR "1.3.99-1.347" |
79 | 79 | ||
80 | MODULE_DESCRIPTION("Myricom 10G driver (10GbE)"); | 80 | MODULE_DESCRIPTION("Myricom 10G driver (10GbE)"); |
81 | MODULE_AUTHOR("Maintainer: help@myri.com"); | 81 | MODULE_AUTHOR("Maintainer: help@myri.com"); |
@@ -631,7 +631,7 @@ static int myri10ge_adopt_running_firmware(struct myri10ge_priv *mgp) | |||
631 | return status; | 631 | return status; |
632 | } | 632 | } |
633 | 633 | ||
634 | int myri10ge_get_firmware_capabilities(struct myri10ge_priv *mgp) | 634 | static int myri10ge_get_firmware_capabilities(struct myri10ge_priv *mgp) |
635 | { | 635 | { |
636 | struct myri10ge_cmd cmd; | 636 | struct myri10ge_cmd cmd; |
637 | int status; | 637 | int status; |
diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c index 8f328a03847b..a550c9bd126f 100644 --- a/drivers/net/pcmcia/fmvj18x_cs.c +++ b/drivers/net/pcmcia/fmvj18x_cs.c | |||
@@ -391,7 +391,9 @@ static int fmvj18x_config(struct pcmcia_device *link) | |||
391 | cardtype = CONTEC; | 391 | cardtype = CONTEC; |
392 | break; | 392 | break; |
393 | case MANFID_FUJITSU: | 393 | case MANFID_FUJITSU: |
394 | if (link->card_id == PRODID_FUJITSU_MBH10302) | 394 | if (link->conf.ConfigBase == 0x0fe0) |
395 | cardtype = MBH10302; | ||
396 | else if (link->card_id == PRODID_FUJITSU_MBH10302) | ||
395 | /* RATOC REX-5588/9822/4886's PRODID are 0004(=MBH10302), | 397 | /* RATOC REX-5588/9822/4886's PRODID are 0004(=MBH10302), |
396 | but these are MBH10304 based card. */ | 398 | but these are MBH10304 based card. */ |
397 | cardtype = MBH10304; | 399 | cardtype = MBH10304; |
diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c index d041f831a18d..f6c4698ce738 100644 --- a/drivers/net/pcmcia/xirc2ps_cs.c +++ b/drivers/net/pcmcia/xirc2ps_cs.c | |||
@@ -1461,22 +1461,25 @@ static void | |||
1461 | set_multicast_list(struct net_device *dev) | 1461 | set_multicast_list(struct net_device *dev) |
1462 | { | 1462 | { |
1463 | unsigned int ioaddr = dev->base_addr; | 1463 | unsigned int ioaddr = dev->base_addr; |
1464 | unsigned value; | ||
1464 | 1465 | ||
1465 | SelectPage(0x42); | 1466 | SelectPage(0x42); |
1467 | value = GetByte(XIRCREG42_SWC1) & 0xC0; | ||
1468 | |||
1466 | if (dev->flags & IFF_PROMISC) { /* snoop */ | 1469 | if (dev->flags & IFF_PROMISC) { /* snoop */ |
1467 | PutByte(XIRCREG42_SWC1, 0x06); /* set MPE and PME */ | 1470 | PutByte(XIRCREG42_SWC1, value | 0x06); /* set MPE and PME */ |
1468 | } else if (dev->mc_count > 9 || (dev->flags & IFF_ALLMULTI)) { | 1471 | } else if (dev->mc_count > 9 || (dev->flags & IFF_ALLMULTI)) { |
1469 | PutByte(XIRCREG42_SWC1, 0x02); /* set MPE */ | 1472 | PutByte(XIRCREG42_SWC1, value | 0x02); /* set MPE */ |
1470 | } else if (dev->mc_count) { | 1473 | } else if (dev->mc_count) { |
1471 | /* the chip can filter 9 addresses perfectly */ | 1474 | /* the chip can filter 9 addresses perfectly */ |
1472 | PutByte(XIRCREG42_SWC1, 0x01); | 1475 | PutByte(XIRCREG42_SWC1, value | 0x01); |
1473 | SelectPage(0x40); | 1476 | SelectPage(0x40); |
1474 | PutByte(XIRCREG40_CMD0, Offline); | 1477 | PutByte(XIRCREG40_CMD0, Offline); |
1475 | set_addresses(dev); | 1478 | set_addresses(dev); |
1476 | SelectPage(0x40); | 1479 | SelectPage(0x40); |
1477 | PutByte(XIRCREG40_CMD0, EnableRecv | Online); | 1480 | PutByte(XIRCREG40_CMD0, EnableRecv | Online); |
1478 | } else { /* standard usage */ | 1481 | } else { /* standard usage */ |
1479 | PutByte(XIRCREG42_SWC1, 0x00); | 1482 | PutByte(XIRCREG42_SWC1, value | 0x00); |
1480 | } | 1483 | } |
1481 | SelectPage(0); | 1484 | SelectPage(0); |
1482 | } | 1485 | } |
@@ -1722,6 +1725,7 @@ do_reset(struct net_device *dev, int full) | |||
1722 | 1725 | ||
1723 | /* enable receiver and put the mac online */ | 1726 | /* enable receiver and put the mac online */ |
1724 | if (full) { | 1727 | if (full) { |
1728 | set_multicast_list(dev); | ||
1725 | SelectPage(0x40); | 1729 | SelectPage(0x40); |
1726 | PutByte(XIRCREG40_CMD0, EnableRecv | Online); | 1730 | PutByte(XIRCREG40_CMD0, EnableRecv | Online); |
1727 | } | 1731 | } |
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c index a1c454dbc164..1c89b97f4e09 100644 --- a/drivers/net/pcnet32.c +++ b/drivers/net/pcnet32.c | |||
@@ -325,7 +325,7 @@ static int pcnet32_get_regs_len(struct net_device *dev); | |||
325 | static void pcnet32_get_regs(struct net_device *dev, struct ethtool_regs *regs, | 325 | static void pcnet32_get_regs(struct net_device *dev, struct ethtool_regs *regs, |
326 | void *ptr); | 326 | void *ptr); |
327 | static void pcnet32_purge_tx_ring(struct net_device *dev); | 327 | static void pcnet32_purge_tx_ring(struct net_device *dev); |
328 | static int pcnet32_alloc_ring(struct net_device *dev, char *name); | 328 | static int pcnet32_alloc_ring(struct net_device *dev, const char *name); |
329 | static void pcnet32_free_ring(struct net_device *dev); | 329 | static void pcnet32_free_ring(struct net_device *dev); |
330 | static void pcnet32_check_media(struct net_device *dev, int verbose); | 330 | static void pcnet32_check_media(struct net_device *dev, int verbose); |
331 | 331 | ||
@@ -1983,7 +1983,7 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev) | |||
1983 | } | 1983 | } |
1984 | 1984 | ||
1985 | /* if any allocation fails, caller must also call pcnet32_free_ring */ | 1985 | /* if any allocation fails, caller must also call pcnet32_free_ring */ |
1986 | static int pcnet32_alloc_ring(struct net_device *dev, char *name) | 1986 | static int pcnet32_alloc_ring(struct net_device *dev, const char *name) |
1987 | { | 1987 | { |
1988 | struct pcnet32_private *lp = netdev_priv(dev); | 1988 | struct pcnet32_private *lp = netdev_priv(dev); |
1989 | 1989 | ||
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index 6bf9e76b0a00..6eb2d31d1e34 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig | |||
@@ -5,7 +5,7 @@ | |||
5 | menuconfig PHYLIB | 5 | menuconfig PHYLIB |
6 | tristate "PHY Device support and infrastructure" | 6 | tristate "PHY Device support and infrastructure" |
7 | depends on !S390 | 7 | depends on !S390 |
8 | depends on NET_ETHERNET && (BROKEN || !S390) | 8 | depends on NET_ETHERNET |
9 | help | 9 | help |
10 | Ethernet controllers are usually attached to PHY | 10 | Ethernet controllers are usually attached to PHY |
11 | devices. This option provides infrastructure for | 11 | devices. This option provides infrastructure for |
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index ac3c01d28fdf..16a0e7de5888 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c | |||
@@ -207,6 +207,7 @@ int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id) | |||
207 | 207 | ||
208 | return 0; | 208 | return 0; |
209 | } | 209 | } |
210 | EXPORT_SYMBOL(get_phy_id); | ||
210 | 211 | ||
211 | /** | 212 | /** |
212 | * get_phy_device - reads the specified PHY device and returns its @phy_device struct | 213 | * get_phy_device - reads the specified PHY device and returns its @phy_device struct |
diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c index 58a26a47af29..bafb69b6f7cb 100644 --- a/drivers/net/pppoe.c +++ b/drivers/net/pppoe.c | |||
@@ -341,12 +341,6 @@ static int pppoe_rcv_core(struct sock *sk, struct sk_buff *skb) | |||
341 | struct pppox_sock *relay_po; | 341 | struct pppox_sock *relay_po; |
342 | 342 | ||
343 | if (sk->sk_state & PPPOX_BOUND) { | 343 | if (sk->sk_state & PPPOX_BOUND) { |
344 | struct pppoe_hdr *ph = pppoe_hdr(skb); | ||
345 | int len = ntohs(ph->length); | ||
346 | skb_pull_rcsum(skb, sizeof(struct pppoe_hdr)); | ||
347 | if (pskb_trim_rcsum(skb, len)) | ||
348 | goto abort_kfree; | ||
349 | |||
350 | ppp_input(&po->chan, skb); | 344 | ppp_input(&po->chan, skb); |
351 | } else if (sk->sk_state & PPPOX_RELAY) { | 345 | } else if (sk->sk_state & PPPOX_RELAY) { |
352 | relay_po = get_item_by_addr(&po->pppoe_relay); | 346 | relay_po = get_item_by_addr(&po->pppoe_relay); |
@@ -357,7 +351,6 @@ static int pppoe_rcv_core(struct sock *sk, struct sk_buff *skb) | |||
357 | if ((sk_pppox(relay_po)->sk_state & PPPOX_CONNECTED) == 0) | 351 | if ((sk_pppox(relay_po)->sk_state & PPPOX_CONNECTED) == 0) |
358 | goto abort_put; | 352 | goto abort_put; |
359 | 353 | ||
360 | skb_pull(skb, sizeof(struct pppoe_hdr)); | ||
361 | if (!__pppoe_xmit(sk_pppox(relay_po), skb)) | 354 | if (!__pppoe_xmit(sk_pppox(relay_po), skb)) |
362 | goto abort_put; | 355 | goto abort_put; |
363 | } else { | 356 | } else { |
@@ -388,6 +381,7 @@ static int pppoe_rcv(struct sk_buff *skb, | |||
388 | { | 381 | { |
389 | struct pppoe_hdr *ph; | 382 | struct pppoe_hdr *ph; |
390 | struct pppox_sock *po; | 383 | struct pppox_sock *po; |
384 | int len; | ||
391 | 385 | ||
392 | if (!(skb = skb_share_check(skb, GFP_ATOMIC))) | 386 | if (!(skb = skb_share_check(skb, GFP_ATOMIC))) |
393 | goto out; | 387 | goto out; |
@@ -399,10 +393,21 @@ static int pppoe_rcv(struct sk_buff *skb, | |||
399 | goto drop; | 393 | goto drop; |
400 | 394 | ||
401 | ph = pppoe_hdr(skb); | 395 | ph = pppoe_hdr(skb); |
396 | len = ntohs(ph->length); | ||
397 | |||
398 | skb_pull_rcsum(skb, sizeof(*ph)); | ||
399 | if (skb->len < len) | ||
400 | goto drop; | ||
402 | 401 | ||
403 | po = get_item(ph->sid, eth_hdr(skb)->h_source, dev->ifindex); | 402 | po = get_item(ph->sid, eth_hdr(skb)->h_source, dev->ifindex); |
404 | if (po != NULL) | 403 | if (!po) |
405 | return sk_receive_skb(sk_pppox(po), skb, 0); | 404 | goto drop; |
405 | |||
406 | if (pskb_trim_rcsum(skb, len)) | ||
407 | goto drop; | ||
408 | |||
409 | return sk_receive_skb(sk_pppox(po), skb, 0); | ||
410 | |||
406 | drop: | 411 | drop: |
407 | kfree_skb(skb); | 412 | kfree_skb(skb); |
408 | out: | 413 | out: |
@@ -427,12 +432,12 @@ static int pppoe_disc_rcv(struct sk_buff *skb, | |||
427 | if (dev_net(dev) != &init_net) | 432 | if (dev_net(dev) != &init_net) |
428 | goto abort; | 433 | goto abort; |
429 | 434 | ||
430 | if (!pskb_may_pull(skb, sizeof(struct pppoe_hdr))) | ||
431 | goto abort; | ||
432 | |||
433 | if (!(skb = skb_share_check(skb, GFP_ATOMIC))) | 435 | if (!(skb = skb_share_check(skb, GFP_ATOMIC))) |
434 | goto out; | 436 | goto out; |
435 | 437 | ||
438 | if (!pskb_may_pull(skb, sizeof(struct pppoe_hdr))) | ||
439 | goto abort; | ||
440 | |||
436 | ph = pppoe_hdr(skb); | 441 | ph = pppoe_hdr(skb); |
437 | if (ph->code != PADT_CODE) | 442 | if (ph->code != PADT_CODE) |
438 | goto abort; | 443 | goto abort; |
@@ -937,12 +942,10 @@ static int pppoe_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
937 | m->msg_namelen = 0; | 942 | m->msg_namelen = 0; |
938 | 943 | ||
939 | if (skb) { | 944 | if (skb) { |
940 | struct pppoe_hdr *ph = pppoe_hdr(skb); | 945 | total_len = min(total_len, skb->len); |
941 | const int len = ntohs(ph->length); | 946 | error = skb_copy_datagram_iovec(skb, 0, m->msg_iov, total_len); |
942 | |||
943 | error = memcpy_toiovec(m->msg_iov, (unsigned char *) &ph->tag[0], len); | ||
944 | if (error == 0) | 947 | if (error == 0) |
945 | error = len; | 948 | error = total_len; |
946 | } | 949 | } |
947 | 950 | ||
948 | kfree_skb(skb); | 951 | kfree_skb(skb); |
diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c index 79359919335b..f9298827a76c 100644 --- a/drivers/net/pppol2tp.c +++ b/drivers/net/pppol2tp.c | |||
@@ -240,12 +240,15 @@ static inline struct pppol2tp_session *pppol2tp_sock_to_session(struct sock *sk) | |||
240 | if (sk == NULL) | 240 | if (sk == NULL) |
241 | return NULL; | 241 | return NULL; |
242 | 242 | ||
243 | sock_hold(sk); | ||
243 | session = (struct pppol2tp_session *)(sk->sk_user_data); | 244 | session = (struct pppol2tp_session *)(sk->sk_user_data); |
244 | if (session == NULL) | 245 | if (session == NULL) { |
245 | return NULL; | 246 | sock_put(sk); |
247 | goto out; | ||
248 | } | ||
246 | 249 | ||
247 | BUG_ON(session->magic != L2TP_SESSION_MAGIC); | 250 | BUG_ON(session->magic != L2TP_SESSION_MAGIC); |
248 | 251 | out: | |
249 | return session; | 252 | return session; |
250 | } | 253 | } |
251 | 254 | ||
@@ -256,12 +259,15 @@ static inline struct pppol2tp_tunnel *pppol2tp_sock_to_tunnel(struct sock *sk) | |||
256 | if (sk == NULL) | 259 | if (sk == NULL) |
257 | return NULL; | 260 | return NULL; |
258 | 261 | ||
262 | sock_hold(sk); | ||
259 | tunnel = (struct pppol2tp_tunnel *)(sk->sk_user_data); | 263 | tunnel = (struct pppol2tp_tunnel *)(sk->sk_user_data); |
260 | if (tunnel == NULL) | 264 | if (tunnel == NULL) { |
261 | return NULL; | 265 | sock_put(sk); |
266 | goto out; | ||
267 | } | ||
262 | 268 | ||
263 | BUG_ON(tunnel->magic != L2TP_TUNNEL_MAGIC); | 269 | BUG_ON(tunnel->magic != L2TP_TUNNEL_MAGIC); |
264 | 270 | out: | |
265 | return tunnel; | 271 | return tunnel; |
266 | } | 272 | } |
267 | 273 | ||
@@ -716,12 +722,14 @@ discard: | |||
716 | session->stats.rx_errors++; | 722 | session->stats.rx_errors++; |
717 | kfree_skb(skb); | 723 | kfree_skb(skb); |
718 | sock_put(session->sock); | 724 | sock_put(session->sock); |
725 | sock_put(sock); | ||
719 | 726 | ||
720 | return 0; | 727 | return 0; |
721 | 728 | ||
722 | error: | 729 | error: |
723 | /* Put UDP header back */ | 730 | /* Put UDP header back */ |
724 | __skb_push(skb, sizeof(struct udphdr)); | 731 | __skb_push(skb, sizeof(struct udphdr)); |
732 | sock_put(sock); | ||
725 | 733 | ||
726 | no_tunnel: | 734 | no_tunnel: |
727 | return 1; | 735 | return 1; |
@@ -745,10 +753,13 @@ static int pppol2tp_udp_encap_recv(struct sock *sk, struct sk_buff *skb) | |||
745 | "%s: received %d bytes\n", tunnel->name, skb->len); | 753 | "%s: received %d bytes\n", tunnel->name, skb->len); |
746 | 754 | ||
747 | if (pppol2tp_recv_core(sk, skb)) | 755 | if (pppol2tp_recv_core(sk, skb)) |
748 | goto pass_up; | 756 | goto pass_up_put; |
749 | 757 | ||
758 | sock_put(sk); | ||
750 | return 0; | 759 | return 0; |
751 | 760 | ||
761 | pass_up_put: | ||
762 | sock_put(sk); | ||
752 | pass_up: | 763 | pass_up: |
753 | return 1; | 764 | return 1; |
754 | } | 765 | } |
@@ -772,14 +783,18 @@ static int pppol2tp_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
772 | err = 0; | 783 | err = 0; |
773 | skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, | 784 | skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, |
774 | flags & MSG_DONTWAIT, &err); | 785 | flags & MSG_DONTWAIT, &err); |
775 | if (skb) { | 786 | if (!skb) |
776 | err = memcpy_toiovec(msg->msg_iov, (unsigned char *) skb->data, | 787 | goto end; |
777 | skb->len); | 788 | |
778 | if (err < 0) | 789 | if (len > skb->len) |
779 | goto do_skb_free; | 790 | len = skb->len; |
780 | err = skb->len; | 791 | else if (len < skb->len) |
781 | } | 792 | msg->msg_flags |= MSG_TRUNC; |
782 | do_skb_free: | 793 | |
794 | err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, len); | ||
795 | if (likely(err == 0)) | ||
796 | err = len; | ||
797 | |||
783 | kfree_skb(skb); | 798 | kfree_skb(skb); |
784 | end: | 799 | end: |
785 | return err; | 800 | return err; |
@@ -858,7 +873,7 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh | |||
858 | 873 | ||
859 | tunnel = pppol2tp_sock_to_tunnel(session->tunnel_sock); | 874 | tunnel = pppol2tp_sock_to_tunnel(session->tunnel_sock); |
860 | if (tunnel == NULL) | 875 | if (tunnel == NULL) |
861 | goto error; | 876 | goto error_put_sess; |
862 | 877 | ||
863 | /* What header length is configured for this session? */ | 878 | /* What header length is configured for this session? */ |
864 | hdr_len = pppol2tp_l2tp_header_len(session); | 879 | hdr_len = pppol2tp_l2tp_header_len(session); |
@@ -870,7 +885,7 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh | |||
870 | sizeof(ppph) + total_len, | 885 | sizeof(ppph) + total_len, |
871 | 0, GFP_KERNEL); | 886 | 0, GFP_KERNEL); |
872 | if (!skb) | 887 | if (!skb) |
873 | goto error; | 888 | goto error_put_sess_tun; |
874 | 889 | ||
875 | /* Reserve space for headers. */ | 890 | /* Reserve space for headers. */ |
876 | skb_reserve(skb, NET_SKB_PAD); | 891 | skb_reserve(skb, NET_SKB_PAD); |
@@ -900,7 +915,7 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh | |||
900 | error = memcpy_fromiovec(skb->data, m->msg_iov, total_len); | 915 | error = memcpy_fromiovec(skb->data, m->msg_iov, total_len); |
901 | if (error < 0) { | 916 | if (error < 0) { |
902 | kfree_skb(skb); | 917 | kfree_skb(skb); |
903 | goto error; | 918 | goto error_put_sess_tun; |
904 | } | 919 | } |
905 | skb_put(skb, total_len); | 920 | skb_put(skb, total_len); |
906 | 921 | ||
@@ -947,10 +962,33 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh | |||
947 | session->stats.tx_errors++; | 962 | session->stats.tx_errors++; |
948 | } | 963 | } |
949 | 964 | ||
965 | return error; | ||
966 | |||
967 | error_put_sess_tun: | ||
968 | sock_put(session->tunnel_sock); | ||
969 | error_put_sess: | ||
970 | sock_put(sk); | ||
950 | error: | 971 | error: |
951 | return error; | 972 | return error; |
952 | } | 973 | } |
953 | 974 | ||
975 | /* Automatically called when the skb is freed. | ||
976 | */ | ||
977 | static void pppol2tp_sock_wfree(struct sk_buff *skb) | ||
978 | { | ||
979 | sock_put(skb->sk); | ||
980 | } | ||
981 | |||
982 | /* For data skbs that we transmit, we associate with the tunnel socket | ||
983 | * but don't do accounting. | ||
984 | */ | ||
985 | static inline void pppol2tp_skb_set_owner_w(struct sk_buff *skb, struct sock *sk) | ||
986 | { | ||
987 | sock_hold(sk); | ||
988 | skb->sk = sk; | ||
989 | skb->destructor = pppol2tp_sock_wfree; | ||
990 | } | ||
991 | |||
954 | /* Transmit function called by generic PPP driver. Sends PPP frame | 992 | /* Transmit function called by generic PPP driver. Sends PPP frame |
955 | * over PPPoL2TP socket. | 993 | * over PPPoL2TP socket. |
956 | * | 994 | * |
@@ -980,6 +1018,8 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) | |||
980 | __wsum csum = 0; | 1018 | __wsum csum = 0; |
981 | struct udphdr *uh; | 1019 | struct udphdr *uh; |
982 | unsigned int len; | 1020 | unsigned int len; |
1021 | int old_headroom; | ||
1022 | int new_headroom; | ||
983 | 1023 | ||
984 | if (sock_flag(sk, SOCK_DEAD) || !(sk->sk_state & PPPOX_CONNECTED)) | 1024 | if (sock_flag(sk, SOCK_DEAD) || !(sk->sk_state & PPPOX_CONNECTED)) |
985 | goto abort; | 1025 | goto abort; |
@@ -991,25 +1031,27 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) | |||
991 | 1031 | ||
992 | sk_tun = session->tunnel_sock; | 1032 | sk_tun = session->tunnel_sock; |
993 | if (sk_tun == NULL) | 1033 | if (sk_tun == NULL) |
994 | goto abort; | 1034 | goto abort_put_sess; |
995 | tunnel = pppol2tp_sock_to_tunnel(sk_tun); | 1035 | tunnel = pppol2tp_sock_to_tunnel(sk_tun); |
996 | if (tunnel == NULL) | 1036 | if (tunnel == NULL) |
997 | goto abort; | 1037 | goto abort_put_sess; |
998 | 1038 | ||
999 | /* What header length is configured for this session? */ | 1039 | /* What header length is configured for this session? */ |
1000 | hdr_len = pppol2tp_l2tp_header_len(session); | 1040 | hdr_len = pppol2tp_l2tp_header_len(session); |
1001 | 1041 | ||
1002 | /* Check that there's enough headroom in the skb to insert IP, | 1042 | /* Check that there's enough headroom in the skb to insert IP, |
1003 | * UDP and L2TP and PPP headers. If not enough, expand it to | 1043 | * UDP and L2TP and PPP headers. If not enough, expand it to |
1004 | * make room. Note that a new skb (or a clone) is | 1044 | * make room. Adjust truesize. |
1005 | * allocated. If we return an error from this point on, make | ||
1006 | * sure we free the new skb but do not free the original skb | ||
1007 | * since that is done by the caller for the error case. | ||
1008 | */ | 1045 | */ |
1009 | headroom = NET_SKB_PAD + sizeof(struct iphdr) + | 1046 | headroom = NET_SKB_PAD + sizeof(struct iphdr) + |
1010 | sizeof(struct udphdr) + hdr_len + sizeof(ppph); | 1047 | sizeof(struct udphdr) + hdr_len + sizeof(ppph); |
1048 | old_headroom = skb_headroom(skb); | ||
1011 | if (skb_cow_head(skb, headroom)) | 1049 | if (skb_cow_head(skb, headroom)) |
1012 | goto abort; | 1050 | goto abort_put_sess_tun; |
1051 | |||
1052 | new_headroom = skb_headroom(skb); | ||
1053 | skb_orphan(skb); | ||
1054 | skb->truesize += new_headroom - old_headroom; | ||
1013 | 1055 | ||
1014 | /* Setup PPP header */ | 1056 | /* Setup PPP header */ |
1015 | __skb_push(skb, sizeof(ppph)); | 1057 | __skb_push(skb, sizeof(ppph)); |
@@ -1065,8 +1107,7 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) | |||
1065 | /* Get routing info from the tunnel socket */ | 1107 | /* Get routing info from the tunnel socket */ |
1066 | dst_release(skb->dst); | 1108 | dst_release(skb->dst); |
1067 | skb->dst = dst_clone(__sk_dst_get(sk_tun)); | 1109 | skb->dst = dst_clone(__sk_dst_get(sk_tun)); |
1068 | skb_orphan(skb); | 1110 | pppol2tp_skb_set_owner_w(skb, sk_tun); |
1069 | skb->sk = sk_tun; | ||
1070 | 1111 | ||
1071 | /* Queue the packet to IP for output */ | 1112 | /* Queue the packet to IP for output */ |
1072 | len = skb->len; | 1113 | len = skb->len; |
@@ -1083,8 +1124,14 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) | |||
1083 | session->stats.tx_errors++; | 1124 | session->stats.tx_errors++; |
1084 | } | 1125 | } |
1085 | 1126 | ||
1127 | sock_put(sk_tun); | ||
1128 | sock_put(sk); | ||
1086 | return 1; | 1129 | return 1; |
1087 | 1130 | ||
1131 | abort_put_sess_tun: | ||
1132 | sock_put(sk_tun); | ||
1133 | abort_put_sess: | ||
1134 | sock_put(sk); | ||
1088 | abort: | 1135 | abort: |
1089 | /* Free the original skb */ | 1136 | /* Free the original skb */ |
1090 | kfree_skb(skb); | 1137 | kfree_skb(skb); |
@@ -1188,7 +1235,7 @@ static void pppol2tp_tunnel_destruct(struct sock *sk) | |||
1188 | { | 1235 | { |
1189 | struct pppol2tp_tunnel *tunnel; | 1236 | struct pppol2tp_tunnel *tunnel; |
1190 | 1237 | ||
1191 | tunnel = pppol2tp_sock_to_tunnel(sk); | 1238 | tunnel = sk->sk_user_data; |
1192 | if (tunnel == NULL) | 1239 | if (tunnel == NULL) |
1193 | goto end; | 1240 | goto end; |
1194 | 1241 | ||
@@ -1227,10 +1274,12 @@ static void pppol2tp_session_destruct(struct sock *sk) | |||
1227 | if (sk->sk_user_data != NULL) { | 1274 | if (sk->sk_user_data != NULL) { |
1228 | struct pppol2tp_tunnel *tunnel; | 1275 | struct pppol2tp_tunnel *tunnel; |
1229 | 1276 | ||
1230 | session = pppol2tp_sock_to_session(sk); | 1277 | session = sk->sk_user_data; |
1231 | if (session == NULL) | 1278 | if (session == NULL) |
1232 | goto out; | 1279 | goto out; |
1233 | 1280 | ||
1281 | BUG_ON(session->magic != L2TP_SESSION_MAGIC); | ||
1282 | |||
1234 | /* Don't use pppol2tp_sock_to_tunnel() here to | 1283 | /* Don't use pppol2tp_sock_to_tunnel() here to |
1235 | * get the tunnel context because the tunnel | 1284 | * get the tunnel context because the tunnel |
1236 | * socket might have already been closed (its | 1285 | * socket might have already been closed (its |
@@ -1276,6 +1325,7 @@ out: | |||
1276 | static int pppol2tp_release(struct socket *sock) | 1325 | static int pppol2tp_release(struct socket *sock) |
1277 | { | 1326 | { |
1278 | struct sock *sk = sock->sk; | 1327 | struct sock *sk = sock->sk; |
1328 | struct pppol2tp_session *session; | ||
1279 | int error; | 1329 | int error; |
1280 | 1330 | ||
1281 | if (!sk) | 1331 | if (!sk) |
@@ -1293,9 +1343,18 @@ static int pppol2tp_release(struct socket *sock) | |||
1293 | sock_orphan(sk); | 1343 | sock_orphan(sk); |
1294 | sock->sk = NULL; | 1344 | sock->sk = NULL; |
1295 | 1345 | ||
1346 | session = pppol2tp_sock_to_session(sk); | ||
1347 | |||
1296 | /* Purge any queued data */ | 1348 | /* Purge any queued data */ |
1297 | skb_queue_purge(&sk->sk_receive_queue); | 1349 | skb_queue_purge(&sk->sk_receive_queue); |
1298 | skb_queue_purge(&sk->sk_write_queue); | 1350 | skb_queue_purge(&sk->sk_write_queue); |
1351 | if (session != NULL) { | ||
1352 | struct sk_buff *skb; | ||
1353 | while ((skb = skb_dequeue(&session->reorder_q))) { | ||
1354 | kfree_skb(skb); | ||
1355 | sock_put(sk); | ||
1356 | } | ||
1357 | } | ||
1299 | 1358 | ||
1300 | release_sock(sk); | 1359 | release_sock(sk); |
1301 | 1360 | ||
@@ -1598,7 +1657,7 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr, | |||
1598 | 1657 | ||
1599 | error = ppp_register_channel(&po->chan); | 1658 | error = ppp_register_channel(&po->chan); |
1600 | if (error) | 1659 | if (error) |
1601 | goto end; | 1660 | goto end_put_tun; |
1602 | 1661 | ||
1603 | /* This is how we get the session context from the socket. */ | 1662 | /* This is how we get the session context from the socket. */ |
1604 | sk->sk_user_data = session; | 1663 | sk->sk_user_data = session; |
@@ -1618,6 +1677,8 @@ out_no_ppp: | |||
1618 | PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, | 1677 | PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, |
1619 | "%s: created\n", session->name); | 1678 | "%s: created\n", session->name); |
1620 | 1679 | ||
1680 | end_put_tun: | ||
1681 | sock_put(tunnel_sock); | ||
1621 | end: | 1682 | end: |
1622 | release_sock(sk); | 1683 | release_sock(sk); |
1623 | 1684 | ||
@@ -1665,6 +1726,7 @@ static int pppol2tp_getname(struct socket *sock, struct sockaddr *uaddr, | |||
1665 | *usockaddr_len = len; | 1726 | *usockaddr_len = len; |
1666 | 1727 | ||
1667 | error = 0; | 1728 | error = 0; |
1729 | sock_put(sock->sk); | ||
1668 | 1730 | ||
1669 | end: | 1731 | end: |
1670 | return error; | 1732 | return error; |
@@ -1903,14 +1965,17 @@ static int pppol2tp_ioctl(struct socket *sock, unsigned int cmd, | |||
1903 | err = -EBADF; | 1965 | err = -EBADF; |
1904 | tunnel = pppol2tp_sock_to_tunnel(session->tunnel_sock); | 1966 | tunnel = pppol2tp_sock_to_tunnel(session->tunnel_sock); |
1905 | if (tunnel == NULL) | 1967 | if (tunnel == NULL) |
1906 | goto end; | 1968 | goto end_put_sess; |
1907 | 1969 | ||
1908 | err = pppol2tp_tunnel_ioctl(tunnel, cmd, arg); | 1970 | err = pppol2tp_tunnel_ioctl(tunnel, cmd, arg); |
1909 | goto end; | 1971 | sock_put(session->tunnel_sock); |
1972 | goto end_put_sess; | ||
1910 | } | 1973 | } |
1911 | 1974 | ||
1912 | err = pppol2tp_session_ioctl(session, cmd, arg); | 1975 | err = pppol2tp_session_ioctl(session, cmd, arg); |
1913 | 1976 | ||
1977 | end_put_sess: | ||
1978 | sock_put(sk); | ||
1914 | end: | 1979 | end: |
1915 | return err; | 1980 | return err; |
1916 | } | 1981 | } |
@@ -2056,14 +2121,17 @@ static int pppol2tp_setsockopt(struct socket *sock, int level, int optname, | |||
2056 | err = -EBADF; | 2121 | err = -EBADF; |
2057 | tunnel = pppol2tp_sock_to_tunnel(session->tunnel_sock); | 2122 | tunnel = pppol2tp_sock_to_tunnel(session->tunnel_sock); |
2058 | if (tunnel == NULL) | 2123 | if (tunnel == NULL) |
2059 | goto end; | 2124 | goto end_put_sess; |
2060 | 2125 | ||
2061 | err = pppol2tp_tunnel_setsockopt(sk, tunnel, optname, val); | 2126 | err = pppol2tp_tunnel_setsockopt(sk, tunnel, optname, val); |
2127 | sock_put(session->tunnel_sock); | ||
2062 | } else | 2128 | } else |
2063 | err = pppol2tp_session_setsockopt(sk, session, optname, val); | 2129 | err = pppol2tp_session_setsockopt(sk, session, optname, val); |
2064 | 2130 | ||
2065 | err = 0; | 2131 | err = 0; |
2066 | 2132 | ||
2133 | end_put_sess: | ||
2134 | sock_put(sk); | ||
2067 | end: | 2135 | end: |
2068 | return err; | 2136 | return err; |
2069 | } | 2137 | } |
@@ -2178,20 +2246,24 @@ static int pppol2tp_getsockopt(struct socket *sock, int level, | |||
2178 | err = -EBADF; | 2246 | err = -EBADF; |
2179 | tunnel = pppol2tp_sock_to_tunnel(session->tunnel_sock); | 2247 | tunnel = pppol2tp_sock_to_tunnel(session->tunnel_sock); |
2180 | if (tunnel == NULL) | 2248 | if (tunnel == NULL) |
2181 | goto end; | 2249 | goto end_put_sess; |
2182 | 2250 | ||
2183 | err = pppol2tp_tunnel_getsockopt(sk, tunnel, optname, &val); | 2251 | err = pppol2tp_tunnel_getsockopt(sk, tunnel, optname, &val); |
2252 | sock_put(session->tunnel_sock); | ||
2184 | } else | 2253 | } else |
2185 | err = pppol2tp_session_getsockopt(sk, session, optname, &val); | 2254 | err = pppol2tp_session_getsockopt(sk, session, optname, &val); |
2186 | 2255 | ||
2187 | err = -EFAULT; | 2256 | err = -EFAULT; |
2188 | if (put_user(len, (int __user *) optlen)) | 2257 | if (put_user(len, (int __user *) optlen)) |
2189 | goto end; | 2258 | goto end_put_sess; |
2190 | 2259 | ||
2191 | if (copy_to_user((void __user *) optval, &val, len)) | 2260 | if (copy_to_user((void __user *) optval, &val, len)) |
2192 | goto end; | 2261 | goto end_put_sess; |
2193 | 2262 | ||
2194 | err = 0; | 2263 | err = 0; |
2264 | |||
2265 | end_put_sess: | ||
2266 | sock_put(sk); | ||
2195 | end: | 2267 | end: |
2196 | return err; | 2268 | return err; |
2197 | } | 2269 | } |
diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c index 169edc154928..858b191517b3 100644 --- a/drivers/net/r6040.c +++ b/drivers/net/r6040.c | |||
@@ -733,7 +733,7 @@ static void r6040_timer(unsigned long data) | |||
733 | } | 733 | } |
734 | 734 | ||
735 | /* Timer active again */ | 735 | /* Timer active again */ |
736 | mod_timer(&lp->timer, jiffies + round_jiffies(HZ)); | 736 | mod_timer(&lp->timer, round_jiffies(jiffies + HZ)); |
737 | } | 737 | } |
738 | 738 | ||
739 | /* Read/set MAC address routines */ | 739 | /* Read/set MAC address routines */ |
diff --git a/drivers/net/s2io-regs.h b/drivers/net/s2io-regs.h index 2109508c047a..f8274f8941ea 100644 --- a/drivers/net/s2io-regs.h +++ b/drivers/net/s2io-regs.h | |||
@@ -250,7 +250,7 @@ struct XENA_dev_config { | |||
250 | u64 tx_mat0_n[0x8]; | 250 | u64 tx_mat0_n[0x8]; |
251 | #define TX_MAT_SET(fifo, msi) vBIT(msi, (8 * fifo), 8) | 251 | #define TX_MAT_SET(fifo, msi) vBIT(msi, (8 * fifo), 8) |
252 | 252 | ||
253 | u8 unused_1[0x8]; | 253 | u64 xmsi_mask_reg; |
254 | u64 stat_byte_cnt; | 254 | u64 stat_byte_cnt; |
255 | #define STAT_BC(n) vBIT(n,4,12) | 255 | #define STAT_BC(n) vBIT(n,4,12) |
256 | 256 | ||
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 523478ebfd69..b5c1e663417d 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c | |||
@@ -86,7 +86,7 @@ | |||
86 | #include "s2io.h" | 86 | #include "s2io.h" |
87 | #include "s2io-regs.h" | 87 | #include "s2io-regs.h" |
88 | 88 | ||
89 | #define DRV_VERSION "2.0.26.23" | 89 | #define DRV_VERSION "2.0.26.24" |
90 | 90 | ||
91 | /* S2io Driver name & version. */ | 91 | /* S2io Driver name & version. */ |
92 | static char s2io_driver_name[] = "Neterion"; | 92 | static char s2io_driver_name[] = "Neterion"; |
@@ -1113,9 +1113,10 @@ static int s2io_on_nec_bridge(struct pci_dev *s2io_pdev) | |||
1113 | struct pci_dev *tdev = NULL; | 1113 | struct pci_dev *tdev = NULL; |
1114 | while ((tdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, tdev)) != NULL) { | 1114 | while ((tdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, tdev)) != NULL) { |
1115 | if (tdev->vendor == NEC_VENID && tdev->device == NEC_DEVID) { | 1115 | if (tdev->vendor == NEC_VENID && tdev->device == NEC_DEVID) { |
1116 | if (tdev->bus == s2io_pdev->bus->parent) | 1116 | if (tdev->bus == s2io_pdev->bus->parent) { |
1117 | pci_dev_put(tdev); | 1117 | pci_dev_put(tdev); |
1118 | return 1; | 1118 | return 1; |
1119 | } | ||
1119 | } | 1120 | } |
1120 | } | 1121 | } |
1121 | return 0; | 1122 | return 0; |
@@ -1219,15 +1220,33 @@ static int init_tti(struct s2io_nic *nic, int link) | |||
1219 | TTI_DATA1_MEM_TX_URNG_B(0x10) | | 1220 | TTI_DATA1_MEM_TX_URNG_B(0x10) | |
1220 | TTI_DATA1_MEM_TX_URNG_C(0x30) | | 1221 | TTI_DATA1_MEM_TX_URNG_C(0x30) | |
1221 | TTI_DATA1_MEM_TX_TIMER_AC_EN; | 1222 | TTI_DATA1_MEM_TX_TIMER_AC_EN; |
1222 | 1223 | if (i == 0) | |
1223 | if (use_continuous_tx_intrs && (link == LINK_UP)) | 1224 | if (use_continuous_tx_intrs && (link == LINK_UP)) |
1224 | val64 |= TTI_DATA1_MEM_TX_TIMER_CI_EN; | 1225 | val64 |= TTI_DATA1_MEM_TX_TIMER_CI_EN; |
1225 | writeq(val64, &bar0->tti_data1_mem); | 1226 | writeq(val64, &bar0->tti_data1_mem); |
1226 | 1227 | ||
1227 | val64 = TTI_DATA2_MEM_TX_UFC_A(0x10) | | 1228 | if (nic->config.intr_type == MSI_X) { |
1228 | TTI_DATA2_MEM_TX_UFC_B(0x20) | | 1229 | val64 = TTI_DATA2_MEM_TX_UFC_A(0x10) | |
1229 | TTI_DATA2_MEM_TX_UFC_C(0x40) | | 1230 | TTI_DATA2_MEM_TX_UFC_B(0x100) | |
1230 | TTI_DATA2_MEM_TX_UFC_D(0x80); | 1231 | TTI_DATA2_MEM_TX_UFC_C(0x200) | |
1232 | TTI_DATA2_MEM_TX_UFC_D(0x300); | ||
1233 | } else { | ||
1234 | if ((nic->config.tx_steering_type == | ||
1235 | TX_DEFAULT_STEERING) && | ||
1236 | (config->tx_fifo_num > 1) && | ||
1237 | (i >= nic->udp_fifo_idx) && | ||
1238 | (i < (nic->udp_fifo_idx + | ||
1239 | nic->total_udp_fifos))) | ||
1240 | val64 = TTI_DATA2_MEM_TX_UFC_A(0x50) | | ||
1241 | TTI_DATA2_MEM_TX_UFC_B(0x80) | | ||
1242 | TTI_DATA2_MEM_TX_UFC_C(0x100) | | ||
1243 | TTI_DATA2_MEM_TX_UFC_D(0x120); | ||
1244 | else | ||
1245 | val64 = TTI_DATA2_MEM_TX_UFC_A(0x10) | | ||
1246 | TTI_DATA2_MEM_TX_UFC_B(0x20) | | ||
1247 | TTI_DATA2_MEM_TX_UFC_C(0x40) | | ||
1248 | TTI_DATA2_MEM_TX_UFC_D(0x80); | ||
1249 | } | ||
1231 | 1250 | ||
1232 | writeq(val64, &bar0->tti_data2_mem); | 1251 | writeq(val64, &bar0->tti_data2_mem); |
1233 | 1252 | ||
@@ -2813,6 +2832,15 @@ static void free_rx_buffers(struct s2io_nic *sp) | |||
2813 | } | 2832 | } |
2814 | } | 2833 | } |
2815 | 2834 | ||
2835 | static int s2io_chk_rx_buffers(struct ring_info *ring) | ||
2836 | { | ||
2837 | if (fill_rx_buffers(ring) == -ENOMEM) { | ||
2838 | DBG_PRINT(INFO_DBG, "%s:Out of memory", ring->dev->name); | ||
2839 | DBG_PRINT(INFO_DBG, " in Rx Intr!!\n"); | ||
2840 | } | ||
2841 | return 0; | ||
2842 | } | ||
2843 | |||
2816 | /** | 2844 | /** |
2817 | * s2io_poll - Rx interrupt handler for NAPI support | 2845 | * s2io_poll - Rx interrupt handler for NAPI support |
2818 | * @napi : pointer to the napi structure. | 2846 | * @napi : pointer to the napi structure. |
@@ -2826,57 +2854,73 @@ static void free_rx_buffers(struct s2io_nic *sp) | |||
2826 | * 0 on success and 1 if there are No Rx packets to be processed. | 2854 | * 0 on success and 1 if there are No Rx packets to be processed. |
2827 | */ | 2855 | */ |
2828 | 2856 | ||
2829 | static int s2io_poll(struct napi_struct *napi, int budget) | 2857 | static int s2io_poll_msix(struct napi_struct *napi, int budget) |
2830 | { | 2858 | { |
2831 | struct s2io_nic *nic = container_of(napi, struct s2io_nic, napi); | 2859 | struct ring_info *ring = container_of(napi, struct ring_info, napi); |
2832 | struct net_device *dev = nic->dev; | 2860 | struct net_device *dev = ring->dev; |
2833 | int pkt_cnt = 0, org_pkts_to_process; | ||
2834 | struct mac_info *mac_control; | ||
2835 | struct config_param *config; | 2861 | struct config_param *config; |
2862 | struct mac_info *mac_control; | ||
2863 | int pkts_processed = 0; | ||
2864 | u8 __iomem *addr = NULL; | ||
2865 | u8 val8 = 0; | ||
2866 | struct s2io_nic *nic = dev->priv; | ||
2836 | struct XENA_dev_config __iomem *bar0 = nic->bar0; | 2867 | struct XENA_dev_config __iomem *bar0 = nic->bar0; |
2837 | int i; | 2868 | int budget_org = budget; |
2838 | 2869 | ||
2839 | mac_control = &nic->mac_control; | ||
2840 | config = &nic->config; | 2870 | config = &nic->config; |
2871 | mac_control = &nic->mac_control; | ||
2841 | 2872 | ||
2842 | nic->pkts_to_process = budget; | 2873 | if (unlikely(!is_s2io_card_up(nic))) |
2843 | org_pkts_to_process = nic->pkts_to_process; | 2874 | return 0; |
2844 | 2875 | ||
2845 | writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_int); | 2876 | pkts_processed = rx_intr_handler(ring, budget); |
2846 | readl(&bar0->rx_traffic_int); | 2877 | s2io_chk_rx_buffers(ring); |
2847 | 2878 | ||
2848 | for (i = 0; i < config->rx_ring_num; i++) { | 2879 | if (pkts_processed < budget_org) { |
2849 | rx_intr_handler(&mac_control->rings[i]); | 2880 | netif_rx_complete(dev, napi); |
2850 | pkt_cnt = org_pkts_to_process - nic->pkts_to_process; | 2881 | /*Re Enable MSI-Rx Vector*/ |
2851 | if (!nic->pkts_to_process) { | 2882 | addr = (u8 __iomem *)&bar0->xmsi_mask_reg; |
2852 | /* Quota for the current iteration has been met */ | 2883 | addr += 7 - ring->ring_no; |
2853 | goto no_rx; | 2884 | val8 = (ring->ring_no == 0) ? 0x3f : 0xbf; |
2854 | } | 2885 | writeb(val8, addr); |
2886 | val8 = readb(addr); | ||
2855 | } | 2887 | } |
2888 | return pkts_processed; | ||
2889 | } | ||
2890 | static int s2io_poll_inta(struct napi_struct *napi, int budget) | ||
2891 | { | ||
2892 | struct s2io_nic *nic = container_of(napi, struct s2io_nic, napi); | ||
2893 | struct ring_info *ring; | ||
2894 | struct net_device *dev = nic->dev; | ||
2895 | struct config_param *config; | ||
2896 | struct mac_info *mac_control; | ||
2897 | int pkts_processed = 0; | ||
2898 | int ring_pkts_processed, i; | ||
2899 | struct XENA_dev_config __iomem *bar0 = nic->bar0; | ||
2900 | int budget_org = budget; | ||
2856 | 2901 | ||
2857 | netif_rx_complete(dev, napi); | 2902 | config = &nic->config; |
2903 | mac_control = &nic->mac_control; | ||
2858 | 2904 | ||
2859 | for (i = 0; i < config->rx_ring_num; i++) { | 2905 | if (unlikely(!is_s2io_card_up(nic))) |
2860 | if (fill_rx_buffers(&mac_control->rings[i]) == -ENOMEM) { | 2906 | return 0; |
2861 | DBG_PRINT(INFO_DBG, "%s:Out of memory", dev->name); | ||
2862 | DBG_PRINT(INFO_DBG, " in Rx Poll!!\n"); | ||
2863 | break; | ||
2864 | } | ||
2865 | } | ||
2866 | /* Re enable the Rx interrupts. */ | ||
2867 | writeq(0x0, &bar0->rx_traffic_mask); | ||
2868 | readl(&bar0->rx_traffic_mask); | ||
2869 | return pkt_cnt; | ||
2870 | 2907 | ||
2871 | no_rx: | ||
2872 | for (i = 0; i < config->rx_ring_num; i++) { | 2908 | for (i = 0; i < config->rx_ring_num; i++) { |
2873 | if (fill_rx_buffers(&mac_control->rings[i]) == -ENOMEM) { | 2909 | ring = &mac_control->rings[i]; |
2874 | DBG_PRINT(INFO_DBG, "%s:Out of memory", dev->name); | 2910 | ring_pkts_processed = rx_intr_handler(ring, budget); |
2875 | DBG_PRINT(INFO_DBG, " in Rx Poll!!\n"); | 2911 | s2io_chk_rx_buffers(ring); |
2912 | pkts_processed += ring_pkts_processed; | ||
2913 | budget -= ring_pkts_processed; | ||
2914 | if (budget <= 0) | ||
2876 | break; | 2915 | break; |
2877 | } | ||
2878 | } | 2916 | } |
2879 | return pkt_cnt; | 2917 | if (pkts_processed < budget_org) { |
2918 | netif_rx_complete(dev, napi); | ||
2919 | /* Re enable the Rx interrupts for the ring */ | ||
2920 | writeq(0, &bar0->rx_traffic_mask); | ||
2921 | readl(&bar0->rx_traffic_mask); | ||
2922 | } | ||
2923 | return pkts_processed; | ||
2880 | } | 2924 | } |
2881 | 2925 | ||
2882 | #ifdef CONFIG_NET_POLL_CONTROLLER | 2926 | #ifdef CONFIG_NET_POLL_CONTROLLER |
@@ -2918,7 +2962,7 @@ static void s2io_netpoll(struct net_device *dev) | |||
2918 | 2962 | ||
2919 | /* check for received packet and indicate up to network */ | 2963 | /* check for received packet and indicate up to network */ |
2920 | for (i = 0; i < config->rx_ring_num; i++) | 2964 | for (i = 0; i < config->rx_ring_num; i++) |
2921 | rx_intr_handler(&mac_control->rings[i]); | 2965 | rx_intr_handler(&mac_control->rings[i], 0); |
2922 | 2966 | ||
2923 | for (i = 0; i < config->rx_ring_num; i++) { | 2967 | for (i = 0; i < config->rx_ring_num; i++) { |
2924 | if (fill_rx_buffers(&mac_control->rings[i]) == -ENOMEM) { | 2968 | if (fill_rx_buffers(&mac_control->rings[i]) == -ENOMEM) { |
@@ -2934,7 +2978,8 @@ static void s2io_netpoll(struct net_device *dev) | |||
2934 | 2978 | ||
2935 | /** | 2979 | /** |
2936 | * rx_intr_handler - Rx interrupt handler | 2980 | * rx_intr_handler - Rx interrupt handler |
2937 | * @nic: device private variable. | 2981 | * @ring_info: per ring structure. |
2982 | * @budget: budget for napi processing. | ||
2938 | * Description: | 2983 | * Description: |
2939 | * If the interrupt is because of a received frame or if the | 2984 | * If the interrupt is because of a received frame or if the |
2940 | * receive ring contains fresh as yet un-processed frames,this function is | 2985 | * receive ring contains fresh as yet un-processed frames,this function is |
@@ -2942,15 +2987,15 @@ static void s2io_netpoll(struct net_device *dev) | |||
2942 | * stopped and sends the skb to the OSM's Rx handler and then increments | 2987 | * stopped and sends the skb to the OSM's Rx handler and then increments |
2943 | * the offset. | 2988 | * the offset. |
2944 | * Return Value: | 2989 | * Return Value: |
2945 | * NONE. | 2990 | * No. of napi packets processed. |
2946 | */ | 2991 | */ |
2947 | static void rx_intr_handler(struct ring_info *ring_data) | 2992 | static int rx_intr_handler(struct ring_info *ring_data, int budget) |
2948 | { | 2993 | { |
2949 | int get_block, put_block; | 2994 | int get_block, put_block; |
2950 | struct rx_curr_get_info get_info, put_info; | 2995 | struct rx_curr_get_info get_info, put_info; |
2951 | struct RxD_t *rxdp; | 2996 | struct RxD_t *rxdp; |
2952 | struct sk_buff *skb; | 2997 | struct sk_buff *skb; |
2953 | int pkt_cnt = 0; | 2998 | int pkt_cnt = 0, napi_pkts = 0; |
2954 | int i; | 2999 | int i; |
2955 | struct RxD1* rxdp1; | 3000 | struct RxD1* rxdp1; |
2956 | struct RxD3* rxdp3; | 3001 | struct RxD3* rxdp3; |
@@ -2977,7 +3022,7 @@ static void rx_intr_handler(struct ring_info *ring_data) | |||
2977 | DBG_PRINT(ERR_DBG, "%s: The skb is ", | 3022 | DBG_PRINT(ERR_DBG, "%s: The skb is ", |
2978 | ring_data->dev->name); | 3023 | ring_data->dev->name); |
2979 | DBG_PRINT(ERR_DBG, "Null in Rx Intr\n"); | 3024 | DBG_PRINT(ERR_DBG, "Null in Rx Intr\n"); |
2980 | return; | 3025 | return 0; |
2981 | } | 3026 | } |
2982 | if (ring_data->rxd_mode == RXD_MODE_1) { | 3027 | if (ring_data->rxd_mode == RXD_MODE_1) { |
2983 | rxdp1 = (struct RxD1*)rxdp; | 3028 | rxdp1 = (struct RxD1*)rxdp; |
@@ -3014,9 +3059,10 @@ static void rx_intr_handler(struct ring_info *ring_data) | |||
3014 | rxdp = ring_data->rx_blocks[get_block].block_virt_addr; | 3059 | rxdp = ring_data->rx_blocks[get_block].block_virt_addr; |
3015 | } | 3060 | } |
3016 | 3061 | ||
3017 | if(ring_data->nic->config.napi){ | 3062 | if (ring_data->nic->config.napi) { |
3018 | ring_data->nic->pkts_to_process -= 1; | 3063 | budget--; |
3019 | if (!ring_data->nic->pkts_to_process) | 3064 | napi_pkts++; |
3065 | if (!budget) | ||
3020 | break; | 3066 | break; |
3021 | } | 3067 | } |
3022 | pkt_cnt++; | 3068 | pkt_cnt++; |
@@ -3034,6 +3080,7 @@ static void rx_intr_handler(struct ring_info *ring_data) | |||
3034 | } | 3080 | } |
3035 | } | 3081 | } |
3036 | } | 3082 | } |
3083 | return(napi_pkts); | ||
3037 | } | 3084 | } |
3038 | 3085 | ||
3039 | /** | 3086 | /** |
@@ -3730,14 +3777,19 @@ static void restore_xmsi_data(struct s2io_nic *nic) | |||
3730 | { | 3777 | { |
3731 | struct XENA_dev_config __iomem *bar0 = nic->bar0; | 3778 | struct XENA_dev_config __iomem *bar0 = nic->bar0; |
3732 | u64 val64; | 3779 | u64 val64; |
3733 | int i; | 3780 | int i, msix_index; |
3781 | |||
3782 | |||
3783 | if (nic->device_type == XFRAME_I_DEVICE) | ||
3784 | return; | ||
3734 | 3785 | ||
3735 | for (i=0; i < MAX_REQUESTED_MSI_X; i++) { | 3786 | for (i=0; i < MAX_REQUESTED_MSI_X; i++) { |
3787 | msix_index = (i) ? ((i-1) * 8 + 1): 0; | ||
3736 | writeq(nic->msix_info[i].addr, &bar0->xmsi_address); | 3788 | writeq(nic->msix_info[i].addr, &bar0->xmsi_address); |
3737 | writeq(nic->msix_info[i].data, &bar0->xmsi_data); | 3789 | writeq(nic->msix_info[i].data, &bar0->xmsi_data); |
3738 | val64 = (s2BIT(7) | s2BIT(15) | vBIT(i, 26, 6)); | 3790 | val64 = (s2BIT(7) | s2BIT(15) | vBIT(msix_index, 26, 6)); |
3739 | writeq(val64, &bar0->xmsi_access); | 3791 | writeq(val64, &bar0->xmsi_access); |
3740 | if (wait_for_msix_trans(nic, i)) { | 3792 | if (wait_for_msix_trans(nic, msix_index)) { |
3741 | DBG_PRINT(ERR_DBG, "failed in %s\n", __FUNCTION__); | 3793 | DBG_PRINT(ERR_DBG, "failed in %s\n", __FUNCTION__); |
3742 | continue; | 3794 | continue; |
3743 | } | 3795 | } |
@@ -3748,13 +3800,17 @@ static void store_xmsi_data(struct s2io_nic *nic) | |||
3748 | { | 3800 | { |
3749 | struct XENA_dev_config __iomem *bar0 = nic->bar0; | 3801 | struct XENA_dev_config __iomem *bar0 = nic->bar0; |
3750 | u64 val64, addr, data; | 3802 | u64 val64, addr, data; |
3751 | int i; | 3803 | int i, msix_index; |
3804 | |||
3805 | if (nic->device_type == XFRAME_I_DEVICE) | ||
3806 | return; | ||
3752 | 3807 | ||
3753 | /* Store and display */ | 3808 | /* Store and display */ |
3754 | for (i=0; i < MAX_REQUESTED_MSI_X; i++) { | 3809 | for (i=0; i < MAX_REQUESTED_MSI_X; i++) { |
3755 | val64 = (s2BIT(15) | vBIT(i, 26, 6)); | 3810 | msix_index = (i) ? ((i-1) * 8 + 1): 0; |
3811 | val64 = (s2BIT(15) | vBIT(msix_index, 26, 6)); | ||
3756 | writeq(val64, &bar0->xmsi_access); | 3812 | writeq(val64, &bar0->xmsi_access); |
3757 | if (wait_for_msix_trans(nic, i)) { | 3813 | if (wait_for_msix_trans(nic, msix_index)) { |
3758 | DBG_PRINT(ERR_DBG, "failed in %s\n", __FUNCTION__); | 3814 | DBG_PRINT(ERR_DBG, "failed in %s\n", __FUNCTION__); |
3759 | continue; | 3815 | continue; |
3760 | } | 3816 | } |
@@ -3770,11 +3826,11 @@ static void store_xmsi_data(struct s2io_nic *nic) | |||
3770 | static int s2io_enable_msi_x(struct s2io_nic *nic) | 3826 | static int s2io_enable_msi_x(struct s2io_nic *nic) |
3771 | { | 3827 | { |
3772 | struct XENA_dev_config __iomem *bar0 = nic->bar0; | 3828 | struct XENA_dev_config __iomem *bar0 = nic->bar0; |
3773 | u64 tx_mat, rx_mat; | 3829 | u64 rx_mat; |
3774 | u16 msi_control; /* Temp variable */ | 3830 | u16 msi_control; /* Temp variable */ |
3775 | int ret, i, j, msix_indx = 1; | 3831 | int ret, i, j, msix_indx = 1; |
3776 | 3832 | ||
3777 | nic->entries = kcalloc(MAX_REQUESTED_MSI_X, sizeof(struct msix_entry), | 3833 | nic->entries = kmalloc(nic->num_entries * sizeof(struct msix_entry), |
3778 | GFP_KERNEL); | 3834 | GFP_KERNEL); |
3779 | if (!nic->entries) { | 3835 | if (!nic->entries) { |
3780 | DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n", \ | 3836 | DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n", \ |
@@ -3783,10 +3839,12 @@ static int s2io_enable_msi_x(struct s2io_nic *nic) | |||
3783 | return -ENOMEM; | 3839 | return -ENOMEM; |
3784 | } | 3840 | } |
3785 | nic->mac_control.stats_info->sw_stat.mem_allocated | 3841 | nic->mac_control.stats_info->sw_stat.mem_allocated |
3786 | += (MAX_REQUESTED_MSI_X * sizeof(struct msix_entry)); | 3842 | += (nic->num_entries * sizeof(struct msix_entry)); |
3843 | |||
3844 | memset(nic->entries, 0, nic->num_entries * sizeof(struct msix_entry)); | ||
3787 | 3845 | ||
3788 | nic->s2io_entries = | 3846 | nic->s2io_entries = |
3789 | kcalloc(MAX_REQUESTED_MSI_X, sizeof(struct s2io_msix_entry), | 3847 | kmalloc(nic->num_entries * sizeof(struct s2io_msix_entry), |
3790 | GFP_KERNEL); | 3848 | GFP_KERNEL); |
3791 | if (!nic->s2io_entries) { | 3849 | if (!nic->s2io_entries) { |
3792 | DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n", | 3850 | DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n", |
@@ -3794,60 +3852,52 @@ static int s2io_enable_msi_x(struct s2io_nic *nic) | |||
3794 | nic->mac_control.stats_info->sw_stat.mem_alloc_fail_cnt++; | 3852 | nic->mac_control.stats_info->sw_stat.mem_alloc_fail_cnt++; |
3795 | kfree(nic->entries); | 3853 | kfree(nic->entries); |
3796 | nic->mac_control.stats_info->sw_stat.mem_freed | 3854 | nic->mac_control.stats_info->sw_stat.mem_freed |
3797 | += (MAX_REQUESTED_MSI_X * sizeof(struct msix_entry)); | 3855 | += (nic->num_entries * sizeof(struct msix_entry)); |
3798 | return -ENOMEM; | 3856 | return -ENOMEM; |
3799 | } | 3857 | } |
3800 | nic->mac_control.stats_info->sw_stat.mem_allocated | 3858 | nic->mac_control.stats_info->sw_stat.mem_allocated |
3801 | += (MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry)); | 3859 | += (nic->num_entries * sizeof(struct s2io_msix_entry)); |
3802 | 3860 | memset(nic->s2io_entries, 0, | |
3803 | for (i=0; i< MAX_REQUESTED_MSI_X; i++) { | 3861 | nic->num_entries * sizeof(struct s2io_msix_entry)); |
3804 | nic->entries[i].entry = i; | 3862 | |
3805 | nic->s2io_entries[i].entry = i; | 3863 | nic->entries[0].entry = 0; |
3864 | nic->s2io_entries[0].entry = 0; | ||
3865 | nic->s2io_entries[0].in_use = MSIX_FLG; | ||
3866 | nic->s2io_entries[0].type = MSIX_ALARM_TYPE; | ||
3867 | nic->s2io_entries[0].arg = &nic->mac_control.fifos; | ||
3868 | |||
3869 | for (i = 1; i < nic->num_entries; i++) { | ||
3870 | nic->entries[i].entry = ((i - 1) * 8) + 1; | ||
3871 | nic->s2io_entries[i].entry = ((i - 1) * 8) + 1; | ||
3806 | nic->s2io_entries[i].arg = NULL; | 3872 | nic->s2io_entries[i].arg = NULL; |
3807 | nic->s2io_entries[i].in_use = 0; | 3873 | nic->s2io_entries[i].in_use = 0; |
3808 | } | 3874 | } |
3809 | 3875 | ||
3810 | tx_mat = readq(&bar0->tx_mat0_n[0]); | ||
3811 | for (i=0; i<nic->config.tx_fifo_num; i++, msix_indx++) { | ||
3812 | tx_mat |= TX_MAT_SET(i, msix_indx); | ||
3813 | nic->s2io_entries[msix_indx].arg = &nic->mac_control.fifos[i]; | ||
3814 | nic->s2io_entries[msix_indx].type = MSIX_FIFO_TYPE; | ||
3815 | nic->s2io_entries[msix_indx].in_use = MSIX_FLG; | ||
3816 | } | ||
3817 | writeq(tx_mat, &bar0->tx_mat0_n[0]); | ||
3818 | |||
3819 | rx_mat = readq(&bar0->rx_mat); | 3876 | rx_mat = readq(&bar0->rx_mat); |
3820 | for (j = 0; j < nic->config.rx_ring_num; j++, msix_indx++) { | 3877 | for (j = 0; j < nic->config.rx_ring_num; j++) { |
3821 | rx_mat |= RX_MAT_SET(j, msix_indx); | 3878 | rx_mat |= RX_MAT_SET(j, msix_indx); |
3822 | nic->s2io_entries[msix_indx].arg | 3879 | nic->s2io_entries[j+1].arg = &nic->mac_control.rings[j]; |
3823 | = &nic->mac_control.rings[j]; | 3880 | nic->s2io_entries[j+1].type = MSIX_RING_TYPE; |
3824 | nic->s2io_entries[msix_indx].type = MSIX_RING_TYPE; | 3881 | nic->s2io_entries[j+1].in_use = MSIX_FLG; |
3825 | nic->s2io_entries[msix_indx].in_use = MSIX_FLG; | 3882 | msix_indx += 8; |
3826 | } | 3883 | } |
3827 | writeq(rx_mat, &bar0->rx_mat); | 3884 | writeq(rx_mat, &bar0->rx_mat); |
3885 | readq(&bar0->rx_mat); | ||
3828 | 3886 | ||
3829 | nic->avail_msix_vectors = 0; | 3887 | ret = pci_enable_msix(nic->pdev, nic->entries, nic->num_entries); |
3830 | ret = pci_enable_msix(nic->pdev, nic->entries, MAX_REQUESTED_MSI_X); | ||
3831 | /* We fail init if error or we get less vectors than min required */ | 3888 | /* We fail init if error or we get less vectors than min required */ |
3832 | if (ret >= (nic->config.tx_fifo_num + nic->config.rx_ring_num + 1)) { | ||
3833 | nic->avail_msix_vectors = ret; | ||
3834 | ret = pci_enable_msix(nic->pdev, nic->entries, ret); | ||
3835 | } | ||
3836 | if (ret) { | 3889 | if (ret) { |
3837 | DBG_PRINT(ERR_DBG, "%s: Enabling MSIX failed\n", nic->dev->name); | 3890 | DBG_PRINT(ERR_DBG, "%s: Enabling MSIX failed\n", nic->dev->name); |
3838 | kfree(nic->entries); | 3891 | kfree(nic->entries); |
3839 | nic->mac_control.stats_info->sw_stat.mem_freed | 3892 | nic->mac_control.stats_info->sw_stat.mem_freed |
3840 | += (MAX_REQUESTED_MSI_X * sizeof(struct msix_entry)); | 3893 | += (nic->num_entries * sizeof(struct msix_entry)); |
3841 | kfree(nic->s2io_entries); | 3894 | kfree(nic->s2io_entries); |
3842 | nic->mac_control.stats_info->sw_stat.mem_freed | 3895 | nic->mac_control.stats_info->sw_stat.mem_freed |
3843 | += (MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry)); | 3896 | += (nic->num_entries * sizeof(struct s2io_msix_entry)); |
3844 | nic->entries = NULL; | 3897 | nic->entries = NULL; |
3845 | nic->s2io_entries = NULL; | 3898 | nic->s2io_entries = NULL; |
3846 | nic->avail_msix_vectors = 0; | ||
3847 | return -ENOMEM; | 3899 | return -ENOMEM; |
3848 | } | 3900 | } |
3849 | if (!nic->avail_msix_vectors) | ||
3850 | nic->avail_msix_vectors = MAX_REQUESTED_MSI_X; | ||
3851 | 3901 | ||
3852 | /* | 3902 | /* |
3853 | * To enable MSI-X, MSI also needs to be enabled, due to a bug | 3903 | * To enable MSI-X, MSI also needs to be enabled, due to a bug |
@@ -3919,7 +3969,7 @@ static void remove_msix_isr(struct s2io_nic *sp) | |||
3919 | int i; | 3969 | int i; |
3920 | u16 msi_control; | 3970 | u16 msi_control; |
3921 | 3971 | ||
3922 | for (i = 0; i < MAX_REQUESTED_MSI_X; i++) { | 3972 | for (i = 0; i < sp->num_entries; i++) { |
3923 | if (sp->s2io_entries[i].in_use == | 3973 | if (sp->s2io_entries[i].in_use == |
3924 | MSIX_REGISTERED_SUCCESS) { | 3974 | MSIX_REGISTERED_SUCCESS) { |
3925 | int vector = sp->entries[i].vector; | 3975 | int vector = sp->entries[i].vector; |
@@ -3975,29 +4025,6 @@ static int s2io_open(struct net_device *dev) | |||
3975 | netif_carrier_off(dev); | 4025 | netif_carrier_off(dev); |
3976 | sp->last_link_state = 0; | 4026 | sp->last_link_state = 0; |
3977 | 4027 | ||
3978 | if (sp->config.intr_type == MSI_X) { | ||
3979 | int ret = s2io_enable_msi_x(sp); | ||
3980 | |||
3981 | if (!ret) { | ||
3982 | ret = s2io_test_msi(sp); | ||
3983 | /* rollback MSI-X, will re-enable during add_isr() */ | ||
3984 | remove_msix_isr(sp); | ||
3985 | } | ||
3986 | if (ret) { | ||
3987 | |||
3988 | DBG_PRINT(ERR_DBG, | ||
3989 | "%s: MSI-X requested but failed to enable\n", | ||
3990 | dev->name); | ||
3991 | sp->config.intr_type = INTA; | ||
3992 | } | ||
3993 | } | ||
3994 | |||
3995 | /* NAPI doesn't work well with MSI(X) */ | ||
3996 | if (sp->config.intr_type != INTA) { | ||
3997 | if(sp->config.napi) | ||
3998 | sp->config.napi = 0; | ||
3999 | } | ||
4000 | |||
4001 | /* Initialize H/W and enable interrupts */ | 4028 | /* Initialize H/W and enable interrupts */ |
4002 | err = s2io_card_up(sp); | 4029 | err = s2io_card_up(sp); |
4003 | if (err) { | 4030 | if (err) { |
@@ -4020,12 +4047,12 @@ hw_init_failed: | |||
4020 | if (sp->entries) { | 4047 | if (sp->entries) { |
4021 | kfree(sp->entries); | 4048 | kfree(sp->entries); |
4022 | sp->mac_control.stats_info->sw_stat.mem_freed | 4049 | sp->mac_control.stats_info->sw_stat.mem_freed |
4023 | += (MAX_REQUESTED_MSI_X * sizeof(struct msix_entry)); | 4050 | += (sp->num_entries * sizeof(struct msix_entry)); |
4024 | } | 4051 | } |
4025 | if (sp->s2io_entries) { | 4052 | if (sp->s2io_entries) { |
4026 | kfree(sp->s2io_entries); | 4053 | kfree(sp->s2io_entries); |
4027 | sp->mac_control.stats_info->sw_stat.mem_freed | 4054 | sp->mac_control.stats_info->sw_stat.mem_freed |
4028 | += (MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry)); | 4055 | += (sp->num_entries * sizeof(struct s2io_msix_entry)); |
4029 | } | 4056 | } |
4030 | } | 4057 | } |
4031 | return err; | 4058 | return err; |
@@ -4327,40 +4354,65 @@ s2io_alarm_handle(unsigned long data) | |||
4327 | mod_timer(&sp->alarm_timer, jiffies + HZ / 2); | 4354 | mod_timer(&sp->alarm_timer, jiffies + HZ / 2); |
4328 | } | 4355 | } |
4329 | 4356 | ||
4330 | static int s2io_chk_rx_buffers(struct ring_info *ring) | ||
4331 | { | ||
4332 | if (fill_rx_buffers(ring) == -ENOMEM) { | ||
4333 | DBG_PRINT(INFO_DBG, "%s:Out of memory", ring->dev->name); | ||
4334 | DBG_PRINT(INFO_DBG, " in Rx Intr!!\n"); | ||
4335 | } | ||
4336 | return 0; | ||
4337 | } | ||
4338 | |||
4339 | static irqreturn_t s2io_msix_ring_handle(int irq, void *dev_id) | 4357 | static irqreturn_t s2io_msix_ring_handle(int irq, void *dev_id) |
4340 | { | 4358 | { |
4341 | struct ring_info *ring = (struct ring_info *)dev_id; | 4359 | struct ring_info *ring = (struct ring_info *)dev_id; |
4342 | struct s2io_nic *sp = ring->nic; | 4360 | struct s2io_nic *sp = ring->nic; |
4361 | struct XENA_dev_config __iomem *bar0 = sp->bar0; | ||
4362 | struct net_device *dev = sp->dev; | ||
4343 | 4363 | ||
4344 | if (!is_s2io_card_up(sp)) | 4364 | if (unlikely(!is_s2io_card_up(sp))) |
4345 | return IRQ_HANDLED; | 4365 | return IRQ_HANDLED; |
4346 | 4366 | ||
4347 | rx_intr_handler(ring); | 4367 | if (sp->config.napi) { |
4348 | s2io_chk_rx_buffers(ring); | 4368 | u8 __iomem *addr = NULL; |
4369 | u8 val8 = 0; | ||
4370 | |||
4371 | addr = (u8 __iomem *)&bar0->xmsi_mask_reg; | ||
4372 | addr += (7 - ring->ring_no); | ||
4373 | val8 = (ring->ring_no == 0) ? 0x7f : 0xff; | ||
4374 | writeb(val8, addr); | ||
4375 | val8 = readb(addr); | ||
4376 | netif_rx_schedule(dev, &ring->napi); | ||
4377 | } else { | ||
4378 | rx_intr_handler(ring, 0); | ||
4379 | s2io_chk_rx_buffers(ring); | ||
4380 | } | ||
4349 | 4381 | ||
4350 | return IRQ_HANDLED; | 4382 | return IRQ_HANDLED; |
4351 | } | 4383 | } |
4352 | 4384 | ||
4353 | static irqreturn_t s2io_msix_fifo_handle(int irq, void *dev_id) | 4385 | static irqreturn_t s2io_msix_fifo_handle(int irq, void *dev_id) |
4354 | { | 4386 | { |
4355 | struct fifo_info *fifo = (struct fifo_info *)dev_id; | 4387 | int i; |
4356 | struct s2io_nic *sp = fifo->nic; | 4388 | struct fifo_info *fifos = (struct fifo_info *)dev_id; |
4389 | struct s2io_nic *sp = fifos->nic; | ||
4390 | struct XENA_dev_config __iomem *bar0 = sp->bar0; | ||
4391 | struct config_param *config = &sp->config; | ||
4392 | u64 reason; | ||
4357 | 4393 | ||
4358 | if (!is_s2io_card_up(sp)) | 4394 | if (unlikely(!is_s2io_card_up(sp))) |
4395 | return IRQ_NONE; | ||
4396 | |||
4397 | reason = readq(&bar0->general_int_status); | ||
4398 | if (unlikely(reason == S2IO_MINUS_ONE)) | ||
4399 | /* Nothing much can be done. Get out */ | ||
4359 | return IRQ_HANDLED; | 4400 | return IRQ_HANDLED; |
4360 | 4401 | ||
4361 | tx_intr_handler(fifo); | 4402 | writeq(S2IO_MINUS_ONE, &bar0->general_int_mask); |
4403 | |||
4404 | if (reason & GEN_INTR_TXTRAFFIC) | ||
4405 | writeq(S2IO_MINUS_ONE, &bar0->tx_traffic_int); | ||
4406 | |||
4407 | for (i = 0; i < config->tx_fifo_num; i++) | ||
4408 | tx_intr_handler(&fifos[i]); | ||
4409 | |||
4410 | writeq(sp->general_int_mask, &bar0->general_int_mask); | ||
4411 | readl(&bar0->general_int_status); | ||
4412 | |||
4362 | return IRQ_HANDLED; | 4413 | return IRQ_HANDLED; |
4363 | } | 4414 | } |
4415 | |||
4364 | static void s2io_txpic_intr_handle(struct s2io_nic *sp) | 4416 | static void s2io_txpic_intr_handle(struct s2io_nic *sp) |
4365 | { | 4417 | { |
4366 | struct XENA_dev_config __iomem *bar0 = sp->bar0; | 4418 | struct XENA_dev_config __iomem *bar0 = sp->bar0; |
@@ -4762,14 +4814,10 @@ static irqreturn_t s2io_isr(int irq, void *dev_id) | |||
4762 | 4814 | ||
4763 | if (config->napi) { | 4815 | if (config->napi) { |
4764 | if (reason & GEN_INTR_RXTRAFFIC) { | 4816 | if (reason & GEN_INTR_RXTRAFFIC) { |
4765 | if (likely(netif_rx_schedule_prep(dev, | 4817 | netif_rx_schedule(dev, &sp->napi); |
4766 | &sp->napi))) { | 4818 | writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_mask); |
4767 | __netif_rx_schedule(dev, &sp->napi); | 4819 | writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_int); |
4768 | writeq(S2IO_MINUS_ONE, | 4820 | readl(&bar0->rx_traffic_int); |
4769 | &bar0->rx_traffic_mask); | ||
4770 | } else | ||
4771 | writeq(S2IO_MINUS_ONE, | ||
4772 | &bar0->rx_traffic_int); | ||
4773 | } | 4821 | } |
4774 | } else { | 4822 | } else { |
4775 | /* | 4823 | /* |
@@ -4781,7 +4829,7 @@ static irqreturn_t s2io_isr(int irq, void *dev_id) | |||
4781 | writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_int); | 4829 | writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_int); |
4782 | 4830 | ||
4783 | for (i = 0; i < config->rx_ring_num; i++) | 4831 | for (i = 0; i < config->rx_ring_num; i++) |
4784 | rx_intr_handler(&mac_control->rings[i]); | 4832 | rx_intr_handler(&mac_control->rings[i], 0); |
4785 | } | 4833 | } |
4786 | 4834 | ||
4787 | /* | 4835 | /* |
@@ -6984,62 +7032,62 @@ static int s2io_add_isr(struct s2io_nic * sp) | |||
6984 | 7032 | ||
6985 | /* After proper initialization of H/W, register ISR */ | 7033 | /* After proper initialization of H/W, register ISR */ |
6986 | if (sp->config.intr_type == MSI_X) { | 7034 | if (sp->config.intr_type == MSI_X) { |
6987 | int i, msix_tx_cnt=0,msix_rx_cnt=0; | 7035 | int i, msix_rx_cnt = 0; |
6988 | 7036 | ||
6989 | for (i=1; (sp->s2io_entries[i].in_use == MSIX_FLG); i++) { | 7037 | for (i = 0; i < sp->num_entries; i++) { |
6990 | if (sp->s2io_entries[i].type == MSIX_FIFO_TYPE) { | 7038 | if (sp->s2io_entries[i].in_use == MSIX_FLG) { |
6991 | sprintf(sp->desc[i], "%s:MSI-X-%d-TX", | 7039 | if (sp->s2io_entries[i].type == |
7040 | MSIX_RING_TYPE) { | ||
7041 | sprintf(sp->desc[i], "%s:MSI-X-%d-RX", | ||
7042 | dev->name, i); | ||
7043 | err = request_irq(sp->entries[i].vector, | ||
7044 | s2io_msix_ring_handle, 0, | ||
7045 | sp->desc[i], | ||
7046 | sp->s2io_entries[i].arg); | ||
7047 | } else if (sp->s2io_entries[i].type == | ||
7048 | MSIX_ALARM_TYPE) { | ||
7049 | sprintf(sp->desc[i], "%s:MSI-X-%d-TX", | ||
6992 | dev->name, i); | 7050 | dev->name, i); |
6993 | err = request_irq(sp->entries[i].vector, | 7051 | err = request_irq(sp->entries[i].vector, |
6994 | s2io_msix_fifo_handle, 0, sp->desc[i], | 7052 | s2io_msix_fifo_handle, 0, |
6995 | sp->s2io_entries[i].arg); | 7053 | sp->desc[i], |
6996 | /* If either data or addr is zero print it */ | 7054 | sp->s2io_entries[i].arg); |
6997 | if(!(sp->msix_info[i].addr && | 7055 | |
6998 | sp->msix_info[i].data)) { | ||
6999 | DBG_PRINT(ERR_DBG, "%s @ Addr:0x%llx " | ||
7000 | "Data:0x%llx\n",sp->desc[i], | ||
7001 | (unsigned long long) | ||
7002 | sp->msix_info[i].addr, | ||
7003 | (unsigned long long) | ||
7004 | sp->msix_info[i].data); | ||
7005 | } else { | ||
7006 | msix_tx_cnt++; | ||
7007 | } | 7056 | } |
7008 | } else { | 7057 | /* if either data or addr is zero print it. */ |
7009 | sprintf(sp->desc[i], "%s:MSI-X-%d-RX", | 7058 | if (!(sp->msix_info[i].addr && |
7010 | dev->name, i); | ||
7011 | err = request_irq(sp->entries[i].vector, | ||
7012 | s2io_msix_ring_handle, 0, sp->desc[i], | ||
7013 | sp->s2io_entries[i].arg); | ||
7014 | /* If either data or addr is zero print it */ | ||
7015 | if(!(sp->msix_info[i].addr && | ||
7016 | sp->msix_info[i].data)) { | 7059 | sp->msix_info[i].data)) { |
7017 | DBG_PRINT(ERR_DBG, "%s @ Addr:0x%llx " | 7060 | DBG_PRINT(ERR_DBG, |
7018 | "Data:0x%llx\n",sp->desc[i], | 7061 | "%s @Addr:0x%llx Data:0x%llx\n", |
7062 | sp->desc[i], | ||
7019 | (unsigned long long) | 7063 | (unsigned long long) |
7020 | sp->msix_info[i].addr, | 7064 | sp->msix_info[i].addr, |
7021 | (unsigned long long) | 7065 | (unsigned long long) |
7022 | sp->msix_info[i].data); | 7066 | ntohl(sp->msix_info[i].data)); |
7023 | } else { | 7067 | } else |
7024 | msix_rx_cnt++; | 7068 | msix_rx_cnt++; |
7069 | if (err) { | ||
7070 | remove_msix_isr(sp); | ||
7071 | |||
7072 | DBG_PRINT(ERR_DBG, | ||
7073 | "%s:MSI-X-%d registration " | ||
7074 | "failed\n", dev->name, i); | ||
7075 | |||
7076 | DBG_PRINT(ERR_DBG, | ||
7077 | "%s: Defaulting to INTA\n", | ||
7078 | dev->name); | ||
7079 | sp->config.intr_type = INTA; | ||
7080 | break; | ||
7025 | } | 7081 | } |
7082 | sp->s2io_entries[i].in_use = | ||
7083 | MSIX_REGISTERED_SUCCESS; | ||
7026 | } | 7084 | } |
7027 | if (err) { | ||
7028 | remove_msix_isr(sp); | ||
7029 | DBG_PRINT(ERR_DBG,"%s:MSI-X-%d registration " | ||
7030 | "failed\n", dev->name, i); | ||
7031 | DBG_PRINT(ERR_DBG, "%s: defaulting to INTA\n", | ||
7032 | dev->name); | ||
7033 | sp->config.intr_type = INTA; | ||
7034 | break; | ||
7035 | } | ||
7036 | sp->s2io_entries[i].in_use = MSIX_REGISTERED_SUCCESS; | ||
7037 | } | 7085 | } |
7038 | if (!err) { | 7086 | if (!err) { |
7039 | printk(KERN_INFO "MSI-X-TX %d entries enabled\n", | ||
7040 | msix_tx_cnt); | ||
7041 | printk(KERN_INFO "MSI-X-RX %d entries enabled\n", | 7087 | printk(KERN_INFO "MSI-X-RX %d entries enabled\n", |
7042 | msix_rx_cnt); | 7088 | --msix_rx_cnt); |
7089 | DBG_PRINT(INFO_DBG, "MSI-X-TX entries enabled" | ||
7090 | " through alarm vector\n"); | ||
7043 | } | 7091 | } |
7044 | } | 7092 | } |
7045 | if (sp->config.intr_type == INTA) { | 7093 | if (sp->config.intr_type == INTA) { |
@@ -7080,8 +7128,15 @@ static void do_s2io_card_down(struct s2io_nic * sp, int do_io) | |||
7080 | clear_bit(__S2IO_STATE_CARD_UP, &sp->state); | 7128 | clear_bit(__S2IO_STATE_CARD_UP, &sp->state); |
7081 | 7129 | ||
7082 | /* Disable napi */ | 7130 | /* Disable napi */ |
7083 | if (config->napi) | 7131 | if (sp->config.napi) { |
7084 | napi_disable(&sp->napi); | 7132 | int off = 0; |
7133 | if (config->intr_type == MSI_X) { | ||
7134 | for (; off < sp->config.rx_ring_num; off++) | ||
7135 | napi_disable(&sp->mac_control.rings[off].napi); | ||
7136 | } | ||
7137 | else | ||
7138 | napi_disable(&sp->napi); | ||
7139 | } | ||
7085 | 7140 | ||
7086 | /* disable Tx and Rx traffic on the NIC */ | 7141 | /* disable Tx and Rx traffic on the NIC */ |
7087 | if (do_io) | 7142 | if (do_io) |
@@ -7173,8 +7228,15 @@ static int s2io_card_up(struct s2io_nic * sp) | |||
7173 | } | 7228 | } |
7174 | 7229 | ||
7175 | /* Initialise napi */ | 7230 | /* Initialise napi */ |
7176 | if (config->napi) | 7231 | if (config->napi) { |
7177 | napi_enable(&sp->napi); | 7232 | int i; |
7233 | if (config->intr_type == MSI_X) { | ||
7234 | for (i = 0; i < sp->config.rx_ring_num; i++) | ||
7235 | napi_enable(&sp->mac_control.rings[i].napi); | ||
7236 | } else { | ||
7237 | napi_enable(&sp->napi); | ||
7238 | } | ||
7239 | } | ||
7178 | 7240 | ||
7179 | /* Maintain the state prior to the open */ | 7241 | /* Maintain the state prior to the open */ |
7180 | if (sp->promisc_flg) | 7242 | if (sp->promisc_flg) |
@@ -7217,7 +7279,7 @@ static int s2io_card_up(struct s2io_nic * sp) | |||
7217 | /* Enable select interrupts */ | 7279 | /* Enable select interrupts */ |
7218 | en_dis_err_alarms(sp, ENA_ALL_INTRS, ENABLE_INTRS); | 7280 | en_dis_err_alarms(sp, ENA_ALL_INTRS, ENABLE_INTRS); |
7219 | if (sp->config.intr_type != INTA) | 7281 | if (sp->config.intr_type != INTA) |
7220 | en_dis_able_nic_intrs(sp, ENA_ALL_INTRS, DISABLE_INTRS); | 7282 | en_dis_able_nic_intrs(sp, TX_TRAFFIC_INTR, ENABLE_INTRS); |
7221 | else { | 7283 | else { |
7222 | interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR; | 7284 | interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR; |
7223 | interruptible |= TX_PIC_INTR; | 7285 | interruptible |= TX_PIC_INTR; |
@@ -7615,9 +7677,6 @@ static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type, | |||
7615 | rx_ring_num = MAX_RX_RINGS; | 7677 | rx_ring_num = MAX_RX_RINGS; |
7616 | } | 7678 | } |
7617 | 7679 | ||
7618 | if (*dev_intr_type != INTA) | ||
7619 | napi = 0; | ||
7620 | |||
7621 | if ((*dev_intr_type != INTA) && (*dev_intr_type != MSI_X)) { | 7680 | if ((*dev_intr_type != INTA) && (*dev_intr_type != MSI_X)) { |
7622 | DBG_PRINT(ERR_DBG, "s2io: Wrong intr_type requested. " | 7681 | DBG_PRINT(ERR_DBG, "s2io: Wrong intr_type requested. " |
7623 | "Defaulting to INTA\n"); | 7682 | "Defaulting to INTA\n"); |
@@ -7918,8 +7977,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
7918 | * will use eth_mac_addr() for dev->set_mac_address | 7977 | * will use eth_mac_addr() for dev->set_mac_address |
7919 | * mac address will be set every time dev->open() is called | 7978 | * mac address will be set every time dev->open() is called |
7920 | */ | 7979 | */ |
7921 | netif_napi_add(dev, &sp->napi, s2io_poll, 32); | ||
7922 | |||
7923 | #ifdef CONFIG_NET_POLL_CONTROLLER | 7980 | #ifdef CONFIG_NET_POLL_CONTROLLER |
7924 | dev->poll_controller = s2io_netpoll; | 7981 | dev->poll_controller = s2io_netpoll; |
7925 | #endif | 7982 | #endif |
@@ -7963,6 +8020,32 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
7963 | } | 8020 | } |
7964 | } | 8021 | } |
7965 | 8022 | ||
8023 | if (sp->config.intr_type == MSI_X) { | ||
8024 | sp->num_entries = config->rx_ring_num + 1; | ||
8025 | ret = s2io_enable_msi_x(sp); | ||
8026 | |||
8027 | if (!ret) { | ||
8028 | ret = s2io_test_msi(sp); | ||
8029 | /* rollback MSI-X, will re-enable during add_isr() */ | ||
8030 | remove_msix_isr(sp); | ||
8031 | } | ||
8032 | if (ret) { | ||
8033 | |||
8034 | DBG_PRINT(ERR_DBG, | ||
8035 | "%s: MSI-X requested but failed to enable\n", | ||
8036 | dev->name); | ||
8037 | sp->config.intr_type = INTA; | ||
8038 | } | ||
8039 | } | ||
8040 | |||
8041 | if (config->intr_type == MSI_X) { | ||
8042 | for (i = 0; i < config->rx_ring_num ; i++) | ||
8043 | netif_napi_add(dev, &mac_control->rings[i].napi, | ||
8044 | s2io_poll_msix, 64); | ||
8045 | } else { | ||
8046 | netif_napi_add(dev, &sp->napi, s2io_poll_inta, 64); | ||
8047 | } | ||
8048 | |||
7966 | /* Not needed for Herc */ | 8049 | /* Not needed for Herc */ |
7967 | if (sp->device_type & XFRAME_I_DEVICE) { | 8050 | if (sp->device_type & XFRAME_I_DEVICE) { |
7968 | /* | 8051 | /* |
@@ -8013,6 +8096,11 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
8013 | /* store mac addresses from CAM to s2io_nic structure */ | 8096 | /* store mac addresses from CAM to s2io_nic structure */ |
8014 | do_s2io_store_unicast_mc(sp); | 8097 | do_s2io_store_unicast_mc(sp); |
8015 | 8098 | ||
8099 | /* Configure MSIX vector for number of rings configured plus one */ | ||
8100 | if ((sp->device_type == XFRAME_II_DEVICE) && | ||
8101 | (config->intr_type == MSI_X)) | ||
8102 | sp->num_entries = config->rx_ring_num + 1; | ||
8103 | |||
8016 | /* Store the values of the MSIX table in the s2io_nic structure */ | 8104 | /* Store the values of the MSIX table in the s2io_nic structure */ |
8017 | store_xmsi_data(sp); | 8105 | store_xmsi_data(sp); |
8018 | /* reset Nic and bring it to known state */ | 8106 | /* reset Nic and bring it to known state */ |
@@ -8078,8 +8166,14 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
8078 | break; | 8166 | break; |
8079 | } | 8167 | } |
8080 | 8168 | ||
8081 | if (napi) | 8169 | switch (sp->config.napi) { |
8170 | case 0: | ||
8171 | DBG_PRINT(ERR_DBG, "%s: NAPI disabled\n", dev->name); | ||
8172 | break; | ||
8173 | case 1: | ||
8082 | DBG_PRINT(ERR_DBG, "%s: NAPI enabled\n", dev->name); | 8174 | DBG_PRINT(ERR_DBG, "%s: NAPI enabled\n", dev->name); |
8175 | break; | ||
8176 | } | ||
8083 | 8177 | ||
8084 | DBG_PRINT(ERR_DBG, "%s: Using %d Tx fifo(s)\n", dev->name, | 8178 | DBG_PRINT(ERR_DBG, "%s: Using %d Tx fifo(s)\n", dev->name, |
8085 | sp->config.tx_fifo_num); | 8179 | sp->config.tx_fifo_num); |
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h index 0709ebae9139..4706f7f9acb6 100644 --- a/drivers/net/s2io.h +++ b/drivers/net/s2io.h | |||
@@ -706,7 +706,7 @@ struct ring_info { | |||
706 | /* per-ring buffer counter */ | 706 | /* per-ring buffer counter */ |
707 | u32 rx_bufs_left; | 707 | u32 rx_bufs_left; |
708 | 708 | ||
709 | #define MAX_LRO_SESSIONS 32 | 709 | #define MAX_LRO_SESSIONS 32 |
710 | struct lro lro0_n[MAX_LRO_SESSIONS]; | 710 | struct lro lro0_n[MAX_LRO_SESSIONS]; |
711 | u8 lro; | 711 | u8 lro; |
712 | 712 | ||
@@ -725,6 +725,11 @@ struct ring_info { | |||
725 | /* copy of sp->pdev pointer */ | 725 | /* copy of sp->pdev pointer */ |
726 | struct pci_dev *pdev; | 726 | struct pci_dev *pdev; |
727 | 727 | ||
728 | /* Per ring napi struct */ | ||
729 | struct napi_struct napi; | ||
730 | |||
731 | unsigned long interrupt_count; | ||
732 | |||
728 | /* | 733 | /* |
729 | * Place holders for the virtual and physical addresses of | 734 | * Place holders for the virtual and physical addresses of |
730 | * all the Rx Blocks | 735 | * all the Rx Blocks |
@@ -841,7 +846,7 @@ struct usr_addr { | |||
841 | * Structure to keep track of the MSI-X vectors and the corresponding | 846 | * Structure to keep track of the MSI-X vectors and the corresponding |
842 | * argument registered against each vector | 847 | * argument registered against each vector |
843 | */ | 848 | */ |
844 | #define MAX_REQUESTED_MSI_X 17 | 849 | #define MAX_REQUESTED_MSI_X 9 |
845 | struct s2io_msix_entry | 850 | struct s2io_msix_entry |
846 | { | 851 | { |
847 | u16 vector; | 852 | u16 vector; |
@@ -849,8 +854,8 @@ struct s2io_msix_entry | |||
849 | void *arg; | 854 | void *arg; |
850 | 855 | ||
851 | u8 type; | 856 | u8 type; |
852 | #define MSIX_FIFO_TYPE 1 | 857 | #define MSIX_ALARM_TYPE 1 |
853 | #define MSIX_RING_TYPE 2 | 858 | #define MSIX_RING_TYPE 2 |
854 | 859 | ||
855 | u8 in_use; | 860 | u8 in_use; |
856 | #define MSIX_REGISTERED_SUCCESS 0xAA | 861 | #define MSIX_REGISTERED_SUCCESS 0xAA |
@@ -877,7 +882,6 @@ struct s2io_nic { | |||
877 | */ | 882 | */ |
878 | int pkts_to_process; | 883 | int pkts_to_process; |
879 | struct net_device *dev; | 884 | struct net_device *dev; |
880 | struct napi_struct napi; | ||
881 | struct mac_info mac_control; | 885 | struct mac_info mac_control; |
882 | struct config_param config; | 886 | struct config_param config; |
883 | struct pci_dev *pdev; | 887 | struct pci_dev *pdev; |
@@ -948,6 +952,7 @@ struct s2io_nic { | |||
948 | */ | 952 | */ |
949 | u8 other_fifo_idx; | 953 | u8 other_fifo_idx; |
950 | 954 | ||
955 | struct napi_struct napi; | ||
951 | /* after blink, the adapter must be restored with original | 956 | /* after blink, the adapter must be restored with original |
952 | * values. | 957 | * values. |
953 | */ | 958 | */ |
@@ -962,6 +967,7 @@ struct s2io_nic { | |||
962 | unsigned long long start_time; | 967 | unsigned long long start_time; |
963 | struct vlan_group *vlgrp; | 968 | struct vlan_group *vlgrp; |
964 | #define MSIX_FLG 0xA5 | 969 | #define MSIX_FLG 0xA5 |
970 | int num_entries; | ||
965 | struct msix_entry *entries; | 971 | struct msix_entry *entries; |
966 | int msi_detected; | 972 | int msi_detected; |
967 | wait_queue_head_t msi_wait; | 973 | wait_queue_head_t msi_wait; |
@@ -982,6 +988,7 @@ struct s2io_nic { | |||
982 | u16 lro_max_aggr_per_sess; | 988 | u16 lro_max_aggr_per_sess; |
983 | volatile unsigned long state; | 989 | volatile unsigned long state; |
984 | u64 general_int_mask; | 990 | u64 general_int_mask; |
991 | |||
985 | #define VPD_STRING_LEN 80 | 992 | #define VPD_STRING_LEN 80 |
986 | u8 product_name[VPD_STRING_LEN]; | 993 | u8 product_name[VPD_STRING_LEN]; |
987 | u8 serial_num[VPD_STRING_LEN]; | 994 | u8 serial_num[VPD_STRING_LEN]; |
@@ -1103,7 +1110,7 @@ static void __devexit s2io_rem_nic(struct pci_dev *pdev); | |||
1103 | static int init_shared_mem(struct s2io_nic *sp); | 1110 | static int init_shared_mem(struct s2io_nic *sp); |
1104 | static void free_shared_mem(struct s2io_nic *sp); | 1111 | static void free_shared_mem(struct s2io_nic *sp); |
1105 | static int init_nic(struct s2io_nic *nic); | 1112 | static int init_nic(struct s2io_nic *nic); |
1106 | static void rx_intr_handler(struct ring_info *ring_data); | 1113 | static int rx_intr_handler(struct ring_info *ring_data, int budget); |
1107 | static void tx_intr_handler(struct fifo_info *fifo_data); | 1114 | static void tx_intr_handler(struct fifo_info *fifo_data); |
1108 | static void s2io_handle_errors(void * dev_id); | 1115 | static void s2io_handle_errors(void * dev_id); |
1109 | 1116 | ||
@@ -1114,7 +1121,8 @@ static void s2io_set_multicast(struct net_device *dev); | |||
1114 | static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp); | 1121 | static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp); |
1115 | static void s2io_link(struct s2io_nic * sp, int link); | 1122 | static void s2io_link(struct s2io_nic * sp, int link); |
1116 | static void s2io_reset(struct s2io_nic * sp); | 1123 | static void s2io_reset(struct s2io_nic * sp); |
1117 | static int s2io_poll(struct napi_struct *napi, int budget); | 1124 | static int s2io_poll_msix(struct napi_struct *napi, int budget); |
1125 | static int s2io_poll_inta(struct napi_struct *napi, int budget); | ||
1118 | static void s2io_init_pci(struct s2io_nic * sp); | 1126 | static void s2io_init_pci(struct s2io_nic * sp); |
1119 | static int do_s2io_prog_unicast(struct net_device *dev, u8 *addr); | 1127 | static int do_s2io_prog_unicast(struct net_device *dev, u8 *addr); |
1120 | static void s2io_alarm_handle(unsigned long data); | 1128 | static void s2io_alarm_handle(unsigned long data); |
diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c index 888b7dec9866..33bb18f810fb 100644 --- a/drivers/net/sb1250-mac.c +++ b/drivers/net/sb1250-mac.c | |||
@@ -179,8 +179,7 @@ enum sbmac_state { | |||
179 | #define SBMAC_MAX_TXDESCR 256 | 179 | #define SBMAC_MAX_TXDESCR 256 |
180 | #define SBMAC_MAX_RXDESCR 256 | 180 | #define SBMAC_MAX_RXDESCR 256 |
181 | 181 | ||
182 | #define ETHER_ALIGN 2 | 182 | #define ETHER_ADDR_LEN 6 |
183 | #define ETHER_ADDR_LEN 6 | ||
184 | #define ENET_PACKET_SIZE 1518 | 183 | #define ENET_PACKET_SIZE 1518 |
185 | /*#define ENET_PACKET_SIZE 9216 */ | 184 | /*#define ENET_PACKET_SIZE 9216 */ |
186 | 185 | ||
@@ -262,8 +261,6 @@ struct sbmac_softc { | |||
262 | spinlock_t sbm_lock; /* spin lock */ | 261 | spinlock_t sbm_lock; /* spin lock */ |
263 | int sbm_devflags; /* current device flags */ | 262 | int sbm_devflags; /* current device flags */ |
264 | 263 | ||
265 | int sbm_buffersize; | ||
266 | |||
267 | /* | 264 | /* |
268 | * Controller-specific things | 265 | * Controller-specific things |
269 | */ | 266 | */ |
@@ -305,10 +302,11 @@ struct sbmac_softc { | |||
305 | static void sbdma_initctx(struct sbmacdma *d, struct sbmac_softc *s, int chan, | 302 | static void sbdma_initctx(struct sbmacdma *d, struct sbmac_softc *s, int chan, |
306 | int txrx, int maxdescr); | 303 | int txrx, int maxdescr); |
307 | static void sbdma_channel_start(struct sbmacdma *d, int rxtx); | 304 | static void sbdma_channel_start(struct sbmacdma *d, int rxtx); |
308 | static int sbdma_add_rcvbuffer(struct sbmacdma *d, struct sk_buff *m); | 305 | static int sbdma_add_rcvbuffer(struct sbmac_softc *sc, struct sbmacdma *d, |
306 | struct sk_buff *m); | ||
309 | static int sbdma_add_txbuffer(struct sbmacdma *d, struct sk_buff *m); | 307 | static int sbdma_add_txbuffer(struct sbmacdma *d, struct sk_buff *m); |
310 | static void sbdma_emptyring(struct sbmacdma *d); | 308 | static void sbdma_emptyring(struct sbmacdma *d); |
311 | static void sbdma_fillring(struct sbmacdma *d); | 309 | static void sbdma_fillring(struct sbmac_softc *sc, struct sbmacdma *d); |
312 | static int sbdma_rx_process(struct sbmac_softc *sc, struct sbmacdma *d, | 310 | static int sbdma_rx_process(struct sbmac_softc *sc, struct sbmacdma *d, |
313 | int work_to_do, int poll); | 311 | int work_to_do, int poll); |
314 | static void sbdma_tx_process(struct sbmac_softc *sc, struct sbmacdma *d, | 312 | static void sbdma_tx_process(struct sbmac_softc *sc, struct sbmacdma *d, |
@@ -777,16 +775,13 @@ static void sbdma_channel_stop(struct sbmacdma *d) | |||
777 | d->sbdma_remptr = NULL; | 775 | d->sbdma_remptr = NULL; |
778 | } | 776 | } |
779 | 777 | ||
780 | static void sbdma_align_skb(struct sk_buff *skb,int power2,int offset) | 778 | static inline void sbdma_align_skb(struct sk_buff *skb, |
779 | unsigned int power2, unsigned int offset) | ||
781 | { | 780 | { |
782 | unsigned long addr; | 781 | unsigned char *addr = skb->data; |
783 | unsigned long newaddr; | 782 | unsigned char *newaddr = PTR_ALIGN(addr, power2); |
784 | |||
785 | addr = (unsigned long) skb->data; | ||
786 | |||
787 | newaddr = (addr + power2 - 1) & ~(power2 - 1); | ||
788 | 783 | ||
789 | skb_reserve(skb,newaddr-addr+offset); | 784 | skb_reserve(skb, newaddr - addr + offset); |
790 | } | 785 | } |
791 | 786 | ||
792 | 787 | ||
@@ -797,7 +792,8 @@ static void sbdma_align_skb(struct sk_buff *skb,int power2,int offset) | |||
797 | * this queues a buffer for inbound packets. | 792 | * this queues a buffer for inbound packets. |
798 | * | 793 | * |
799 | * Input parameters: | 794 | * Input parameters: |
800 | * d - DMA channel descriptor | 795 | * sc - softc structure |
796 | * d - DMA channel descriptor | ||
801 | * sb - sk_buff to add, or NULL if we should allocate one | 797 | * sb - sk_buff to add, or NULL if we should allocate one |
802 | * | 798 | * |
803 | * Return value: | 799 | * Return value: |
@@ -806,8 +802,10 @@ static void sbdma_align_skb(struct sk_buff *skb,int power2,int offset) | |||
806 | ********************************************************************* */ | 802 | ********************************************************************* */ |
807 | 803 | ||
808 | 804 | ||
809 | static int sbdma_add_rcvbuffer(struct sbmacdma *d, struct sk_buff *sb) | 805 | static int sbdma_add_rcvbuffer(struct sbmac_softc *sc, struct sbmacdma *d, |
806 | struct sk_buff *sb) | ||
810 | { | 807 | { |
808 | struct net_device *dev = sc->sbm_dev; | ||
811 | struct sbdmadscr *dsc; | 809 | struct sbdmadscr *dsc; |
812 | struct sbdmadscr *nextdsc; | 810 | struct sbdmadscr *nextdsc; |
813 | struct sk_buff *sb_new = NULL; | 811 | struct sk_buff *sb_new = NULL; |
@@ -848,14 +846,16 @@ static int sbdma_add_rcvbuffer(struct sbmacdma *d, struct sk_buff *sb) | |||
848 | */ | 846 | */ |
849 | 847 | ||
850 | if (sb == NULL) { | 848 | if (sb == NULL) { |
851 | sb_new = dev_alloc_skb(ENET_PACKET_SIZE + SMP_CACHE_BYTES * 2 + ETHER_ALIGN); | 849 | sb_new = netdev_alloc_skb(dev, ENET_PACKET_SIZE + |
850 | SMP_CACHE_BYTES * 2 + | ||
851 | NET_IP_ALIGN); | ||
852 | if (sb_new == NULL) { | 852 | if (sb_new == NULL) { |
853 | pr_info("%s: sk_buff allocation failed\n", | 853 | pr_info("%s: sk_buff allocation failed\n", |
854 | d->sbdma_eth->sbm_dev->name); | 854 | d->sbdma_eth->sbm_dev->name); |
855 | return -ENOBUFS; | 855 | return -ENOBUFS; |
856 | } | 856 | } |
857 | 857 | ||
858 | sbdma_align_skb(sb_new, SMP_CACHE_BYTES, ETHER_ALIGN); | 858 | sbdma_align_skb(sb_new, SMP_CACHE_BYTES, NET_IP_ALIGN); |
859 | } | 859 | } |
860 | else { | 860 | else { |
861 | sb_new = sb; | 861 | sb_new = sb; |
@@ -874,10 +874,10 @@ static int sbdma_add_rcvbuffer(struct sbmacdma *d, struct sk_buff *sb) | |||
874 | * Do not interrupt per DMA transfer. | 874 | * Do not interrupt per DMA transfer. |
875 | */ | 875 | */ |
876 | dsc->dscr_a = virt_to_phys(sb_new->data) | | 876 | dsc->dscr_a = virt_to_phys(sb_new->data) | |
877 | V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize+ETHER_ALIGN)) | 0; | 877 | V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize + NET_IP_ALIGN)) | 0; |
878 | #else | 878 | #else |
879 | dsc->dscr_a = virt_to_phys(sb_new->data) | | 879 | dsc->dscr_a = virt_to_phys(sb_new->data) | |
880 | V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize+ETHER_ALIGN)) | | 880 | V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize + NET_IP_ALIGN)) | |
881 | M_DMA_DSCRA_INTERRUPT; | 881 | M_DMA_DSCRA_INTERRUPT; |
882 | #endif | 882 | #endif |
883 | 883 | ||
@@ -1032,18 +1032,19 @@ static void sbdma_emptyring(struct sbmacdma *d) | |||
1032 | * with sk_buffs | 1032 | * with sk_buffs |
1033 | * | 1033 | * |
1034 | * Input parameters: | 1034 | * Input parameters: |
1035 | * d - DMA channel | 1035 | * sc - softc structure |
1036 | * d - DMA channel | ||
1036 | * | 1037 | * |
1037 | * Return value: | 1038 | * Return value: |
1038 | * nothing | 1039 | * nothing |
1039 | ********************************************************************* */ | 1040 | ********************************************************************* */ |
1040 | 1041 | ||
1041 | static void sbdma_fillring(struct sbmacdma *d) | 1042 | static void sbdma_fillring(struct sbmac_softc *sc, struct sbmacdma *d) |
1042 | { | 1043 | { |
1043 | int idx; | 1044 | int idx; |
1044 | 1045 | ||
1045 | for (idx = 0; idx < SBMAC_MAX_RXDESCR-1; idx++) { | 1046 | for (idx = 0; idx < SBMAC_MAX_RXDESCR - 1; idx++) { |
1046 | if (sbdma_add_rcvbuffer(d,NULL) != 0) | 1047 | if (sbdma_add_rcvbuffer(sc, d, NULL) != 0) |
1047 | break; | 1048 | break; |
1048 | } | 1049 | } |
1049 | } | 1050 | } |
@@ -1159,10 +1160,11 @@ again: | |||
1159 | * packet and put it right back on the receive ring. | 1160 | * packet and put it right back on the receive ring. |
1160 | */ | 1161 | */ |
1161 | 1162 | ||
1162 | if (unlikely (sbdma_add_rcvbuffer(d,NULL) == | 1163 | if (unlikely(sbdma_add_rcvbuffer(sc, d, NULL) == |
1163 | -ENOBUFS)) { | 1164 | -ENOBUFS)) { |
1164 | dev->stats.rx_dropped++; | 1165 | dev->stats.rx_dropped++; |
1165 | sbdma_add_rcvbuffer(d,sb); /* re-add old buffer */ | 1166 | /* Re-add old buffer */ |
1167 | sbdma_add_rcvbuffer(sc, d, sb); | ||
1166 | /* No point in continuing at the moment */ | 1168 | /* No point in continuing at the moment */ |
1167 | printk(KERN_ERR "dropped packet (1)\n"); | 1169 | printk(KERN_ERR "dropped packet (1)\n"); |
1168 | d->sbdma_remptr = SBDMA_NEXTBUF(d,sbdma_remptr); | 1170 | d->sbdma_remptr = SBDMA_NEXTBUF(d,sbdma_remptr); |
@@ -1212,7 +1214,7 @@ again: | |||
1212 | * put it back on the receive ring. | 1214 | * put it back on the receive ring. |
1213 | */ | 1215 | */ |
1214 | dev->stats.rx_errors++; | 1216 | dev->stats.rx_errors++; |
1215 | sbdma_add_rcvbuffer(d,sb); | 1217 | sbdma_add_rcvbuffer(sc, d, sb); |
1216 | } | 1218 | } |
1217 | 1219 | ||
1218 | 1220 | ||
@@ -1570,7 +1572,7 @@ static void sbmac_channel_start(struct sbmac_softc *s) | |||
1570 | * Fill the receive ring | 1572 | * Fill the receive ring |
1571 | */ | 1573 | */ |
1572 | 1574 | ||
1573 | sbdma_fillring(&(s->sbm_rxdma)); | 1575 | sbdma_fillring(s, &(s->sbm_rxdma)); |
1574 | 1576 | ||
1575 | /* | 1577 | /* |
1576 | * Turn on the rest of the bits in the enable register | 1578 | * Turn on the rest of the bits in the enable register |
@@ -2312,13 +2314,6 @@ static int sbmac_init(struct platform_device *pldev, long long base) | |||
2312 | dev->dev_addr[i] = eaddr[i]; | 2314 | dev->dev_addr[i] = eaddr[i]; |
2313 | } | 2315 | } |
2314 | 2316 | ||
2315 | |||
2316 | /* | ||
2317 | * Init packet size | ||
2318 | */ | ||
2319 | |||
2320 | sc->sbm_buffersize = ENET_PACKET_SIZE + SMP_CACHE_BYTES * 2 + ETHER_ALIGN; | ||
2321 | |||
2322 | /* | 2317 | /* |
2323 | * Initialize context (get pointers to registers and stuff), then | 2318 | * Initialize context (get pointers to registers and stuff), then |
2324 | * allocate the memory for the descriptor tables. | 2319 | * allocate the memory for the descriptor tables. |
diff --git a/drivers/net/sc92031.c b/drivers/net/sc92031.c index f64a860029b7..61955f8d8011 100644 --- a/drivers/net/sc92031.c +++ b/drivers/net/sc92031.c | |||
@@ -953,9 +953,6 @@ static int sc92031_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
953 | unsigned entry; | 953 | unsigned entry; |
954 | u32 tx_status; | 954 | u32 tx_status; |
955 | 955 | ||
956 | if (skb_padto(skb, ETH_ZLEN)) | ||
957 | return NETDEV_TX_OK; | ||
958 | |||
959 | if (unlikely(skb->len > TX_BUF_SIZE)) { | 956 | if (unlikely(skb->len > TX_BUF_SIZE)) { |
960 | dev->stats.tx_dropped++; | 957 | dev->stats.tx_dropped++; |
961 | goto out; | 958 | goto out; |
@@ -975,6 +972,11 @@ static int sc92031_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
975 | skb_copy_and_csum_dev(skb, priv->tx_bufs + entry * TX_BUF_SIZE); | 972 | skb_copy_and_csum_dev(skb, priv->tx_bufs + entry * TX_BUF_SIZE); |
976 | 973 | ||
977 | len = skb->len; | 974 | len = skb->len; |
975 | if (len < ETH_ZLEN) { | ||
976 | memset(priv->tx_bufs + entry * TX_BUF_SIZE + len, | ||
977 | 0, ETH_ZLEN - len); | ||
978 | len = ETH_ZLEN; | ||
979 | } | ||
978 | 980 | ||
979 | wmb(); | 981 | wmb(); |
980 | 982 | ||
diff --git a/drivers/net/sfc/bitfield.h b/drivers/net/sfc/bitfield.h index 2806201644cc..2c79d27404e0 100644 --- a/drivers/net/sfc/bitfield.h +++ b/drivers/net/sfc/bitfield.h | |||
@@ -483,7 +483,7 @@ typedef union efx_oword { | |||
483 | #endif | 483 | #endif |
484 | 484 | ||
485 | #define EFX_SET_OWORD_FIELD_VER(efx, oword, field, value) do { \ | 485 | #define EFX_SET_OWORD_FIELD_VER(efx, oword, field, value) do { \ |
486 | if (FALCON_REV(efx) >= FALCON_REV_B0) { \ | 486 | if (falcon_rev(efx) >= FALCON_REV_B0) { \ |
487 | EFX_SET_OWORD_FIELD((oword), field##_B0, (value)); \ | 487 | EFX_SET_OWORD_FIELD((oword), field##_B0, (value)); \ |
488 | } else { \ | 488 | } else { \ |
489 | EFX_SET_OWORD_FIELD((oword), field##_A1, (value)); \ | 489 | EFX_SET_OWORD_FIELD((oword), field##_A1, (value)); \ |
@@ -491,7 +491,7 @@ typedef union efx_oword { | |||
491 | } while (0) | 491 | } while (0) |
492 | 492 | ||
493 | #define EFX_QWORD_FIELD_VER(efx, qword, field) \ | 493 | #define EFX_QWORD_FIELD_VER(efx, qword, field) \ |
494 | (FALCON_REV(efx) >= FALCON_REV_B0 ? \ | 494 | (falcon_rev(efx) >= FALCON_REV_B0 ? \ |
495 | EFX_QWORD_FIELD((qword), field##_B0) : \ | 495 | EFX_QWORD_FIELD((qword), field##_B0) : \ |
496 | EFX_QWORD_FIELD((qword), field##_A1)) | 496 | EFX_QWORD_FIELD((qword), field##_A1)) |
497 | 497 | ||
@@ -501,8 +501,5 @@ typedef union efx_oword { | |||
501 | #define DMA_ADDR_T_WIDTH (8 * sizeof(dma_addr_t)) | 501 | #define DMA_ADDR_T_WIDTH (8 * sizeof(dma_addr_t)) |
502 | #define EFX_DMA_TYPE_WIDTH(width) \ | 502 | #define EFX_DMA_TYPE_WIDTH(width) \ |
503 | (((width) < DMA_ADDR_T_WIDTH) ? (width) : DMA_ADDR_T_WIDTH) | 503 | (((width) < DMA_ADDR_T_WIDTH) ? (width) : DMA_ADDR_T_WIDTH) |
504 | #define EFX_DMA_MAX_MASK ((DMA_ADDR_T_WIDTH == 64) ? \ | ||
505 | ~((u64) 0) : ~((u32) 0)) | ||
506 | #define EFX_DMA_MASK(mask) ((mask) & EFX_DMA_MAX_MASK) | ||
507 | 504 | ||
508 | #endif /* EFX_BITFIELD_H */ | 505 | #endif /* EFX_BITFIELD_H */ |
diff --git a/drivers/net/sfc/boards.c b/drivers/net/sfc/boards.c index eecaa6d58584..7fc0328dc055 100644 --- a/drivers/net/sfc/boards.c +++ b/drivers/net/sfc/boards.c | |||
@@ -27,10 +27,8 @@ static void blink_led_timer(unsigned long context) | |||
27 | struct efx_blinker *bl = &efx->board_info.blinker; | 27 | struct efx_blinker *bl = &efx->board_info.blinker; |
28 | efx->board_info.set_fault_led(efx, bl->state); | 28 | efx->board_info.set_fault_led(efx, bl->state); |
29 | bl->state = !bl->state; | 29 | bl->state = !bl->state; |
30 | if (bl->resubmit) { | 30 | if (bl->resubmit) |
31 | bl->timer.expires = jiffies + BLINK_INTERVAL; | 31 | mod_timer(&bl->timer, jiffies + BLINK_INTERVAL); |
32 | add_timer(&bl->timer); | ||
33 | } | ||
34 | } | 32 | } |
35 | 33 | ||
36 | static void board_blink(struct efx_nic *efx, int blink) | 34 | static void board_blink(struct efx_nic *efx, int blink) |
@@ -44,8 +42,7 @@ static void board_blink(struct efx_nic *efx, int blink) | |||
44 | blinker->state = 0; | 42 | blinker->state = 0; |
45 | setup_timer(&blinker->timer, blink_led_timer, | 43 | setup_timer(&blinker->timer, blink_led_timer, |
46 | (unsigned long)efx); | 44 | (unsigned long)efx); |
47 | blinker->timer.expires = jiffies + BLINK_INTERVAL; | 45 | mod_timer(&blinker->timer, jiffies + BLINK_INTERVAL); |
48 | add_timer(&blinker->timer); | ||
49 | } else { | 46 | } else { |
50 | blinker->resubmit = 0; | 47 | blinker->resubmit = 0; |
51 | if (blinker->timer.function) | 48 | if (blinker->timer.function) |
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index 418f2e53a95b..449760642e31 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c | |||
@@ -199,11 +199,12 @@ static inline int efx_process_channel(struct efx_channel *channel, int rx_quota) | |||
199 | */ | 199 | */ |
200 | static inline void efx_channel_processed(struct efx_channel *channel) | 200 | static inline void efx_channel_processed(struct efx_channel *channel) |
201 | { | 201 | { |
202 | /* Write to EVQ_RPTR_REG. If a new event arrived in a race | 202 | /* The interrupt handler for this channel may set work_pending |
203 | * with finishing processing, a new interrupt will be raised. | 203 | * as soon as we acknowledge the events we've seen. Make sure |
204 | */ | 204 | * it's cleared before then. */ |
205 | channel->work_pending = 0; | 205 | channel->work_pending = 0; |
206 | smp_wmb(); /* Ensure channel updated before any new interrupt. */ | 206 | smp_wmb(); |
207 | |||
207 | falcon_eventq_read_ack(channel); | 208 | falcon_eventq_read_ack(channel); |
208 | } | 209 | } |
209 | 210 | ||
@@ -265,7 +266,7 @@ void efx_process_channel_now(struct efx_channel *channel) | |||
265 | napi_disable(&channel->napi_str); | 266 | napi_disable(&channel->napi_str); |
266 | 267 | ||
267 | /* Poll the channel */ | 268 | /* Poll the channel */ |
268 | (void) efx_process_channel(channel, efx->type->evq_size); | 269 | efx_process_channel(channel, efx->type->evq_size); |
269 | 270 | ||
270 | /* Ack the eventq. This may cause an interrupt to be generated | 271 | /* Ack the eventq. This may cause an interrupt to be generated |
271 | * when they are reenabled */ | 272 | * when they are reenabled */ |
@@ -317,26 +318,6 @@ static void efx_remove_eventq(struct efx_channel *channel) | |||
317 | * | 318 | * |
318 | *************************************************************************/ | 319 | *************************************************************************/ |
319 | 320 | ||
320 | /* Setup per-NIC RX buffer parameters. | ||
321 | * Calculate the rx buffer allocation parameters required to support | ||
322 | * the current MTU, including padding for header alignment and overruns. | ||
323 | */ | ||
324 | static void efx_calc_rx_buffer_params(struct efx_nic *efx) | ||
325 | { | ||
326 | unsigned int order, len; | ||
327 | |||
328 | len = (max(EFX_PAGE_IP_ALIGN, NET_IP_ALIGN) + | ||
329 | EFX_MAX_FRAME_LEN(efx->net_dev->mtu) + | ||
330 | efx->type->rx_buffer_padding); | ||
331 | |||
332 | /* Calculate page-order */ | ||
333 | for (order = 0; ((1u << order) * PAGE_SIZE) < len; ++order) | ||
334 | ; | ||
335 | |||
336 | efx->rx_buffer_len = len; | ||
337 | efx->rx_buffer_order = order; | ||
338 | } | ||
339 | |||
340 | static int efx_probe_channel(struct efx_channel *channel) | 321 | static int efx_probe_channel(struct efx_channel *channel) |
341 | { | 322 | { |
342 | struct efx_tx_queue *tx_queue; | 323 | struct efx_tx_queue *tx_queue; |
@@ -387,7 +368,14 @@ static int efx_init_channels(struct efx_nic *efx) | |||
387 | struct efx_channel *channel; | 368 | struct efx_channel *channel; |
388 | int rc = 0; | 369 | int rc = 0; |
389 | 370 | ||
390 | efx_calc_rx_buffer_params(efx); | 371 | /* Calculate the rx buffer allocation parameters required to |
372 | * support the current MTU, including padding for header | ||
373 | * alignment and overruns. | ||
374 | */ | ||
375 | efx->rx_buffer_len = (max(EFX_PAGE_IP_ALIGN, NET_IP_ALIGN) + | ||
376 | EFX_MAX_FRAME_LEN(efx->net_dev->mtu) + | ||
377 | efx->type->rx_buffer_padding); | ||
378 | efx->rx_buffer_order = get_order(efx->rx_buffer_len); | ||
391 | 379 | ||
392 | /* Initialise the channels */ | 380 | /* Initialise the channels */ |
393 | efx_for_each_channel(channel, efx) { | 381 | efx_for_each_channel(channel, efx) { |
@@ -440,9 +428,12 @@ static void efx_start_channel(struct efx_channel *channel) | |||
440 | netif_napi_add(channel->napi_dev, &channel->napi_str, | 428 | netif_napi_add(channel->napi_dev, &channel->napi_str, |
441 | efx_poll, napi_weight); | 429 | efx_poll, napi_weight); |
442 | 430 | ||
431 | /* The interrupt handler for this channel may set work_pending | ||
432 | * as soon as we enable it. Make sure it's cleared before | ||
433 | * then. Similarly, make sure it sees the enabled flag set. */ | ||
443 | channel->work_pending = 0; | 434 | channel->work_pending = 0; |
444 | channel->enabled = 1; | 435 | channel->enabled = 1; |
445 | smp_wmb(); /* ensure channel updated before first interrupt */ | 436 | smp_wmb(); |
446 | 437 | ||
447 | napi_enable(&channel->napi_str); | 438 | napi_enable(&channel->napi_str); |
448 | 439 | ||
@@ -704,7 +695,7 @@ static void efx_stop_port(struct efx_nic *efx) | |||
704 | mutex_unlock(&efx->mac_lock); | 695 | mutex_unlock(&efx->mac_lock); |
705 | 696 | ||
706 | /* Serialise against efx_set_multicast_list() */ | 697 | /* Serialise against efx_set_multicast_list() */ |
707 | if (NET_DEV_REGISTERED(efx)) { | 698 | if (efx_dev_registered(efx)) { |
708 | netif_tx_lock_bh(efx->net_dev); | 699 | netif_tx_lock_bh(efx->net_dev); |
709 | netif_tx_unlock_bh(efx->net_dev); | 700 | netif_tx_unlock_bh(efx->net_dev); |
710 | } | 701 | } |
@@ -791,22 +782,23 @@ static int efx_init_io(struct efx_nic *efx) | |||
791 | efx->membase = ioremap_nocache(efx->membase_phys, | 782 | efx->membase = ioremap_nocache(efx->membase_phys, |
792 | efx->type->mem_map_size); | 783 | efx->type->mem_map_size); |
793 | if (!efx->membase) { | 784 | if (!efx->membase) { |
794 | EFX_ERR(efx, "could not map memory BAR %d at %lx+%x\n", | 785 | EFX_ERR(efx, "could not map memory BAR %d at %llx+%x\n", |
795 | efx->type->mem_bar, efx->membase_phys, | 786 | efx->type->mem_bar, |
787 | (unsigned long long)efx->membase_phys, | ||
796 | efx->type->mem_map_size); | 788 | efx->type->mem_map_size); |
797 | rc = -ENOMEM; | 789 | rc = -ENOMEM; |
798 | goto fail4; | 790 | goto fail4; |
799 | } | 791 | } |
800 | EFX_LOG(efx, "memory BAR %u at %lx+%x (virtual %p)\n", | 792 | EFX_LOG(efx, "memory BAR %u at %llx+%x (virtual %p)\n", |
801 | efx->type->mem_bar, efx->membase_phys, efx->type->mem_map_size, | 793 | efx->type->mem_bar, (unsigned long long)efx->membase_phys, |
802 | efx->membase); | 794 | efx->type->mem_map_size, efx->membase); |
803 | 795 | ||
804 | return 0; | 796 | return 0; |
805 | 797 | ||
806 | fail4: | 798 | fail4: |
807 | release_mem_region(efx->membase_phys, efx->type->mem_map_size); | 799 | release_mem_region(efx->membase_phys, efx->type->mem_map_size); |
808 | fail3: | 800 | fail3: |
809 | efx->membase_phys = 0UL; | 801 | efx->membase_phys = 0; |
810 | fail2: | 802 | fail2: |
811 | pci_disable_device(efx->pci_dev); | 803 | pci_disable_device(efx->pci_dev); |
812 | fail1: | 804 | fail1: |
@@ -824,7 +816,7 @@ static void efx_fini_io(struct efx_nic *efx) | |||
824 | 816 | ||
825 | if (efx->membase_phys) { | 817 | if (efx->membase_phys) { |
826 | pci_release_region(efx->pci_dev, efx->type->mem_bar); | 818 | pci_release_region(efx->pci_dev, efx->type->mem_bar); |
827 | efx->membase_phys = 0UL; | 819 | efx->membase_phys = 0; |
828 | } | 820 | } |
829 | 821 | ||
830 | pci_disable_device(efx->pci_dev); | 822 | pci_disable_device(efx->pci_dev); |
@@ -1043,7 +1035,7 @@ static void efx_start_all(struct efx_nic *efx) | |||
1043 | return; | 1035 | return; |
1044 | if ((efx->state != STATE_RUNNING) && (efx->state != STATE_INIT)) | 1036 | if ((efx->state != STATE_RUNNING) && (efx->state != STATE_INIT)) |
1045 | return; | 1037 | return; |
1046 | if (NET_DEV_REGISTERED(efx) && !netif_running(efx->net_dev)) | 1038 | if (efx_dev_registered(efx) && !netif_running(efx->net_dev)) |
1047 | return; | 1039 | return; |
1048 | 1040 | ||
1049 | /* Mark the port as enabled so port reconfigurations can start, then | 1041 | /* Mark the port as enabled so port reconfigurations can start, then |
@@ -1073,9 +1065,8 @@ static void efx_flush_all(struct efx_nic *efx) | |||
1073 | cancel_delayed_work_sync(&efx->monitor_work); | 1065 | cancel_delayed_work_sync(&efx->monitor_work); |
1074 | 1066 | ||
1075 | /* Ensure that all RX slow refills are complete. */ | 1067 | /* Ensure that all RX slow refills are complete. */ |
1076 | efx_for_each_rx_queue(rx_queue, efx) { | 1068 | efx_for_each_rx_queue(rx_queue, efx) |
1077 | cancel_delayed_work_sync(&rx_queue->work); | 1069 | cancel_delayed_work_sync(&rx_queue->work); |
1078 | } | ||
1079 | 1070 | ||
1080 | /* Stop scheduled port reconfigurations */ | 1071 | /* Stop scheduled port reconfigurations */ |
1081 | cancel_work_sync(&efx->reconfigure_work); | 1072 | cancel_work_sync(&efx->reconfigure_work); |
@@ -1101,9 +1092,10 @@ static void efx_stop_all(struct efx_nic *efx) | |||
1101 | falcon_disable_interrupts(efx); | 1092 | falcon_disable_interrupts(efx); |
1102 | if (efx->legacy_irq) | 1093 | if (efx->legacy_irq) |
1103 | synchronize_irq(efx->legacy_irq); | 1094 | synchronize_irq(efx->legacy_irq); |
1104 | efx_for_each_channel_with_interrupt(channel, efx) | 1095 | efx_for_each_channel_with_interrupt(channel, efx) { |
1105 | if (channel->irq) | 1096 | if (channel->irq) |
1106 | synchronize_irq(channel->irq); | 1097 | synchronize_irq(channel->irq); |
1098 | } | ||
1107 | 1099 | ||
1108 | /* Stop all NAPI processing and synchronous rx refills */ | 1100 | /* Stop all NAPI processing and synchronous rx refills */ |
1109 | efx_for_each_channel(channel, efx) | 1101 | efx_for_each_channel(channel, efx) |
@@ -1125,7 +1117,7 @@ static void efx_stop_all(struct efx_nic *efx) | |||
1125 | /* Stop the kernel transmit interface late, so the watchdog | 1117 | /* Stop the kernel transmit interface late, so the watchdog |
1126 | * timer isn't ticking over the flush */ | 1118 | * timer isn't ticking over the flush */ |
1127 | efx_stop_queue(efx); | 1119 | efx_stop_queue(efx); |
1128 | if (NET_DEV_REGISTERED(efx)) { | 1120 | if (efx_dev_registered(efx)) { |
1129 | netif_tx_lock_bh(efx->net_dev); | 1121 | netif_tx_lock_bh(efx->net_dev); |
1130 | netif_tx_unlock_bh(efx->net_dev); | 1122 | netif_tx_unlock_bh(efx->net_dev); |
1131 | } | 1123 | } |
@@ -1344,13 +1336,17 @@ static int efx_net_stop(struct net_device *net_dev) | |||
1344 | return 0; | 1336 | return 0; |
1345 | } | 1337 | } |
1346 | 1338 | ||
1347 | /* Context: process, dev_base_lock held, non-blocking. */ | 1339 | /* Context: process, dev_base_lock or RTNL held, non-blocking. */ |
1348 | static struct net_device_stats *efx_net_stats(struct net_device *net_dev) | 1340 | static struct net_device_stats *efx_net_stats(struct net_device *net_dev) |
1349 | { | 1341 | { |
1350 | struct efx_nic *efx = net_dev->priv; | 1342 | struct efx_nic *efx = net_dev->priv; |
1351 | struct efx_mac_stats *mac_stats = &efx->mac_stats; | 1343 | struct efx_mac_stats *mac_stats = &efx->mac_stats; |
1352 | struct net_device_stats *stats = &net_dev->stats; | 1344 | struct net_device_stats *stats = &net_dev->stats; |
1353 | 1345 | ||
1346 | /* Update stats if possible, but do not wait if another thread | ||
1347 | * is updating them (or resetting the NIC); slightly stale | ||
1348 | * stats are acceptable. | ||
1349 | */ | ||
1354 | if (!spin_trylock(&efx->stats_lock)) | 1350 | if (!spin_trylock(&efx->stats_lock)) |
1355 | return stats; | 1351 | return stats; |
1356 | if (efx->state == STATE_RUNNING) { | 1352 | if (efx->state == STATE_RUNNING) { |
@@ -1494,7 +1490,7 @@ static void efx_set_multicast_list(struct net_device *net_dev) | |||
1494 | static int efx_netdev_event(struct notifier_block *this, | 1490 | static int efx_netdev_event(struct notifier_block *this, |
1495 | unsigned long event, void *ptr) | 1491 | unsigned long event, void *ptr) |
1496 | { | 1492 | { |
1497 | struct net_device *net_dev = (struct net_device *)ptr; | 1493 | struct net_device *net_dev = ptr; |
1498 | 1494 | ||
1499 | if (net_dev->open == efx_net_open && event == NETDEV_CHANGENAME) { | 1495 | if (net_dev->open == efx_net_open && event == NETDEV_CHANGENAME) { |
1500 | struct efx_nic *efx = net_dev->priv; | 1496 | struct efx_nic *efx = net_dev->priv; |
@@ -1563,7 +1559,7 @@ static void efx_unregister_netdev(struct efx_nic *efx) | |||
1563 | efx_for_each_tx_queue(tx_queue, efx) | 1559 | efx_for_each_tx_queue(tx_queue, efx) |
1564 | efx_release_tx_buffers(tx_queue); | 1560 | efx_release_tx_buffers(tx_queue); |
1565 | 1561 | ||
1566 | if (NET_DEV_REGISTERED(efx)) { | 1562 | if (efx_dev_registered(efx)) { |
1567 | strlcpy(efx->name, pci_name(efx->pci_dev), sizeof(efx->name)); | 1563 | strlcpy(efx->name, pci_name(efx->pci_dev), sizeof(efx->name)); |
1568 | unregister_netdev(efx->net_dev); | 1564 | unregister_netdev(efx->net_dev); |
1569 | } | 1565 | } |
@@ -1688,7 +1684,7 @@ static int efx_reset(struct efx_nic *efx) | |||
1688 | if (method == RESET_TYPE_DISABLE) { | 1684 | if (method == RESET_TYPE_DISABLE) { |
1689 | /* Reinitialise the device anyway so the driver unload sequence | 1685 | /* Reinitialise the device anyway so the driver unload sequence |
1690 | * can talk to the external SRAM */ | 1686 | * can talk to the external SRAM */ |
1691 | (void) falcon_init_nic(efx); | 1687 | falcon_init_nic(efx); |
1692 | rc = -EIO; | 1688 | rc = -EIO; |
1693 | goto fail4; | 1689 | goto fail4; |
1694 | } | 1690 | } |
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index b57cc68058c0..790db89db345 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c | |||
@@ -116,17 +116,8 @@ MODULE_PARM_DESC(rx_xon_thresh_bytes, "RX fifo XON threshold"); | |||
116 | ************************************************************************** | 116 | ************************************************************************** |
117 | */ | 117 | */ |
118 | 118 | ||
119 | /* DMA address mask (up to 46-bit, avoiding compiler warnings) | 119 | /* DMA address mask */ |
120 | * | 120 | #define FALCON_DMA_MASK DMA_BIT_MASK(46) |
121 | * Note that it is possible to have a platform with 64-bit longs and | ||
122 | * 32-bit DMA addresses, or vice versa. EFX_DMA_MASK takes care of the | ||
123 | * platform DMA mask. | ||
124 | */ | ||
125 | #if BITS_PER_LONG == 64 | ||
126 | #define FALCON_DMA_MASK EFX_DMA_MASK(0x00003fffffffffffUL) | ||
127 | #else | ||
128 | #define FALCON_DMA_MASK EFX_DMA_MASK(0x00003fffffffffffULL) | ||
129 | #endif | ||
130 | 121 | ||
131 | /* TX DMA length mask (13-bit) */ | 122 | /* TX DMA length mask (13-bit) */ |
132 | #define FALCON_TX_DMA_MASK (4096 - 1) | 123 | #define FALCON_TX_DMA_MASK (4096 - 1) |
@@ -145,7 +136,7 @@ MODULE_PARM_DESC(rx_xon_thresh_bytes, "RX fifo XON threshold"); | |||
145 | #define PCI_EXP_LNKSTA_LNK_WID_LBN 4 | 136 | #define PCI_EXP_LNKSTA_LNK_WID_LBN 4 |
146 | 137 | ||
147 | #define FALCON_IS_DUAL_FUNC(efx) \ | 138 | #define FALCON_IS_DUAL_FUNC(efx) \ |
148 | (FALCON_REV(efx) < FALCON_REV_B0) | 139 | (falcon_rev(efx) < FALCON_REV_B0) |
149 | 140 | ||
150 | /************************************************************************** | 141 | /************************************************************************** |
151 | * | 142 | * |
@@ -465,7 +456,7 @@ int falcon_init_tx(struct efx_tx_queue *tx_queue) | |||
465 | TX_DESCQ_TYPE, 0, | 456 | TX_DESCQ_TYPE, 0, |
466 | TX_NON_IP_DROP_DIS_B0, 1); | 457 | TX_NON_IP_DROP_DIS_B0, 1); |
467 | 458 | ||
468 | if (FALCON_REV(efx) >= FALCON_REV_B0) { | 459 | if (falcon_rev(efx) >= FALCON_REV_B0) { |
469 | int csum = !(efx->net_dev->features & NETIF_F_IP_CSUM); | 460 | int csum = !(efx->net_dev->features & NETIF_F_IP_CSUM); |
470 | EFX_SET_OWORD_FIELD(tx_desc_ptr, TX_IP_CHKSM_DIS_B0, csum); | 461 | EFX_SET_OWORD_FIELD(tx_desc_ptr, TX_IP_CHKSM_DIS_B0, csum); |
471 | EFX_SET_OWORD_FIELD(tx_desc_ptr, TX_TCP_CHKSM_DIS_B0, csum); | 462 | EFX_SET_OWORD_FIELD(tx_desc_ptr, TX_TCP_CHKSM_DIS_B0, csum); |
@@ -474,7 +465,7 @@ int falcon_init_tx(struct efx_tx_queue *tx_queue) | |||
474 | falcon_write_table(efx, &tx_desc_ptr, efx->type->txd_ptr_tbl_base, | 465 | falcon_write_table(efx, &tx_desc_ptr, efx->type->txd_ptr_tbl_base, |
475 | tx_queue->queue); | 466 | tx_queue->queue); |
476 | 467 | ||
477 | if (FALCON_REV(efx) < FALCON_REV_B0) { | 468 | if (falcon_rev(efx) < FALCON_REV_B0) { |
478 | efx_oword_t reg; | 469 | efx_oword_t reg; |
479 | 470 | ||
480 | BUG_ON(tx_queue->queue >= 128); /* HW limit */ | 471 | BUG_ON(tx_queue->queue >= 128); /* HW limit */ |
@@ -635,7 +626,7 @@ int falcon_init_rx(struct efx_rx_queue *rx_queue) | |||
635 | efx_oword_t rx_desc_ptr; | 626 | efx_oword_t rx_desc_ptr; |
636 | struct efx_nic *efx = rx_queue->efx; | 627 | struct efx_nic *efx = rx_queue->efx; |
637 | int rc; | 628 | int rc; |
638 | int is_b0 = FALCON_REV(efx) >= FALCON_REV_B0; | 629 | int is_b0 = falcon_rev(efx) >= FALCON_REV_B0; |
639 | int iscsi_digest_en = is_b0; | 630 | int iscsi_digest_en = is_b0; |
640 | 631 | ||
641 | EFX_LOG(efx, "RX queue %d ring in special buffers %d-%d\n", | 632 | EFX_LOG(efx, "RX queue %d ring in special buffers %d-%d\n", |
@@ -742,8 +733,10 @@ void falcon_fini_rx(struct efx_rx_queue *rx_queue) | |||
742 | continue; | 733 | continue; |
743 | break; | 734 | break; |
744 | } | 735 | } |
745 | if (rc) | 736 | if (rc) { |
746 | EFX_ERR(efx, "failed to flush rx queue %d\n", rx_queue->queue); | 737 | EFX_ERR(efx, "failed to flush rx queue %d\n", rx_queue->queue); |
738 | efx_schedule_reset(efx, RESET_TYPE_INVISIBLE); | ||
739 | } | ||
747 | 740 | ||
748 | /* Remove RX descriptor ring from card */ | 741 | /* Remove RX descriptor ring from card */ |
749 | EFX_ZERO_OWORD(rx_desc_ptr); | 742 | EFX_ZERO_OWORD(rx_desc_ptr); |
@@ -822,10 +815,10 @@ static inline void falcon_handle_tx_event(struct efx_channel *channel, | |||
822 | tx_ev_q_label = EFX_QWORD_FIELD(*event, TX_EV_Q_LABEL); | 815 | tx_ev_q_label = EFX_QWORD_FIELD(*event, TX_EV_Q_LABEL); |
823 | tx_queue = &efx->tx_queue[tx_ev_q_label]; | 816 | tx_queue = &efx->tx_queue[tx_ev_q_label]; |
824 | 817 | ||
825 | if (NET_DEV_REGISTERED(efx)) | 818 | if (efx_dev_registered(efx)) |
826 | netif_tx_lock(efx->net_dev); | 819 | netif_tx_lock(efx->net_dev); |
827 | falcon_notify_tx_desc(tx_queue); | 820 | falcon_notify_tx_desc(tx_queue); |
828 | if (NET_DEV_REGISTERED(efx)) | 821 | if (efx_dev_registered(efx)) |
829 | netif_tx_unlock(efx->net_dev); | 822 | netif_tx_unlock(efx->net_dev); |
830 | } else if (EFX_QWORD_FIELD(*event, TX_EV_PKT_ERR) && | 823 | } else if (EFX_QWORD_FIELD(*event, TX_EV_PKT_ERR) && |
831 | EFX_WORKAROUND_10727(efx)) { | 824 | EFX_WORKAROUND_10727(efx)) { |
@@ -884,7 +877,7 @@ static void falcon_handle_rx_not_ok(struct efx_rx_queue *rx_queue, | |||
884 | RX_EV_TCP_UDP_CHKSUM_ERR); | 877 | RX_EV_TCP_UDP_CHKSUM_ERR); |
885 | rx_ev_eth_crc_err = EFX_QWORD_FIELD(*event, RX_EV_ETH_CRC_ERR); | 878 | rx_ev_eth_crc_err = EFX_QWORD_FIELD(*event, RX_EV_ETH_CRC_ERR); |
886 | rx_ev_frm_trunc = EFX_QWORD_FIELD(*event, RX_EV_FRM_TRUNC); | 879 | rx_ev_frm_trunc = EFX_QWORD_FIELD(*event, RX_EV_FRM_TRUNC); |
887 | rx_ev_drib_nib = ((FALCON_REV(efx) >= FALCON_REV_B0) ? | 880 | rx_ev_drib_nib = ((falcon_rev(efx) >= FALCON_REV_B0) ? |
888 | 0 : EFX_QWORD_FIELD(*event, RX_EV_DRIB_NIB)); | 881 | 0 : EFX_QWORD_FIELD(*event, RX_EV_DRIB_NIB)); |
889 | rx_ev_pause_frm = EFX_QWORD_FIELD(*event, RX_EV_PAUSE_FRM_ERR); | 882 | rx_ev_pause_frm = EFX_QWORD_FIELD(*event, RX_EV_PAUSE_FRM_ERR); |
890 | 883 | ||
@@ -1065,7 +1058,7 @@ static void falcon_handle_global_event(struct efx_channel *channel, | |||
1065 | EFX_QWORD_FIELD(*event, XG_PHY_INTR)) | 1058 | EFX_QWORD_FIELD(*event, XG_PHY_INTR)) |
1066 | is_phy_event = 1; | 1059 | is_phy_event = 1; |
1067 | 1060 | ||
1068 | if ((FALCON_REV(efx) >= FALCON_REV_B0) && | 1061 | if ((falcon_rev(efx) >= FALCON_REV_B0) && |
1069 | EFX_OWORD_FIELD(*event, XG_MNT_INTR_B0)) | 1062 | EFX_OWORD_FIELD(*event, XG_MNT_INTR_B0)) |
1070 | is_phy_event = 1; | 1063 | is_phy_event = 1; |
1071 | 1064 | ||
@@ -1405,7 +1398,7 @@ static inline void falcon_irq_ack_a1(struct efx_nic *efx) | |||
1405 | static irqreturn_t falcon_fatal_interrupt(struct efx_nic *efx) | 1398 | static irqreturn_t falcon_fatal_interrupt(struct efx_nic *efx) |
1406 | { | 1399 | { |
1407 | struct falcon_nic_data *nic_data = efx->nic_data; | 1400 | struct falcon_nic_data *nic_data = efx->nic_data; |
1408 | efx_oword_t *int_ker = (efx_oword_t *) efx->irq_status.addr; | 1401 | efx_oword_t *int_ker = efx->irq_status.addr; |
1409 | efx_oword_t fatal_intr; | 1402 | efx_oword_t fatal_intr; |
1410 | int error, mem_perr; | 1403 | int error, mem_perr; |
1411 | static int n_int_errors; | 1404 | static int n_int_errors; |
@@ -1451,8 +1444,8 @@ out: | |||
1451 | */ | 1444 | */ |
1452 | static irqreturn_t falcon_legacy_interrupt_b0(int irq, void *dev_id) | 1445 | static irqreturn_t falcon_legacy_interrupt_b0(int irq, void *dev_id) |
1453 | { | 1446 | { |
1454 | struct efx_nic *efx = (struct efx_nic *)dev_id; | 1447 | struct efx_nic *efx = dev_id; |
1455 | efx_oword_t *int_ker = (efx_oword_t *) efx->irq_status.addr; | 1448 | efx_oword_t *int_ker = efx->irq_status.addr; |
1456 | struct efx_channel *channel; | 1449 | struct efx_channel *channel; |
1457 | efx_dword_t reg; | 1450 | efx_dword_t reg; |
1458 | u32 queues; | 1451 | u32 queues; |
@@ -1489,8 +1482,8 @@ static irqreturn_t falcon_legacy_interrupt_b0(int irq, void *dev_id) | |||
1489 | 1482 | ||
1490 | static irqreturn_t falcon_legacy_interrupt_a1(int irq, void *dev_id) | 1483 | static irqreturn_t falcon_legacy_interrupt_a1(int irq, void *dev_id) |
1491 | { | 1484 | { |
1492 | struct efx_nic *efx = (struct efx_nic *)dev_id; | 1485 | struct efx_nic *efx = dev_id; |
1493 | efx_oword_t *int_ker = (efx_oword_t *) efx->irq_status.addr; | 1486 | efx_oword_t *int_ker = efx->irq_status.addr; |
1494 | struct efx_channel *channel; | 1487 | struct efx_channel *channel; |
1495 | int syserr; | 1488 | int syserr; |
1496 | int queues; | 1489 | int queues; |
@@ -1542,9 +1535,9 @@ static irqreturn_t falcon_legacy_interrupt_a1(int irq, void *dev_id) | |||
1542 | */ | 1535 | */ |
1543 | static irqreturn_t falcon_msi_interrupt(int irq, void *dev_id) | 1536 | static irqreturn_t falcon_msi_interrupt(int irq, void *dev_id) |
1544 | { | 1537 | { |
1545 | struct efx_channel *channel = (struct efx_channel *)dev_id; | 1538 | struct efx_channel *channel = dev_id; |
1546 | struct efx_nic *efx = channel->efx; | 1539 | struct efx_nic *efx = channel->efx; |
1547 | efx_oword_t *int_ker = (efx_oword_t *) efx->irq_status.addr; | 1540 | efx_oword_t *int_ker = efx->irq_status.addr; |
1548 | int syserr; | 1541 | int syserr; |
1549 | 1542 | ||
1550 | efx->last_irq_cpu = raw_smp_processor_id(); | 1543 | efx->last_irq_cpu = raw_smp_processor_id(); |
@@ -1572,7 +1565,7 @@ static void falcon_setup_rss_indir_table(struct efx_nic *efx) | |||
1572 | unsigned long offset; | 1565 | unsigned long offset; |
1573 | efx_dword_t dword; | 1566 | efx_dword_t dword; |
1574 | 1567 | ||
1575 | if (FALCON_REV(efx) < FALCON_REV_B0) | 1568 | if (falcon_rev(efx) < FALCON_REV_B0) |
1576 | return; | 1569 | return; |
1577 | 1570 | ||
1578 | for (offset = RX_RSS_INDIR_TBL_B0; | 1571 | for (offset = RX_RSS_INDIR_TBL_B0; |
@@ -1595,7 +1588,7 @@ int falcon_init_interrupt(struct efx_nic *efx) | |||
1595 | 1588 | ||
1596 | if (!EFX_INT_MODE_USE_MSI(efx)) { | 1589 | if (!EFX_INT_MODE_USE_MSI(efx)) { |
1597 | irq_handler_t handler; | 1590 | irq_handler_t handler; |
1598 | if (FALCON_REV(efx) >= FALCON_REV_B0) | 1591 | if (falcon_rev(efx) >= FALCON_REV_B0) |
1599 | handler = falcon_legacy_interrupt_b0; | 1592 | handler = falcon_legacy_interrupt_b0; |
1600 | else | 1593 | else |
1601 | handler = falcon_legacy_interrupt_a1; | 1594 | handler = falcon_legacy_interrupt_a1; |
@@ -1636,12 +1629,13 @@ void falcon_fini_interrupt(struct efx_nic *efx) | |||
1636 | efx_oword_t reg; | 1629 | efx_oword_t reg; |
1637 | 1630 | ||
1638 | /* Disable MSI/MSI-X interrupts */ | 1631 | /* Disable MSI/MSI-X interrupts */ |
1639 | efx_for_each_channel_with_interrupt(channel, efx) | 1632 | efx_for_each_channel_with_interrupt(channel, efx) { |
1640 | if (channel->irq) | 1633 | if (channel->irq) |
1641 | free_irq(channel->irq, channel); | 1634 | free_irq(channel->irq, channel); |
1635 | } | ||
1642 | 1636 | ||
1643 | /* ACK legacy interrupt */ | 1637 | /* ACK legacy interrupt */ |
1644 | if (FALCON_REV(efx) >= FALCON_REV_B0) | 1638 | if (falcon_rev(efx) >= FALCON_REV_B0) |
1645 | falcon_read(efx, ®, INT_ISR0_B0); | 1639 | falcon_read(efx, ®, INT_ISR0_B0); |
1646 | else | 1640 | else |
1647 | falcon_irq_ack_a1(efx); | 1641 | falcon_irq_ack_a1(efx); |
@@ -1732,7 +1726,7 @@ void falcon_drain_tx_fifo(struct efx_nic *efx) | |||
1732 | efx_oword_t temp; | 1726 | efx_oword_t temp; |
1733 | int count; | 1727 | int count; |
1734 | 1728 | ||
1735 | if ((FALCON_REV(efx) < FALCON_REV_B0) || | 1729 | if ((falcon_rev(efx) < FALCON_REV_B0) || |
1736 | (efx->loopback_mode != LOOPBACK_NONE)) | 1730 | (efx->loopback_mode != LOOPBACK_NONE)) |
1737 | return; | 1731 | return; |
1738 | 1732 | ||
@@ -1785,7 +1779,7 @@ void falcon_deconfigure_mac_wrapper(struct efx_nic *efx) | |||
1785 | { | 1779 | { |
1786 | efx_oword_t temp; | 1780 | efx_oword_t temp; |
1787 | 1781 | ||
1788 | if (FALCON_REV(efx) < FALCON_REV_B0) | 1782 | if (falcon_rev(efx) < FALCON_REV_B0) |
1789 | return; | 1783 | return; |
1790 | 1784 | ||
1791 | /* Isolate the MAC -> RX */ | 1785 | /* Isolate the MAC -> RX */ |
@@ -1823,7 +1817,7 @@ void falcon_reconfigure_mac_wrapper(struct efx_nic *efx) | |||
1823 | MAC_SPEED, link_speed); | 1817 | MAC_SPEED, link_speed); |
1824 | /* On B0, MAC backpressure can be disabled and packets get | 1818 | /* On B0, MAC backpressure can be disabled and packets get |
1825 | * discarded. */ | 1819 | * discarded. */ |
1826 | if (FALCON_REV(efx) >= FALCON_REV_B0) { | 1820 | if (falcon_rev(efx) >= FALCON_REV_B0) { |
1827 | EFX_SET_OWORD_FIELD(reg, TXFIFO_DRAIN_EN_B0, | 1821 | EFX_SET_OWORD_FIELD(reg, TXFIFO_DRAIN_EN_B0, |
1828 | !efx->link_up); | 1822 | !efx->link_up); |
1829 | } | 1823 | } |
@@ -1841,7 +1835,7 @@ void falcon_reconfigure_mac_wrapper(struct efx_nic *efx) | |||
1841 | EFX_SET_OWORD_FIELD_VER(efx, reg, RX_XOFF_MAC_EN, tx_fc); | 1835 | EFX_SET_OWORD_FIELD_VER(efx, reg, RX_XOFF_MAC_EN, tx_fc); |
1842 | 1836 | ||
1843 | /* Unisolate the MAC -> RX */ | 1837 | /* Unisolate the MAC -> RX */ |
1844 | if (FALCON_REV(efx) >= FALCON_REV_B0) | 1838 | if (falcon_rev(efx) >= FALCON_REV_B0) |
1845 | EFX_SET_OWORD_FIELD(reg, RX_INGR_EN_B0, 1); | 1839 | EFX_SET_OWORD_FIELD(reg, RX_INGR_EN_B0, 1); |
1846 | falcon_write(efx, ®, RX_CFG_REG_KER); | 1840 | falcon_write(efx, ®, RX_CFG_REG_KER); |
1847 | } | 1841 | } |
@@ -1856,7 +1850,7 @@ int falcon_dma_stats(struct efx_nic *efx, unsigned int done_offset) | |||
1856 | return 0; | 1850 | return 0; |
1857 | 1851 | ||
1858 | /* Statistics fetch will fail if the MAC is in TX drain */ | 1852 | /* Statistics fetch will fail if the MAC is in TX drain */ |
1859 | if (FALCON_REV(efx) >= FALCON_REV_B0) { | 1853 | if (falcon_rev(efx) >= FALCON_REV_B0) { |
1860 | efx_oword_t temp; | 1854 | efx_oword_t temp; |
1861 | falcon_read(efx, &temp, MAC0_CTRL_REG_KER); | 1855 | falcon_read(efx, &temp, MAC0_CTRL_REG_KER); |
1862 | if (EFX_OWORD_FIELD(temp, TXFIFO_DRAIN_EN_B0)) | 1856 | if (EFX_OWORD_FIELD(temp, TXFIFO_DRAIN_EN_B0)) |
@@ -1940,7 +1934,7 @@ static int falcon_gmii_wait(struct efx_nic *efx) | |||
1940 | static void falcon_mdio_write(struct net_device *net_dev, int phy_id, | 1934 | static void falcon_mdio_write(struct net_device *net_dev, int phy_id, |
1941 | int addr, int value) | 1935 | int addr, int value) |
1942 | { | 1936 | { |
1943 | struct efx_nic *efx = (struct efx_nic *)net_dev->priv; | 1937 | struct efx_nic *efx = net_dev->priv; |
1944 | unsigned int phy_id2 = phy_id & FALCON_PHY_ID_ID_MASK; | 1938 | unsigned int phy_id2 = phy_id & FALCON_PHY_ID_ID_MASK; |
1945 | efx_oword_t reg; | 1939 | efx_oword_t reg; |
1946 | 1940 | ||
@@ -2008,7 +2002,7 @@ static void falcon_mdio_write(struct net_device *net_dev, int phy_id, | |||
2008 | * could be read, -1 will be returned. */ | 2002 | * could be read, -1 will be returned. */ |
2009 | static int falcon_mdio_read(struct net_device *net_dev, int phy_id, int addr) | 2003 | static int falcon_mdio_read(struct net_device *net_dev, int phy_id, int addr) |
2010 | { | 2004 | { |
2011 | struct efx_nic *efx = (struct efx_nic *)net_dev->priv; | 2005 | struct efx_nic *efx = net_dev->priv; |
2012 | unsigned int phy_addr = phy_id & FALCON_PHY_ID_ID_MASK; | 2006 | unsigned int phy_addr = phy_id & FALCON_PHY_ID_ID_MASK; |
2013 | efx_oword_t reg; | 2007 | efx_oword_t reg; |
2014 | int value = -1; | 2008 | int value = -1; |
@@ -2113,7 +2107,7 @@ int falcon_probe_port(struct efx_nic *efx) | |||
2113 | falcon_init_mdio(&efx->mii); | 2107 | falcon_init_mdio(&efx->mii); |
2114 | 2108 | ||
2115 | /* Hardware flow ctrl. FalconA RX FIFO too small for pause generation */ | 2109 | /* Hardware flow ctrl. FalconA RX FIFO too small for pause generation */ |
2116 | if (FALCON_REV(efx) >= FALCON_REV_B0) | 2110 | if (falcon_rev(efx) >= FALCON_REV_B0) |
2117 | efx->flow_control = EFX_FC_RX | EFX_FC_TX; | 2111 | efx->flow_control = EFX_FC_RX | EFX_FC_TX; |
2118 | else | 2112 | else |
2119 | efx->flow_control = EFX_FC_RX; | 2113 | efx->flow_control = EFX_FC_RX; |
@@ -2373,7 +2367,7 @@ static int falcon_probe_nic_variant(struct efx_nic *efx) | |||
2373 | return -ENODEV; | 2367 | return -ENODEV; |
2374 | } | 2368 | } |
2375 | 2369 | ||
2376 | switch (FALCON_REV(efx)) { | 2370 | switch (falcon_rev(efx)) { |
2377 | case FALCON_REV_A0: | 2371 | case FALCON_REV_A0: |
2378 | case 0xff: | 2372 | case 0xff: |
2379 | EFX_ERR(efx, "Falcon rev A0 not supported\n"); | 2373 | EFX_ERR(efx, "Falcon rev A0 not supported\n"); |
@@ -2399,7 +2393,7 @@ static int falcon_probe_nic_variant(struct efx_nic *efx) | |||
2399 | break; | 2393 | break; |
2400 | 2394 | ||
2401 | default: | 2395 | default: |
2402 | EFX_ERR(efx, "Unknown Falcon rev %d\n", FALCON_REV(efx)); | 2396 | EFX_ERR(efx, "Unknown Falcon rev %d\n", falcon_rev(efx)); |
2403 | return -ENODEV; | 2397 | return -ENODEV; |
2404 | } | 2398 | } |
2405 | 2399 | ||
@@ -2419,7 +2413,7 @@ int falcon_probe_nic(struct efx_nic *efx) | |||
2419 | 2413 | ||
2420 | /* Allocate storage for hardware specific data */ | 2414 | /* Allocate storage for hardware specific data */ |
2421 | nic_data = kzalloc(sizeof(*nic_data), GFP_KERNEL); | 2415 | nic_data = kzalloc(sizeof(*nic_data), GFP_KERNEL); |
2422 | efx->nic_data = (void *) nic_data; | 2416 | efx->nic_data = nic_data; |
2423 | 2417 | ||
2424 | /* Determine number of ports etc. */ | 2418 | /* Determine number of ports etc. */ |
2425 | rc = falcon_probe_nic_variant(efx); | 2419 | rc = falcon_probe_nic_variant(efx); |
@@ -2489,13 +2483,10 @@ int falcon_probe_nic(struct efx_nic *efx) | |||
2489 | */ | 2483 | */ |
2490 | int falcon_init_nic(struct efx_nic *efx) | 2484 | int falcon_init_nic(struct efx_nic *efx) |
2491 | { | 2485 | { |
2492 | struct falcon_nic_data *data; | ||
2493 | efx_oword_t temp; | 2486 | efx_oword_t temp; |
2494 | unsigned thresh; | 2487 | unsigned thresh; |
2495 | int rc; | 2488 | int rc; |
2496 | 2489 | ||
2497 | data = (struct falcon_nic_data *)efx->nic_data; | ||
2498 | |||
2499 | /* Set up the address region register. This is only needed | 2490 | /* Set up the address region register. This is only needed |
2500 | * for the B0 FPGA, but since we are just pushing in the | 2491 | * for the B0 FPGA, but since we are just pushing in the |
2501 | * reset defaults this may as well be unconditional. */ | 2492 | * reset defaults this may as well be unconditional. */ |
@@ -2562,7 +2553,7 @@ int falcon_init_nic(struct efx_nic *efx) | |||
2562 | 2553 | ||
2563 | /* Set number of RSS queues for receive path. */ | 2554 | /* Set number of RSS queues for receive path. */ |
2564 | falcon_read(efx, &temp, RX_FILTER_CTL_REG); | 2555 | falcon_read(efx, &temp, RX_FILTER_CTL_REG); |
2565 | if (FALCON_REV(efx) >= FALCON_REV_B0) | 2556 | if (falcon_rev(efx) >= FALCON_REV_B0) |
2566 | EFX_SET_OWORD_FIELD(temp, NUM_KER, 0); | 2557 | EFX_SET_OWORD_FIELD(temp, NUM_KER, 0); |
2567 | else | 2558 | else |
2568 | EFX_SET_OWORD_FIELD(temp, NUM_KER, efx->rss_queues - 1); | 2559 | EFX_SET_OWORD_FIELD(temp, NUM_KER, efx->rss_queues - 1); |
@@ -2600,7 +2591,7 @@ int falcon_init_nic(struct efx_nic *efx) | |||
2600 | /* Prefetch threshold 2 => fetch when descriptor cache half empty */ | 2591 | /* Prefetch threshold 2 => fetch when descriptor cache half empty */ |
2601 | EFX_SET_OWORD_FIELD(temp, TX_PREF_THRESHOLD, 2); | 2592 | EFX_SET_OWORD_FIELD(temp, TX_PREF_THRESHOLD, 2); |
2602 | /* Squash TX of packets of 16 bytes or less */ | 2593 | /* Squash TX of packets of 16 bytes or less */ |
2603 | if (FALCON_REV(efx) >= FALCON_REV_B0 && EFX_WORKAROUND_9141(efx)) | 2594 | if (falcon_rev(efx) >= FALCON_REV_B0 && EFX_WORKAROUND_9141(efx)) |
2604 | EFX_SET_OWORD_FIELD(temp, TX_FLUSH_MIN_LEN_EN_B0, 1); | 2595 | EFX_SET_OWORD_FIELD(temp, TX_FLUSH_MIN_LEN_EN_B0, 1); |
2605 | falcon_write(efx, &temp, TX_CFG2_REG_KER); | 2596 | falcon_write(efx, &temp, TX_CFG2_REG_KER); |
2606 | 2597 | ||
@@ -2617,7 +2608,7 @@ int falcon_init_nic(struct efx_nic *efx) | |||
2617 | if (EFX_WORKAROUND_7575(efx)) | 2608 | if (EFX_WORKAROUND_7575(efx)) |
2618 | EFX_SET_OWORD_FIELD_VER(efx, temp, RX_USR_BUF_SIZE, | 2609 | EFX_SET_OWORD_FIELD_VER(efx, temp, RX_USR_BUF_SIZE, |
2619 | (3 * 4096) / 32); | 2610 | (3 * 4096) / 32); |
2620 | if (FALCON_REV(efx) >= FALCON_REV_B0) | 2611 | if (falcon_rev(efx) >= FALCON_REV_B0) |
2621 | EFX_SET_OWORD_FIELD(temp, RX_INGR_EN_B0, 1); | 2612 | EFX_SET_OWORD_FIELD(temp, RX_INGR_EN_B0, 1); |
2622 | 2613 | ||
2623 | /* RX FIFO flow control thresholds */ | 2614 | /* RX FIFO flow control thresholds */ |
@@ -2633,7 +2624,7 @@ int falcon_init_nic(struct efx_nic *efx) | |||
2633 | falcon_write(efx, &temp, RX_CFG_REG_KER); | 2624 | falcon_write(efx, &temp, RX_CFG_REG_KER); |
2634 | 2625 | ||
2635 | /* Set destination of both TX and RX Flush events */ | 2626 | /* Set destination of both TX and RX Flush events */ |
2636 | if (FALCON_REV(efx) >= FALCON_REV_B0) { | 2627 | if (falcon_rev(efx) >= FALCON_REV_B0) { |
2637 | EFX_POPULATE_OWORD_1(temp, FLS_EVQ_ID, 0); | 2628 | EFX_POPULATE_OWORD_1(temp, FLS_EVQ_ID, 0); |
2638 | falcon_write(efx, &temp, DP_CTRL_REG); | 2629 | falcon_write(efx, &temp, DP_CTRL_REG); |
2639 | } | 2630 | } |
@@ -2647,7 +2638,7 @@ void falcon_remove_nic(struct efx_nic *efx) | |||
2647 | 2638 | ||
2648 | falcon_free_buffer(efx, &efx->irq_status); | 2639 | falcon_free_buffer(efx, &efx->irq_status); |
2649 | 2640 | ||
2650 | (void) falcon_reset_hw(efx, RESET_TYPE_ALL); | 2641 | falcon_reset_hw(efx, RESET_TYPE_ALL); |
2651 | 2642 | ||
2652 | /* Release the second function after the reset */ | 2643 | /* Release the second function after the reset */ |
2653 | if (nic_data->pci_dev2) { | 2644 | if (nic_data->pci_dev2) { |
diff --git a/drivers/net/sfc/falcon.h b/drivers/net/sfc/falcon.h index 6117403b0c03..492f9bc28840 100644 --- a/drivers/net/sfc/falcon.h +++ b/drivers/net/sfc/falcon.h | |||
@@ -23,7 +23,10 @@ enum falcon_revision { | |||
23 | FALCON_REV_B0 = 2, | 23 | FALCON_REV_B0 = 2, |
24 | }; | 24 | }; |
25 | 25 | ||
26 | #define FALCON_REV(efx) ((efx)->pci_dev->revision) | 26 | static inline int falcon_rev(struct efx_nic *efx) |
27 | { | ||
28 | return efx->pci_dev->revision; | ||
29 | } | ||
27 | 30 | ||
28 | extern struct efx_nic_type falcon_a_nic_type; | 31 | extern struct efx_nic_type falcon_a_nic_type; |
29 | extern struct efx_nic_type falcon_b_nic_type; | 32 | extern struct efx_nic_type falcon_b_nic_type; |
diff --git a/drivers/net/sfc/falcon_hwdefs.h b/drivers/net/sfc/falcon_hwdefs.h index 06e2d68fc3d1..6d003114eeab 100644 --- a/drivers/net/sfc/falcon_hwdefs.h +++ b/drivers/net/sfc/falcon_hwdefs.h | |||
@@ -1125,7 +1125,7 @@ struct falcon_nvconfig_board_v2 { | |||
1125 | u8 port1_phy_type; | 1125 | u8 port1_phy_type; |
1126 | __le16 asic_sub_revision; | 1126 | __le16 asic_sub_revision; |
1127 | __le16 board_revision; | 1127 | __le16 board_revision; |
1128 | } __attribute__ ((packed)); | 1128 | } __packed; |
1129 | 1129 | ||
1130 | #define NVCONFIG_BASE 0x300 | 1130 | #define NVCONFIG_BASE 0x300 |
1131 | #define NVCONFIG_BOARD_MAGIC_NUM 0xFA1C | 1131 | #define NVCONFIG_BOARD_MAGIC_NUM 0xFA1C |
@@ -1144,6 +1144,6 @@ struct falcon_nvconfig { | |||
1144 | __le16 board_struct_ver; | 1144 | __le16 board_struct_ver; |
1145 | __le16 board_checksum; | 1145 | __le16 board_checksum; |
1146 | struct falcon_nvconfig_board_v2 board_v2; | 1146 | struct falcon_nvconfig_board_v2 board_v2; |
1147 | } __attribute__ ((packed)); | 1147 | } __packed; |
1148 | 1148 | ||
1149 | #endif /* EFX_FALCON_HWDEFS_H */ | 1149 | #endif /* EFX_FALCON_HWDEFS_H */ |
diff --git a/drivers/net/sfc/falcon_io.h b/drivers/net/sfc/falcon_io.h index ea08184ddfa9..6670cdfc41ab 100644 --- a/drivers/net/sfc/falcon_io.h +++ b/drivers/net/sfc/falcon_io.h | |||
@@ -56,14 +56,27 @@ | |||
56 | #define FALCON_USE_QWORD_IO 1 | 56 | #define FALCON_USE_QWORD_IO 1 |
57 | #endif | 57 | #endif |
58 | 58 | ||
59 | #define _falcon_writeq(efx, value, reg) \ | 59 | #ifdef FALCON_USE_QWORD_IO |
60 | __raw_writeq((__force u64) (value), (efx)->membase + (reg)) | 60 | static inline void _falcon_writeq(struct efx_nic *efx, __le64 value, |
61 | #define _falcon_writel(efx, value, reg) \ | 61 | unsigned int reg) |
62 | __raw_writel((__force u32) (value), (efx)->membase + (reg)) | 62 | { |
63 | #define _falcon_readq(efx, reg) \ | 63 | __raw_writeq((__force u64)value, efx->membase + reg); |
64 | ((__force __le64) __raw_readq((efx)->membase + (reg))) | 64 | } |
65 | #define _falcon_readl(efx, reg) \ | 65 | static inline __le64 _falcon_readq(struct efx_nic *efx, unsigned int reg) |
66 | ((__force __le32) __raw_readl((efx)->membase + (reg))) | 66 | { |
67 | return (__force __le64)__raw_readq(efx->membase + reg); | ||
68 | } | ||
69 | #endif | ||
70 | |||
71 | static inline void _falcon_writel(struct efx_nic *efx, __le32 value, | ||
72 | unsigned int reg) | ||
73 | { | ||
74 | __raw_writel((__force u32)value, efx->membase + reg); | ||
75 | } | ||
76 | static inline __le32 _falcon_readl(struct efx_nic *efx, unsigned int reg) | ||
77 | { | ||
78 | return (__force __le32)__raw_readl(efx->membase + reg); | ||
79 | } | ||
67 | 80 | ||
68 | /* Writes to a normal 16-byte Falcon register, locking as appropriate. */ | 81 | /* Writes to a normal 16-byte Falcon register, locking as appropriate. */ |
69 | static inline void falcon_write(struct efx_nic *efx, efx_oword_t *value, | 82 | static inline void falcon_write(struct efx_nic *efx, efx_oword_t *value, |
diff --git a/drivers/net/sfc/falcon_xmac.c b/drivers/net/sfc/falcon_xmac.c index a74b7931a3c4..55c0d9760be8 100644 --- a/drivers/net/sfc/falcon_xmac.c +++ b/drivers/net/sfc/falcon_xmac.c | |||
@@ -221,7 +221,7 @@ static int falcon_xgmii_status(struct efx_nic *efx) | |||
221 | { | 221 | { |
222 | efx_dword_t reg; | 222 | efx_dword_t reg; |
223 | 223 | ||
224 | if (FALCON_REV(efx) < FALCON_REV_B0) | 224 | if (falcon_rev(efx) < FALCON_REV_B0) |
225 | return 1; | 225 | return 1; |
226 | 226 | ||
227 | /* The ISR latches, so clear it and re-read */ | 227 | /* The ISR latches, so clear it and re-read */ |
@@ -241,7 +241,7 @@ static void falcon_mask_status_intr(struct efx_nic *efx, int enable) | |||
241 | { | 241 | { |
242 | efx_dword_t reg; | 242 | efx_dword_t reg; |
243 | 243 | ||
244 | if ((FALCON_REV(efx) < FALCON_REV_B0) || LOOPBACK_INTERNAL(efx)) | 244 | if ((falcon_rev(efx) < FALCON_REV_B0) || LOOPBACK_INTERNAL(efx)) |
245 | return; | 245 | return; |
246 | 246 | ||
247 | /* Flush the ISR */ | 247 | /* Flush the ISR */ |
@@ -454,12 +454,12 @@ static int falcon_check_xaui_link_up(struct efx_nic *efx) | |||
454 | 454 | ||
455 | EFX_LOG(efx, "%s Clobbering XAUI (%d tries left).\n", | 455 | EFX_LOG(efx, "%s Clobbering XAUI (%d tries left).\n", |
456 | __func__, tries); | 456 | __func__, tries); |
457 | (void) falcon_reset_xaui(efx); | 457 | falcon_reset_xaui(efx); |
458 | udelay(200); | 458 | udelay(200); |
459 | tries--; | 459 | tries--; |
460 | } | 460 | } |
461 | 461 | ||
462 | EFX_ERR(efx, "Failed to bring XAUI link back up in %d tries!\n", | 462 | EFX_LOG(efx, "Failed to bring XAUI link back up in %d tries!\n", |
463 | max_tries); | 463 | max_tries); |
464 | return 0; | 464 | return 0; |
465 | } | 465 | } |
@@ -572,7 +572,7 @@ int falcon_check_xmac(struct efx_nic *efx) | |||
572 | xaui_link_ok = falcon_xaui_link_ok(efx); | 572 | xaui_link_ok = falcon_xaui_link_ok(efx); |
573 | 573 | ||
574 | if (EFX_WORKAROUND_5147(efx) && !xaui_link_ok) | 574 | if (EFX_WORKAROUND_5147(efx) && !xaui_link_ok) |
575 | (void) falcon_reset_xaui(efx); | 575 | falcon_reset_xaui(efx); |
576 | 576 | ||
577 | /* Call the PHY check_hw routine */ | 577 | /* Call the PHY check_hw routine */ |
578 | rc = efx->phy_op->check_hw(efx); | 578 | rc = efx->phy_op->check_hw(efx); |
@@ -639,7 +639,7 @@ int falcon_xmac_set_pause(struct efx_nic *efx, enum efx_fc_type flow_control) | |||
639 | reset = ((flow_control & EFX_FC_TX) && | 639 | reset = ((flow_control & EFX_FC_TX) && |
640 | !(efx->flow_control & EFX_FC_TX)); | 640 | !(efx->flow_control & EFX_FC_TX)); |
641 | if (EFX_WORKAROUND_11482(efx) && reset) { | 641 | if (EFX_WORKAROUND_11482(efx) && reset) { |
642 | if (FALCON_REV(efx) >= FALCON_REV_B0) { | 642 | if (falcon_rev(efx) >= FALCON_REV_B0) { |
643 | /* Recover by resetting the EM block */ | 643 | /* Recover by resetting the EM block */ |
644 | if (efx->link_up) | 644 | if (efx->link_up) |
645 | falcon_drain_tx_fifo(efx); | 645 | falcon_drain_tx_fifo(efx); |
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 59f261b4171f..5e20e7551dae 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h | |||
@@ -42,7 +42,7 @@ | |||
42 | #ifndef EFX_DRIVER_NAME | 42 | #ifndef EFX_DRIVER_NAME |
43 | #define EFX_DRIVER_NAME "sfc" | 43 | #define EFX_DRIVER_NAME "sfc" |
44 | #endif | 44 | #endif |
45 | #define EFX_DRIVER_VERSION "2.2.0136" | 45 | #define EFX_DRIVER_VERSION "2.2" |
46 | 46 | ||
47 | #ifdef EFX_ENABLE_DEBUG | 47 | #ifdef EFX_ENABLE_DEBUG |
48 | #define EFX_BUG_ON_PARANOID(x) BUG_ON(x) | 48 | #define EFX_BUG_ON_PARANOID(x) BUG_ON(x) |
@@ -52,28 +52,19 @@ | |||
52 | #define EFX_WARN_ON_PARANOID(x) do {} while (0) | 52 | #define EFX_WARN_ON_PARANOID(x) do {} while (0) |
53 | #endif | 53 | #endif |
54 | 54 | ||
55 | #define NET_DEV_REGISTERED(efx) \ | ||
56 | ((efx)->net_dev->reg_state == NETREG_REGISTERED) | ||
57 | |||
58 | /* Include net device name in log messages if it has been registered. | ||
59 | * Use efx->name not efx->net_dev->name so that races with (un)registration | ||
60 | * are harmless. | ||
61 | */ | ||
62 | #define NET_DEV_NAME(efx) (NET_DEV_REGISTERED(efx) ? (efx)->name : "") | ||
63 | |||
64 | /* Un-rate-limited logging */ | 55 | /* Un-rate-limited logging */ |
65 | #define EFX_ERR(efx, fmt, args...) \ | 56 | #define EFX_ERR(efx, fmt, args...) \ |
66 | dev_err(&((efx)->pci_dev->dev), "ERR: %s " fmt, NET_DEV_NAME(efx), ##args) | 57 | dev_err(&((efx)->pci_dev->dev), "ERR: %s " fmt, efx_dev_name(efx), ##args) |
67 | 58 | ||
68 | #define EFX_INFO(efx, fmt, args...) \ | 59 | #define EFX_INFO(efx, fmt, args...) \ |
69 | dev_info(&((efx)->pci_dev->dev), "INFO: %s " fmt, NET_DEV_NAME(efx), ##args) | 60 | dev_info(&((efx)->pci_dev->dev), "INFO: %s " fmt, efx_dev_name(efx), ##args) |
70 | 61 | ||
71 | #ifdef EFX_ENABLE_DEBUG | 62 | #ifdef EFX_ENABLE_DEBUG |
72 | #define EFX_LOG(efx, fmt, args...) \ | 63 | #define EFX_LOG(efx, fmt, args...) \ |
73 | dev_info(&((efx)->pci_dev->dev), "DBG: %s " fmt, NET_DEV_NAME(efx), ##args) | 64 | dev_info(&((efx)->pci_dev->dev), "DBG: %s " fmt, efx_dev_name(efx), ##args) |
74 | #else | 65 | #else |
75 | #define EFX_LOG(efx, fmt, args...) \ | 66 | #define EFX_LOG(efx, fmt, args...) \ |
76 | dev_dbg(&((efx)->pci_dev->dev), "DBG: %s " fmt, NET_DEV_NAME(efx), ##args) | 67 | dev_dbg(&((efx)->pci_dev->dev), "DBG: %s " fmt, efx_dev_name(efx), ##args) |
77 | #endif | 68 | #endif |
78 | 69 | ||
79 | #define EFX_TRACE(efx, fmt, args...) do {} while (0) | 70 | #define EFX_TRACE(efx, fmt, args...) do {} while (0) |
@@ -90,11 +81,6 @@ do {if (net_ratelimit()) EFX_INFO(efx, fmt, ##args); } while (0) | |||
90 | #define EFX_LOG_RL(efx, fmt, args...) \ | 81 | #define EFX_LOG_RL(efx, fmt, args...) \ |
91 | do {if (net_ratelimit()) EFX_LOG(efx, fmt, ##args); } while (0) | 82 | do {if (net_ratelimit()) EFX_LOG(efx, fmt, ##args); } while (0) |
92 | 83 | ||
93 | /* Kernel headers may redefine inline anyway */ | ||
94 | #ifndef inline | ||
95 | #define inline inline __attribute__ ((always_inline)) | ||
96 | #endif | ||
97 | |||
98 | /************************************************************************** | 84 | /************************************************************************** |
99 | * | 85 | * |
100 | * Efx data structures | 86 | * Efx data structures |
@@ -695,7 +681,7 @@ struct efx_nic { | |||
695 | struct workqueue_struct *workqueue; | 681 | struct workqueue_struct *workqueue; |
696 | struct work_struct reset_work; | 682 | struct work_struct reset_work; |
697 | struct delayed_work monitor_work; | 683 | struct delayed_work monitor_work; |
698 | unsigned long membase_phys; | 684 | resource_size_t membase_phys; |
699 | void __iomem *membase; | 685 | void __iomem *membase; |
700 | spinlock_t biu_lock; | 686 | spinlock_t biu_lock; |
701 | enum efx_int_mode interrupt_mode; | 687 | enum efx_int_mode interrupt_mode; |
@@ -719,7 +705,7 @@ struct efx_nic { | |||
719 | 705 | ||
720 | unsigned n_rx_nodesc_drop_cnt; | 706 | unsigned n_rx_nodesc_drop_cnt; |
721 | 707 | ||
722 | void *nic_data; | 708 | struct falcon_nic_data *nic_data; |
723 | 709 | ||
724 | struct mutex mac_lock; | 710 | struct mutex mac_lock; |
725 | int port_enabled; | 711 | int port_enabled; |
@@ -760,6 +746,20 @@ struct efx_nic { | |||
760 | void *loopback_selftest; | 746 | void *loopback_selftest; |
761 | }; | 747 | }; |
762 | 748 | ||
749 | static inline int efx_dev_registered(struct efx_nic *efx) | ||
750 | { | ||
751 | return efx->net_dev->reg_state == NETREG_REGISTERED; | ||
752 | } | ||
753 | |||
754 | /* Net device name, for inclusion in log messages if it has been registered. | ||
755 | * Use efx->name not efx->net_dev->name so that races with (un)registration | ||
756 | * are harmless. | ||
757 | */ | ||
758 | static inline const char *efx_dev_name(struct efx_nic *efx) | ||
759 | { | ||
760 | return efx_dev_registered(efx) ? efx->name : ""; | ||
761 | } | ||
762 | |||
763 | /** | 763 | /** |
764 | * struct efx_nic_type - Efx device type definition | 764 | * struct efx_nic_type - Efx device type definition |
765 | * @mem_bar: Memory BAR number | 765 | * @mem_bar: Memory BAR number |
@@ -795,7 +795,7 @@ struct efx_nic_type { | |||
795 | unsigned int txd_ring_mask; | 795 | unsigned int txd_ring_mask; |
796 | unsigned int rxd_ring_mask; | 796 | unsigned int rxd_ring_mask; |
797 | unsigned int evq_size; | 797 | unsigned int evq_size; |
798 | dma_addr_t max_dma_mask; | 798 | u64 max_dma_mask; |
799 | unsigned int tx_dma_mask; | 799 | unsigned int tx_dma_mask; |
800 | unsigned bug5391_mask; | 800 | unsigned bug5391_mask; |
801 | 801 | ||
diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c index 670622373ddf..601b001437c0 100644 --- a/drivers/net/sfc/rx.c +++ b/drivers/net/sfc/rx.c | |||
@@ -86,14 +86,17 @@ static unsigned int rx_refill_limit = 95; | |||
86 | */ | 86 | */ |
87 | #define EFX_RXD_HEAD_ROOM 2 | 87 | #define EFX_RXD_HEAD_ROOM 2 |
88 | 88 | ||
89 | /* Macros for zero-order pages (potentially) containing multiple RX buffers */ | 89 | static inline unsigned int efx_rx_buf_offset(struct efx_rx_buffer *buf) |
90 | #define RX_DATA_OFFSET(_data) \ | 90 | { |
91 | (((unsigned long) (_data)) & (PAGE_SIZE-1)) | 91 | /* Offset is always within one page, so we don't need to consider |
92 | #define RX_BUF_OFFSET(_rx_buf) \ | 92 | * the page order. |
93 | RX_DATA_OFFSET((_rx_buf)->data) | 93 | */ |
94 | 94 | return (__force unsigned long) buf->data & (PAGE_SIZE - 1); | |
95 | #define RX_PAGE_SIZE(_efx) \ | 95 | } |
96 | (PAGE_SIZE * (1u << (_efx)->rx_buffer_order)) | 96 | static inline unsigned int efx_rx_buf_size(struct efx_nic *efx) |
97 | { | ||
98 | return PAGE_SIZE << efx->rx_buffer_order; | ||
99 | } | ||
97 | 100 | ||
98 | 101 | ||
99 | /************************************************************************** | 102 | /************************************************************************** |
@@ -106,7 +109,7 @@ static unsigned int rx_refill_limit = 95; | |||
106 | static int efx_lro_get_skb_hdr(struct sk_buff *skb, void **ip_hdr, | 109 | static int efx_lro_get_skb_hdr(struct sk_buff *skb, void **ip_hdr, |
107 | void **tcpudp_hdr, u64 *hdr_flags, void *priv) | 110 | void **tcpudp_hdr, u64 *hdr_flags, void *priv) |
108 | { | 111 | { |
109 | struct efx_channel *channel = (struct efx_channel *)priv; | 112 | struct efx_channel *channel = priv; |
110 | struct iphdr *iph; | 113 | struct iphdr *iph; |
111 | struct tcphdr *th; | 114 | struct tcphdr *th; |
112 | 115 | ||
@@ -131,12 +134,12 @@ static int efx_get_frag_hdr(struct skb_frag_struct *frag, void **mac_hdr, | |||
131 | void **ip_hdr, void **tcpudp_hdr, u64 *hdr_flags, | 134 | void **ip_hdr, void **tcpudp_hdr, u64 *hdr_flags, |
132 | void *priv) | 135 | void *priv) |
133 | { | 136 | { |
134 | struct efx_channel *channel = (struct efx_channel *)priv; | 137 | struct efx_channel *channel = priv; |
135 | struct ethhdr *eh; | 138 | struct ethhdr *eh; |
136 | struct iphdr *iph; | 139 | struct iphdr *iph; |
137 | 140 | ||
138 | /* We support EtherII and VLAN encapsulated IPv4 */ | 141 | /* We support EtherII and VLAN encapsulated IPv4 */ |
139 | eh = (struct ethhdr *)(page_address(frag->page) + frag->page_offset); | 142 | eh = page_address(frag->page) + frag->page_offset; |
140 | *mac_hdr = eh; | 143 | *mac_hdr = eh; |
141 | 144 | ||
142 | if (eh->h_proto == htons(ETH_P_IP)) { | 145 | if (eh->h_proto == htons(ETH_P_IP)) { |
@@ -269,7 +272,7 @@ static inline int efx_init_rx_buffer_page(struct efx_rx_queue *rx_queue, | |||
269 | return -ENOMEM; | 272 | return -ENOMEM; |
270 | 273 | ||
271 | dma_addr = pci_map_page(efx->pci_dev, rx_buf->page, | 274 | dma_addr = pci_map_page(efx->pci_dev, rx_buf->page, |
272 | 0, RX_PAGE_SIZE(efx), | 275 | 0, efx_rx_buf_size(efx), |
273 | PCI_DMA_FROMDEVICE); | 276 | PCI_DMA_FROMDEVICE); |
274 | 277 | ||
275 | if (unlikely(pci_dma_mapping_error(dma_addr))) { | 278 | if (unlikely(pci_dma_mapping_error(dma_addr))) { |
@@ -280,14 +283,14 @@ static inline int efx_init_rx_buffer_page(struct efx_rx_queue *rx_queue, | |||
280 | 283 | ||
281 | rx_queue->buf_page = rx_buf->page; | 284 | rx_queue->buf_page = rx_buf->page; |
282 | rx_queue->buf_dma_addr = dma_addr; | 285 | rx_queue->buf_dma_addr = dma_addr; |
283 | rx_queue->buf_data = ((char *) page_address(rx_buf->page) + | 286 | rx_queue->buf_data = (page_address(rx_buf->page) + |
284 | EFX_PAGE_IP_ALIGN); | 287 | EFX_PAGE_IP_ALIGN); |
285 | } | 288 | } |
286 | 289 | ||
287 | offset = RX_DATA_OFFSET(rx_queue->buf_data); | ||
288 | rx_buf->len = bytes; | 290 | rx_buf->len = bytes; |
289 | rx_buf->dma_addr = rx_queue->buf_dma_addr + offset; | ||
290 | rx_buf->data = rx_queue->buf_data; | 291 | rx_buf->data = rx_queue->buf_data; |
292 | offset = efx_rx_buf_offset(rx_buf); | ||
293 | rx_buf->dma_addr = rx_queue->buf_dma_addr + offset; | ||
291 | 294 | ||
292 | /* Try to pack multiple buffers per page */ | 295 | /* Try to pack multiple buffers per page */ |
293 | if (efx->rx_buffer_order == 0) { | 296 | if (efx->rx_buffer_order == 0) { |
@@ -295,7 +298,7 @@ static inline int efx_init_rx_buffer_page(struct efx_rx_queue *rx_queue, | |||
295 | rx_queue->buf_data += ((bytes + 0x1ff) & ~0x1ff); | 298 | rx_queue->buf_data += ((bytes + 0x1ff) & ~0x1ff); |
296 | offset += ((bytes + 0x1ff) & ~0x1ff); | 299 | offset += ((bytes + 0x1ff) & ~0x1ff); |
297 | 300 | ||
298 | space = RX_PAGE_SIZE(efx) - offset; | 301 | space = efx_rx_buf_size(efx) - offset; |
299 | if (space >= bytes) { | 302 | if (space >= bytes) { |
300 | /* Refs dropped on kernel releasing each skb */ | 303 | /* Refs dropped on kernel releasing each skb */ |
301 | get_page(rx_queue->buf_page); | 304 | get_page(rx_queue->buf_page); |
@@ -344,7 +347,8 @@ static inline void efx_unmap_rx_buffer(struct efx_nic *efx, | |||
344 | EFX_BUG_ON_PARANOID(rx_buf->skb); | 347 | EFX_BUG_ON_PARANOID(rx_buf->skb); |
345 | if (rx_buf->unmap_addr) { | 348 | if (rx_buf->unmap_addr) { |
346 | pci_unmap_page(efx->pci_dev, rx_buf->unmap_addr, | 349 | pci_unmap_page(efx->pci_dev, rx_buf->unmap_addr, |
347 | RX_PAGE_SIZE(efx), PCI_DMA_FROMDEVICE); | 350 | efx_rx_buf_size(efx), |
351 | PCI_DMA_FROMDEVICE); | ||
348 | rx_buf->unmap_addr = 0; | 352 | rx_buf->unmap_addr = 0; |
349 | } | 353 | } |
350 | } else if (likely(rx_buf->skb)) { | 354 | } else if (likely(rx_buf->skb)) { |
@@ -400,9 +404,10 @@ static int __efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue, | |||
400 | return 0; | 404 | return 0; |
401 | 405 | ||
402 | /* Record minimum fill level */ | 406 | /* Record minimum fill level */ |
403 | if (unlikely(fill_level < rx_queue->min_fill)) | 407 | if (unlikely(fill_level < rx_queue->min_fill)) { |
404 | if (fill_level) | 408 | if (fill_level) |
405 | rx_queue->min_fill = fill_level; | 409 | rx_queue->min_fill = fill_level; |
410 | } | ||
406 | 411 | ||
407 | /* Acquire RX add lock. If this lock is contended, then a fast | 412 | /* Acquire RX add lock. If this lock is contended, then a fast |
408 | * fill must already be in progress (e.g. in the refill | 413 | * fill must already be in progress (e.g. in the refill |
@@ -552,7 +557,7 @@ static inline void efx_rx_packet_lro(struct efx_channel *channel, | |||
552 | struct skb_frag_struct frags; | 557 | struct skb_frag_struct frags; |
553 | 558 | ||
554 | frags.page = rx_buf->page; | 559 | frags.page = rx_buf->page; |
555 | frags.page_offset = RX_BUF_OFFSET(rx_buf); | 560 | frags.page_offset = efx_rx_buf_offset(rx_buf); |
556 | frags.size = rx_buf->len; | 561 | frags.size = rx_buf->len; |
557 | 562 | ||
558 | lro_receive_frags(lro_mgr, &frags, rx_buf->len, | 563 | lro_receive_frags(lro_mgr, &frags, rx_buf->len, |
@@ -597,7 +602,7 @@ static inline struct sk_buff *efx_rx_mk_skb(struct efx_rx_buffer *rx_buf, | |||
597 | if (unlikely(rx_buf->len > hdr_len)) { | 602 | if (unlikely(rx_buf->len > hdr_len)) { |
598 | struct skb_frag_struct *frag = skb_shinfo(skb)->frags; | 603 | struct skb_frag_struct *frag = skb_shinfo(skb)->frags; |
599 | frag->page = rx_buf->page; | 604 | frag->page = rx_buf->page; |
600 | frag->page_offset = RX_BUF_OFFSET(rx_buf) + hdr_len; | 605 | frag->page_offset = efx_rx_buf_offset(rx_buf) + hdr_len; |
601 | frag->size = skb->len - hdr_len; | 606 | frag->size = skb->len - hdr_len; |
602 | skb_shinfo(skb)->nr_frags = 1; | 607 | skb_shinfo(skb)->nr_frags = 1; |
603 | skb->data_len = frag->size; | 608 | skb->data_len = frag->size; |
@@ -851,7 +856,8 @@ void efx_fini_rx_queue(struct efx_rx_queue *rx_queue) | |||
851 | /* For a page that is part-way through splitting into RX buffers */ | 856 | /* For a page that is part-way through splitting into RX buffers */ |
852 | if (rx_queue->buf_page != NULL) { | 857 | if (rx_queue->buf_page != NULL) { |
853 | pci_unmap_page(rx_queue->efx->pci_dev, rx_queue->buf_dma_addr, | 858 | pci_unmap_page(rx_queue->efx->pci_dev, rx_queue->buf_dma_addr, |
854 | RX_PAGE_SIZE(rx_queue->efx), PCI_DMA_FROMDEVICE); | 859 | efx_rx_buf_size(rx_queue->efx), |
860 | PCI_DMA_FROMDEVICE); | ||
855 | __free_pages(rx_queue->buf_page, | 861 | __free_pages(rx_queue->buf_page, |
856 | rx_queue->efx->rx_buffer_order); | 862 | rx_queue->efx->rx_buffer_order); |
857 | rx_queue->buf_page = NULL; | 863 | rx_queue->buf_page = NULL; |
diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c index cbda15946e8f..3b2de9fe7f27 100644 --- a/drivers/net/sfc/selftest.c +++ b/drivers/net/sfc/selftest.c | |||
@@ -290,7 +290,7 @@ void efx_loopback_rx_packet(struct efx_nic *efx, | |||
290 | 290 | ||
291 | payload = &state->payload; | 291 | payload = &state->payload; |
292 | 292 | ||
293 | received = (struct efx_loopback_payload *)(char *) buf_ptr; | 293 | received = (struct efx_loopback_payload *) buf_ptr; |
294 | received->ip.saddr = payload->ip.saddr; | 294 | received->ip.saddr = payload->ip.saddr; |
295 | received->ip.check = payload->ip.check; | 295 | received->ip.check = payload->ip.check; |
296 | 296 | ||
@@ -424,10 +424,10 @@ static int efx_tx_loopback(struct efx_tx_queue *tx_queue) | |||
424 | * interrupt handler. */ | 424 | * interrupt handler. */ |
425 | smp_wmb(); | 425 | smp_wmb(); |
426 | 426 | ||
427 | if (NET_DEV_REGISTERED(efx)) | 427 | if (efx_dev_registered(efx)) |
428 | netif_tx_lock_bh(efx->net_dev); | 428 | netif_tx_lock_bh(efx->net_dev); |
429 | rc = efx_xmit(efx, tx_queue, skb); | 429 | rc = efx_xmit(efx, tx_queue, skb); |
430 | if (NET_DEV_REGISTERED(efx)) | 430 | if (efx_dev_registered(efx)) |
431 | netif_tx_unlock_bh(efx->net_dev); | 431 | netif_tx_unlock_bh(efx->net_dev); |
432 | 432 | ||
433 | if (rc != NETDEV_TX_OK) { | 433 | if (rc != NETDEV_TX_OK) { |
@@ -453,7 +453,7 @@ static int efx_rx_loopback(struct efx_tx_queue *tx_queue, | |||
453 | int tx_done = 0, rx_good, rx_bad; | 453 | int tx_done = 0, rx_good, rx_bad; |
454 | int i, rc = 0; | 454 | int i, rc = 0; |
455 | 455 | ||
456 | if (NET_DEV_REGISTERED(efx)) | 456 | if (efx_dev_registered(efx)) |
457 | netif_tx_lock_bh(efx->net_dev); | 457 | netif_tx_lock_bh(efx->net_dev); |
458 | 458 | ||
459 | /* Count the number of tx completions, and decrement the refcnt. Any | 459 | /* Count the number of tx completions, and decrement the refcnt. Any |
@@ -465,7 +465,7 @@ static int efx_rx_loopback(struct efx_tx_queue *tx_queue, | |||
465 | dev_kfree_skb_any(skb); | 465 | dev_kfree_skb_any(skb); |
466 | } | 466 | } |
467 | 467 | ||
468 | if (NET_DEV_REGISTERED(efx)) | 468 | if (efx_dev_registered(efx)) |
469 | netif_tx_unlock_bh(efx->net_dev); | 469 | netif_tx_unlock_bh(efx->net_dev); |
470 | 470 | ||
471 | /* Check TX completion and received packet counts */ | 471 | /* Check TX completion and received packet counts */ |
@@ -517,6 +517,8 @@ efx_test_loopback(struct efx_tx_queue *tx_queue, | |||
517 | state->packet_count = min(1 << (i << 2), state->packet_count); | 517 | state->packet_count = min(1 << (i << 2), state->packet_count); |
518 | state->skbs = kzalloc(sizeof(state->skbs[0]) * | 518 | state->skbs = kzalloc(sizeof(state->skbs[0]) * |
519 | state->packet_count, GFP_KERNEL); | 519 | state->packet_count, GFP_KERNEL); |
520 | if (!state->skbs) | ||
521 | return -ENOMEM; | ||
520 | state->flush = 0; | 522 | state->flush = 0; |
521 | 523 | ||
522 | EFX_LOG(efx, "TX queue %d testing %s loopback with %d " | 524 | EFX_LOG(efx, "TX queue %d testing %s loopback with %d " |
@@ -700,7 +702,7 @@ int efx_offline_test(struct efx_nic *efx, | |||
700 | * "flushing" so all inflight packets are dropped */ | 702 | * "flushing" so all inflight packets are dropped */ |
701 | BUG_ON(efx->loopback_selftest); | 703 | BUG_ON(efx->loopback_selftest); |
702 | state->flush = 1; | 704 | state->flush = 1; |
703 | efx->loopback_selftest = (void *)state; | 705 | efx->loopback_selftest = state; |
704 | 706 | ||
705 | rc = efx_test_loopbacks(efx, tests, loopback_modes); | 707 | rc = efx_test_loopbacks(efx, tests, loopback_modes); |
706 | 708 | ||
diff --git a/drivers/net/sfc/sfe4001.c b/drivers/net/sfc/sfe4001.c index 725d1a539c49..66a0d1442aba 100644 --- a/drivers/net/sfc/sfe4001.c +++ b/drivers/net/sfc/sfe4001.c | |||
@@ -116,18 +116,18 @@ void sfe4001_poweroff(struct efx_nic *efx) | |||
116 | 116 | ||
117 | /* Turn off all power rails */ | 117 | /* Turn off all power rails */ |
118 | out = 0xff; | 118 | out = 0xff; |
119 | (void) efx_i2c_write(i2c, PCA9539, P0_OUT, &out, 1); | 119 | efx_i2c_write(i2c, PCA9539, P0_OUT, &out, 1); |
120 | 120 | ||
121 | /* Disable port 1 outputs on IO expander */ | 121 | /* Disable port 1 outputs on IO expander */ |
122 | cfg = 0xff; | 122 | cfg = 0xff; |
123 | (void) efx_i2c_write(i2c, PCA9539, P1_CONFIG, &cfg, 1); | 123 | efx_i2c_write(i2c, PCA9539, P1_CONFIG, &cfg, 1); |
124 | 124 | ||
125 | /* Disable port 0 outputs on IO expander */ | 125 | /* Disable port 0 outputs on IO expander */ |
126 | cfg = 0xff; | 126 | cfg = 0xff; |
127 | (void) efx_i2c_write(i2c, PCA9539, P0_CONFIG, &cfg, 1); | 127 | efx_i2c_write(i2c, PCA9539, P0_CONFIG, &cfg, 1); |
128 | 128 | ||
129 | /* Clear any over-temperature alert */ | 129 | /* Clear any over-temperature alert */ |
130 | (void) efx_i2c_read(i2c, MAX6647, RSL, &in, 1); | 130 | efx_i2c_read(i2c, MAX6647, RSL, &in, 1); |
131 | } | 131 | } |
132 | 132 | ||
133 | /* The P0_EN_3V3X line on SFE4001 boards (from A2 onward) is connected | 133 | /* The P0_EN_3V3X line on SFE4001 boards (from A2 onward) is connected |
@@ -253,14 +253,14 @@ done: | |||
253 | fail3: | 253 | fail3: |
254 | /* Turn off all power rails */ | 254 | /* Turn off all power rails */ |
255 | out = 0xff; | 255 | out = 0xff; |
256 | (void) efx_i2c_write(i2c, PCA9539, P0_OUT, &out, 1); | 256 | efx_i2c_write(i2c, PCA9539, P0_OUT, &out, 1); |
257 | /* Disable port 1 outputs on IO expander */ | 257 | /* Disable port 1 outputs on IO expander */ |
258 | out = 0xff; | 258 | out = 0xff; |
259 | (void) efx_i2c_write(i2c, PCA9539, P1_CONFIG, &out, 1); | 259 | efx_i2c_write(i2c, PCA9539, P1_CONFIG, &out, 1); |
260 | fail2: | 260 | fail2: |
261 | /* Disable port 0 outputs on IO expander */ | 261 | /* Disable port 0 outputs on IO expander */ |
262 | out = 0xff; | 262 | out = 0xff; |
263 | (void) efx_i2c_write(i2c, PCA9539, P0_CONFIG, &out, 1); | 263 | efx_i2c_write(i2c, PCA9539, P0_CONFIG, &out, 1); |
264 | fail1: | 264 | fail1: |
265 | return rc; | 265 | return rc; |
266 | } | 266 | } |
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c index b1cd6deec01f..c0146061c326 100644 --- a/drivers/net/sfc/tenxpress.c +++ b/drivers/net/sfc/tenxpress.c | |||
@@ -211,6 +211,8 @@ static int tenxpress_phy_init(struct efx_nic *efx) | |||
211 | int rc = 0; | 211 | int rc = 0; |
212 | 212 | ||
213 | phy_data = kzalloc(sizeof(*phy_data), GFP_KERNEL); | 213 | phy_data = kzalloc(sizeof(*phy_data), GFP_KERNEL); |
214 | if (!phy_data) | ||
215 | return -ENOMEM; | ||
214 | efx->phy_data = phy_data; | 216 | efx->phy_data = phy_data; |
215 | 217 | ||
216 | tenxpress_set_state(efx, TENXPRESS_STATUS_NORMAL); | 218 | tenxpress_set_state(efx, TENXPRESS_STATUS_NORMAL); |
@@ -376,7 +378,7 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx) | |||
376 | * perform a special software reset */ | 378 | * perform a special software reset */ |
377 | if ((phy_data->tx_disabled && !efx->tx_disabled) || | 379 | if ((phy_data->tx_disabled && !efx->tx_disabled) || |
378 | loop_change) { | 380 | loop_change) { |
379 | (void) tenxpress_special_reset(efx); | 381 | tenxpress_special_reset(efx); |
380 | falcon_reset_xaui(efx); | 382 | falcon_reset_xaui(efx); |
381 | } | 383 | } |
382 | 384 | ||
diff --git a/drivers/net/sfc/tx.c b/drivers/net/sfc/tx.c index 9b436f5b4888..5cdd082ab8f6 100644 --- a/drivers/net/sfc/tx.c +++ b/drivers/net/sfc/tx.c | |||
@@ -387,7 +387,7 @@ void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index) | |||
387 | if (unlikely(tx_queue->stopped)) { | 387 | if (unlikely(tx_queue->stopped)) { |
388 | fill_level = tx_queue->insert_count - tx_queue->read_count; | 388 | fill_level = tx_queue->insert_count - tx_queue->read_count; |
389 | if (fill_level < EFX_NETDEV_TX_THRESHOLD(tx_queue)) { | 389 | if (fill_level < EFX_NETDEV_TX_THRESHOLD(tx_queue)) { |
390 | EFX_BUG_ON_PARANOID(!NET_DEV_REGISTERED(efx)); | 390 | EFX_BUG_ON_PARANOID(!efx_dev_registered(efx)); |
391 | 391 | ||
392 | /* Do this under netif_tx_lock(), to avoid racing | 392 | /* Do this under netif_tx_lock(), to avoid racing |
393 | * with efx_xmit(). */ | 393 | * with efx_xmit(). */ |
@@ -639,11 +639,12 @@ static void efx_tsoh_block_free(struct efx_tx_queue *tx_queue, | |||
639 | base_dma = tsoh->dma_addr & PAGE_MASK; | 639 | base_dma = tsoh->dma_addr & PAGE_MASK; |
640 | 640 | ||
641 | p = &tx_queue->tso_headers_free; | 641 | p = &tx_queue->tso_headers_free; |
642 | while (*p != NULL) | 642 | while (*p != NULL) { |
643 | if (((unsigned long)*p & PAGE_MASK) == base_kva) | 643 | if (((unsigned long)*p & PAGE_MASK) == base_kva) |
644 | *p = (*p)->next; | 644 | *p = (*p)->next; |
645 | else | 645 | else |
646 | p = &(*p)->next; | 646 | p = &(*p)->next; |
647 | } | ||
647 | 648 | ||
648 | pci_free_consistent(pci_dev, PAGE_SIZE, (void *)base_kva, base_dma); | 649 | pci_free_consistent(pci_dev, PAGE_SIZE, (void *)base_kva, base_dma); |
649 | } | 650 | } |
@@ -939,9 +940,10 @@ static inline int tso_start_new_packet(struct efx_tx_queue *tx_queue, | |||
939 | 940 | ||
940 | /* Allocate a DMA-mapped header buffer. */ | 941 | /* Allocate a DMA-mapped header buffer. */ |
941 | if (likely(TSOH_SIZE(st->p.header_length) <= TSOH_STD_SIZE)) { | 942 | if (likely(TSOH_SIZE(st->p.header_length) <= TSOH_STD_SIZE)) { |
942 | if (tx_queue->tso_headers_free == NULL) | 943 | if (tx_queue->tso_headers_free == NULL) { |
943 | if (efx_tsoh_block_alloc(tx_queue)) | 944 | if (efx_tsoh_block_alloc(tx_queue)) |
944 | return -1; | 945 | return -1; |
946 | } | ||
945 | EFX_BUG_ON_PARANOID(!tx_queue->tso_headers_free); | 947 | EFX_BUG_ON_PARANOID(!tx_queue->tso_headers_free); |
946 | tsoh = tx_queue->tso_headers_free; | 948 | tsoh = tx_queue->tso_headers_free; |
947 | tx_queue->tso_headers_free = tsoh->next; | 949 | tx_queue->tso_headers_free = tsoh->next; |
@@ -1106,9 +1108,10 @@ static void efx_fini_tso(struct efx_tx_queue *tx_queue) | |||
1106 | { | 1108 | { |
1107 | unsigned i; | 1109 | unsigned i; |
1108 | 1110 | ||
1109 | if (tx_queue->buffer) | 1111 | if (tx_queue->buffer) { |
1110 | for (i = 0; i <= tx_queue->efx->type->txd_ring_mask; ++i) | 1112 | for (i = 0; i <= tx_queue->efx->type->txd_ring_mask; ++i) |
1111 | efx_tsoh_free(tx_queue, &tx_queue->buffer[i]); | 1113 | efx_tsoh_free(tx_queue, &tx_queue->buffer[i]); |
1114 | } | ||
1112 | 1115 | ||
1113 | while (tx_queue->tso_headers_free != NULL) | 1116 | while (tx_queue->tso_headers_free != NULL) |
1114 | efx_tsoh_block_free(tx_queue, tx_queue->tso_headers_free, | 1117 | efx_tsoh_block_free(tx_queue, tx_queue->tso_headers_free, |
diff --git a/drivers/net/sfc/workarounds.h b/drivers/net/sfc/workarounds.h index dca62f190198..35ab19c27f8d 100644 --- a/drivers/net/sfc/workarounds.h +++ b/drivers/net/sfc/workarounds.h | |||
@@ -16,7 +16,7 @@ | |||
16 | */ | 16 | */ |
17 | 17 | ||
18 | #define EFX_WORKAROUND_ALWAYS(efx) 1 | 18 | #define EFX_WORKAROUND_ALWAYS(efx) 1 |
19 | #define EFX_WORKAROUND_FALCON_A(efx) (FALCON_REV(efx) <= FALCON_REV_A1) | 19 | #define EFX_WORKAROUND_FALCON_A(efx) (falcon_rev(efx) <= FALCON_REV_A1) |
20 | 20 | ||
21 | /* XAUI resets if link not detected */ | 21 | /* XAUI resets if link not detected */ |
22 | #define EFX_WORKAROUND_5147 EFX_WORKAROUND_ALWAYS | 22 | #define EFX_WORKAROUND_5147 EFX_WORKAROUND_ALWAYS |
diff --git a/drivers/net/sfc/xfp_phy.c b/drivers/net/sfc/xfp_phy.c index 3b9f9ddbc372..f3684ad28887 100644 --- a/drivers/net/sfc/xfp_phy.c +++ b/drivers/net/sfc/xfp_phy.c | |||
@@ -85,7 +85,9 @@ static int xfp_phy_init(struct efx_nic *efx) | |||
85 | int rc; | 85 | int rc; |
86 | 86 | ||
87 | phy_data = kzalloc(sizeof(struct xfp_phy_data), GFP_KERNEL); | 87 | phy_data = kzalloc(sizeof(struct xfp_phy_data), GFP_KERNEL); |
88 | efx->phy_data = (void *) phy_data; | 88 | if (!phy_data) |
89 | return -ENOMEM; | ||
90 | efx->phy_data = phy_data; | ||
89 | 91 | ||
90 | EFX_INFO(efx, "XFP: PHY ID reg %x (OUI %x model %x revision" | 92 | EFX_INFO(efx, "XFP: PHY ID reg %x (OUI %x model %x revision" |
91 | " %x)\n", devid, MDIO_ID_OUI(devid), MDIO_ID_MODEL(devid), | 93 | " %x)\n", devid, MDIO_ID_OUI(devid), MDIO_ID_MODEL(devid), |
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index f226bcac7d17..62436b3a18c6 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -1159,17 +1159,9 @@ static int sky2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | |||
1159 | } | 1159 | } |
1160 | 1160 | ||
1161 | #ifdef SKY2_VLAN_TAG_USED | 1161 | #ifdef SKY2_VLAN_TAG_USED |
1162 | static void sky2_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) | 1162 | static void sky2_set_vlan_mode(struct sky2_hw *hw, u16 port, bool onoff) |
1163 | { | 1163 | { |
1164 | struct sky2_port *sky2 = netdev_priv(dev); | 1164 | if (onoff) { |
1165 | struct sky2_hw *hw = sky2->hw; | ||
1166 | u16 port = sky2->port; | ||
1167 | |||
1168 | netif_tx_lock_bh(dev); | ||
1169 | napi_disable(&hw->napi); | ||
1170 | |||
1171 | sky2->vlgrp = grp; | ||
1172 | if (grp) { | ||
1173 | sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), | 1165 | sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), |
1174 | RX_VLAN_STRIP_ON); | 1166 | RX_VLAN_STRIP_ON); |
1175 | sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), | 1167 | sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), |
@@ -1180,6 +1172,19 @@ static void sky2_vlan_rx_register(struct net_device *dev, struct vlan_group *grp | |||
1180 | sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), | 1172 | sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), |
1181 | TX_VLAN_TAG_OFF); | 1173 | TX_VLAN_TAG_OFF); |
1182 | } | 1174 | } |
1175 | } | ||
1176 | |||
1177 | static void sky2_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) | ||
1178 | { | ||
1179 | struct sky2_port *sky2 = netdev_priv(dev); | ||
1180 | struct sky2_hw *hw = sky2->hw; | ||
1181 | u16 port = sky2->port; | ||
1182 | |||
1183 | netif_tx_lock_bh(dev); | ||
1184 | napi_disable(&hw->napi); | ||
1185 | |||
1186 | sky2->vlgrp = grp; | ||
1187 | sky2_set_vlan_mode(hw, port, grp != NULL); | ||
1183 | 1188 | ||
1184 | sky2_read32(hw, B0_Y2_SP_LISR); | 1189 | sky2_read32(hw, B0_Y2_SP_LISR); |
1185 | napi_enable(&hw->napi); | 1190 | napi_enable(&hw->napi); |
@@ -1418,6 +1423,10 @@ static int sky2_up(struct net_device *dev) | |||
1418 | sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map, | 1423 | sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map, |
1419 | TX_RING_SIZE - 1); | 1424 | TX_RING_SIZE - 1); |
1420 | 1425 | ||
1426 | #ifdef SKY2_VLAN_TAG_USED | ||
1427 | sky2_set_vlan_mode(hw, port, sky2->vlgrp != NULL); | ||
1428 | #endif | ||
1429 | |||
1421 | err = sky2_rx_start(sky2); | 1430 | err = sky2_rx_start(sky2); |
1422 | if (err) | 1431 | if (err) |
1423 | goto err_out; | 1432 | goto err_out; |
@@ -4395,7 +4404,9 @@ static int sky2_resume(struct pci_dev *pdev) | |||
4395 | if (err) { | 4404 | if (err) { |
4396 | printk(KERN_ERR PFX "%s: could not up: %d\n", | 4405 | printk(KERN_ERR PFX "%s: could not up: %d\n", |
4397 | dev->name, err); | 4406 | dev->name, err); |
4407 | rtnl_lock(); | ||
4398 | dev_close(dev); | 4408 | dev_close(dev); |
4409 | rtnl_unlock(); | ||
4399 | goto out; | 4410 | goto out; |
4400 | } | 4411 | } |
4401 | } | 4412 | } |
diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c index 4e2800205189..e2ee91a6ae7e 100644 --- a/drivers/net/smc911x.c +++ b/drivers/net/smc911x.c | |||
@@ -136,7 +136,6 @@ struct smc911x_local { | |||
136 | 136 | ||
137 | /* work queue */ | 137 | /* work queue */ |
138 | struct work_struct phy_configure; | 138 | struct work_struct phy_configure; |
139 | int work_pending; | ||
140 | 139 | ||
141 | int tx_throttle; | 140 | int tx_throttle; |
142 | spinlock_t lock; | 141 | spinlock_t lock; |
@@ -960,11 +959,11 @@ static void smc911x_phy_configure(struct work_struct *work) | |||
960 | * We should not be called if phy_type is zero. | 959 | * We should not be called if phy_type is zero. |
961 | */ | 960 | */ |
962 | if (lp->phy_type == 0) | 961 | if (lp->phy_type == 0) |
963 | goto smc911x_phy_configure_exit_nolock; | 962 | return; |
964 | 963 | ||
965 | if (smc911x_phy_reset(dev, phyaddr)) { | 964 | if (smc911x_phy_reset(dev, phyaddr)) { |
966 | printk("%s: PHY reset timed out\n", dev->name); | 965 | printk("%s: PHY reset timed out\n", dev->name); |
967 | goto smc911x_phy_configure_exit_nolock; | 966 | return; |
968 | } | 967 | } |
969 | spin_lock_irqsave(&lp->lock, flags); | 968 | spin_lock_irqsave(&lp->lock, flags); |
970 | 969 | ||
@@ -1033,8 +1032,6 @@ static void smc911x_phy_configure(struct work_struct *work) | |||
1033 | 1032 | ||
1034 | smc911x_phy_configure_exit: | 1033 | smc911x_phy_configure_exit: |
1035 | spin_unlock_irqrestore(&lp->lock, flags); | 1034 | spin_unlock_irqrestore(&lp->lock, flags); |
1036 | smc911x_phy_configure_exit_nolock: | ||
1037 | lp->work_pending = 0; | ||
1038 | } | 1035 | } |
1039 | 1036 | ||
1040 | /* | 1037 | /* |
@@ -1356,11 +1353,8 @@ static void smc911x_timeout(struct net_device *dev) | |||
1356 | * smc911x_phy_configure() calls msleep() which calls schedule_timeout() | 1353 | * smc911x_phy_configure() calls msleep() which calls schedule_timeout() |
1357 | * which calls schedule(). Hence we use a work queue. | 1354 | * which calls schedule(). Hence we use a work queue. |
1358 | */ | 1355 | */ |
1359 | if (lp->phy_type != 0) { | 1356 | if (lp->phy_type != 0) |
1360 | if (schedule_work(&lp->phy_configure)) { | 1357 | schedule_work(&lp->phy_configure); |
1361 | lp->work_pending = 1; | ||
1362 | } | ||
1363 | } | ||
1364 | 1358 | ||
1365 | /* We can accept TX packets again */ | 1359 | /* We can accept TX packets again */ |
1366 | dev->trans_start = jiffies; | 1360 | dev->trans_start = jiffies; |
@@ -1531,16 +1525,8 @@ static int smc911x_close(struct net_device *dev) | |||
1531 | if (lp->phy_type != 0) { | 1525 | if (lp->phy_type != 0) { |
1532 | /* We need to ensure that no calls to | 1526 | /* We need to ensure that no calls to |
1533 | * smc911x_phy_configure are pending. | 1527 | * smc911x_phy_configure are pending. |
1534 | |||
1535 | * flush_scheduled_work() cannot be called because we | ||
1536 | * are running with the netlink semaphore held (from | ||
1537 | * devinet_ioctl()) and the pending work queue | ||
1538 | * contains linkwatch_event() (scheduled by | ||
1539 | * netif_carrier_off() above). linkwatch_event() also | ||
1540 | * wants the netlink semaphore. | ||
1541 | */ | 1528 | */ |
1542 | while (lp->work_pending) | 1529 | cancel_work_sync(&lp->phy_configure); |
1543 | schedule(); | ||
1544 | smc911x_phy_powerdown(dev, lp->mii.phy_id); | 1530 | smc911x_phy_powerdown(dev, lp->mii.phy_id); |
1545 | } | 1531 | } |
1546 | 1532 | ||
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c index a188e33484e6..f2051b209da2 100644 --- a/drivers/net/smc91x.c +++ b/drivers/net/smc91x.c | |||
@@ -1016,15 +1016,8 @@ static void smc_phy_powerdown(struct net_device *dev) | |||
1016 | 1016 | ||
1017 | /* We need to ensure that no calls to smc_phy_configure are | 1017 | /* We need to ensure that no calls to smc_phy_configure are |
1018 | pending. | 1018 | pending. |
1019 | |||
1020 | flush_scheduled_work() cannot be called because we are | ||
1021 | running with the netlink semaphore held (from | ||
1022 | devinet_ioctl()) and the pending work queue contains | ||
1023 | linkwatch_event() (scheduled by netif_carrier_off() | ||
1024 | above). linkwatch_event() also wants the netlink semaphore. | ||
1025 | */ | 1019 | */ |
1026 | while(lp->work_pending) | 1020 | cancel_work_sync(&lp->phy_configure); |
1027 | yield(); | ||
1028 | 1021 | ||
1029 | bmcr = smc_phy_read(dev, phy, MII_BMCR); | 1022 | bmcr = smc_phy_read(dev, phy, MII_BMCR); |
1030 | smc_phy_write(dev, phy, MII_BMCR, bmcr | BMCR_PDOWN); | 1023 | smc_phy_write(dev, phy, MII_BMCR, bmcr | BMCR_PDOWN); |
@@ -1161,7 +1154,6 @@ static void smc_phy_configure(struct work_struct *work) | |||
1161 | smc_phy_configure_exit: | 1154 | smc_phy_configure_exit: |
1162 | SMC_SELECT_BANK(lp, 2); | 1155 | SMC_SELECT_BANK(lp, 2); |
1163 | spin_unlock_irq(&lp->lock); | 1156 | spin_unlock_irq(&lp->lock); |
1164 | lp->work_pending = 0; | ||
1165 | } | 1157 | } |
1166 | 1158 | ||
1167 | /* | 1159 | /* |
@@ -1389,11 +1381,8 @@ static void smc_timeout(struct net_device *dev) | |||
1389 | * smc_phy_configure() calls msleep() which calls schedule_timeout() | 1381 | * smc_phy_configure() calls msleep() which calls schedule_timeout() |
1390 | * which calls schedule(). Hence we use a work queue. | 1382 | * which calls schedule(). Hence we use a work queue. |
1391 | */ | 1383 | */ |
1392 | if (lp->phy_type != 0) { | 1384 | if (lp->phy_type != 0) |
1393 | if (schedule_work(&lp->phy_configure)) { | 1385 | schedule_work(&lp->phy_configure); |
1394 | lp->work_pending = 1; | ||
1395 | } | ||
1396 | } | ||
1397 | 1386 | ||
1398 | /* We can accept TX packets again */ | 1387 | /* We can accept TX packets again */ |
1399 | dev->trans_start = jiffies; | 1388 | dev->trans_start = jiffies; |
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h index 69e97a1cb1c4..8606818653f8 100644 --- a/drivers/net/smc91x.h +++ b/drivers/net/smc91x.h | |||
@@ -93,14 +93,14 @@ | |||
93 | #define SMC_insw(a, r, p, l) insw ((unsigned long *)((a) + (r)), p, l) | 93 | #define SMC_insw(a, r, p, l) insw ((unsigned long *)((a) + (r)), p, l) |
94 | # endif | 94 | # endif |
95 | /* check if the mac in reg is valid */ | 95 | /* check if the mac in reg is valid */ |
96 | #define SMC_GET_MAC_ADDR(addr) \ | 96 | #define SMC_GET_MAC_ADDR(lp, addr) \ |
97 | do { \ | 97 | do { \ |
98 | unsigned int __v; \ | 98 | unsigned int __v; \ |
99 | __v = SMC_inw(ioaddr, ADDR0_REG); \ | 99 | __v = SMC_inw(ioaddr, ADDR0_REG(lp)); \ |
100 | addr[0] = __v; addr[1] = __v >> 8; \ | 100 | addr[0] = __v; addr[1] = __v >> 8; \ |
101 | __v = SMC_inw(ioaddr, ADDR1_REG); \ | 101 | __v = SMC_inw(ioaddr, ADDR1_REG(lp)); \ |
102 | addr[2] = __v; addr[3] = __v >> 8; \ | 102 | addr[2] = __v; addr[3] = __v >> 8; \ |
103 | __v = SMC_inw(ioaddr, ADDR2_REG); \ | 103 | __v = SMC_inw(ioaddr, ADDR2_REG(lp)); \ |
104 | addr[4] = __v; addr[5] = __v >> 8; \ | 104 | addr[4] = __v; addr[5] = __v >> 8; \ |
105 | if (*(u32 *)(&addr[0]) == 0xFFFFFFFF) { \ | 105 | if (*(u32 *)(&addr[0]) == 0xFFFFFFFF) { \ |
106 | random_ether_addr(addr); \ | 106 | random_ether_addr(addr); \ |
diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c index b4e7f30ea4e8..1aa425be3067 100644 --- a/drivers/net/sunhme.c +++ b/drivers/net/sunhme.c | |||
@@ -111,7 +111,7 @@ static __inline__ void tx_add_log(struct happy_meal *hp, unsigned int a, unsigne | |||
111 | struct hme_tx_logent *tlp; | 111 | struct hme_tx_logent *tlp; |
112 | unsigned long flags; | 112 | unsigned long flags; |
113 | 113 | ||
114 | save_and_cli(flags); | 114 | local_irq_save(flags); |
115 | tlp = &tx_log[txlog_cur_entry]; | 115 | tlp = &tx_log[txlog_cur_entry]; |
116 | tlp->tstamp = (unsigned int)jiffies; | 116 | tlp->tstamp = (unsigned int)jiffies; |
117 | tlp->tx_new = hp->tx_new; | 117 | tlp->tx_new = hp->tx_new; |
@@ -119,7 +119,7 @@ static __inline__ void tx_add_log(struct happy_meal *hp, unsigned int a, unsigne | |||
119 | tlp->action = a; | 119 | tlp->action = a; |
120 | tlp->status = s; | 120 | tlp->status = s; |
121 | txlog_cur_entry = (txlog_cur_entry + 1) & (TX_LOG_LEN - 1); | 121 | txlog_cur_entry = (txlog_cur_entry + 1) & (TX_LOG_LEN - 1); |
122 | restore_flags(flags); | 122 | local_irq_restore(flags); |
123 | } | 123 | } |
124 | static __inline__ void tx_dump_log(void) | 124 | static __inline__ void tx_dump_log(void) |
125 | { | 125 | { |
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 07b3f77e7626..cc4bde852542 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -64,8 +64,8 @@ | |||
64 | 64 | ||
65 | #define DRV_MODULE_NAME "tg3" | 65 | #define DRV_MODULE_NAME "tg3" |
66 | #define PFX DRV_MODULE_NAME ": " | 66 | #define PFX DRV_MODULE_NAME ": " |
67 | #define DRV_MODULE_VERSION "3.92" | 67 | #define DRV_MODULE_VERSION "3.92.1" |
68 | #define DRV_MODULE_RELDATE "May 2, 2008" | 68 | #define DRV_MODULE_RELDATE "June 9, 2008" |
69 | 69 | ||
70 | #define TG3_DEF_MAC_MODE 0 | 70 | #define TG3_DEF_MAC_MODE 0 |
71 | #define TG3_DEF_RX_MODE 0 | 71 | #define TG3_DEF_RX_MODE 0 |
@@ -1295,6 +1295,21 @@ static void tg3_frob_aux_power(struct tg3 *tp) | |||
1295 | GRC_LCLCTRL_GPIO_OUTPUT0 | | 1295 | GRC_LCLCTRL_GPIO_OUTPUT0 | |
1296 | GRC_LCLCTRL_GPIO_OUTPUT1), | 1296 | GRC_LCLCTRL_GPIO_OUTPUT1), |
1297 | 100); | 1297 | 100); |
1298 | } else if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5761) { | ||
1299 | /* The 5761 non-e device swaps GPIO 0 and GPIO 2. */ | ||
1300 | u32 grc_local_ctrl = GRC_LCLCTRL_GPIO_OE0 | | ||
1301 | GRC_LCLCTRL_GPIO_OE1 | | ||
1302 | GRC_LCLCTRL_GPIO_OE2 | | ||
1303 | GRC_LCLCTRL_GPIO_OUTPUT0 | | ||
1304 | GRC_LCLCTRL_GPIO_OUTPUT1 | | ||
1305 | tp->grc_local_ctrl; | ||
1306 | tw32_wait_f(GRC_LOCAL_CTRL, grc_local_ctrl, 100); | ||
1307 | |||
1308 | grc_local_ctrl |= GRC_LCLCTRL_GPIO_OUTPUT2; | ||
1309 | tw32_wait_f(GRC_LOCAL_CTRL, grc_local_ctrl, 100); | ||
1310 | |||
1311 | grc_local_ctrl &= ~GRC_LCLCTRL_GPIO_OUTPUT0; | ||
1312 | tw32_wait_f(GRC_LOCAL_CTRL, grc_local_ctrl, 100); | ||
1298 | } else { | 1313 | } else { |
1299 | u32 no_gpio2; | 1314 | u32 no_gpio2; |
1300 | u32 grc_local_ctrl = 0; | 1315 | u32 grc_local_ctrl = 0; |
@@ -3168,8 +3183,7 @@ static int tg3_setup_fiber_mii_phy(struct tg3 *tp, int force_reset) | |||
3168 | err |= tg3_readphy(tp, MII_BMCR, &bmcr); | 3183 | err |= tg3_readphy(tp, MII_BMCR, &bmcr); |
3169 | 3184 | ||
3170 | if ((tp->link_config.autoneg == AUTONEG_ENABLE) && !force_reset && | 3185 | if ((tp->link_config.autoneg == AUTONEG_ENABLE) && !force_reset && |
3171 | (tp->tg3_flags2 & TG3_FLG2_PARALLEL_DETECT) && | 3186 | (tp->tg3_flags2 & TG3_FLG2_PARALLEL_DETECT)) { |
3172 | tp->link_config.flowctrl == tp->link_config.active_flowctrl) { | ||
3173 | /* do nothing, just check for link up at the end */ | 3187 | /* do nothing, just check for link up at the end */ |
3174 | } else if (tp->link_config.autoneg == AUTONEG_ENABLE) { | 3188 | } else if (tp->link_config.autoneg == AUTONEG_ENABLE) { |
3175 | u32 adv, new_adv; | 3189 | u32 adv, new_adv; |
@@ -8599,7 +8613,7 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | |||
8599 | (cmd->speed == SPEED_1000)) | 8613 | (cmd->speed == SPEED_1000)) |
8600 | return -EINVAL; | 8614 | return -EINVAL; |
8601 | else if ((cmd->speed == SPEED_1000) && | 8615 | else if ((cmd->speed == SPEED_1000) && |
8602 | (tp->tg3_flags2 & TG3_FLAG_10_100_ONLY)) | 8616 | (tp->tg3_flags & TG3_FLAG_10_100_ONLY)) |
8603 | return -EINVAL; | 8617 | return -EINVAL; |
8604 | 8618 | ||
8605 | tg3_full_lock(tp, 0); | 8619 | tg3_full_lock(tp, 0); |
@@ -11768,6 +11782,15 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) | |||
11768 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755) | 11782 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755) |
11769 | tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_UART_SEL; | 11783 | tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_UART_SEL; |
11770 | 11784 | ||
11785 | if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5761) { | ||
11786 | /* Turn off the debug UART. */ | ||
11787 | tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_UART_SEL; | ||
11788 | if (tp->tg3_flags2 & TG3_FLG2_IS_NIC) | ||
11789 | /* Keep VMain power. */ | ||
11790 | tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_OE0 | | ||
11791 | GRC_LCLCTRL_GPIO_OUTPUT0; | ||
11792 | } | ||
11793 | |||
11771 | /* Force the chip into D0. */ | 11794 | /* Force the chip into D0. */ |
11772 | err = tg3_set_power_state(tp, PCI_D0); | 11795 | err = tg3_set_power_state(tp, PCI_D0); |
11773 | if (err) { | 11796 | if (err) { |
diff --git a/drivers/net/tokenring/3c359.h b/drivers/net/tokenring/3c359.h index b880cba0f6fd..74cf8e1a181b 100644 --- a/drivers/net/tokenring/3c359.h +++ b/drivers/net/tokenring/3c359.h | |||
@@ -264,7 +264,7 @@ struct xl_private { | |||
264 | u16 asb; | 264 | u16 asb; |
265 | 265 | ||
266 | u8 __iomem *xl_mmio; | 266 | u8 __iomem *xl_mmio; |
267 | char *xl_card_name; | 267 | const char *xl_card_name; |
268 | struct pci_dev *pdev ; | 268 | struct pci_dev *pdev ; |
269 | 269 | ||
270 | spinlock_t xl_lock ; | 270 | spinlock_t xl_lock ; |
diff --git a/drivers/net/tokenring/olympic.h b/drivers/net/tokenring/olympic.h index c91956310fb2..10fbba08978f 100644 --- a/drivers/net/tokenring/olympic.h +++ b/drivers/net/tokenring/olympic.h | |||
@@ -254,7 +254,7 @@ struct olympic_private { | |||
254 | u8 __iomem *olympic_mmio; | 254 | u8 __iomem *olympic_mmio; |
255 | u8 __iomem *olympic_lap; | 255 | u8 __iomem *olympic_lap; |
256 | struct pci_dev *pdev ; | 256 | struct pci_dev *pdev ; |
257 | char *olympic_card_name ; | 257 | const char *olympic_card_name; |
258 | 258 | ||
259 | spinlock_t olympic_lock ; | 259 | spinlock_t olympic_lock ; |
260 | 260 | ||
diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c index f9d13fa05d64..af8d2c436efd 100644 --- a/drivers/net/tulip/tulip_core.c +++ b/drivers/net/tulip/tulip_core.c | |||
@@ -731,7 +731,7 @@ static void tulip_down (struct net_device *dev) | |||
731 | void __iomem *ioaddr = tp->base_addr; | 731 | void __iomem *ioaddr = tp->base_addr; |
732 | unsigned long flags; | 732 | unsigned long flags; |
733 | 733 | ||
734 | flush_scheduled_work(); | 734 | cancel_work_sync(&tp->media_work); |
735 | 735 | ||
736 | #ifdef CONFIG_TULIP_NAPI | 736 | #ifdef CONFIG_TULIP_NAPI |
737 | napi_disable(&tp->napi); | 737 | napi_disable(&tp->napi); |
@@ -1729,12 +1729,15 @@ static int tulip_suspend (struct pci_dev *pdev, pm_message_t state) | |||
1729 | if (!dev) | 1729 | if (!dev) |
1730 | return -EINVAL; | 1730 | return -EINVAL; |
1731 | 1731 | ||
1732 | if (netif_running(dev)) | 1732 | if (!netif_running(dev)) |
1733 | tulip_down(dev); | 1733 | goto save_state; |
1734 | |||
1735 | tulip_down(dev); | ||
1734 | 1736 | ||
1735 | netif_device_detach(dev); | 1737 | netif_device_detach(dev); |
1736 | free_irq(dev->irq, dev); | 1738 | free_irq(dev->irq, dev); |
1737 | 1739 | ||
1740 | save_state: | ||
1738 | pci_save_state(pdev); | 1741 | pci_save_state(pdev); |
1739 | pci_disable_device(pdev); | 1742 | pci_disable_device(pdev); |
1740 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | 1743 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); |
@@ -1754,6 +1757,9 @@ static int tulip_resume(struct pci_dev *pdev) | |||
1754 | pci_set_power_state(pdev, PCI_D0); | 1757 | pci_set_power_state(pdev, PCI_D0); |
1755 | pci_restore_state(pdev); | 1758 | pci_restore_state(pdev); |
1756 | 1759 | ||
1760 | if (!netif_running(dev)) | ||
1761 | return 0; | ||
1762 | |||
1757 | if ((retval = pci_enable_device(pdev))) { | 1763 | if ((retval = pci_enable_device(pdev))) { |
1758 | printk (KERN_ERR "tulip: pci_enable_device failed in resume\n"); | 1764 | printk (KERN_ERR "tulip: pci_enable_device failed in resume\n"); |
1759 | return retval; | 1765 | return retval; |
diff --git a/drivers/net/tulip/uli526x.c b/drivers/net/tulip/uli526x.c index 2511ca7a12aa..e9e628621639 100644 --- a/drivers/net/tulip/uli526x.c +++ b/drivers/net/tulip/uli526x.c | |||
@@ -225,6 +225,9 @@ static void uli526x_set_filter_mode(struct net_device *); | |||
225 | static const struct ethtool_ops netdev_ethtool_ops; | 225 | static const struct ethtool_ops netdev_ethtool_ops; |
226 | static u16 read_srom_word(long, int); | 226 | static u16 read_srom_word(long, int); |
227 | static irqreturn_t uli526x_interrupt(int, void *); | 227 | static irqreturn_t uli526x_interrupt(int, void *); |
228 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
229 | static void uli526x_poll(struct net_device *dev); | ||
230 | #endif | ||
228 | static void uli526x_descriptor_init(struct uli526x_board_info *, unsigned long); | 231 | static void uli526x_descriptor_init(struct uli526x_board_info *, unsigned long); |
229 | static void allocate_rx_buffer(struct uli526x_board_info *); | 232 | static void allocate_rx_buffer(struct uli526x_board_info *); |
230 | static void update_cr6(u32, unsigned long); | 233 | static void update_cr6(u32, unsigned long); |
@@ -339,6 +342,9 @@ static int __devinit uli526x_init_one (struct pci_dev *pdev, | |||
339 | dev->get_stats = &uli526x_get_stats; | 342 | dev->get_stats = &uli526x_get_stats; |
340 | dev->set_multicast_list = &uli526x_set_filter_mode; | 343 | dev->set_multicast_list = &uli526x_set_filter_mode; |
341 | dev->ethtool_ops = &netdev_ethtool_ops; | 344 | dev->ethtool_ops = &netdev_ethtool_ops; |
345 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
346 | dev->poll_controller = &uli526x_poll; | ||
347 | #endif | ||
342 | spin_lock_init(&db->lock); | 348 | spin_lock_init(&db->lock); |
343 | 349 | ||
344 | 350 | ||
@@ -681,8 +687,9 @@ static irqreturn_t uli526x_interrupt(int irq, void *dev_id) | |||
681 | db->cr5_data = inl(ioaddr + DCR5); | 687 | db->cr5_data = inl(ioaddr + DCR5); |
682 | outl(db->cr5_data, ioaddr + DCR5); | 688 | outl(db->cr5_data, ioaddr + DCR5); |
683 | if ( !(db->cr5_data & 0x180c1) ) { | 689 | if ( !(db->cr5_data & 0x180c1) ) { |
684 | spin_unlock_irqrestore(&db->lock, flags); | 690 | /* Restore CR7 to enable interrupt mask */ |
685 | outl(db->cr7_data, ioaddr + DCR7); | 691 | outl(db->cr7_data, ioaddr + DCR7); |
692 | spin_unlock_irqrestore(&db->lock, flags); | ||
686 | return IRQ_HANDLED; | 693 | return IRQ_HANDLED; |
687 | } | 694 | } |
688 | 695 | ||
@@ -715,6 +722,13 @@ static irqreturn_t uli526x_interrupt(int irq, void *dev_id) | |||
715 | return IRQ_HANDLED; | 722 | return IRQ_HANDLED; |
716 | } | 723 | } |
717 | 724 | ||
725 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
726 | static void uli526x_poll(struct net_device *dev) | ||
727 | { | ||
728 | /* ISR grabs the irqsave lock, so this should be safe */ | ||
729 | uli526x_interrupt(dev->irq, dev); | ||
730 | } | ||
731 | #endif | ||
718 | 732 | ||
719 | /* | 733 | /* |
720 | * Free TX resource after TX complete | 734 | * Free TX resource after TX complete |
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index ca0bdac07a78..fb0b918e5ccb 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c | |||
@@ -237,7 +237,7 @@ static struct sk_buff *get_new_skb(struct ucc_geth_private *ugeth, | |||
237 | skb->dev = ugeth->dev; | 237 | skb->dev = ugeth->dev; |
238 | 238 | ||
239 | out_be32(&((struct qe_bd __iomem *)bd)->buf, | 239 | out_be32(&((struct qe_bd __iomem *)bd)->buf, |
240 | dma_map_single(NULL, | 240 | dma_map_single(&ugeth->dev->dev, |
241 | skb->data, | 241 | skb->data, |
242 | ugeth->ug_info->uf_info.max_rx_buf_length + | 242 | ugeth->ug_info->uf_info.max_rx_buf_length + |
243 | UCC_GETH_RX_DATA_BUF_ALIGNMENT, | 243 | UCC_GETH_RX_DATA_BUF_ALIGNMENT, |
@@ -2158,7 +2158,7 @@ static void ucc_geth_memclean(struct ucc_geth_private *ugeth) | |||
2158 | continue; | 2158 | continue; |
2159 | for (j = 0; j < ugeth->ug_info->bdRingLenTx[i]; j++) { | 2159 | for (j = 0; j < ugeth->ug_info->bdRingLenTx[i]; j++) { |
2160 | if (ugeth->tx_skbuff[i][j]) { | 2160 | if (ugeth->tx_skbuff[i][j]) { |
2161 | dma_unmap_single(NULL, | 2161 | dma_unmap_single(&ugeth->dev->dev, |
2162 | in_be32(&((struct qe_bd __iomem *)bd)->buf), | 2162 | in_be32(&((struct qe_bd __iomem *)bd)->buf), |
2163 | (in_be32((u32 __iomem *)bd) & | 2163 | (in_be32((u32 __iomem *)bd) & |
2164 | BD_LENGTH_MASK), | 2164 | BD_LENGTH_MASK), |
@@ -2186,7 +2186,7 @@ static void ucc_geth_memclean(struct ucc_geth_private *ugeth) | |||
2186 | bd = ugeth->p_rx_bd_ring[i]; | 2186 | bd = ugeth->p_rx_bd_ring[i]; |
2187 | for (j = 0; j < ugeth->ug_info->bdRingLenRx[i]; j++) { | 2187 | for (j = 0; j < ugeth->ug_info->bdRingLenRx[i]; j++) { |
2188 | if (ugeth->rx_skbuff[i][j]) { | 2188 | if (ugeth->rx_skbuff[i][j]) { |
2189 | dma_unmap_single(NULL, | 2189 | dma_unmap_single(&ugeth->dev->dev, |
2190 | in_be32(&((struct qe_bd __iomem *)bd)->buf), | 2190 | in_be32(&((struct qe_bd __iomem *)bd)->buf), |
2191 | ugeth->ug_info-> | 2191 | ugeth->ug_info-> |
2192 | uf_info.max_rx_buf_length + | 2192 | uf_info.max_rx_buf_length + |
@@ -3406,7 +3406,8 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3406 | 3406 | ||
3407 | /* set up the buffer descriptor */ | 3407 | /* set up the buffer descriptor */ |
3408 | out_be32(&((struct qe_bd __iomem *)bd)->buf, | 3408 | out_be32(&((struct qe_bd __iomem *)bd)->buf, |
3409 | dma_map_single(NULL, skb->data, skb->len, DMA_TO_DEVICE)); | 3409 | dma_map_single(&ugeth->dev->dev, skb->data, |
3410 | skb->len, DMA_TO_DEVICE)); | ||
3410 | 3411 | ||
3411 | /* printk(KERN_DEBUG"skb->data is 0x%x\n",skb->data); */ | 3412 | /* printk(KERN_DEBUG"skb->data is 0x%x\n",skb->data); */ |
3412 | 3413 | ||
diff --git a/drivers/net/ucc_geth_ethtool.c b/drivers/net/ucc_geth_ethtool.c index 299b7f176950..f5839c4a5cbd 100644 --- a/drivers/net/ucc_geth_ethtool.c +++ b/drivers/net/ucc_geth_ethtool.c | |||
@@ -73,6 +73,7 @@ static char tx_fw_stat_gstrings[][ETH_GSTRING_LEN] = { | |||
73 | "tx-frames-ok", | 73 | "tx-frames-ok", |
74 | "tx-excessive-differ-frames", | 74 | "tx-excessive-differ-frames", |
75 | "tx-256-511-frames", | 75 | "tx-256-511-frames", |
76 | "tx-512-1023-frames", | ||
76 | "tx-1024-1518-frames", | 77 | "tx-1024-1518-frames", |
77 | "tx-jumbo-frames", | 78 | "tx-jumbo-frames", |
78 | }; | 79 | }; |
@@ -308,7 +309,7 @@ static void uec_get_strings(struct net_device *netdev, u32 stringset, u8 *buf) | |||
308 | buf += UEC_TX_FW_STATS_LEN * ETH_GSTRING_LEN; | 309 | buf += UEC_TX_FW_STATS_LEN * ETH_GSTRING_LEN; |
309 | } | 310 | } |
310 | if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_RX) | 311 | if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_RX) |
311 | memcpy(buf, tx_fw_stat_gstrings, UEC_RX_FW_STATS_LEN * | 312 | memcpy(buf, rx_fw_stat_gstrings, UEC_RX_FW_STATS_LEN * |
312 | ETH_GSTRING_LEN); | 313 | ETH_GSTRING_LEN); |
313 | } | 314 | } |
314 | 315 | ||
diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index dc6f097062df..37ecf845edfe 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c | |||
@@ -1440,6 +1440,10 @@ static const struct usb_device_id products [] = { | |||
1440 | // Belkin F5D5055 | 1440 | // Belkin F5D5055 |
1441 | USB_DEVICE(0x050d, 0x5055), | 1441 | USB_DEVICE(0x050d, 0x5055), |
1442 | .driver_info = (unsigned long) &ax88178_info, | 1442 | .driver_info = (unsigned long) &ax88178_info, |
1443 | }, { | ||
1444 | // Apple USB Ethernet Adapter | ||
1445 | USB_DEVICE(0x05ac, 0x1402), | ||
1446 | .driver_info = (unsigned long) &ax88772_info, | ||
1443 | }, | 1447 | }, |
1444 | { }, // END | 1448 | { }, // END |
1445 | }; | 1449 | }; |
diff --git a/drivers/net/usb/catc.c b/drivers/net/usb/catc.c index 76752d84a30f..22c17bbacb69 100644 --- a/drivers/net/usb/catc.c +++ b/drivers/net/usb/catc.c | |||
@@ -423,7 +423,10 @@ static int catc_hard_start_xmit(struct sk_buff *skb, struct net_device *netdev) | |||
423 | 423 | ||
424 | catc->tx_ptr = (((catc->tx_ptr - 1) >> 6) + 1) << 6; | 424 | catc->tx_ptr = (((catc->tx_ptr - 1) >> 6) + 1) << 6; |
425 | tx_buf = catc->tx_buf[catc->tx_idx] + catc->tx_ptr; | 425 | tx_buf = catc->tx_buf[catc->tx_idx] + catc->tx_ptr; |
426 | *((u16*)tx_buf) = (catc->is_f5u011) ? cpu_to_be16((u16)skb->len) : cpu_to_le16((u16)skb->len); | 426 | if (catc->is_f5u011) |
427 | *(__be16 *)tx_buf = cpu_to_be16(skb->len); | ||
428 | else | ||
429 | *(__le16 *)tx_buf = cpu_to_le16(skb->len); | ||
427 | skb_copy_from_linear_data(skb, tx_buf + 2, skb->len); | 430 | skb_copy_from_linear_data(skb, tx_buf + 2, skb->len); |
428 | catc->tx_ptr += skb->len + 2; | 431 | catc->tx_ptr += skb->len + 2; |
429 | 432 | ||
diff --git a/drivers/net/usb/cdc_subset.c b/drivers/net/usb/cdc_subset.c index 0ec7936cbe21..c66b9c324f54 100644 --- a/drivers/net/usb/cdc_subset.c +++ b/drivers/net/usb/cdc_subset.c | |||
@@ -218,7 +218,7 @@ static const struct driver_info blob_info = { | |||
218 | /*-------------------------------------------------------------------------*/ | 218 | /*-------------------------------------------------------------------------*/ |
219 | 219 | ||
220 | #ifndef HAVE_HARDWARE | 220 | #ifndef HAVE_HARDWARE |
221 | #error You need to configure some hardware for this driver | 221 | #warning You need to configure some hardware for this driver |
222 | #endif | 222 | #endif |
223 | 223 | ||
224 | /* | 224 | /* |
diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c index 0dcfc0310264..7c66b052f55a 100644 --- a/drivers/net/usb/kaweth.c +++ b/drivers/net/usb/kaweth.c | |||
@@ -706,7 +706,7 @@ static void kaweth_kill_urbs(struct kaweth_device *kaweth) | |||
706 | usb_kill_urb(kaweth->rx_urb); | 706 | usb_kill_urb(kaweth->rx_urb); |
707 | usb_kill_urb(kaweth->tx_urb); | 707 | usb_kill_urb(kaweth->tx_urb); |
708 | 708 | ||
709 | flush_scheduled_work(); | 709 | cancel_delayed_work_sync(&kaweth->lowmem_work); |
710 | 710 | ||
711 | /* a scheduled work may have resubmitted, | 711 | /* a scheduled work may have resubmitted, |
712 | we hit them again */ | 712 | we hit them again */ |
diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c index 21a7785cb8b6..ae467f182c40 100644 --- a/drivers/net/usb/rndis_host.c +++ b/drivers/net/usb/rndis_host.c | |||
@@ -194,7 +194,7 @@ int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf) | |||
194 | dev_dbg(&info->control->dev, | 194 | dev_dbg(&info->control->dev, |
195 | "rndis response error, code %d\n", retval); | 195 | "rndis response error, code %d\n", retval); |
196 | } | 196 | } |
197 | msleep(2); | 197 | msleep(20); |
198 | } | 198 | } |
199 | dev_dbg(&info->control->dev, "rndis response timeout\n"); | 199 | dev_dbg(&info->control->dev, "rndis response timeout\n"); |
200 | return -ETIMEDOUT; | 200 | return -ETIMEDOUT; |
@@ -283,8 +283,8 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags) | |||
283 | struct rndis_set_c *set_c; | 283 | struct rndis_set_c *set_c; |
284 | struct rndis_halt *halt; | 284 | struct rndis_halt *halt; |
285 | } u; | 285 | } u; |
286 | u32 tmp, phym_unspec; | 286 | u32 tmp; |
287 | __le32 *phym; | 287 | __le32 phym_unspec, *phym; |
288 | int reply_len; | 288 | int reply_len; |
289 | unsigned char *bp; | 289 | unsigned char *bp; |
290 | 290 | ||
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index f926b5ab3d09..4452306d5328 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c | |||
@@ -44,9 +44,16 @@ struct virtnet_info | |||
44 | /* The skb we couldn't send because buffers were full. */ | 44 | /* The skb we couldn't send because buffers were full. */ |
45 | struct sk_buff *last_xmit_skb; | 45 | struct sk_buff *last_xmit_skb; |
46 | 46 | ||
47 | /* If we need to free in a timer, this is it. */ | ||
48 | struct timer_list xmit_free_timer; | ||
49 | |||
47 | /* Number of input buffers, and max we've ever had. */ | 50 | /* Number of input buffers, and max we've ever had. */ |
48 | unsigned int num, max; | 51 | unsigned int num, max; |
49 | 52 | ||
53 | /* For cleaning up after transmission. */ | ||
54 | struct tasklet_struct tasklet; | ||
55 | bool free_in_tasklet; | ||
56 | |||
50 | /* Receive & send queues. */ | 57 | /* Receive & send queues. */ |
51 | struct sk_buff_head recv; | 58 | struct sk_buff_head recv; |
52 | struct sk_buff_head send; | 59 | struct sk_buff_head send; |
@@ -68,8 +75,13 @@ static void skb_xmit_done(struct virtqueue *svq) | |||
68 | 75 | ||
69 | /* Suppress further interrupts. */ | 76 | /* Suppress further interrupts. */ |
70 | svq->vq_ops->disable_cb(svq); | 77 | svq->vq_ops->disable_cb(svq); |
71 | /* We were waiting for more output buffers. */ | 78 | |
79 | /* We were probably waiting for more output buffers. */ | ||
72 | netif_wake_queue(vi->dev); | 80 | netif_wake_queue(vi->dev); |
81 | |||
82 | /* Make sure we re-xmit last_xmit_skb: if there are no more packets | ||
83 | * queued, start_xmit won't be called. */ | ||
84 | tasklet_schedule(&vi->tasklet); | ||
73 | } | 85 | } |
74 | 86 | ||
75 | static void receive_skb(struct net_device *dev, struct sk_buff *skb, | 87 | static void receive_skb(struct net_device *dev, struct sk_buff *skb, |
@@ -86,9 +98,7 @@ static void receive_skb(struct net_device *dev, struct sk_buff *skb, | |||
86 | BUG_ON(len > MAX_PACKET_LEN); | 98 | BUG_ON(len > MAX_PACKET_LEN); |
87 | 99 | ||
88 | skb_trim(skb, len); | 100 | skb_trim(skb, len); |
89 | skb->protocol = eth_type_trans(skb, dev); | 101 | |
90 | pr_debug("Receiving skb proto 0x%04x len %i type %i\n", | ||
91 | ntohs(skb->protocol), skb->len, skb->pkt_type); | ||
92 | dev->stats.rx_bytes += skb->len; | 102 | dev->stats.rx_bytes += skb->len; |
93 | dev->stats.rx_packets++; | 103 | dev->stats.rx_packets++; |
94 | 104 | ||
@@ -98,6 +108,10 @@ static void receive_skb(struct net_device *dev, struct sk_buff *skb, | |||
98 | goto frame_err; | 108 | goto frame_err; |
99 | } | 109 | } |
100 | 110 | ||
111 | skb->protocol = eth_type_trans(skb, dev); | ||
112 | pr_debug("Receiving skb proto 0x%04x len %i type %i\n", | ||
113 | ntohs(skb->protocol), skb->len, skb->pkt_type); | ||
114 | |||
101 | if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) { | 115 | if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) { |
102 | pr_debug("GSO!\n"); | 116 | pr_debug("GSO!\n"); |
103 | switch (hdr->gso_type & ~VIRTIO_NET_HDR_GSO_ECN) { | 117 | switch (hdr->gso_type & ~VIRTIO_NET_HDR_GSO_ECN) { |
@@ -230,9 +244,25 @@ static void free_old_xmit_skbs(struct virtnet_info *vi) | |||
230 | } | 244 | } |
231 | } | 245 | } |
232 | 246 | ||
247 | /* If the virtio transport doesn't always notify us when all in-flight packets | ||
248 | * are consumed, we fall back to using this function on a timer to free them. */ | ||
249 | static void xmit_free(unsigned long data) | ||
250 | { | ||
251 | struct virtnet_info *vi = (void *)data; | ||
252 | |||
253 | netif_tx_lock(vi->dev); | ||
254 | |||
255 | free_old_xmit_skbs(vi); | ||
256 | |||
257 | if (!skb_queue_empty(&vi->send)) | ||
258 | mod_timer(&vi->xmit_free_timer, jiffies + (HZ/10)); | ||
259 | |||
260 | netif_tx_unlock(vi->dev); | ||
261 | } | ||
262 | |||
233 | static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb) | 263 | static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb) |
234 | { | 264 | { |
235 | int num; | 265 | int num, err; |
236 | struct scatterlist sg[2+MAX_SKB_FRAGS]; | 266 | struct scatterlist sg[2+MAX_SKB_FRAGS]; |
237 | struct virtio_net_hdr *hdr; | 267 | struct virtio_net_hdr *hdr; |
238 | const unsigned char *dest = ((struct ethhdr *)skb->data)->h_dest; | 268 | const unsigned char *dest = ((struct ethhdr *)skb->data)->h_dest; |
@@ -275,7 +305,25 @@ static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb) | |||
275 | vnet_hdr_to_sg(sg, skb); | 305 | vnet_hdr_to_sg(sg, skb); |
276 | num = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1; | 306 | num = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1; |
277 | 307 | ||
278 | return vi->svq->vq_ops->add_buf(vi->svq, sg, num, 0, skb); | 308 | err = vi->svq->vq_ops->add_buf(vi->svq, sg, num, 0, skb); |
309 | if (!err && !vi->free_in_tasklet) | ||
310 | mod_timer(&vi->xmit_free_timer, jiffies + (HZ/10)); | ||
311 | |||
312 | return err; | ||
313 | } | ||
314 | |||
315 | static void xmit_tasklet(unsigned long data) | ||
316 | { | ||
317 | struct virtnet_info *vi = (void *)data; | ||
318 | |||
319 | netif_tx_lock_bh(vi->dev); | ||
320 | if (vi->last_xmit_skb && xmit_skb(vi, vi->last_xmit_skb) == 0) { | ||
321 | vi->svq->vq_ops->kick(vi->svq); | ||
322 | vi->last_xmit_skb = NULL; | ||
323 | } | ||
324 | if (vi->free_in_tasklet) | ||
325 | free_old_xmit_skbs(vi); | ||
326 | netif_tx_unlock_bh(vi->dev); | ||
279 | } | 327 | } |
280 | 328 | ||
281 | static int start_xmit(struct sk_buff *skb, struct net_device *dev) | 329 | static int start_xmit(struct sk_buff *skb, struct net_device *dev) |
@@ -287,21 +335,25 @@ again: | |||
287 | free_old_xmit_skbs(vi); | 335 | free_old_xmit_skbs(vi); |
288 | 336 | ||
289 | /* If we has a buffer left over from last time, send it now. */ | 337 | /* If we has a buffer left over from last time, send it now. */ |
290 | if (vi->last_xmit_skb) { | 338 | if (unlikely(vi->last_xmit_skb)) { |
291 | if (xmit_skb(vi, vi->last_xmit_skb) != 0) { | 339 | if (xmit_skb(vi, vi->last_xmit_skb) != 0) { |
292 | /* Drop this skb: we only queue one. */ | 340 | /* Drop this skb: we only queue one. */ |
293 | vi->dev->stats.tx_dropped++; | 341 | vi->dev->stats.tx_dropped++; |
294 | kfree_skb(skb); | 342 | kfree_skb(skb); |
343 | skb = NULL; | ||
295 | goto stop_queue; | 344 | goto stop_queue; |
296 | } | 345 | } |
297 | vi->last_xmit_skb = NULL; | 346 | vi->last_xmit_skb = NULL; |
298 | } | 347 | } |
299 | 348 | ||
300 | /* Put new one in send queue and do transmit */ | 349 | /* Put new one in send queue and do transmit */ |
301 | __skb_queue_head(&vi->send, skb); | 350 | if (likely(skb)) { |
302 | if (xmit_skb(vi, skb) != 0) { | 351 | __skb_queue_head(&vi->send, skb); |
303 | vi->last_xmit_skb = skb; | 352 | if (xmit_skb(vi, skb) != 0) { |
304 | goto stop_queue; | 353 | vi->last_xmit_skb = skb; |
354 | skb = NULL; | ||
355 | goto stop_queue; | ||
356 | } | ||
305 | } | 357 | } |
306 | done: | 358 | done: |
307 | vi->svq->vq_ops->kick(vi->svq); | 359 | vi->svq->vq_ops->kick(vi->svq); |
@@ -411,6 +463,10 @@ static int virtnet_probe(struct virtio_device *vdev) | |||
411 | vi->vdev = vdev; | 463 | vi->vdev = vdev; |
412 | vdev->priv = vi; | 464 | vdev->priv = vi; |
413 | 465 | ||
466 | /* If they give us a callback when all buffers are done, we don't need | ||
467 | * the timer. */ | ||
468 | vi->free_in_tasklet = virtio_has_feature(vdev,VIRTIO_F_NOTIFY_ON_EMPTY); | ||
469 | |||
414 | /* We expect two virtqueues, receive then send. */ | 470 | /* We expect two virtqueues, receive then send. */ |
415 | vi->rvq = vdev->config->find_vq(vdev, 0, skb_recv_done); | 471 | vi->rvq = vdev->config->find_vq(vdev, 0, skb_recv_done); |
416 | if (IS_ERR(vi->rvq)) { | 472 | if (IS_ERR(vi->rvq)) { |
@@ -428,6 +484,11 @@ static int virtnet_probe(struct virtio_device *vdev) | |||
428 | skb_queue_head_init(&vi->recv); | 484 | skb_queue_head_init(&vi->recv); |
429 | skb_queue_head_init(&vi->send); | 485 | skb_queue_head_init(&vi->send); |
430 | 486 | ||
487 | tasklet_init(&vi->tasklet, xmit_tasklet, (unsigned long)vi); | ||
488 | |||
489 | if (!vi->free_in_tasklet) | ||
490 | setup_timer(&vi->xmit_free_timer, xmit_free, (unsigned long)vi); | ||
491 | |||
431 | err = register_netdev(dev); | 492 | err = register_netdev(dev); |
432 | if (err) { | 493 | if (err) { |
433 | pr_debug("virtio_net: registering device failed\n"); | 494 | pr_debug("virtio_net: registering device failed\n"); |
@@ -465,13 +526,15 @@ static void virtnet_remove(struct virtio_device *vdev) | |||
465 | /* Stop all the virtqueues. */ | 526 | /* Stop all the virtqueues. */ |
466 | vdev->config->reset(vdev); | 527 | vdev->config->reset(vdev); |
467 | 528 | ||
529 | if (!vi->free_in_tasklet) | ||
530 | del_timer_sync(&vi->xmit_free_timer); | ||
531 | |||
468 | /* Free our skbs in send and recv queues, if any. */ | 532 | /* Free our skbs in send and recv queues, if any. */ |
469 | while ((skb = __skb_dequeue(&vi->recv)) != NULL) { | 533 | while ((skb = __skb_dequeue(&vi->recv)) != NULL) { |
470 | kfree_skb(skb); | 534 | kfree_skb(skb); |
471 | vi->num--; | 535 | vi->num--; |
472 | } | 536 | } |
473 | while ((skb = __skb_dequeue(&vi->send)) != NULL) | 537 | __skb_queue_purge(&vi->send); |
474 | kfree_skb(skb); | ||
475 | 538 | ||
476 | BUG_ON(vi->num != 0); | 539 | BUG_ON(vi->num != 0); |
477 | 540 | ||
@@ -489,7 +552,7 @@ static struct virtio_device_id id_table[] = { | |||
489 | static unsigned int features[] = { | 552 | static unsigned int features[] = { |
490 | VIRTIO_NET_F_CSUM, VIRTIO_NET_F_GSO, VIRTIO_NET_F_MAC, | 553 | VIRTIO_NET_F_CSUM, VIRTIO_NET_F_GSO, VIRTIO_NET_F_MAC, |
491 | VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO, VIRTIO_NET_F_HOST_TSO6, | 554 | VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO, VIRTIO_NET_F_HOST_TSO6, |
492 | VIRTIO_NET_F_HOST_ECN, | 555 | VIRTIO_NET_F_HOST_ECN, VIRTIO_F_NOTIFY_ON_EMPTY, |
493 | }; | 556 | }; |
494 | 557 | ||
495 | static struct virtio_driver virtio_net = { | 558 | static struct virtio_driver virtio_net = { |
diff --git a/drivers/net/wan/hdlc.c b/drivers/net/wan/hdlc.c index 9a83c9d5b8cf..7f984895b0d5 100644 --- a/drivers/net/wan/hdlc.c +++ b/drivers/net/wan/hdlc.c | |||
@@ -43,8 +43,7 @@ static const char* version = "HDLC support module revision 1.22"; | |||
43 | 43 | ||
44 | #undef DEBUG_LINK | 44 | #undef DEBUG_LINK |
45 | 45 | ||
46 | static struct hdlc_proto *first_proto = NULL; | 46 | static struct hdlc_proto *first_proto; |
47 | |||
48 | 47 | ||
49 | static int hdlc_change_mtu(struct net_device *dev, int new_mtu) | 48 | static int hdlc_change_mtu(struct net_device *dev, int new_mtu) |
50 | { | 49 | { |
@@ -314,21 +313,25 @@ void detach_hdlc_protocol(struct net_device *dev) | |||
314 | 313 | ||
315 | void register_hdlc_protocol(struct hdlc_proto *proto) | 314 | void register_hdlc_protocol(struct hdlc_proto *proto) |
316 | { | 315 | { |
316 | rtnl_lock(); | ||
317 | proto->next = first_proto; | 317 | proto->next = first_proto; |
318 | first_proto = proto; | 318 | first_proto = proto; |
319 | rtnl_unlock(); | ||
319 | } | 320 | } |
320 | 321 | ||
321 | 322 | ||
322 | void unregister_hdlc_protocol(struct hdlc_proto *proto) | 323 | void unregister_hdlc_protocol(struct hdlc_proto *proto) |
323 | { | 324 | { |
324 | struct hdlc_proto **p = &first_proto; | 325 | struct hdlc_proto **p; |
325 | while (*p) { | 326 | |
326 | if (*p == proto) { | 327 | rtnl_lock(); |
327 | *p = proto->next; | 328 | p = &first_proto; |
328 | return; | 329 | while (*p != proto) { |
329 | } | 330 | BUG_ON(!*p); |
330 | p = &((*p)->next); | 331 | p = &((*p)->next); |
331 | } | 332 | } |
333 | *p = proto->next; | ||
334 | rtnl_unlock(); | ||
332 | } | 335 | } |
333 | 336 | ||
334 | 337 | ||
diff --git a/drivers/net/wan/hdlc_cisco.c b/drivers/net/wan/hdlc_cisco.c index 7133c688cf20..762d21c1c703 100644 --- a/drivers/net/wan/hdlc_cisco.c +++ b/drivers/net/wan/hdlc_cisco.c | |||
@@ -56,6 +56,7 @@ struct cisco_state { | |||
56 | cisco_proto settings; | 56 | cisco_proto settings; |
57 | 57 | ||
58 | struct timer_list timer; | 58 | struct timer_list timer; |
59 | spinlock_t lock; | ||
59 | unsigned long last_poll; | 60 | unsigned long last_poll; |
60 | int up; | 61 | int up; |
61 | int request_sent; | 62 | int request_sent; |
@@ -158,6 +159,7 @@ static int cisco_rx(struct sk_buff *skb) | |||
158 | { | 159 | { |
159 | struct net_device *dev = skb->dev; | 160 | struct net_device *dev = skb->dev; |
160 | hdlc_device *hdlc = dev_to_hdlc(dev); | 161 | hdlc_device *hdlc = dev_to_hdlc(dev); |
162 | struct cisco_state *st = state(hdlc); | ||
161 | struct hdlc_header *data = (struct hdlc_header*)skb->data; | 163 | struct hdlc_header *data = (struct hdlc_header*)skb->data; |
162 | struct cisco_packet *cisco_data; | 164 | struct cisco_packet *cisco_data; |
163 | struct in_device *in_dev; | 165 | struct in_device *in_dev; |
@@ -220,11 +222,12 @@ static int cisco_rx(struct sk_buff *skb) | |||
220 | goto rx_error; | 222 | goto rx_error; |
221 | 223 | ||
222 | case CISCO_KEEPALIVE_REQ: | 224 | case CISCO_KEEPALIVE_REQ: |
223 | state(hdlc)->rxseq = ntohl(cisco_data->par1); | 225 | spin_lock(&st->lock); |
224 | if (state(hdlc)->request_sent && | 226 | st->rxseq = ntohl(cisco_data->par1); |
225 | ntohl(cisco_data->par2) == state(hdlc)->txseq) { | 227 | if (st->request_sent && |
226 | state(hdlc)->last_poll = jiffies; | 228 | ntohl(cisco_data->par2) == st->txseq) { |
227 | if (!state(hdlc)->up) { | 229 | st->last_poll = jiffies; |
230 | if (!st->up) { | ||
228 | u32 sec, min, hrs, days; | 231 | u32 sec, min, hrs, days; |
229 | sec = ntohl(cisco_data->time) / 1000; | 232 | sec = ntohl(cisco_data->time) / 1000; |
230 | min = sec / 60; sec -= min * 60; | 233 | min = sec / 60; sec -= min * 60; |
@@ -232,12 +235,12 @@ static int cisco_rx(struct sk_buff *skb) | |||
232 | days = hrs / 24; hrs -= days * 24; | 235 | days = hrs / 24; hrs -= days * 24; |
233 | printk(KERN_INFO "%s: Link up (peer " | 236 | printk(KERN_INFO "%s: Link up (peer " |
234 | "uptime %ud%uh%um%us)\n", | 237 | "uptime %ud%uh%um%us)\n", |
235 | dev->name, days, hrs, | 238 | dev->name, days, hrs, min, sec); |
236 | min, sec); | ||
237 | netif_dormant_off(dev); | 239 | netif_dormant_off(dev); |
238 | state(hdlc)->up = 1; | 240 | st->up = 1; |
239 | } | 241 | } |
240 | } | 242 | } |
243 | spin_unlock(&st->lock); | ||
241 | 244 | ||
242 | dev_kfree_skb_any(skb); | 245 | dev_kfree_skb_any(skb); |
243 | return NET_RX_SUCCESS; | 246 | return NET_RX_SUCCESS; |
@@ -261,24 +264,25 @@ static void cisco_timer(unsigned long arg) | |||
261 | { | 264 | { |
262 | struct net_device *dev = (struct net_device *)arg; | 265 | struct net_device *dev = (struct net_device *)arg; |
263 | hdlc_device *hdlc = dev_to_hdlc(dev); | 266 | hdlc_device *hdlc = dev_to_hdlc(dev); |
267 | struct cisco_state *st = state(hdlc); | ||
264 | 268 | ||
265 | if (state(hdlc)->up && | 269 | spin_lock(&st->lock); |
266 | time_after(jiffies, state(hdlc)->last_poll + | 270 | if (st->up && |
267 | state(hdlc)->settings.timeout * HZ)) { | 271 | time_after(jiffies, st->last_poll + st->settings.timeout * HZ)) { |
268 | state(hdlc)->up = 0; | 272 | st->up = 0; |
269 | printk(KERN_INFO "%s: Link down\n", dev->name); | 273 | printk(KERN_INFO "%s: Link down\n", dev->name); |
270 | netif_dormant_on(dev); | 274 | netif_dormant_on(dev); |
271 | } | 275 | } |
272 | 276 | ||
273 | cisco_keepalive_send(dev, CISCO_KEEPALIVE_REQ, | 277 | cisco_keepalive_send(dev, CISCO_KEEPALIVE_REQ, htonl(++st->txseq), |
274 | htonl(++state(hdlc)->txseq), | 278 | htonl(st->rxseq)); |
275 | htonl(state(hdlc)->rxseq)); | 279 | st->request_sent = 1; |
276 | state(hdlc)->request_sent = 1; | 280 | spin_unlock(&st->lock); |
277 | state(hdlc)->timer.expires = jiffies + | 281 | |
278 | state(hdlc)->settings.interval * HZ; | 282 | st->timer.expires = jiffies + st->settings.interval * HZ; |
279 | state(hdlc)->timer.function = cisco_timer; | 283 | st->timer.function = cisco_timer; |
280 | state(hdlc)->timer.data = arg; | 284 | st->timer.data = arg; |
281 | add_timer(&state(hdlc)->timer); | 285 | add_timer(&st->timer); |
282 | } | 286 | } |
283 | 287 | ||
284 | 288 | ||
@@ -286,15 +290,20 @@ static void cisco_timer(unsigned long arg) | |||
286 | static void cisco_start(struct net_device *dev) | 290 | static void cisco_start(struct net_device *dev) |
287 | { | 291 | { |
288 | hdlc_device *hdlc = dev_to_hdlc(dev); | 292 | hdlc_device *hdlc = dev_to_hdlc(dev); |
289 | state(hdlc)->up = 0; | 293 | struct cisco_state *st = state(hdlc); |
290 | state(hdlc)->request_sent = 0; | 294 | unsigned long flags; |
291 | state(hdlc)->txseq = state(hdlc)->rxseq = 0; | 295 | |
292 | 296 | spin_lock_irqsave(&st->lock, flags); | |
293 | init_timer(&state(hdlc)->timer); | 297 | st->up = 0; |
294 | state(hdlc)->timer.expires = jiffies + HZ; /*First poll after 1s*/ | 298 | st->request_sent = 0; |
295 | state(hdlc)->timer.function = cisco_timer; | 299 | st->txseq = st->rxseq = 0; |
296 | state(hdlc)->timer.data = (unsigned long)dev; | 300 | spin_unlock_irqrestore(&st->lock, flags); |
297 | add_timer(&state(hdlc)->timer); | 301 | |
302 | init_timer(&st->timer); | ||
303 | st->timer.expires = jiffies + HZ; /* First poll after 1 s */ | ||
304 | st->timer.function = cisco_timer; | ||
305 | st->timer.data = (unsigned long)dev; | ||
306 | add_timer(&st->timer); | ||
298 | } | 307 | } |
299 | 308 | ||
300 | 309 | ||
@@ -302,10 +311,16 @@ static void cisco_start(struct net_device *dev) | |||
302 | static void cisco_stop(struct net_device *dev) | 311 | static void cisco_stop(struct net_device *dev) |
303 | { | 312 | { |
304 | hdlc_device *hdlc = dev_to_hdlc(dev); | 313 | hdlc_device *hdlc = dev_to_hdlc(dev); |
305 | del_timer_sync(&state(hdlc)->timer); | 314 | struct cisco_state *st = state(hdlc); |
315 | unsigned long flags; | ||
316 | |||
317 | del_timer_sync(&st->timer); | ||
318 | |||
319 | spin_lock_irqsave(&st->lock, flags); | ||
306 | netif_dormant_on(dev); | 320 | netif_dormant_on(dev); |
307 | state(hdlc)->up = 0; | 321 | st->up = 0; |
308 | state(hdlc)->request_sent = 0; | 322 | st->request_sent = 0; |
323 | spin_unlock_irqrestore(&st->lock, flags); | ||
309 | } | 324 | } |
310 | 325 | ||
311 | 326 | ||
@@ -367,6 +382,7 @@ static int cisco_ioctl(struct net_device *dev, struct ifreq *ifr) | |||
367 | return result; | 382 | return result; |
368 | 383 | ||
369 | memcpy(&state(hdlc)->settings, &new_settings, size); | 384 | memcpy(&state(hdlc)->settings, &new_settings, size); |
385 | spin_lock_init(&state(hdlc)->lock); | ||
370 | dev->hard_start_xmit = hdlc->xmit; | 386 | dev->hard_start_xmit = hdlc->xmit; |
371 | dev->header_ops = &cisco_header_ops; | 387 | dev->header_ops = &cisco_header_ops; |
372 | dev->type = ARPHRD_CISCO; | 388 | dev->type = ARPHRD_CISCO; |
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index 45f47c1c0a35..32019fb878d8 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c | |||
@@ -2668,6 +2668,7 @@ static struct net_device *init_wifidev(struct airo_info *ai, | |||
2668 | dev->irq = ethdev->irq; | 2668 | dev->irq = ethdev->irq; |
2669 | dev->base_addr = ethdev->base_addr; | 2669 | dev->base_addr = ethdev->base_addr; |
2670 | dev->wireless_data = ethdev->wireless_data; | 2670 | dev->wireless_data = ethdev->wireless_data; |
2671 | SET_NETDEV_DEV(dev, ethdev->dev.parent); | ||
2671 | memcpy(dev->dev_addr, ethdev->dev_addr, dev->addr_len); | 2672 | memcpy(dev->dev_addr, ethdev->dev_addr, dev->addr_len); |
2672 | err = register_netdev(dev); | 2673 | err = register_netdev(dev); |
2673 | if (err<0) { | 2674 | if (err<0) { |
@@ -2904,7 +2905,7 @@ EXPORT_SYMBOL(init_airo_card); | |||
2904 | 2905 | ||
2905 | static int waitbusy (struct airo_info *ai) { | 2906 | static int waitbusy (struct airo_info *ai) { |
2906 | int delay = 0; | 2907 | int delay = 0; |
2907 | while ((IN4500 (ai, COMMAND) & COMMAND_BUSY) & (delay < 10000)) { | 2908 | while ((IN4500(ai, COMMAND) & COMMAND_BUSY) && (delay < 10000)) { |
2908 | udelay (10); | 2909 | udelay (10); |
2909 | if ((++delay % 20) == 0) | 2910 | if ((++delay % 20) == 0) |
2910 | OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY); | 2911 | OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY); |
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c index 4e5c8fc35200..635b9ac9aaa1 100644 --- a/drivers/net/wireless/ath5k/base.c +++ b/drivers/net/wireless/ath5k/base.c | |||
@@ -1787,6 +1787,8 @@ ath5k_tasklet_rx(unsigned long data) | |||
1787 | 1787 | ||
1788 | spin_lock(&sc->rxbuflock); | 1788 | spin_lock(&sc->rxbuflock); |
1789 | do { | 1789 | do { |
1790 | rxs.flag = 0; | ||
1791 | |||
1790 | if (unlikely(list_empty(&sc->rxbuf))) { | 1792 | if (unlikely(list_empty(&sc->rxbuf))) { |
1791 | ATH5K_WARN(sc, "empty rx buf pool\n"); | 1793 | ATH5K_WARN(sc, "empty rx buf pool\n"); |
1792 | break; | 1794 | break; |
diff --git a/drivers/net/wireless/ath5k/hw.c b/drivers/net/wireless/ath5k/hw.c index 5fb1ae6ad3e2..77990b56860b 100644 --- a/drivers/net/wireless/ath5k/hw.c +++ b/drivers/net/wireless/ath5k/hw.c | |||
@@ -4119,6 +4119,7 @@ static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah, | |||
4119 | rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, | 4119 | rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, |
4120 | AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); | 4120 | AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); |
4121 | rs->rs_status = 0; | 4121 | rs->rs_status = 0; |
4122 | rs->rs_phyerr = 0; | ||
4122 | 4123 | ||
4123 | /* | 4124 | /* |
4124 | * Key table status | 4125 | * Key table status |
@@ -4145,7 +4146,7 @@ static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah, | |||
4145 | if (rx_status->rx_status_1 & | 4146 | if (rx_status->rx_status_1 & |
4146 | AR5K_5210_RX_DESC_STATUS1_PHY_ERROR) { | 4147 | AR5K_5210_RX_DESC_STATUS1_PHY_ERROR) { |
4147 | rs->rs_status |= AR5K_RXERR_PHY; | 4148 | rs->rs_status |= AR5K_RXERR_PHY; |
4148 | rs->rs_phyerr = AR5K_REG_MS(rx_status->rx_status_1, | 4149 | rs->rs_phyerr |= AR5K_REG_MS(rx_status->rx_status_1, |
4149 | AR5K_5210_RX_DESC_STATUS1_PHY_ERROR); | 4150 | AR5K_5210_RX_DESC_STATUS1_PHY_ERROR); |
4150 | } | 4151 | } |
4151 | 4152 | ||
@@ -4193,6 +4194,7 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah, | |||
4193 | rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, | 4194 | rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, |
4194 | AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); | 4195 | AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); |
4195 | rs->rs_status = 0; | 4196 | rs->rs_status = 0; |
4197 | rs->rs_phyerr = 0; | ||
4196 | 4198 | ||
4197 | /* | 4199 | /* |
4198 | * Key table status | 4200 | * Key table status |
@@ -4215,7 +4217,7 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah, | |||
4215 | if (rx_status->rx_status_1 & | 4217 | if (rx_status->rx_status_1 & |
4216 | AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) { | 4218 | AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) { |
4217 | rs->rs_status |= AR5K_RXERR_PHY; | 4219 | rs->rs_status |= AR5K_RXERR_PHY; |
4218 | rs->rs_phyerr = AR5K_REG_MS(rx_err->rx_error_1, | 4220 | rs->rs_phyerr |= AR5K_REG_MS(rx_err->rx_error_1, |
4219 | AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE); | 4221 | AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE); |
4220 | } | 4222 | } |
4221 | 4223 | ||
diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig index f51b2d9b085b..1fa043d1802c 100644 --- a/drivers/net/wireless/b43/Kconfig +++ b/drivers/net/wireless/b43/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config B43 | 1 | config B43 |
2 | tristate "Broadcom 43xx wireless support (mac80211 stack)" | 2 | tristate "Broadcom 43xx wireless support (mac80211 stack)" |
3 | depends on SSB_POSSIBLE && MAC80211 && WLAN_80211 | 3 | depends on SSB_POSSIBLE && MAC80211 && WLAN_80211 && HAS_DMA |
4 | select SSB | 4 | select SSB |
5 | select FW_LOADER | 5 | select FW_LOADER |
6 | select HW_RANDOM | 6 | select HW_RANDOM |
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index 37783cdd301a..dfa4bdd5597c 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h | |||
@@ -737,6 +737,7 @@ struct b43_wl { | |||
737 | struct ieee80211_tx_control beacon_txctl; | 737 | struct ieee80211_tx_control beacon_txctl; |
738 | bool beacon0_uploaded; | 738 | bool beacon0_uploaded; |
739 | bool beacon1_uploaded; | 739 | bool beacon1_uploaded; |
740 | bool beacon_templates_virgin; /* Never wrote the templates? */ | ||
740 | struct work_struct beacon_update_trigger; | 741 | struct work_struct beacon_update_trigger; |
741 | 742 | ||
742 | /* The current QOS parameters for the 4 queues. | 743 | /* The current QOS parameters for the 4 queues. |
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 8fdba9415c04..6c3d9ea0a9f8 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -1544,6 +1544,30 @@ static void b43_write_probe_resp_template(struct b43_wldev *dev, | |||
1544 | kfree(probe_resp_data); | 1544 | kfree(probe_resp_data); |
1545 | } | 1545 | } |
1546 | 1546 | ||
1547 | static void b43_upload_beacon0(struct b43_wldev *dev) | ||
1548 | { | ||
1549 | struct b43_wl *wl = dev->wl; | ||
1550 | |||
1551 | if (wl->beacon0_uploaded) | ||
1552 | return; | ||
1553 | b43_write_beacon_template(dev, 0x68, 0x18); | ||
1554 | /* FIXME: Probe resp upload doesn't really belong here, | ||
1555 | * but we don't use that feature anyway. */ | ||
1556 | b43_write_probe_resp_template(dev, 0x268, 0x4A, | ||
1557 | &__b43_ratetable[3]); | ||
1558 | wl->beacon0_uploaded = 1; | ||
1559 | } | ||
1560 | |||
1561 | static void b43_upload_beacon1(struct b43_wldev *dev) | ||
1562 | { | ||
1563 | struct b43_wl *wl = dev->wl; | ||
1564 | |||
1565 | if (wl->beacon1_uploaded) | ||
1566 | return; | ||
1567 | b43_write_beacon_template(dev, 0x468, 0x1A); | ||
1568 | wl->beacon1_uploaded = 1; | ||
1569 | } | ||
1570 | |||
1547 | static void handle_irq_beacon(struct b43_wldev *dev) | 1571 | static void handle_irq_beacon(struct b43_wldev *dev) |
1548 | { | 1572 | { |
1549 | struct b43_wl *wl = dev->wl; | 1573 | struct b43_wl *wl = dev->wl; |
@@ -1568,24 +1592,27 @@ static void handle_irq_beacon(struct b43_wldev *dev) | |||
1568 | return; | 1592 | return; |
1569 | } | 1593 | } |
1570 | 1594 | ||
1571 | if (!beacon0_valid) { | 1595 | if (unlikely(wl->beacon_templates_virgin)) { |
1572 | if (!wl->beacon0_uploaded) { | 1596 | /* We never uploaded a beacon before. |
1573 | b43_write_beacon_template(dev, 0x68, 0x18); | 1597 | * Upload both templates now, but only mark one valid. */ |
1574 | b43_write_probe_resp_template(dev, 0x268, 0x4A, | 1598 | wl->beacon_templates_virgin = 0; |
1575 | &__b43_ratetable[3]); | 1599 | b43_upload_beacon0(dev); |
1576 | wl->beacon0_uploaded = 1; | 1600 | b43_upload_beacon1(dev); |
1577 | } | ||
1578 | cmd = b43_read32(dev, B43_MMIO_MACCMD); | 1601 | cmd = b43_read32(dev, B43_MMIO_MACCMD); |
1579 | cmd |= B43_MACCMD_BEACON0_VALID; | 1602 | cmd |= B43_MACCMD_BEACON0_VALID; |
1580 | b43_write32(dev, B43_MMIO_MACCMD, cmd); | 1603 | b43_write32(dev, B43_MMIO_MACCMD, cmd); |
1581 | } else if (!beacon1_valid) { | 1604 | } else { |
1582 | if (!wl->beacon1_uploaded) { | 1605 | if (!beacon0_valid) { |
1583 | b43_write_beacon_template(dev, 0x468, 0x1A); | 1606 | b43_upload_beacon0(dev); |
1584 | wl->beacon1_uploaded = 1; | 1607 | cmd = b43_read32(dev, B43_MMIO_MACCMD); |
1608 | cmd |= B43_MACCMD_BEACON0_VALID; | ||
1609 | b43_write32(dev, B43_MMIO_MACCMD, cmd); | ||
1610 | } else if (!beacon1_valid) { | ||
1611 | b43_upload_beacon1(dev); | ||
1612 | cmd = b43_read32(dev, B43_MMIO_MACCMD); | ||
1613 | cmd |= B43_MACCMD_BEACON1_VALID; | ||
1614 | b43_write32(dev, B43_MMIO_MACCMD, cmd); | ||
1585 | } | 1615 | } |
1586 | cmd = b43_read32(dev, B43_MMIO_MACCMD); | ||
1587 | cmd |= B43_MACCMD_BEACON1_VALID; | ||
1588 | b43_write32(dev, B43_MMIO_MACCMD, cmd); | ||
1589 | } | 1616 | } |
1590 | } | 1617 | } |
1591 | 1618 | ||
@@ -4073,6 +4100,9 @@ static int b43_op_start(struct ieee80211_hw *hw) | |||
4073 | wl->filter_flags = 0; | 4100 | wl->filter_flags = 0; |
4074 | wl->radiotap_enabled = 0; | 4101 | wl->radiotap_enabled = 0; |
4075 | b43_qos_clear(wl); | 4102 | b43_qos_clear(wl); |
4103 | wl->beacon0_uploaded = 0; | ||
4104 | wl->beacon1_uploaded = 0; | ||
4105 | wl->beacon_templates_virgin = 1; | ||
4076 | 4106 | ||
4077 | /* First register RFkill. | 4107 | /* First register RFkill. |
4078 | * LEDs that are registered later depend on it. */ | 4108 | * LEDs that are registered later depend on it. */ |
@@ -4241,7 +4271,9 @@ static void b43_chip_reset(struct work_struct *work) | |||
4241 | goto out; | 4271 | goto out; |
4242 | } | 4272 | } |
4243 | } | 4273 | } |
4244 | out: | 4274 | out: |
4275 | if (err) | ||
4276 | wl->current_dev = NULL; /* Failed to init the dev. */ | ||
4245 | mutex_unlock(&wl->mutex); | 4277 | mutex_unlock(&wl->mutex); |
4246 | if (err) | 4278 | if (err) |
4247 | b43err(wl, "Controller restart FAILED\n"); | 4279 | b43err(wl, "Controller restart FAILED\n"); |
@@ -4382,9 +4414,11 @@ static void b43_one_core_detach(struct ssb_device *dev) | |||
4382 | struct b43_wldev *wldev; | 4414 | struct b43_wldev *wldev; |
4383 | struct b43_wl *wl; | 4415 | struct b43_wl *wl; |
4384 | 4416 | ||
4417 | /* Do not cancel ieee80211-workqueue based work here. | ||
4418 | * See comment in b43_remove(). */ | ||
4419 | |||
4385 | wldev = ssb_get_drvdata(dev); | 4420 | wldev = ssb_get_drvdata(dev); |
4386 | wl = wldev->wl; | 4421 | wl = wldev->wl; |
4387 | cancel_work_sync(&wldev->restart_work); | ||
4388 | b43_debugfs_remove_device(wldev); | 4422 | b43_debugfs_remove_device(wldev); |
4389 | b43_wireless_core_detach(wldev); | 4423 | b43_wireless_core_detach(wldev); |
4390 | list_del(&wldev->list); | 4424 | list_del(&wldev->list); |
@@ -4569,6 +4603,10 @@ static void b43_remove(struct ssb_device *dev) | |||
4569 | struct b43_wl *wl = ssb_get_devtypedata(dev); | 4603 | struct b43_wl *wl = ssb_get_devtypedata(dev); |
4570 | struct b43_wldev *wldev = ssb_get_drvdata(dev); | 4604 | struct b43_wldev *wldev = ssb_get_drvdata(dev); |
4571 | 4605 | ||
4606 | /* We must cancel any work here before unregistering from ieee80211, | ||
4607 | * as the ieee80211 unreg will destroy the workqueue. */ | ||
4608 | cancel_work_sync(&wldev->restart_work); | ||
4609 | |||
4572 | B43_WARN_ON(!wl); | 4610 | B43_WARN_ON(!wl); |
4573 | if (wl->current_dev == wldev) | 4611 | if (wl->current_dev == wldev) |
4574 | ieee80211_unregister_hw(wl->hw); | 4612 | ieee80211_unregister_hw(wl->hw); |
diff --git a/drivers/net/wireless/b43legacy/Kconfig b/drivers/net/wireless/b43legacy/Kconfig index 13c65faf0247..aef2298d37ac 100644 --- a/drivers/net/wireless/b43legacy/Kconfig +++ b/drivers/net/wireless/b43legacy/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config B43LEGACY | 1 | config B43LEGACY |
2 | tristate "Broadcom 43xx-legacy wireless support (mac80211 stack)" | 2 | tristate "Broadcom 43xx-legacy wireless support (mac80211 stack)" |
3 | depends on SSB_POSSIBLE && MAC80211 && WLAN_80211 | 3 | depends on SSB_POSSIBLE && MAC80211 && WLAN_80211 && HAS_DMA |
4 | select SSB | 4 | select SSB |
5 | select FW_LOADER | 5 | select FW_LOADER |
6 | select HW_RANDOM | 6 | select HW_RANDOM |
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index 14a5eea2573e..204077c13870 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c | |||
@@ -3039,7 +3039,6 @@ static void b43legacy_set_pretbtt(struct b43legacy_wldev *dev) | |||
3039 | /* Locking: wl->mutex */ | 3039 | /* Locking: wl->mutex */ |
3040 | static void b43legacy_wireless_core_exit(struct b43legacy_wldev *dev) | 3040 | static void b43legacy_wireless_core_exit(struct b43legacy_wldev *dev) |
3041 | { | 3041 | { |
3042 | struct b43legacy_wl *wl = dev->wl; | ||
3043 | struct b43legacy_phy *phy = &dev->phy; | 3042 | struct b43legacy_phy *phy = &dev->phy; |
3044 | u32 macctl; | 3043 | u32 macctl; |
3045 | 3044 | ||
@@ -3054,12 +3053,6 @@ static void b43legacy_wireless_core_exit(struct b43legacy_wldev *dev) | |||
3054 | macctl |= B43legacy_MACCTL_PSM_JMP0; | 3053 | macctl |= B43legacy_MACCTL_PSM_JMP0; |
3055 | b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl); | 3054 | b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl); |
3056 | 3055 | ||
3057 | mutex_unlock(&wl->mutex); | ||
3058 | /* Must unlock as it would otherwise deadlock. No races here. | ||
3059 | * Cancel possibly pending workqueues. */ | ||
3060 | cancel_work_sync(&dev->restart_work); | ||
3061 | mutex_lock(&wl->mutex); | ||
3062 | |||
3063 | b43legacy_leds_exit(dev); | 3056 | b43legacy_leds_exit(dev); |
3064 | b43legacy_rng_exit(dev->wl); | 3057 | b43legacy_rng_exit(dev->wl); |
3065 | b43legacy_pio_free(dev); | 3058 | b43legacy_pio_free(dev); |
@@ -3486,6 +3479,8 @@ static void b43legacy_chip_reset(struct work_struct *work) | |||
3486 | } | 3479 | } |
3487 | } | 3480 | } |
3488 | out: | 3481 | out: |
3482 | if (err) | ||
3483 | wl->current_dev = NULL; /* Failed to init the dev. */ | ||
3489 | mutex_unlock(&wl->mutex); | 3484 | mutex_unlock(&wl->mutex); |
3490 | if (err) | 3485 | if (err) |
3491 | b43legacyerr(wl, "Controller restart FAILED\n"); | 3486 | b43legacyerr(wl, "Controller restart FAILED\n"); |
@@ -3618,9 +3613,11 @@ static void b43legacy_one_core_detach(struct ssb_device *dev) | |||
3618 | struct b43legacy_wldev *wldev; | 3613 | struct b43legacy_wldev *wldev; |
3619 | struct b43legacy_wl *wl; | 3614 | struct b43legacy_wl *wl; |
3620 | 3615 | ||
3616 | /* Do not cancel ieee80211-workqueue based work here. | ||
3617 | * See comment in b43legacy_remove(). */ | ||
3618 | |||
3621 | wldev = ssb_get_drvdata(dev); | 3619 | wldev = ssb_get_drvdata(dev); |
3622 | wl = wldev->wl; | 3620 | wl = wldev->wl; |
3623 | cancel_work_sync(&wldev->restart_work); | ||
3624 | b43legacy_debugfs_remove_device(wldev); | 3621 | b43legacy_debugfs_remove_device(wldev); |
3625 | b43legacy_wireless_core_detach(wldev); | 3622 | b43legacy_wireless_core_detach(wldev); |
3626 | list_del(&wldev->list); | 3623 | list_del(&wldev->list); |
@@ -3789,6 +3786,10 @@ static void b43legacy_remove(struct ssb_device *dev) | |||
3789 | struct b43legacy_wl *wl = ssb_get_devtypedata(dev); | 3786 | struct b43legacy_wl *wl = ssb_get_devtypedata(dev); |
3790 | struct b43legacy_wldev *wldev = ssb_get_drvdata(dev); | 3787 | struct b43legacy_wldev *wldev = ssb_get_drvdata(dev); |
3791 | 3788 | ||
3789 | /* We must cancel any work here before unregistering from ieee80211, | ||
3790 | * as the ieee80211 unreg will destroy the workqueue. */ | ||
3791 | cancel_work_sync(&wldev->restart_work); | ||
3792 | |||
3792 | B43legacy_WARN_ON(!wl); | 3793 | B43legacy_WARN_ON(!wl); |
3793 | if (wl->current_dev == wldev) | 3794 | if (wl->current_dev == wldev) |
3794 | ieee80211_unregister_hw(wl->hw); | 3795 | ieee80211_unregister_hw(wl->hw); |
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c index 437a9bcc9bd3..ed4317a17cbb 100644 --- a/drivers/net/wireless/hostap/hostap_cs.c +++ b/drivers/net/wireless/hostap/hostap_cs.c | |||
@@ -833,6 +833,7 @@ static struct pcmcia_device_id hostap_cs_ids[] = { | |||
833 | PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x0001), | 833 | PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x0001), |
834 | PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x7300), | 834 | PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x7300), |
835 | /* PCMCIA_DEVICE_MANF_CARD(0xc00f, 0x0000), conflict with pcnet_cs */ | 835 | /* PCMCIA_DEVICE_MANF_CARD(0xc00f, 0x0000), conflict with pcnet_cs */ |
836 | PCMCIA_DEVICE_MANF_CARD(0xc250, 0x0002), | ||
836 | PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002), | 837 | PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002), |
837 | PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005), | 838 | PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005), |
838 | PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0010), | 839 | PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0010), |
diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c index 7be68db6f300..cdf90c40f11b 100644 --- a/drivers/net/wireless/hostap/hostap_hw.c +++ b/drivers/net/wireless/hostap/hostap_hw.c | |||
@@ -3276,11 +3276,6 @@ while (0) | |||
3276 | } | 3276 | } |
3277 | printk(KERN_INFO "%s: Registered netdevice %s\n", dev_info, dev->name); | 3277 | printk(KERN_INFO "%s: Registered netdevice %s\n", dev_info, dev->name); |
3278 | 3278 | ||
3279 | #ifndef PRISM2_NO_PROCFS_DEBUG | ||
3280 | create_proc_read_entry("registers", 0, local->proc, | ||
3281 | prism2_registers_proc_read, local); | ||
3282 | #endif /* PRISM2_NO_PROCFS_DEBUG */ | ||
3283 | |||
3284 | hostap_init_data(local); | 3279 | hostap_init_data(local); |
3285 | return dev; | 3280 | return dev; |
3286 | 3281 | ||
@@ -3307,6 +3302,10 @@ static int hostap_hw_ready(struct net_device *dev) | |||
3307 | netif_carrier_off(local->ddev); | 3302 | netif_carrier_off(local->ddev); |
3308 | } | 3303 | } |
3309 | hostap_init_proc(local); | 3304 | hostap_init_proc(local); |
3305 | #ifndef PRISM2_NO_PROCFS_DEBUG | ||
3306 | create_proc_read_entry("registers", 0, local->proc, | ||
3307 | prism2_registers_proc_read, local); | ||
3308 | #endif /* PRISM2_NO_PROCFS_DEBUG */ | ||
3310 | hostap_init_ap_proc(local); | 3309 | hostap_init_ap_proc(local); |
3311 | return 0; | 3310 | return 0; |
3312 | } | 3311 | } |
diff --git a/drivers/net/wireless/hostap/hostap_main.c b/drivers/net/wireless/hostap/hostap_main.c index 20d387f6658c..f7aec9309d04 100644 --- a/drivers/net/wireless/hostap/hostap_main.c +++ b/drivers/net/wireless/hostap/hostap_main.c | |||
@@ -682,7 +682,13 @@ static int prism2_close(struct net_device *dev) | |||
682 | netif_device_detach(dev); | 682 | netif_device_detach(dev); |
683 | } | 683 | } |
684 | 684 | ||
685 | flush_scheduled_work(); | 685 | cancel_work_sync(&local->reset_queue); |
686 | cancel_work_sync(&local->set_multicast_list_queue); | ||
687 | cancel_work_sync(&local->set_tim_queue); | ||
688 | #ifndef PRISM2_NO_STATION_MODES | ||
689 | cancel_work_sync(&local->info_queue); | ||
690 | #endif | ||
691 | cancel_work_sync(&local->comms_qual_update); | ||
686 | 692 | ||
687 | module_put(local->hw_module); | 693 | module_put(local->hw_module); |
688 | 694 | ||
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c index fa87c5c2ae0b..6e704608947c 100644 --- a/drivers/net/wireless/ipw2200.c +++ b/drivers/net/wireless/ipw2200.c | |||
@@ -1753,6 +1753,8 @@ static int ipw_radio_kill_sw(struct ipw_priv *priv, int disable_radio) | |||
1753 | 1753 | ||
1754 | if (priv->workqueue) { | 1754 | if (priv->workqueue) { |
1755 | cancel_delayed_work(&priv->request_scan); | 1755 | cancel_delayed_work(&priv->request_scan); |
1756 | cancel_delayed_work(&priv->request_direct_scan); | ||
1757 | cancel_delayed_work(&priv->request_passive_scan); | ||
1756 | cancel_delayed_work(&priv->scan_event); | 1758 | cancel_delayed_work(&priv->scan_event); |
1757 | } | 1759 | } |
1758 | queue_work(priv->workqueue, &priv->down); | 1760 | queue_work(priv->workqueue, &priv->down); |
@@ -2005,6 +2007,8 @@ static void ipw_irq_tasklet(struct ipw_priv *priv) | |||
2005 | wake_up_interruptible(&priv->wait_command_queue); | 2007 | wake_up_interruptible(&priv->wait_command_queue); |
2006 | priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING); | 2008 | priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING); |
2007 | cancel_delayed_work(&priv->request_scan); | 2009 | cancel_delayed_work(&priv->request_scan); |
2010 | cancel_delayed_work(&priv->request_direct_scan); | ||
2011 | cancel_delayed_work(&priv->request_passive_scan); | ||
2008 | cancel_delayed_work(&priv->scan_event); | 2012 | cancel_delayed_work(&priv->scan_event); |
2009 | schedule_work(&priv->link_down); | 2013 | schedule_work(&priv->link_down); |
2010 | queue_delayed_work(priv->workqueue, &priv->rf_kill, 2 * HZ); | 2014 | queue_delayed_work(priv->workqueue, &priv->rf_kill, 2 * HZ); |
@@ -4712,6 +4716,12 @@ static void ipw_rx_notification(struct ipw_priv *priv, | |||
4712 | priv->status &= ~STATUS_SCAN_FORCED; | 4716 | priv->status &= ~STATUS_SCAN_FORCED; |
4713 | #endif /* CONFIG_IPW2200_MONITOR */ | 4717 | #endif /* CONFIG_IPW2200_MONITOR */ |
4714 | 4718 | ||
4719 | /* Do queued direct scans first */ | ||
4720 | if (priv->status & STATUS_DIRECT_SCAN_PENDING) { | ||
4721 | queue_delayed_work(priv->workqueue, | ||
4722 | &priv->request_direct_scan, 0); | ||
4723 | } | ||
4724 | |||
4715 | if (!(priv->status & (STATUS_ASSOCIATED | | 4725 | if (!(priv->status & (STATUS_ASSOCIATED | |
4716 | STATUS_ASSOCIATING | | 4726 | STATUS_ASSOCIATING | |
4717 | STATUS_ROAMING | | 4727 | STATUS_ROAMING | |
@@ -6267,7 +6277,7 @@ static void ipw_add_scan_channels(struct ipw_priv *priv, | |||
6267 | } | 6277 | } |
6268 | } | 6278 | } |
6269 | 6279 | ||
6270 | static int ipw_request_scan_helper(struct ipw_priv *priv, int type) | 6280 | static int ipw_request_scan_helper(struct ipw_priv *priv, int type, int direct) |
6271 | { | 6281 | { |
6272 | struct ipw_scan_request_ext scan; | 6282 | struct ipw_scan_request_ext scan; |
6273 | int err = 0, scan_type; | 6283 | int err = 0, scan_type; |
@@ -6278,22 +6288,31 @@ static int ipw_request_scan_helper(struct ipw_priv *priv, int type) | |||
6278 | 6288 | ||
6279 | mutex_lock(&priv->mutex); | 6289 | mutex_lock(&priv->mutex); |
6280 | 6290 | ||
6291 | if (direct && (priv->direct_scan_ssid_len == 0)) { | ||
6292 | IPW_DEBUG_HC("Direct scan requested but no SSID to scan for\n"); | ||
6293 | priv->status &= ~STATUS_DIRECT_SCAN_PENDING; | ||
6294 | goto done; | ||
6295 | } | ||
6296 | |||
6281 | if (priv->status & STATUS_SCANNING) { | 6297 | if (priv->status & STATUS_SCANNING) { |
6282 | IPW_DEBUG_HC("Concurrent scan requested. Ignoring.\n"); | 6298 | IPW_DEBUG_HC("Concurrent scan requested. Queuing.\n"); |
6283 | priv->status |= STATUS_SCAN_PENDING; | 6299 | priv->status |= direct ? STATUS_DIRECT_SCAN_PENDING : |
6300 | STATUS_SCAN_PENDING; | ||
6284 | goto done; | 6301 | goto done; |
6285 | } | 6302 | } |
6286 | 6303 | ||
6287 | if (!(priv->status & STATUS_SCAN_FORCED) && | 6304 | if (!(priv->status & STATUS_SCAN_FORCED) && |
6288 | priv->status & STATUS_SCAN_ABORTING) { | 6305 | priv->status & STATUS_SCAN_ABORTING) { |
6289 | IPW_DEBUG_HC("Scan request while abort pending. Queuing.\n"); | 6306 | IPW_DEBUG_HC("Scan request while abort pending. Queuing.\n"); |
6290 | priv->status |= STATUS_SCAN_PENDING; | 6307 | priv->status |= direct ? STATUS_DIRECT_SCAN_PENDING : |
6308 | STATUS_SCAN_PENDING; | ||
6291 | goto done; | 6309 | goto done; |
6292 | } | 6310 | } |
6293 | 6311 | ||
6294 | if (priv->status & STATUS_RF_KILL_MASK) { | 6312 | if (priv->status & STATUS_RF_KILL_MASK) { |
6295 | IPW_DEBUG_HC("Aborting scan due to RF Kill activation\n"); | 6313 | IPW_DEBUG_HC("Queuing scan due to RF Kill activation\n"); |
6296 | priv->status |= STATUS_SCAN_PENDING; | 6314 | priv->status |= direct ? STATUS_DIRECT_SCAN_PENDING : |
6315 | STATUS_SCAN_PENDING; | ||
6297 | goto done; | 6316 | goto done; |
6298 | } | 6317 | } |
6299 | 6318 | ||
@@ -6321,6 +6340,7 @@ static int ipw_request_scan_helper(struct ipw_priv *priv, int type) | |||
6321 | cpu_to_le16(20); | 6340 | cpu_to_le16(20); |
6322 | 6341 | ||
6323 | scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = cpu_to_le16(120); | 6342 | scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = cpu_to_le16(120); |
6343 | scan.dwell_time[IPW_SCAN_ACTIVE_DIRECT_SCAN] = cpu_to_le16(20); | ||
6324 | 6344 | ||
6325 | #ifdef CONFIG_IPW2200_MONITOR | 6345 | #ifdef CONFIG_IPW2200_MONITOR |
6326 | if (priv->ieee->iw_mode == IW_MODE_MONITOR) { | 6346 | if (priv->ieee->iw_mode == IW_MODE_MONITOR) { |
@@ -6360,13 +6380,23 @@ static int ipw_request_scan_helper(struct ipw_priv *priv, int type) | |||
6360 | cpu_to_le16(2000); | 6380 | cpu_to_le16(2000); |
6361 | } else { | 6381 | } else { |
6362 | #endif /* CONFIG_IPW2200_MONITOR */ | 6382 | #endif /* CONFIG_IPW2200_MONITOR */ |
6363 | /* If we are roaming, then make this a directed scan for the | 6383 | /* Honor direct scans first, otherwise if we are roaming make |
6364 | * current network. Otherwise, ensure that every other scan | 6384 | * this a direct scan for the current network. Finally, |
6365 | * is a fast channel hop scan */ | 6385 | * ensure that every other scan is a fast channel hop scan */ |
6366 | if ((priv->status & STATUS_ROAMING) | 6386 | if (direct) { |
6367 | || (!(priv->status & STATUS_ASSOCIATED) | 6387 | err = ipw_send_ssid(priv, priv->direct_scan_ssid, |
6368 | && (priv->config & CFG_STATIC_ESSID) | 6388 | priv->direct_scan_ssid_len); |
6369 | && (le32_to_cpu(scan.full_scan_index) % 2))) { | 6389 | if (err) { |
6390 | IPW_DEBUG_HC("Attempt to send SSID command " | ||
6391 | "failed\n"); | ||
6392 | goto done; | ||
6393 | } | ||
6394 | |||
6395 | scan_type = IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN; | ||
6396 | } else if ((priv->status & STATUS_ROAMING) | ||
6397 | || (!(priv->status & STATUS_ASSOCIATED) | ||
6398 | && (priv->config & CFG_STATIC_ESSID) | ||
6399 | && (le32_to_cpu(scan.full_scan_index) % 2))) { | ||
6370 | err = ipw_send_ssid(priv, priv->essid, priv->essid_len); | 6400 | err = ipw_send_ssid(priv, priv->essid, priv->essid_len); |
6371 | if (err) { | 6401 | if (err) { |
6372 | IPW_DEBUG_HC("Attempt to send SSID command " | 6402 | IPW_DEBUG_HC("Attempt to send SSID command " |
@@ -6391,7 +6421,12 @@ send_request: | |||
6391 | } | 6421 | } |
6392 | 6422 | ||
6393 | priv->status |= STATUS_SCANNING; | 6423 | priv->status |= STATUS_SCANNING; |
6394 | priv->status &= ~STATUS_SCAN_PENDING; | 6424 | if (direct) { |
6425 | priv->status &= ~STATUS_DIRECT_SCAN_PENDING; | ||
6426 | priv->direct_scan_ssid_len = 0; | ||
6427 | } else | ||
6428 | priv->status &= ~STATUS_SCAN_PENDING; | ||
6429 | |||
6395 | queue_delayed_work(priv->workqueue, &priv->scan_check, | 6430 | queue_delayed_work(priv->workqueue, &priv->scan_check, |
6396 | IPW_SCAN_CHECK_WATCHDOG); | 6431 | IPW_SCAN_CHECK_WATCHDOG); |
6397 | done: | 6432 | done: |
@@ -6402,15 +6437,22 @@ done: | |||
6402 | static void ipw_request_passive_scan(struct work_struct *work) | 6437 | static void ipw_request_passive_scan(struct work_struct *work) |
6403 | { | 6438 | { |
6404 | struct ipw_priv *priv = | 6439 | struct ipw_priv *priv = |
6405 | container_of(work, struct ipw_priv, request_passive_scan); | 6440 | container_of(work, struct ipw_priv, request_passive_scan.work); |
6406 | ipw_request_scan_helper(priv, IW_SCAN_TYPE_PASSIVE); | 6441 | ipw_request_scan_helper(priv, IW_SCAN_TYPE_PASSIVE, 0); |
6407 | } | 6442 | } |
6408 | 6443 | ||
6409 | static void ipw_request_scan(struct work_struct *work) | 6444 | static void ipw_request_scan(struct work_struct *work) |
6410 | { | 6445 | { |
6411 | struct ipw_priv *priv = | 6446 | struct ipw_priv *priv = |
6412 | container_of(work, struct ipw_priv, request_scan.work); | 6447 | container_of(work, struct ipw_priv, request_scan.work); |
6413 | ipw_request_scan_helper(priv, IW_SCAN_TYPE_ACTIVE); | 6448 | ipw_request_scan_helper(priv, IW_SCAN_TYPE_ACTIVE, 0); |
6449 | } | ||
6450 | |||
6451 | static void ipw_request_direct_scan(struct work_struct *work) | ||
6452 | { | ||
6453 | struct ipw_priv *priv = | ||
6454 | container_of(work, struct ipw_priv, request_direct_scan.work); | ||
6455 | ipw_request_scan_helper(priv, IW_SCAN_TYPE_ACTIVE, 1); | ||
6414 | } | 6456 | } |
6415 | 6457 | ||
6416 | static void ipw_bg_abort_scan(struct work_struct *work) | 6458 | static void ipw_bg_abort_scan(struct work_struct *work) |
@@ -7558,8 +7600,31 @@ static int ipw_associate(void *data) | |||
7558 | priv->ieee->iw_mode == IW_MODE_ADHOC && | 7600 | priv->ieee->iw_mode == IW_MODE_ADHOC && |
7559 | priv->config & CFG_ADHOC_CREATE && | 7601 | priv->config & CFG_ADHOC_CREATE && |
7560 | priv->config & CFG_STATIC_ESSID && | 7602 | priv->config & CFG_STATIC_ESSID && |
7561 | priv->config & CFG_STATIC_CHANNEL && | 7603 | priv->config & CFG_STATIC_CHANNEL) { |
7562 | !list_empty(&priv->ieee->network_free_list)) { | 7604 | /* Use oldest network if the free list is empty */ |
7605 | if (list_empty(&priv->ieee->network_free_list)) { | ||
7606 | struct ieee80211_network *oldest = NULL; | ||
7607 | struct ieee80211_network *target; | ||
7608 | DECLARE_MAC_BUF(mac); | ||
7609 | |||
7610 | list_for_each_entry(target, &priv->ieee->network_list, list) { | ||
7611 | if ((oldest == NULL) || | ||
7612 | (target->last_scanned < oldest->last_scanned)) | ||
7613 | oldest = target; | ||
7614 | } | ||
7615 | |||
7616 | /* If there are no more slots, expire the oldest */ | ||
7617 | list_del(&oldest->list); | ||
7618 | target = oldest; | ||
7619 | IPW_DEBUG_ASSOC("Expired '%s' (%s) from " | ||
7620 | "network list.\n", | ||
7621 | escape_essid(target->ssid, | ||
7622 | target->ssid_len), | ||
7623 | print_mac(mac, target->bssid)); | ||
7624 | list_add_tail(&target->list, | ||
7625 | &priv->ieee->network_free_list); | ||
7626 | } | ||
7627 | |||
7563 | element = priv->ieee->network_free_list.next; | 7628 | element = priv->ieee->network_free_list.next; |
7564 | network = list_entry(element, struct ieee80211_network, list); | 7629 | network = list_entry(element, struct ieee80211_network, list); |
7565 | ipw_adhoc_create(priv, network); | 7630 | ipw_adhoc_create(priv, network); |
@@ -9454,99 +9519,38 @@ static int ipw_wx_get_retry(struct net_device *dev, | |||
9454 | return 0; | 9519 | return 0; |
9455 | } | 9520 | } |
9456 | 9521 | ||
9457 | static int ipw_request_direct_scan(struct ipw_priv *priv, char *essid, | ||
9458 | int essid_len) | ||
9459 | { | ||
9460 | struct ipw_scan_request_ext scan; | ||
9461 | int err = 0, scan_type; | ||
9462 | |||
9463 | if (!(priv->status & STATUS_INIT) || | ||
9464 | (priv->status & STATUS_EXIT_PENDING)) | ||
9465 | return 0; | ||
9466 | |||
9467 | mutex_lock(&priv->mutex); | ||
9468 | |||
9469 | if (priv->status & STATUS_RF_KILL_MASK) { | ||
9470 | IPW_DEBUG_HC("Aborting scan due to RF kill activation\n"); | ||
9471 | priv->status |= STATUS_SCAN_PENDING; | ||
9472 | goto done; | ||
9473 | } | ||
9474 | |||
9475 | IPW_DEBUG_HC("starting request direct scan!\n"); | ||
9476 | |||
9477 | if (priv->status & (STATUS_SCANNING | STATUS_SCAN_ABORTING)) { | ||
9478 | /* We should not sleep here; otherwise we will block most | ||
9479 | * of the system (for instance, we hold rtnl_lock when we | ||
9480 | * get here). | ||
9481 | */ | ||
9482 | err = -EAGAIN; | ||
9483 | goto done; | ||
9484 | } | ||
9485 | memset(&scan, 0, sizeof(scan)); | ||
9486 | |||
9487 | if (priv->config & CFG_SPEED_SCAN) | ||
9488 | scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] = | ||
9489 | cpu_to_le16(30); | ||
9490 | else | ||
9491 | scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] = | ||
9492 | cpu_to_le16(20); | ||
9493 | |||
9494 | scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN] = | ||
9495 | cpu_to_le16(20); | ||
9496 | scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = cpu_to_le16(120); | ||
9497 | scan.dwell_time[IPW_SCAN_ACTIVE_DIRECT_SCAN] = cpu_to_le16(20); | ||
9498 | |||
9499 | scan.full_scan_index = cpu_to_le32(ieee80211_get_scans(priv->ieee)); | ||
9500 | |||
9501 | err = ipw_send_ssid(priv, essid, essid_len); | ||
9502 | if (err) { | ||
9503 | IPW_DEBUG_HC("Attempt to send SSID command failed\n"); | ||
9504 | goto done; | ||
9505 | } | ||
9506 | scan_type = IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN; | ||
9507 | |||
9508 | ipw_add_scan_channels(priv, &scan, scan_type); | ||
9509 | |||
9510 | err = ipw_send_scan_request_ext(priv, &scan); | ||
9511 | if (err) { | ||
9512 | IPW_DEBUG_HC("Sending scan command failed: %08X\n", err); | ||
9513 | goto done; | ||
9514 | } | ||
9515 | |||
9516 | priv->status |= STATUS_SCANNING; | ||
9517 | |||
9518 | done: | ||
9519 | mutex_unlock(&priv->mutex); | ||
9520 | return err; | ||
9521 | } | ||
9522 | |||
9523 | static int ipw_wx_set_scan(struct net_device *dev, | 9522 | static int ipw_wx_set_scan(struct net_device *dev, |
9524 | struct iw_request_info *info, | 9523 | struct iw_request_info *info, |
9525 | union iwreq_data *wrqu, char *extra) | 9524 | union iwreq_data *wrqu, char *extra) |
9526 | { | 9525 | { |
9527 | struct ipw_priv *priv = ieee80211_priv(dev); | 9526 | struct ipw_priv *priv = ieee80211_priv(dev); |
9528 | struct iw_scan_req *req = (struct iw_scan_req *)extra; | 9527 | struct iw_scan_req *req = (struct iw_scan_req *)extra; |
9528 | struct delayed_work *work = NULL; | ||
9529 | 9529 | ||
9530 | mutex_lock(&priv->mutex); | 9530 | mutex_lock(&priv->mutex); |
9531 | |||
9531 | priv->user_requested_scan = 1; | 9532 | priv->user_requested_scan = 1; |
9532 | mutex_unlock(&priv->mutex); | ||
9533 | 9533 | ||
9534 | if (wrqu->data.length == sizeof(struct iw_scan_req)) { | 9534 | if (wrqu->data.length == sizeof(struct iw_scan_req)) { |
9535 | if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { | 9535 | if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { |
9536 | ipw_request_direct_scan(priv, req->essid, | 9536 | int len = min((int)req->essid_len, |
9537 | req->essid_len); | 9537 | (int)sizeof(priv->direct_scan_ssid)); |
9538 | return 0; | 9538 | memcpy(priv->direct_scan_ssid, req->essid, len); |
9539 | } | 9539 | priv->direct_scan_ssid_len = len; |
9540 | if (req->scan_type == IW_SCAN_TYPE_PASSIVE) { | 9540 | work = &priv->request_direct_scan; |
9541 | queue_work(priv->workqueue, | 9541 | } else if (req->scan_type == IW_SCAN_TYPE_PASSIVE) { |
9542 | &priv->request_passive_scan); | 9542 | work = &priv->request_passive_scan; |
9543 | return 0; | ||
9544 | } | 9543 | } |
9544 | } else { | ||
9545 | /* Normal active broadcast scan */ | ||
9546 | work = &priv->request_scan; | ||
9545 | } | 9547 | } |
9546 | 9548 | ||
9549 | mutex_unlock(&priv->mutex); | ||
9550 | |||
9547 | IPW_DEBUG_WX("Start scan\n"); | 9551 | IPW_DEBUG_WX("Start scan\n"); |
9548 | 9552 | ||
9549 | queue_delayed_work(priv->workqueue, &priv->request_scan, 0); | 9553 | queue_delayed_work(priv->workqueue, work, 0); |
9550 | 9554 | ||
9551 | return 0; | 9555 | return 0; |
9552 | } | 9556 | } |
@@ -10708,6 +10712,8 @@ static void ipw_link_up(struct ipw_priv *priv) | |||
10708 | } | 10712 | } |
10709 | 10713 | ||
10710 | cancel_delayed_work(&priv->request_scan); | 10714 | cancel_delayed_work(&priv->request_scan); |
10715 | cancel_delayed_work(&priv->request_direct_scan); | ||
10716 | cancel_delayed_work(&priv->request_passive_scan); | ||
10711 | cancel_delayed_work(&priv->scan_event); | 10717 | cancel_delayed_work(&priv->scan_event); |
10712 | ipw_reset_stats(priv); | 10718 | ipw_reset_stats(priv); |
10713 | /* Ensure the rate is updated immediately */ | 10719 | /* Ensure the rate is updated immediately */ |
@@ -10738,6 +10744,8 @@ static void ipw_link_down(struct ipw_priv *priv) | |||
10738 | 10744 | ||
10739 | /* Cancel any queued work ... */ | 10745 | /* Cancel any queued work ... */ |
10740 | cancel_delayed_work(&priv->request_scan); | 10746 | cancel_delayed_work(&priv->request_scan); |
10747 | cancel_delayed_work(&priv->request_direct_scan); | ||
10748 | cancel_delayed_work(&priv->request_passive_scan); | ||
10741 | cancel_delayed_work(&priv->adhoc_check); | 10749 | cancel_delayed_work(&priv->adhoc_check); |
10742 | cancel_delayed_work(&priv->gather_stats); | 10750 | cancel_delayed_work(&priv->gather_stats); |
10743 | 10751 | ||
@@ -10777,8 +10785,9 @@ static int __devinit ipw_setup_deferred_work(struct ipw_priv *priv) | |||
10777 | INIT_WORK(&priv->up, ipw_bg_up); | 10785 | INIT_WORK(&priv->up, ipw_bg_up); |
10778 | INIT_WORK(&priv->down, ipw_bg_down); | 10786 | INIT_WORK(&priv->down, ipw_bg_down); |
10779 | INIT_DELAYED_WORK(&priv->request_scan, ipw_request_scan); | 10787 | INIT_DELAYED_WORK(&priv->request_scan, ipw_request_scan); |
10788 | INIT_DELAYED_WORK(&priv->request_direct_scan, ipw_request_direct_scan); | ||
10789 | INIT_DELAYED_WORK(&priv->request_passive_scan, ipw_request_passive_scan); | ||
10780 | INIT_DELAYED_WORK(&priv->scan_event, ipw_scan_event); | 10790 | INIT_DELAYED_WORK(&priv->scan_event, ipw_scan_event); |
10781 | INIT_WORK(&priv->request_passive_scan, ipw_request_passive_scan); | ||
10782 | INIT_DELAYED_WORK(&priv->gather_stats, ipw_bg_gather_stats); | 10791 | INIT_DELAYED_WORK(&priv->gather_stats, ipw_bg_gather_stats); |
10783 | INIT_WORK(&priv->abort_scan, ipw_bg_abort_scan); | 10792 | INIT_WORK(&priv->abort_scan, ipw_bg_abort_scan); |
10784 | INIT_WORK(&priv->roam, ipw_bg_roam); | 10793 | INIT_WORK(&priv->roam, ipw_bg_roam); |
@@ -11584,6 +11593,7 @@ static int ipw_prom_alloc(struct ipw_priv *priv) | |||
11584 | priv->prom_net_dev->hard_start_xmit = ipw_prom_hard_start_xmit; | 11593 | priv->prom_net_dev->hard_start_xmit = ipw_prom_hard_start_xmit; |
11585 | 11594 | ||
11586 | priv->prom_priv->ieee->iw_mode = IW_MODE_MONITOR; | 11595 | priv->prom_priv->ieee->iw_mode = IW_MODE_MONITOR; |
11596 | SET_NETDEV_DEV(priv->prom_net_dev, &priv->pci_dev->dev); | ||
11587 | 11597 | ||
11588 | rc = register_netdev(priv->prom_net_dev); | 11598 | rc = register_netdev(priv->prom_net_dev); |
11589 | if (rc) { | 11599 | if (rc) { |
@@ -11811,6 +11821,8 @@ static void __devexit ipw_pci_remove(struct pci_dev *pdev) | |||
11811 | cancel_delayed_work(&priv->adhoc_check); | 11821 | cancel_delayed_work(&priv->adhoc_check); |
11812 | cancel_delayed_work(&priv->gather_stats); | 11822 | cancel_delayed_work(&priv->gather_stats); |
11813 | cancel_delayed_work(&priv->request_scan); | 11823 | cancel_delayed_work(&priv->request_scan); |
11824 | cancel_delayed_work(&priv->request_direct_scan); | ||
11825 | cancel_delayed_work(&priv->request_passive_scan); | ||
11814 | cancel_delayed_work(&priv->scan_event); | 11826 | cancel_delayed_work(&priv->scan_event); |
11815 | cancel_delayed_work(&priv->rf_kill); | 11827 | cancel_delayed_work(&priv->rf_kill); |
11816 | cancel_delayed_work(&priv->scan_check); | 11828 | cancel_delayed_work(&priv->scan_check); |
diff --git a/drivers/net/wireless/ipw2200.h b/drivers/net/wireless/ipw2200.h index cd3295b66dd6..d4ab28b73b32 100644 --- a/drivers/net/wireless/ipw2200.h +++ b/drivers/net/wireless/ipw2200.h | |||
@@ -1037,6 +1037,7 @@ struct ipw_cmd { /* XXX */ | |||
1037 | #define STATUS_DISASSOC_PENDING (1<<12) | 1037 | #define STATUS_DISASSOC_PENDING (1<<12) |
1038 | #define STATUS_STATE_PENDING (1<<13) | 1038 | #define STATUS_STATE_PENDING (1<<13) |
1039 | 1039 | ||
1040 | #define STATUS_DIRECT_SCAN_PENDING (1<<19) | ||
1040 | #define STATUS_SCAN_PENDING (1<<20) | 1041 | #define STATUS_SCAN_PENDING (1<<20) |
1041 | #define STATUS_SCANNING (1<<21) | 1042 | #define STATUS_SCANNING (1<<21) |
1042 | #define STATUS_SCAN_ABORTING (1<<22) | 1043 | #define STATUS_SCAN_ABORTING (1<<22) |
@@ -1292,6 +1293,8 @@ struct ipw_priv { | |||
1292 | struct iw_public_data wireless_data; | 1293 | struct iw_public_data wireless_data; |
1293 | 1294 | ||
1294 | int user_requested_scan; | 1295 | int user_requested_scan; |
1296 | u8 direct_scan_ssid[IW_ESSID_MAX_SIZE]; | ||
1297 | u8 direct_scan_ssid_len; | ||
1295 | 1298 | ||
1296 | struct workqueue_struct *workqueue; | 1299 | struct workqueue_struct *workqueue; |
1297 | 1300 | ||
@@ -1301,8 +1304,9 @@ struct ipw_priv { | |||
1301 | struct work_struct system_config; | 1304 | struct work_struct system_config; |
1302 | struct work_struct rx_replenish; | 1305 | struct work_struct rx_replenish; |
1303 | struct delayed_work request_scan; | 1306 | struct delayed_work request_scan; |
1307 | struct delayed_work request_direct_scan; | ||
1308 | struct delayed_work request_passive_scan; | ||
1304 | struct delayed_work scan_event; | 1309 | struct delayed_work scan_event; |
1305 | struct work_struct request_passive_scan; | ||
1306 | struct work_struct adapter_restart; | 1310 | struct work_struct adapter_restart; |
1307 | struct delayed_work rf_kill; | 1311 | struct delayed_work rf_kill; |
1308 | struct work_struct up; | 1312 | struct work_struct up; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-led.c b/drivers/net/wireless/iwlwifi/iwl-3945-led.c index d200d08fb086..8b1528e52d43 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945-led.c | |||
@@ -229,14 +229,15 @@ static int iwl3945_led_register_led(struct iwl3945_priv *priv, | |||
229 | led->led_dev.brightness_set = iwl3945_led_brightness_set; | 229 | led->led_dev.brightness_set = iwl3945_led_brightness_set; |
230 | led->led_dev.default_trigger = trigger; | 230 | led->led_dev.default_trigger = trigger; |
231 | 231 | ||
232 | led->priv = priv; | ||
233 | led->type = type; | ||
234 | |||
232 | ret = led_classdev_register(device, &led->led_dev); | 235 | ret = led_classdev_register(device, &led->led_dev); |
233 | if (ret) { | 236 | if (ret) { |
234 | IWL_ERROR("Error: failed to register led handler.\n"); | 237 | IWL_ERROR("Error: failed to register led handler.\n"); |
235 | return ret; | 238 | return ret; |
236 | } | 239 | } |
237 | 240 | ||
238 | led->priv = priv; | ||
239 | led->type = type; | ||
240 | led->registered = 1; | 241 | led->registered = 1; |
241 | 242 | ||
242 | if (set_led && led->led_on) | 243 | if (set_led && led->led_on) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c index c9847b1a67f7..3a7f0cb710ec 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c | |||
@@ -1162,7 +1162,6 @@ static s32 rs_get_best_rate(struct iwl_priv *priv, | |||
1162 | 1162 | ||
1163 | /* Higher rate not available, use the original */ | 1163 | /* Higher rate not available, use the original */ |
1164 | } else { | 1164 | } else { |
1165 | new_rate = rate; | ||
1166 | break; | 1165 | break; |
1167 | } | 1166 | } |
1168 | } | 1167 | } |
@@ -2009,7 +2008,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, | |||
2009 | * 2) Not just finishing up a search | 2008 | * 2) Not just finishing up a search |
2010 | * 3) Allowing a new search | 2009 | * 3) Allowing a new search |
2011 | */ | 2010 | */ |
2012 | if (!update_lq && !done_search && !lq_sta->stay_in_tbl) { | 2011 | if (!update_lq && !done_search && !lq_sta->stay_in_tbl && window->counter) { |
2013 | /* Save current throughput to compare with "search" throughput*/ | 2012 | /* Save current throughput to compare with "search" throughput*/ |
2014 | lq_sta->last_tpt = current_tpt; | 2013 | lq_sta->last_tpt = current_tpt; |
2015 | 2014 | ||
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index 6328b9593877..8124fd9b1353 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c | |||
@@ -1842,6 +1842,9 @@ static void lbs_send_confirmsleep(struct lbs_private *priv) | |||
1842 | 1842 | ||
1843 | spin_lock_irqsave(&priv->driver_lock, flags); | 1843 | spin_lock_irqsave(&priv->driver_lock, flags); |
1844 | 1844 | ||
1845 | /* We don't get a response on the sleep-confirmation */ | ||
1846 | priv->dnld_sent = DNLD_RES_RECEIVED; | ||
1847 | |||
1845 | /* If nothing to do, go back to sleep (?) */ | 1848 | /* If nothing to do, go back to sleep (?) */ |
1846 | if (!__kfifo_len(priv->event_fifo) && !priv->resp_len[priv->resp_idx]) | 1849 | if (!__kfifo_len(priv->event_fifo) && !priv->resp_len[priv->resp_idx]) |
1847 | priv->psstate = PS_STATE_SLEEP; | 1850 | priv->psstate = PS_STATE_SLEEP; |
@@ -1904,12 +1907,12 @@ void lbs_ps_confirm_sleep(struct lbs_private *priv) | |||
1904 | 1907 | ||
1905 | lbs_deb_enter(LBS_DEB_HOST); | 1908 | lbs_deb_enter(LBS_DEB_HOST); |
1906 | 1909 | ||
1910 | spin_lock_irqsave(&priv->driver_lock, flags); | ||
1907 | if (priv->dnld_sent) { | 1911 | if (priv->dnld_sent) { |
1908 | allowed = 0; | 1912 | allowed = 0; |
1909 | lbs_deb_host("dnld_sent was set\n"); | 1913 | lbs_deb_host("dnld_sent was set\n"); |
1910 | } | 1914 | } |
1911 | 1915 | ||
1912 | spin_lock_irqsave(&priv->driver_lock, flags); | ||
1913 | /* In-progress command? */ | 1916 | /* In-progress command? */ |
1914 | if (priv->cur_cmd) { | 1917 | if (priv->cur_cmd) { |
1915 | allowed = 0; | 1918 | allowed = 0; |
diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c index ad2fabca9116..0aa0ce3b2c42 100644 --- a/drivers/net/wireless/libertas/debugfs.c +++ b/drivers/net/wireless/libertas/debugfs.c | |||
@@ -312,8 +312,8 @@ static ssize_t lbs_threshold_write(uint16_t tlv_type, uint16_t event_mask, | |||
312 | if (tlv_type != TLV_TYPE_BCNMISS) | 312 | if (tlv_type != TLV_TYPE_BCNMISS) |
313 | tlv->freq = freq; | 313 | tlv->freq = freq; |
314 | 314 | ||
315 | /* The command header, the event mask, and the one TLV */ | 315 | /* The command header, the action, the event mask, and one TLV */ |
316 | events->hdr.size = cpu_to_le16(sizeof(events->hdr) + 2 + sizeof(*tlv)); | 316 | events->hdr.size = cpu_to_le16(sizeof(events->hdr) + 4 + sizeof(*tlv)); |
317 | 317 | ||
318 | ret = lbs_cmd_with_response(priv, CMD_802_11_SUBSCRIBE_EVENT, events); | 318 | ret = lbs_cmd_with_response(priv, CMD_802_11_SUBSCRIBE_EVENT, events); |
319 | 319 | ||
diff --git a/drivers/net/wireless/libertas/ethtool.c b/drivers/net/wireless/libertas/ethtool.c index dcfdb404678b..688d60de55cb 100644 --- a/drivers/net/wireless/libertas/ethtool.c +++ b/drivers/net/wireless/libertas/ethtool.c | |||
@@ -73,8 +73,8 @@ out: | |||
73 | return ret; | 73 | return ret; |
74 | } | 74 | } |
75 | 75 | ||
76 | static void lbs_ethtool_get_stats(struct net_device * dev, | 76 | static void lbs_ethtool_get_stats(struct net_device *dev, |
77 | struct ethtool_stats * stats, u64 * data) | 77 | struct ethtool_stats *stats, uint64_t *data) |
78 | { | 78 | { |
79 | struct lbs_private *priv = dev->priv; | 79 | struct lbs_private *priv = dev->priv; |
80 | struct cmd_ds_mesh_access mesh_access; | 80 | struct cmd_ds_mesh_access mesh_access; |
@@ -83,12 +83,12 @@ static void lbs_ethtool_get_stats(struct net_device * dev, | |||
83 | lbs_deb_enter(LBS_DEB_ETHTOOL); | 83 | lbs_deb_enter(LBS_DEB_ETHTOOL); |
84 | 84 | ||
85 | /* Get Mesh Statistics */ | 85 | /* Get Mesh Statistics */ |
86 | ret = lbs_prepare_and_send_command(priv, | 86 | ret = lbs_mesh_access(priv, CMD_ACT_MESH_GET_STATS, &mesh_access); |
87 | CMD_MESH_ACCESS, CMD_ACT_MESH_GET_STATS, | ||
88 | CMD_OPTION_WAITFORRSP, 0, &mesh_access); | ||
89 | 87 | ||
90 | if (ret) | 88 | if (ret) { |
89 | memset(data, 0, MESH_STATS_NUM*(sizeof(uint64_t))); | ||
91 | return; | 90 | return; |
91 | } | ||
92 | 92 | ||
93 | priv->mstats.fwd_drop_rbt = le32_to_cpu(mesh_access.data[0]); | 93 | priv->mstats.fwd_drop_rbt = le32_to_cpu(mesh_access.data[0]); |
94 | priv->mstats.fwd_drop_ttl = le32_to_cpu(mesh_access.data[1]); | 94 | priv->mstats.fwd_drop_ttl = le32_to_cpu(mesh_access.data[1]); |
@@ -111,19 +111,18 @@ static void lbs_ethtool_get_stats(struct net_device * dev, | |||
111 | lbs_deb_enter(LBS_DEB_ETHTOOL); | 111 | lbs_deb_enter(LBS_DEB_ETHTOOL); |
112 | } | 112 | } |
113 | 113 | ||
114 | static int lbs_ethtool_get_sset_count(struct net_device * dev, int sset) | 114 | static int lbs_ethtool_get_sset_count(struct net_device *dev, int sset) |
115 | { | 115 | { |
116 | switch (sset) { | 116 | struct lbs_private *priv = dev->priv; |
117 | case ETH_SS_STATS: | 117 | |
118 | if (sset == ETH_SS_STATS && dev == priv->mesh_dev) | ||
118 | return MESH_STATS_NUM; | 119 | return MESH_STATS_NUM; |
119 | default: | 120 | |
120 | return -EOPNOTSUPP; | 121 | return -EOPNOTSUPP; |
121 | } | ||
122 | } | 122 | } |
123 | 123 | ||
124 | static void lbs_ethtool_get_strings(struct net_device *dev, | 124 | static void lbs_ethtool_get_strings(struct net_device *dev, |
125 | u32 stringset, | 125 | uint32_t stringset, uint8_t *s) |
126 | u8 * s) | ||
127 | { | 126 | { |
128 | int i; | 127 | int i; |
129 | 128 | ||
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index 406f54d40956..acfc4bfcc262 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c | |||
@@ -732,8 +732,8 @@ static int lbs_thread(void *data) | |||
732 | lbs_deb_thread("4: currenttxskb %p, dnld_sent %d\n", | 732 | lbs_deb_thread("4: currenttxskb %p, dnld_sent %d\n", |
733 | priv->currenttxskb, priv->dnld_sent); | 733 | priv->currenttxskb, priv->dnld_sent); |
734 | 734 | ||
735 | spin_lock_irq(&priv->driver_lock); | ||
736 | /* Process any pending command response */ | 735 | /* Process any pending command response */ |
736 | spin_lock_irq(&priv->driver_lock); | ||
737 | resp_idx = priv->resp_idx; | 737 | resp_idx = priv->resp_idx; |
738 | if (priv->resp_len[resp_idx]) { | 738 | if (priv->resp_len[resp_idx]) { |
739 | spin_unlock_irq(&priv->driver_lock); | 739 | spin_unlock_irq(&priv->driver_lock); |
@@ -756,6 +756,7 @@ static int lbs_thread(void *data) | |||
756 | priv->nr_retries = 0; | 756 | priv->nr_retries = 0; |
757 | } else { | 757 | } else { |
758 | priv->cur_cmd = NULL; | 758 | priv->cur_cmd = NULL; |
759 | priv->dnld_sent = DNLD_RES_RECEIVED; | ||
759 | lbs_pr_info("requeueing command %x due to timeout (#%d)\n", | 760 | lbs_pr_info("requeueing command %x due to timeout (#%d)\n", |
760 | le16_to_cpu(cmdnode->cmdbuf->command), priv->nr_retries); | 761 | le16_to_cpu(cmdnode->cmdbuf->command), priv->nr_retries); |
761 | 762 | ||
@@ -1564,6 +1565,7 @@ static int lbs_add_rtap(struct lbs_private *priv) | |||
1564 | rtap_dev->hard_start_xmit = lbs_rtap_hard_start_xmit; | 1565 | rtap_dev->hard_start_xmit = lbs_rtap_hard_start_xmit; |
1565 | rtap_dev->set_multicast_list = lbs_set_multicast_list; | 1566 | rtap_dev->set_multicast_list = lbs_set_multicast_list; |
1566 | rtap_dev->priv = priv; | 1567 | rtap_dev->priv = priv; |
1568 | SET_NETDEV_DEV(rtap_dev, priv->dev->dev.parent); | ||
1567 | 1569 | ||
1568 | ret = register_netdev(rtap_dev); | 1570 | ret = register_netdev(rtap_dev); |
1569 | if (ret) { | 1571 | if (ret) { |
diff --git a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c index 8b7f5768a103..1c216e015f64 100644 --- a/drivers/net/wireless/orinoco_cs.c +++ b/drivers/net/wireless/orinoco_cs.c | |||
@@ -461,6 +461,7 @@ static struct pcmcia_device_id orinoco_cs_ids[] = { | |||
461 | PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0673), /* Linksys WCF12 Wireless CompactFlash Card */ | 461 | PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0673), /* Linksys WCF12 Wireless CompactFlash Card */ |
462 | PCMCIA_DEVICE_MANF_CARD(0x02aa, 0x0002), /* ASUS SpaceLink WL-100 */ | 462 | PCMCIA_DEVICE_MANF_CARD(0x02aa, 0x0002), /* ASUS SpaceLink WL-100 */ |
463 | PCMCIA_DEVICE_MANF_CARD(0x02ac, 0x0002), /* SpeedStream SS1021 Wireless Adapter */ | 463 | PCMCIA_DEVICE_MANF_CARD(0x02ac, 0x0002), /* SpeedStream SS1021 Wireless Adapter */ |
464 | PCMCIA_DEVICE_MANF_CARD(0x02ac, 0x3021), /* SpeedStream Wireless Adapter */ | ||
464 | PCMCIA_DEVICE_MANF_CARD(0x14ea, 0xb001), /* PLANEX RoadLannerWave GW-NS11H */ | 465 | PCMCIA_DEVICE_MANF_CARD(0x14ea, 0xb001), /* PLANEX RoadLannerWave GW-NS11H */ |
465 | PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x7300), /* Airvast WN-100 */ | 466 | PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x7300), /* Airvast WN-100 */ |
466 | PCMCIA_DEVICE_MANF_CARD(0x9005, 0x0021), /* Adaptec Ultra Wireless ANW-8030 */ | 467 | PCMCIA_DEVICE_MANF_CARD(0x9005, 0x0021), /* Adaptec Ultra Wireless ANW-8030 */ |
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index 98ddbb3b3273..1610a7308c1d 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c | |||
@@ -49,6 +49,7 @@ static struct usb_device_id p54u_table[] __devinitdata = { | |||
49 | {USB_DEVICE(0x5041, 0x2235)}, /* Linksys WUSB54G Portable */ | 49 | {USB_DEVICE(0x5041, 0x2235)}, /* Linksys WUSB54G Portable */ |
50 | 50 | ||
51 | /* Version 2 devices (3887) */ | 51 | /* Version 2 devices (3887) */ |
52 | {USB_DEVICE(0x0471, 0x1230)}, /* Philips CPWUA054/00 */ | ||
52 | {USB_DEVICE(0x050d, 0x7050)}, /* Belkin F5D7050 ver 1000 */ | 53 | {USB_DEVICE(0x050d, 0x7050)}, /* Belkin F5D7050 ver 1000 */ |
53 | {USB_DEVICE(0x0572, 0x2000)}, /* Cohiba Proto board */ | 54 | {USB_DEVICE(0x0572, 0x2000)}, /* Cohiba Proto board */ |
54 | {USB_DEVICE(0x0572, 0x2002)}, /* Cohiba Proto board */ | 55 | {USB_DEVICE(0x0572, 0x2002)}, /* Cohiba Proto board */ |
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index d0b1fb15c709..18c9931e3267 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c | |||
@@ -116,6 +116,7 @@ MODULE_PARM_DESC(workaround_interval, | |||
116 | #define OID_802_11_ENCRYPTION_STATUS ccpu2(0x0d01011b) | 116 | #define OID_802_11_ENCRYPTION_STATUS ccpu2(0x0d01011b) |
117 | #define OID_802_11_ADD_KEY ccpu2(0x0d01011d) | 117 | #define OID_802_11_ADD_KEY ccpu2(0x0d01011d) |
118 | #define OID_802_11_REMOVE_KEY ccpu2(0x0d01011e) | 118 | #define OID_802_11_REMOVE_KEY ccpu2(0x0d01011e) |
119 | #define OID_802_11_ASSOCIATION_INFORMATION ccpu2(0x0d01011f) | ||
119 | #define OID_802_11_PMKID ccpu2(0x0d010123) | 120 | #define OID_802_11_PMKID ccpu2(0x0d010123) |
120 | #define OID_802_11_NETWORK_TYPES_SUPPORTED ccpu2(0x0d010203) | 121 | #define OID_802_11_NETWORK_TYPES_SUPPORTED ccpu2(0x0d010203) |
121 | #define OID_802_11_NETWORK_TYPE_IN_USE ccpu2(0x0d010204) | 122 | #define OID_802_11_NETWORK_TYPE_IN_USE ccpu2(0x0d010204) |
@@ -271,6 +272,26 @@ struct ndis_config_param { | |||
271 | __le32 value_length; | 272 | __le32 value_length; |
272 | } __attribute__((packed)); | 273 | } __attribute__((packed)); |
273 | 274 | ||
275 | struct ndis_80211_assoc_info { | ||
276 | __le32 length; | ||
277 | __le16 req_ies; | ||
278 | struct req_ie { | ||
279 | __le16 capa; | ||
280 | __le16 listen_interval; | ||
281 | u8 cur_ap_address[6]; | ||
282 | } req_ie; | ||
283 | __le32 req_ie_length; | ||
284 | __le32 offset_req_ies; | ||
285 | __le16 resp_ies; | ||
286 | struct resp_ie { | ||
287 | __le16 capa; | ||
288 | __le16 status_code; | ||
289 | __le16 assoc_id; | ||
290 | } resp_ie; | ||
291 | __le32 resp_ie_length; | ||
292 | __le32 offset_resp_ies; | ||
293 | } __attribute__((packed)); | ||
294 | |||
274 | /* these have to match what is in wpa_supplicant */ | 295 | /* these have to match what is in wpa_supplicant */ |
275 | enum wpa_alg { WPA_ALG_NONE, WPA_ALG_WEP, WPA_ALG_TKIP, WPA_ALG_CCMP }; | 296 | enum wpa_alg { WPA_ALG_NONE, WPA_ALG_WEP, WPA_ALG_TKIP, WPA_ALG_CCMP }; |
276 | enum wpa_cipher { CIPHER_NONE, CIPHER_WEP40, CIPHER_TKIP, CIPHER_CCMP, | 297 | enum wpa_cipher { CIPHER_NONE, CIPHER_WEP40, CIPHER_TKIP, CIPHER_CCMP, |
@@ -674,6 +695,12 @@ static int get_bssid(struct usbnet *usbdev, u8 bssid[ETH_ALEN]) | |||
674 | return ret; | 695 | return ret; |
675 | } | 696 | } |
676 | 697 | ||
698 | static int get_association_info(struct usbnet *usbdev, | ||
699 | struct ndis_80211_assoc_info *info, int len) | ||
700 | { | ||
701 | return rndis_query_oid(usbdev, OID_802_11_ASSOCIATION_INFORMATION, | ||
702 | info, &len); | ||
703 | } | ||
677 | 704 | ||
678 | static int is_associated(struct usbnet *usbdev) | 705 | static int is_associated(struct usbnet *usbdev) |
679 | { | 706 | { |
@@ -2182,11 +2209,40 @@ static void rndis_wext_worker(struct work_struct *work) | |||
2182 | struct usbnet *usbdev = priv->usbdev; | 2209 | struct usbnet *usbdev = priv->usbdev; |
2183 | union iwreq_data evt; | 2210 | union iwreq_data evt; |
2184 | unsigned char bssid[ETH_ALEN]; | 2211 | unsigned char bssid[ETH_ALEN]; |
2185 | int ret; | 2212 | struct ndis_80211_assoc_info *info; |
2213 | int assoc_size = sizeof(*info) + IW_CUSTOM_MAX + 32; | ||
2214 | int ret, offset; | ||
2186 | 2215 | ||
2187 | if (test_and_clear_bit(WORK_CONNECTION_EVENT, &priv->work_pending)) { | 2216 | if (test_and_clear_bit(WORK_CONNECTION_EVENT, &priv->work_pending)) { |
2188 | ret = get_bssid(usbdev, bssid); | 2217 | info = kzalloc(assoc_size, GFP_KERNEL); |
2218 | if (!info) | ||
2219 | goto get_bssid; | ||
2220 | |||
2221 | /* Get association info IEs from device and send them back to | ||
2222 | * userspace. */ | ||
2223 | ret = get_association_info(usbdev, info, assoc_size); | ||
2224 | if (!ret) { | ||
2225 | evt.data.length = le32_to_cpu(info->req_ie_length); | ||
2226 | if (evt.data.length > 0) { | ||
2227 | offset = le32_to_cpu(info->offset_req_ies); | ||
2228 | wireless_send_event(usbdev->net, | ||
2229 | IWEVASSOCREQIE, &evt, | ||
2230 | (char *)info + offset); | ||
2231 | } | ||
2232 | |||
2233 | evt.data.length = le32_to_cpu(info->resp_ie_length); | ||
2234 | if (evt.data.length > 0) { | ||
2235 | offset = le32_to_cpu(info->offset_resp_ies); | ||
2236 | wireless_send_event(usbdev->net, | ||
2237 | IWEVASSOCRESPIE, &evt, | ||
2238 | (char *)info + offset); | ||
2239 | } | ||
2240 | } | ||
2241 | |||
2242 | kfree(info); | ||
2189 | 2243 | ||
2244 | get_bssid: | ||
2245 | ret = get_bssid(usbdev, bssid); | ||
2190 | if (!ret) { | 2246 | if (!ret) { |
2191 | evt.data.flags = 0; | 2247 | evt.data.flags = 0; |
2192 | evt.data.length = 0; | 2248 | evt.data.length = 0; |
@@ -2414,6 +2470,11 @@ static int bcm4320_early_init(struct usbnet *dev) | |||
2414 | else if (priv->param_power_save > 2) | 2470 | else if (priv->param_power_save > 2) |
2415 | priv->param_power_save = 2; | 2471 | priv->param_power_save = 2; |
2416 | 2472 | ||
2473 | if (priv->param_power_output < 0) | ||
2474 | priv->param_power_output = 0; | ||
2475 | else if (priv->param_power_output > 3) | ||
2476 | priv->param_power_output = 3; | ||
2477 | |||
2417 | if (priv->param_roamtrigger < -80) | 2478 | if (priv->param_roamtrigger < -80) |
2418 | priv->param_roamtrigger = -80; | 2479 | priv->param_roamtrigger = -80; |
2419 | else if (priv->param_roamtrigger > -60) | 2480 | else if (priv->param_roamtrigger > -60) |
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 57bdc153952f..611d98320593 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h | |||
@@ -328,6 +328,11 @@ static inline int rt2x00_get_link_ant_rssi(struct link *link) | |||
328 | return DEFAULT_RSSI; | 328 | return DEFAULT_RSSI; |
329 | } | 329 | } |
330 | 330 | ||
331 | static inline void rt2x00_reset_link_ant_rssi(struct link *link) | ||
332 | { | ||
333 | link->ant.rssi_ant = 0; | ||
334 | } | ||
335 | |||
331 | static inline int rt2x00_get_link_ant_rssi_history(struct link *link, | 336 | static inline int rt2x00_get_link_ant_rssi_history(struct link *link, |
332 | enum antenna ant) | 337 | enum antenna ant) |
333 | { | 338 | { |
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index a9930a03f450..48608e8cc8b4 100644 --- a/drivers/net/wireless/rt2x00/rt2x00config.c +++ b/drivers/net/wireless/rt2x00/rt2x00config.c | |||
@@ -129,6 +129,7 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
129 | */ | 129 | */ |
130 | rt2x00dev->ops->lib->config(rt2x00dev, &libconf, CONFIG_UPDATE_ANTENNA); | 130 | rt2x00dev->ops->lib->config(rt2x00dev, &libconf, CONFIG_UPDATE_ANTENNA); |
131 | rt2x00lib_reset_link_tuner(rt2x00dev); | 131 | rt2x00lib_reset_link_tuner(rt2x00dev); |
132 | rt2x00_reset_link_ant_rssi(&rt2x00dev->link); | ||
132 | 133 | ||
133 | rt2x00dev->link.ant.active.rx = libconf.ant.rx; | 134 | rt2x00dev->link.ant.active.rx = libconf.ant.rx; |
134 | rt2x00dev->link.ant.active.tx = libconf.ant.tx; | 135 | rt2x00dev->link.ant.active.tx = libconf.ant.tx; |
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index b22c02737185..2673d568bcac 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -483,9 +483,9 @@ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev) | |||
483 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) | 483 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) |
484 | return; | 484 | return; |
485 | 485 | ||
486 | ieee80211_iterate_active_interfaces(rt2x00dev->hw, | 486 | ieee80211_iterate_active_interfaces_atomic(rt2x00dev->hw, |
487 | rt2x00lib_beacondone_iter, | 487 | rt2x00lib_beacondone_iter, |
488 | rt2x00dev); | 488 | rt2x00dev); |
489 | 489 | ||
490 | queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->intf_work); | 490 | queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->intf_work); |
491 | } | 491 | } |
@@ -507,7 +507,7 @@ void rt2x00lib_txdone(struct queue_entry *entry, | |||
507 | * Update TX statistics. | 507 | * Update TX statistics. |
508 | */ | 508 | */ |
509 | rt2x00dev->link.qual.tx_success += success; | 509 | rt2x00dev->link.qual.tx_success += success; |
510 | rt2x00dev->link.qual.tx_failed += txdesc->retry + fail; | 510 | rt2x00dev->link.qual.tx_failed += fail; |
511 | 511 | ||
512 | /* | 512 | /* |
513 | * Initialize TX status | 513 | * Initialize TX status |
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index c206b5092070..87e280a21971 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c | |||
@@ -93,6 +93,7 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
93 | */ | 93 | */ |
94 | if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags)) { | 94 | if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags)) { |
95 | ieee80211_stop_queues(hw); | 95 | ieee80211_stop_queues(hw); |
96 | dev_kfree_skb_any(skb); | ||
96 | return NETDEV_TX_OK; | 97 | return NETDEV_TX_OK; |
97 | } | 98 | } |
98 | 99 | ||
diff --git a/drivers/net/wireless/rtl8180_grf5101.c b/drivers/net/wireless/rtl8180_grf5101.c index 5d47935dbac3..947ee55f18b2 100644 --- a/drivers/net/wireless/rtl8180_grf5101.c +++ b/drivers/net/wireless/rtl8180_grf5101.c | |||
@@ -88,7 +88,7 @@ static void grf5101_rf_set_channel(struct ieee80211_hw *dev, | |||
88 | write_grf5101(dev, 0x0B, chan); | 88 | write_grf5101(dev, 0x0B, chan); |
89 | write_grf5101(dev, 0x07, 0x1000); | 89 | write_grf5101(dev, 0x07, 0x1000); |
90 | 90 | ||
91 | grf5101_write_phy_antenna(dev, chan); | 91 | grf5101_write_phy_antenna(dev, channel); |
92 | } | 92 | } |
93 | 93 | ||
94 | static void grf5101_rf_stop(struct ieee80211_hw *dev) | 94 | static void grf5101_rf_stop(struct ieee80211_hw *dev) |
diff --git a/drivers/net/wireless/rtl8180_max2820.c b/drivers/net/wireless/rtl8180_max2820.c index a34dfd382b6d..6c825fd7f3b6 100644 --- a/drivers/net/wireless/rtl8180_max2820.c +++ b/drivers/net/wireless/rtl8180_max2820.c | |||
@@ -78,7 +78,8 @@ static void max2820_rf_set_channel(struct ieee80211_hw *dev, | |||
78 | struct ieee80211_conf *conf) | 78 | struct ieee80211_conf *conf) |
79 | { | 79 | { |
80 | struct rtl8180_priv *priv = dev->priv; | 80 | struct rtl8180_priv *priv = dev->priv; |
81 | int channel = ieee80211_frequency_to_channel(conf->channel->center_freq); | 81 | int channel = conf ? |
82 | ieee80211_frequency_to_channel(conf->channel->center_freq) : 1; | ||
82 | unsigned int chan_idx = channel - 1; | 83 | unsigned int chan_idx = channel - 1; |
83 | u32 txpw = priv->channels[chan_idx].hw_value & 0xFF; | 84 | u32 txpw = priv->channels[chan_idx].hw_value & 0xFF; |
84 | u32 chan = max2820_chan[chan_idx]; | 85 | u32 chan = max2820_chan[chan_idx]; |
@@ -87,7 +88,7 @@ static void max2820_rf_set_channel(struct ieee80211_hw *dev, | |||
87 | * sa2400, for MAXIM we do this directly from BB */ | 88 | * sa2400, for MAXIM we do this directly from BB */ |
88 | rtl8180_write_phy(dev, 3, txpw); | 89 | rtl8180_write_phy(dev, 3, txpw); |
89 | 90 | ||
90 | max2820_write_phy_antenna(dev, chan); | 91 | max2820_write_phy_antenna(dev, channel); |
91 | write_max2820(dev, 3, chan); | 92 | write_max2820(dev, 3, chan); |
92 | } | 93 | } |
93 | 94 | ||
diff --git a/drivers/net/wireless/rtl8180_sa2400.c b/drivers/net/wireless/rtl8180_sa2400.c index 0311b4ea124c..cea4e0ccb92d 100644 --- a/drivers/net/wireless/rtl8180_sa2400.c +++ b/drivers/net/wireless/rtl8180_sa2400.c | |||
@@ -86,7 +86,7 @@ static void sa2400_rf_set_channel(struct ieee80211_hw *dev, | |||
86 | 86 | ||
87 | write_sa2400(dev, 7, txpw); | 87 | write_sa2400(dev, 7, txpw); |
88 | 88 | ||
89 | sa2400_write_phy_antenna(dev, chan); | 89 | sa2400_write_phy_antenna(dev, channel); |
90 | 90 | ||
91 | write_sa2400(dev, 0, chan); | 91 | write_sa2400(dev, 0, chan); |
92 | write_sa2400(dev, 1, 0xbb50); | 92 | write_sa2400(dev, 1, 0xbb50); |
diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c index d5787b37e1fb..9223ada5f00e 100644 --- a/drivers/net/wireless/rtl8187_dev.c +++ b/drivers/net/wireless/rtl8187_dev.c | |||
@@ -92,6 +92,7 @@ static void rtl8187_iowrite_async(struct rtl8187_priv *priv, __le16 addr, | |||
92 | u8 data[4]; | 92 | u8 data[4]; |
93 | struct usb_ctrlrequest dr; | 93 | struct usb_ctrlrequest dr; |
94 | } *buf; | 94 | } *buf; |
95 | int rc; | ||
95 | 96 | ||
96 | buf = kmalloc(sizeof(*buf), GFP_ATOMIC); | 97 | buf = kmalloc(sizeof(*buf), GFP_ATOMIC); |
97 | if (!buf) | 98 | if (!buf) |
@@ -116,7 +117,11 @@ static void rtl8187_iowrite_async(struct rtl8187_priv *priv, __le16 addr, | |||
116 | usb_fill_control_urb(urb, priv->udev, usb_sndctrlpipe(priv->udev, 0), | 117 | usb_fill_control_urb(urb, priv->udev, usb_sndctrlpipe(priv->udev, 0), |
117 | (unsigned char *)dr, buf, len, | 118 | (unsigned char *)dr, buf, len, |
118 | rtl8187_iowrite_async_cb, buf); | 119 | rtl8187_iowrite_async_cb, buf); |
119 | usb_submit_urb(urb, GFP_ATOMIC); | 120 | rc = usb_submit_urb(urb, GFP_ATOMIC); |
121 | if (rc < 0) { | ||
122 | kfree(buf); | ||
123 | usb_free_urb(urb); | ||
124 | } | ||
120 | } | 125 | } |
121 | 126 | ||
122 | static inline void rtl818x_iowrite32_async(struct rtl8187_priv *priv, | 127 | static inline void rtl818x_iowrite32_async(struct rtl8187_priv *priv, |
@@ -169,6 +174,7 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb, | |||
169 | struct urb *urb; | 174 | struct urb *urb; |
170 | __le16 rts_dur = 0; | 175 | __le16 rts_dur = 0; |
171 | u32 flags; | 176 | u32 flags; |
177 | int rc; | ||
172 | 178 | ||
173 | urb = usb_alloc_urb(0, GFP_ATOMIC); | 179 | urb = usb_alloc_urb(0, GFP_ATOMIC); |
174 | if (!urb) { | 180 | if (!urb) { |
@@ -208,7 +214,11 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb, | |||
208 | info->dev = dev; | 214 | info->dev = dev; |
209 | usb_fill_bulk_urb(urb, priv->udev, usb_sndbulkpipe(priv->udev, 2), | 215 | usb_fill_bulk_urb(urb, priv->udev, usb_sndbulkpipe(priv->udev, 2), |
210 | hdr, skb->len, rtl8187_tx_cb, skb); | 216 | hdr, skb->len, rtl8187_tx_cb, skb); |
211 | usb_submit_urb(urb, GFP_ATOMIC); | 217 | rc = usb_submit_urb(urb, GFP_ATOMIC); |
218 | if (rc < 0) { | ||
219 | usb_free_urb(urb); | ||
220 | kfree_skb(skb); | ||
221 | } | ||
212 | 222 | ||
213 | return 0; | 223 | return 0; |
214 | } | 224 | } |
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 69c45ca99051..418606ac1c3b 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c | |||
@@ -719,7 +719,7 @@ int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length) | |||
719 | fc = le16_to_cpu(*((__le16 *) buffer)); | 719 | fc = le16_to_cpu(*((__le16 *) buffer)); |
720 | 720 | ||
721 | is_qos = ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) && | 721 | is_qos = ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) && |
722 | ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_QOS_DATA); | 722 | (fc & IEEE80211_STYPE_QOS_DATA); |
723 | is_4addr = (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == | 723 | is_4addr = (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == |
724 | (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS); | 724 | (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS); |
725 | need_padding = is_qos ^ is_4addr; | 725 | need_padding = is_qos ^ is_4addr; |
@@ -805,7 +805,7 @@ void zd_process_intr(struct work_struct *work) | |||
805 | u16 int_status; | 805 | u16 int_status; |
806 | struct zd_mac *mac = container_of(work, struct zd_mac, process_intr); | 806 | struct zd_mac *mac = container_of(work, struct zd_mac, process_intr); |
807 | 807 | ||
808 | int_status = le16_to_cpu(*(u16 *)(mac->intr_buffer+4)); | 808 | int_status = le16_to_cpu(*(__le16 *)(mac->intr_buffer+4)); |
809 | if (int_status & INT_CFG_NEXT_BCN) { | 809 | if (int_status & INT_CFG_NEXT_BCN) { |
810 | if (net_ratelimit()) | 810 | if (net_ratelimit()) |
811 | dev_dbg_f(zd_mac_dev(mac), "INT_CFG_NEXT_BCN\n"); | 811 | dev_dbg_f(zd_mac_dev(mac), "INT_CFG_NEXT_BCN\n"); |
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index 12e24f04dddf..8941f5eb96c2 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c | |||
@@ -342,7 +342,7 @@ static inline void handle_regs_int(struct urb *urb) | |||
342 | ZD_ASSERT(in_interrupt()); | 342 | ZD_ASSERT(in_interrupt()); |
343 | spin_lock(&intr->lock); | 343 | spin_lock(&intr->lock); |
344 | 344 | ||
345 | int_num = le16_to_cpu(*(u16 *)(urb->transfer_buffer+2)); | 345 | int_num = le16_to_cpu(*(__le16 *)(urb->transfer_buffer+2)); |
346 | if (int_num == CR_INTERRUPT) { | 346 | if (int_num == CR_INTERRUPT) { |
347 | struct zd_mac *mac = zd_hw_mac(zd_usb_to_hw(urb->context)); | 347 | struct zd_mac *mac = zd_hw_mac(zd_usb_to_hw(urb->context)); |
348 | memcpy(&mac->intr_buffer, urb->transfer_buffer, | 348 | memcpy(&mac->intr_buffer, urb->transfer_buffer, |
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 8bddff150c70..d26f69b0184f 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c | |||
@@ -946,8 +946,7 @@ err: | |||
946 | work_done++; | 946 | work_done++; |
947 | } | 947 | } |
948 | 948 | ||
949 | while ((skb = __skb_dequeue(&errq))) | 949 | __skb_queue_purge(&errq); |
950 | kfree_skb(skb); | ||
951 | 950 | ||
952 | work_done -= handle_incoming_queue(dev, &rxq); | 951 | work_done -= handle_incoming_queue(dev, &rxq); |
953 | 952 | ||
@@ -1079,8 +1078,7 @@ static void xennet_release_rx_bufs(struct netfront_info *np) | |||
1079 | } | 1078 | } |
1080 | } | 1079 | } |
1081 | 1080 | ||
1082 | while ((skb = __skb_dequeue(&free_list)) != NULL) | 1081 | __skb_queue_purge(&free_list); |
1083 | dev_kfree_skb(skb); | ||
1084 | 1082 | ||
1085 | spin_unlock_bh(&np->rx_lock); | 1083 | spin_unlock_bh(&np->rx_lock); |
1086 | } | 1084 | } |
diff --git a/drivers/of/of_i2c.c b/drivers/of/of_i2c.c index 715a44471617..b2ccdcbeb896 100644 --- a/drivers/of/of_i2c.c +++ b/drivers/of/of_i2c.c | |||
@@ -21,7 +21,6 @@ struct i2c_driver_device { | |||
21 | }; | 21 | }; |
22 | 22 | ||
23 | static struct i2c_driver_device i2c_devices[] = { | 23 | static struct i2c_driver_device i2c_devices[] = { |
24 | { "dallas,ds1374", "rtc-ds1374" }, | ||
25 | }; | 24 | }; |
26 | 25 | ||
27 | static int of_find_i2c_driver(struct device_node *node, | 26 | static int of_find_i2c_driver(struct device_node *node, |
diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c index 925ba16355ce..a11021e8ce37 100644 --- a/drivers/pci/hotplug/pci_hotplug_core.c +++ b/drivers/pci/hotplug/pci_hotplug_core.c | |||
@@ -619,6 +619,7 @@ static struct hotplug_slot *get_slot_from_name (const char *name) | |||
619 | int pci_hp_register (struct hotplug_slot *slot) | 619 | int pci_hp_register (struct hotplug_slot *slot) |
620 | { | 620 | { |
621 | int result; | 621 | int result; |
622 | struct hotplug_slot *tmp; | ||
622 | 623 | ||
623 | if (slot == NULL) | 624 | if (slot == NULL) |
624 | return -ENODEV; | 625 | return -ENODEV; |
@@ -630,7 +631,11 @@ int pci_hp_register (struct hotplug_slot *slot) | |||
630 | return -EINVAL; | 631 | return -EINVAL; |
631 | } | 632 | } |
632 | 633 | ||
633 | /* this can fail if we have already registered a slot with the same name */ | 634 | /* Check if we have already registered a slot with the same name. */ |
635 | tmp = get_slot_from_name(slot->name); | ||
636 | if (tmp) | ||
637 | return -EEXIST; | ||
638 | |||
634 | slot->kobj.kset = pci_hotplug_slots_kset; | 639 | slot->kobj.kset = pci_hotplug_slots_kset; |
635 | result = kobject_init_and_add(&slot->kobj, &hotplug_slot_ktype, NULL, | 640 | result = kobject_init_and_add(&slot->kobj, &hotplug_slot_ktype, NULL, |
636 | "%s", slot->name); | 641 | "%s", slot->name); |
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index 8264a7680435..79c9ddaad3fb 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h | |||
@@ -97,6 +97,7 @@ struct controller { | |||
97 | u8 cap_base; | 97 | u8 cap_base; |
98 | struct timer_list poll_timer; | 98 | struct timer_list poll_timer; |
99 | volatile int cmd_busy; | 99 | volatile int cmd_busy; |
100 | unsigned int no_cmd_complete:1; | ||
100 | }; | 101 | }; |
101 | 102 | ||
102 | #define INT_BUTTON_IGNORE 0 | 103 | #define INT_BUTTON_IGNORE 0 |
@@ -135,6 +136,7 @@ struct controller { | |||
135 | #define PWR_LED_PRSN 0x00000010 | 136 | #define PWR_LED_PRSN 0x00000010 |
136 | #define HP_SUPR_RM_SUP 0x00000020 | 137 | #define HP_SUPR_RM_SUP 0x00000020 |
137 | #define EMI_PRSN 0x00020000 | 138 | #define EMI_PRSN 0x00020000 |
139 | #define NO_CMD_CMPL_SUP 0x00040000 | ||
138 | 140 | ||
139 | #define ATTN_BUTTN(ctrl) ((ctrl)->slot_cap & ATTN_BUTTN_PRSN) | 141 | #define ATTN_BUTTN(ctrl) ((ctrl)->slot_cap & ATTN_BUTTN_PRSN) |
140 | #define POWER_CTRL(ctrl) ((ctrl)->slot_cap & PWR_CTRL_PRSN) | 142 | #define POWER_CTRL(ctrl) ((ctrl)->slot_cap & PWR_CTRL_PRSN) |
@@ -143,13 +145,14 @@ struct controller { | |||
143 | #define PWR_LED(ctrl) ((ctrl)->slot_cap & PWR_LED_PRSN) | 145 | #define PWR_LED(ctrl) ((ctrl)->slot_cap & PWR_LED_PRSN) |
144 | #define HP_SUPR_RM(ctrl) ((ctrl)->slot_cap & HP_SUPR_RM_SUP) | 146 | #define HP_SUPR_RM(ctrl) ((ctrl)->slot_cap & HP_SUPR_RM_SUP) |
145 | #define EMI(ctrl) ((ctrl)->slot_cap & EMI_PRSN) | 147 | #define EMI(ctrl) ((ctrl)->slot_cap & EMI_PRSN) |
148 | #define NO_CMD_CMPL(ctrl) ((ctrl)->slot_cap & NO_CMD_CMPL_SUP) | ||
146 | 149 | ||
147 | extern int pciehp_sysfs_enable_slot(struct slot *slot); | 150 | extern int pciehp_sysfs_enable_slot(struct slot *slot); |
148 | extern int pciehp_sysfs_disable_slot(struct slot *slot); | 151 | extern int pciehp_sysfs_disable_slot(struct slot *slot); |
149 | extern u8 pciehp_handle_attention_button(u8 hp_slot, struct controller *ctrl); | 152 | extern u8 pciehp_handle_attention_button(struct slot *p_slot); |
150 | extern u8 pciehp_handle_switch_change(u8 hp_slot, struct controller *ctrl); | 153 | extern u8 pciehp_handle_switch_change(struct slot *p_slot); |
151 | extern u8 pciehp_handle_presence_change(u8 hp_slot, struct controller *ctrl); | 154 | extern u8 pciehp_handle_presence_change(struct slot *p_slot); |
152 | extern u8 pciehp_handle_power_fault(u8 hp_slot, struct controller *ctrl); | 155 | extern u8 pciehp_handle_power_fault(struct slot *p_slot); |
153 | extern int pciehp_configure_device(struct slot *p_slot); | 156 | extern int pciehp_configure_device(struct slot *p_slot); |
154 | extern int pciehp_unconfigure_device(struct slot *p_slot); | 157 | extern int pciehp_unconfigure_device(struct slot *p_slot); |
155 | extern void pciehp_queue_pushbutton_work(struct work_struct *work); | 158 | extern void pciehp_queue_pushbutton_work(struct work_struct *work); |
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index 43d8ddb2d679..48a2ed378914 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c | |||
@@ -254,7 +254,11 @@ static int init_slots(struct controller *ctrl) | |||
254 | slot->hp_slot, slot->number, ctrl->slot_device_offset); | 254 | slot->hp_slot, slot->number, ctrl->slot_device_offset); |
255 | retval = pci_hp_register(hotplug_slot); | 255 | retval = pci_hp_register(hotplug_slot); |
256 | if (retval) { | 256 | if (retval) { |
257 | err ("pci_hp_register failed with error %d\n", retval); | 257 | err("pci_hp_register failed with error %d\n", retval); |
258 | if (retval == -EEXIST) | ||
259 | err("Failed to register slot because of name " | ||
260 | "collision. Try \'pciehp_slot_with_bus\' " | ||
261 | "module option.\n"); | ||
258 | goto error_info; | 262 | goto error_info; |
259 | } | 263 | } |
260 | /* create additional sysfs entries */ | 264 | /* create additional sysfs entries */ |
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c index 0a7aa628e955..96a5d55a4983 100644 --- a/drivers/pci/hotplug/pciehp_ctrl.c +++ b/drivers/pci/hotplug/pciehp_ctrl.c | |||
@@ -55,16 +55,13 @@ static int queue_interrupt_event(struct slot *p_slot, u32 event_type) | |||
55 | return 0; | 55 | return 0; |
56 | } | 56 | } |
57 | 57 | ||
58 | u8 pciehp_handle_attention_button(u8 hp_slot, struct controller *ctrl) | 58 | u8 pciehp_handle_attention_button(struct slot *p_slot) |
59 | { | 59 | { |
60 | struct slot *p_slot; | ||
61 | u32 event_type; | 60 | u32 event_type; |
62 | 61 | ||
63 | /* Attention Button Change */ | 62 | /* Attention Button Change */ |
64 | dbg("pciehp: Attention button interrupt received.\n"); | 63 | dbg("pciehp: Attention button interrupt received.\n"); |
65 | 64 | ||
66 | p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); | ||
67 | |||
68 | /* | 65 | /* |
69 | * Button pressed - See if need to TAKE ACTION!!! | 66 | * Button pressed - See if need to TAKE ACTION!!! |
70 | */ | 67 | */ |
@@ -76,18 +73,15 @@ u8 pciehp_handle_attention_button(u8 hp_slot, struct controller *ctrl) | |||
76 | return 0; | 73 | return 0; |
77 | } | 74 | } |
78 | 75 | ||
79 | u8 pciehp_handle_switch_change(u8 hp_slot, struct controller *ctrl) | 76 | u8 pciehp_handle_switch_change(struct slot *p_slot) |
80 | { | 77 | { |
81 | struct slot *p_slot; | ||
82 | u8 getstatus; | 78 | u8 getstatus; |
83 | u32 event_type; | 79 | u32 event_type; |
84 | 80 | ||
85 | /* Switch Change */ | 81 | /* Switch Change */ |
86 | dbg("pciehp: Switch interrupt received.\n"); | 82 | dbg("pciehp: Switch interrupt received.\n"); |
87 | 83 | ||
88 | p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); | ||
89 | p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); | 84 | p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); |
90 | |||
91 | if (getstatus) { | 85 | if (getstatus) { |
92 | /* | 86 | /* |
93 | * Switch opened | 87 | * Switch opened |
@@ -107,17 +101,14 @@ u8 pciehp_handle_switch_change(u8 hp_slot, struct controller *ctrl) | |||
107 | return 1; | 101 | return 1; |
108 | } | 102 | } |
109 | 103 | ||
110 | u8 pciehp_handle_presence_change(u8 hp_slot, struct controller *ctrl) | 104 | u8 pciehp_handle_presence_change(struct slot *p_slot) |
111 | { | 105 | { |
112 | struct slot *p_slot; | ||
113 | u32 event_type; | 106 | u32 event_type; |
114 | u8 presence_save; | 107 | u8 presence_save; |
115 | 108 | ||
116 | /* Presence Change */ | 109 | /* Presence Change */ |
117 | dbg("pciehp: Presence/Notify input change.\n"); | 110 | dbg("pciehp: Presence/Notify input change.\n"); |
118 | 111 | ||
119 | p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); | ||
120 | |||
121 | /* Switch is open, assume a presence change | 112 | /* Switch is open, assume a presence change |
122 | * Save the presence state | 113 | * Save the presence state |
123 | */ | 114 | */ |
@@ -141,16 +132,13 @@ u8 pciehp_handle_presence_change(u8 hp_slot, struct controller *ctrl) | |||
141 | return 1; | 132 | return 1; |
142 | } | 133 | } |
143 | 134 | ||
144 | u8 pciehp_handle_power_fault(u8 hp_slot, struct controller *ctrl) | 135 | u8 pciehp_handle_power_fault(struct slot *p_slot) |
145 | { | 136 | { |
146 | struct slot *p_slot; | ||
147 | u32 event_type; | 137 | u32 event_type; |
148 | 138 | ||
149 | /* power fault */ | 139 | /* power fault */ |
150 | dbg("pciehp: Power fault interrupt received.\n"); | 140 | dbg("pciehp: Power fault interrupt received.\n"); |
151 | 141 | ||
152 | p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); | ||
153 | |||
154 | if ( !(p_slot->hpc_ops->query_power_fault(p_slot))) { | 142 | if ( !(p_slot->hpc_ops->query_power_fault(p_slot))) { |
155 | /* | 143 | /* |
156 | * power fault Cleared | 144 | * power fault Cleared |
@@ -163,7 +151,7 @@ u8 pciehp_handle_power_fault(u8 hp_slot, struct controller *ctrl) | |||
163 | */ | 151 | */ |
164 | info("Power fault on Slot(%s)\n", p_slot->name); | 152 | info("Power fault on Slot(%s)\n", p_slot->name); |
165 | event_type = INT_POWER_FAULT; | 153 | event_type = INT_POWER_FAULT; |
166 | info("power fault bit %x set\n", hp_slot); | 154 | info("power fault bit %x set\n", 0); |
167 | } | 155 | } |
168 | 156 | ||
169 | queue_interrupt_event(p_slot, event_type); | 157 | queue_interrupt_event(p_slot, event_type); |
@@ -186,6 +174,13 @@ static void set_slot_off(struct controller *ctrl, struct slot * pslot) | |||
186 | } | 174 | } |
187 | } | 175 | } |
188 | 176 | ||
177 | /* | ||
178 | * After turning power off, we must wait for at least 1 second | ||
179 | * before taking any action that relies on power having been | ||
180 | * removed from the slot/adapter. | ||
181 | */ | ||
182 | msleep(1000); | ||
183 | |||
189 | if (PWR_LED(ctrl)) | 184 | if (PWR_LED(ctrl)) |
190 | pslot->hpc_ops->green_led_off(pslot); | 185 | pslot->hpc_ops->green_led_off(pslot); |
191 | 186 | ||
@@ -289,6 +284,13 @@ static int remove_board(struct slot *p_slot) | |||
289 | } | 284 | } |
290 | } | 285 | } |
291 | 286 | ||
287 | /* | ||
288 | * After turning power off, we must wait for at least 1 second | ||
289 | * before taking any action that relies on power having been | ||
290 | * removed from the slot/adapter. | ||
291 | */ | ||
292 | msleep(1000); | ||
293 | |||
292 | if (PWR_LED(ctrl)) | 294 | if (PWR_LED(ctrl)) |
293 | /* turn off Green LED */ | 295 | /* turn off Green LED */ |
294 | p_slot->hpc_ops->green_led_off(p_slot); | 296 | p_slot->hpc_ops->green_led_off(p_slot); |
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 891f81a0400c..79f104963166 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c | |||
@@ -247,14 +247,38 @@ static inline void pciehp_free_irq(struct controller *ctrl) | |||
247 | free_irq(ctrl->pci_dev->irq, ctrl); | 247 | free_irq(ctrl->pci_dev->irq, ctrl); |
248 | } | 248 | } |
249 | 249 | ||
250 | static inline int pcie_wait_cmd(struct controller *ctrl) | 250 | static inline int pcie_poll_cmd(struct controller *ctrl) |
251 | { | ||
252 | u16 slot_status; | ||
253 | int timeout = 1000; | ||
254 | |||
255 | if (!pciehp_readw(ctrl, SLOTSTATUS, &slot_status)) | ||
256 | if (slot_status & CMD_COMPLETED) | ||
257 | goto completed; | ||
258 | for (timeout = 1000; timeout > 0; timeout -= 100) { | ||
259 | msleep(100); | ||
260 | if (!pciehp_readw(ctrl, SLOTSTATUS, &slot_status)) | ||
261 | if (slot_status & CMD_COMPLETED) | ||
262 | goto completed; | ||
263 | } | ||
264 | return 0; /* timeout */ | ||
265 | |||
266 | completed: | ||
267 | pciehp_writew(ctrl, SLOTSTATUS, CMD_COMPLETED); | ||
268 | return timeout; | ||
269 | } | ||
270 | |||
271 | static inline int pcie_wait_cmd(struct controller *ctrl, int poll) | ||
251 | { | 272 | { |
252 | int retval = 0; | 273 | int retval = 0; |
253 | unsigned int msecs = pciehp_poll_mode ? 2500 : 1000; | 274 | unsigned int msecs = pciehp_poll_mode ? 2500 : 1000; |
254 | unsigned long timeout = msecs_to_jiffies(msecs); | 275 | unsigned long timeout = msecs_to_jiffies(msecs); |
255 | int rc; | 276 | int rc; |
256 | 277 | ||
257 | rc = wait_event_interruptible_timeout(ctrl->queue, | 278 | if (poll) |
279 | rc = pcie_poll_cmd(ctrl); | ||
280 | else | ||
281 | rc = wait_event_interruptible_timeout(ctrl->queue, | ||
258 | !ctrl->cmd_busy, timeout); | 282 | !ctrl->cmd_busy, timeout); |
259 | if (!rc) | 283 | if (!rc) |
260 | dbg("Command not completed in 1000 msec\n"); | 284 | dbg("Command not completed in 1000 msec\n"); |
@@ -286,12 +310,28 @@ static int pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask) | |||
286 | goto out; | 310 | goto out; |
287 | } | 311 | } |
288 | 312 | ||
289 | if ((slot_status & CMD_COMPLETED) == CMD_COMPLETED ) { | 313 | if (slot_status & CMD_COMPLETED) { |
290 | /* After 1 sec and CMD_COMPLETED still not set, just | 314 | if (!ctrl->no_cmd_complete) { |
291 | proceed forward to issue the next command according | 315 | /* |
292 | to spec. Just print out the error message */ | 316 | * After 1 sec and CMD_COMPLETED still not set, just |
293 | dbg("%s: CMD_COMPLETED not clear after 1 sec.\n", | 317 | * proceed forward to issue the next command according |
294 | __func__); | 318 | * to spec. Just print out the error message. |
319 | */ | ||
320 | dbg("%s: CMD_COMPLETED not clear after 1 sec.\n", | ||
321 | __func__); | ||
322 | } else if (!NO_CMD_CMPL(ctrl)) { | ||
323 | /* | ||
324 | * This controller semms to notify of command completed | ||
325 | * event even though it supports none of power | ||
326 | * controller, attention led, power led and EMI. | ||
327 | */ | ||
328 | dbg("%s: Unexpected CMD_COMPLETED. Need to wait for " | ||
329 | "command completed event.\n", __func__); | ||
330 | ctrl->no_cmd_complete = 0; | ||
331 | } else { | ||
332 | dbg("%s: Unexpected CMD_COMPLETED. Maybe the " | ||
333 | "controller is broken.\n", __func__); | ||
334 | } | ||
295 | } | 335 | } |
296 | 336 | ||
297 | retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); | 337 | retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); |
@@ -315,8 +355,18 @@ static int pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask) | |||
315 | /* | 355 | /* |
316 | * Wait for command completion. | 356 | * Wait for command completion. |
317 | */ | 357 | */ |
318 | if (!retval) | 358 | if (!retval && !ctrl->no_cmd_complete) { |
319 | retval = pcie_wait_cmd(ctrl); | 359 | int poll = 0; |
360 | /* | ||
361 | * if hotplug interrupt is not enabled or command | ||
362 | * completed interrupt is not enabled, we need to poll | ||
363 | * command completed event. | ||
364 | */ | ||
365 | if (!(slot_ctrl & HP_INTR_ENABLE) || | ||
366 | !(slot_ctrl & CMD_CMPL_INTR_ENABLE)) | ||
367 | poll = 1; | ||
368 | retval = pcie_wait_cmd(ctrl, poll); | ||
369 | } | ||
320 | out: | 370 | out: |
321 | mutex_unlock(&ctrl->ctrl_lock); | 371 | mutex_unlock(&ctrl->ctrl_lock); |
322 | return retval; | 372 | return retval; |
@@ -704,13 +754,6 @@ static int hpc_power_off_slot(struct slot * slot) | |||
704 | } | 754 | } |
705 | dbg("%s: SLOTCTRL %x write cmd %x\n", | 755 | dbg("%s: SLOTCTRL %x write cmd %x\n", |
706 | __func__, ctrl->cap_base + SLOTCTRL, slot_cmd); | 756 | __func__, ctrl->cap_base + SLOTCTRL, slot_cmd); |
707 | |||
708 | /* | ||
709 | * After turning power off, we must wait for at least 1 second | ||
710 | * before taking any action that relies on power having been | ||
711 | * removed from the slot/adapter. | ||
712 | */ | ||
713 | msleep(1000); | ||
714 | out: | 757 | out: |
715 | if (changed) | 758 | if (changed) |
716 | pcie_unmask_bad_dllp(ctrl); | 759 | pcie_unmask_bad_dllp(ctrl); |
@@ -722,6 +765,7 @@ static irqreturn_t pcie_isr(int irq, void *dev_id) | |||
722 | { | 765 | { |
723 | struct controller *ctrl = (struct controller *)dev_id; | 766 | struct controller *ctrl = (struct controller *)dev_id; |
724 | u16 detected, intr_loc; | 767 | u16 detected, intr_loc; |
768 | struct slot *p_slot; | ||
725 | 769 | ||
726 | /* | 770 | /* |
727 | * In order to guarantee that all interrupt events are | 771 | * In order to guarantee that all interrupt events are |
@@ -756,21 +800,38 @@ static irqreturn_t pcie_isr(int irq, void *dev_id) | |||
756 | wake_up_interruptible(&ctrl->queue); | 800 | wake_up_interruptible(&ctrl->queue); |
757 | } | 801 | } |
758 | 802 | ||
803 | if (!(intr_loc & ~CMD_COMPLETED)) | ||
804 | return IRQ_HANDLED; | ||
805 | |||
806 | /* | ||
807 | * Return without handling events if this handler routine is | ||
808 | * called before controller initialization is done. This may | ||
809 | * happen if hotplug event or another interrupt that shares | ||
810 | * the IRQ with pciehp arrives before slot initialization is | ||
811 | * done after interrupt handler is registered. | ||
812 | * | ||
813 | * FIXME - Need more structural fixes. We need to be ready to | ||
814 | * handle the event before installing interrupt handler. | ||
815 | */ | ||
816 | p_slot = pciehp_find_slot(ctrl, ctrl->slot_device_offset); | ||
817 | if (!p_slot || !p_slot->hpc_ops) | ||
818 | return IRQ_HANDLED; | ||
819 | |||
759 | /* Check MRL Sensor Changed */ | 820 | /* Check MRL Sensor Changed */ |
760 | if (intr_loc & MRL_SENS_CHANGED) | 821 | if (intr_loc & MRL_SENS_CHANGED) |
761 | pciehp_handle_switch_change(0, ctrl); | 822 | pciehp_handle_switch_change(p_slot); |
762 | 823 | ||
763 | /* Check Attention Button Pressed */ | 824 | /* Check Attention Button Pressed */ |
764 | if (intr_loc & ATTN_BUTTN_PRESSED) | 825 | if (intr_loc & ATTN_BUTTN_PRESSED) |
765 | pciehp_handle_attention_button(0, ctrl); | 826 | pciehp_handle_attention_button(p_slot); |
766 | 827 | ||
767 | /* Check Presence Detect Changed */ | 828 | /* Check Presence Detect Changed */ |
768 | if (intr_loc & PRSN_DETECT_CHANGED) | 829 | if (intr_loc & PRSN_DETECT_CHANGED) |
769 | pciehp_handle_presence_change(0, ctrl); | 830 | pciehp_handle_presence_change(p_slot); |
770 | 831 | ||
771 | /* Check Power Fault Detected */ | 832 | /* Check Power Fault Detected */ |
772 | if (intr_loc & PWR_FAULT_DETECTED) | 833 | if (intr_loc & PWR_FAULT_DETECTED) |
773 | pciehp_handle_power_fault(0, ctrl); | 834 | pciehp_handle_power_fault(p_slot); |
774 | 835 | ||
775 | return IRQ_HANDLED; | 836 | return IRQ_HANDLED; |
776 | } | 837 | } |
@@ -1028,6 +1089,12 @@ static int pciehp_acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev) | |||
1028 | static int pcie_init_hardware_part1(struct controller *ctrl, | 1089 | static int pcie_init_hardware_part1(struct controller *ctrl, |
1029 | struct pcie_device *dev) | 1090 | struct pcie_device *dev) |
1030 | { | 1091 | { |
1092 | /* Clear all remaining event bits in Slot Status register */ | ||
1093 | if (pciehp_writew(ctrl, SLOTSTATUS, 0x1f)) { | ||
1094 | err("%s: Cannot write to SLOTSTATUS register\n", __func__); | ||
1095 | return -1; | ||
1096 | } | ||
1097 | |||
1031 | /* Mask Hot-plug Interrupt Enable */ | 1098 | /* Mask Hot-plug Interrupt Enable */ |
1032 | if (pcie_write_cmd(ctrl, 0, HP_INTR_ENABLE | CMD_CMPL_INTR_ENABLE)) { | 1099 | if (pcie_write_cmd(ctrl, 0, HP_INTR_ENABLE | CMD_CMPL_INTR_ENABLE)) { |
1033 | err("%s: Cannot mask hotplug interrupt enable\n", __func__); | 1100 | err("%s: Cannot mask hotplug interrupt enable\n", __func__); |
@@ -1040,16 +1107,6 @@ int pcie_init_hardware_part2(struct controller *ctrl, struct pcie_device *dev) | |||
1040 | { | 1107 | { |
1041 | u16 cmd, mask; | 1108 | u16 cmd, mask; |
1042 | 1109 | ||
1043 | /* | ||
1044 | * We need to clear all events before enabling hotplug interrupt | ||
1045 | * notification mechanism in order for hotplug controler to | ||
1046 | * generate interrupts. | ||
1047 | */ | ||
1048 | if (pciehp_writew(ctrl, SLOTSTATUS, 0x1f)) { | ||
1049 | err("%s: Cannot write to SLOTSTATUS register\n", __FUNCTION__); | ||
1050 | return -1; | ||
1051 | } | ||
1052 | |||
1053 | cmd = PRSN_DETECT_ENABLE; | 1110 | cmd = PRSN_DETECT_ENABLE; |
1054 | if (ATTN_BUTTN(ctrl)) | 1111 | if (ATTN_BUTTN(ctrl)) |
1055 | cmd |= ATTN_BUTTN_ENABLE; | 1112 | cmd |= ATTN_BUTTN_ENABLE; |
@@ -1116,6 +1173,7 @@ static inline void dbg_ctrl(struct controller *ctrl) | |||
1116 | dbg(" Power Indicator : %3s\n", PWR_LED(ctrl) ? "yes" : "no"); | 1173 | dbg(" Power Indicator : %3s\n", PWR_LED(ctrl) ? "yes" : "no"); |
1117 | dbg(" Hot-Plug Surprise : %3s\n", HP_SUPR_RM(ctrl) ? "yes" : "no"); | 1174 | dbg(" Hot-Plug Surprise : %3s\n", HP_SUPR_RM(ctrl) ? "yes" : "no"); |
1118 | dbg(" EMI Present : %3s\n", EMI(ctrl) ? "yes" : "no"); | 1175 | dbg(" EMI Present : %3s\n", EMI(ctrl) ? "yes" : "no"); |
1176 | dbg(" Comamnd Completed : %3s\n", NO_CMD_CMPL(ctrl)? "no" : "yes"); | ||
1119 | pciehp_readw(ctrl, SLOTSTATUS, ®16); | 1177 | pciehp_readw(ctrl, SLOTSTATUS, ®16); |
1120 | dbg("Slot Status : 0x%04x\n", reg16); | 1178 | dbg("Slot Status : 0x%04x\n", reg16); |
1121 | pciehp_readw(ctrl, SLOTSTATUS, ®16); | 1179 | pciehp_readw(ctrl, SLOTSTATUS, ®16); |
@@ -1147,6 +1205,15 @@ int pcie_init(struct controller *ctrl, struct pcie_device *dev) | |||
1147 | mutex_init(&ctrl->ctrl_lock); | 1205 | mutex_init(&ctrl->ctrl_lock); |
1148 | init_waitqueue_head(&ctrl->queue); | 1206 | init_waitqueue_head(&ctrl->queue); |
1149 | dbg_ctrl(ctrl); | 1207 | dbg_ctrl(ctrl); |
1208 | /* | ||
1209 | * Controller doesn't notify of command completion if the "No | ||
1210 | * Command Completed Support" bit is set in Slot Capability | ||
1211 | * register or the controller supports none of power | ||
1212 | * controller, attention led, power led and EMI. | ||
1213 | */ | ||
1214 | if (NO_CMD_CMPL(ctrl) || | ||
1215 | !(POWER_CTRL(ctrl) | ATTN_LED(ctrl) | PWR_LED(ctrl) | EMI(ctrl))) | ||
1216 | ctrl->no_cmd_complete = 1; | ||
1150 | 1217 | ||
1151 | info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", | 1218 | info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", |
1152 | pdev->vendor, pdev->device, | 1219 | pdev->vendor, pdev->device, |
diff --git a/drivers/pci/hotplug/rpadlpar_sysfs.c b/drivers/pci/hotplug/rpadlpar_sysfs.c index e32148a8fa12..779c5db71be4 100644 --- a/drivers/pci/hotplug/rpadlpar_sysfs.c +++ b/drivers/pci/hotplug/rpadlpar_sysfs.c | |||
@@ -18,8 +18,12 @@ | |||
18 | #include "rpadlpar.h" | 18 | #include "rpadlpar.h" |
19 | 19 | ||
20 | #define DLPAR_KOBJ_NAME "control" | 20 | #define DLPAR_KOBJ_NAME "control" |
21 | #define ADD_SLOT_ATTR_NAME "add_slot" | 21 | |
22 | #define REMOVE_SLOT_ATTR_NAME "remove_slot" | 22 | /* Those two have no quotes because they are passed to __ATTR() which |
23 | * stringifies the argument (yuck !) | ||
24 | */ | ||
25 | #define ADD_SLOT_ATTR_NAME add_slot | ||
26 | #define REMOVE_SLOT_ATTR_NAME remove_slot | ||
23 | 27 | ||
24 | #define MAX_DRC_NAME_LEN 64 | 28 | #define MAX_DRC_NAME_LEN 64 |
25 | 29 | ||
diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c index 1648076600fc..97848654652a 100644 --- a/drivers/pci/hotplug/shpchp_core.c +++ b/drivers/pci/hotplug/shpchp_core.c | |||
@@ -162,6 +162,10 @@ static int init_slots(struct controller *ctrl) | |||
162 | retval = pci_hp_register(slot->hotplug_slot); | 162 | retval = pci_hp_register(slot->hotplug_slot); |
163 | if (retval) { | 163 | if (retval) { |
164 | err("pci_hp_register failed with error %d\n", retval); | 164 | err("pci_hp_register failed with error %d\n", retval); |
165 | if (retval == -EEXIST) | ||
166 | err("Failed to register slot because of name " | ||
167 | "collision. Try \'shpchp_slot_with_bus\' " | ||
168 | "module option.\n"); | ||
165 | goto error_info; | 169 | goto error_info; |
166 | } | 170 | } |
167 | 171 | ||
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 72cf61ed8f96..e1637bd82b8e 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c | |||
@@ -181,7 +181,7 @@ static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev, | |||
181 | any need to change it. */ | 181 | any need to change it. */ |
182 | struct mempolicy *oldpol; | 182 | struct mempolicy *oldpol; |
183 | cpumask_t oldmask = current->cpus_allowed; | 183 | cpumask_t oldmask = current->cpus_allowed; |
184 | int node = pcibus_to_node(dev->bus); | 184 | int node = dev_to_node(&dev->dev); |
185 | 185 | ||
186 | if (node >= 0) { | 186 | if (node >= 0) { |
187 | node_to_cpumask_ptr(nodecpumask, node); | 187 | node_to_cpumask_ptr(nodecpumask, node); |
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 271d41cc05ab..6f3c7446c329 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
@@ -489,13 +489,13 @@ pci_mmap_legacy_mem(struct kobject *kobj, struct bin_attribute *attr, | |||
489 | * @kobj: kobject for mapping | 489 | * @kobj: kobject for mapping |
490 | * @attr: struct bin_attribute for the file being mapped | 490 | * @attr: struct bin_attribute for the file being mapped |
491 | * @vma: struct vm_area_struct passed into the mmap | 491 | * @vma: struct vm_area_struct passed into the mmap |
492 | * @write_combine: 1 for write_combine mapping | ||
492 | * | 493 | * |
493 | * Use the regular PCI mapping routines to map a PCI resource into userspace. | 494 | * Use the regular PCI mapping routines to map a PCI resource into userspace. |
494 | * FIXME: write combining? maybe automatic for prefetchable regions? | ||
495 | */ | 495 | */ |
496 | static int | 496 | static int |
497 | pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr, | 497 | pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr, |
498 | struct vm_area_struct *vma) | 498 | struct vm_area_struct *vma, int write_combine) |
499 | { | 499 | { |
500 | struct pci_dev *pdev = to_pci_dev(container_of(kobj, | 500 | struct pci_dev *pdev = to_pci_dev(container_of(kobj, |
501 | struct device, kobj)); | 501 | struct device, kobj)); |
@@ -518,7 +518,21 @@ pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr, | |||
518 | vma->vm_pgoff += start >> PAGE_SHIFT; | 518 | vma->vm_pgoff += start >> PAGE_SHIFT; |
519 | mmap_type = res->flags & IORESOURCE_MEM ? pci_mmap_mem : pci_mmap_io; | 519 | mmap_type = res->flags & IORESOURCE_MEM ? pci_mmap_mem : pci_mmap_io; |
520 | 520 | ||
521 | return pci_mmap_page_range(pdev, vma, mmap_type, 0); | 521 | return pci_mmap_page_range(pdev, vma, mmap_type, write_combine); |
522 | } | ||
523 | |||
524 | static int | ||
525 | pci_mmap_resource_uc(struct kobject *kobj, struct bin_attribute *attr, | ||
526 | struct vm_area_struct *vma) | ||
527 | { | ||
528 | return pci_mmap_resource(kobj, attr, vma, 0); | ||
529 | } | ||
530 | |||
531 | static int | ||
532 | pci_mmap_resource_wc(struct kobject *kobj, struct bin_attribute *attr, | ||
533 | struct vm_area_struct *vma) | ||
534 | { | ||
535 | return pci_mmap_resource(kobj, attr, vma, 1); | ||
522 | } | 536 | } |
523 | 537 | ||
524 | /** | 538 | /** |
@@ -541,9 +555,46 @@ pci_remove_resource_files(struct pci_dev *pdev) | |||
541 | sysfs_remove_bin_file(&pdev->dev.kobj, res_attr); | 555 | sysfs_remove_bin_file(&pdev->dev.kobj, res_attr); |
542 | kfree(res_attr); | 556 | kfree(res_attr); |
543 | } | 557 | } |
558 | |||
559 | res_attr = pdev->res_attr_wc[i]; | ||
560 | if (res_attr) { | ||
561 | sysfs_remove_bin_file(&pdev->dev.kobj, res_attr); | ||
562 | kfree(res_attr); | ||
563 | } | ||
544 | } | 564 | } |
545 | } | 565 | } |
546 | 566 | ||
567 | static int pci_create_attr(struct pci_dev *pdev, int num, int write_combine) | ||
568 | { | ||
569 | /* allocate attribute structure, piggyback attribute name */ | ||
570 | int name_len = write_combine ? 13 : 10; | ||
571 | struct bin_attribute *res_attr; | ||
572 | int retval; | ||
573 | |||
574 | res_attr = kzalloc(sizeof(*res_attr) + name_len, GFP_ATOMIC); | ||
575 | if (res_attr) { | ||
576 | char *res_attr_name = (char *)(res_attr + 1); | ||
577 | |||
578 | if (write_combine) { | ||
579 | pdev->res_attr_wc[num] = res_attr; | ||
580 | sprintf(res_attr_name, "resource%d_wc", num); | ||
581 | res_attr->mmap = pci_mmap_resource_wc; | ||
582 | } else { | ||
583 | pdev->res_attr[num] = res_attr; | ||
584 | sprintf(res_attr_name, "resource%d", num); | ||
585 | res_attr->mmap = pci_mmap_resource_uc; | ||
586 | } | ||
587 | res_attr->attr.name = res_attr_name; | ||
588 | res_attr->attr.mode = S_IRUSR | S_IWUSR; | ||
589 | res_attr->size = pci_resource_len(pdev, num); | ||
590 | res_attr->private = &pdev->resource[num]; | ||
591 | retval = sysfs_create_bin_file(&pdev->dev.kobj, res_attr); | ||
592 | } else | ||
593 | retval = -ENOMEM; | ||
594 | |||
595 | return retval; | ||
596 | } | ||
597 | |||
547 | /** | 598 | /** |
548 | * pci_create_resource_files - create resource files in sysfs for @dev | 599 | * pci_create_resource_files - create resource files in sysfs for @dev |
549 | * @dev: dev in question | 600 | * @dev: dev in question |
@@ -557,31 +608,19 @@ static int pci_create_resource_files(struct pci_dev *pdev) | |||
557 | 608 | ||
558 | /* Expose the PCI resources from this device as files */ | 609 | /* Expose the PCI resources from this device as files */ |
559 | for (i = 0; i < PCI_ROM_RESOURCE; i++) { | 610 | for (i = 0; i < PCI_ROM_RESOURCE; i++) { |
560 | struct bin_attribute *res_attr; | ||
561 | 611 | ||
562 | /* skip empty resources */ | 612 | /* skip empty resources */ |
563 | if (!pci_resource_len(pdev, i)) | 613 | if (!pci_resource_len(pdev, i)) |
564 | continue; | 614 | continue; |
565 | 615 | ||
566 | /* allocate attribute structure, piggyback attribute name */ | 616 | retval = pci_create_attr(pdev, i, 0); |
567 | res_attr = kzalloc(sizeof(*res_attr) + 10, GFP_ATOMIC); | 617 | /* for prefetchable resources, create a WC mappable file */ |
568 | if (res_attr) { | 618 | if (!retval && pdev->resource[i].flags & IORESOURCE_PREFETCH) |
569 | char *res_attr_name = (char *)(res_attr + 1); | 619 | retval = pci_create_attr(pdev, i, 1); |
570 | 620 | ||
571 | pdev->res_attr[i] = res_attr; | 621 | if (retval) { |
572 | sprintf(res_attr_name, "resource%d", i); | 622 | pci_remove_resource_files(pdev); |
573 | res_attr->attr.name = res_attr_name; | 623 | return retval; |
574 | res_attr->attr.mode = S_IRUSR | S_IWUSR; | ||
575 | res_attr->size = pci_resource_len(pdev, i); | ||
576 | res_attr->mmap = pci_mmap_resource; | ||
577 | res_attr->private = &pdev->resource[i]; | ||
578 | retval = sysfs_create_bin_file(&pdev->dev.kobj, res_attr); | ||
579 | if (retval) { | ||
580 | pci_remove_resource_files(pdev); | ||
581 | return retval; | ||
582 | } | ||
583 | } else { | ||
584 | return -ENOMEM; | ||
585 | } | 624 | } |
586 | } | 625 | } |
587 | return 0; | 626 | return 0; |
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index 61fedb2448b6..f82495583e63 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c | |||
@@ -506,6 +506,23 @@ static void free_link_state(struct pci_dev *pdev) | |||
506 | pdev->link_state = NULL; | 506 | pdev->link_state = NULL; |
507 | } | 507 | } |
508 | 508 | ||
509 | static int pcie_aspm_sanity_check(struct pci_dev *pdev) | ||
510 | { | ||
511 | struct pci_dev *child_dev; | ||
512 | int child_pos; | ||
513 | |||
514 | /* | ||
515 | * Some functions in a slot might not all be PCIE functions, very | ||
516 | * strange. Disable ASPM for the whole slot | ||
517 | */ | ||
518 | list_for_each_entry(child_dev, &pdev->subordinate->devices, bus_list) { | ||
519 | child_pos = pci_find_capability(child_dev, PCI_CAP_ID_EXP); | ||
520 | if (!child_pos) | ||
521 | return -EINVAL; | ||
522 | } | ||
523 | return 0; | ||
524 | } | ||
525 | |||
509 | /* | 526 | /* |
510 | * pcie_aspm_init_link_state: Initiate PCI express link state. | 527 | * pcie_aspm_init_link_state: Initiate PCI express link state. |
511 | * It is called after the pcie and its children devices are scaned. | 528 | * It is called after the pcie and its children devices are scaned. |
@@ -526,6 +543,9 @@ void pcie_aspm_init_link_state(struct pci_dev *pdev) | |||
526 | if (list_empty(&pdev->subordinate->devices)) | 543 | if (list_empty(&pdev->subordinate->devices)) |
527 | goto out; | 544 | goto out; |
528 | 545 | ||
546 | if (pcie_aspm_sanity_check(pdev)) | ||
547 | goto out; | ||
548 | |||
529 | mutex_lock(&aspm_lock); | 549 | mutex_lock(&aspm_lock); |
530 | 550 | ||
531 | link_state = kzalloc(sizeof(*link_state), GFP_KERNEL); | 551 | link_state = kzalloc(sizeof(*link_state), GFP_KERNEL); |
diff --git a/drivers/pcmcia/electra_cf.c b/drivers/pcmcia/electra_cf.c index 0a6cea1316b4..52d0aa8c2e7a 100644 --- a/drivers/pcmcia/electra_cf.c +++ b/drivers/pcmcia/electra_cf.c | |||
@@ -352,6 +352,7 @@ static struct of_device_id electra_cf_match[] = { | |||
352 | }, | 352 | }, |
353 | {}, | 353 | {}, |
354 | }; | 354 | }; |
355 | MODULE_DEVICE_TABLE(of, electra_cf_match); | ||
355 | 356 | ||
356 | static struct of_platform_driver electra_cf_driver = { | 357 | static struct of_platform_driver electra_cf_driver = { |
357 | .name = (char *)driver_name, | 358 | .name = (char *)driver_name, |
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index 0201c8adfda7..46c791adb894 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c | |||
@@ -50,15 +50,17 @@ static int irq_flags(int triggering, int polarity, int shareable) | |||
50 | flags = IORESOURCE_IRQ_HIGHEDGE; | 50 | flags = IORESOURCE_IRQ_HIGHEDGE; |
51 | } | 51 | } |
52 | 52 | ||
53 | if (shareable) | 53 | if (shareable == ACPI_SHARED) |
54 | flags |= IORESOURCE_IRQ_SHAREABLE; | 54 | flags |= IORESOURCE_IRQ_SHAREABLE; |
55 | 55 | ||
56 | return flags; | 56 | return flags; |
57 | } | 57 | } |
58 | 58 | ||
59 | static void decode_irq_flags(int flag, int *triggering, int *polarity) | 59 | static void decode_irq_flags(struct pnp_dev *dev, int flags, int *triggering, |
60 | int *polarity, int *shareable) | ||
60 | { | 61 | { |
61 | switch (flag) { | 62 | switch (flags & (IORESOURCE_IRQ_LOWLEVEL | IORESOURCE_IRQ_HIGHLEVEL | |
63 | IORESOURCE_IRQ_LOWEDGE | IORESOURCE_IRQ_HIGHEDGE)) { | ||
62 | case IORESOURCE_IRQ_LOWLEVEL: | 64 | case IORESOURCE_IRQ_LOWLEVEL: |
63 | *triggering = ACPI_LEVEL_SENSITIVE; | 65 | *triggering = ACPI_LEVEL_SENSITIVE; |
64 | *polarity = ACPI_ACTIVE_LOW; | 66 | *polarity = ACPI_ACTIVE_LOW; |
@@ -75,7 +77,18 @@ static void decode_irq_flags(int flag, int *triggering, int *polarity) | |||
75 | *triggering = ACPI_EDGE_SENSITIVE; | 77 | *triggering = ACPI_EDGE_SENSITIVE; |
76 | *polarity = ACPI_ACTIVE_HIGH; | 78 | *polarity = ACPI_ACTIVE_HIGH; |
77 | break; | 79 | break; |
80 | default: | ||
81 | dev_err(&dev->dev, "can't encode invalid IRQ mode %#x\n", | ||
82 | flags); | ||
83 | *triggering = ACPI_EDGE_SENSITIVE; | ||
84 | *polarity = ACPI_ACTIVE_HIGH; | ||
85 | break; | ||
78 | } | 86 | } |
87 | |||
88 | if (flags & IORESOURCE_IRQ_SHAREABLE) | ||
89 | *shareable = ACPI_SHARED; | ||
90 | else | ||
91 | *shareable = ACPI_EXCLUSIVE; | ||
79 | } | 92 | } |
80 | 93 | ||
81 | static void pnpacpi_parse_allocated_irqresource(struct pnp_dev *dev, | 94 | static void pnpacpi_parse_allocated_irqresource(struct pnp_dev *dev, |
@@ -742,6 +755,9 @@ static acpi_status pnpacpi_type_resources(struct acpi_resource *res, void *data) | |||
742 | if (pnpacpi_supported_resource(res)) { | 755 | if (pnpacpi_supported_resource(res)) { |
743 | (*resource)->type = res->type; | 756 | (*resource)->type = res->type; |
744 | (*resource)->length = sizeof(struct acpi_resource); | 757 | (*resource)->length = sizeof(struct acpi_resource); |
758 | if (res->type == ACPI_RESOURCE_TYPE_IRQ) | ||
759 | (*resource)->data.irq.descriptor_length = | ||
760 | res->data.irq.descriptor_length; | ||
745 | (*resource)++; | 761 | (*resource)++; |
746 | } | 762 | } |
747 | 763 | ||
@@ -788,22 +804,21 @@ static void pnpacpi_encode_irq(struct pnp_dev *dev, | |||
788 | struct resource *p) | 804 | struct resource *p) |
789 | { | 805 | { |
790 | struct acpi_resource_irq *irq = &resource->data.irq; | 806 | struct acpi_resource_irq *irq = &resource->data.irq; |
791 | int triggering, polarity; | 807 | int triggering, polarity, shareable; |
792 | 808 | ||
793 | decode_irq_flags(p->flags & IORESOURCE_BITS, &triggering, &polarity); | 809 | decode_irq_flags(dev, p->flags, &triggering, &polarity, &shareable); |
794 | irq->triggering = triggering; | 810 | irq->triggering = triggering; |
795 | irq->polarity = polarity; | 811 | irq->polarity = polarity; |
796 | if (triggering == ACPI_EDGE_SENSITIVE) | 812 | irq->sharable = shareable; |
797 | irq->sharable = ACPI_EXCLUSIVE; | ||
798 | else | ||
799 | irq->sharable = ACPI_SHARED; | ||
800 | irq->interrupt_count = 1; | 813 | irq->interrupt_count = 1; |
801 | irq->interrupts[0] = p->start; | 814 | irq->interrupts[0] = p->start; |
802 | 815 | ||
803 | dev_dbg(&dev->dev, " encode irq %d %s %s %s\n", (int) p->start, | 816 | dev_dbg(&dev->dev, " encode irq %d %s %s %s (%d-byte descriptor)\n", |
817 | (int) p->start, | ||
804 | triggering == ACPI_LEVEL_SENSITIVE ? "level" : "edge", | 818 | triggering == ACPI_LEVEL_SENSITIVE ? "level" : "edge", |
805 | polarity == ACPI_ACTIVE_LOW ? "low" : "high", | 819 | polarity == ACPI_ACTIVE_LOW ? "low" : "high", |
806 | irq->sharable == ACPI_SHARED ? "shared" : "exclusive"); | 820 | irq->sharable == ACPI_SHARED ? "shared" : "exclusive", |
821 | irq->descriptor_length); | ||
807 | } | 822 | } |
808 | 823 | ||
809 | static void pnpacpi_encode_ext_irq(struct pnp_dev *dev, | 824 | static void pnpacpi_encode_ext_irq(struct pnp_dev *dev, |
@@ -811,16 +826,13 @@ static void pnpacpi_encode_ext_irq(struct pnp_dev *dev, | |||
811 | struct resource *p) | 826 | struct resource *p) |
812 | { | 827 | { |
813 | struct acpi_resource_extended_irq *extended_irq = &resource->data.extended_irq; | 828 | struct acpi_resource_extended_irq *extended_irq = &resource->data.extended_irq; |
814 | int triggering, polarity; | 829 | int triggering, polarity, shareable; |
815 | 830 | ||
816 | decode_irq_flags(p->flags & IORESOURCE_BITS, &triggering, &polarity); | 831 | decode_irq_flags(dev, p->flags, &triggering, &polarity, &shareable); |
817 | extended_irq->producer_consumer = ACPI_CONSUMER; | 832 | extended_irq->producer_consumer = ACPI_CONSUMER; |
818 | extended_irq->triggering = triggering; | 833 | extended_irq->triggering = triggering; |
819 | extended_irq->polarity = polarity; | 834 | extended_irq->polarity = polarity; |
820 | if (triggering == ACPI_EDGE_SENSITIVE) | 835 | extended_irq->sharable = shareable; |
821 | extended_irq->sharable = ACPI_EXCLUSIVE; | ||
822 | else | ||
823 | extended_irq->sharable = ACPI_SHARED; | ||
824 | extended_irq->interrupt_count = 1; | 836 | extended_irq->interrupt_count = 1; |
825 | extended_irq->interrupts[0] = p->start; | 837 | extended_irq->interrupts[0] = p->start; |
826 | 838 | ||
diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c index e2b7de4cb05e..1ff3bb585ab2 100644 --- a/drivers/pnp/quirks.c +++ b/drivers/pnp/quirks.c | |||
@@ -286,7 +286,7 @@ static void quirk_system_pci_resources(struct pnp_dev *dev) | |||
286 | pci_name(pdev), i, | 286 | pci_name(pdev), i, |
287 | (unsigned long long) pci_start, | 287 | (unsigned long long) pci_start, |
288 | (unsigned long long) pci_end); | 288 | (unsigned long long) pci_end); |
289 | res->flags = 0; | 289 | res->flags |= IORESOURCE_DISABLED; |
290 | } | 290 | } |
291 | } | 291 | } |
292 | } | 292 | } |
diff --git a/drivers/pnp/system.c b/drivers/pnp/system.c index 9c2496dbeee4..cf4e07b01d48 100644 --- a/drivers/pnp/system.c +++ b/drivers/pnp/system.c | |||
@@ -81,7 +81,7 @@ static void reserve_resources_of_dev(struct pnp_dev *dev) | |||
81 | } | 81 | } |
82 | 82 | ||
83 | for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_MEM, i)); i++) { | 83 | for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_MEM, i)); i++) { |
84 | if (res->flags & IORESOURCE_UNSET) | 84 | if (res->flags & (IORESOURCE_UNSET | IORESOURCE_DISABLED)) |
85 | continue; | 85 | continue; |
86 | 86 | ||
87 | reserve_range(dev, res->start, res->end, 0); | 87 | reserve_range(dev, res->start, res->end, 0); |
diff --git a/drivers/power/power_supply_core.c b/drivers/power/power_supply_core.c index 138dd76ee347..af1633eb3b70 100644 --- a/drivers/power/power_supply_core.c +++ b/drivers/power/power_supply_core.c | |||
@@ -91,15 +91,13 @@ int power_supply_register(struct device *parent, struct power_supply *psy) | |||
91 | { | 91 | { |
92 | int rc = 0; | 92 | int rc = 0; |
93 | 93 | ||
94 | psy->dev = device_create(power_supply_class, parent, 0, | 94 | psy->dev = device_create_drvdata(power_supply_class, parent, 0, |
95 | "%s", psy->name); | 95 | psy, "%s", psy->name); |
96 | if (IS_ERR(psy->dev)) { | 96 | if (IS_ERR(psy->dev)) { |
97 | rc = PTR_ERR(psy->dev); | 97 | rc = PTR_ERR(psy->dev); |
98 | goto dev_create_failed; | 98 | goto dev_create_failed; |
99 | } | 99 | } |
100 | 100 | ||
101 | dev_set_drvdata(psy->dev, psy); | ||
102 | |||
103 | INIT_WORK(&psy->changed_work, power_supply_changed_work); | 101 | INIT_WORK(&psy->changed_work, power_supply_changed_work); |
104 | 102 | ||
105 | rc = power_supply_create_attrs(psy); | 103 | rc = power_supply_create_attrs(psy); |
diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c index c444d6b10c58..49215da5249b 100644 --- a/drivers/power/power_supply_sysfs.c +++ b/drivers/power/power_supply_sysfs.c | |||
@@ -201,7 +201,7 @@ int power_supply_uevent(struct device *dev, struct kobj_uevent_env *env) | |||
201 | 201 | ||
202 | dev_dbg(dev, "uevent\n"); | 202 | dev_dbg(dev, "uevent\n"); |
203 | 203 | ||
204 | if (!psy) { | 204 | if (!psy || !psy->dev) { |
205 | dev_dbg(dev, "No power supply yet\n"); | 205 | dev_dbg(dev, "No power supply yet\n"); |
206 | return ret; | 206 | return ret; |
207 | } | 207 | } |
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 6cc2c0330230..4949dc4859be 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
@@ -256,6 +256,17 @@ config RTC_DRV_S35390A | |||
256 | This driver can also be built as a module. If so the module | 256 | This driver can also be built as a module. If so the module |
257 | will be called rtc-s35390a. | 257 | will be called rtc-s35390a. |
258 | 258 | ||
259 | config RTC_DRV_FM3130 | ||
260 | tristate "Ramtron FM3130" | ||
261 | help | ||
262 | If you say Y here you will get support for the | ||
263 | Ramtron FM3130 RTC chips. | ||
264 | Ramtron FM3130 is a chip with two separate devices inside, | ||
265 | RTC clock and FRAM. This driver provides only RTC functionality. | ||
266 | |||
267 | This driver can also be built as a module. If so the module | ||
268 | will be called rtc-fm3130. | ||
269 | |||
259 | endif # I2C | 270 | endif # I2C |
260 | 271 | ||
261 | comment "SPI RTC drivers" | 272 | comment "SPI RTC drivers" |
@@ -534,4 +545,12 @@ config RTC_DRV_RS5C313 | |||
534 | help | 545 | help |
535 | If you say yes here you get support for the Ricoh RS5C313 RTC chips. | 546 | If you say yes here you get support for the Ricoh RS5C313 RTC chips. |
536 | 547 | ||
548 | config RTC_DRV_PPC | ||
549 | tristate "PowerPC machine dependent RTC support" | ||
550 | depends on PPC_MERGE | ||
551 | help | ||
552 | The PowerPC kernel has machine-specific functions for accessing | ||
553 | the RTC. This exposes that functionality through the generic RTC | ||
554 | class. | ||
555 | |||
537 | endif # RTC_CLASS | 556 | endif # RTC_CLASS |
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 872f1218ff9f..b6e14d51670b 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile | |||
@@ -31,6 +31,7 @@ obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o | |||
31 | obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o | 31 | obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o |
32 | obj-$(CONFIG_RTC_DRV_DS1742) += rtc-ds1742.o | 32 | obj-$(CONFIG_RTC_DRV_DS1742) += rtc-ds1742.o |
33 | obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o | 33 | obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o |
34 | obj-$(CONFIG_RTC_DRV_FM3130) += rtc-fm3130.o | ||
34 | obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o | 35 | obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o |
35 | obj-$(CONFIG_RTC_DRV_M41T80) += rtc-m41t80.o | 36 | obj-$(CONFIG_RTC_DRV_M41T80) += rtc-m41t80.o |
36 | obj-$(CONFIG_RTC_DRV_M48T59) += rtc-m48t59.o | 37 | obj-$(CONFIG_RTC_DRV_M48T59) += rtc-m48t59.o |
@@ -41,6 +42,7 @@ obj-$(CONFIG_RTC_DRV_OMAP) += rtc-omap.o | |||
41 | obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o | 42 | obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o |
42 | obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o | 43 | obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o |
43 | obj-$(CONFIG_RTC_DRV_PL031) += rtc-pl031.o | 44 | obj-$(CONFIG_RTC_DRV_PL031) += rtc-pl031.o |
45 | obj-$(CONFIG_RTC_DRV_PPC) += rtc-ppc.o | ||
44 | obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o | 46 | obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o |
45 | obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o | 47 | obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o |
46 | obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o | 48 | obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o |
diff --git a/drivers/rtc/rtc-at32ap700x.c b/drivers/rtc/rtc-at32ap700x.c index 42244f14b41c..2ef8cdfda4a7 100644 --- a/drivers/rtc/rtc-at32ap700x.c +++ b/drivers/rtc/rtc-at32ap700x.c | |||
@@ -94,8 +94,11 @@ static int at32_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
94 | { | 94 | { |
95 | struct rtc_at32ap700x *rtc = dev_get_drvdata(dev); | 95 | struct rtc_at32ap700x *rtc = dev_get_drvdata(dev); |
96 | 96 | ||
97 | spin_lock_irq(&rtc->lock); | ||
97 | rtc_time_to_tm(rtc->alarm_time, &alrm->time); | 98 | rtc_time_to_tm(rtc->alarm_time, &alrm->time); |
98 | alrm->pending = rtc_readl(rtc, IMR) & RTC_BIT(IMR_TOPI) ? 1 : 0; | 99 | alrm->enabled = rtc_readl(rtc, IMR) & RTC_BIT(IMR_TOPI) ? 1 : 0; |
100 | alrm->pending = rtc_readl(rtc, ISR) & RTC_BIT(ISR_TOPI) ? 1 : 0; | ||
101 | spin_unlock_irq(&rtc->lock); | ||
99 | 102 | ||
100 | return 0; | 103 | return 0; |
101 | } | 104 | } |
@@ -119,7 +122,7 @@ static int at32_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
119 | spin_lock_irq(&rtc->lock); | 122 | spin_lock_irq(&rtc->lock); |
120 | rtc->alarm_time = alarm_unix_time; | 123 | rtc->alarm_time = alarm_unix_time; |
121 | rtc_writel(rtc, TOP, rtc->alarm_time); | 124 | rtc_writel(rtc, TOP, rtc->alarm_time); |
122 | if (alrm->pending) | 125 | if (alrm->enabled) |
123 | rtc_writel(rtc, CTRL, rtc_readl(rtc, CTRL) | 126 | rtc_writel(rtc, CTRL, rtc_readl(rtc, CTRL) |
124 | | RTC_BIT(CTRL_TOPEN)); | 127 | | RTC_BIT(CTRL_TOPEN)); |
125 | else | 128 | else |
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index d060a06ce05b..d7bb9bac71df 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c | |||
@@ -905,19 +905,7 @@ static struct pnp_driver cmos_pnp_driver = { | |||
905 | .resume = cmos_pnp_resume, | 905 | .resume = cmos_pnp_resume, |
906 | }; | 906 | }; |
907 | 907 | ||
908 | static int __init cmos_init(void) | 908 | #endif /* CONFIG_PNP */ |
909 | { | ||
910 | return pnp_register_driver(&cmos_pnp_driver); | ||
911 | } | ||
912 | module_init(cmos_init); | ||
913 | |||
914 | static void __exit cmos_exit(void) | ||
915 | { | ||
916 | pnp_unregister_driver(&cmos_pnp_driver); | ||
917 | } | ||
918 | module_exit(cmos_exit); | ||
919 | |||
920 | #else /* no PNP */ | ||
921 | 909 | ||
922 | /*----------------------------------------------------------------*/ | 910 | /*----------------------------------------------------------------*/ |
923 | 911 | ||
@@ -958,20 +946,33 @@ static struct platform_driver cmos_platform_driver = { | |||
958 | 946 | ||
959 | static int __init cmos_init(void) | 947 | static int __init cmos_init(void) |
960 | { | 948 | { |
949 | #ifdef CONFIG_PNP | ||
950 | if (pnp_platform_devices) | ||
951 | return pnp_register_driver(&cmos_pnp_driver); | ||
952 | else | ||
953 | return platform_driver_probe(&cmos_platform_driver, | ||
954 | cmos_platform_probe); | ||
955 | #else | ||
961 | return platform_driver_probe(&cmos_platform_driver, | 956 | return platform_driver_probe(&cmos_platform_driver, |
962 | cmos_platform_probe); | 957 | cmos_platform_probe); |
958 | #endif /* CONFIG_PNP */ | ||
963 | } | 959 | } |
964 | module_init(cmos_init); | 960 | module_init(cmos_init); |
965 | 961 | ||
966 | static void __exit cmos_exit(void) | 962 | static void __exit cmos_exit(void) |
967 | { | 963 | { |
964 | #ifdef CONFIG_PNP | ||
965 | if (pnp_platform_devices) | ||
966 | pnp_unregister_driver(&cmos_pnp_driver); | ||
967 | else | ||
968 | platform_driver_unregister(&cmos_platform_driver); | ||
969 | #else | ||
968 | platform_driver_unregister(&cmos_platform_driver); | 970 | platform_driver_unregister(&cmos_platform_driver); |
971 | #endif /* CONFIG_PNP */ | ||
969 | } | 972 | } |
970 | module_exit(cmos_exit); | 973 | module_exit(cmos_exit); |
971 | 974 | ||
972 | 975 | ||
973 | #endif /* !PNP */ | ||
974 | |||
975 | MODULE_AUTHOR("David Brownell"); | 976 | MODULE_AUTHOR("David Brownell"); |
976 | MODULE_DESCRIPTION("Driver for PC-style 'CMOS' RTCs"); | 977 | MODULE_DESCRIPTION("Driver for PC-style 'CMOS' RTCs"); |
977 | MODULE_LICENSE("GPL"); | 978 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c index fa2d2f8b3f4d..640acd20fdde 100644 --- a/drivers/rtc/rtc-ds1374.c +++ b/drivers/rtc/rtc-ds1374.c | |||
@@ -42,7 +42,7 @@ | |||
42 | #define DS1374_REG_TCR 0x09 /* Trickle Charge */ | 42 | #define DS1374_REG_TCR 0x09 /* Trickle Charge */ |
43 | 43 | ||
44 | static const struct i2c_device_id ds1374_id[] = { | 44 | static const struct i2c_device_id ds1374_id[] = { |
45 | { "rtc-ds1374", 0 }, | 45 | { "ds1374", 0 }, |
46 | { } | 46 | { } |
47 | }; | 47 | }; |
48 | MODULE_DEVICE_TABLE(i2c, ds1374_id); | 48 | MODULE_DEVICE_TABLE(i2c, ds1374_id); |
diff --git a/drivers/rtc/rtc-fm3130.c b/drivers/rtc/rtc-fm3130.c new file mode 100644 index 000000000000..11644c8fca82 --- /dev/null +++ b/drivers/rtc/rtc-fm3130.c | |||
@@ -0,0 +1,501 @@ | |||
1 | /* | ||
2 | * rtc-fm3130.c - RTC driver for Ramtron FM3130 I2C chip. | ||
3 | * | ||
4 | * Copyright (C) 2008 Sergey Lapin | ||
5 | * Based on ds1307 driver by James Chapman and David Brownell | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/i2c.h> | ||
14 | #include <linux/rtc.h> | ||
15 | #include <linux/bcd.h> | ||
16 | |||
17 | #define FM3130_RTC_CONTROL (0x0) | ||
18 | #define FM3130_CAL_CONTROL (0x1) | ||
19 | #define FM3130_RTC_SECONDS (0x2) | ||
20 | #define FM3130_RTC_MINUTES (0x3) | ||
21 | #define FM3130_RTC_HOURS (0x4) | ||
22 | #define FM3130_RTC_DAY (0x5) | ||
23 | #define FM3130_RTC_DATE (0x6) | ||
24 | #define FM3130_RTC_MONTHS (0x7) | ||
25 | #define FM3130_RTC_YEARS (0x8) | ||
26 | |||
27 | #define FM3130_ALARM_SECONDS (0x9) | ||
28 | #define FM3130_ALARM_MINUTES (0xa) | ||
29 | #define FM3130_ALARM_HOURS (0xb) | ||
30 | #define FM3130_ALARM_DATE (0xc) | ||
31 | #define FM3130_ALARM_MONTHS (0xd) | ||
32 | #define FM3130_ALARM_WP_CONTROL (0xe) | ||
33 | |||
34 | #define FM3130_CAL_CONTROL_BIT_nOSCEN (1 << 7) /* Osciallator enabled */ | ||
35 | #define FM3130_RTC_CONTROL_BIT_LB (1 << 7) /* Low battery */ | ||
36 | #define FM3130_RTC_CONTROL_BIT_AF (1 << 6) /* Alarm flag */ | ||
37 | #define FM3130_RTC_CONTROL_BIT_CF (1 << 5) /* Century overflow */ | ||
38 | #define FM3130_RTC_CONTROL_BIT_POR (1 << 4) /* Power on reset */ | ||
39 | #define FM3130_RTC_CONTROL_BIT_AEN (1 << 3) /* Alarm enable */ | ||
40 | #define FM3130_RTC_CONTROL_BIT_CAL (1 << 2) /* Calibration mode */ | ||
41 | #define FM3130_RTC_CONTROL_BIT_WRITE (1 << 1) /* W=1 -> write mode W=0 normal */ | ||
42 | #define FM3130_RTC_CONTROL_BIT_READ (1 << 0) /* R=1 -> read mode R=0 normal */ | ||
43 | |||
44 | #define FM3130_CLOCK_REGS 7 | ||
45 | #define FM3130_ALARM_REGS 5 | ||
46 | |||
47 | struct fm3130 { | ||
48 | u8 reg_addr_time; | ||
49 | u8 reg_addr_alarm; | ||
50 | u8 regs[15]; | ||
51 | struct i2c_msg msg[4]; | ||
52 | struct i2c_client *client; | ||
53 | struct rtc_device *rtc; | ||
54 | int data_valid; | ||
55 | int alarm; | ||
56 | }; | ||
57 | static const struct i2c_device_id fm3130_id[] = { | ||
58 | { "fm3130-rtc", 0 }, | ||
59 | { } | ||
60 | }; | ||
61 | MODULE_DEVICE_TABLE(i2c, fm3130_id); | ||
62 | |||
63 | #define FM3130_MODE_NORMAL 0 | ||
64 | #define FM3130_MODE_WRITE 1 | ||
65 | #define FM3130_MODE_READ 2 | ||
66 | |||
67 | static void fm3130_rtc_mode(struct device *dev, int mode) | ||
68 | { | ||
69 | struct fm3130 *fm3130 = dev_get_drvdata(dev); | ||
70 | |||
71 | fm3130->regs[FM3130_RTC_CONTROL] = | ||
72 | i2c_smbus_read_byte_data(fm3130->client, FM3130_RTC_CONTROL); | ||
73 | switch (mode) { | ||
74 | case FM3130_MODE_NORMAL: | ||
75 | fm3130->regs[FM3130_RTC_CONTROL] &= | ||
76 | ~(FM3130_RTC_CONTROL_BIT_WRITE | | ||
77 | FM3130_RTC_CONTROL_BIT_READ); | ||
78 | break; | ||
79 | case FM3130_MODE_WRITE: | ||
80 | fm3130->regs[FM3130_RTC_CONTROL] |= FM3130_RTC_CONTROL_BIT_WRITE; | ||
81 | break; | ||
82 | case FM3130_MODE_READ: | ||
83 | fm3130->regs[FM3130_RTC_CONTROL] |= FM3130_RTC_CONTROL_BIT_READ; | ||
84 | break; | ||
85 | default: | ||
86 | dev_dbg(dev, "invalid mode %d\n", mode); | ||
87 | break; | ||
88 | } | ||
89 | /* Checking for alarm */ | ||
90 | if (fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_AF) { | ||
91 | fm3130->alarm = 1; | ||
92 | fm3130->regs[FM3130_RTC_CONTROL] &= ~FM3130_RTC_CONTROL_BIT_AF; | ||
93 | } | ||
94 | i2c_smbus_write_byte_data(fm3130->client, | ||
95 | FM3130_RTC_CONTROL, fm3130->regs[FM3130_RTC_CONTROL]); | ||
96 | } | ||
97 | |||
98 | static int fm3130_get_time(struct device *dev, struct rtc_time *t) | ||
99 | { | ||
100 | struct fm3130 *fm3130 = dev_get_drvdata(dev); | ||
101 | int tmp; | ||
102 | |||
103 | if (!fm3130->data_valid) { | ||
104 | /* We have invalid data in RTC, probably due | ||
105 | to battery faults or other problems. Return EIO | ||
106 | for now, it will allow us to set data later insted | ||
107 | of error during probing which disables device */ | ||
108 | return -EIO; | ||
109 | } | ||
110 | fm3130_rtc_mode(dev, FM3130_MODE_READ); | ||
111 | |||
112 | /* read the RTC date and time registers all at once */ | ||
113 | tmp = i2c_transfer(to_i2c_adapter(fm3130->client->dev.parent), | ||
114 | fm3130->msg, 2); | ||
115 | if (tmp != 2) { | ||
116 | dev_err(dev, "%s error %d\n", "read", tmp); | ||
117 | return -EIO; | ||
118 | } | ||
119 | |||
120 | fm3130_rtc_mode(dev, FM3130_MODE_NORMAL); | ||
121 | |||
122 | dev_dbg(dev, "%s: %02x %02x %02x %02x %02x %02x %02x %02x" | ||
123 | "%02x %02x %02x %02x %02x %02x %02x\n", | ||
124 | "read", | ||
125 | fm3130->regs[0], fm3130->regs[1], | ||
126 | fm3130->regs[2], fm3130->regs[3], | ||
127 | fm3130->regs[4], fm3130->regs[5], | ||
128 | fm3130->regs[6], fm3130->regs[7], | ||
129 | fm3130->regs[8], fm3130->regs[9], | ||
130 | fm3130->regs[0xa], fm3130->regs[0xb], | ||
131 | fm3130->regs[0xc], fm3130->regs[0xd], | ||
132 | fm3130->regs[0xe]); | ||
133 | |||
134 | t->tm_sec = BCD2BIN(fm3130->regs[FM3130_RTC_SECONDS] & 0x7f); | ||
135 | t->tm_min = BCD2BIN(fm3130->regs[FM3130_RTC_MINUTES] & 0x7f); | ||
136 | tmp = fm3130->regs[FM3130_RTC_HOURS] & 0x3f; | ||
137 | t->tm_hour = BCD2BIN(tmp); | ||
138 | t->tm_wday = BCD2BIN(fm3130->regs[FM3130_RTC_DAY] & 0x07) - 1; | ||
139 | t->tm_mday = BCD2BIN(fm3130->regs[FM3130_RTC_DATE] & 0x3f); | ||
140 | tmp = fm3130->regs[FM3130_RTC_MONTHS] & 0x1f; | ||
141 | t->tm_mon = BCD2BIN(tmp) - 1; | ||
142 | |||
143 | /* assume 20YY not 19YY, and ignore CF bit */ | ||
144 | t->tm_year = BCD2BIN(fm3130->regs[FM3130_RTC_YEARS]) + 100; | ||
145 | |||
146 | dev_dbg(dev, "%s secs=%d, mins=%d, " | ||
147 | "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n", | ||
148 | "read", t->tm_sec, t->tm_min, | ||
149 | t->tm_hour, t->tm_mday, | ||
150 | t->tm_mon, t->tm_year, t->tm_wday); | ||
151 | |||
152 | /* initial clock setting can be undefined */ | ||
153 | return rtc_valid_tm(t); | ||
154 | } | ||
155 | |||
156 | |||
157 | static int fm3130_set_time(struct device *dev, struct rtc_time *t) | ||
158 | { | ||
159 | struct fm3130 *fm3130 = dev_get_drvdata(dev); | ||
160 | int tmp, i; | ||
161 | u8 *buf = fm3130->regs; | ||
162 | |||
163 | dev_dbg(dev, "%s secs=%d, mins=%d, " | ||
164 | "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n", | ||
165 | "write", t->tm_sec, t->tm_min, | ||
166 | t->tm_hour, t->tm_mday, | ||
167 | t->tm_mon, t->tm_year, t->tm_wday); | ||
168 | |||
169 | /* first register addr */ | ||
170 | buf[FM3130_RTC_SECONDS] = BIN2BCD(t->tm_sec); | ||
171 | buf[FM3130_RTC_MINUTES] = BIN2BCD(t->tm_min); | ||
172 | buf[FM3130_RTC_HOURS] = BIN2BCD(t->tm_hour); | ||
173 | buf[FM3130_RTC_DAY] = BIN2BCD(t->tm_wday + 1); | ||
174 | buf[FM3130_RTC_DATE] = BIN2BCD(t->tm_mday); | ||
175 | buf[FM3130_RTC_MONTHS] = BIN2BCD(t->tm_mon + 1); | ||
176 | |||
177 | /* assume 20YY not 19YY */ | ||
178 | tmp = t->tm_year - 100; | ||
179 | buf[FM3130_RTC_YEARS] = BIN2BCD(tmp); | ||
180 | |||
181 | dev_dbg(dev, "%s: %02x %02x %02x %02x %02x %02x %02x" | ||
182 | "%02x %02x %02x %02x %02x %02x %02x %02x\n", | ||
183 | "write", buf[0], buf[1], buf[2], buf[3], | ||
184 | buf[4], buf[5], buf[6], buf[7], | ||
185 | buf[8], buf[9], buf[0xa], buf[0xb], | ||
186 | buf[0xc], buf[0xd], buf[0xe]); | ||
187 | |||
188 | fm3130_rtc_mode(dev, FM3130_MODE_WRITE); | ||
189 | |||
190 | /* Writing time registers, we don't support multibyte transfers */ | ||
191 | for (i = 0; i < FM3130_CLOCK_REGS; i++) { | ||
192 | i2c_smbus_write_byte_data(fm3130->client, | ||
193 | FM3130_RTC_SECONDS + i, | ||
194 | fm3130->regs[FM3130_RTC_SECONDS + i]); | ||
195 | } | ||
196 | |||
197 | fm3130_rtc_mode(dev, FM3130_MODE_NORMAL); | ||
198 | |||
199 | /* We assume here that data are valid once written */ | ||
200 | if (!fm3130->data_valid) | ||
201 | fm3130->data_valid = 1; | ||
202 | return 0; | ||
203 | } | ||
204 | |||
205 | static int fm3130_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
206 | { | ||
207 | struct fm3130 *fm3130 = dev_get_drvdata(dev); | ||
208 | int tmp; | ||
209 | struct rtc_time *tm = &alrm->time; | ||
210 | /* read the RTC alarm registers all at once */ | ||
211 | tmp = i2c_transfer(to_i2c_adapter(fm3130->client->dev.parent), | ||
212 | &fm3130->msg[2], 2); | ||
213 | if (tmp != 2) { | ||
214 | dev_err(dev, "%s error %d\n", "read", tmp); | ||
215 | return -EIO; | ||
216 | } | ||
217 | dev_dbg(dev, "alarm read %02x %02x %02x %02x %02x\n", | ||
218 | fm3130->regs[FM3130_ALARM_SECONDS], | ||
219 | fm3130->regs[FM3130_ALARM_MINUTES], | ||
220 | fm3130->regs[FM3130_ALARM_HOURS], | ||
221 | fm3130->regs[FM3130_ALARM_DATE], | ||
222 | fm3130->regs[FM3130_ALARM_MONTHS]); | ||
223 | |||
224 | |||
225 | tm->tm_sec = BCD2BIN(fm3130->regs[FM3130_ALARM_SECONDS] & 0x7F); | ||
226 | tm->tm_min = BCD2BIN(fm3130->regs[FM3130_ALARM_MINUTES] & 0x7F); | ||
227 | tm->tm_hour = BCD2BIN(fm3130->regs[FM3130_ALARM_HOURS] & 0x3F); | ||
228 | tm->tm_mday = BCD2BIN(fm3130->regs[FM3130_ALARM_DATE] & 0x3F); | ||
229 | tm->tm_mon = BCD2BIN(fm3130->regs[FM3130_ALARM_MONTHS] & 0x1F); | ||
230 | if (tm->tm_mon > 0) | ||
231 | tm->tm_mon -= 1; /* RTC is 1-12, tm_mon is 0-11 */ | ||
232 | dev_dbg(dev, "%s secs=%d, mins=%d, " | ||
233 | "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n", | ||
234 | "read alarm", tm->tm_sec, tm->tm_min, | ||
235 | tm->tm_hour, tm->tm_mday, | ||
236 | tm->tm_mon, tm->tm_year, tm->tm_wday); | ||
237 | |||
238 | return 0; | ||
239 | } | ||
240 | |||
241 | static int fm3130_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
242 | { | ||
243 | struct fm3130 *fm3130 = dev_get_drvdata(dev); | ||
244 | struct rtc_time *tm = &alrm->time; | ||
245 | int i; | ||
246 | |||
247 | dev_dbg(dev, "%s secs=%d, mins=%d, " | ||
248 | "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n", | ||
249 | "write alarm", tm->tm_sec, tm->tm_min, | ||
250 | tm->tm_hour, tm->tm_mday, | ||
251 | tm->tm_mon, tm->tm_year, tm->tm_wday); | ||
252 | |||
253 | if (tm->tm_sec != -1) | ||
254 | fm3130->regs[FM3130_ALARM_SECONDS] = | ||
255 | BIN2BCD(tm->tm_sec) | 0x80; | ||
256 | |||
257 | if (tm->tm_min != -1) | ||
258 | fm3130->regs[FM3130_ALARM_MINUTES] = | ||
259 | BIN2BCD(tm->tm_min) | 0x80; | ||
260 | |||
261 | if (tm->tm_hour != -1) | ||
262 | fm3130->regs[FM3130_ALARM_HOURS] = | ||
263 | BIN2BCD(tm->tm_hour) | 0x80; | ||
264 | |||
265 | if (tm->tm_mday != -1) | ||
266 | fm3130->regs[FM3130_ALARM_DATE] = | ||
267 | BIN2BCD(tm->tm_mday) | 0x80; | ||
268 | |||
269 | if (tm->tm_mon != -1) | ||
270 | fm3130->regs[FM3130_ALARM_MONTHS] = | ||
271 | BIN2BCD(tm->tm_mon + 1) | 0x80; | ||
272 | |||
273 | dev_dbg(dev, "alarm write %02x %02x %02x %02x %02x\n", | ||
274 | fm3130->regs[FM3130_ALARM_SECONDS], | ||
275 | fm3130->regs[FM3130_ALARM_MINUTES], | ||
276 | fm3130->regs[FM3130_ALARM_HOURS], | ||
277 | fm3130->regs[FM3130_ALARM_DATE], | ||
278 | fm3130->regs[FM3130_ALARM_MONTHS]); | ||
279 | /* Writing time registers, we don't support multibyte transfers */ | ||
280 | for (i = 0; i < FM3130_ALARM_REGS; i++) { | ||
281 | i2c_smbus_write_byte_data(fm3130->client, | ||
282 | FM3130_ALARM_SECONDS + i, | ||
283 | fm3130->regs[FM3130_ALARM_SECONDS + i]); | ||
284 | } | ||
285 | fm3130->regs[FM3130_RTC_CONTROL] = | ||
286 | i2c_smbus_read_byte_data(fm3130->client, FM3130_RTC_CONTROL); | ||
287 | /* Checking for alarm */ | ||
288 | if (fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_AF) { | ||
289 | fm3130->alarm = 1; | ||
290 | fm3130->regs[FM3130_RTC_CONTROL] &= ~FM3130_RTC_CONTROL_BIT_AF; | ||
291 | } | ||
292 | if (alrm->enabled) { | ||
293 | i2c_smbus_write_byte_data(fm3130->client, FM3130_RTC_CONTROL, | ||
294 | (fm3130->regs[FM3130_RTC_CONTROL] & | ||
295 | ~(FM3130_RTC_CONTROL_BIT_CAL)) | | ||
296 | FM3130_RTC_CONTROL_BIT_AEN); | ||
297 | } else { | ||
298 | i2c_smbus_write_byte_data(fm3130->client, FM3130_RTC_CONTROL, | ||
299 | fm3130->regs[FM3130_RTC_CONTROL] & | ||
300 | ~(FM3130_RTC_CONTROL_BIT_AEN)); | ||
301 | } | ||
302 | return 0; | ||
303 | } | ||
304 | |||
305 | static const struct rtc_class_ops fm3130_rtc_ops = { | ||
306 | .read_time = fm3130_get_time, | ||
307 | .set_time = fm3130_set_time, | ||
308 | .read_alarm = fm3130_read_alarm, | ||
309 | .set_alarm = fm3130_set_alarm, | ||
310 | }; | ||
311 | |||
312 | static struct i2c_driver fm3130_driver; | ||
313 | |||
314 | static int __devinit fm3130_probe(struct i2c_client *client, | ||
315 | const struct i2c_device_id *id) | ||
316 | { | ||
317 | struct fm3130 *fm3130; | ||
318 | int err = -ENODEV; | ||
319 | int tmp; | ||
320 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); | ||
321 | |||
322 | if (!i2c_check_functionality(adapter, | ||
323 | I2C_FUNC_I2C | I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) | ||
324 | return -EIO; | ||
325 | |||
326 | fm3130 = kzalloc(sizeof(struct fm3130), GFP_KERNEL); | ||
327 | |||
328 | if (!fm3130) | ||
329 | return -ENOMEM; | ||
330 | |||
331 | fm3130->client = client; | ||
332 | i2c_set_clientdata(client, fm3130); | ||
333 | fm3130->reg_addr_time = FM3130_RTC_SECONDS; | ||
334 | fm3130->reg_addr_alarm = FM3130_ALARM_SECONDS; | ||
335 | |||
336 | /* Messages to read time */ | ||
337 | fm3130->msg[0].addr = client->addr; | ||
338 | fm3130->msg[0].flags = 0; | ||
339 | fm3130->msg[0].len = 1; | ||
340 | fm3130->msg[0].buf = &fm3130->reg_addr_time; | ||
341 | |||
342 | fm3130->msg[1].addr = client->addr; | ||
343 | fm3130->msg[1].flags = I2C_M_RD; | ||
344 | fm3130->msg[1].len = FM3130_CLOCK_REGS; | ||
345 | fm3130->msg[1].buf = &fm3130->regs[FM3130_RTC_SECONDS]; | ||
346 | |||
347 | /* Messages to read alarm */ | ||
348 | fm3130->msg[2].addr = client->addr; | ||
349 | fm3130->msg[2].flags = 0; | ||
350 | fm3130->msg[2].len = 1; | ||
351 | fm3130->msg[2].buf = &fm3130->reg_addr_alarm; | ||
352 | |||
353 | fm3130->msg[3].addr = client->addr; | ||
354 | fm3130->msg[3].flags = I2C_M_RD; | ||
355 | fm3130->msg[3].len = FM3130_ALARM_REGS; | ||
356 | fm3130->msg[3].buf = &fm3130->regs[FM3130_ALARM_SECONDS]; | ||
357 | |||
358 | fm3130->data_valid = 0; | ||
359 | |||
360 | tmp = i2c_transfer(adapter, fm3130->msg, 4); | ||
361 | if (tmp != 4) { | ||
362 | pr_debug("read error %d\n", tmp); | ||
363 | err = -EIO; | ||
364 | goto exit_free; | ||
365 | } | ||
366 | |||
367 | fm3130->regs[FM3130_RTC_CONTROL] = | ||
368 | i2c_smbus_read_byte_data(client, FM3130_RTC_CONTROL); | ||
369 | fm3130->regs[FM3130_CAL_CONTROL] = | ||
370 | i2c_smbus_read_byte_data(client, FM3130_CAL_CONTROL); | ||
371 | |||
372 | /* Checking for alarm */ | ||
373 | if (fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_AF) { | ||
374 | fm3130->alarm = 1; | ||
375 | fm3130->regs[FM3130_RTC_CONTROL] &= ~FM3130_RTC_CONTROL_BIT_AF; | ||
376 | } | ||
377 | |||
378 | /* Disabling calibration mode */ | ||
379 | if (fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_CAL) | ||
380 | i2c_smbus_write_byte_data(client, FM3130_RTC_CONTROL, | ||
381 | fm3130->regs[FM3130_RTC_CONTROL] & | ||
382 | ~(FM3130_RTC_CONTROL_BIT_CAL)); | ||
383 | dev_warn(&client->dev, "Disabling calibration mode!\n"); | ||
384 | |||
385 | /* Disabling read and write modes */ | ||
386 | if (fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_WRITE || | ||
387 | fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_READ) | ||
388 | i2c_smbus_write_byte_data(client, FM3130_RTC_CONTROL, | ||
389 | fm3130->regs[FM3130_RTC_CONTROL] & | ||
390 | ~(FM3130_RTC_CONTROL_BIT_READ | | ||
391 | FM3130_RTC_CONTROL_BIT_WRITE)); | ||
392 | dev_warn(&client->dev, "Disabling READ or WRITE mode!\n"); | ||
393 | |||
394 | /* oscillator off? turn it on, so clock can tick. */ | ||
395 | if (fm3130->regs[FM3130_CAL_CONTROL] & FM3130_CAL_CONTROL_BIT_nOSCEN) | ||
396 | i2c_smbus_write_byte_data(client, FM3130_CAL_CONTROL, | ||
397 | fm3130->regs[FM3130_CAL_CONTROL] & | ||
398 | ~(FM3130_CAL_CONTROL_BIT_nOSCEN)); | ||
399 | |||
400 | /* oscillator fault? clear flag, and warn */ | ||
401 | if (fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_LB) | ||
402 | dev_warn(&client->dev, "Low battery!\n"); | ||
403 | |||
404 | /* oscillator fault? clear flag, and warn */ | ||
405 | if (fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_POR) { | ||
406 | i2c_smbus_write_byte_data(client, FM3130_RTC_CONTROL, | ||
407 | fm3130->regs[FM3130_RTC_CONTROL] & | ||
408 | ~FM3130_RTC_CONTROL_BIT_POR); | ||
409 | dev_warn(&client->dev, "SET TIME!\n"); | ||
410 | } | ||
411 | /* ACS is controlled by alarm */ | ||
412 | i2c_smbus_write_byte_data(client, FM3130_ALARM_WP_CONTROL, 0x80); | ||
413 | |||
414 | /* TODO */ | ||
415 | /* TODO need to sanity check alarm */ | ||
416 | tmp = fm3130->regs[FM3130_RTC_SECONDS]; | ||
417 | tmp = BCD2BIN(tmp & 0x7f); | ||
418 | if (tmp > 60) | ||
419 | goto exit_bad; | ||
420 | tmp = BCD2BIN(fm3130->regs[FM3130_RTC_MINUTES] & 0x7f); | ||
421 | if (tmp > 60) | ||
422 | goto exit_bad; | ||
423 | |||
424 | tmp = BCD2BIN(fm3130->regs[FM3130_RTC_DATE] & 0x3f); | ||
425 | if (tmp == 0 || tmp > 31) | ||
426 | goto exit_bad; | ||
427 | |||
428 | tmp = BCD2BIN(fm3130->regs[FM3130_RTC_MONTHS] & 0x1f); | ||
429 | if (tmp == 0 || tmp > 12) | ||
430 | goto exit_bad; | ||
431 | |||
432 | tmp = fm3130->regs[FM3130_RTC_HOURS]; | ||
433 | |||
434 | fm3130->data_valid = 1; | ||
435 | |||
436 | exit_bad: | ||
437 | if (!fm3130->data_valid) | ||
438 | dev_dbg(&client->dev, | ||
439 | "%s: %02x %02x %02x %02x %02x %02x %02x %02x" | ||
440 | "%02x %02x %02x %02x %02x %02x %02x\n", | ||
441 | "bogus registers", | ||
442 | fm3130->regs[0], fm3130->regs[1], | ||
443 | fm3130->regs[2], fm3130->regs[3], | ||
444 | fm3130->regs[4], fm3130->regs[5], | ||
445 | fm3130->regs[6], fm3130->regs[7], | ||
446 | fm3130->regs[8], fm3130->regs[9], | ||
447 | fm3130->regs[0xa], fm3130->regs[0xb], | ||
448 | fm3130->regs[0xc], fm3130->regs[0xd], | ||
449 | fm3130->regs[0xe]); | ||
450 | |||
451 | /* We won't bail out here because we just got invalid data. | ||
452 | Time setting from u-boot doesn't work anyway */ | ||
453 | fm3130->rtc = rtc_device_register(client->name, &client->dev, | ||
454 | &fm3130_rtc_ops, THIS_MODULE); | ||
455 | if (IS_ERR(fm3130->rtc)) { | ||
456 | err = PTR_ERR(fm3130->rtc); | ||
457 | dev_err(&client->dev, | ||
458 | "unable to register the class device\n"); | ||
459 | goto exit_free; | ||
460 | } | ||
461 | return 0; | ||
462 | exit_free: | ||
463 | kfree(fm3130); | ||
464 | return err; | ||
465 | } | ||
466 | |||
467 | static int __devexit fm3130_remove(struct i2c_client *client) | ||
468 | { | ||
469 | struct fm3130 *fm3130 = i2c_get_clientdata(client); | ||
470 | |||
471 | rtc_device_unregister(fm3130->rtc); | ||
472 | kfree(fm3130); | ||
473 | return 0; | ||
474 | } | ||
475 | |||
476 | static struct i2c_driver fm3130_driver = { | ||
477 | .driver = { | ||
478 | .name = "rtc-fm3130", | ||
479 | .owner = THIS_MODULE, | ||
480 | }, | ||
481 | .probe = fm3130_probe, | ||
482 | .remove = __devexit_p(fm3130_remove), | ||
483 | .id_table = fm3130_id, | ||
484 | }; | ||
485 | |||
486 | static int __init fm3130_init(void) | ||
487 | { | ||
488 | return i2c_add_driver(&fm3130_driver); | ||
489 | } | ||
490 | module_init(fm3130_init); | ||
491 | |||
492 | static void __exit fm3130_exit(void) | ||
493 | { | ||
494 | i2c_del_driver(&fm3130_driver); | ||
495 | } | ||
496 | module_exit(fm3130_exit); | ||
497 | |||
498 | MODULE_DESCRIPTION("RTC driver for FM3130"); | ||
499 | MODULE_AUTHOR("Sergey Lapin <slapin@ossfans.org>"); | ||
500 | MODULE_LICENSE("GPL"); | ||
501 | |||
diff --git a/drivers/rtc/rtc-ppc.c b/drivers/rtc/rtc-ppc.c new file mode 100644 index 000000000000..c8e97e25ef7e --- /dev/null +++ b/drivers/rtc/rtc-ppc.c | |||
@@ -0,0 +1,69 @@ | |||
1 | /* | ||
2 | * RTC driver for ppc_md RTC functions | ||
3 | * | ||
4 | * © 2007 Red Hat, Inc. | ||
5 | * | ||
6 | * Author: David Woodhouse <dwmw2@infradead.org> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | |||
14 | #include <linux/module.h> | ||
15 | #include <linux/err.h> | ||
16 | #include <linux/rtc.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | #include <asm/machdep.h> | ||
19 | |||
20 | static int ppc_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
21 | { | ||
22 | ppc_md.get_rtc_time(tm); | ||
23 | return 0; | ||
24 | } | ||
25 | |||
26 | static int ppc_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
27 | { | ||
28 | return ppc_md.set_rtc_time(tm); | ||
29 | } | ||
30 | |||
31 | static const struct rtc_class_ops ppc_rtc_ops = { | ||
32 | .set_time = ppc_rtc_set_time, | ||
33 | .read_time = ppc_rtc_read_time, | ||
34 | }; | ||
35 | |||
36 | static struct rtc_device *rtc; | ||
37 | static struct platform_device *ppc_rtc_pdev; | ||
38 | |||
39 | static int __init ppc_rtc_init(void) | ||
40 | { | ||
41 | if (!ppc_md.get_rtc_time || !ppc_md.set_rtc_time) | ||
42 | return -ENODEV; | ||
43 | |||
44 | ppc_rtc_pdev = platform_device_register_simple("ppc-rtc", 0, NULL, 0); | ||
45 | if (IS_ERR(ppc_rtc_pdev)) | ||
46 | return PTR_ERR(ppc_rtc_pdev); | ||
47 | |||
48 | rtc = rtc_device_register("ppc_md", &ppc_rtc_pdev->dev, | ||
49 | &ppc_rtc_ops, THIS_MODULE); | ||
50 | if (IS_ERR(rtc)) { | ||
51 | platform_device_unregister(ppc_rtc_pdev); | ||
52 | return PTR_ERR(rtc); | ||
53 | } | ||
54 | |||
55 | return 0; | ||
56 | } | ||
57 | |||
58 | static void __exit ppc_rtc_exit(void) | ||
59 | { | ||
60 | rtc_device_unregister(rtc); | ||
61 | platform_device_unregister(ppc_rtc_pdev); | ||
62 | } | ||
63 | |||
64 | module_init(ppc_rtc_init); | ||
65 | module_exit(ppc_rtc_exit); | ||
66 | |||
67 | MODULE_LICENSE("GPL"); | ||
68 | MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>"); | ||
69 | MODULE_DESCRIPTION("Generic RTC class driver for PowerPC"); | ||
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 8ba3f135da22..1a4025683362 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c | |||
@@ -63,6 +63,7 @@ static void dasd_return_cqr_cb(struct dasd_ccw_req *, void *); | |||
63 | */ | 63 | */ |
64 | static wait_queue_head_t dasd_init_waitq; | 64 | static wait_queue_head_t dasd_init_waitq; |
65 | static wait_queue_head_t dasd_flush_wq; | 65 | static wait_queue_head_t dasd_flush_wq; |
66 | static wait_queue_head_t generic_waitq; | ||
66 | 67 | ||
67 | /* | 68 | /* |
68 | * Allocate memory for a new device structure. | 69 | * Allocate memory for a new device structure. |
@@ -1151,11 +1152,15 @@ static void __dasd_device_process_final_queue(struct dasd_device *device, | |||
1151 | struct list_head *l, *n; | 1152 | struct list_head *l, *n; |
1152 | struct dasd_ccw_req *cqr; | 1153 | struct dasd_ccw_req *cqr; |
1153 | struct dasd_block *block; | 1154 | struct dasd_block *block; |
1155 | void (*callback)(struct dasd_ccw_req *, void *data); | ||
1156 | void *callback_data; | ||
1154 | 1157 | ||
1155 | list_for_each_safe(l, n, final_queue) { | 1158 | list_for_each_safe(l, n, final_queue) { |
1156 | cqr = list_entry(l, struct dasd_ccw_req, devlist); | 1159 | cqr = list_entry(l, struct dasd_ccw_req, devlist); |
1157 | list_del_init(&cqr->devlist); | 1160 | list_del_init(&cqr->devlist); |
1158 | block = cqr->block; | 1161 | block = cqr->block; |
1162 | callback = cqr->callback; | ||
1163 | callback_data = cqr->callback_data; | ||
1159 | if (block) | 1164 | if (block) |
1160 | spin_lock_bh(&block->queue_lock); | 1165 | spin_lock_bh(&block->queue_lock); |
1161 | switch (cqr->status) { | 1166 | switch (cqr->status) { |
@@ -1176,7 +1181,7 @@ static void __dasd_device_process_final_queue(struct dasd_device *device, | |||
1176 | BUG(); | 1181 | BUG(); |
1177 | } | 1182 | } |
1178 | if (cqr->callback != NULL) | 1183 | if (cqr->callback != NULL) |
1179 | (cqr->callback)(cqr, cqr->callback_data); | 1184 | (callback)(cqr, callback_data); |
1180 | if (block) | 1185 | if (block) |
1181 | spin_unlock_bh(&block->queue_lock); | 1186 | spin_unlock_bh(&block->queue_lock); |
1182 | } | 1187 | } |
@@ -1406,17 +1411,15 @@ static inline int _wait_for_wakeup(struct dasd_ccw_req *cqr) | |||
1406 | */ | 1411 | */ |
1407 | int dasd_sleep_on(struct dasd_ccw_req *cqr) | 1412 | int dasd_sleep_on(struct dasd_ccw_req *cqr) |
1408 | { | 1413 | { |
1409 | wait_queue_head_t wait_q; | ||
1410 | struct dasd_device *device; | 1414 | struct dasd_device *device; |
1411 | int rc; | 1415 | int rc; |
1412 | 1416 | ||
1413 | device = cqr->startdev; | 1417 | device = cqr->startdev; |
1414 | 1418 | ||
1415 | init_waitqueue_head (&wait_q); | ||
1416 | cqr->callback = dasd_wakeup_cb; | 1419 | cqr->callback = dasd_wakeup_cb; |
1417 | cqr->callback_data = (void *) &wait_q; | 1420 | cqr->callback_data = (void *) &generic_waitq; |
1418 | dasd_add_request_tail(cqr); | 1421 | dasd_add_request_tail(cqr); |
1419 | wait_event(wait_q, _wait_for_wakeup(cqr)); | 1422 | wait_event(generic_waitq, _wait_for_wakeup(cqr)); |
1420 | 1423 | ||
1421 | /* Request status is either done or failed. */ | 1424 | /* Request status is either done or failed. */ |
1422 | rc = (cqr->status == DASD_CQR_DONE) ? 0 : -EIO; | 1425 | rc = (cqr->status == DASD_CQR_DONE) ? 0 : -EIO; |
@@ -1429,20 +1432,18 @@ int dasd_sleep_on(struct dasd_ccw_req *cqr) | |||
1429 | */ | 1432 | */ |
1430 | int dasd_sleep_on_interruptible(struct dasd_ccw_req *cqr) | 1433 | int dasd_sleep_on_interruptible(struct dasd_ccw_req *cqr) |
1431 | { | 1434 | { |
1432 | wait_queue_head_t wait_q; | ||
1433 | struct dasd_device *device; | 1435 | struct dasd_device *device; |
1434 | int rc; | 1436 | int rc; |
1435 | 1437 | ||
1436 | device = cqr->startdev; | 1438 | device = cqr->startdev; |
1437 | init_waitqueue_head (&wait_q); | ||
1438 | cqr->callback = dasd_wakeup_cb; | 1439 | cqr->callback = dasd_wakeup_cb; |
1439 | cqr->callback_data = (void *) &wait_q; | 1440 | cqr->callback_data = (void *) &generic_waitq; |
1440 | dasd_add_request_tail(cqr); | 1441 | dasd_add_request_tail(cqr); |
1441 | rc = wait_event_interruptible(wait_q, _wait_for_wakeup(cqr)); | 1442 | rc = wait_event_interruptible(generic_waitq, _wait_for_wakeup(cqr)); |
1442 | if (rc == -ERESTARTSYS) { | 1443 | if (rc == -ERESTARTSYS) { |
1443 | dasd_cancel_req(cqr); | 1444 | dasd_cancel_req(cqr); |
1444 | /* wait (non-interruptible) for final status */ | 1445 | /* wait (non-interruptible) for final status */ |
1445 | wait_event(wait_q, _wait_for_wakeup(cqr)); | 1446 | wait_event(generic_waitq, _wait_for_wakeup(cqr)); |
1446 | } | 1447 | } |
1447 | rc = (cqr->status == DASD_CQR_DONE) ? 0 : -EIO; | 1448 | rc = (cqr->status == DASD_CQR_DONE) ? 0 : -EIO; |
1448 | return rc; | 1449 | return rc; |
@@ -1466,7 +1467,6 @@ static inline int _dasd_term_running_cqr(struct dasd_device *device) | |||
1466 | 1467 | ||
1467 | int dasd_sleep_on_immediatly(struct dasd_ccw_req *cqr) | 1468 | int dasd_sleep_on_immediatly(struct dasd_ccw_req *cqr) |
1468 | { | 1469 | { |
1469 | wait_queue_head_t wait_q; | ||
1470 | struct dasd_device *device; | 1470 | struct dasd_device *device; |
1471 | int rc; | 1471 | int rc; |
1472 | 1472 | ||
@@ -1478,9 +1478,8 @@ int dasd_sleep_on_immediatly(struct dasd_ccw_req *cqr) | |||
1478 | return rc; | 1478 | return rc; |
1479 | } | 1479 | } |
1480 | 1480 | ||
1481 | init_waitqueue_head (&wait_q); | ||
1482 | cqr->callback = dasd_wakeup_cb; | 1481 | cqr->callback = dasd_wakeup_cb; |
1483 | cqr->callback_data = (void *) &wait_q; | 1482 | cqr->callback_data = (void *) &generic_waitq; |
1484 | cqr->status = DASD_CQR_QUEUED; | 1483 | cqr->status = DASD_CQR_QUEUED; |
1485 | list_add(&cqr->devlist, &device->ccw_queue); | 1484 | list_add(&cqr->devlist, &device->ccw_queue); |
1486 | 1485 | ||
@@ -1489,7 +1488,7 @@ int dasd_sleep_on_immediatly(struct dasd_ccw_req *cqr) | |||
1489 | 1488 | ||
1490 | spin_unlock_irq(get_ccwdev_lock(device->cdev)); | 1489 | spin_unlock_irq(get_ccwdev_lock(device->cdev)); |
1491 | 1490 | ||
1492 | wait_event(wait_q, _wait_for_wakeup(cqr)); | 1491 | wait_event(generic_waitq, _wait_for_wakeup(cqr)); |
1493 | 1492 | ||
1494 | /* Request status is either done or failed. */ | 1493 | /* Request status is either done or failed. */ |
1495 | rc = (cqr->status == DASD_CQR_DONE) ? 0 : -EIO; | 1494 | rc = (cqr->status == DASD_CQR_DONE) ? 0 : -EIO; |
@@ -2430,6 +2429,7 @@ static int __init dasd_init(void) | |||
2430 | 2429 | ||
2431 | init_waitqueue_head(&dasd_init_waitq); | 2430 | init_waitqueue_head(&dasd_init_waitq); |
2432 | init_waitqueue_head(&dasd_flush_wq); | 2431 | init_waitqueue_head(&dasd_flush_wq); |
2432 | init_waitqueue_head(&generic_waitq); | ||
2433 | 2433 | ||
2434 | /* register 'common' DASD debug area, used for all DBF_XXX calls */ | 2434 | /* register 'common' DASD debug area, used for all DBF_XXX calls */ |
2435 | dasd_debug_area = debug_register("dasd", 1, 1, 8 * sizeof(long)); | 2435 | dasd_debug_area = debug_register("dasd", 1, 1, 8 * sizeof(long)); |
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c index 0d98f1ff2edd..848ef7e8523f 100644 --- a/drivers/s390/char/raw3270.c +++ b/drivers/s390/char/raw3270.c | |||
@@ -549,7 +549,6 @@ raw3270_start_init(struct raw3270 *rp, struct raw3270_view *view, | |||
549 | struct raw3270_request *rq) | 549 | struct raw3270_request *rq) |
550 | { | 550 | { |
551 | unsigned long flags; | 551 | unsigned long flags; |
552 | wait_queue_head_t wq; | ||
553 | int rc; | 552 | int rc; |
554 | 553 | ||
555 | #ifdef CONFIG_TN3270_CONSOLE | 554 | #ifdef CONFIG_TN3270_CONSOLE |
@@ -566,20 +565,20 @@ raw3270_start_init(struct raw3270 *rp, struct raw3270_view *view, | |||
566 | return rq->rc; | 565 | return rq->rc; |
567 | } | 566 | } |
568 | #endif | 567 | #endif |
569 | init_waitqueue_head(&wq); | ||
570 | rq->callback = raw3270_wake_init; | 568 | rq->callback = raw3270_wake_init; |
571 | rq->callback_data = &wq; | 569 | rq->callback_data = &raw3270_wait_queue; |
572 | spin_lock_irqsave(get_ccwdev_lock(view->dev->cdev), flags); | 570 | spin_lock_irqsave(get_ccwdev_lock(view->dev->cdev), flags); |
573 | rc = __raw3270_start(rp, view, rq); | 571 | rc = __raw3270_start(rp, view, rq); |
574 | spin_unlock_irqrestore(get_ccwdev_lock(view->dev->cdev), flags); | 572 | spin_unlock_irqrestore(get_ccwdev_lock(view->dev->cdev), flags); |
575 | if (rc) | 573 | if (rc) |
576 | return rc; | 574 | return rc; |
577 | /* Now wait for the completion. */ | 575 | /* Now wait for the completion. */ |
578 | rc = wait_event_interruptible(wq, raw3270_request_final(rq)); | 576 | rc = wait_event_interruptible(raw3270_wait_queue, |
577 | raw3270_request_final(rq)); | ||
579 | if (rc == -ERESTARTSYS) { /* Interrupted by a signal. */ | 578 | if (rc == -ERESTARTSYS) { /* Interrupted by a signal. */ |
580 | raw3270_halt_io(view->dev, rq); | 579 | raw3270_halt_io(view->dev, rq); |
581 | /* No wait for the halt to complete. */ | 580 | /* No wait for the halt to complete. */ |
582 | wait_event(wq, raw3270_request_final(rq)); | 581 | wait_event(raw3270_wait_queue, raw3270_request_final(rq)); |
583 | return -ERESTARTSYS; | 582 | return -ERESTARTSYS; |
584 | } | 583 | } |
585 | return rq->rc; | 584 | return rq->rc; |
diff --git a/drivers/s390/char/sclp_config.c b/drivers/s390/char/sclp_config.c index 9e784d5f7f57..ad05a87bc480 100644 --- a/drivers/s390/char/sclp_config.c +++ b/drivers/s390/char/sclp_config.c | |||
@@ -40,7 +40,7 @@ static void sclp_cpu_capability_notify(struct work_struct *work) | |||
40 | put_online_cpus(); | 40 | put_online_cpus(); |
41 | } | 41 | } |
42 | 42 | ||
43 | static void sclp_cpu_change_notify(struct work_struct *work) | 43 | static void __ref sclp_cpu_change_notify(struct work_struct *work) |
44 | { | 44 | { |
45 | smp_rescan_cpus(); | 45 | smp_rescan_cpus(); |
46 | } | 46 | } |
diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c index 35707c04e613..3e577f655b18 100644 --- a/drivers/s390/char/sclp_vt220.c +++ b/drivers/s390/char/sclp_vt220.c | |||
@@ -71,9 +71,6 @@ static struct list_head sclp_vt220_outqueue; | |||
71 | /* Number of requests in outqueue */ | 71 | /* Number of requests in outqueue */ |
72 | static int sclp_vt220_outqueue_count; | 72 | static int sclp_vt220_outqueue_count; |
73 | 73 | ||
74 | /* Wait queue used to delay write requests while we've run out of buffers */ | ||
75 | static wait_queue_head_t sclp_vt220_waitq; | ||
76 | |||
77 | /* Timer used for delaying write requests to merge subsequent messages into | 74 | /* Timer used for delaying write requests to merge subsequent messages into |
78 | * a single buffer */ | 75 | * a single buffer */ |
79 | static struct timer_list sclp_vt220_timer; | 76 | static struct timer_list sclp_vt220_timer; |
@@ -133,7 +130,6 @@ sclp_vt220_process_queue(struct sclp_vt220_request *request) | |||
133 | } while (request && __sclp_vt220_emit(request)); | 130 | } while (request && __sclp_vt220_emit(request)); |
134 | if (request == NULL && sclp_vt220_flush_later) | 131 | if (request == NULL && sclp_vt220_flush_later) |
135 | sclp_vt220_emit_current(); | 132 | sclp_vt220_emit_current(); |
136 | wake_up(&sclp_vt220_waitq); | ||
137 | /* Check if the tty needs a wake up call */ | 133 | /* Check if the tty needs a wake up call */ |
138 | if (sclp_vt220_tty != NULL) { | 134 | if (sclp_vt220_tty != NULL) { |
139 | tty_wakeup(sclp_vt220_tty); | 135 | tty_wakeup(sclp_vt220_tty); |
@@ -383,7 +379,7 @@ sclp_vt220_timeout(unsigned long data) | |||
383 | */ | 379 | */ |
384 | static int | 380 | static int |
385 | __sclp_vt220_write(const unsigned char *buf, int count, int do_schedule, | 381 | __sclp_vt220_write(const unsigned char *buf, int count, int do_schedule, |
386 | int convertlf, int may_schedule) | 382 | int convertlf, int may_fail) |
387 | { | 383 | { |
388 | unsigned long flags; | 384 | unsigned long flags; |
389 | void *page; | 385 | void *page; |
@@ -395,15 +391,14 @@ __sclp_vt220_write(const unsigned char *buf, int count, int do_schedule, | |||
395 | overall_written = 0; | 391 | overall_written = 0; |
396 | spin_lock_irqsave(&sclp_vt220_lock, flags); | 392 | spin_lock_irqsave(&sclp_vt220_lock, flags); |
397 | do { | 393 | do { |
398 | /* Create a sclp output buffer if none exists yet */ | 394 | /* Create an sclp output buffer if none exists yet */ |
399 | if (sclp_vt220_current_request == NULL) { | 395 | if (sclp_vt220_current_request == NULL) { |
400 | while (list_empty(&sclp_vt220_empty)) { | 396 | while (list_empty(&sclp_vt220_empty)) { |
401 | spin_unlock_irqrestore(&sclp_vt220_lock, flags); | 397 | spin_unlock_irqrestore(&sclp_vt220_lock, flags); |
402 | if (in_interrupt() || !may_schedule) | 398 | if (may_fail) |
403 | sclp_sync_wait(); | 399 | goto out; |
404 | else | 400 | else |
405 | wait_event(sclp_vt220_waitq, | 401 | sclp_sync_wait(); |
406 | !list_empty(&sclp_vt220_empty)); | ||
407 | spin_lock_irqsave(&sclp_vt220_lock, flags); | 402 | spin_lock_irqsave(&sclp_vt220_lock, flags); |
408 | } | 403 | } |
409 | page = (void *) sclp_vt220_empty.next; | 404 | page = (void *) sclp_vt220_empty.next; |
@@ -437,6 +432,7 @@ __sclp_vt220_write(const unsigned char *buf, int count, int do_schedule, | |||
437 | add_timer(&sclp_vt220_timer); | 432 | add_timer(&sclp_vt220_timer); |
438 | } | 433 | } |
439 | spin_unlock_irqrestore(&sclp_vt220_lock, flags); | 434 | spin_unlock_irqrestore(&sclp_vt220_lock, flags); |
435 | out: | ||
440 | return overall_written; | 436 | return overall_written; |
441 | } | 437 | } |
442 | 438 | ||
@@ -520,19 +516,11 @@ sclp_vt220_close(struct tty_struct *tty, struct file *filp) | |||
520 | * character to the tty device. If the kernel uses this routine, | 516 | * character to the tty device. If the kernel uses this routine, |
521 | * it must call the flush_chars() routine (if defined) when it is | 517 | * it must call the flush_chars() routine (if defined) when it is |
522 | * done stuffing characters into the driver. | 518 | * done stuffing characters into the driver. |
523 | * | ||
524 | * NOTE: include/linux/tty_driver.h specifies that a character should be | ||
525 | * ignored if there is no room in the queue. This driver implements a different | ||
526 | * semantic in that it will block when there is no more room left. | ||
527 | * | ||
528 | * FIXME: putchar can currently be called from BH and other non blocking | ||
529 | * handlers so this semantic isn't a good idea. | ||
530 | */ | 519 | */ |
531 | static int | 520 | static int |
532 | sclp_vt220_put_char(struct tty_struct *tty, unsigned char ch) | 521 | sclp_vt220_put_char(struct tty_struct *tty, unsigned char ch) |
533 | { | 522 | { |
534 | __sclp_vt220_write(&ch, 1, 0, 0, 1); | 523 | return __sclp_vt220_write(&ch, 1, 0, 0, 1); |
535 | return 1; | ||
536 | } | 524 | } |
537 | 525 | ||
538 | /* | 526 | /* |
@@ -653,7 +641,6 @@ static int __init __sclp_vt220_init(void) | |||
653 | spin_lock_init(&sclp_vt220_lock); | 641 | spin_lock_init(&sclp_vt220_lock); |
654 | INIT_LIST_HEAD(&sclp_vt220_empty); | 642 | INIT_LIST_HEAD(&sclp_vt220_empty); |
655 | INIT_LIST_HEAD(&sclp_vt220_outqueue); | 643 | INIT_LIST_HEAD(&sclp_vt220_outqueue); |
656 | init_waitqueue_head(&sclp_vt220_waitq); | ||
657 | init_timer(&sclp_vt220_timer); | 644 | init_timer(&sclp_vt220_timer); |
658 | sclp_vt220_current_request = NULL; | 645 | sclp_vt220_current_request = NULL; |
659 | sclp_vt220_buffered_chars = 0; | 646 | sclp_vt220_buffered_chars = 0; |
@@ -786,6 +773,7 @@ sclp_vt220_con_init(void) | |||
786 | { | 773 | { |
787 | int rc; | 774 | int rc; |
788 | 775 | ||
776 | INIT_LIST_HEAD(&sclp_vt220_register.list); | ||
789 | if (!CONSOLE_IS_SCLP) | 777 | if (!CONSOLE_IS_SCLP) |
790 | return 0; | 778 | return 0; |
791 | rc = __sclp_vt220_init(); | 779 | rc = __sclp_vt220_init(); |
diff --git a/drivers/s390/char/tape.h b/drivers/s390/char/tape.h index dddf8d62c153..d0d565a05dfe 100644 --- a/drivers/s390/char/tape.h +++ b/drivers/s390/char/tape.h | |||
@@ -231,6 +231,9 @@ struct tape_device { | |||
231 | /* Request queue. */ | 231 | /* Request queue. */ |
232 | struct list_head req_queue; | 232 | struct list_head req_queue; |
233 | 233 | ||
234 | /* Request wait queue. */ | ||
235 | wait_queue_head_t wait_queue; | ||
236 | |||
234 | /* Each tape device has (currently) two minor numbers. */ | 237 | /* Each tape device has (currently) two minor numbers. */ |
235 | int first_minor; | 238 | int first_minor; |
236 | 239 | ||
diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c index 8246ef3ab095..42ce7915fc5d 100644 --- a/drivers/s390/char/tape_3590.c +++ b/drivers/s390/char/tape_3590.c | |||
@@ -1598,7 +1598,7 @@ tape_3590_setup_device(struct tape_device *device) | |||
1598 | rc = tape_3590_read_dev_chars(device, rdc_data); | 1598 | rc = tape_3590_read_dev_chars(device, rdc_data); |
1599 | if (rc) { | 1599 | if (rc) { |
1600 | DBF_LH(3, "Read device characteristics failed!\n"); | 1600 | DBF_LH(3, "Read device characteristics failed!\n"); |
1601 | goto fail_kmalloc; | 1601 | goto fail_rdc_data; |
1602 | } | 1602 | } |
1603 | rc = tape_std_assign(device); | 1603 | rc = tape_std_assign(device); |
1604 | if (rc) | 1604 | if (rc) |
diff --git a/drivers/s390/char/tape_block.c b/drivers/s390/char/tape_block.c index ddc4a114e7f4..95da72bc17e8 100644 --- a/drivers/s390/char/tape_block.c +++ b/drivers/s390/char/tape_block.c | |||
@@ -179,11 +179,11 @@ tapeblock_requeue(struct work_struct *work) { | |||
179 | tapeblock_end_request(req, -EIO); | 179 | tapeblock_end_request(req, -EIO); |
180 | continue; | 180 | continue; |
181 | } | 181 | } |
182 | blkdev_dequeue_request(req); | ||
183 | nr_queued++; | ||
182 | spin_unlock_irq(&device->blk_data.request_queue_lock); | 184 | spin_unlock_irq(&device->blk_data.request_queue_lock); |
183 | rc = tapeblock_start_request(device, req); | 185 | rc = tapeblock_start_request(device, req); |
184 | spin_lock_irq(&device->blk_data.request_queue_lock); | 186 | spin_lock_irq(&device->blk_data.request_queue_lock); |
185 | blkdev_dequeue_request(req); | ||
186 | nr_queued++; | ||
187 | } | 187 | } |
188 | spin_unlock_irq(&device->blk_data.request_queue_lock); | 188 | spin_unlock_irq(&device->blk_data.request_queue_lock); |
189 | atomic_set(&device->blk_data.requeue_scheduled, 0); | 189 | atomic_set(&device->blk_data.requeue_scheduled, 0); |
diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c index 76e44eb7c47f..c20e3c548343 100644 --- a/drivers/s390/char/tape_core.c +++ b/drivers/s390/char/tape_core.c | |||
@@ -449,6 +449,7 @@ tape_alloc_device(void) | |||
449 | INIT_LIST_HEAD(&device->req_queue); | 449 | INIT_LIST_HEAD(&device->req_queue); |
450 | INIT_LIST_HEAD(&device->node); | 450 | INIT_LIST_HEAD(&device->node); |
451 | init_waitqueue_head(&device->state_change_wq); | 451 | init_waitqueue_head(&device->state_change_wq); |
452 | init_waitqueue_head(&device->wait_queue); | ||
452 | device->tape_state = TS_INIT; | 453 | device->tape_state = TS_INIT; |
453 | device->medium_state = MS_UNKNOWN; | 454 | device->medium_state = MS_UNKNOWN; |
454 | *device->modeset_byte = 0; | 455 | *device->modeset_byte = 0; |
@@ -954,21 +955,19 @@ __tape_wake_up(struct tape_request *request, void *data) | |||
954 | int | 955 | int |
955 | tape_do_io(struct tape_device *device, struct tape_request *request) | 956 | tape_do_io(struct tape_device *device, struct tape_request *request) |
956 | { | 957 | { |
957 | wait_queue_head_t wq; | ||
958 | int rc; | 958 | int rc; |
959 | 959 | ||
960 | init_waitqueue_head(&wq); | ||
961 | spin_lock_irq(get_ccwdev_lock(device->cdev)); | 960 | spin_lock_irq(get_ccwdev_lock(device->cdev)); |
962 | /* Setup callback */ | 961 | /* Setup callback */ |
963 | request->callback = __tape_wake_up; | 962 | request->callback = __tape_wake_up; |
964 | request->callback_data = &wq; | 963 | request->callback_data = &device->wait_queue; |
965 | /* Add request to request queue and try to start it. */ | 964 | /* Add request to request queue and try to start it. */ |
966 | rc = __tape_start_request(device, request); | 965 | rc = __tape_start_request(device, request); |
967 | spin_unlock_irq(get_ccwdev_lock(device->cdev)); | 966 | spin_unlock_irq(get_ccwdev_lock(device->cdev)); |
968 | if (rc) | 967 | if (rc) |
969 | return rc; | 968 | return rc; |
970 | /* Request added to the queue. Wait for its completion. */ | 969 | /* Request added to the queue. Wait for its completion. */ |
971 | wait_event(wq, (request->callback == NULL)); | 970 | wait_event(device->wait_queue, (request->callback == NULL)); |
972 | /* Get rc from request */ | 971 | /* Get rc from request */ |
973 | return request->rc; | 972 | return request->rc; |
974 | } | 973 | } |
@@ -989,20 +988,19 @@ int | |||
989 | tape_do_io_interruptible(struct tape_device *device, | 988 | tape_do_io_interruptible(struct tape_device *device, |
990 | struct tape_request *request) | 989 | struct tape_request *request) |
991 | { | 990 | { |
992 | wait_queue_head_t wq; | ||
993 | int rc; | 991 | int rc; |
994 | 992 | ||
995 | init_waitqueue_head(&wq); | ||
996 | spin_lock_irq(get_ccwdev_lock(device->cdev)); | 993 | spin_lock_irq(get_ccwdev_lock(device->cdev)); |
997 | /* Setup callback */ | 994 | /* Setup callback */ |
998 | request->callback = __tape_wake_up_interruptible; | 995 | request->callback = __tape_wake_up_interruptible; |
999 | request->callback_data = &wq; | 996 | request->callback_data = &device->wait_queue; |
1000 | rc = __tape_start_request(device, request); | 997 | rc = __tape_start_request(device, request); |
1001 | spin_unlock_irq(get_ccwdev_lock(device->cdev)); | 998 | spin_unlock_irq(get_ccwdev_lock(device->cdev)); |
1002 | if (rc) | 999 | if (rc) |
1003 | return rc; | 1000 | return rc; |
1004 | /* Request added to the queue. Wait for its completion. */ | 1001 | /* Request added to the queue. Wait for its completion. */ |
1005 | rc = wait_event_interruptible(wq, (request->callback == NULL)); | 1002 | rc = wait_event_interruptible(device->wait_queue, |
1003 | (request->callback == NULL)); | ||
1006 | if (rc != -ERESTARTSYS) | 1004 | if (rc != -ERESTARTSYS) |
1007 | /* Request finished normally. */ | 1005 | /* Request finished normally. */ |
1008 | return request->rc; | 1006 | return request->rc; |
@@ -1015,7 +1013,7 @@ tape_do_io_interruptible(struct tape_device *device, | |||
1015 | /* Wait for the interrupt that acknowledges the halt. */ | 1013 | /* Wait for the interrupt that acknowledges the halt. */ |
1016 | do { | 1014 | do { |
1017 | rc = wait_event_interruptible( | 1015 | rc = wait_event_interruptible( |
1018 | wq, | 1016 | device->wait_queue, |
1019 | (request->callback == NULL) | 1017 | (request->callback == NULL) |
1020 | ); | 1018 | ); |
1021 | } while (rc == -ERESTARTSYS); | 1019 | } while (rc == -ERESTARTSYS); |
diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c index e8487347e4d4..2c2428cc05d8 100644 --- a/drivers/s390/char/vmlogrdr.c +++ b/drivers/s390/char/vmlogrdr.c | |||
@@ -762,10 +762,10 @@ static int vmlogrdr_register_device(struct vmlogrdr_priv_t *priv) | |||
762 | device_unregister(dev); | 762 | device_unregister(dev); |
763 | return ret; | 763 | return ret; |
764 | } | 764 | } |
765 | priv->class_device = device_create(vmlogrdr_class, dev, | 765 | priv->class_device = device_create_drvdata(vmlogrdr_class, dev, |
766 | MKDEV(vmlogrdr_major, | 766 | MKDEV(vmlogrdr_major, |
767 | priv->minor_num), | 767 | priv->minor_num), |
768 | "%s", dev->bus_id); | 768 | priv, "%s", dev->bus_id); |
769 | if (IS_ERR(priv->class_device)) { | 769 | if (IS_ERR(priv->class_device)) { |
770 | ret = PTR_ERR(priv->class_device); | 770 | ret = PTR_ERR(priv->class_device); |
771 | priv->class_device=NULL; | 771 | priv->class_device=NULL; |
@@ -773,7 +773,6 @@ static int vmlogrdr_register_device(struct vmlogrdr_priv_t *priv) | |||
773 | device_unregister(dev); | 773 | device_unregister(dev); |
774 | return ret; | 774 | return ret; |
775 | } | 775 | } |
776 | dev->driver_data = priv; | ||
777 | priv->device = dev; | 776 | priv->device = dev; |
778 | return 0; | 777 | return 0; |
779 | } | 778 | } |
diff --git a/drivers/s390/cio/blacklist.c b/drivers/s390/cio/blacklist.c index a4a5f2efea48..0bfcbbe375c4 100644 --- a/drivers/s390/cio/blacklist.c +++ b/drivers/s390/cio/blacklist.c | |||
@@ -97,8 +97,8 @@ static int pure_hex(char **cp, unsigned int *val, int min_digit, | |||
97 | return 0; | 97 | return 0; |
98 | } | 98 | } |
99 | 99 | ||
100 | static int parse_busid(char *str, int *cssid, int *ssid, int *devno, | 100 | static int parse_busid(char *str, unsigned int *cssid, unsigned int *ssid, |
101 | int msgtrigger) | 101 | unsigned int *devno, int msgtrigger) |
102 | { | 102 | { |
103 | char *str_work; | 103 | char *str_work; |
104 | int val, rc, ret; | 104 | int val, rc, ret; |
@@ -148,7 +148,7 @@ out: | |||
148 | static int blacklist_parse_parameters(char *str, range_action action, | 148 | static int blacklist_parse_parameters(char *str, range_action action, |
149 | int msgtrigger) | 149 | int msgtrigger) |
150 | { | 150 | { |
151 | int from_cssid, to_cssid, from_ssid, to_ssid, from, to; | 151 | unsigned int from_cssid, to_cssid, from_ssid, to_ssid, from, to; |
152 | int rc, totalrc; | 152 | int rc, totalrc; |
153 | char *parm; | 153 | char *parm; |
154 | range_action ra; | 154 | range_action ra; |
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index 82c6a2d45128..b32d7eb3d81a 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c | |||
@@ -576,12 +576,14 @@ cio_validate_subchannel (struct subchannel *sch, struct subchannel_id schid) | |||
576 | err = -ENODEV; | 576 | err = -ENODEV; |
577 | goto out; | 577 | goto out; |
578 | } | 578 | } |
579 | if (cio_is_console(sch->schid)) | 579 | if (cio_is_console(sch->schid)) { |
580 | sch->opm = 0xff; | 580 | sch->opm = 0xff; |
581 | else | 581 | sch->isc = 1; |
582 | } else { | ||
582 | sch->opm = chp_get_sch_opm(sch); | 583 | sch->opm = chp_get_sch_opm(sch); |
584 | sch->isc = 3; | ||
585 | } | ||
583 | sch->lpm = sch->schib.pmcw.pam & sch->opm; | 586 | sch->lpm = sch->schib.pmcw.pam & sch->opm; |
584 | sch->isc = 3; | ||
585 | 587 | ||
586 | CIO_MSG_EVENT(6, "Detected device %04x on subchannel 0.%x.%04X " | 588 | CIO_MSG_EVENT(6, "Detected device %04x on subchannel 0.%x.%04X " |
587 | "- PIM = %02X, PAM = %02X, POM = %02X\n", | 589 | "- PIM = %02X, PAM = %02X, POM = %02X\n", |
@@ -704,9 +706,9 @@ void wait_cons_dev(void) | |||
704 | if (!console_subchannel_in_use) | 706 | if (!console_subchannel_in_use) |
705 | return; | 707 | return; |
706 | 708 | ||
707 | /* disable all but isc 7 (console device) */ | 709 | /* disable all but isc 1 (console device) */ |
708 | __ctl_store (save_cr6, 6, 6); | 710 | __ctl_store (save_cr6, 6, 6); |
709 | cr6 = 0x01000000; | 711 | cr6 = 0x40000000; |
710 | __ctl_load (cr6, 6, 6); | 712 | __ctl_load (cr6, 6, 6); |
711 | 713 | ||
712 | do { | 714 | do { |
@@ -788,11 +790,11 @@ cio_probe_console(void) | |||
788 | } | 790 | } |
789 | 791 | ||
790 | /* | 792 | /* |
791 | * enable console I/O-interrupt subclass 7 | 793 | * enable console I/O-interrupt subclass 1 |
792 | */ | 794 | */ |
793 | ctl_set_bit(6, 24); | 795 | ctl_set_bit(6, 30); |
794 | console_subchannel.isc = 7; | 796 | console_subchannel.isc = 1; |
795 | console_subchannel.schib.pmcw.isc = 7; | 797 | console_subchannel.schib.pmcw.isc = 1; |
796 | console_subchannel.schib.pmcw.intparm = | 798 | console_subchannel.schib.pmcw.intparm = |
797 | (u32)(addr_t)&console_subchannel; | 799 | (u32)(addr_t)&console_subchannel; |
798 | ret = cio_modify(&console_subchannel); | 800 | ret = cio_modify(&console_subchannel); |
diff --git a/drivers/s390/kvm/kvm_virtio.c b/drivers/s390/kvm/kvm_virtio.c index 47a7e6200b26..5ab34340919b 100644 --- a/drivers/s390/kvm/kvm_virtio.c +++ b/drivers/s390/kvm/kvm_virtio.c | |||
@@ -31,11 +31,6 @@ | |||
31 | */ | 31 | */ |
32 | static void *kvm_devices; | 32 | static void *kvm_devices; |
33 | 33 | ||
34 | /* | ||
35 | * Unique numbering for kvm devices. | ||
36 | */ | ||
37 | static unsigned int dev_index; | ||
38 | |||
39 | struct kvm_device { | 34 | struct kvm_device { |
40 | struct virtio_device vdev; | 35 | struct virtio_device vdev; |
41 | struct kvm_device_desc *desc; | 36 | struct kvm_device_desc *desc; |
@@ -78,27 +73,32 @@ static unsigned desc_size(const struct kvm_device_desc *desc) | |||
78 | + desc->config_len; | 73 | + desc->config_len; |
79 | } | 74 | } |
80 | 75 | ||
81 | /* | 76 | /* This gets the device's feature bits. */ |
82 | * This tests (and acknowleges) a feature bit. | 77 | static u32 kvm_get_features(struct virtio_device *vdev) |
83 | */ | ||
84 | static bool kvm_feature(struct virtio_device *vdev, unsigned fbit) | ||
85 | { | 78 | { |
79 | unsigned int i; | ||
80 | u32 features = 0; | ||
86 | struct kvm_device_desc *desc = to_kvmdev(vdev)->desc; | 81 | struct kvm_device_desc *desc = to_kvmdev(vdev)->desc; |
87 | u8 *features; | 82 | u8 *in_features = kvm_vq_features(desc); |
88 | 83 | ||
89 | if (fbit / 8 > desc->feature_len) | 84 | for (i = 0; i < min(desc->feature_len * 8, 32); i++) |
90 | return false; | 85 | if (in_features[i / 8] & (1 << (i % 8))) |
86 | features |= (1 << i); | ||
87 | return features; | ||
88 | } | ||
91 | 89 | ||
92 | features = kvm_vq_features(desc); | 90 | static void kvm_set_features(struct virtio_device *vdev, u32 features) |
93 | if (!(features[fbit / 8] & (1 << (fbit % 8)))) | 91 | { |
94 | return false; | 92 | unsigned int i; |
93 | struct kvm_device_desc *desc = to_kvmdev(vdev)->desc; | ||
94 | /* Second half of bitmap is features we accept. */ | ||
95 | u8 *out_features = kvm_vq_features(desc) + desc->feature_len; | ||
95 | 96 | ||
96 | /* | 97 | memset(out_features, 0, desc->feature_len); |
97 | * We set the matching bit in the other half of the bitmap to tell the | 98 | for (i = 0; i < min(desc->feature_len * 8, 32); i++) { |
98 | * Host we want to use this feature. | 99 | if (features & (1 << i)) |
99 | */ | 100 | out_features[i / 8] |= (1 << (i % 8)); |
100 | features[desc->feature_len + fbit / 8] |= (1 << (fbit % 8)); | 101 | } |
101 | return true; | ||
102 | } | 102 | } |
103 | 103 | ||
104 | /* | 104 | /* |
@@ -221,7 +221,8 @@ static void kvm_del_vq(struct virtqueue *vq) | |||
221 | * The config ops structure as defined by virtio config | 221 | * The config ops structure as defined by virtio config |
222 | */ | 222 | */ |
223 | static struct virtio_config_ops kvm_vq_configspace_ops = { | 223 | static struct virtio_config_ops kvm_vq_configspace_ops = { |
224 | .feature = kvm_feature, | 224 | .get_features = kvm_get_features, |
225 | .set_features = kvm_set_features, | ||
225 | .get = kvm_get, | 226 | .get = kvm_get, |
226 | .set = kvm_set, | 227 | .set = kvm_set, |
227 | .get_status = kvm_get_status, | 228 | .get_status = kvm_get_status, |
@@ -244,26 +245,25 @@ static struct device kvm_root = { | |||
244 | * adds a new device and register it with virtio | 245 | * adds a new device and register it with virtio |
245 | * appropriate drivers are loaded by the device model | 246 | * appropriate drivers are loaded by the device model |
246 | */ | 247 | */ |
247 | static void add_kvm_device(struct kvm_device_desc *d) | 248 | static void add_kvm_device(struct kvm_device_desc *d, unsigned int offset) |
248 | { | 249 | { |
249 | struct kvm_device *kdev; | 250 | struct kvm_device *kdev; |
250 | 251 | ||
251 | kdev = kzalloc(sizeof(*kdev), GFP_KERNEL); | 252 | kdev = kzalloc(sizeof(*kdev), GFP_KERNEL); |
252 | if (!kdev) { | 253 | if (!kdev) { |
253 | printk(KERN_EMERG "Cannot allocate kvm dev %u\n", | 254 | printk(KERN_EMERG "Cannot allocate kvm dev %u type %u\n", |
254 | dev_index++); | 255 | offset, d->type); |
255 | return; | 256 | return; |
256 | } | 257 | } |
257 | 258 | ||
258 | kdev->vdev.dev.parent = &kvm_root; | 259 | kdev->vdev.dev.parent = &kvm_root; |
259 | kdev->vdev.index = dev_index++; | ||
260 | kdev->vdev.id.device = d->type; | 260 | kdev->vdev.id.device = d->type; |
261 | kdev->vdev.config = &kvm_vq_configspace_ops; | 261 | kdev->vdev.config = &kvm_vq_configspace_ops; |
262 | kdev->desc = d; | 262 | kdev->desc = d; |
263 | 263 | ||
264 | if (register_virtio_device(&kdev->vdev) != 0) { | 264 | if (register_virtio_device(&kdev->vdev) != 0) { |
265 | printk(KERN_ERR "Failed to register kvm device %u\n", | 265 | printk(KERN_ERR "Failed to register kvm device %u type %u\n", |
266 | kdev->vdev.index); | 266 | offset, d->type); |
267 | kfree(kdev); | 267 | kfree(kdev); |
268 | } | 268 | } |
269 | } | 269 | } |
@@ -283,7 +283,7 @@ static void scan_devices(void) | |||
283 | if (d->type == 0) | 283 | if (d->type == 0) |
284 | break; | 284 | break; |
285 | 285 | ||
286 | add_kvm_device(d); | 286 | add_kvm_device(d, i); |
287 | } | 287 | } |
288 | } | 288 | } |
289 | 289 | ||
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 436bf1f6d4a6..9a71dae223e8 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c | |||
@@ -290,9 +290,6 @@ int qeth_set_large_send(struct qeth_card *card, | |||
290 | card->dev->features |= NETIF_F_TSO | NETIF_F_SG | | 290 | card->dev->features |= NETIF_F_TSO | NETIF_F_SG | |
291 | NETIF_F_HW_CSUM; | 291 | NETIF_F_HW_CSUM; |
292 | } else { | 292 | } else { |
293 | PRINT_WARN("TSO not supported on %s. " | ||
294 | "large_send set to 'no'.\n", | ||
295 | card->dev->name); | ||
296 | card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG | | 293 | card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG | |
297 | NETIF_F_HW_CSUM); | 294 | NETIF_F_HW_CSUM); |
298 | card->options.large_send = QETH_LARGE_SEND_NO; | 295 | card->options.large_send = QETH_LARGE_SEND_NO; |
@@ -1407,12 +1404,6 @@ static void qeth_init_func_level(struct qeth_card *card) | |||
1407 | } | 1404 | } |
1408 | } | 1405 | } |
1409 | 1406 | ||
1410 | static inline __u16 qeth_raw_devno_from_bus_id(char *id) | ||
1411 | { | ||
1412 | id += (strlen(id) - 4); | ||
1413 | return (__u16) simple_strtoul(id, &id, 16); | ||
1414 | } | ||
1415 | |||
1416 | static int qeth_idx_activate_get_answer(struct qeth_channel *channel, | 1407 | static int qeth_idx_activate_get_answer(struct qeth_channel *channel, |
1417 | void (*idx_reply_cb)(struct qeth_channel *, | 1408 | void (*idx_reply_cb)(struct qeth_channel *, |
1418 | struct qeth_cmd_buffer *)) | 1409 | struct qeth_cmd_buffer *)) |
@@ -1439,7 +1430,7 @@ static int qeth_idx_activate_get_answer(struct qeth_channel *channel, | |||
1439 | spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags); | 1430 | spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags); |
1440 | 1431 | ||
1441 | if (rc) { | 1432 | if (rc) { |
1442 | PRINT_ERR("Error2 in activating channel rc=%d\n", rc); | 1433 | QETH_DBF_MESSAGE(2, "Error2 in activating channel rc=%d\n", rc); |
1443 | QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc); | 1434 | QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc); |
1444 | atomic_set(&channel->irq_pending, 0); | 1435 | atomic_set(&channel->irq_pending, 0); |
1445 | wake_up(&card->wait_q); | 1436 | wake_up(&card->wait_q); |
@@ -1468,6 +1459,7 @@ static int qeth_idx_activate_channel(struct qeth_channel *channel, | |||
1468 | __u16 temp; | 1459 | __u16 temp; |
1469 | __u8 tmp; | 1460 | __u8 tmp; |
1470 | int rc; | 1461 | int rc; |
1462 | struct ccw_dev_id temp_devid; | ||
1471 | 1463 | ||
1472 | card = CARD_FROM_CDEV(channel->ccwdev); | 1464 | card = CARD_FROM_CDEV(channel->ccwdev); |
1473 | 1465 | ||
@@ -1494,8 +1486,8 @@ static int qeth_idx_activate_channel(struct qeth_channel *channel, | |||
1494 | &card->token.issuer_rm_w, QETH_MPC_TOKEN_LENGTH); | 1486 | &card->token.issuer_rm_w, QETH_MPC_TOKEN_LENGTH); |
1495 | memcpy(QETH_IDX_ACT_FUNC_LEVEL(iob->data), | 1487 | memcpy(QETH_IDX_ACT_FUNC_LEVEL(iob->data), |
1496 | &card->info.func_level, sizeof(__u16)); | 1488 | &card->info.func_level, sizeof(__u16)); |
1497 | temp = qeth_raw_devno_from_bus_id(CARD_DDEV_ID(card)); | 1489 | ccw_device_get_id(CARD_DDEV(card), &temp_devid); |
1498 | memcpy(QETH_IDX_ACT_QDIO_DEV_CUA(iob->data), &temp, 2); | 1490 | memcpy(QETH_IDX_ACT_QDIO_DEV_CUA(iob->data), &temp_devid.devno, 2); |
1499 | temp = (card->info.cula << 8) + card->info.unit_addr2; | 1491 | temp = (card->info.cula << 8) + card->info.unit_addr2; |
1500 | memcpy(QETH_IDX_ACT_QDIO_DEV_REALADDR(iob->data), &temp, 2); | 1492 | memcpy(QETH_IDX_ACT_QDIO_DEV_REALADDR(iob->data), &temp, 2); |
1501 | 1493 | ||
@@ -1508,7 +1500,8 @@ static int qeth_idx_activate_channel(struct qeth_channel *channel, | |||
1508 | spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags); | 1500 | spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags); |
1509 | 1501 | ||
1510 | if (rc) { | 1502 | if (rc) { |
1511 | PRINT_ERR("Error1 in activating channel. rc=%d\n", rc); | 1503 | QETH_DBF_MESSAGE(2, "Error1 in activating channel. rc=%d\n", |
1504 | rc); | ||
1512 | QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc); | 1505 | QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc); |
1513 | atomic_set(&channel->irq_pending, 0); | 1506 | atomic_set(&channel->irq_pending, 0); |
1514 | wake_up(&card->wait_q); | 1507 | wake_up(&card->wait_q); |
@@ -1658,7 +1651,6 @@ int qeth_send_control_data(struct qeth_card *card, int len, | |||
1658 | 1651 | ||
1659 | reply = qeth_alloc_reply(card); | 1652 | reply = qeth_alloc_reply(card); |
1660 | if (!reply) { | 1653 | if (!reply) { |
1661 | PRINT_WARN("Could not alloc qeth_reply!\n"); | ||
1662 | return -ENOMEM; | 1654 | return -ENOMEM; |
1663 | } | 1655 | } |
1664 | reply->callback = reply_cb; | 1656 | reply->callback = reply_cb; |
@@ -2612,15 +2604,9 @@ void qeth_queue_input_buffer(struct qeth_card *card, int index) | |||
2612 | if (newcount < count) { | 2604 | if (newcount < count) { |
2613 | /* we are in memory shortage so we switch back to | 2605 | /* we are in memory shortage so we switch back to |
2614 | traditional skb allocation and drop packages */ | 2606 | traditional skb allocation and drop packages */ |
2615 | if (!atomic_read(&card->force_alloc_skb) && | ||
2616 | net_ratelimit()) | ||
2617 | PRINT_WARN("Switch to alloc skb\n"); | ||
2618 | atomic_set(&card->force_alloc_skb, 3); | 2607 | atomic_set(&card->force_alloc_skb, 3); |
2619 | count = newcount; | 2608 | count = newcount; |
2620 | } else { | 2609 | } else { |
2621 | if ((atomic_read(&card->force_alloc_skb) == 1) && | ||
2622 | net_ratelimit()) | ||
2623 | PRINT_WARN("Switch to sg\n"); | ||
2624 | atomic_add_unless(&card->force_alloc_skb, -1, 0); | 2610 | atomic_add_unless(&card->force_alloc_skb, -1, 0); |
2625 | } | 2611 | } |
2626 | 2612 | ||
@@ -3034,7 +3020,7 @@ int qeth_get_elements_no(struct qeth_card *card, void *hdr, | |||
3034 | elements_needed = 1 + (((((unsigned long) hdr) % PAGE_SIZE) | 3020 | elements_needed = 1 + (((((unsigned long) hdr) % PAGE_SIZE) |
3035 | + skb->len) >> PAGE_SHIFT); | 3021 | + skb->len) >> PAGE_SHIFT); |
3036 | if ((elements_needed + elems) > QETH_MAX_BUFFER_ELEMENTS(card)) { | 3022 | if ((elements_needed + elems) > QETH_MAX_BUFFER_ELEMENTS(card)) { |
3037 | PRINT_ERR("Invalid size of IP packet " | 3023 | QETH_DBF_MESSAGE(2, "Invalid size of IP packet " |
3038 | "(Number=%d / Length=%d). Discarded.\n", | 3024 | "(Number=%d / Length=%d). Discarded.\n", |
3039 | (elements_needed+elems), skb->len); | 3025 | (elements_needed+elems), skb->len); |
3040 | return 0; | 3026 | return 0; |
@@ -3247,8 +3233,6 @@ int qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue, | |||
3247 | * free buffers) to handle eddp context */ | 3233 | * free buffers) to handle eddp context */ |
3248 | if (qeth_eddp_check_buffers_for_context(queue, ctx) | 3234 | if (qeth_eddp_check_buffers_for_context(queue, ctx) |
3249 | < 0) { | 3235 | < 0) { |
3250 | if (net_ratelimit()) | ||
3251 | PRINT_WARN("eddp tx_dropped 1\n"); | ||
3252 | rc = -EBUSY; | 3236 | rc = -EBUSY; |
3253 | goto out; | 3237 | goto out; |
3254 | } | 3238 | } |
@@ -3260,7 +3244,6 @@ int qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue, | |||
3260 | tmp = qeth_eddp_fill_buffer(queue, ctx, | 3244 | tmp = qeth_eddp_fill_buffer(queue, ctx, |
3261 | queue->next_buf_to_fill); | 3245 | queue->next_buf_to_fill); |
3262 | if (tmp < 0) { | 3246 | if (tmp < 0) { |
3263 | PRINT_ERR("eddp tx_dropped 2\n"); | ||
3264 | rc = -EBUSY; | 3247 | rc = -EBUSY; |
3265 | goto out; | 3248 | goto out; |
3266 | } | 3249 | } |
@@ -3602,8 +3585,6 @@ int qeth_snmp_command(struct qeth_card *card, char __user *udata) | |||
3602 | 3585 | ||
3603 | if ((!qeth_adp_supported(card, IPA_SETADP_SET_SNMP_CONTROL)) && | 3586 | if ((!qeth_adp_supported(card, IPA_SETADP_SET_SNMP_CONTROL)) && |
3604 | (!card->options.layer2)) { | 3587 | (!card->options.layer2)) { |
3605 | PRINT_WARN("SNMP Query MIBS not supported " | ||
3606 | "on %s!\n", QETH_CARD_IFNAME(card)); | ||
3607 | return -EOPNOTSUPP; | 3588 | return -EOPNOTSUPP; |
3608 | } | 3589 | } |
3609 | /* skip 4 bytes (data_len struct member) to get req_len */ | 3590 | /* skip 4 bytes (data_len struct member) to get req_len */ |
@@ -3634,7 +3615,7 @@ int qeth_snmp_command(struct qeth_card *card, char __user *udata) | |||
3634 | rc = qeth_send_ipa_snmp_cmd(card, iob, QETH_SETADP_BASE_LEN + req_len, | 3615 | rc = qeth_send_ipa_snmp_cmd(card, iob, QETH_SETADP_BASE_LEN + req_len, |
3635 | qeth_snmp_command_cb, (void *)&qinfo); | 3616 | qeth_snmp_command_cb, (void *)&qinfo); |
3636 | if (rc) | 3617 | if (rc) |
3637 | PRINT_WARN("SNMP command failed on %s: (0x%x)\n", | 3618 | QETH_DBF_MESSAGE(2, "SNMP command failed on %s: (0x%x)\n", |
3638 | QETH_CARD_IFNAME(card), rc); | 3619 | QETH_CARD_IFNAME(card), rc); |
3639 | else { | 3620 | else { |
3640 | if (copy_to_user(udata, qinfo.udata, qinfo.udata_len)) | 3621 | if (copy_to_user(udata, qinfo.udata, qinfo.udata_len)) |
@@ -3807,8 +3788,8 @@ retry: | |||
3807 | if (mpno) | 3788 | if (mpno) |
3808 | mpno = min(mpno - 1, QETH_MAX_PORTNO); | 3789 | mpno = min(mpno - 1, QETH_MAX_PORTNO); |
3809 | if (card->info.portno > mpno) { | 3790 | if (card->info.portno > mpno) { |
3810 | PRINT_ERR("Device %s does not offer port number %d \n.", | 3791 | QETH_DBF_MESSAGE(2, "Device %s does not offer port number %d" |
3811 | CARD_BUS_ID(card), card->info.portno); | 3792 | "\n.", CARD_BUS_ID(card), card->info.portno); |
3812 | rc = -ENODEV; | 3793 | rc = -ENODEV; |
3813 | goto out; | 3794 | goto out; |
3814 | } | 3795 | } |
@@ -3985,8 +3966,6 @@ struct sk_buff *qeth_core_get_next_skb(struct qeth_card *card, | |||
3985 | return skb; | 3966 | return skb; |
3986 | no_mem: | 3967 | no_mem: |
3987 | if (net_ratelimit()) { | 3968 | if (net_ratelimit()) { |
3988 | PRINT_WARN("No memory for packet received on %s.\n", | ||
3989 | QETH_CARD_IFNAME(card)); | ||
3990 | QETH_DBF_TEXT(TRACE, 2, "noskbmem"); | 3969 | QETH_DBF_TEXT(TRACE, 2, "noskbmem"); |
3991 | QETH_DBF_TEXT_(TRACE, 2, "%s", CARD_BUS_ID(card)); | 3970 | QETH_DBF_TEXT_(TRACE, 2, "%s", CARD_BUS_ID(card)); |
3992 | } | 3971 | } |
@@ -4004,15 +3983,17 @@ static void qeth_unregister_dbf_views(void) | |||
4004 | } | 3983 | } |
4005 | } | 3984 | } |
4006 | 3985 | ||
4007 | void qeth_dbf_longtext(enum qeth_dbf_names dbf_nix, int level, char *text, ...) | 3986 | void qeth_dbf_longtext(enum qeth_dbf_names dbf_nix, int level, char *fmt, ...) |
4008 | { | 3987 | { |
4009 | char dbf_txt_buf[32]; | 3988 | char dbf_txt_buf[32]; |
3989 | va_list args; | ||
4010 | 3990 | ||
4011 | if (level > (qeth_dbf[dbf_nix].id)->level) | 3991 | if (level > (qeth_dbf[dbf_nix].id)->level) |
4012 | return; | 3992 | return; |
4013 | snprintf(dbf_txt_buf, sizeof(dbf_txt_buf), text); | 3993 | va_start(args, fmt); |
3994 | vsnprintf(dbf_txt_buf, sizeof(dbf_txt_buf), fmt, args); | ||
3995 | va_end(args); | ||
4014 | debug_text_event(qeth_dbf[dbf_nix].id, level, dbf_txt_buf); | 3996 | debug_text_event(qeth_dbf[dbf_nix].id, level, dbf_txt_buf); |
4015 | |||
4016 | } | 3997 | } |
4017 | EXPORT_SYMBOL_GPL(qeth_dbf_longtext); | 3998 | EXPORT_SYMBOL_GPL(qeth_dbf_longtext); |
4018 | 3999 | ||
diff --git a/drivers/s390/net/qeth_core_offl.c b/drivers/s390/net/qeth_core_offl.c index 822df8362856..452874e89740 100644 --- a/drivers/s390/net/qeth_core_offl.c +++ b/drivers/s390/net/qeth_core_offl.c | |||
@@ -122,8 +122,8 @@ int qeth_eddp_fill_buffer(struct qeth_qdio_out_q *queue, | |||
122 | if (element == 0) | 122 | if (element == 0) |
123 | return -EBUSY; | 123 | return -EBUSY; |
124 | else { | 124 | else { |
125 | PRINT_WARN("could only partially fill eddp " | 125 | QETH_DBF_MESSAGE(2, "could only partially fill" |
126 | "buffer!\n"); | 126 | "eddp buffer!\n"); |
127 | goto out; | 127 | goto out; |
128 | } | 128 | } |
129 | } | 129 | } |
@@ -143,8 +143,6 @@ int qeth_eddp_fill_buffer(struct qeth_qdio_out_q *queue, | |||
143 | if (must_refcnt) { | 143 | if (must_refcnt) { |
144 | must_refcnt = 0; | 144 | must_refcnt = 0; |
145 | if (qeth_eddp_buf_ref_context(buf, ctx)) { | 145 | if (qeth_eddp_buf_ref_context(buf, ctx)) { |
146 | PRINT_WARN("no memory to create eddp context " | ||
147 | "reference\n"); | ||
148 | goto out_check; | 146 | goto out_check; |
149 | } | 147 | } |
150 | } | 148 | } |
diff --git a/drivers/s390/net/qeth_core_sys.c b/drivers/s390/net/qeth_core_sys.c index 08a50f057284..c26e842ad905 100644 --- a/drivers/s390/net/qeth_core_sys.c +++ b/drivers/s390/net/qeth_core_sys.c | |||
@@ -129,7 +129,6 @@ static ssize_t qeth_dev_portno_store(struct device *dev, | |||
129 | 129 | ||
130 | portno = simple_strtoul(buf, &tmp, 16); | 130 | portno = simple_strtoul(buf, &tmp, 16); |
131 | if (portno > QETH_MAX_PORTNO) { | 131 | if (portno > QETH_MAX_PORTNO) { |
132 | PRINT_WARN("portno 0x%X is out of range\n", portno); | ||
133 | return -EINVAL; | 132 | return -EINVAL; |
134 | } | 133 | } |
135 | 134 | ||
@@ -223,8 +222,6 @@ static ssize_t qeth_dev_prioqing_store(struct device *dev, | |||
223 | * if though we have to permit priority queueing | 222 | * if though we have to permit priority queueing |
224 | */ | 223 | */ |
225 | if (card->qdio.no_out_queues == 1) { | 224 | if (card->qdio.no_out_queues == 1) { |
226 | PRINT_WARN("Priority queueing disabled due " | ||
227 | "to hardware limitations!\n"); | ||
228 | card->qdio.do_prio_queueing = QETH_PRIOQ_DEFAULT; | 225 | card->qdio.do_prio_queueing = QETH_PRIOQ_DEFAULT; |
229 | return -EPERM; | 226 | return -EPERM; |
230 | } | 227 | } |
@@ -250,7 +247,6 @@ static ssize_t qeth_dev_prioqing_store(struct device *dev, | |||
250 | card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING; | 247 | card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING; |
251 | card->qdio.default_out_queue = QETH_DEFAULT_QUEUE; | 248 | card->qdio.default_out_queue = QETH_DEFAULT_QUEUE; |
252 | } else { | 249 | } else { |
253 | PRINT_WARN("Unknown queueing type '%s'\n", tmp); | ||
254 | return -EINVAL; | 250 | return -EINVAL; |
255 | } | 251 | } |
256 | return count; | 252 | return count; |
@@ -291,9 +287,6 @@ static ssize_t qeth_dev_bufcnt_store(struct device *dev, | |||
291 | ((cnt > QETH_IN_BUF_COUNT_MAX) ? QETH_IN_BUF_COUNT_MAX : cnt); | 287 | ((cnt > QETH_IN_BUF_COUNT_MAX) ? QETH_IN_BUF_COUNT_MAX : cnt); |
292 | if (old_cnt != cnt) { | 288 | if (old_cnt != cnt) { |
293 | rc = qeth_realloc_buffer_pool(card, cnt); | 289 | rc = qeth_realloc_buffer_pool(card, cnt); |
294 | if (rc) | ||
295 | PRINT_WARN("Error (%d) while setting " | ||
296 | "buffer count.\n", rc); | ||
297 | } | 290 | } |
298 | return count; | 291 | return count; |
299 | } | 292 | } |
@@ -355,7 +348,6 @@ static ssize_t qeth_dev_performance_stats_store(struct device *dev, | |||
355 | card->perf_stats.initial_rx_packets = card->stats.rx_packets; | 348 | card->perf_stats.initial_rx_packets = card->stats.rx_packets; |
356 | card->perf_stats.initial_tx_packets = card->stats.tx_packets; | 349 | card->perf_stats.initial_tx_packets = card->stats.tx_packets; |
357 | } else { | 350 | } else { |
358 | PRINT_WARN("performance_stats: write 0 or 1 to this file!\n"); | ||
359 | return -EINVAL; | 351 | return -EINVAL; |
360 | } | 352 | } |
361 | return count; | 353 | return count; |
@@ -399,7 +391,6 @@ static ssize_t qeth_dev_layer2_store(struct device *dev, | |||
399 | newdis = QETH_DISCIPLINE_LAYER2; | 391 | newdis = QETH_DISCIPLINE_LAYER2; |
400 | break; | 392 | break; |
401 | default: | 393 | default: |
402 | PRINT_WARN("layer2: write 0 or 1 to this file!\n"); | ||
403 | return -EINVAL; | 394 | return -EINVAL; |
404 | } | 395 | } |
405 | 396 | ||
@@ -463,7 +454,6 @@ static ssize_t qeth_dev_large_send_store(struct device *dev, | |||
463 | } else if (!strcmp(tmp, "TSO")) { | 454 | } else if (!strcmp(tmp, "TSO")) { |
464 | type = QETH_LARGE_SEND_TSO; | 455 | type = QETH_LARGE_SEND_TSO; |
465 | } else { | 456 | } else { |
466 | PRINT_WARN("large_send: invalid mode %s!\n", tmp); | ||
467 | return -EINVAL; | 457 | return -EINVAL; |
468 | } | 458 | } |
469 | if (card->options.large_send == type) | 459 | if (card->options.large_send == type) |
@@ -503,8 +493,6 @@ static ssize_t qeth_dev_blkt_store(struct qeth_card *card, | |||
503 | if (i <= max_value) { | 493 | if (i <= max_value) { |
504 | *value = i; | 494 | *value = i; |
505 | } else { | 495 | } else { |
506 | PRINT_WARN("blkt total time: write values between" | ||
507 | " 0 and %d to this file!\n", max_value); | ||
508 | return -EINVAL; | 496 | return -EINVAL; |
509 | } | 497 | } |
510 | return count; | 498 | return count; |
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 86ec50ddae13..f682f7b14480 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c | |||
@@ -101,19 +101,16 @@ static struct net_device *qeth_l2_netdev_by_devno(unsigned char *read_dev_no) | |||
101 | { | 101 | { |
102 | struct qeth_card *card; | 102 | struct qeth_card *card; |
103 | struct net_device *ndev; | 103 | struct net_device *ndev; |
104 | unsigned char *readno; | 104 | __u16 temp_dev_no; |
105 | __u16 temp_dev_no, card_dev_no; | ||
106 | char *endp; | ||
107 | unsigned long flags; | 105 | unsigned long flags; |
106 | struct ccw_dev_id read_devid; | ||
108 | 107 | ||
109 | ndev = NULL; | 108 | ndev = NULL; |
110 | memcpy(&temp_dev_no, read_dev_no, 2); | 109 | memcpy(&temp_dev_no, read_dev_no, 2); |
111 | read_lock_irqsave(&qeth_core_card_list.rwlock, flags); | 110 | read_lock_irqsave(&qeth_core_card_list.rwlock, flags); |
112 | list_for_each_entry(card, &qeth_core_card_list.list, list) { | 111 | list_for_each_entry(card, &qeth_core_card_list.list, list) { |
113 | readno = CARD_RDEV_ID(card); | 112 | ccw_device_get_id(CARD_RDEV(card), &read_devid); |
114 | readno += (strlen(readno) - 4); | 113 | if (read_devid.devno == temp_dev_no) { |
115 | card_dev_no = simple_strtoul(readno, &endp, 16); | ||
116 | if (card_dev_no == temp_dev_no) { | ||
117 | ndev = card->dev; | 114 | ndev = card->dev; |
118 | break; | 115 | break; |
119 | } | 116 | } |
@@ -134,14 +131,14 @@ static int qeth_l2_send_setgroupmac_cb(struct qeth_card *card, | |||
134 | mac = &cmd->data.setdelmac.mac[0]; | 131 | mac = &cmd->data.setdelmac.mac[0]; |
135 | /* MAC already registered, needed in couple/uncouple case */ | 132 | /* MAC already registered, needed in couple/uncouple case */ |
136 | if (cmd->hdr.return_code == 0x2005) { | 133 | if (cmd->hdr.return_code == 0x2005) { |
137 | PRINT_WARN("Group MAC %02x:%02x:%02x:%02x:%02x:%02x " \ | 134 | QETH_DBF_MESSAGE(2, "Group MAC %02x:%02x:%02x:%02x:%02x:%02x " |
138 | "already existing on %s \n", | 135 | "already existing on %s \n", |
139 | mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], | 136 | mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], |
140 | QETH_CARD_IFNAME(card)); | 137 | QETH_CARD_IFNAME(card)); |
141 | cmd->hdr.return_code = 0; | 138 | cmd->hdr.return_code = 0; |
142 | } | 139 | } |
143 | if (cmd->hdr.return_code) | 140 | if (cmd->hdr.return_code) |
144 | PRINT_ERR("Could not set group MAC " \ | 141 | QETH_DBF_MESSAGE(2, "Could not set group MAC " |
145 | "%02x:%02x:%02x:%02x:%02x:%02x on %s: %x\n", | 142 | "%02x:%02x:%02x:%02x:%02x:%02x on %s: %x\n", |
146 | mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], | 143 | mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], |
147 | QETH_CARD_IFNAME(card), cmd->hdr.return_code); | 144 | QETH_CARD_IFNAME(card), cmd->hdr.return_code); |
@@ -166,7 +163,7 @@ static int qeth_l2_send_delgroupmac_cb(struct qeth_card *card, | |||
166 | cmd = (struct qeth_ipa_cmd *) data; | 163 | cmd = (struct qeth_ipa_cmd *) data; |
167 | mac = &cmd->data.setdelmac.mac[0]; | 164 | mac = &cmd->data.setdelmac.mac[0]; |
168 | if (cmd->hdr.return_code) | 165 | if (cmd->hdr.return_code) |
169 | PRINT_ERR("Could not delete group MAC " \ | 166 | QETH_DBF_MESSAGE(2, "Could not delete group MAC " |
170 | "%02x:%02x:%02x:%02x:%02x:%02x on %s: %x\n", | 167 | "%02x:%02x:%02x:%02x:%02x:%02x on %s: %x\n", |
171 | mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], | 168 | mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], |
172 | QETH_CARD_IFNAME(card), cmd->hdr.return_code); | 169 | QETH_CARD_IFNAME(card), cmd->hdr.return_code); |
@@ -186,10 +183,8 @@ static void qeth_l2_add_mc(struct qeth_card *card, __u8 *mac) | |||
186 | 183 | ||
187 | mc = kmalloc(sizeof(struct qeth_mc_mac), GFP_ATOMIC); | 184 | mc = kmalloc(sizeof(struct qeth_mc_mac), GFP_ATOMIC); |
188 | 185 | ||
189 | if (!mc) { | 186 | if (!mc) |
190 | PRINT_ERR("no mem vor mc mac address\n"); | ||
191 | return; | 187 | return; |
192 | } | ||
193 | 188 | ||
194 | memcpy(mc->mc_addr, mac, OSA_ADDR_LEN); | 189 | memcpy(mc->mc_addr, mac, OSA_ADDR_LEN); |
195 | mc->mc_addrlen = OSA_ADDR_LEN; | 190 | mc->mc_addrlen = OSA_ADDR_LEN; |
@@ -280,7 +275,7 @@ static int qeth_l2_send_setdelvlan_cb(struct qeth_card *card, | |||
280 | QETH_DBF_TEXT(TRACE, 2, "L2sdvcb"); | 275 | QETH_DBF_TEXT(TRACE, 2, "L2sdvcb"); |
281 | cmd = (struct qeth_ipa_cmd *) data; | 276 | cmd = (struct qeth_ipa_cmd *) data; |
282 | if (cmd->hdr.return_code) { | 277 | if (cmd->hdr.return_code) { |
283 | PRINT_ERR("Error in processing VLAN %i on %s: 0x%x. " | 278 | QETH_DBF_MESSAGE(2, "Error in processing VLAN %i on %s: 0x%x. " |
284 | "Continuing\n", cmd->data.setdelvlan.vlan_id, | 279 | "Continuing\n", cmd->data.setdelvlan.vlan_id, |
285 | QETH_CARD_IFNAME(card), cmd->hdr.return_code); | 280 | QETH_CARD_IFNAME(card), cmd->hdr.return_code); |
286 | QETH_DBF_TEXT_(TRACE, 2, "L2VL%4x", cmd->hdr.command); | 281 | QETH_DBF_TEXT_(TRACE, 2, "L2VL%4x", cmd->hdr.command); |
@@ -333,8 +328,6 @@ static void qeth_l2_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) | |||
333 | spin_lock_bh(&card->vlanlock); | 328 | spin_lock_bh(&card->vlanlock); |
334 | list_add_tail(&id->list, &card->vid_list); | 329 | list_add_tail(&id->list, &card->vid_list); |
335 | spin_unlock_bh(&card->vlanlock); | 330 | spin_unlock_bh(&card->vlanlock); |
336 | } else { | ||
337 | PRINT_ERR("no memory for vid\n"); | ||
338 | } | 331 | } |
339 | } | 332 | } |
340 | 333 | ||
@@ -550,16 +543,15 @@ static int qeth_l2_request_initial_mac(struct qeth_card *card) | |||
550 | 543 | ||
551 | rc = qeth_query_setadapterparms(card); | 544 | rc = qeth_query_setadapterparms(card); |
552 | if (rc) { | 545 | if (rc) { |
553 | PRINT_WARN("could not query adapter parameters on device %s: " | 546 | QETH_DBF_MESSAGE(2, "could not query adapter parameters on " |
554 | "x%x\n", CARD_BUS_ID(card), rc); | 547 | "device %s: x%x\n", CARD_BUS_ID(card), rc); |
555 | } | 548 | } |
556 | 549 | ||
557 | if (card->info.guestlan) { | 550 | if (card->info.guestlan) { |
558 | rc = qeth_setadpparms_change_macaddr(card); | 551 | rc = qeth_setadpparms_change_macaddr(card); |
559 | if (rc) { | 552 | if (rc) { |
560 | PRINT_WARN("couldn't get MAC address on " | 553 | QETH_DBF_MESSAGE(2, "couldn't get MAC address on " |
561 | "device %s: x%x\n", | 554 | "device %s: x%x\n", CARD_BUS_ID(card), rc); |
562 | CARD_BUS_ID(card), rc); | ||
563 | QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc); | 555 | QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc); |
564 | return rc; | 556 | return rc; |
565 | } | 557 | } |
@@ -585,8 +577,6 @@ static int qeth_l2_set_mac_address(struct net_device *dev, void *p) | |||
585 | } | 577 | } |
586 | 578 | ||
587 | if (card->info.type == QETH_CARD_TYPE_OSN) { | 579 | if (card->info.type == QETH_CARD_TYPE_OSN) { |
588 | PRINT_WARN("Setting MAC address on %s is not supported.\n", | ||
589 | dev->name); | ||
590 | QETH_DBF_TEXT(TRACE, 3, "setmcOSN"); | 580 | QETH_DBF_TEXT(TRACE, 3, "setmcOSN"); |
591 | return -EOPNOTSUPP; | 581 | return -EOPNOTSUPP; |
592 | } | 582 | } |
@@ -666,7 +656,7 @@ static int qeth_l2_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
666 | ctx = qeth_eddp_create_context(card, new_skb, hdr, | 656 | ctx = qeth_eddp_create_context(card, new_skb, hdr, |
667 | skb->sk->sk_protocol); | 657 | skb->sk->sk_protocol); |
668 | if (ctx == NULL) { | 658 | if (ctx == NULL) { |
669 | PRINT_WARN("could not create eddp context\n"); | 659 | QETH_DBF_MESSAGE(2, "could not create eddp context\n"); |
670 | goto tx_drop; | 660 | goto tx_drop; |
671 | } | 661 | } |
672 | } else { | 662 | } else { |
@@ -731,6 +721,7 @@ tx_drop: | |||
731 | if ((new_skb != skb) && new_skb) | 721 | if ((new_skb != skb) && new_skb) |
732 | dev_kfree_skb_any(new_skb); | 722 | dev_kfree_skb_any(new_skb); |
733 | dev_kfree_skb_any(skb); | 723 | dev_kfree_skb_any(skb); |
724 | netif_wake_queue(dev); | ||
734 | return NETDEV_TX_OK; | 725 | return NETDEV_TX_OK; |
735 | } | 726 | } |
736 | 727 | ||
@@ -1155,7 +1146,7 @@ static int qeth_osn_send_control_data(struct qeth_card *card, int len, | |||
1155 | (addr_t) iob, 0, 0); | 1146 | (addr_t) iob, 0, 0); |
1156 | spin_unlock_irqrestore(get_ccwdev_lock(card->write.ccwdev), flags); | 1147 | spin_unlock_irqrestore(get_ccwdev_lock(card->write.ccwdev), flags); |
1157 | if (rc) { | 1148 | if (rc) { |
1158 | PRINT_WARN("qeth_osn_send_control_data: " | 1149 | QETH_DBF_MESSAGE(2, "qeth_osn_send_control_data: " |
1159 | "ccw_device_start rc = %i\n", rc); | 1150 | "ccw_device_start rc = %i\n", rc); |
1160 | QETH_DBF_TEXT_(TRACE, 2, " err%d", rc); | 1151 | QETH_DBF_TEXT_(TRACE, 2, " err%d", rc); |
1161 | qeth_release_buffer(iob->channel, iob); | 1152 | qeth_release_buffer(iob->channel, iob); |
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 94a8ead64ed4..999552c83bbe 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c | |||
@@ -311,7 +311,6 @@ static struct qeth_ipaddr *qeth_l3_get_addr_buffer( | |||
311 | 311 | ||
312 | addr = kzalloc(sizeof(struct qeth_ipaddr), GFP_ATOMIC); | 312 | addr = kzalloc(sizeof(struct qeth_ipaddr), GFP_ATOMIC); |
313 | if (addr == NULL) { | 313 | if (addr == NULL) { |
314 | PRINT_WARN("Not enough memory to add address\n"); | ||
315 | return NULL; | 314 | return NULL; |
316 | } | 315 | } |
317 | addr->type = QETH_IP_TYPE_NORMAL; | 316 | addr->type = QETH_IP_TYPE_NORMAL; |
@@ -649,15 +648,6 @@ static void qeth_l3_correct_routing_type(struct qeth_card *card, | |||
649 | } | 648 | } |
650 | } | 649 | } |
651 | out_inval: | 650 | out_inval: |
652 | PRINT_WARN("Routing type '%s' not supported for interface %s.\n" | ||
653 | "Router status set to 'no router'.\n", | ||
654 | ((*type == PRIMARY_ROUTER)? "primary router" : | ||
655 | (*type == SECONDARY_ROUTER)? "secondary router" : | ||
656 | (*type == PRIMARY_CONNECTOR)? "primary connector" : | ||
657 | (*type == SECONDARY_CONNECTOR)? "secondary connector" : | ||
658 | (*type == MULTICAST_ROUTER)? "multicast router" : | ||
659 | "unknown"), | ||
660 | card->dev->name); | ||
661 | *type = NO_ROUTER; | 651 | *type = NO_ROUTER; |
662 | } | 652 | } |
663 | 653 | ||
@@ -674,9 +664,9 @@ int qeth_l3_setrouting_v4(struct qeth_card *card) | |||
674 | QETH_PROT_IPV4); | 664 | QETH_PROT_IPV4); |
675 | if (rc) { | 665 | if (rc) { |
676 | card->options.route4.type = NO_ROUTER; | 666 | card->options.route4.type = NO_ROUTER; |
677 | PRINT_WARN("Error (0x%04x) while setting routing type on %s. " | 667 | QETH_DBF_MESSAGE(2, "Error (0x%04x) while setting routing type" |
678 | "Type set to 'no router'.\n", | 668 | " on %s. Type set to 'no router'.\n", rc, |
679 | rc, QETH_CARD_IFNAME(card)); | 669 | QETH_CARD_IFNAME(card)); |
680 | } | 670 | } |
681 | return rc; | 671 | return rc; |
682 | } | 672 | } |
@@ -697,9 +687,9 @@ int qeth_l3_setrouting_v6(struct qeth_card *card) | |||
697 | QETH_PROT_IPV6); | 687 | QETH_PROT_IPV6); |
698 | if (rc) { | 688 | if (rc) { |
699 | card->options.route6.type = NO_ROUTER; | 689 | card->options.route6.type = NO_ROUTER; |
700 | PRINT_WARN("Error (0x%04x) while setting routing type on %s. " | 690 | QETH_DBF_MESSAGE(2, "Error (0x%04x) while setting routing type" |
701 | "Type set to 'no router'.\n", | 691 | " on %s. Type set to 'no router'.\n", rc, |
702 | rc, QETH_CARD_IFNAME(card)); | 692 | QETH_CARD_IFNAME(card)); |
703 | } | 693 | } |
704 | #endif | 694 | #endif |
705 | return rc; | 695 | return rc; |
@@ -737,7 +727,6 @@ int qeth_l3_add_ipato_entry(struct qeth_card *card, | |||
737 | if (!memcmp(ipatoe->addr, new->addr, | 727 | if (!memcmp(ipatoe->addr, new->addr, |
738 | (ipatoe->proto == QETH_PROT_IPV4)? 4:16) && | 728 | (ipatoe->proto == QETH_PROT_IPV4)? 4:16) && |
739 | (ipatoe->mask_bits == new->mask_bits)) { | 729 | (ipatoe->mask_bits == new->mask_bits)) { |
740 | PRINT_WARN("ipato entry already exists!\n"); | ||
741 | rc = -EEXIST; | 730 | rc = -EEXIST; |
742 | break; | 731 | break; |
743 | } | 732 | } |
@@ -802,7 +791,6 @@ int qeth_l3_add_vipa(struct qeth_card *card, enum qeth_prot_versions proto, | |||
802 | rc = -EEXIST; | 791 | rc = -EEXIST; |
803 | spin_unlock_irqrestore(&card->ip_lock, flags); | 792 | spin_unlock_irqrestore(&card->ip_lock, flags); |
804 | if (rc) { | 793 | if (rc) { |
805 | PRINT_WARN("Cannot add VIPA. Address already exists!\n"); | ||
806 | return rc; | 794 | return rc; |
807 | } | 795 | } |
808 | if (!qeth_l3_add_ip(card, ipaddr)) | 796 | if (!qeth_l3_add_ip(card, ipaddr)) |
@@ -867,7 +855,6 @@ int qeth_l3_add_rxip(struct qeth_card *card, enum qeth_prot_versions proto, | |||
867 | rc = -EEXIST; | 855 | rc = -EEXIST; |
868 | spin_unlock_irqrestore(&card->ip_lock, flags); | 856 | spin_unlock_irqrestore(&card->ip_lock, flags); |
869 | if (rc) { | 857 | if (rc) { |
870 | PRINT_WARN("Cannot add RXIP. Address already exists!\n"); | ||
871 | return rc; | 858 | return rc; |
872 | } | 859 | } |
873 | if (!qeth_l3_add_ip(card, ipaddr)) | 860 | if (!qeth_l3_add_ip(card, ipaddr)) |
@@ -1020,23 +1007,23 @@ static int qeth_l3_setadapter_hstr(struct qeth_card *card) | |||
1020 | IPA_SETADP_SET_BROADCAST_MODE, | 1007 | IPA_SETADP_SET_BROADCAST_MODE, |
1021 | card->options.broadcast_mode); | 1008 | card->options.broadcast_mode); |
1022 | if (rc) | 1009 | if (rc) |
1023 | PRINT_WARN("couldn't set broadcast mode on " | 1010 | QETH_DBF_MESSAGE(2, "couldn't set broadcast mode on " |
1024 | "device %s: x%x\n", | 1011 | "device %s: x%x\n", |
1025 | CARD_BUS_ID(card), rc); | 1012 | CARD_BUS_ID(card), rc); |
1026 | rc = qeth_l3_send_setadp_mode(card, | 1013 | rc = qeth_l3_send_setadp_mode(card, |
1027 | IPA_SETADP_ALTER_MAC_ADDRESS, | 1014 | IPA_SETADP_ALTER_MAC_ADDRESS, |
1028 | card->options.macaddr_mode); | 1015 | card->options.macaddr_mode); |
1029 | if (rc) | 1016 | if (rc) |
1030 | PRINT_WARN("couldn't set macaddr mode on " | 1017 | QETH_DBF_MESSAGE(2, "couldn't set macaddr mode on " |
1031 | "device %s: x%x\n", CARD_BUS_ID(card), rc); | 1018 | "device %s: x%x\n", CARD_BUS_ID(card), rc); |
1032 | return rc; | 1019 | return rc; |
1033 | } | 1020 | } |
1034 | if (card->options.broadcast_mode == QETH_TR_BROADCAST_LOCAL) | 1021 | if (card->options.broadcast_mode == QETH_TR_BROADCAST_LOCAL) |
1035 | PRINT_WARN("set adapter parameters not available " | 1022 | QETH_DBF_MESSAGE(2, "set adapter parameters not available " |
1036 | "to set broadcast mode, using ALLRINGS " | 1023 | "to set broadcast mode, using ALLRINGS " |
1037 | "on device %s:\n", CARD_BUS_ID(card)); | 1024 | "on device %s:\n", CARD_BUS_ID(card)); |
1038 | if (card->options.macaddr_mode == QETH_TR_MACADDR_CANONICAL) | 1025 | if (card->options.macaddr_mode == QETH_TR_MACADDR_CANONICAL) |
1039 | PRINT_WARN("set adapter parameters not available " | 1026 | QETH_DBF_MESSAGE(2, "set adapter parameters not available " |
1040 | "to set macaddr mode, using NONCANONICAL " | 1027 | "to set macaddr mode, using NONCANONICAL " |
1041 | "on device %s:\n", CARD_BUS_ID(card)); | 1028 | "on device %s:\n", CARD_BUS_ID(card)); |
1042 | return 0; | 1029 | return 0; |
@@ -2070,7 +2057,7 @@ static struct qeth_card *qeth_l3_get_card_from_dev(struct net_device *dev) | |||
2070 | card = netdev_priv(dev); | 2057 | card = netdev_priv(dev); |
2071 | else if (rc == QETH_VLAN_CARD) | 2058 | else if (rc == QETH_VLAN_CARD) |
2072 | card = netdev_priv(vlan_dev_info(dev)->real_dev); | 2059 | card = netdev_priv(vlan_dev_info(dev)->real_dev); |
2073 | if (card->options.layer2) | 2060 | if (card && card->options.layer2) |
2074 | card = NULL; | 2061 | card = NULL; |
2075 | QETH_DBF_TEXT_(TRACE, 4, "%d", rc); | 2062 | QETH_DBF_TEXT_(TRACE, 4, "%d", rc); |
2076 | return card ; | 2063 | return card ; |
@@ -2182,8 +2169,6 @@ static int qeth_l3_arp_set_no_entries(struct qeth_card *card, int no_entries) | |||
2182 | if (card->info.guestlan) | 2169 | if (card->info.guestlan) |
2183 | return -EOPNOTSUPP; | 2170 | return -EOPNOTSUPP; |
2184 | if (!qeth_is_supported(card, IPA_ARP_PROCESSING)) { | 2171 | if (!qeth_is_supported(card, IPA_ARP_PROCESSING)) { |
2185 | PRINT_WARN("ARP processing not supported " | ||
2186 | "on %s!\n", QETH_CARD_IFNAME(card)); | ||
2187 | return -EOPNOTSUPP; | 2172 | return -EOPNOTSUPP; |
2188 | } | 2173 | } |
2189 | rc = qeth_l3_send_simple_setassparms(card, IPA_ARP_PROCESSING, | 2174 | rc = qeth_l3_send_simple_setassparms(card, IPA_ARP_PROCESSING, |
@@ -2191,8 +2176,8 @@ static int qeth_l3_arp_set_no_entries(struct qeth_card *card, int no_entries) | |||
2191 | no_entries); | 2176 | no_entries); |
2192 | if (rc) { | 2177 | if (rc) { |
2193 | tmp = rc; | 2178 | tmp = rc; |
2194 | PRINT_WARN("Could not set number of ARP entries on %s: " | 2179 | QETH_DBF_MESSAGE(2, "Could not set number of ARP entries on " |
2195 | "%s (0x%x/%d)\n", QETH_CARD_IFNAME(card), | 2180 | "%s: %s (0x%x/%d)\n", QETH_CARD_IFNAME(card), |
2196 | qeth_l3_arp_get_error_cause(&rc), tmp, tmp); | 2181 | qeth_l3_arp_get_error_cause(&rc), tmp, tmp); |
2197 | } | 2182 | } |
2198 | return rc; | 2183 | return rc; |
@@ -2260,9 +2245,6 @@ static int qeth_l3_arp_query_cb(struct qeth_card *card, | |||
2260 | qdata->no_entries * uentry_size){ | 2245 | qdata->no_entries * uentry_size){ |
2261 | QETH_DBF_TEXT_(TRACE, 4, "qaer3%i", -ENOMEM); | 2246 | QETH_DBF_TEXT_(TRACE, 4, "qaer3%i", -ENOMEM); |
2262 | cmd->hdr.return_code = -ENOMEM; | 2247 | cmd->hdr.return_code = -ENOMEM; |
2263 | PRINT_WARN("query ARP user space buffer is too small for " | ||
2264 | "the returned number of ARP entries. " | ||
2265 | "Aborting query!\n"); | ||
2266 | goto out_error; | 2248 | goto out_error; |
2267 | } | 2249 | } |
2268 | QETH_DBF_TEXT_(TRACE, 4, "anore%i", | 2250 | QETH_DBF_TEXT_(TRACE, 4, "anore%i", |
@@ -2324,8 +2306,6 @@ static int qeth_l3_arp_query(struct qeth_card *card, char __user *udata) | |||
2324 | 2306 | ||
2325 | if (!qeth_is_supported(card,/*IPA_QUERY_ARP_ADDR_INFO*/ | 2307 | if (!qeth_is_supported(card,/*IPA_QUERY_ARP_ADDR_INFO*/ |
2326 | IPA_ARP_PROCESSING)) { | 2308 | IPA_ARP_PROCESSING)) { |
2327 | PRINT_WARN("ARP processing not supported " | ||
2328 | "on %s!\n", QETH_CARD_IFNAME(card)); | ||
2329 | return -EOPNOTSUPP; | 2309 | return -EOPNOTSUPP; |
2330 | } | 2310 | } |
2331 | /* get size of userspace buffer and mask_bits -> 6 bytes */ | 2311 | /* get size of userspace buffer and mask_bits -> 6 bytes */ |
@@ -2344,7 +2324,7 @@ static int qeth_l3_arp_query(struct qeth_card *card, char __user *udata) | |||
2344 | qeth_l3_arp_query_cb, (void *)&qinfo); | 2324 | qeth_l3_arp_query_cb, (void *)&qinfo); |
2345 | if (rc) { | 2325 | if (rc) { |
2346 | tmp = rc; | 2326 | tmp = rc; |
2347 | PRINT_WARN("Error while querying ARP cache on %s: %s " | 2327 | QETH_DBF_MESSAGE(2, "Error while querying ARP cache on %s: %s " |
2348 | "(0x%x/%d)\n", QETH_CARD_IFNAME(card), | 2328 | "(0x%x/%d)\n", QETH_CARD_IFNAME(card), |
2349 | qeth_l3_arp_get_error_cause(&rc), tmp, tmp); | 2329 | qeth_l3_arp_get_error_cause(&rc), tmp, tmp); |
2350 | if (copy_to_user(udata, qinfo.udata, 4)) | 2330 | if (copy_to_user(udata, qinfo.udata, 4)) |
@@ -2375,8 +2355,6 @@ static int qeth_l3_arp_add_entry(struct qeth_card *card, | |||
2375 | if (card->info.guestlan) | 2355 | if (card->info.guestlan) |
2376 | return -EOPNOTSUPP; | 2356 | return -EOPNOTSUPP; |
2377 | if (!qeth_is_supported(card, IPA_ARP_PROCESSING)) { | 2357 | if (!qeth_is_supported(card, IPA_ARP_PROCESSING)) { |
2378 | PRINT_WARN("ARP processing not supported " | ||
2379 | "on %s!\n", QETH_CARD_IFNAME(card)); | ||
2380 | return -EOPNOTSUPP; | 2358 | return -EOPNOTSUPP; |
2381 | } | 2359 | } |
2382 | 2360 | ||
@@ -2391,10 +2369,9 @@ static int qeth_l3_arp_add_entry(struct qeth_card *card, | |||
2391 | if (rc) { | 2369 | if (rc) { |
2392 | tmp = rc; | 2370 | tmp = rc; |
2393 | qeth_l3_ipaddr4_to_string((u8 *)entry->ipaddr, buf); | 2371 | qeth_l3_ipaddr4_to_string((u8 *)entry->ipaddr, buf); |
2394 | PRINT_WARN("Could not add ARP entry for address %s on %s: " | 2372 | QETH_DBF_MESSAGE(2, "Could not add ARP entry for address %s " |
2395 | "%s (0x%x/%d)\n", | 2373 | "on %s: %s (0x%x/%d)\n", buf, QETH_CARD_IFNAME(card), |
2396 | buf, QETH_CARD_IFNAME(card), | 2374 | qeth_l3_arp_get_error_cause(&rc), tmp, tmp); |
2397 | qeth_l3_arp_get_error_cause(&rc), tmp, tmp); | ||
2398 | } | 2375 | } |
2399 | return rc; | 2376 | return rc; |
2400 | } | 2377 | } |
@@ -2417,8 +2394,6 @@ static int qeth_l3_arp_remove_entry(struct qeth_card *card, | |||
2417 | if (card->info.guestlan) | 2394 | if (card->info.guestlan) |
2418 | return -EOPNOTSUPP; | 2395 | return -EOPNOTSUPP; |
2419 | if (!qeth_is_supported(card, IPA_ARP_PROCESSING)) { | 2396 | if (!qeth_is_supported(card, IPA_ARP_PROCESSING)) { |
2420 | PRINT_WARN("ARP processing not supported " | ||
2421 | "on %s!\n", QETH_CARD_IFNAME(card)); | ||
2422 | return -EOPNOTSUPP; | 2397 | return -EOPNOTSUPP; |
2423 | } | 2398 | } |
2424 | memcpy(buf, entry, 12); | 2399 | memcpy(buf, entry, 12); |
@@ -2433,10 +2408,9 @@ static int qeth_l3_arp_remove_entry(struct qeth_card *card, | |||
2433 | tmp = rc; | 2408 | tmp = rc; |
2434 | memset(buf, 0, 16); | 2409 | memset(buf, 0, 16); |
2435 | qeth_l3_ipaddr4_to_string((u8 *)entry->ipaddr, buf); | 2410 | qeth_l3_ipaddr4_to_string((u8 *)entry->ipaddr, buf); |
2436 | PRINT_WARN("Could not delete ARP entry for address %s on %s: " | 2411 | QETH_DBF_MESSAGE(2, "Could not delete ARP entry for address %s" |
2437 | "%s (0x%x/%d)\n", | 2412 | " on %s: %s (0x%x/%d)\n", buf, QETH_CARD_IFNAME(card), |
2438 | buf, QETH_CARD_IFNAME(card), | 2413 | qeth_l3_arp_get_error_cause(&rc), tmp, tmp); |
2439 | qeth_l3_arp_get_error_cause(&rc), tmp, tmp); | ||
2440 | } | 2414 | } |
2441 | return rc; | 2415 | return rc; |
2442 | } | 2416 | } |
@@ -2456,16 +2430,14 @@ static int qeth_l3_arp_flush_cache(struct qeth_card *card) | |||
2456 | if (card->info.guestlan || (card->info.type == QETH_CARD_TYPE_IQD)) | 2430 | if (card->info.guestlan || (card->info.type == QETH_CARD_TYPE_IQD)) |
2457 | return -EOPNOTSUPP; | 2431 | return -EOPNOTSUPP; |
2458 | if (!qeth_is_supported(card, IPA_ARP_PROCESSING)) { | 2432 | if (!qeth_is_supported(card, IPA_ARP_PROCESSING)) { |
2459 | PRINT_WARN("ARP processing not supported " | ||
2460 | "on %s!\n", QETH_CARD_IFNAME(card)); | ||
2461 | return -EOPNOTSUPP; | 2433 | return -EOPNOTSUPP; |
2462 | } | 2434 | } |
2463 | rc = qeth_l3_send_simple_setassparms(card, IPA_ARP_PROCESSING, | 2435 | rc = qeth_l3_send_simple_setassparms(card, IPA_ARP_PROCESSING, |
2464 | IPA_CMD_ASS_ARP_FLUSH_CACHE, 0); | 2436 | IPA_CMD_ASS_ARP_FLUSH_CACHE, 0); |
2465 | if (rc) { | 2437 | if (rc) { |
2466 | tmp = rc; | 2438 | tmp = rc; |
2467 | PRINT_WARN("Could not flush ARP cache on %s: %s (0x%x/%d)\n", | 2439 | QETH_DBF_MESSAGE(2, "Could not flush ARP cache on %s: %s " |
2468 | QETH_CARD_IFNAME(card), | 2440 | "(0x%x/%d)\n", QETH_CARD_IFNAME(card), |
2469 | qeth_l3_arp_get_error_cause(&rc), tmp, tmp); | 2441 | qeth_l3_arp_get_error_cause(&rc), tmp, tmp); |
2470 | } | 2442 | } |
2471 | return rc; | 2443 | return rc; |
@@ -2724,7 +2696,7 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2724 | ctx = qeth_eddp_create_context(card, new_skb, hdr, | 2696 | ctx = qeth_eddp_create_context(card, new_skb, hdr, |
2725 | skb->sk->sk_protocol); | 2697 | skb->sk->sk_protocol); |
2726 | if (ctx == NULL) { | 2698 | if (ctx == NULL) { |
2727 | PRINT_WARN("could not create eddp context\n"); | 2699 | QETH_DBF_MESSAGE(2, "could not create eddp context\n"); |
2728 | goto tx_drop; | 2700 | goto tx_drop; |
2729 | } | 2701 | } |
2730 | } else { | 2702 | } else { |
@@ -2792,6 +2764,7 @@ tx_drop: | |||
2792 | if ((new_skb != skb) && new_skb) | 2764 | if ((new_skb != skb) && new_skb) |
2793 | dev_kfree_skb_any(new_skb); | 2765 | dev_kfree_skb_any(new_skb); |
2794 | dev_kfree_skb_any(skb); | 2766 | dev_kfree_skb_any(skb); |
2767 | netif_wake_queue(dev); | ||
2795 | return NETDEV_TX_OK; | 2768 | return NETDEV_TX_OK; |
2796 | } | 2769 | } |
2797 | 2770 | ||
diff --git a/drivers/s390/net/qeth_l3_sys.c b/drivers/s390/net/qeth_l3_sys.c index 08f51fd902c4..ac1993708ae9 100644 --- a/drivers/s390/net/qeth_l3_sys.c +++ b/drivers/s390/net/qeth_l3_sys.c | |||
@@ -85,7 +85,6 @@ static ssize_t qeth_l3_dev_route_store(struct qeth_card *card, | |||
85 | } else if (!strcmp(tmp, "multicast_router")) { | 85 | } else if (!strcmp(tmp, "multicast_router")) { |
86 | route->type = MULTICAST_ROUTER; | 86 | route->type = MULTICAST_ROUTER; |
87 | } else { | 87 | } else { |
88 | PRINT_WARN("Invalid routing type '%s'.\n", tmp); | ||
89 | return -EINVAL; | 88 | return -EINVAL; |
90 | } | 89 | } |
91 | if (((card->state == CARD_STATE_SOFTSETUP) || | 90 | if (((card->state == CARD_STATE_SOFTSETUP) || |
@@ -137,9 +136,6 @@ static ssize_t qeth_l3_dev_route6_store(struct device *dev, | |||
137 | return -EINVAL; | 136 | return -EINVAL; |
138 | 137 | ||
139 | if (!qeth_is_supported(card, IPA_IPV6)) { | 138 | if (!qeth_is_supported(card, IPA_IPV6)) { |
140 | PRINT_WARN("IPv6 not supported for interface %s.\n" | ||
141 | "Routing status no changed.\n", | ||
142 | QETH_CARD_IFNAME(card)); | ||
143 | return -ENOTSUPP; | 139 | return -ENOTSUPP; |
144 | } | 140 | } |
145 | 141 | ||
@@ -179,7 +175,6 @@ static ssize_t qeth_l3_dev_fake_broadcast_store(struct device *dev, | |||
179 | if ((i == 0) || (i == 1)) | 175 | if ((i == 0) || (i == 1)) |
180 | card->options.fake_broadcast = i; | 176 | card->options.fake_broadcast = i; |
181 | else { | 177 | else { |
182 | PRINT_WARN("fake_broadcast: write 0 or 1 to this file!\n"); | ||
183 | return -EINVAL; | 178 | return -EINVAL; |
184 | } | 179 | } |
185 | return count; | 180 | return count; |
@@ -220,7 +215,6 @@ static ssize_t qeth_l3_dev_broadcast_mode_store(struct device *dev, | |||
220 | 215 | ||
221 | if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) || | 216 | if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) || |
222 | (card->info.link_type == QETH_LINK_TYPE_LANE_TR))) { | 217 | (card->info.link_type == QETH_LINK_TYPE_LANE_TR))) { |
223 | PRINT_WARN("Device is not a tokenring device!\n"); | ||
224 | return -EINVAL; | 218 | return -EINVAL; |
225 | } | 219 | } |
226 | 220 | ||
@@ -233,8 +227,6 @@ static ssize_t qeth_l3_dev_broadcast_mode_store(struct device *dev, | |||
233 | card->options.broadcast_mode = QETH_TR_BROADCAST_ALLRINGS; | 227 | card->options.broadcast_mode = QETH_TR_BROADCAST_ALLRINGS; |
234 | return count; | 228 | return count; |
235 | } else { | 229 | } else { |
236 | PRINT_WARN("broadcast_mode: invalid mode %s!\n", | ||
237 | tmp); | ||
238 | return -EINVAL; | 230 | return -EINVAL; |
239 | } | 231 | } |
240 | return count; | 232 | return count; |
@@ -275,7 +267,6 @@ static ssize_t qeth_l3_dev_canonical_macaddr_store(struct device *dev, | |||
275 | 267 | ||
276 | if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) || | 268 | if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) || |
277 | (card->info.link_type == QETH_LINK_TYPE_LANE_TR))) { | 269 | (card->info.link_type == QETH_LINK_TYPE_LANE_TR))) { |
278 | PRINT_WARN("Device is not a tokenring device!\n"); | ||
279 | return -EINVAL; | 270 | return -EINVAL; |
280 | } | 271 | } |
281 | 272 | ||
@@ -285,7 +276,6 @@ static ssize_t qeth_l3_dev_canonical_macaddr_store(struct device *dev, | |||
285 | QETH_TR_MACADDR_CANONICAL : | 276 | QETH_TR_MACADDR_CANONICAL : |
286 | QETH_TR_MACADDR_NONCANONICAL; | 277 | QETH_TR_MACADDR_NONCANONICAL; |
287 | else { | 278 | else { |
288 | PRINT_WARN("canonical_macaddr: write 0 or 1 to this file!\n"); | ||
289 | return -EINVAL; | 279 | return -EINVAL; |
290 | } | 280 | } |
291 | return count; | 281 | return count; |
@@ -327,7 +317,6 @@ static ssize_t qeth_l3_dev_checksum_store(struct device *dev, | |||
327 | else if (!strcmp(tmp, "no_checksumming")) | 317 | else if (!strcmp(tmp, "no_checksumming")) |
328 | card->options.checksum_type = NO_CHECKSUMMING; | 318 | card->options.checksum_type = NO_CHECKSUMMING; |
329 | else { | 319 | else { |
330 | PRINT_WARN("Unknown checksumming type '%s'\n", tmp); | ||
331 | return -EINVAL; | 320 | return -EINVAL; |
332 | } | 321 | } |
333 | return count; | 322 | return count; |
@@ -382,8 +371,6 @@ static ssize_t qeth_l3_dev_ipato_enable_store(struct device *dev, | |||
382 | } else if (!strcmp(tmp, "0")) { | 371 | } else if (!strcmp(tmp, "0")) { |
383 | card->ipato.enabled = 0; | 372 | card->ipato.enabled = 0; |
384 | } else { | 373 | } else { |
385 | PRINT_WARN("ipato_enable: write 0, 1 or 'toggle' to " | ||
386 | "this file\n"); | ||
387 | return -EINVAL; | 374 | return -EINVAL; |
388 | } | 375 | } |
389 | return count; | 376 | return count; |
@@ -422,8 +409,6 @@ static ssize_t qeth_l3_dev_ipato_invert4_store(struct device *dev, | |||
422 | } else if (!strcmp(tmp, "0")) { | 409 | } else if (!strcmp(tmp, "0")) { |
423 | card->ipato.invert4 = 0; | 410 | card->ipato.invert4 = 0; |
424 | } else { | 411 | } else { |
425 | PRINT_WARN("ipato_invert4: write 0, 1 or 'toggle' to " | ||
426 | "this file\n"); | ||
427 | return -EINVAL; | 412 | return -EINVAL; |
428 | } | 413 | } |
429 | return count; | 414 | return count; |
@@ -486,13 +471,10 @@ static int qeth_l3_parse_ipatoe(const char *buf, enum qeth_prot_versions proto, | |||
486 | /* get address string */ | 471 | /* get address string */ |
487 | end = strchr(start, '/'); | 472 | end = strchr(start, '/'); |
488 | if (!end || (end - start >= 40)) { | 473 | if (!end || (end - start >= 40)) { |
489 | PRINT_WARN("Invalid format for ipato_addx/delx. " | ||
490 | "Use <ip addr>/<mask bits>\n"); | ||
491 | return -EINVAL; | 474 | return -EINVAL; |
492 | } | 475 | } |
493 | strncpy(buffer, start, end - start); | 476 | strncpy(buffer, start, end - start); |
494 | if (qeth_l3_string_to_ipaddr(buffer, proto, addr)) { | 477 | if (qeth_l3_string_to_ipaddr(buffer, proto, addr)) { |
495 | PRINT_WARN("Invalid IP address format!\n"); | ||
496 | return -EINVAL; | 478 | return -EINVAL; |
497 | } | 479 | } |
498 | start = end + 1; | 480 | start = end + 1; |
@@ -500,7 +482,6 @@ static int qeth_l3_parse_ipatoe(const char *buf, enum qeth_prot_versions proto, | |||
500 | if (!strlen(start) || | 482 | if (!strlen(start) || |
501 | (tmp == start) || | 483 | (tmp == start) || |
502 | (*mask_bits > ((proto == QETH_PROT_IPV4) ? 32 : 128))) { | 484 | (*mask_bits > ((proto == QETH_PROT_IPV4) ? 32 : 128))) { |
503 | PRINT_WARN("Invalid mask bits for ipato_addx/delx !\n"); | ||
504 | return -EINVAL; | 485 | return -EINVAL; |
505 | } | 486 | } |
506 | return 0; | 487 | return 0; |
@@ -520,7 +501,6 @@ static ssize_t qeth_l3_dev_ipato_add_store(const char *buf, size_t count, | |||
520 | 501 | ||
521 | ipatoe = kzalloc(sizeof(struct qeth_ipato_entry), GFP_KERNEL); | 502 | ipatoe = kzalloc(sizeof(struct qeth_ipato_entry), GFP_KERNEL); |
522 | if (!ipatoe) { | 503 | if (!ipatoe) { |
523 | PRINT_WARN("No memory to allocate ipato entry\n"); | ||
524 | return -ENOMEM; | 504 | return -ENOMEM; |
525 | } | 505 | } |
526 | ipatoe->proto = proto; | 506 | ipatoe->proto = proto; |
@@ -609,8 +589,6 @@ static ssize_t qeth_l3_dev_ipato_invert6_store(struct device *dev, | |||
609 | } else if (!strcmp(tmp, "0")) { | 589 | } else if (!strcmp(tmp, "0")) { |
610 | card->ipato.invert6 = 0; | 590 | card->ipato.invert6 = 0; |
611 | } else { | 591 | } else { |
612 | PRINT_WARN("ipato_invert6: write 0, 1 or 'toggle' to " | ||
613 | "this file\n"); | ||
614 | return -EINVAL; | 592 | return -EINVAL; |
615 | } | 593 | } |
616 | return count; | 594 | return count; |
@@ -724,7 +702,6 @@ static int qeth_l3_parse_vipae(const char *buf, enum qeth_prot_versions proto, | |||
724 | u8 *addr) | 702 | u8 *addr) |
725 | { | 703 | { |
726 | if (qeth_l3_string_to_ipaddr(buf, proto, addr)) { | 704 | if (qeth_l3_string_to_ipaddr(buf, proto, addr)) { |
727 | PRINT_WARN("Invalid IP address format!\n"); | ||
728 | return -EINVAL; | 705 | return -EINVAL; |
729 | } | 706 | } |
730 | return 0; | 707 | return 0; |
@@ -891,7 +868,6 @@ static int qeth_l3_parse_rxipe(const char *buf, enum qeth_prot_versions proto, | |||
891 | u8 *addr) | 868 | u8 *addr) |
892 | { | 869 | { |
893 | if (qeth_l3_string_to_ipaddr(buf, proto, addr)) { | 870 | if (qeth_l3_string_to_ipaddr(buf, proto, addr)) { |
894 | PRINT_WARN("Invalid IP address format!\n"); | ||
895 | return -EINVAL; | 871 | return -EINVAL; |
896 | } | 872 | } |
897 | return 0; | 873 | return 0; |
diff --git a/drivers/s390/s390mach.c b/drivers/s390/s390mach.c index 5080f343ad74..5bfbe7659830 100644 --- a/drivers/s390/s390mach.c +++ b/drivers/s390/s390mach.c | |||
@@ -207,6 +207,7 @@ s390_handle_mcck(void) | |||
207 | do_exit(SIGSEGV); | 207 | do_exit(SIGSEGV); |
208 | } | 208 | } |
209 | } | 209 | } |
210 | EXPORT_SYMBOL_GPL(s390_handle_mcck); | ||
210 | 211 | ||
211 | /* | 212 | /* |
212 | * returns 0 if all registers could be validated | 213 | * returns 0 if all registers could be validated |
diff --git a/drivers/sbus/char/bpp.c b/drivers/sbus/char/bpp.c index b87037ec9805..03c966059471 100644 --- a/drivers/sbus/char/bpp.c +++ b/drivers/sbus/char/bpp.c | |||
@@ -869,7 +869,7 @@ static void probeLptPort(unsigned idx) | |||
869 | instances[idx].mode = COMPATIBILITY; | 869 | instances[idx].mode = COMPATIBILITY; |
870 | instances[idx].run_length = 0; | 870 | instances[idx].run_length = 0; |
871 | instances[idx].run_flag = 0; | 871 | instances[idx].run_flag = 0; |
872 | if (!request_region(lpAddr,3, dev_name)) return; | 872 | if (!request_region(lpAddr,3, bpp_dev_name)) return; |
873 | 873 | ||
874 | /* | 874 | /* |
875 | * First, make sure the instance exists. Do this by writing to | 875 | * First, make sure the instance exists. Do this by writing to |
@@ -1021,7 +1021,7 @@ static int __init bpp_init(void) | |||
1021 | if (rc == 0) | 1021 | if (rc == 0) |
1022 | return -ENODEV; | 1022 | return -ENODEV; |
1023 | 1023 | ||
1024 | rc = register_chrdev(BPP_MAJOR, dev_name, &bpp_fops); | 1024 | rc = register_chrdev(BPP_MAJOR, bpp_dev_name, &bpp_fops); |
1025 | if (rc < 0) | 1025 | if (rc < 0) |
1026 | return rc; | 1026 | return rc; |
1027 | 1027 | ||
@@ -1037,7 +1037,7 @@ static void __exit bpp_cleanup(void) | |||
1037 | { | 1037 | { |
1038 | unsigned idx; | 1038 | unsigned idx; |
1039 | 1039 | ||
1040 | unregister_chrdev(BPP_MAJOR, dev_name); | 1040 | unregister_chrdev(BPP_MAJOR, bpp_dev_name); |
1041 | 1041 | ||
1042 | for (idx = 0; idx < BPP_NO; idx++) { | 1042 | for (idx = 0; idx < BPP_NO; idx++) { |
1043 | if (instances[idx].present) | 1043 | if (instances[idx].present) |
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c index b31faeccb9cd..867f6fd5c2c0 100644 --- a/drivers/scsi/3w-9xxx.c +++ b/drivers/scsi/3w-9xxx.c | |||
@@ -1278,7 +1278,7 @@ static irqreturn_t twa_interrupt(int irq, void *dev_instance) | |||
1278 | error = 0; | 1278 | error = 0; |
1279 | /* Check for command packet errors */ | 1279 | /* Check for command packet errors */ |
1280 | if (full_command_packet->command.newcommand.status != 0) { | 1280 | if (full_command_packet->command.newcommand.status != 0) { |
1281 | if (tw_dev->srb[request_id] != 0) { | 1281 | if (tw_dev->srb[request_id] != NULL) { |
1282 | error = twa_fill_sense(tw_dev, request_id, 1, 1); | 1282 | error = twa_fill_sense(tw_dev, request_id, 1, 1); |
1283 | } else { | 1283 | } else { |
1284 | /* Skip ioctl error prints */ | 1284 | /* Skip ioctl error prints */ |
@@ -1290,7 +1290,7 @@ static irqreturn_t twa_interrupt(int irq, void *dev_instance) | |||
1290 | 1290 | ||
1291 | /* Check for correct state */ | 1291 | /* Check for correct state */ |
1292 | if (tw_dev->state[request_id] != TW_S_POSTED) { | 1292 | if (tw_dev->state[request_id] != TW_S_POSTED) { |
1293 | if (tw_dev->srb[request_id] != 0) { | 1293 | if (tw_dev->srb[request_id] != NULL) { |
1294 | TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1a, "Received a request id that wasn't posted"); | 1294 | TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1a, "Received a request id that wasn't posted"); |
1295 | TW_CLEAR_ALL_INTERRUPTS(tw_dev); | 1295 | TW_CLEAR_ALL_INTERRUPTS(tw_dev); |
1296 | goto twa_interrupt_bail; | 1296 | goto twa_interrupt_bail; |
@@ -1298,7 +1298,7 @@ static irqreturn_t twa_interrupt(int irq, void *dev_instance) | |||
1298 | } | 1298 | } |
1299 | 1299 | ||
1300 | /* Check for internal command completion */ | 1300 | /* Check for internal command completion */ |
1301 | if (tw_dev->srb[request_id] == 0) { | 1301 | if (tw_dev->srb[request_id] == NULL) { |
1302 | if (request_id != tw_dev->chrdev_request_id) { | 1302 | if (request_id != tw_dev->chrdev_request_id) { |
1303 | if (twa_aen_complete(tw_dev, request_id)) | 1303 | if (twa_aen_complete(tw_dev, request_id)) |
1304 | TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1b, "Error completing AEN during attention interrupt"); | 1304 | TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1b, "Error completing AEN during attention interrupt"); |
diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c index 1dca1775f4b1..0899cb61e3dd 100644 --- a/drivers/scsi/aha152x.c +++ b/drivers/scsi/aha152x.c | |||
@@ -3582,7 +3582,7 @@ static int checksetup(struct aha152x_setup *setup) | |||
3582 | if (i == ARRAY_SIZE(ports)) | 3582 | if (i == ARRAY_SIZE(ports)) |
3583 | return 0; | 3583 | return 0; |
3584 | 3584 | ||
3585 | if ( request_region(setup->io_port, IO_RANGE, "aha152x")==0 ) { | 3585 | if (!request_region(setup->io_port, IO_RANGE, "aha152x")) { |
3586 | printk(KERN_ERR "aha152x: io port 0x%x busy.\n", setup->io_port); | 3586 | printk(KERN_ERR "aha152x: io port 0x%x busy.\n", setup->io_port); |
3587 | return 0; | 3587 | return 0; |
3588 | } | 3588 | } |
@@ -3842,7 +3842,7 @@ static int __init aha152x_init(void) | |||
3842 | if ((setup_count == 1) && (setup[0].io_port == ports[i])) | 3842 | if ((setup_count == 1) && (setup[0].io_port == ports[i])) |
3843 | continue; | 3843 | continue; |
3844 | 3844 | ||
3845 | if ( request_region(ports[i], IO_RANGE, "aha152x")==0 ) { | 3845 | if (!request_region(ports[i], IO_RANGE, "aha152x")) { |
3846 | printk(KERN_ERR "aha152x: io port 0x%x busy.\n", ports[i]); | 3846 | printk(KERN_ERR "aha152x: io port 0x%x busy.\n", ports[i]); |
3847 | continue; | 3847 | continue; |
3848 | } | 3848 | } |
diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index db6de5e6afb3..7d311541c76c 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c | |||
@@ -747,7 +747,7 @@ static void send_s870(struct atp_unit *dev,unsigned char c) | |||
747 | dev->quhd[c] = 0; | 747 | dev->quhd[c] = 0; |
748 | } | 748 | } |
749 | workreq = dev->quereq[c][dev->quhd[c]]; | 749 | workreq = dev->quereq[c][dev->quhd[c]]; |
750 | if (dev->id[c][scmd_id(workreq)].curr_req == 0) { | 750 | if (dev->id[c][scmd_id(workreq)].curr_req == NULL) { |
751 | dev->id[c][scmd_id(workreq)].curr_req = workreq; | 751 | dev->id[c][scmd_id(workreq)].curr_req = workreq; |
752 | dev->last_cmd[c] = scmd_id(workreq); | 752 | dev->last_cmd[c] = scmd_id(workreq); |
753 | goto cmd_subp; | 753 | goto cmd_subp; |
diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c index 75c84d7b9ce8..c4b938bc30d3 100644 --- a/drivers/scsi/ch.c +++ b/drivers/scsi/ch.c | |||
@@ -910,9 +910,9 @@ static int ch_probe(struct device *dev) | |||
910 | ch->minor = minor; | 910 | ch->minor = minor; |
911 | sprintf(ch->name,"ch%d",ch->minor); | 911 | sprintf(ch->name,"ch%d",ch->minor); |
912 | 912 | ||
913 | class_dev = device_create(ch_sysfs_class, dev, | 913 | class_dev = device_create_drvdata(ch_sysfs_class, dev, |
914 | MKDEV(SCSI_CHANGER_MAJOR,ch->minor), | 914 | MKDEV(SCSI_CHANGER_MAJOR, ch->minor), |
915 | "s%s", ch->name); | 915 | ch, "s%s", ch->name); |
916 | if (IS_ERR(class_dev)) { | 916 | if (IS_ERR(class_dev)) { |
917 | printk(KERN_WARNING "ch%d: device_create failed\n", | 917 | printk(KERN_WARNING "ch%d: device_create failed\n", |
918 | ch->minor); | 918 | ch->minor); |
@@ -926,7 +926,6 @@ static int ch_probe(struct device *dev) | |||
926 | if (init) | 926 | if (init) |
927 | ch_init_elem(ch); | 927 | ch_init_elem(ch); |
928 | 928 | ||
929 | dev_set_drvdata(dev, ch); | ||
930 | sdev_printk(KERN_INFO, sd, "Attached scsi changer %s\n", ch->name); | 929 | sdev_printk(KERN_INFO, sd, "Attached scsi changer %s\n", ch->name); |
931 | 930 | ||
932 | return 0; | 931 | return 0; |
diff --git a/drivers/scsi/hptiop.c b/drivers/scsi/hptiop.c index aaa48e0c8ed0..da876d3924be 100644 --- a/drivers/scsi/hptiop.c +++ b/drivers/scsi/hptiop.c | |||
@@ -444,7 +444,7 @@ static void __iomem *hptiop_map_pci_bar(struct hptiop_hba *hba, int index) | |||
444 | if (!(pci_resource_flags(pcidev, index) & IORESOURCE_MEM)) { | 444 | if (!(pci_resource_flags(pcidev, index) & IORESOURCE_MEM)) { |
445 | printk(KERN_ERR "scsi%d: pci resource invalid\n", | 445 | printk(KERN_ERR "scsi%d: pci resource invalid\n", |
446 | hba->host->host_no); | 446 | hba->host->host_no); |
447 | return 0; | 447 | return NULL; |
448 | } | 448 | } |
449 | 449 | ||
450 | mem_base_phy = pci_resource_start(pcidev, index); | 450 | mem_base_phy = pci_resource_start(pcidev, index); |
@@ -454,7 +454,7 @@ static void __iomem *hptiop_map_pci_bar(struct hptiop_hba *hba, int index) | |||
454 | if (!mem_base_virt) { | 454 | if (!mem_base_virt) { |
455 | printk(KERN_ERR "scsi%d: Fail to ioremap memory space\n", | 455 | printk(KERN_ERR "scsi%d: Fail to ioremap memory space\n", |
456 | hba->host->host_no); | 456 | hba->host->host_no); |
457 | return 0; | 457 | return NULL; |
458 | } | 458 | } |
459 | return mem_base_virt; | 459 | return mem_base_virt; |
460 | } | 460 | } |
@@ -476,11 +476,11 @@ static void hptiop_unmap_pci_bar_itl(struct hptiop_hba *hba) | |||
476 | static int hptiop_map_pci_bar_mv(struct hptiop_hba *hba) | 476 | static int hptiop_map_pci_bar_mv(struct hptiop_hba *hba) |
477 | { | 477 | { |
478 | hba->u.mv.regs = hptiop_map_pci_bar(hba, 0); | 478 | hba->u.mv.regs = hptiop_map_pci_bar(hba, 0); |
479 | if (hba->u.mv.regs == 0) | 479 | if (hba->u.mv.regs == NULL) |
480 | return -1; | 480 | return -1; |
481 | 481 | ||
482 | hba->u.mv.mu = hptiop_map_pci_bar(hba, 2); | 482 | hba->u.mv.mu = hptiop_map_pci_bar(hba, 2); |
483 | if (hba->u.mv.mu == 0) { | 483 | if (hba->u.mv.mu == NULL) { |
484 | iounmap(hba->u.mv.regs); | 484 | iounmap(hba->u.mv.regs); |
485 | return -1; | 485 | return -1; |
486 | } | 486 | } |
@@ -1210,8 +1210,8 @@ static void hptiop_remove(struct pci_dev *pcidev) | |||
1210 | 1210 | ||
1211 | static struct hptiop_adapter_ops hptiop_itl_ops = { | 1211 | static struct hptiop_adapter_ops hptiop_itl_ops = { |
1212 | .iop_wait_ready = iop_wait_ready_itl, | 1212 | .iop_wait_ready = iop_wait_ready_itl, |
1213 | .internal_memalloc = 0, | 1213 | .internal_memalloc = NULL, |
1214 | .internal_memfree = 0, | 1214 | .internal_memfree = NULL, |
1215 | .map_pci_bar = hptiop_map_pci_bar_itl, | 1215 | .map_pci_bar = hptiop_map_pci_bar_itl, |
1216 | .unmap_pci_bar = hptiop_unmap_pci_bar_itl, | 1216 | .unmap_pci_bar = hptiop_unmap_pci_bar_itl, |
1217 | .enable_intr = hptiop_enable_intr_itl, | 1217 | .enable_intr = hptiop_enable_intr_itl, |
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index ccfd8aca3765..5d23368a1bce 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c | |||
@@ -1348,7 +1348,7 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq, | |||
1348 | 1348 | ||
1349 | del_timer(&evt_struct->timer); | 1349 | del_timer(&evt_struct->timer); |
1350 | 1350 | ||
1351 | if (crq->status != VIOSRP_OK && evt_struct->cmnd) | 1351 | if ((crq->status != VIOSRP_OK && crq->status != VIOSRP_OK2) && evt_struct->cmnd) |
1352 | evt_struct->cmnd->result = DID_ERROR << 16; | 1352 | evt_struct->cmnd->result = DID_ERROR << 16; |
1353 | if (evt_struct->done) | 1353 | if (evt_struct->done) |
1354 | evt_struct->done(evt_struct); | 1354 | evt_struct->done(evt_struct); |
diff --git a/drivers/scsi/ibmvscsi/viosrp.h b/drivers/scsi/ibmvscsi/viosrp.h index 4c4aadb3e405..204604501ad8 100644 --- a/drivers/scsi/ibmvscsi/viosrp.h +++ b/drivers/scsi/ibmvscsi/viosrp.h | |||
@@ -65,7 +65,8 @@ enum viosrp_crq_status { | |||
65 | VIOSRP_VIOLATES_MAX_XFER = 0x2, | 65 | VIOSRP_VIOLATES_MAX_XFER = 0x2, |
66 | VIOSRP_PARTNER_PANIC = 0x3, | 66 | VIOSRP_PARTNER_PANIC = 0x3, |
67 | VIOSRP_DEVICE_BUSY = 0x8, | 67 | VIOSRP_DEVICE_BUSY = 0x8, |
68 | VIOSRP_ADAPTER_FAIL = 0x10 | 68 | VIOSRP_ADAPTER_FAIL = 0x10, |
69 | VIOSRP_OK2 = 0x99, | ||
69 | }; | 70 | }; |
70 | 71 | ||
71 | struct viosrp_crq { | 72 | struct viosrp_crq { |
diff --git a/drivers/scsi/mac_esp.c b/drivers/scsi/mac_esp.c index cd37bd69a115..887682a24e36 100644 --- a/drivers/scsi/mac_esp.c +++ b/drivers/scsi/mac_esp.c | |||
@@ -650,7 +650,7 @@ static void __exit mac_esp_exit(void) | |||
650 | 650 | ||
651 | MODULE_DESCRIPTION("Mac ESP SCSI driver"); | 651 | MODULE_DESCRIPTION("Mac ESP SCSI driver"); |
652 | MODULE_AUTHOR("Finn Thain <fthain@telegraphics.com.au>"); | 652 | MODULE_AUTHOR("Finn Thain <fthain@telegraphics.com.au>"); |
653 | MODULE_LICENSE("GPLv2"); | 653 | MODULE_LICENSE("GPL v2"); |
654 | MODULE_VERSION(DRV_VERSION); | 654 | MODULE_VERSION(DRV_VERSION); |
655 | 655 | ||
656 | module_init(mac_esp_init); | 656 | module_init(mac_esp_init); |
diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c index 31f7aec44d90..243d8becd30f 100644 --- a/drivers/scsi/osst.c +++ b/drivers/scsi/osst.c | |||
@@ -5695,13 +5695,12 @@ static int osst_sysfs_add(dev_t dev, struct device *device, struct osst_tape * S | |||
5695 | struct device *osst_member; | 5695 | struct device *osst_member; |
5696 | int err; | 5696 | int err; |
5697 | 5697 | ||
5698 | osst_member = device_create(osst_sysfs_class, device, dev, "%s", name); | 5698 | osst_member = device_create_drvdata(osst_sysfs_class, device, dev, STp, "%s", name); |
5699 | if (IS_ERR(osst_member)) { | 5699 | if (IS_ERR(osst_member)) { |
5700 | printk(KERN_WARNING "osst :W: Unable to add sysfs class member %s\n", name); | 5700 | printk(KERN_WARNING "osst :W: Unable to add sysfs class member %s\n", name); |
5701 | return PTR_ERR(osst_member); | 5701 | return PTR_ERR(osst_member); |
5702 | } | 5702 | } |
5703 | 5703 | ||
5704 | dev_set_drvdata(osst_member, STp); | ||
5705 | err = device_create_file(osst_member, &dev_attr_ADR_rev); | 5704 | err = device_create_file(osst_member, &dev_attr_ADR_rev); |
5706 | if (err) | 5705 | if (err) |
5707 | goto err_out; | 5706 | goto err_out; |
diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c index 51e2f299dbbb..3754ab87f89a 100644 --- a/drivers/scsi/qla1280.c +++ b/drivers/scsi/qla1280.c | |||
@@ -2811,7 +2811,7 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp) | |||
2811 | 2811 | ||
2812 | /* Check for room in outstanding command list. */ | 2812 | /* Check for room in outstanding command list. */ |
2813 | for (cnt = 0; cnt < MAX_OUTSTANDING_COMMANDS && | 2813 | for (cnt = 0; cnt < MAX_OUTSTANDING_COMMANDS && |
2814 | ha->outstanding_cmds[cnt] != 0; cnt++); | 2814 | ha->outstanding_cmds[cnt] != NULL; cnt++); |
2815 | 2815 | ||
2816 | if (cnt >= MAX_OUTSTANDING_COMMANDS) { | 2816 | if (cnt >= MAX_OUTSTANDING_COMMANDS) { |
2817 | status = 1; | 2817 | status = 1; |
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 287690853caf..8dd88fc1244a 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c | |||
@@ -70,6 +70,9 @@ qla2x00_sysfs_write_fw_dump(struct kobject *kobj, | |||
70 | case 2: | 70 | case 2: |
71 | qla2x00_alloc_fw_dump(ha); | 71 | qla2x00_alloc_fw_dump(ha); |
72 | break; | 72 | break; |
73 | case 3: | ||
74 | qla2x00_system_error(ha); | ||
75 | break; | ||
73 | } | 76 | } |
74 | return (count); | 77 | return (count); |
75 | } | 78 | } |
@@ -886,9 +889,13 @@ qla2x00_get_host_speed(struct Scsi_Host *shost) | |||
886 | static void | 889 | static void |
887 | qla2x00_get_host_port_type(struct Scsi_Host *shost) | 890 | qla2x00_get_host_port_type(struct Scsi_Host *shost) |
888 | { | 891 | { |
889 | scsi_qla_host_t *ha = to_qla_parent(shost_priv(shost)); | 892 | scsi_qla_host_t *ha = shost_priv(shost); |
890 | uint32_t port_type = FC_PORTTYPE_UNKNOWN; | 893 | uint32_t port_type = FC_PORTTYPE_UNKNOWN; |
891 | 894 | ||
895 | if (ha->parent) { | ||
896 | fc_host_port_type(shost) = FC_PORTTYPE_NPIV; | ||
897 | return; | ||
898 | } | ||
892 | switch (ha->current_topology) { | 899 | switch (ha->current_topology) { |
893 | case ISP_CFG_NL: | 900 | case ISP_CFG_NL: |
894 | port_type = FC_PORTTYPE_LPORT; | 901 | port_type = FC_PORTTYPE_LPORT; |
@@ -1172,10 +1179,10 @@ qla24xx_vport_delete(struct fc_vport *fc_vport) | |||
1172 | qla24xx_disable_vp(vha); | 1179 | qla24xx_disable_vp(vha); |
1173 | qla24xx_deallocate_vp_id(vha); | 1180 | qla24xx_deallocate_vp_id(vha); |
1174 | 1181 | ||
1175 | down(&ha->vport_sem); | 1182 | mutex_lock(&ha->vport_lock); |
1176 | ha->cur_vport_count--; | 1183 | ha->cur_vport_count--; |
1177 | clear_bit(vha->vp_idx, ha->vp_idx_map); | 1184 | clear_bit(vha->vp_idx, ha->vp_idx_map); |
1178 | up(&ha->vport_sem); | 1185 | mutex_unlock(&ha->vport_lock); |
1179 | 1186 | ||
1180 | kfree(vha->node_name); | 1187 | kfree(vha->node_name); |
1181 | kfree(vha->port_name); | 1188 | kfree(vha->port_name); |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 299eccf6cabd..8dd600013bd1 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -2457,7 +2457,7 @@ typedef struct scsi_qla_host { | |||
2457 | #define MBX_INTR_WAIT 2 | 2457 | #define MBX_INTR_WAIT 2 |
2458 | #define MBX_UPDATE_FLASH_ACTIVE 3 | 2458 | #define MBX_UPDATE_FLASH_ACTIVE 3 |
2459 | 2459 | ||
2460 | struct semaphore vport_sem; /* Virtual port synchronization */ | 2460 | struct mutex vport_lock; /* Virtual port synchronization */ |
2461 | struct completion mbx_cmd_comp; /* Serialize mbx access */ | 2461 | struct completion mbx_cmd_comp; /* Serialize mbx access */ |
2462 | struct completion mbx_intr_comp; /* Used for completion notification */ | 2462 | struct completion mbx_intr_comp; /* Used for completion notification */ |
2463 | 2463 | ||
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index f8827068d30f..9b4bebee6879 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h | |||
@@ -228,6 +228,9 @@ extern int qla24xx_abort_target(struct fc_port *, unsigned int); | |||
228 | extern int qla24xx_lun_reset(struct fc_port *, unsigned int); | 228 | extern int qla24xx_lun_reset(struct fc_port *, unsigned int); |
229 | 229 | ||
230 | extern int | 230 | extern int |
231 | qla2x00_system_error(scsi_qla_host_t *); | ||
232 | |||
233 | extern int | ||
231 | qla2x00_set_serdes_params(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t); | 234 | qla2x00_set_serdes_params(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t); |
232 | 235 | ||
233 | extern int | 236 | extern int |
diff --git a/drivers/scsi/qla2xxx/qla_inline.h b/drivers/scsi/qla2xxx/qla_inline.h index e9bae27737d1..92fafbdbbaab 100644 --- a/drivers/scsi/qla2xxx/qla_inline.h +++ b/drivers/scsi/qla2xxx/qla_inline.h | |||
@@ -34,7 +34,11 @@ qla2x00_debounce_register(volatile uint16_t __iomem *addr) | |||
34 | static inline void | 34 | static inline void |
35 | qla2x00_poll(scsi_qla_host_t *ha) | 35 | qla2x00_poll(scsi_qla_host_t *ha) |
36 | { | 36 | { |
37 | unsigned long flags; | ||
38 | |||
39 | local_irq_save(flags); | ||
37 | ha->isp_ops->intr_handler(0, ha); | 40 | ha->isp_ops->intr_handler(0, ha); |
41 | local_irq_restore(flags); | ||
38 | } | 42 | } |
39 | 43 | ||
40 | static __inline__ scsi_qla_host_t * | 44 | static __inline__ scsi_qla_host_t * |
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 5d9a64a7879b..ec63b79f900a 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
@@ -272,8 +272,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
272 | uint32_t rscn_entry, host_pid; | 272 | uint32_t rscn_entry, host_pid; |
273 | uint8_t rscn_queue_index; | 273 | uint8_t rscn_queue_index; |
274 | unsigned long flags; | 274 | unsigned long flags; |
275 | scsi_qla_host_t *vha; | ||
276 | int i; | ||
277 | 275 | ||
278 | /* Setup to process RIO completion. */ | 276 | /* Setup to process RIO completion. */ |
279 | handle_cnt = 0; | 277 | handle_cnt = 0; |
@@ -544,18 +542,10 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
544 | break; | 542 | break; |
545 | 543 | ||
546 | case MBA_PORT_UPDATE: /* Port database update */ | 544 | case MBA_PORT_UPDATE: /* Port database update */ |
547 | if ((ha->flags.npiv_supported) && (ha->num_vhosts)) { | 545 | /* Only handle SCNs for our Vport index. */ |
548 | for_each_mapped_vp_idx(ha, i) { | 546 | if (ha->parent && ha->vp_idx != (mb[3] & 0xff)) |
549 | list_for_each_entry(vha, &ha->vp_list, | 547 | break; |
550 | vp_list) { | 548 | |
551 | if ((mb[3] & 0xff) | ||
552 | == vha->vp_idx) { | ||
553 | ha = vha; | ||
554 | break; | ||
555 | } | ||
556 | } | ||
557 | } | ||
558 | } | ||
559 | /* | 549 | /* |
560 | * If PORT UPDATE is global (recieved LIP_OCCURED/LIP_RESET | 550 | * If PORT UPDATE is global (recieved LIP_OCCURED/LIP_RESET |
561 | * event etc. earlier indicating loop is down) then process | 551 | * event etc. earlier indicating loop is down) then process |
@@ -590,18 +580,12 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
590 | break; | 580 | break; |
591 | 581 | ||
592 | case MBA_RSCN_UPDATE: /* State Change Registration */ | 582 | case MBA_RSCN_UPDATE: /* State Change Registration */ |
593 | if ((ha->flags.npiv_supported) && (ha->num_vhosts)) { | 583 | /* Check if the Vport has issued a SCR */ |
594 | for_each_mapped_vp_idx(ha, i) { | 584 | if (ha->parent && test_bit(VP_SCR_NEEDED, &ha->vp_flags)) |
595 | list_for_each_entry(vha, &ha->vp_list, | 585 | break; |
596 | vp_list) { | 586 | /* Only handle SCNs for our Vport index. */ |
597 | if ((mb[3] & 0xff) | 587 | if (ha->parent && ha->vp_idx != (mb[3] & 0xff)) |
598 | == vha->vp_idx) { | 588 | break; |
599 | ha = vha; | ||
600 | break; | ||
601 | } | ||
602 | } | ||
603 | } | ||
604 | } | ||
605 | 589 | ||
606 | DEBUG2(printk("scsi(%ld): Asynchronous RSCR UPDATE.\n", | 590 | DEBUG2(printk("scsi(%ld): Asynchronous RSCR UPDATE.\n", |
607 | ha->host_no)); | 591 | ha->host_no)); |
@@ -1132,25 +1116,6 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) | |||
1132 | break; | 1116 | break; |
1133 | 1117 | ||
1134 | qla2x00_handle_sense(sp, sense_data, sense_len); | 1118 | qla2x00_handle_sense(sp, sense_data, sense_len); |
1135 | |||
1136 | /* | ||
1137 | * In case of a Underrun condition, set both the lscsi | ||
1138 | * status and the completion status to appropriate | ||
1139 | * values. | ||
1140 | */ | ||
1141 | if (resid && | ||
1142 | ((unsigned)(scsi_bufflen(cp) - resid) < | ||
1143 | cp->underflow)) { | ||
1144 | DEBUG2(qla_printk(KERN_INFO, ha, | ||
1145 | "scsi(%ld:%d:%d:%d): Mid-layer underflow " | ||
1146 | "detected (%x of %x bytes)...returning " | ||
1147 | "error status.\n", ha->host_no, | ||
1148 | cp->device->channel, cp->device->id, | ||
1149 | cp->device->lun, resid, | ||
1150 | scsi_bufflen(cp))); | ||
1151 | |||
1152 | cp->result = DID_ERROR << 16 | lscsi_status; | ||
1153 | } | ||
1154 | } else { | 1119 | } else { |
1155 | /* | 1120 | /* |
1156 | * If RISC reports underrun and target does not report | 1121 | * If RISC reports underrun and target does not report |
@@ -1639,12 +1604,12 @@ qla24xx_msix_rsp_q(int irq, void *dev_id) | |||
1639 | ha = dev_id; | 1604 | ha = dev_id; |
1640 | reg = &ha->iobase->isp24; | 1605 | reg = &ha->iobase->isp24; |
1641 | 1606 | ||
1642 | spin_lock(&ha->hardware_lock); | 1607 | spin_lock_irq(&ha->hardware_lock); |
1643 | 1608 | ||
1644 | qla24xx_process_response_queue(ha); | 1609 | qla24xx_process_response_queue(ha); |
1645 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); | 1610 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); |
1646 | 1611 | ||
1647 | spin_unlock(&ha->hardware_lock); | 1612 | spin_unlock_irq(&ha->hardware_lock); |
1648 | 1613 | ||
1649 | return IRQ_HANDLED; | 1614 | return IRQ_HANDLED; |
1650 | } | 1615 | } |
@@ -1663,7 +1628,7 @@ qla24xx_msix_default(int irq, void *dev_id) | |||
1663 | reg = &ha->iobase->isp24; | 1628 | reg = &ha->iobase->isp24; |
1664 | status = 0; | 1629 | status = 0; |
1665 | 1630 | ||
1666 | spin_lock(&ha->hardware_lock); | 1631 | spin_lock_irq(&ha->hardware_lock); |
1667 | do { | 1632 | do { |
1668 | stat = RD_REG_DWORD(®->host_status); | 1633 | stat = RD_REG_DWORD(®->host_status); |
1669 | if (stat & HSRX_RISC_PAUSED) { | 1634 | if (stat & HSRX_RISC_PAUSED) { |
@@ -1716,7 +1681,7 @@ qla24xx_msix_default(int irq, void *dev_id) | |||
1716 | } | 1681 | } |
1717 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); | 1682 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); |
1718 | } while (0); | 1683 | } while (0); |
1719 | spin_unlock(&ha->hardware_lock); | 1684 | spin_unlock_irq(&ha->hardware_lock); |
1720 | 1685 | ||
1721 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && | 1686 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && |
1722 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { | 1687 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { |
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 210060420809..250d2f604397 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c | |||
@@ -2303,8 +2303,6 @@ qla24xx_lun_reset(struct fc_port *fcport, unsigned int l) | |||
2303 | return __qla24xx_issue_tmf("Lun", TCF_LUN_RESET, fcport, l); | 2303 | return __qla24xx_issue_tmf("Lun", TCF_LUN_RESET, fcport, l); |
2304 | } | 2304 | } |
2305 | 2305 | ||
2306 | #if 0 | ||
2307 | |||
2308 | int | 2306 | int |
2309 | qla2x00_system_error(scsi_qla_host_t *ha) | 2307 | qla2x00_system_error(scsi_qla_host_t *ha) |
2310 | { | 2308 | { |
@@ -2312,7 +2310,7 @@ qla2x00_system_error(scsi_qla_host_t *ha) | |||
2312 | mbx_cmd_t mc; | 2310 | mbx_cmd_t mc; |
2313 | mbx_cmd_t *mcp = &mc; | 2311 | mbx_cmd_t *mcp = &mc; |
2314 | 2312 | ||
2315 | if (!IS_FWI2_CAPABLE(ha)) | 2313 | if (!IS_QLA23XX(ha) && !IS_FWI2_CAPABLE(ha)) |
2316 | return QLA_FUNCTION_FAILED; | 2314 | return QLA_FUNCTION_FAILED; |
2317 | 2315 | ||
2318 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); | 2316 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); |
@@ -2334,8 +2332,6 @@ qla2x00_system_error(scsi_qla_host_t *ha) | |||
2334 | return rval; | 2332 | return rval; |
2335 | } | 2333 | } |
2336 | 2334 | ||
2337 | #endif /* 0 */ | ||
2338 | |||
2339 | /** | 2335 | /** |
2340 | * qla2x00_set_serdes_params() - | 2336 | * qla2x00_set_serdes_params() - |
2341 | * @ha: HA context | 2337 | * @ha: HA context |
@@ -2508,7 +2504,7 @@ qla2x00_enable_fce_trace(scsi_qla_host_t *ha, dma_addr_t fce_dma, | |||
2508 | if (mb) | 2504 | if (mb) |
2509 | memcpy(mb, mcp->mb, 8 * sizeof(*mb)); | 2505 | memcpy(mb, mcp->mb, 8 * sizeof(*mb)); |
2510 | if (dwords) | 2506 | if (dwords) |
2511 | *dwords = mcp->mb[6]; | 2507 | *dwords = buffers; |
2512 | } | 2508 | } |
2513 | 2509 | ||
2514 | return rval; | 2510 | return rval; |
@@ -2807,9 +2803,9 @@ qla24xx_control_vp(scsi_qla_host_t *vha, int cmd) | |||
2807 | */ | 2803 | */ |
2808 | map = (vp_index - 1) / 8; | 2804 | map = (vp_index - 1) / 8; |
2809 | pos = (vp_index - 1) & 7; | 2805 | pos = (vp_index - 1) & 7; |
2810 | down(&ha->vport_sem); | 2806 | mutex_lock(&ha->vport_lock); |
2811 | vce->vp_idx_map[map] |= 1 << pos; | 2807 | vce->vp_idx_map[map] |= 1 << pos; |
2812 | up(&ha->vport_sem); | 2808 | mutex_unlock(&ha->vport_lock); |
2813 | 2809 | ||
2814 | rval = qla2x00_issue_iocb(ha, vce, vce_dma, 0); | 2810 | rval = qla2x00_issue_iocb(ha, vce, vce_dma, 0); |
2815 | if (rval != QLA_SUCCESS) { | 2811 | if (rval != QLA_SUCCESS) { |
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index f2b04979e5f0..62a3ad6e8ecb 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c | |||
@@ -32,12 +32,12 @@ qla24xx_allocate_vp_id(scsi_qla_host_t *vha) | |||
32 | scsi_qla_host_t *ha = vha->parent; | 32 | scsi_qla_host_t *ha = vha->parent; |
33 | 33 | ||
34 | /* Find an empty slot and assign an vp_id */ | 34 | /* Find an empty slot and assign an vp_id */ |
35 | down(&ha->vport_sem); | 35 | mutex_lock(&ha->vport_lock); |
36 | vp_id = find_first_zero_bit(ha->vp_idx_map, ha->max_npiv_vports + 1); | 36 | vp_id = find_first_zero_bit(ha->vp_idx_map, ha->max_npiv_vports + 1); |
37 | if (vp_id > ha->max_npiv_vports) { | 37 | if (vp_id > ha->max_npiv_vports) { |
38 | DEBUG15(printk ("vp_id %d is bigger than max-supported %d.\n", | 38 | DEBUG15(printk ("vp_id %d is bigger than max-supported %d.\n", |
39 | vp_id, ha->max_npiv_vports)); | 39 | vp_id, ha->max_npiv_vports)); |
40 | up(&ha->vport_sem); | 40 | mutex_unlock(&ha->vport_lock); |
41 | return vp_id; | 41 | return vp_id; |
42 | } | 42 | } |
43 | 43 | ||
@@ -45,7 +45,7 @@ qla24xx_allocate_vp_id(scsi_qla_host_t *vha) | |||
45 | ha->num_vhosts++; | 45 | ha->num_vhosts++; |
46 | vha->vp_idx = vp_id; | 46 | vha->vp_idx = vp_id; |
47 | list_add_tail(&vha->vp_list, &ha->vp_list); | 47 | list_add_tail(&vha->vp_list, &ha->vp_list); |
48 | up(&ha->vport_sem); | 48 | mutex_unlock(&ha->vport_lock); |
49 | return vp_id; | 49 | return vp_id; |
50 | } | 50 | } |
51 | 51 | ||
@@ -55,12 +55,12 @@ qla24xx_deallocate_vp_id(scsi_qla_host_t *vha) | |||
55 | uint16_t vp_id; | 55 | uint16_t vp_id; |
56 | scsi_qla_host_t *ha = vha->parent; | 56 | scsi_qla_host_t *ha = vha->parent; |
57 | 57 | ||
58 | down(&ha->vport_sem); | 58 | mutex_lock(&ha->vport_lock); |
59 | vp_id = vha->vp_idx; | 59 | vp_id = vha->vp_idx; |
60 | ha->num_vhosts--; | 60 | ha->num_vhosts--; |
61 | clear_bit(vp_id, ha->vp_idx_map); | 61 | clear_bit(vp_id, ha->vp_idx_map); |
62 | list_del(&vha->vp_list); | 62 | list_del(&vha->vp_list); |
63 | up(&ha->vport_sem); | 63 | mutex_unlock(&ha->vport_lock); |
64 | } | 64 | } |
65 | 65 | ||
66 | static scsi_qla_host_t * | 66 | static scsi_qla_host_t * |
@@ -145,9 +145,9 @@ qla24xx_enable_vp(scsi_qla_host_t *vha) | |||
145 | } | 145 | } |
146 | 146 | ||
147 | /* Initialize the new vport unless it is a persistent port */ | 147 | /* Initialize the new vport unless it is a persistent port */ |
148 | down(&ha->vport_sem); | 148 | mutex_lock(&ha->vport_lock); |
149 | ret = qla24xx_modify_vp_config(vha); | 149 | ret = qla24xx_modify_vp_config(vha); |
150 | up(&ha->vport_sem); | 150 | mutex_unlock(&ha->vport_lock); |
151 | 151 | ||
152 | if (ret != QLA_SUCCESS) { | 152 | if (ret != QLA_SUCCESS) { |
153 | fc_vport_set_state(vha->fc_vport, FC_VPORT_FAILED); | 153 | fc_vport_set_state(vha->fc_vport, FC_VPORT_FAILED); |
@@ -406,6 +406,7 @@ qla24xx_create_vhost(struct fc_vport *fc_vport) | |||
406 | INIT_LIST_HEAD(&vha->list); | 406 | INIT_LIST_HEAD(&vha->list); |
407 | INIT_LIST_HEAD(&vha->fcports); | 407 | INIT_LIST_HEAD(&vha->fcports); |
408 | INIT_LIST_HEAD(&vha->vp_fcports); | 408 | INIT_LIST_HEAD(&vha->vp_fcports); |
409 | INIT_LIST_HEAD(&vha->work_list); | ||
409 | 410 | ||
410 | vha->dpc_flags = 0L; | 411 | vha->dpc_flags = 0L; |
411 | set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags); | 412 | set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags); |
@@ -437,10 +438,10 @@ qla24xx_create_vhost(struct fc_vport *fc_vport) | |||
437 | vha->flags.init_done = 1; | 438 | vha->flags.init_done = 1; |
438 | num_hosts++; | 439 | num_hosts++; |
439 | 440 | ||
440 | down(&ha->vport_sem); | 441 | mutex_lock(&ha->vport_lock); |
441 | set_bit(vha->vp_idx, ha->vp_idx_map); | 442 | set_bit(vha->vp_idx, ha->vp_idx_map); |
442 | ha->cur_vport_count++; | 443 | ha->cur_vport_count++; |
443 | up(&ha->vport_sem); | 444 | mutex_unlock(&ha->vport_lock); |
444 | 445 | ||
445 | return vha; | 446 | return vha; |
446 | 447 | ||
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 3223fd16bcfe..48eaa3bb5433 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/vmalloc.h> | 10 | #include <linux/vmalloc.h> |
11 | #include <linux/delay.h> | 11 | #include <linux/delay.h> |
12 | #include <linux/kthread.h> | 12 | #include <linux/kthread.h> |
13 | #include <linux/mutex.h> | ||
13 | 14 | ||
14 | #include <scsi/scsi_tcq.h> | 15 | #include <scsi/scsi_tcq.h> |
15 | #include <scsi/scsicam.h> | 16 | #include <scsi/scsicam.h> |
@@ -1631,7 +1632,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1631 | /* load the F/W, read paramaters, and init the H/W */ | 1632 | /* load the F/W, read paramaters, and init the H/W */ |
1632 | ha->instance = num_hosts; | 1633 | ha->instance = num_hosts; |
1633 | 1634 | ||
1634 | init_MUTEX(&ha->vport_sem); | 1635 | mutex_init(&ha->vport_lock); |
1635 | init_completion(&ha->mbx_cmd_comp); | 1636 | init_completion(&ha->mbx_cmd_comp); |
1636 | complete(&ha->mbx_cmd_comp); | 1637 | complete(&ha->mbx_cmd_comp); |
1637 | init_completion(&ha->mbx_intr_comp); | 1638 | init_completion(&ha->mbx_intr_comp); |
@@ -2156,13 +2157,14 @@ static int | |||
2156 | qla2x00_post_work(struct scsi_qla_host *ha, struct qla_work_evt *e, int locked) | 2157 | qla2x00_post_work(struct scsi_qla_host *ha, struct qla_work_evt *e, int locked) |
2157 | { | 2158 | { |
2158 | unsigned long flags; | 2159 | unsigned long flags; |
2160 | scsi_qla_host_t *pha = to_qla_parent(ha); | ||
2159 | 2161 | ||
2160 | if (!locked) | 2162 | if (!locked) |
2161 | spin_lock_irqsave(&ha->hardware_lock, flags); | 2163 | spin_lock_irqsave(&pha->hardware_lock, flags); |
2162 | list_add_tail(&e->list, &ha->work_list); | 2164 | list_add_tail(&e->list, &ha->work_list); |
2163 | qla2xxx_wake_dpc(ha); | 2165 | qla2xxx_wake_dpc(ha); |
2164 | if (!locked) | 2166 | if (!locked) |
2165 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 2167 | spin_unlock_irqrestore(&pha->hardware_lock, flags); |
2166 | return QLA_SUCCESS; | 2168 | return QLA_SUCCESS; |
2167 | } | 2169 | } |
2168 | 2170 | ||
@@ -2202,12 +2204,13 @@ static void | |||
2202 | qla2x00_do_work(struct scsi_qla_host *ha) | 2204 | qla2x00_do_work(struct scsi_qla_host *ha) |
2203 | { | 2205 | { |
2204 | struct qla_work_evt *e; | 2206 | struct qla_work_evt *e; |
2207 | scsi_qla_host_t *pha = to_qla_parent(ha); | ||
2205 | 2208 | ||
2206 | spin_lock_irq(&ha->hardware_lock); | 2209 | spin_lock_irq(&pha->hardware_lock); |
2207 | while (!list_empty(&ha->work_list)) { | 2210 | while (!list_empty(&ha->work_list)) { |
2208 | e = list_entry(ha->work_list.next, struct qla_work_evt, list); | 2211 | e = list_entry(ha->work_list.next, struct qla_work_evt, list); |
2209 | list_del_init(&e->list); | 2212 | list_del_init(&e->list); |
2210 | spin_unlock_irq(&ha->hardware_lock); | 2213 | spin_unlock_irq(&pha->hardware_lock); |
2211 | 2214 | ||
2212 | switch (e->type) { | 2215 | switch (e->type) { |
2213 | case QLA_EVT_AEN: | 2216 | case QLA_EVT_AEN: |
@@ -2221,9 +2224,9 @@ qla2x00_do_work(struct scsi_qla_host *ha) | |||
2221 | } | 2224 | } |
2222 | if (e->flags & QLA_EVT_FLAG_FREE) | 2225 | if (e->flags & QLA_EVT_FLAG_FREE) |
2223 | kfree(e); | 2226 | kfree(e); |
2224 | spin_lock_irq(&ha->hardware_lock); | 2227 | spin_lock_irq(&pha->hardware_lock); |
2225 | } | 2228 | } |
2226 | spin_unlock_irq(&ha->hardware_lock); | 2229 | spin_unlock_irq(&pha->hardware_lock); |
2227 | } | 2230 | } |
2228 | 2231 | ||
2229 | /************************************************************************** | 2232 | /************************************************************************** |
@@ -2634,7 +2637,7 @@ qla2x00_timer(scsi_qla_host_t *ha) | |||
2634 | #define FW_FILE_ISP24XX "ql2400_fw.bin" | 2637 | #define FW_FILE_ISP24XX "ql2400_fw.bin" |
2635 | #define FW_FILE_ISP25XX "ql2500_fw.bin" | 2638 | #define FW_FILE_ISP25XX "ql2500_fw.bin" |
2636 | 2639 | ||
2637 | static DECLARE_MUTEX(qla_fw_lock); | 2640 | static DEFINE_MUTEX(qla_fw_lock); |
2638 | 2641 | ||
2639 | static struct fw_blob qla_fw_blobs[FW_BLOBS] = { | 2642 | static struct fw_blob qla_fw_blobs[FW_BLOBS] = { |
2640 | { .name = FW_FILE_ISP21XX, .segs = { 0x1000, 0 }, }, | 2643 | { .name = FW_FILE_ISP21XX, .segs = { 0x1000, 0 }, }, |
@@ -2665,7 +2668,7 @@ qla2x00_request_firmware(scsi_qla_host_t *ha) | |||
2665 | blob = &qla_fw_blobs[FW_ISP25XX]; | 2668 | blob = &qla_fw_blobs[FW_ISP25XX]; |
2666 | } | 2669 | } |
2667 | 2670 | ||
2668 | down(&qla_fw_lock); | 2671 | mutex_lock(&qla_fw_lock); |
2669 | if (blob->fw) | 2672 | if (blob->fw) |
2670 | goto out; | 2673 | goto out; |
2671 | 2674 | ||
@@ -2678,7 +2681,7 @@ qla2x00_request_firmware(scsi_qla_host_t *ha) | |||
2678 | } | 2681 | } |
2679 | 2682 | ||
2680 | out: | 2683 | out: |
2681 | up(&qla_fw_lock); | 2684 | mutex_unlock(&qla_fw_lock); |
2682 | return blob; | 2685 | return blob; |
2683 | } | 2686 | } |
2684 | 2687 | ||
@@ -2687,11 +2690,11 @@ qla2x00_release_firmware(void) | |||
2687 | { | 2690 | { |
2688 | int idx; | 2691 | int idx; |
2689 | 2692 | ||
2690 | down(&qla_fw_lock); | 2693 | mutex_lock(&qla_fw_lock); |
2691 | for (idx = 0; idx < FW_BLOBS; idx++) | 2694 | for (idx = 0; idx < FW_BLOBS; idx++) |
2692 | if (qla_fw_blobs[idx].fw) | 2695 | if (qla_fw_blobs[idx].fw) |
2693 | release_firmware(qla_fw_blobs[idx].fw); | 2696 | release_firmware(qla_fw_blobs[idx].fw); |
2694 | up(&qla_fw_lock); | 2697 | mutex_unlock(&qla_fw_lock); |
2695 | } | 2698 | } |
2696 | 2699 | ||
2697 | static pci_ers_result_t | 2700 | static pci_ers_result_t |
@@ -2864,7 +2867,8 @@ qla2x00_module_init(void) | |||
2864 | return -ENODEV; | 2867 | return -ENODEV; |
2865 | } | 2868 | } |
2866 | 2869 | ||
2867 | printk(KERN_INFO "QLogic Fibre Channel HBA Driver\n"); | 2870 | printk(KERN_INFO "QLogic Fibre Channel HBA Driver: %s\n", |
2871 | qla2x00_version_str); | ||
2868 | ret = pci_register_driver(&qla2xxx_pci_driver); | 2872 | ret = pci_register_driver(&qla2xxx_pci_driver); |
2869 | if (ret) { | 2873 | if (ret) { |
2870 | kmem_cache_destroy(srb_cachep); | 2874 | kmem_cache_destroy(srb_cachep); |
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index afeae2bfe7eb..d058c8862b35 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h | |||
@@ -7,7 +7,7 @@ | |||
7 | /* | 7 | /* |
8 | * Driver version | 8 | * Driver version |
9 | */ | 9 | */ |
10 | #define QLA2XXX_VERSION "8.02.01-k2" | 10 | #define QLA2XXX_VERSION "8.02.01-k4" |
11 | 11 | ||
12 | #define QLA_DRIVER_MAJOR_VER 8 | 12 | #define QLA_DRIVER_MAJOR_VER 8 |
13 | #define QLA_DRIVER_MINOR_VER 2 | 13 | #define QLA_DRIVER_MINOR_VER 2 |
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 049103f1d16f..93d2b6714453 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c | |||
@@ -359,7 +359,12 @@ static int scsi_bus_match(struct device *dev, struct device_driver *gendrv) | |||
359 | 359 | ||
360 | static int scsi_bus_uevent(struct device *dev, struct kobj_uevent_env *env) | 360 | static int scsi_bus_uevent(struct device *dev, struct kobj_uevent_env *env) |
361 | { | 361 | { |
362 | struct scsi_device *sdev = to_scsi_device(dev); | 362 | struct scsi_device *sdev; |
363 | |||
364 | if (dev->type != &scsi_dev_type) | ||
365 | return 0; | ||
366 | |||
367 | sdev = to_scsi_device(dev); | ||
363 | 368 | ||
364 | add_uevent_var(env, "MODALIAS=" SCSI_DEVICE_MODALIAS_FMT, sdev->type); | 369 | add_uevent_var(env, "MODALIAS=" SCSI_DEVICE_MODALIAS_FMT, sdev->type); |
365 | return 0; | 370 | return 0; |
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index c9d7f721b9e2..ea0edd1b2e76 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c | |||
@@ -1441,17 +1441,18 @@ sg_add(struct device *cl_dev, struct class_interface *cl_intf) | |||
1441 | if (sg_sysfs_valid) { | 1441 | if (sg_sysfs_valid) { |
1442 | struct device *sg_class_member; | 1442 | struct device *sg_class_member; |
1443 | 1443 | ||
1444 | sg_class_member = device_create(sg_sysfs_class, cl_dev->parent, | 1444 | sg_class_member = device_create_drvdata(sg_sysfs_class, |
1445 | MKDEV(SCSI_GENERIC_MAJOR, | 1445 | cl_dev->parent, |
1446 | sdp->index), | 1446 | MKDEV(SCSI_GENERIC_MAJOR, |
1447 | "%s", disk->disk_name); | 1447 | sdp->index), |
1448 | sdp, | ||
1449 | "%s", disk->disk_name); | ||
1448 | if (IS_ERR(sg_class_member)) { | 1450 | if (IS_ERR(sg_class_member)) { |
1449 | printk(KERN_ERR "sg_add: " | 1451 | printk(KERN_ERR "sg_add: " |
1450 | "device_create failed\n"); | 1452 | "device_create failed\n"); |
1451 | error = PTR_ERR(sg_class_member); | 1453 | error = PTR_ERR(sg_class_member); |
1452 | goto cdev_add_err; | 1454 | goto cdev_add_err; |
1453 | } | 1455 | } |
1454 | dev_set_drvdata(sg_class_member, sdp); | ||
1455 | error = sysfs_create_link(&scsidp->sdev_gendev.kobj, | 1456 | error = sysfs_create_link(&scsidp->sdev_gendev.kobj, |
1456 | &sg_class_member->kobj, "generic"); | 1457 | &sg_class_member->kobj, "generic"); |
1457 | if (error) | 1458 | if (error) |
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index e8db66ad0bde..6e5a5bb31311 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c | |||
@@ -4424,17 +4424,19 @@ static int do_create_class_files(struct scsi_tape *STp, int dev_num, int mode) | |||
4424 | snprintf(name, 10, "%s%s%s", rew ? "n" : "", | 4424 | snprintf(name, 10, "%s%s%s", rew ? "n" : "", |
4425 | STp->disk->disk_name, st_formats[i]); | 4425 | STp->disk->disk_name, st_formats[i]); |
4426 | st_class_member = | 4426 | st_class_member = |
4427 | device_create(st_sysfs_class, &STp->device->sdev_gendev, | 4427 | device_create_drvdata(st_sysfs_class, |
4428 | MKDEV(SCSI_TAPE_MAJOR, | 4428 | &STp->device->sdev_gendev, |
4429 | TAPE_MINOR(dev_num, mode, rew)), | 4429 | MKDEV(SCSI_TAPE_MAJOR, |
4430 | "%s", name); | 4430 | TAPE_MINOR(dev_num, |
4431 | mode, rew)), | ||
4432 | &STp->modes[mode], | ||
4433 | "%s", name); | ||
4431 | if (IS_ERR(st_class_member)) { | 4434 | if (IS_ERR(st_class_member)) { |
4432 | printk(KERN_WARNING "st%d: device_create failed\n", | 4435 | printk(KERN_WARNING "st%d: device_create failed\n", |
4433 | dev_num); | 4436 | dev_num); |
4434 | error = PTR_ERR(st_class_member); | 4437 | error = PTR_ERR(st_class_member); |
4435 | goto out; | 4438 | goto out; |
4436 | } | 4439 | } |
4437 | dev_set_drvdata(st_class_member, &STp->modes[mode]); | ||
4438 | 4440 | ||
4439 | error = device_create_file(st_class_member, | 4441 | error = device_create_file(st_class_member, |
4440 | &dev_attr_defined); | 4442 | &dev_attr_defined); |
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index a1ca9b7bf2d5..1bc00b721e9d 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c | |||
@@ -93,7 +93,6 @@ static unsigned int nr_uarts = CONFIG_SERIAL_8250_RUNTIME_UARTS; | |||
93 | #define CONFIG_HUB6 1 | 93 | #define CONFIG_HUB6 1 |
94 | 94 | ||
95 | #include <asm/serial.h> | 95 | #include <asm/serial.h> |
96 | |||
97 | /* | 96 | /* |
98 | * SERIAL_PORT_DFNS tells us about built-in ports that have no | 97 | * SERIAL_PORT_DFNS tells us about built-in ports that have no |
99 | * standard enumeration mechanism. Platforms that can find all | 98 | * standard enumeration mechanism. Platforms that can find all |
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c index 53fa19cf2f06..788c3559522d 100644 --- a/drivers/serial/8250_pci.c +++ b/drivers/serial/8250_pci.c | |||
@@ -2602,7 +2602,12 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
2602 | { PCI_VENDOR_ID_INTASHIELD, PCI_DEVICE_ID_INTASHIELD_IS200, | 2602 | { PCI_VENDOR_ID_INTASHIELD, PCI_DEVICE_ID_INTASHIELD_IS200, |
2603 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, /* 135a.0811 */ | 2603 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, /* 135a.0811 */ |
2604 | pbn_b2_2_115200 }, | 2604 | pbn_b2_2_115200 }, |
2605 | 2605 | /* | |
2606 | * IntaShield IS-400 | ||
2607 | */ | ||
2608 | { PCI_VENDOR_ID_INTASHIELD, PCI_DEVICE_ID_INTASHIELD_IS400, | ||
2609 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, /* 135a.0dc0 */ | ||
2610 | pbn_b2_4_115200 }, | ||
2606 | /* | 2611 | /* |
2607 | * Perle PCI-RAS cards | 2612 | * Perle PCI-RAS cards |
2608 | */ | 2613 | */ |
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 62e6eb136a3c..9bc42763623c 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig | |||
@@ -1361,7 +1361,7 @@ config SERIAL_SC26XX_CONSOLE | |||
1361 | 1361 | ||
1362 | config SERIAL_BFIN_SPORT | 1362 | config SERIAL_BFIN_SPORT |
1363 | tristate "Blackfin SPORT emulate UART (EXPERIMENTAL)" | 1363 | tristate "Blackfin SPORT emulate UART (EXPERIMENTAL)" |
1364 | depends on BFIN && EXPERIMENTAL | 1364 | depends on BLACKFIN && EXPERIMENTAL |
1365 | select SERIAL_CORE | 1365 | select SERIAL_CORE |
1366 | help | 1366 | help |
1367 | Enble support SPORT emulate UART on Blackfin series. | 1367 | Enble support SPORT emulate UART on Blackfin series. |
diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c index c065a704a93a..42be8b01a40f 100644 --- a/drivers/serial/atmel_serial.c +++ b/drivers/serial/atmel_serial.c | |||
@@ -1318,7 +1318,7 @@ static void __init atmel_console_get_options(struct uart_port *port, int *baud, | |||
1318 | * If the baud rate generator isn't running, the port wasn't | 1318 | * If the baud rate generator isn't running, the port wasn't |
1319 | * initialized by the boot loader. | 1319 | * initialized by the boot loader. |
1320 | */ | 1320 | */ |
1321 | quot = UART_GET_BRGR(port); | 1321 | quot = UART_GET_BRGR(port) & ATMEL_US_CD; |
1322 | if (!quot) | 1322 | if (!quot) |
1323 | return; | 1323 | return; |
1324 | 1324 | ||
diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c index d6b4ead693b7..f20952c43cb8 100644 --- a/drivers/serial/bfin_5xx.c +++ b/drivers/serial/bfin_5xx.c | |||
@@ -530,11 +530,7 @@ static unsigned int bfin_serial_get_mctrl(struct uart_port *port) | |||
530 | if (uart->cts_pin < 0) | 530 | if (uart->cts_pin < 0) |
531 | return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; | 531 | return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; |
532 | 532 | ||
533 | # ifdef BF54x | 533 | if (UART_GET_CTS(uart)) |
534 | if (UART_GET_MSR(uart) & CTS) | ||
535 | # else | ||
536 | if (gpio_get_value(uart->cts_pin)) | ||
537 | # endif | ||
538 | return TIOCM_DSR | TIOCM_CAR; | 534 | return TIOCM_DSR | TIOCM_CAR; |
539 | else | 535 | else |
540 | #endif | 536 | #endif |
@@ -549,17 +545,9 @@ static void bfin_serial_set_mctrl(struct uart_port *port, unsigned int mctrl) | |||
549 | return; | 545 | return; |
550 | 546 | ||
551 | if (mctrl & TIOCM_RTS) | 547 | if (mctrl & TIOCM_RTS) |
552 | # ifdef BF54x | 548 | UART_CLEAR_RTS(uart); |
553 | UART_PUT_MCR(uart, UART_GET_MCR(uart) & ~MRTS); | ||
554 | # else | ||
555 | gpio_set_value(uart->rts_pin, 0); | ||
556 | # endif | ||
557 | else | 549 | else |
558 | # ifdef BF54x | 550 | UART_SET_RTS(uart); |
559 | UART_PUT_MCR(uart, UART_GET_MCR(uart) | MRTS); | ||
560 | # else | ||
561 | gpio_set_value(uart->rts_pin, 1); | ||
562 | # endif | ||
563 | #endif | 551 | #endif |
564 | } | 552 | } |
565 | 553 | ||
@@ -752,11 +740,7 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios, | |||
752 | 740 | ||
753 | /* Disable UART */ | 741 | /* Disable UART */ |
754 | ier = UART_GET_IER(uart); | 742 | ier = UART_GET_IER(uart); |
755 | #ifdef CONFIG_BF54x | 743 | UART_DISABLE_INTS(uart); |
756 | UART_CLEAR_IER(uart, 0xF); | ||
757 | #else | ||
758 | UART_PUT_IER(uart, 0); | ||
759 | #endif | ||
760 | 744 | ||
761 | /* Set DLAB in LCR to Access DLL and DLH */ | 745 | /* Set DLAB in LCR to Access DLL and DLH */ |
762 | UART_SET_DLAB(uart); | 746 | UART_SET_DLAB(uart); |
@@ -771,11 +755,7 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios, | |||
771 | UART_PUT_LCR(uart, lcr); | 755 | UART_PUT_LCR(uart, lcr); |
772 | 756 | ||
773 | /* Enable UART */ | 757 | /* Enable UART */ |
774 | #ifdef CONFIG_BF54x | 758 | UART_ENABLE_INTS(uart, ier); |
775 | UART_SET_IER(uart, ier); | ||
776 | #else | ||
777 | UART_PUT_IER(uart, ier); | ||
778 | #endif | ||
779 | 759 | ||
780 | val = UART_GET_GCTL(uart); | 760 | val = UART_GET_GCTL(uart); |
781 | val |= UCEN; | 761 | val |= UCEN; |
@@ -833,15 +813,15 @@ bfin_serial_verify_port(struct uart_port *port, struct serial_struct *ser) | |||
833 | * Enable the IrDA function if tty->ldisc.num is N_IRDA. | 813 | * Enable the IrDA function if tty->ldisc.num is N_IRDA. |
834 | * In other cases, disable IrDA function. | 814 | * In other cases, disable IrDA function. |
835 | */ | 815 | */ |
836 | static void bfin_set_ldisc(struct tty_struct *tty) | 816 | static void bfin_serial_set_ldisc(struct uart_port *port) |
837 | { | 817 | { |
838 | int line = tty->index; | 818 | int line = port->line; |
839 | unsigned short val; | 819 | unsigned short val; |
840 | 820 | ||
841 | if (line >= tty->driver->num) | 821 | if (line >= port->info->tty->driver->num) |
842 | return; | 822 | return; |
843 | 823 | ||
844 | switch (tty->ldisc.num) { | 824 | switch (port->info->tty->ldisc.num) { |
845 | case N_IRDA: | 825 | case N_IRDA: |
846 | val = UART_GET_GCTL(&bfin_serial_ports[line]); | 826 | val = UART_GET_GCTL(&bfin_serial_ports[line]); |
847 | val |= (IREN | RPOLC); | 827 | val |= (IREN | RPOLC); |
@@ -866,6 +846,7 @@ static struct uart_ops bfin_serial_pops = { | |||
866 | .startup = bfin_serial_startup, | 846 | .startup = bfin_serial_startup, |
867 | .shutdown = bfin_serial_shutdown, | 847 | .shutdown = bfin_serial_shutdown, |
868 | .set_termios = bfin_serial_set_termios, | 848 | .set_termios = bfin_serial_set_termios, |
849 | .set_ldisc = bfin_serial_set_ldisc, | ||
869 | .type = bfin_serial_type, | 850 | .type = bfin_serial_type, |
870 | .release_port = bfin_serial_release_port, | 851 | .release_port = bfin_serial_release_port, |
871 | .request_port = bfin_serial_request_port, | 852 | .request_port = bfin_serial_request_port, |
@@ -1206,7 +1187,6 @@ static int __init bfin_serial_init(void) | |||
1206 | 1187 | ||
1207 | ret = uart_register_driver(&bfin_serial_reg); | 1188 | ret = uart_register_driver(&bfin_serial_reg); |
1208 | if (ret == 0) { | 1189 | if (ret == 0) { |
1209 | bfin_serial_reg.tty_driver->set_ldisc = bfin_set_ldisc; | ||
1210 | ret = platform_driver_register(&bfin_serial_driver); | 1190 | ret = platform_driver_register(&bfin_serial_driver); |
1211 | if (ret) { | 1191 | if (ret) { |
1212 | pr_debug("uart register failed\n"); | 1192 | pr_debug("uart register failed\n"); |
diff --git a/drivers/serial/sb1250-duart.c b/drivers/serial/sb1250-duart.c index 2d6c08b3dbcf..f8e1447a022a 100644 --- a/drivers/serial/sb1250-duart.c +++ b/drivers/serial/sb1250-duart.c | |||
@@ -924,7 +924,7 @@ console_initcall(sbd_serial_console_init); | |||
924 | 924 | ||
925 | static struct uart_driver sbd_reg = { | 925 | static struct uart_driver sbd_reg = { |
926 | .owner = THIS_MODULE, | 926 | .owner = THIS_MODULE, |
927 | .driver_name = "serial", | 927 | .driver_name = "sb1250_duart", |
928 | .dev_name = "duart", | 928 | .dev_name = "duart", |
929 | .major = TTY_MAJOR, | 929 | .major = TTY_MAJOR, |
930 | .minor = SB1250_DUART_MINOR_BASE, | 930 | .minor = SB1250_DUART_MINOR_BASE, |
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index eab032733790..c9b64e73c987 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/serial/serial_core.c | |||
@@ -1165,6 +1165,15 @@ out: | |||
1165 | return ret; | 1165 | return ret; |
1166 | } | 1166 | } |
1167 | 1167 | ||
1168 | static void uart_set_ldisc(struct tty_struct *tty) | ||
1169 | { | ||
1170 | struct uart_state *state = tty->driver_data; | ||
1171 | struct uart_port *port = state->port; | ||
1172 | |||
1173 | if (port->ops->set_ldisc) | ||
1174 | port->ops->set_ldisc(port); | ||
1175 | } | ||
1176 | |||
1168 | static void uart_set_termios(struct tty_struct *tty, | 1177 | static void uart_set_termios(struct tty_struct *tty, |
1169 | struct ktermios *old_termios) | 1178 | struct ktermios *old_termios) |
1170 | { | 1179 | { |
@@ -2054,6 +2063,8 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *port) | |||
2054 | int uart_resume_port(struct uart_driver *drv, struct uart_port *port) | 2063 | int uart_resume_port(struct uart_driver *drv, struct uart_port *port) |
2055 | { | 2064 | { |
2056 | struct uart_state *state = drv->state + port->line; | 2065 | struct uart_state *state = drv->state + port->line; |
2066 | struct device *tty_dev; | ||
2067 | struct uart_match match = {port, drv}; | ||
2057 | 2068 | ||
2058 | mutex_lock(&state->mutex); | 2069 | mutex_lock(&state->mutex); |
2059 | 2070 | ||
@@ -2063,7 +2074,8 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port) | |||
2063 | return 0; | 2074 | return 0; |
2064 | } | 2075 | } |
2065 | 2076 | ||
2066 | if (!port->suspended) { | 2077 | tty_dev = device_find_child(port->dev, &match, serial_match_port); |
2078 | if (!port->suspended && device_may_wakeup(tty_dev)) { | ||
2067 | disable_irq_wake(port->irq); | 2079 | disable_irq_wake(port->irq); |
2068 | mutex_unlock(&state->mutex); | 2080 | mutex_unlock(&state->mutex); |
2069 | return 0; | 2081 | return 0; |
@@ -2285,6 +2297,7 @@ static const struct tty_operations uart_ops = { | |||
2285 | .unthrottle = uart_unthrottle, | 2297 | .unthrottle = uart_unthrottle, |
2286 | .send_xchar = uart_send_xchar, | 2298 | .send_xchar = uart_send_xchar, |
2287 | .set_termios = uart_set_termios, | 2299 | .set_termios = uart_set_termios, |
2300 | .set_ldisc = uart_set_ldisc, | ||
2288 | .stop = uart_stop, | 2301 | .stop = uart_stop, |
2289 | .start = uart_start, | 2302 | .start = uart_start, |
2290 | .hangup = uart_hangup, | 2303 | .hangup = uart_hangup, |
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 8fdafc27fce8..ce6ee92b3a1b 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c | |||
@@ -184,15 +184,15 @@ static void put_string(struct sci_port *sci_port, const char *buffer, int count) | |||
184 | int h, l; | 184 | int h, l; |
185 | 185 | ||
186 | c = *p++; | 186 | c = *p++; |
187 | h = highhex(c); | 187 | h = hex_asc_hi(c); |
188 | l = lowhex(c); | 188 | l = hex_asc_lo(c); |
189 | put_char(port, h); | 189 | put_char(port, h); |
190 | put_char(port, l); | 190 | put_char(port, l); |
191 | checksum += h + l; | 191 | checksum += h + l; |
192 | } | 192 | } |
193 | put_char(port, '#'); | 193 | put_char(port, '#'); |
194 | put_char(port, highhex(checksum)); | 194 | put_char(port, hex_asc_hi(checksum)); |
195 | put_char(port, lowhex(checksum)); | 195 | put_char(port, hex_asc_lo(checksum)); |
196 | } while (get_char(port) != '+'); | 196 | } while (get_char(port) != '+'); |
197 | } else | 197 | } else |
198 | #endif /* CONFIG_SH_STANDARD_BIOS || CONFIG_SH_KGDB */ | 198 | #endif /* CONFIG_SH_STANDARD_BIOS || CONFIG_SH_KGDB */ |
diff --git a/drivers/serial/sunhv.c b/drivers/serial/sunhv.c index 145c0281495d..2847336742d7 100644 --- a/drivers/serial/sunhv.c +++ b/drivers/serial/sunhv.c | |||
@@ -499,7 +499,6 @@ static void sunhv_console_write_bychar(struct console *con, const char *s, unsig | |||
499 | } else | 499 | } else |
500 | spin_lock(&port->lock); | 500 | spin_lock(&port->lock); |
501 | 501 | ||
502 | spin_lock_irqsave(&port->lock, flags); | ||
503 | for (i = 0; i < n; i++) { | 502 | for (i = 0; i < n; i++) { |
504 | if (*s == '\n') | 503 | if (*s == '\n') |
505 | sunhv_console_putchar(port, '\r'); | 504 | sunhv_console_putchar(port, '\r'); |
diff --git a/drivers/serial/ucc_uart.c b/drivers/serial/ucc_uart.c index 01917c433f17..566a8b42e05a 100644 --- a/drivers/serial/ucc_uart.c +++ b/drivers/serial/ucc_uart.c | |||
@@ -195,7 +195,7 @@ struct uart_qe_port { | |||
195 | 195 | ||
196 | static struct uart_driver ucc_uart_driver = { | 196 | static struct uart_driver ucc_uart_driver = { |
197 | .owner = THIS_MODULE, | 197 | .owner = THIS_MODULE, |
198 | .driver_name = "serial", | 198 | .driver_name = "ucc_uart", |
199 | .dev_name = "ttyQE", | 199 | .dev_name = "ttyQE", |
200 | .major = SERIAL_QE_MAJOR, | 200 | .major = SERIAL_QE_MAJOR, |
201 | .minor = SERIAL_QE_MINOR, | 201 | .minor = SERIAL_QE_MINOR, |
diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c index b3518ca9f04e..799337f7fde1 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/ioctl.h> | 25 | #include <linux/ioctl.h> |
26 | #include <linux/fs.h> | 26 | #include <linux/fs.h> |
27 | #include <linux/device.h> | 27 | #include <linux/device.h> |
28 | #include <linux/err.h> | ||
28 | #include <linux/list.h> | 29 | #include <linux/list.h> |
29 | #include <linux/errno.h> | 30 | #include <linux/errno.h> |
30 | #include <linux/mutex.h> | 31 | #include <linux/mutex.h> |
@@ -67,10 +68,12 @@ static unsigned long minors[N_SPI_MINORS / BITS_PER_LONG]; | |||
67 | | SPI_LSB_FIRST | SPI_3WIRE | SPI_LOOP) | 68 | | SPI_LSB_FIRST | SPI_3WIRE | SPI_LOOP) |
68 | 69 | ||
69 | struct spidev_data { | 70 | struct spidev_data { |
70 | struct device dev; | 71 | dev_t devt; |
72 | spinlock_t spi_lock; | ||
71 | struct spi_device *spi; | 73 | struct spi_device *spi; |
72 | struct list_head device_entry; | 74 | struct list_head device_entry; |
73 | 75 | ||
76 | /* buffer is NULL unless this device is open (users > 0) */ | ||
74 | struct mutex buf_lock; | 77 | struct mutex buf_lock; |
75 | unsigned users; | 78 | unsigned users; |
76 | u8 *buffer; | 79 | u8 *buffer; |
@@ -85,12 +88,75 @@ MODULE_PARM_DESC(bufsiz, "data bytes in biggest supported SPI message"); | |||
85 | 88 | ||
86 | /*-------------------------------------------------------------------------*/ | 89 | /*-------------------------------------------------------------------------*/ |
87 | 90 | ||
91 | /* | ||
92 | * We can't use the standard synchronous wrappers for file I/O; we | ||
93 | * need to protect against async removal of the underlying spi_device. | ||
94 | */ | ||
95 | static void spidev_complete(void *arg) | ||
96 | { | ||
97 | complete(arg); | ||
98 | } | ||
99 | |||
100 | static ssize_t | ||
101 | spidev_sync(struct spidev_data *spidev, struct spi_message *message) | ||
102 | { | ||
103 | DECLARE_COMPLETION_ONSTACK(done); | ||
104 | int status; | ||
105 | |||
106 | message->complete = spidev_complete; | ||
107 | message->context = &done; | ||
108 | |||
109 | spin_lock_irq(&spidev->spi_lock); | ||
110 | if (spidev->spi == NULL) | ||
111 | status = -ESHUTDOWN; | ||
112 | else | ||
113 | status = spi_async(spidev->spi, message); | ||
114 | spin_unlock_irq(&spidev->spi_lock); | ||
115 | |||
116 | if (status == 0) { | ||
117 | wait_for_completion(&done); | ||
118 | status = message->status; | ||
119 | if (status == 0) | ||
120 | status = message->actual_length; | ||
121 | } | ||
122 | return status; | ||
123 | } | ||
124 | |||
125 | static inline ssize_t | ||
126 | spidev_sync_write(struct spidev_data *spidev, size_t len) | ||
127 | { | ||
128 | struct spi_transfer t = { | ||
129 | .tx_buf = spidev->buffer, | ||
130 | .len = len, | ||
131 | }; | ||
132 | struct spi_message m; | ||
133 | |||
134 | spi_message_init(&m); | ||
135 | spi_message_add_tail(&t, &m); | ||
136 | return spidev_sync(spidev, &m); | ||
137 | } | ||
138 | |||
139 | static inline ssize_t | ||
140 | spidev_sync_read(struct spidev_data *spidev, size_t len) | ||
141 | { | ||
142 | struct spi_transfer t = { | ||
143 | .rx_buf = spidev->buffer, | ||
144 | .len = len, | ||
145 | }; | ||
146 | struct spi_message m; | ||
147 | |||
148 | spi_message_init(&m); | ||
149 | spi_message_add_tail(&t, &m); | ||
150 | return spidev_sync(spidev, &m); | ||
151 | } | ||
152 | |||
153 | /*-------------------------------------------------------------------------*/ | ||
154 | |||
88 | /* Read-only message with current device setup */ | 155 | /* Read-only message with current device setup */ |
89 | static ssize_t | 156 | static ssize_t |
90 | spidev_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) | 157 | spidev_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) |
91 | { | 158 | { |
92 | struct spidev_data *spidev; | 159 | struct spidev_data *spidev; |
93 | struct spi_device *spi; | ||
94 | ssize_t status = 0; | 160 | ssize_t status = 0; |
95 | 161 | ||
96 | /* chipselect only toggles at start or end of operation */ | 162 | /* chipselect only toggles at start or end of operation */ |
@@ -98,10 +164,9 @@ spidev_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) | |||
98 | return -EMSGSIZE; | 164 | return -EMSGSIZE; |
99 | 165 | ||
100 | spidev = filp->private_data; | 166 | spidev = filp->private_data; |
101 | spi = spidev->spi; | ||
102 | 167 | ||
103 | mutex_lock(&spidev->buf_lock); | 168 | mutex_lock(&spidev->buf_lock); |
104 | status = spi_read(spi, spidev->buffer, count); | 169 | status = spidev_sync_read(spidev, count); |
105 | if (status == 0) { | 170 | if (status == 0) { |
106 | unsigned long missing; | 171 | unsigned long missing; |
107 | 172 | ||
@@ -122,7 +187,6 @@ spidev_write(struct file *filp, const char __user *buf, | |||
122 | size_t count, loff_t *f_pos) | 187 | size_t count, loff_t *f_pos) |
123 | { | 188 | { |
124 | struct spidev_data *spidev; | 189 | struct spidev_data *spidev; |
125 | struct spi_device *spi; | ||
126 | ssize_t status = 0; | 190 | ssize_t status = 0; |
127 | unsigned long missing; | 191 | unsigned long missing; |
128 | 192 | ||
@@ -131,12 +195,11 @@ spidev_write(struct file *filp, const char __user *buf, | |||
131 | return -EMSGSIZE; | 195 | return -EMSGSIZE; |
132 | 196 | ||
133 | spidev = filp->private_data; | 197 | spidev = filp->private_data; |
134 | spi = spidev->spi; | ||
135 | 198 | ||
136 | mutex_lock(&spidev->buf_lock); | 199 | mutex_lock(&spidev->buf_lock); |
137 | missing = copy_from_user(spidev->buffer, buf, count); | 200 | missing = copy_from_user(spidev->buffer, buf, count); |
138 | if (missing == 0) { | 201 | if (missing == 0) { |
139 | status = spi_write(spi, spidev->buffer, count); | 202 | status = spidev_sync_write(spidev, count); |
140 | if (status == 0) | 203 | if (status == 0) |
141 | status = count; | 204 | status = count; |
142 | } else | 205 | } else |
@@ -153,7 +216,6 @@ static int spidev_message(struct spidev_data *spidev, | |||
153 | struct spi_transfer *k_xfers; | 216 | struct spi_transfer *k_xfers; |
154 | struct spi_transfer *k_tmp; | 217 | struct spi_transfer *k_tmp; |
155 | struct spi_ioc_transfer *u_tmp; | 218 | struct spi_ioc_transfer *u_tmp; |
156 | struct spi_device *spi = spidev->spi; | ||
157 | unsigned n, total; | 219 | unsigned n, total; |
158 | u8 *buf; | 220 | u8 *buf; |
159 | int status = -EFAULT; | 221 | int status = -EFAULT; |
@@ -215,7 +277,7 @@ static int spidev_message(struct spidev_data *spidev, | |||
215 | spi_message_add_tail(k_tmp, &msg); | 277 | spi_message_add_tail(k_tmp, &msg); |
216 | } | 278 | } |
217 | 279 | ||
218 | status = spi_sync(spi, &msg); | 280 | status = spidev_sync(spidev, &msg); |
219 | if (status < 0) | 281 | if (status < 0) |
220 | goto done; | 282 | goto done; |
221 | 283 | ||
@@ -269,8 +331,16 @@ spidev_ioctl(struct inode *inode, struct file *filp, | |||
269 | if (err) | 331 | if (err) |
270 | return -EFAULT; | 332 | return -EFAULT; |
271 | 333 | ||
334 | /* guard against device removal before, or while, | ||
335 | * we issue this ioctl. | ||
336 | */ | ||
272 | spidev = filp->private_data; | 337 | spidev = filp->private_data; |
273 | spi = spidev->spi; | 338 | spin_lock_irq(&spidev->spi_lock); |
339 | spi = spi_dev_get(spidev->spi); | ||
340 | spin_unlock_irq(&spidev->spi_lock); | ||
341 | |||
342 | if (spi == NULL) | ||
343 | return -ESHUTDOWN; | ||
274 | 344 | ||
275 | switch (cmd) { | 345 | switch (cmd) { |
276 | /* read requests */ | 346 | /* read requests */ |
@@ -356,8 +426,10 @@ spidev_ioctl(struct inode *inode, struct file *filp, | |||
356 | default: | 426 | default: |
357 | /* segmented and/or full-duplex I/O request */ | 427 | /* segmented and/or full-duplex I/O request */ |
358 | if (_IOC_NR(cmd) != _IOC_NR(SPI_IOC_MESSAGE(0)) | 428 | if (_IOC_NR(cmd) != _IOC_NR(SPI_IOC_MESSAGE(0)) |
359 | || _IOC_DIR(cmd) != _IOC_WRITE) | 429 | || _IOC_DIR(cmd) != _IOC_WRITE) { |
360 | return -ENOTTY; | 430 | retval = -ENOTTY; |
431 | break; | ||
432 | } | ||
361 | 433 | ||
362 | tmp = _IOC_SIZE(cmd); | 434 | tmp = _IOC_SIZE(cmd); |
363 | if ((tmp % sizeof(struct spi_ioc_transfer)) != 0) { | 435 | if ((tmp % sizeof(struct spi_ioc_transfer)) != 0) { |
@@ -385,6 +457,7 @@ spidev_ioctl(struct inode *inode, struct file *filp, | |||
385 | kfree(ioc); | 457 | kfree(ioc); |
386 | break; | 458 | break; |
387 | } | 459 | } |
460 | spi_dev_put(spi); | ||
388 | return retval; | 461 | return retval; |
389 | } | 462 | } |
390 | 463 | ||
@@ -396,7 +469,7 @@ static int spidev_open(struct inode *inode, struct file *filp) | |||
396 | mutex_lock(&device_list_lock); | 469 | mutex_lock(&device_list_lock); |
397 | 470 | ||
398 | list_for_each_entry(spidev, &device_list, device_entry) { | 471 | list_for_each_entry(spidev, &device_list, device_entry) { |
399 | if (spidev->dev.devt == inode->i_rdev) { | 472 | if (spidev->devt == inode->i_rdev) { |
400 | status = 0; | 473 | status = 0; |
401 | break; | 474 | break; |
402 | } | 475 | } |
@@ -429,10 +502,22 @@ static int spidev_release(struct inode *inode, struct file *filp) | |||
429 | mutex_lock(&device_list_lock); | 502 | mutex_lock(&device_list_lock); |
430 | spidev = filp->private_data; | 503 | spidev = filp->private_data; |
431 | filp->private_data = NULL; | 504 | filp->private_data = NULL; |
505 | |||
506 | /* last close? */ | ||
432 | spidev->users--; | 507 | spidev->users--; |
433 | if (!spidev->users) { | 508 | if (!spidev->users) { |
509 | int dofree; | ||
510 | |||
434 | kfree(spidev->buffer); | 511 | kfree(spidev->buffer); |
435 | spidev->buffer = NULL; | 512 | spidev->buffer = NULL; |
513 | |||
514 | /* ... after we unbound from the underlying device? */ | ||
515 | spin_lock_irq(&spidev->spi_lock); | ||
516 | dofree = (spidev->spi == NULL); | ||
517 | spin_unlock_irq(&spidev->spi_lock); | ||
518 | |||
519 | if (dofree) | ||
520 | kfree(spidev); | ||
436 | } | 521 | } |
437 | mutex_unlock(&device_list_lock); | 522 | mutex_unlock(&device_list_lock); |
438 | 523 | ||
@@ -459,19 +544,7 @@ static struct file_operations spidev_fops = { | |||
459 | * It also simplifies memory management. | 544 | * It also simplifies memory management. |
460 | */ | 545 | */ |
461 | 546 | ||
462 | static void spidev_classdev_release(struct device *dev) | 547 | static struct class *spidev_class; |
463 | { | ||
464 | struct spidev_data *spidev; | ||
465 | |||
466 | spidev = container_of(dev, struct spidev_data, dev); | ||
467 | kfree(spidev); | ||
468 | } | ||
469 | |||
470 | static struct class spidev_class = { | ||
471 | .name = "spidev", | ||
472 | .owner = THIS_MODULE, | ||
473 | .dev_release = spidev_classdev_release, | ||
474 | }; | ||
475 | 548 | ||
476 | /*-------------------------------------------------------------------------*/ | 549 | /*-------------------------------------------------------------------------*/ |
477 | 550 | ||
@@ -488,6 +561,7 @@ static int spidev_probe(struct spi_device *spi) | |||
488 | 561 | ||
489 | /* Initialize the driver data */ | 562 | /* Initialize the driver data */ |
490 | spidev->spi = spi; | 563 | spidev->spi = spi; |
564 | spin_lock_init(&spidev->spi_lock); | ||
491 | mutex_init(&spidev->buf_lock); | 565 | mutex_init(&spidev->buf_lock); |
492 | 566 | ||
493 | INIT_LIST_HEAD(&spidev->device_entry); | 567 | INIT_LIST_HEAD(&spidev->device_entry); |
@@ -498,20 +572,20 @@ static int spidev_probe(struct spi_device *spi) | |||
498 | mutex_lock(&device_list_lock); | 572 | mutex_lock(&device_list_lock); |
499 | minor = find_first_zero_bit(minors, N_SPI_MINORS); | 573 | minor = find_first_zero_bit(minors, N_SPI_MINORS); |
500 | if (minor < N_SPI_MINORS) { | 574 | if (minor < N_SPI_MINORS) { |
501 | spidev->dev.parent = &spi->dev; | 575 | struct device *dev; |
502 | spidev->dev.class = &spidev_class; | 576 | |
503 | spidev->dev.devt = MKDEV(SPIDEV_MAJOR, minor); | 577 | spidev->devt = MKDEV(SPIDEV_MAJOR, minor); |
504 | snprintf(spidev->dev.bus_id, sizeof spidev->dev.bus_id, | 578 | dev = device_create(spidev_class, &spi->dev, spidev->devt, |
505 | "spidev%d.%d", | 579 | "spidev%d.%d", |
506 | spi->master->bus_num, spi->chip_select); | 580 | spi->master->bus_num, spi->chip_select); |
507 | status = device_register(&spidev->dev); | 581 | status = IS_ERR(dev) ? PTR_ERR(dev) : 0; |
508 | } else { | 582 | } else { |
509 | dev_dbg(&spi->dev, "no minor number available!\n"); | 583 | dev_dbg(&spi->dev, "no minor number available!\n"); |
510 | status = -ENODEV; | 584 | status = -ENODEV; |
511 | } | 585 | } |
512 | if (status == 0) { | 586 | if (status == 0) { |
513 | set_bit(minor, minors); | 587 | set_bit(minor, minors); |
514 | dev_set_drvdata(&spi->dev, spidev); | 588 | spi_set_drvdata(spi, spidev); |
515 | list_add(&spidev->device_entry, &device_list); | 589 | list_add(&spidev->device_entry, &device_list); |
516 | } | 590 | } |
517 | mutex_unlock(&device_list_lock); | 591 | mutex_unlock(&device_list_lock); |
@@ -524,15 +598,21 @@ static int spidev_probe(struct spi_device *spi) | |||
524 | 598 | ||
525 | static int spidev_remove(struct spi_device *spi) | 599 | static int spidev_remove(struct spi_device *spi) |
526 | { | 600 | { |
527 | struct spidev_data *spidev = dev_get_drvdata(&spi->dev); | 601 | struct spidev_data *spidev = spi_get_drvdata(spi); |
528 | 602 | ||
529 | mutex_lock(&device_list_lock); | 603 | /* make sure ops on existing fds can abort cleanly */ |
604 | spin_lock_irq(&spidev->spi_lock); | ||
605 | spidev->spi = NULL; | ||
606 | spi_set_drvdata(spi, NULL); | ||
607 | spin_unlock_irq(&spidev->spi_lock); | ||
530 | 608 | ||
609 | /* prevent new opens */ | ||
610 | mutex_lock(&device_list_lock); | ||
531 | list_del(&spidev->device_entry); | 611 | list_del(&spidev->device_entry); |
532 | dev_set_drvdata(&spi->dev, NULL); | 612 | device_destroy(spidev_class, spidev->devt); |
533 | clear_bit(MINOR(spidev->dev.devt), minors); | 613 | clear_bit(MINOR(spidev->devt), minors); |
534 | device_unregister(&spidev->dev); | 614 | if (spidev->users == 0) |
535 | 615 | kfree(spidev); | |
536 | mutex_unlock(&device_list_lock); | 616 | mutex_unlock(&device_list_lock); |
537 | 617 | ||
538 | return 0; | 618 | return 0; |
@@ -568,15 +648,15 @@ static int __init spidev_init(void) | |||
568 | if (status < 0) | 648 | if (status < 0) |
569 | return status; | 649 | return status; |
570 | 650 | ||
571 | status = class_register(&spidev_class); | 651 | spidev_class = class_create(THIS_MODULE, "spidev"); |
572 | if (status < 0) { | 652 | if (IS_ERR(spidev_class)) { |
573 | unregister_chrdev(SPIDEV_MAJOR, spidev_spi.driver.name); | 653 | unregister_chrdev(SPIDEV_MAJOR, spidev_spi.driver.name); |
574 | return status; | 654 | return PTR_ERR(spidev_class); |
575 | } | 655 | } |
576 | 656 | ||
577 | status = spi_register_driver(&spidev_spi); | 657 | status = spi_register_driver(&spidev_spi); |
578 | if (status < 0) { | 658 | if (status < 0) { |
579 | class_unregister(&spidev_class); | 659 | class_destroy(spidev_class); |
580 | unregister_chrdev(SPIDEV_MAJOR, spidev_spi.driver.name); | 660 | unregister_chrdev(SPIDEV_MAJOR, spidev_spi.driver.name); |
581 | } | 661 | } |
582 | return status; | 662 | return status; |
@@ -586,7 +666,7 @@ module_init(spidev_init); | |||
586 | static void __exit spidev_exit(void) | 666 | static void __exit spidev_exit(void) |
587 | { | 667 | { |
588 | spi_unregister_driver(&spidev_spi); | 668 | spi_unregister_driver(&spidev_spi); |
589 | class_unregister(&spidev_class); | 669 | class_destroy(spidev_class); |
590 | unregister_chrdev(SPIDEV_MAJOR, spidev_spi.driver.name); | 670 | unregister_chrdev(SPIDEV_MAJOR, spidev_spi.driver.name); |
591 | } | 671 | } |
592 | module_exit(spidev_exit); | 672 | module_exit(spidev_exit); |
diff --git a/drivers/ssb/driver_pcicore.c b/drivers/ssb/driver_pcicore.c index 75def13e797d..d28c53868093 100644 --- a/drivers/ssb/driver_pcicore.c +++ b/drivers/ssb/driver_pcicore.c | |||
@@ -537,12 +537,12 @@ int ssb_pcicore_dev_irqvecs_enable(struct ssb_pcicore *pc, | |||
537 | int err = 0; | 537 | int err = 0; |
538 | u32 tmp; | 538 | u32 tmp; |
539 | 539 | ||
540 | might_sleep(); | ||
541 | |||
542 | if (!pdev) | 540 | if (!pdev) |
543 | goto out; | 541 | goto out; |
544 | bus = pdev->bus; | 542 | bus = pdev->bus; |
545 | 543 | ||
544 | might_sleep_if(pdev->id.coreid != SSB_DEV_PCI); | ||
545 | |||
546 | /* Enable interrupts for this device. */ | 546 | /* Enable interrupts for this device. */ |
547 | if (bus->host_pci && | 547 | if (bus->host_pci && |
548 | ((pdev->id.revision >= 6) || (pdev->id.coreid == SSB_DEV_PCIE))) { | 548 | ((pdev->id.revision >= 6) || (pdev->id.coreid == SSB_DEV_PCIE))) { |
diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c index 55cc7b80422a..0a12e90ad416 100644 --- a/drivers/uio/uio.c +++ b/drivers/uio/uio.c | |||
@@ -649,15 +649,14 @@ int __uio_register_device(struct module *owner, | |||
649 | if (ret) | 649 | if (ret) |
650 | goto err_get_minor; | 650 | goto err_get_minor; |
651 | 651 | ||
652 | idev->dev = device_create(uio_class->class, parent, | 652 | idev->dev = device_create_drvdata(uio_class->class, parent, |
653 | MKDEV(uio_major, idev->minor), | 653 | MKDEV(uio_major, idev->minor), idev, |
654 | "uio%d", idev->minor); | 654 | "uio%d", idev->minor); |
655 | if (IS_ERR(idev->dev)) { | 655 | if (IS_ERR(idev->dev)) { |
656 | printk(KERN_ERR "UIO: device register failed\n"); | 656 | printk(KERN_ERR "UIO: device register failed\n"); |
657 | ret = PTR_ERR(idev->dev); | 657 | ret = PTR_ERR(idev->dev); |
658 | goto err_device_create; | 658 | goto err_device_create; |
659 | } | 659 | } |
660 | dev_set_drvdata(idev->dev, idev); | ||
661 | 660 | ||
662 | ret = uio_dev_add_attributes(idev); | 661 | ret = uio_dev_add_attributes(idev); |
663 | if (ret) | 662 | if (ret) |
diff --git a/drivers/usb/c67x00/c67x00-ll-hpi.c b/drivers/usb/c67x00/c67x00-ll-hpi.c index 5100fbbf6cb0..a9636f43bca2 100644 --- a/drivers/usb/c67x00/c67x00-ll-hpi.c +++ b/drivers/usb/c67x00/c67x00-ll-hpi.c | |||
@@ -120,7 +120,7 @@ static void hpi_write_word(struct c67x00_device *dev, u16 reg, u16 value) | |||
120 | * Only data is little endian, addr has cpu endianess | 120 | * Only data is little endian, addr has cpu endianess |
121 | */ | 121 | */ |
122 | static void hpi_write_words_le16(struct c67x00_device *dev, u16 addr, | 122 | static void hpi_write_words_le16(struct c67x00_device *dev, u16 addr, |
123 | u16 *data, u16 count) | 123 | __le16 *data, u16 count) |
124 | { | 124 | { |
125 | unsigned long flags; | 125 | unsigned long flags; |
126 | int i; | 126 | int i; |
@@ -129,7 +129,7 @@ static void hpi_write_words_le16(struct c67x00_device *dev, u16 addr, | |||
129 | 129 | ||
130 | hpi_write_reg(dev, HPI_ADDR, addr); | 130 | hpi_write_reg(dev, HPI_ADDR, addr); |
131 | for (i = 0; i < count; i++) | 131 | for (i = 0; i < count; i++) |
132 | hpi_write_reg(dev, HPI_DATA, cpu_to_le16(*data++)); | 132 | hpi_write_reg(dev, HPI_DATA, le16_to_cpu(*data++)); |
133 | 133 | ||
134 | spin_unlock_irqrestore(&dev->hpi.lock, flags); | 134 | spin_unlock_irqrestore(&dev->hpi.lock, flags); |
135 | } | 135 | } |
@@ -138,7 +138,7 @@ static void hpi_write_words_le16(struct c67x00_device *dev, u16 addr, | |||
138 | * Only data is little endian, addr has cpu endianess | 138 | * Only data is little endian, addr has cpu endianess |
139 | */ | 139 | */ |
140 | static void hpi_read_words_le16(struct c67x00_device *dev, u16 addr, | 140 | static void hpi_read_words_le16(struct c67x00_device *dev, u16 addr, |
141 | u16 *data, u16 count) | 141 | __le16 *data, u16 count) |
142 | { | 142 | { |
143 | unsigned long flags; | 143 | unsigned long flags; |
144 | int i; | 144 | int i; |
@@ -146,7 +146,7 @@ static void hpi_read_words_le16(struct c67x00_device *dev, u16 addr, | |||
146 | spin_lock_irqsave(&dev->hpi.lock, flags); | 146 | spin_lock_irqsave(&dev->hpi.lock, flags); |
147 | hpi_write_reg(dev, HPI_ADDR, addr); | 147 | hpi_write_reg(dev, HPI_ADDR, addr); |
148 | for (i = 0; i < count; i++) | 148 | for (i = 0; i < count; i++) |
149 | *data++ = le16_to_cpu(hpi_read_reg(dev, HPI_DATA)); | 149 | *data++ = cpu_to_le16(hpi_read_reg(dev, HPI_DATA)); |
150 | 150 | ||
151 | spin_unlock_irqrestore(&dev->hpi.lock, flags); | 151 | spin_unlock_irqrestore(&dev->hpi.lock, flags); |
152 | } | 152 | } |
@@ -425,7 +425,7 @@ void c67x00_ll_write_mem_le16(struct c67x00_device *dev, u16 addr, | |||
425 | len--; | 425 | len--; |
426 | } | 426 | } |
427 | 427 | ||
428 | hpi_write_words_le16(dev, addr, (u16 *)buf, len / 2); | 428 | hpi_write_words_le16(dev, addr, (__le16 *)buf, len / 2); |
429 | buf += len & ~0x01; | 429 | buf += len & ~0x01; |
430 | addr += len & ~0x01; | 430 | addr += len & ~0x01; |
431 | len &= 0x01; | 431 | len &= 0x01; |
@@ -456,7 +456,7 @@ void c67x00_ll_read_mem_le16(struct c67x00_device *dev, u16 addr, | |||
456 | len--; | 456 | len--; |
457 | } | 457 | } |
458 | 458 | ||
459 | hpi_read_words_le16(dev, addr, (u16 *)buf, len / 2); | 459 | hpi_read_words_le16(dev, addr, (__le16 *)buf, len / 2); |
460 | buf += len & ~0x01; | 460 | buf += len & ~0x01; |
461 | addr += len & ~0x01; | 461 | addr += len & ~0x01; |
462 | len &= 0x01; | 462 | len &= 0x01; |
diff --git a/drivers/usb/class/Kconfig b/drivers/usb/class/Kconfig index 3a9102d2591b..66f17ed88cb5 100644 --- a/drivers/usb/class/Kconfig +++ b/drivers/usb/class/Kconfig | |||
@@ -29,3 +29,14 @@ config USB_PRINTER | |||
29 | To compile this driver as a module, choose M here: the | 29 | To compile this driver as a module, choose M here: the |
30 | module will be called usblp. | 30 | module will be called usblp. |
31 | 31 | ||
32 | config USB_WDM | ||
33 | tristate "USB Wireless Device Management support" | ||
34 | depends on USB | ||
35 | ---help--- | ||
36 | This driver supports the WMC Device Management functionality | ||
37 | of cell phones compliant to the CDC WMC specification. You can use | ||
38 | AT commands over this device. | ||
39 | |||
40 | To compile this driver as a module, choose M here: the | ||
41 | module will be called cdc-wdm. | ||
42 | |||
diff --git a/drivers/usb/class/Makefile b/drivers/usb/class/Makefile index cc391e6c2af8..535d59a30600 100644 --- a/drivers/usb/class/Makefile +++ b/drivers/usb/class/Makefile | |||
@@ -5,3 +5,4 @@ | |||
5 | 5 | ||
6 | obj-$(CONFIG_USB_ACM) += cdc-acm.o | 6 | obj-$(CONFIG_USB_ACM) += cdc-acm.o |
7 | obj-$(CONFIG_USB_PRINTER) += usblp.o | 7 | obj-$(CONFIG_USB_PRINTER) += usblp.o |
8 | obj-$(CONFIG_USB_WDM) += cdc-wdm.o | ||
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c new file mode 100644 index 000000000000..731db051070a --- /dev/null +++ b/drivers/usb/class/cdc-wdm.c | |||
@@ -0,0 +1,740 @@ | |||
1 | /* | ||
2 | * cdc-wdm.c | ||
3 | * | ||
4 | * This driver supports USB CDC WCM Device Management. | ||
5 | * | ||
6 | * Copyright (c) 2007-2008 Oliver Neukum | ||
7 | * | ||
8 | * Some code taken from cdc-acm.c | ||
9 | * | ||
10 | * Released under the GPLv2. | ||
11 | * | ||
12 | * Many thanks to Carl Nordbeck | ||
13 | */ | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/errno.h> | ||
16 | #include <linux/slab.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/smp_lock.h> | ||
19 | #include <linux/mutex.h> | ||
20 | #include <linux/uaccess.h> | ||
21 | #include <linux/bitops.h> | ||
22 | #include <linux/poll.h> | ||
23 | #include <linux/usb.h> | ||
24 | #include <linux/usb/cdc.h> | ||
25 | #include <asm/byteorder.h> | ||
26 | #include <asm/unaligned.h> | ||
27 | |||
28 | /* | ||
29 | * Version Information | ||
30 | */ | ||
31 | #define DRIVER_VERSION "v0.02" | ||
32 | #define DRIVER_AUTHOR "Oliver Neukum" | ||
33 | |||
34 | static struct usb_device_id wdm_ids[] = { | ||
35 | { | ||
36 | .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS | | ||
37 | USB_DEVICE_ID_MATCH_INT_SUBCLASS, | ||
38 | .bInterfaceClass = USB_CLASS_COMM, | ||
39 | .bInterfaceSubClass = USB_CDC_SUBCLASS_DMM | ||
40 | }, | ||
41 | { } | ||
42 | }; | ||
43 | |||
44 | #define WDM_MINOR_BASE 176 | ||
45 | |||
46 | |||
47 | #define WDM_IN_USE 1 | ||
48 | #define WDM_DISCONNECTING 2 | ||
49 | #define WDM_RESULT 3 | ||
50 | #define WDM_READ 4 | ||
51 | #define WDM_INT_STALL 5 | ||
52 | #define WDM_POLL_RUNNING 6 | ||
53 | |||
54 | |||
55 | #define WDM_MAX 16 | ||
56 | |||
57 | |||
58 | static DEFINE_MUTEX(wdm_mutex); | ||
59 | |||
60 | /* --- method tables --- */ | ||
61 | |||
62 | struct wdm_device { | ||
63 | u8 *inbuf; /* buffer for response */ | ||
64 | u8 *outbuf; /* buffer for command */ | ||
65 | u8 *sbuf; /* buffer for status */ | ||
66 | u8 *ubuf; /* buffer for copy to user space */ | ||
67 | |||
68 | struct urb *command; | ||
69 | struct urb *response; | ||
70 | struct urb *validity; | ||
71 | struct usb_interface *intf; | ||
72 | struct usb_ctrlrequest *orq; | ||
73 | struct usb_ctrlrequest *irq; | ||
74 | spinlock_t iuspin; | ||
75 | |||
76 | unsigned long flags; | ||
77 | u16 bufsize; | ||
78 | u16 wMaxCommand; | ||
79 | u16 wMaxPacketSize; | ||
80 | u16 bMaxPacketSize0; | ||
81 | __le16 inum; | ||
82 | int reslength; | ||
83 | int length; | ||
84 | int read; | ||
85 | int count; | ||
86 | dma_addr_t shandle; | ||
87 | dma_addr_t ihandle; | ||
88 | struct mutex wlock; | ||
89 | struct mutex rlock; | ||
90 | wait_queue_head_t wait; | ||
91 | struct work_struct rxwork; | ||
92 | int werr; | ||
93 | int rerr; | ||
94 | }; | ||
95 | |||
96 | static struct usb_driver wdm_driver; | ||
97 | |||
98 | /* --- callbacks --- */ | ||
99 | static void wdm_out_callback(struct urb *urb) | ||
100 | { | ||
101 | struct wdm_device *desc; | ||
102 | desc = urb->context; | ||
103 | spin_lock(&desc->iuspin); | ||
104 | desc->werr = urb->status; | ||
105 | spin_unlock(&desc->iuspin); | ||
106 | clear_bit(WDM_IN_USE, &desc->flags); | ||
107 | kfree(desc->outbuf); | ||
108 | wake_up(&desc->wait); | ||
109 | } | ||
110 | |||
111 | static void wdm_in_callback(struct urb *urb) | ||
112 | { | ||
113 | struct wdm_device *desc = urb->context; | ||
114 | int status = urb->status; | ||
115 | |||
116 | spin_lock(&desc->iuspin); | ||
117 | |||
118 | if (status) { | ||
119 | switch (status) { | ||
120 | case -ENOENT: | ||
121 | dev_dbg(&desc->intf->dev, | ||
122 | "nonzero urb status received: -ENOENT"); | ||
123 | break; | ||
124 | case -ECONNRESET: | ||
125 | dev_dbg(&desc->intf->dev, | ||
126 | "nonzero urb status received: -ECONNRESET"); | ||
127 | break; | ||
128 | case -ESHUTDOWN: | ||
129 | dev_dbg(&desc->intf->dev, | ||
130 | "nonzero urb status received: -ESHUTDOWN"); | ||
131 | break; | ||
132 | case -EPIPE: | ||
133 | err("nonzero urb status received: -EPIPE"); | ||
134 | break; | ||
135 | default: | ||
136 | err("Unexpected error %d", status); | ||
137 | break; | ||
138 | } | ||
139 | } | ||
140 | |||
141 | desc->rerr = status; | ||
142 | desc->reslength = urb->actual_length; | ||
143 | memmove(desc->ubuf + desc->length, desc->inbuf, desc->reslength); | ||
144 | desc->length += desc->reslength; | ||
145 | wake_up(&desc->wait); | ||
146 | |||
147 | set_bit(WDM_READ, &desc->flags); | ||
148 | spin_unlock(&desc->iuspin); | ||
149 | } | ||
150 | |||
151 | static void wdm_int_callback(struct urb *urb) | ||
152 | { | ||
153 | int rv = 0; | ||
154 | int status = urb->status; | ||
155 | struct wdm_device *desc; | ||
156 | struct usb_ctrlrequest *req; | ||
157 | struct usb_cdc_notification *dr; | ||
158 | |||
159 | desc = urb->context; | ||
160 | req = desc->irq; | ||
161 | dr = (struct usb_cdc_notification *)desc->sbuf; | ||
162 | |||
163 | if (status) { | ||
164 | switch (status) { | ||
165 | case -ESHUTDOWN: | ||
166 | case -ENOENT: | ||
167 | case -ECONNRESET: | ||
168 | return; /* unplug */ | ||
169 | case -EPIPE: | ||
170 | set_bit(WDM_INT_STALL, &desc->flags); | ||
171 | err("Stall on int endpoint"); | ||
172 | goto sw; /* halt is cleared in work */ | ||
173 | default: | ||
174 | err("nonzero urb status received: %d", status); | ||
175 | break; | ||
176 | } | ||
177 | } | ||
178 | |||
179 | if (urb->actual_length < sizeof(struct usb_cdc_notification)) { | ||
180 | err("wdm_int_callback - %d bytes", urb->actual_length); | ||
181 | goto exit; | ||
182 | } | ||
183 | |||
184 | switch (dr->bNotificationType) { | ||
185 | case USB_CDC_NOTIFY_RESPONSE_AVAILABLE: | ||
186 | dev_dbg(&desc->intf->dev, | ||
187 | "NOTIFY_RESPONSE_AVAILABLE received: index %d len %d", | ||
188 | dr->wIndex, dr->wLength); | ||
189 | break; | ||
190 | |||
191 | case USB_CDC_NOTIFY_NETWORK_CONNECTION: | ||
192 | |||
193 | dev_dbg(&desc->intf->dev, | ||
194 | "NOTIFY_NETWORK_CONNECTION %s network", | ||
195 | dr->wValue ? "connected to" : "disconnected from"); | ||
196 | goto exit; | ||
197 | default: | ||
198 | clear_bit(WDM_POLL_RUNNING, &desc->flags); | ||
199 | err("unknown notification %d received: index %d len %d", | ||
200 | dr->bNotificationType, dr->wIndex, dr->wLength); | ||
201 | goto exit; | ||
202 | } | ||
203 | |||
204 | req->bRequestType = (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE); | ||
205 | req->bRequest = USB_CDC_GET_ENCAPSULATED_RESPONSE; | ||
206 | req->wValue = 0; | ||
207 | req->wIndex = desc->inum; | ||
208 | req->wLength = cpu_to_le16(desc->bMaxPacketSize0); | ||
209 | |||
210 | usb_fill_control_urb( | ||
211 | desc->response, | ||
212 | interface_to_usbdev(desc->intf), | ||
213 | /* using common endpoint 0 */ | ||
214 | usb_rcvctrlpipe(interface_to_usbdev(desc->intf), 0), | ||
215 | (unsigned char *)req, | ||
216 | desc->inbuf, | ||
217 | desc->bMaxPacketSize0, | ||
218 | wdm_in_callback, | ||
219 | desc | ||
220 | ); | ||
221 | desc->response->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
222 | spin_lock(&desc->iuspin); | ||
223 | clear_bit(WDM_READ, &desc->flags); | ||
224 | if (!test_bit(WDM_DISCONNECTING, &desc->flags)) { | ||
225 | rv = usb_submit_urb(desc->response, GFP_ATOMIC); | ||
226 | dev_dbg(&desc->intf->dev, "%s: usb_submit_urb %d", | ||
227 | __func__, rv); | ||
228 | } | ||
229 | spin_unlock(&desc->iuspin); | ||
230 | if (rv < 0) { | ||
231 | if (rv == -EPERM) | ||
232 | return; | ||
233 | if (rv == -ENOMEM) { | ||
234 | sw: | ||
235 | rv = schedule_work(&desc->rxwork); | ||
236 | if (rv) | ||
237 | err("Cannot schedule work"); | ||
238 | } | ||
239 | } | ||
240 | exit: | ||
241 | rv = usb_submit_urb(urb, GFP_ATOMIC); | ||
242 | if (rv) | ||
243 | err("%s - usb_submit_urb failed with result %d", | ||
244 | __func__, rv); | ||
245 | |||
246 | } | ||
247 | |||
248 | static void kill_urbs(struct wdm_device *desc) | ||
249 | { | ||
250 | usb_kill_urb(desc->command); | ||
251 | usb_kill_urb(desc->validity); | ||
252 | usb_kill_urb(desc->response); | ||
253 | } | ||
254 | |||
255 | static void free_urbs(struct wdm_device *desc) | ||
256 | { | ||
257 | usb_free_urb(desc->validity); | ||
258 | usb_free_urb(desc->response); | ||
259 | usb_free_urb(desc->command); | ||
260 | } | ||
261 | |||
262 | static void cleanup(struct wdm_device *desc) | ||
263 | { | ||
264 | usb_buffer_free(interface_to_usbdev(desc->intf), | ||
265 | desc->wMaxPacketSize, | ||
266 | desc->sbuf, | ||
267 | desc->validity->transfer_dma); | ||
268 | usb_buffer_free(interface_to_usbdev(desc->intf), | ||
269 | desc->wMaxPacketSize, | ||
270 | desc->inbuf, | ||
271 | desc->response->transfer_dma); | ||
272 | kfree(desc->orq); | ||
273 | kfree(desc->irq); | ||
274 | kfree(desc->ubuf); | ||
275 | free_urbs(desc); | ||
276 | kfree(desc); | ||
277 | } | ||
278 | |||
279 | static ssize_t wdm_write | ||
280 | (struct file *file, const char __user *buffer, size_t count, loff_t *ppos) | ||
281 | { | ||
282 | u8 *buf; | ||
283 | int rv = -EMSGSIZE, r, we; | ||
284 | struct wdm_device *desc = file->private_data; | ||
285 | struct usb_ctrlrequest *req; | ||
286 | |||
287 | if (count > desc->wMaxCommand) | ||
288 | count = desc->wMaxCommand; | ||
289 | |||
290 | spin_lock_irq(&desc->iuspin); | ||
291 | we = desc->werr; | ||
292 | desc->werr = 0; | ||
293 | spin_unlock_irq(&desc->iuspin); | ||
294 | if (we < 0) | ||
295 | return -EIO; | ||
296 | |||
297 | r = mutex_lock_interruptible(&desc->wlock); /* concurrent writes */ | ||
298 | rv = -ERESTARTSYS; | ||
299 | if (r) | ||
300 | goto outnl; | ||
301 | |||
302 | r = wait_event_interruptible(desc->wait, !test_bit(WDM_IN_USE, | ||
303 | &desc->flags)); | ||
304 | if (r < 0) | ||
305 | goto out; | ||
306 | |||
307 | if (test_bit(WDM_DISCONNECTING, &desc->flags)) { | ||
308 | rv = -ENODEV; | ||
309 | goto out; | ||
310 | } | ||
311 | |||
312 | desc->outbuf = buf = kmalloc(count, GFP_KERNEL); | ||
313 | if (!buf) { | ||
314 | rv = -ENOMEM; | ||
315 | goto out; | ||
316 | } | ||
317 | |||
318 | r = copy_from_user(buf, buffer, count); | ||
319 | if (r > 0) { | ||
320 | kfree(buf); | ||
321 | rv = -EFAULT; | ||
322 | goto out; | ||
323 | } | ||
324 | |||
325 | req = desc->orq; | ||
326 | usb_fill_control_urb( | ||
327 | desc->command, | ||
328 | interface_to_usbdev(desc->intf), | ||
329 | /* using common endpoint 0 */ | ||
330 | usb_sndctrlpipe(interface_to_usbdev(desc->intf), 0), | ||
331 | (unsigned char *)req, | ||
332 | buf, | ||
333 | count, | ||
334 | wdm_out_callback, | ||
335 | desc | ||
336 | ); | ||
337 | |||
338 | req->bRequestType = (USB_DIR_OUT | USB_TYPE_CLASS | | ||
339 | USB_RECIP_INTERFACE); | ||
340 | req->bRequest = USB_CDC_SEND_ENCAPSULATED_COMMAND; | ||
341 | req->wValue = 0; | ||
342 | req->wIndex = desc->inum; | ||
343 | req->wLength = cpu_to_le16(count); | ||
344 | set_bit(WDM_IN_USE, &desc->flags); | ||
345 | |||
346 | rv = usb_submit_urb(desc->command, GFP_KERNEL); | ||
347 | if (rv < 0) { | ||
348 | kfree(buf); | ||
349 | clear_bit(WDM_IN_USE, &desc->flags); | ||
350 | } else { | ||
351 | dev_dbg(&desc->intf->dev, "Tx URB has been submitted index=%d", | ||
352 | req->wIndex); | ||
353 | } | ||
354 | out: | ||
355 | mutex_unlock(&desc->wlock); | ||
356 | outnl: | ||
357 | return rv < 0 ? rv : count; | ||
358 | } | ||
359 | |||
360 | static ssize_t wdm_read | ||
361 | (struct file *file, char __user *buffer, size_t count, loff_t *ppos) | ||
362 | { | ||
363 | int rv, cntr; | ||
364 | int i = 0; | ||
365 | struct wdm_device *desc = file->private_data; | ||
366 | |||
367 | |||
368 | rv = mutex_lock_interruptible(&desc->rlock); /*concurrent reads */ | ||
369 | if (rv < 0) | ||
370 | return -ERESTARTSYS; | ||
371 | |||
372 | if (desc->length == 0) { | ||
373 | desc->read = 0; | ||
374 | retry: | ||
375 | i++; | ||
376 | rv = wait_event_interruptible(desc->wait, | ||
377 | test_bit(WDM_READ, &desc->flags)); | ||
378 | |||
379 | if (rv < 0) { | ||
380 | rv = -ERESTARTSYS; | ||
381 | goto err; | ||
382 | } | ||
383 | |||
384 | spin_lock_irq(&desc->iuspin); | ||
385 | |||
386 | if (desc->rerr) { /* read completed, error happened */ | ||
387 | int t = desc->rerr; | ||
388 | desc->rerr = 0; | ||
389 | spin_unlock_irq(&desc->iuspin); | ||
390 | err("reading had resulted in %d", t); | ||
391 | rv = -EIO; | ||
392 | goto err; | ||
393 | } | ||
394 | /* | ||
395 | * recheck whether we've lost the race | ||
396 | * against the completion handler | ||
397 | */ | ||
398 | if (!test_bit(WDM_READ, &desc->flags)) { /* lost race */ | ||
399 | spin_unlock_irq(&desc->iuspin); | ||
400 | goto retry; | ||
401 | } | ||
402 | if (!desc->reslength) { /* zero length read */ | ||
403 | spin_unlock_irq(&desc->iuspin); | ||
404 | goto retry; | ||
405 | } | ||
406 | clear_bit(WDM_READ, &desc->flags); | ||
407 | spin_unlock_irq(&desc->iuspin); | ||
408 | } | ||
409 | |||
410 | cntr = count > desc->length ? desc->length : count; | ||
411 | rv = copy_to_user(buffer, desc->ubuf, cntr); | ||
412 | if (rv > 0) { | ||
413 | rv = -EFAULT; | ||
414 | goto err; | ||
415 | } | ||
416 | |||
417 | for (i = 0; i < desc->length - cntr; i++) | ||
418 | desc->ubuf[i] = desc->ubuf[i + cntr]; | ||
419 | |||
420 | desc->length -= cntr; | ||
421 | rv = cntr; | ||
422 | |||
423 | err: | ||
424 | mutex_unlock(&desc->rlock); | ||
425 | if (rv < 0) | ||
426 | err("wdm_read: exit error"); | ||
427 | return rv; | ||
428 | } | ||
429 | |||
430 | static int wdm_flush(struct file *file, fl_owner_t id) | ||
431 | { | ||
432 | struct wdm_device *desc = file->private_data; | ||
433 | |||
434 | wait_event(desc->wait, !test_bit(WDM_IN_USE, &desc->flags)); | ||
435 | if (desc->werr < 0) | ||
436 | err("Error in flush path: %d", desc->werr); | ||
437 | |||
438 | return desc->werr; | ||
439 | } | ||
440 | |||
441 | static unsigned int wdm_poll(struct file *file, struct poll_table_struct *wait) | ||
442 | { | ||
443 | struct wdm_device *desc = file->private_data; | ||
444 | unsigned long flags; | ||
445 | unsigned int mask = 0; | ||
446 | |||
447 | spin_lock_irqsave(&desc->iuspin, flags); | ||
448 | if (test_bit(WDM_DISCONNECTING, &desc->flags)) { | ||
449 | mask = POLLERR; | ||
450 | spin_unlock_irqrestore(&desc->iuspin, flags); | ||
451 | goto desc_out; | ||
452 | } | ||
453 | if (test_bit(WDM_READ, &desc->flags)) | ||
454 | mask = POLLIN | POLLRDNORM; | ||
455 | if (desc->rerr || desc->werr) | ||
456 | mask |= POLLERR; | ||
457 | if (!test_bit(WDM_IN_USE, &desc->flags)) | ||
458 | mask |= POLLOUT | POLLWRNORM; | ||
459 | spin_unlock_irqrestore(&desc->iuspin, flags); | ||
460 | |||
461 | poll_wait(file, &desc->wait, wait); | ||
462 | |||
463 | desc_out: | ||
464 | return mask; | ||
465 | } | ||
466 | |||
467 | static int wdm_open(struct inode *inode, struct file *file) | ||
468 | { | ||
469 | int minor = iminor(inode); | ||
470 | int rv = -ENODEV; | ||
471 | struct usb_interface *intf; | ||
472 | struct wdm_device *desc; | ||
473 | |||
474 | mutex_lock(&wdm_mutex); | ||
475 | intf = usb_find_interface(&wdm_driver, minor); | ||
476 | if (!intf) | ||
477 | goto out; | ||
478 | |||
479 | desc = usb_get_intfdata(intf); | ||
480 | if (test_bit(WDM_DISCONNECTING, &desc->flags)) | ||
481 | goto out; | ||
482 | |||
483 | desc->count++; | ||
484 | file->private_data = desc; | ||
485 | |||
486 | rv = usb_submit_urb(desc->validity, GFP_KERNEL); | ||
487 | |||
488 | if (rv < 0) { | ||
489 | desc->count--; | ||
490 | err("Error submitting int urb - %d", rv); | ||
491 | goto out; | ||
492 | } | ||
493 | rv = 0; | ||
494 | |||
495 | out: | ||
496 | mutex_unlock(&wdm_mutex); | ||
497 | return rv; | ||
498 | } | ||
499 | |||
500 | static int wdm_release(struct inode *inode, struct file *file) | ||
501 | { | ||
502 | struct wdm_device *desc = file->private_data; | ||
503 | |||
504 | mutex_lock(&wdm_mutex); | ||
505 | desc->count--; | ||
506 | if (!desc->count) { | ||
507 | dev_dbg(&desc->intf->dev, "wdm_release: cleanup"); | ||
508 | kill_urbs(desc); | ||
509 | } | ||
510 | mutex_unlock(&wdm_mutex); | ||
511 | return 0; | ||
512 | } | ||
513 | |||
514 | static const struct file_operations wdm_fops = { | ||
515 | .owner = THIS_MODULE, | ||
516 | .read = wdm_read, | ||
517 | .write = wdm_write, | ||
518 | .open = wdm_open, | ||
519 | .flush = wdm_flush, | ||
520 | .release = wdm_release, | ||
521 | .poll = wdm_poll | ||
522 | }; | ||
523 | |||
524 | static struct usb_class_driver wdm_class = { | ||
525 | .name = "cdc-wdm%d", | ||
526 | .fops = &wdm_fops, | ||
527 | .minor_base = WDM_MINOR_BASE, | ||
528 | }; | ||
529 | |||
530 | /* --- error handling --- */ | ||
531 | static void wdm_rxwork(struct work_struct *work) | ||
532 | { | ||
533 | struct wdm_device *desc = container_of(work, struct wdm_device, rxwork); | ||
534 | unsigned long flags; | ||
535 | int rv; | ||
536 | |||
537 | spin_lock_irqsave(&desc->iuspin, flags); | ||
538 | if (test_bit(WDM_DISCONNECTING, &desc->flags)) { | ||
539 | spin_unlock_irqrestore(&desc->iuspin, flags); | ||
540 | } else { | ||
541 | spin_unlock_irqrestore(&desc->iuspin, flags); | ||
542 | rv = usb_submit_urb(desc->response, GFP_KERNEL); | ||
543 | if (rv < 0 && rv != -EPERM) { | ||
544 | spin_lock_irqsave(&desc->iuspin, flags); | ||
545 | if (!test_bit(WDM_DISCONNECTING, &desc->flags)) | ||
546 | schedule_work(&desc->rxwork); | ||
547 | spin_unlock_irqrestore(&desc->iuspin, flags); | ||
548 | } | ||
549 | } | ||
550 | } | ||
551 | |||
552 | /* --- hotplug --- */ | ||
553 | |||
554 | static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id) | ||
555 | { | ||
556 | int rv = -EINVAL; | ||
557 | struct usb_device *udev = interface_to_usbdev(intf); | ||
558 | struct wdm_device *desc; | ||
559 | struct usb_host_interface *iface; | ||
560 | struct usb_endpoint_descriptor *ep; | ||
561 | struct usb_cdc_dmm_desc *dmhd; | ||
562 | u8 *buffer = intf->altsetting->extra; | ||
563 | int buflen = intf->altsetting->extralen; | ||
564 | u16 maxcom = 0; | ||
565 | |||
566 | if (!buffer) | ||
567 | goto out; | ||
568 | |||
569 | while (buflen > 0) { | ||
570 | if (buffer [1] != USB_DT_CS_INTERFACE) { | ||
571 | err("skipping garbage"); | ||
572 | goto next_desc; | ||
573 | } | ||
574 | |||
575 | switch (buffer [2]) { | ||
576 | case USB_CDC_HEADER_TYPE: | ||
577 | break; | ||
578 | case USB_CDC_DMM_TYPE: | ||
579 | dmhd = (struct usb_cdc_dmm_desc *)buffer; | ||
580 | maxcom = le16_to_cpu(dmhd->wMaxCommand); | ||
581 | dev_dbg(&intf->dev, | ||
582 | "Finding maximum buffer length: %d", maxcom); | ||
583 | break; | ||
584 | default: | ||
585 | err("Ignoring extra header, type %d, length %d", | ||
586 | buffer[2], buffer[0]); | ||
587 | break; | ||
588 | } | ||
589 | next_desc: | ||
590 | buflen -= buffer[0]; | ||
591 | buffer += buffer[0]; | ||
592 | } | ||
593 | |||
594 | rv = -ENOMEM; | ||
595 | desc = kzalloc(sizeof(struct wdm_device), GFP_KERNEL); | ||
596 | if (!desc) | ||
597 | goto out; | ||
598 | mutex_init(&desc->wlock); | ||
599 | mutex_init(&desc->rlock); | ||
600 | spin_lock_init(&desc->iuspin); | ||
601 | init_waitqueue_head(&desc->wait); | ||
602 | desc->wMaxCommand = maxcom; | ||
603 | desc->inum = cpu_to_le16((u16)intf->cur_altsetting->desc.bInterfaceNumber); | ||
604 | desc->intf = intf; | ||
605 | INIT_WORK(&desc->rxwork, wdm_rxwork); | ||
606 | |||
607 | iface = &intf->altsetting[0]; | ||
608 | ep = &iface->endpoint[0].desc; | ||
609 | if (!usb_endpoint_is_int_in(ep)) { | ||
610 | rv = -EINVAL; | ||
611 | goto err; | ||
612 | } | ||
613 | |||
614 | desc->wMaxPacketSize = le16_to_cpu(ep->wMaxPacketSize); | ||
615 | desc->bMaxPacketSize0 = udev->descriptor.bMaxPacketSize0; | ||
616 | |||
617 | desc->orq = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); | ||
618 | if (!desc->orq) | ||
619 | goto err; | ||
620 | desc->irq = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); | ||
621 | if (!desc->irq) | ||
622 | goto err; | ||
623 | |||
624 | desc->validity = usb_alloc_urb(0, GFP_KERNEL); | ||
625 | if (!desc->validity) | ||
626 | goto err; | ||
627 | |||
628 | desc->response = usb_alloc_urb(0, GFP_KERNEL); | ||
629 | if (!desc->response) | ||
630 | goto err; | ||
631 | |||
632 | desc->command = usb_alloc_urb(0, GFP_KERNEL); | ||
633 | if (!desc->command) | ||
634 | goto err; | ||
635 | |||
636 | desc->ubuf = kmalloc(desc->wMaxCommand, GFP_KERNEL); | ||
637 | if (!desc->ubuf) | ||
638 | goto err; | ||
639 | |||
640 | desc->sbuf = usb_buffer_alloc(interface_to_usbdev(intf), | ||
641 | desc->wMaxPacketSize, | ||
642 | GFP_KERNEL, | ||
643 | &desc->validity->transfer_dma); | ||
644 | if (!desc->sbuf) | ||
645 | goto err; | ||
646 | |||
647 | desc->inbuf = usb_buffer_alloc(interface_to_usbdev(intf), | ||
648 | desc->bMaxPacketSize0, | ||
649 | GFP_KERNEL, | ||
650 | &desc->response->transfer_dma); | ||
651 | if (!desc->inbuf) | ||
652 | goto err2; | ||
653 | |||
654 | usb_fill_int_urb( | ||
655 | desc->validity, | ||
656 | interface_to_usbdev(intf), | ||
657 | usb_rcvintpipe(interface_to_usbdev(intf), ep->bEndpointAddress), | ||
658 | desc->sbuf, | ||
659 | desc->wMaxPacketSize, | ||
660 | wdm_int_callback, | ||
661 | desc, | ||
662 | ep->bInterval | ||
663 | ); | ||
664 | desc->validity->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
665 | |||
666 | usb_set_intfdata(intf, desc); | ||
667 | rv = usb_register_dev(intf, &wdm_class); | ||
668 | dev_info(&intf->dev, "cdc-wdm%d: USB WDM device\n", | ||
669 | intf->minor - WDM_MINOR_BASE); | ||
670 | if (rv < 0) | ||
671 | goto err; | ||
672 | out: | ||
673 | return rv; | ||
674 | err2: | ||
675 | usb_buffer_free(interface_to_usbdev(desc->intf), | ||
676 | desc->wMaxPacketSize, | ||
677 | desc->sbuf, | ||
678 | desc->validity->transfer_dma); | ||
679 | err: | ||
680 | free_urbs(desc); | ||
681 | kfree(desc->ubuf); | ||
682 | kfree(desc->orq); | ||
683 | kfree(desc->irq); | ||
684 | kfree(desc); | ||
685 | return rv; | ||
686 | } | ||
687 | |||
688 | static void wdm_disconnect(struct usb_interface *intf) | ||
689 | { | ||
690 | struct wdm_device *desc; | ||
691 | unsigned long flags; | ||
692 | |||
693 | usb_deregister_dev(intf, &wdm_class); | ||
694 | mutex_lock(&wdm_mutex); | ||
695 | desc = usb_get_intfdata(intf); | ||
696 | |||
697 | /* the spinlock makes sure no new urbs are generated in the callbacks */ | ||
698 | spin_lock_irqsave(&desc->iuspin, flags); | ||
699 | set_bit(WDM_DISCONNECTING, &desc->flags); | ||
700 | set_bit(WDM_READ, &desc->flags); | ||
701 | clear_bit(WDM_IN_USE, &desc->flags); | ||
702 | spin_unlock_irqrestore(&desc->iuspin, flags); | ||
703 | cancel_work_sync(&desc->rxwork); | ||
704 | kill_urbs(desc); | ||
705 | wake_up_all(&desc->wait); | ||
706 | if (!desc->count) | ||
707 | cleanup(desc); | ||
708 | mutex_unlock(&wdm_mutex); | ||
709 | } | ||
710 | |||
711 | static struct usb_driver wdm_driver = { | ||
712 | .name = "cdc_wdm", | ||
713 | .probe = wdm_probe, | ||
714 | .disconnect = wdm_disconnect, | ||
715 | .id_table = wdm_ids, | ||
716 | }; | ||
717 | |||
718 | /* --- low level module stuff --- */ | ||
719 | |||
720 | static int __init wdm_init(void) | ||
721 | { | ||
722 | int rv; | ||
723 | |||
724 | rv = usb_register(&wdm_driver); | ||
725 | |||
726 | return rv; | ||
727 | } | ||
728 | |||
729 | static void __exit wdm_exit(void) | ||
730 | { | ||
731 | usb_deregister(&wdm_driver); | ||
732 | } | ||
733 | |||
734 | module_init(wdm_init); | ||
735 | module_exit(wdm_exit); | ||
736 | |||
737 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
738 | MODULE_DESCRIPTION("USB Abstract Control Model driver for " | ||
739 | "USB WCM Device Management"); | ||
740 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/usb/core/generic.c b/drivers/usb/core/generic.c index c1cb94e9f242..7e912f21fd36 100644 --- a/drivers/usb/core/generic.c +++ b/drivers/usb/core/generic.c | |||
@@ -155,9 +155,6 @@ static int generic_probe(struct usb_device *udev) | |||
155 | { | 155 | { |
156 | int err, c; | 156 | int err, c; |
157 | 157 | ||
158 | /* put device-specific files into sysfs */ | ||
159 | usb_create_sysfs_dev_files(udev); | ||
160 | |||
161 | /* Choose and set the configuration. This registers the interfaces | 158 | /* Choose and set the configuration. This registers the interfaces |
162 | * with the driver core and lets interface drivers bind to them. | 159 | * with the driver core and lets interface drivers bind to them. |
163 | */ | 160 | */ |
@@ -189,8 +186,6 @@ static void generic_disconnect(struct usb_device *udev) | |||
189 | * unconfigure the device */ | 186 | * unconfigure the device */ |
190 | if (udev->actconfig) | 187 | if (udev->actconfig) |
191 | usb_set_configuration(udev, -1); | 188 | usb_set_configuration(udev, -1); |
192 | |||
193 | usb_remove_sysfs_dev_files(udev); | ||
194 | } | 189 | } |
195 | 190 | ||
196 | #ifdef CONFIG_PM | 191 | #ifdef CONFIG_PM |
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index bf10e9c4195e..09a53e7f3327 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -818,12 +818,12 @@ static int usb_register_bus(struct usb_bus *bus) | |||
818 | set_bit (busnum, busmap.busmap); | 818 | set_bit (busnum, busmap.busmap); |
819 | bus->busnum = busnum; | 819 | bus->busnum = busnum; |
820 | 820 | ||
821 | bus->dev = device_create(usb_host_class, bus->controller, MKDEV(0, 0), | 821 | bus->dev = device_create_drvdata(usb_host_class, bus->controller, |
822 | "usb_host%d", busnum); | 822 | MKDEV(0, 0), bus, |
823 | "usb_host%d", busnum); | ||
823 | result = PTR_ERR(bus->dev); | 824 | result = PTR_ERR(bus->dev); |
824 | if (IS_ERR(bus->dev)) | 825 | if (IS_ERR(bus->dev)) |
825 | goto error_create_class_dev; | 826 | goto error_create_class_dev; |
826 | dev_set_drvdata(bus->dev, bus); | ||
827 | 827 | ||
828 | /* Add it to the local list of buses */ | 828 | /* Add it to the local list of buses */ |
829 | list_add (&bus->bus_list, &usb_bus_list); | 829 | list_add (&bus->bus_list, &usb_bus_list); |
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index 1e4b81e9eb50..a0bf5df6cb6f 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h | |||
@@ -213,6 +213,8 @@ struct hc_driver { | |||
213 | 213 | ||
214 | /* force handover of high-speed port to full-speed companion */ | 214 | /* force handover of high-speed port to full-speed companion */ |
215 | void (*relinquish_port)(struct usb_hcd *, int); | 215 | void (*relinquish_port)(struct usb_hcd *, int); |
216 | /* has a port been handed over to a companion? */ | ||
217 | int (*port_handed_over)(struct usb_hcd *, int); | ||
216 | }; | 218 | }; |
217 | 219 | ||
218 | extern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb); | 220 | extern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb); |
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index eb57fcc701d7..94789be54ca3 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -644,6 +644,48 @@ static void hub_stop(struct usb_hub *hub) | |||
644 | 644 | ||
645 | #ifdef CONFIG_PM | 645 | #ifdef CONFIG_PM |
646 | 646 | ||
647 | /* Try to identify which devices need USB-PERSIST handling */ | ||
648 | static int persistent_device(struct usb_device *udev) | ||
649 | { | ||
650 | int i; | ||
651 | int retval; | ||
652 | struct usb_host_config *actconfig; | ||
653 | |||
654 | /* Explicitly not marked persistent? */ | ||
655 | if (!udev->persist_enabled) | ||
656 | return 0; | ||
657 | |||
658 | /* No active config? */ | ||
659 | actconfig = udev->actconfig; | ||
660 | if (!actconfig) | ||
661 | return 0; | ||
662 | |||
663 | /* FIXME! We should check whether it's open here or not! */ | ||
664 | |||
665 | /* | ||
666 | * Check that all the interface drivers have a | ||
667 | * 'reset_resume' entrypoint | ||
668 | */ | ||
669 | retval = 0; | ||
670 | for (i = 0; i < actconfig->desc.bNumInterfaces; i++) { | ||
671 | struct usb_interface *intf; | ||
672 | struct usb_driver *driver; | ||
673 | |||
674 | intf = actconfig->interface[i]; | ||
675 | if (!intf->dev.driver) | ||
676 | continue; | ||
677 | driver = to_usb_driver(intf->dev.driver); | ||
678 | if (!driver->reset_resume) | ||
679 | return 0; | ||
680 | /* | ||
681 | * We have at least one driver, and that one | ||
682 | * has a reset_resume method. | ||
683 | */ | ||
684 | retval = 1; | ||
685 | } | ||
686 | return retval; | ||
687 | } | ||
688 | |||
647 | static void hub_restart(struct usb_hub *hub, int type) | 689 | static void hub_restart(struct usb_hub *hub, int type) |
648 | { | 690 | { |
649 | struct usb_device *hdev = hub->hdev; | 691 | struct usb_device *hdev = hub->hdev; |
@@ -689,8 +731,8 @@ static void hub_restart(struct usb_hub *hub, int type) | |||
689 | * turn off the various status changes to prevent | 731 | * turn off the various status changes to prevent |
690 | * khubd from disconnecting it later. | 732 | * khubd from disconnecting it later. |
691 | */ | 733 | */ |
692 | if (udev->persist_enabled && status == 0 && | 734 | if (status == 0 && !(portstatus & USB_PORT_STAT_ENABLE) && |
693 | !(portstatus & USB_PORT_STAT_ENABLE)) { | 735 | persistent_device(udev)) { |
694 | if (portchange & USB_PORT_STAT_C_ENABLE) | 736 | if (portchange & USB_PORT_STAT_C_ENABLE) |
695 | clear_port_feature(hub->hdev, port1, | 737 | clear_port_feature(hub->hdev, port1, |
696 | USB_PORT_FEAT_C_ENABLE); | 738 | USB_PORT_FEAT_C_ENABLE); |
@@ -1326,6 +1368,12 @@ void usb_disconnect(struct usb_device **pdev) | |||
1326 | 1368 | ||
1327 | usb_unlock_device(udev); | 1369 | usb_unlock_device(udev); |
1328 | 1370 | ||
1371 | /* Remove the device-specific files from sysfs. This must be | ||
1372 | * done with udev unlocked, because some of the attribute | ||
1373 | * routines try to acquire the device lock. | ||
1374 | */ | ||
1375 | usb_remove_sysfs_dev_files(udev); | ||
1376 | |||
1329 | /* Unregister the device. The device driver is responsible | 1377 | /* Unregister the device. The device driver is responsible |
1330 | * for removing the device files from usbfs and sysfs and for | 1378 | * for removing the device files from usbfs and sysfs and for |
1331 | * de-configuring the device. | 1379 | * de-configuring the device. |
@@ -1541,6 +1589,9 @@ int usb_new_device(struct usb_device *udev) | |||
1541 | goto fail; | 1589 | goto fail; |
1542 | } | 1590 | } |
1543 | 1591 | ||
1592 | /* put device-specific files into sysfs */ | ||
1593 | usb_create_sysfs_dev_files(udev); | ||
1594 | |||
1544 | /* Tell the world! */ | 1595 | /* Tell the world! */ |
1545 | announce_device(udev); | 1596 | announce_device(udev); |
1546 | return err; | 1597 | return err; |
@@ -2744,7 +2795,11 @@ loop: | |||
2744 | if ((status == -ENOTCONN) || (status == -ENOTSUPP)) | 2795 | if ((status == -ENOTCONN) || (status == -ENOTSUPP)) |
2745 | break; | 2796 | break; |
2746 | } | 2797 | } |
2747 | dev_err(hub_dev, "unable to enumerate USB device on port %d\n", port1); | 2798 | if (hub->hdev->parent || |
2799 | !hcd->driver->port_handed_over || | ||
2800 | !(hcd->driver->port_handed_over)(hcd, port1)) | ||
2801 | dev_err(hub_dev, "unable to enumerate USB device on port %d\n", | ||
2802 | port1); | ||
2748 | 2803 | ||
2749 | done: | 2804 | done: |
2750 | hub_port_disable(hub, port1, 1); | 2805 | hub_port_disable(hub, port1, 1); |
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index 2e2019390290..3da1ab4b389d 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c | |||
@@ -47,6 +47,10 @@ static const struct usb_device_id usb_quirk_list[] = { | |||
47 | /* Edirol SD-20 */ | 47 | /* Edirol SD-20 */ |
48 | { USB_DEVICE(0x0582, 0x0027), .driver_info = USB_QUIRK_RESET_RESUME }, | 48 | { USB_DEVICE(0x0582, 0x0027), .driver_info = USB_QUIRK_RESET_RESUME }, |
49 | 49 | ||
50 | /* Avision AV600U */ | ||
51 | { USB_DEVICE(0x0638, 0x0a13), .driver_info = | ||
52 | USB_QUIRK_STRING_FETCH_255 }, | ||
53 | |||
50 | /* M-Systems Flash Disk Pioneers */ | 54 | /* M-Systems Flash Disk Pioneers */ |
51 | { USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME }, | 55 | { USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME }, |
52 | 56 | ||
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index c783cb111847..5e1f5d55bf04 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c | |||
@@ -588,35 +588,33 @@ read_descriptors(struct kobject *kobj, struct bin_attribute *attr, | |||
588 | container_of(kobj, struct device, kobj)); | 588 | container_of(kobj, struct device, kobj)); |
589 | size_t nleft = count; | 589 | size_t nleft = count; |
590 | size_t srclen, n; | 590 | size_t srclen, n; |
591 | int cfgno; | ||
592 | void *src; | ||
591 | 593 | ||
592 | usb_lock_device(udev); | 594 | /* The binary attribute begins with the device descriptor. |
593 | 595 | * Following that are the raw descriptor entries for all the | |
594 | /* The binary attribute begins with the device descriptor */ | 596 | * configurations (config plus subsidiary descriptors). |
595 | srclen = sizeof(struct usb_device_descriptor); | ||
596 | if (off < srclen) { | ||
597 | n = min_t(size_t, nleft, srclen - off); | ||
598 | memcpy(buf, off + (char *) &udev->descriptor, n); | ||
599 | nleft -= n; | ||
600 | buf += n; | ||
601 | off = 0; | ||
602 | } else { | ||
603 | off -= srclen; | ||
604 | } | ||
605 | |||
606 | /* Then follows the raw descriptor entry for the current | ||
607 | * configuration (config plus subsidiary descriptors). | ||
608 | */ | 597 | */ |
609 | if (udev->actconfig) { | 598 | for (cfgno = -1; cfgno < udev->descriptor.bNumConfigurations && |
610 | int cfgno = udev->actconfig - udev->config; | 599 | nleft > 0; ++cfgno) { |
611 | 600 | if (cfgno < 0) { | |
612 | srclen = __le16_to_cpu(udev->actconfig->desc.wTotalLength); | 601 | src = &udev->descriptor; |
602 | srclen = sizeof(struct usb_device_descriptor); | ||
603 | } else { | ||
604 | src = udev->rawdescriptors[cfgno]; | ||
605 | srclen = __le16_to_cpu(udev->config[cfgno].desc. | ||
606 | wTotalLength); | ||
607 | } | ||
613 | if (off < srclen) { | 608 | if (off < srclen) { |
614 | n = min_t(size_t, nleft, srclen - off); | 609 | n = min(nleft, srclen - (size_t) off); |
615 | memcpy(buf, off + udev->rawdescriptors[cfgno], n); | 610 | memcpy(buf, src + off, n); |
616 | nleft -= n; | 611 | nleft -= n; |
612 | buf += n; | ||
613 | off = 0; | ||
614 | } else { | ||
615 | off -= srclen; | ||
617 | } | 616 | } |
618 | } | 617 | } |
619 | usb_unlock_device(udev); | ||
620 | return count - nleft; | 618 | return count - nleft; |
621 | } | 619 | } |
622 | 620 | ||
diff --git a/drivers/usb/gadget/fsl_usb2_udc.c b/drivers/usb/gadget/fsl_usb2_udc.c index 651b82701394..18687543d7fa 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.c +++ b/drivers/usb/gadget/fsl_usb2_udc.c | |||
@@ -1627,7 +1627,9 @@ static int reset_queues(struct fsl_udc *udc) | |||
1627 | udc_reset_ep_queue(udc, pipe); | 1627 | udc_reset_ep_queue(udc, pipe); |
1628 | 1628 | ||
1629 | /* report disconnect; the driver is already quiesced */ | 1629 | /* report disconnect; the driver is already quiesced */ |
1630 | spin_unlock(&udc->lock); | ||
1630 | udc->driver->disconnect(&udc->gadget); | 1631 | udc->driver->disconnect(&udc->gadget); |
1632 | spin_lock(&udc->lock); | ||
1631 | 1633 | ||
1632 | return 0; | 1634 | return 0; |
1633 | } | 1635 | } |
diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c index 499b7a23f351..e02bfd4df3a6 100644 --- a/drivers/usb/gadget/pxa27x_udc.c +++ b/drivers/usb/gadget/pxa27x_udc.c | |||
@@ -1526,7 +1526,8 @@ static void udc_disable(struct pxa_udc *udc) | |||
1526 | 1526 | ||
1527 | ep0_idle(udc); | 1527 | ep0_idle(udc); |
1528 | udc->gadget.speed = USB_SPEED_UNKNOWN; | 1528 | udc->gadget.speed = USB_SPEED_UNKNOWN; |
1529 | udc->mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT); | 1529 | if (udc->mach->udc_command) |
1530 | udc->mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT); | ||
1530 | } | 1531 | } |
1531 | 1532 | ||
1532 | /** | 1533 | /** |
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 1ef6df395e0c..228797e54f9c 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig | |||
@@ -300,8 +300,8 @@ config USB_R8A66597_HCD | |||
300 | module will be called r8a66597-hcd. | 300 | module will be called r8a66597-hcd. |
301 | 301 | ||
302 | config SUPERH_ON_CHIP_R8A66597 | 302 | config SUPERH_ON_CHIP_R8A66597 |
303 | boolean "Enable SuperH on-chip USB like the R8A66597" | 303 | boolean "Enable SuperH on-chip R8A66597 USB" |
304 | depends on USB_R8A66597_HCD && CPU_SUBTYPE_SH7366 | 304 | depends on USB_R8A66597_HCD && (CPU_SUBTYPE_SH7366 || CPU_SUBTYPE_SH7723) |
305 | help | 305 | help |
306 | Renesas SuperH processor has USB like the R8A66597. | 306 | This driver enables support for the on-chip R8A66597 in the |
307 | This driver supported processor is SH7366. | 307 | SH7366 and SH7723 processors. |
diff --git a/drivers/usb/host/ehci-au1xxx.c b/drivers/usb/host/ehci-au1xxx.c index 8b5f991e949c..08a4335401a9 100644 --- a/drivers/usb/host/ehci-au1xxx.c +++ b/drivers/usb/host/ehci-au1xxx.c | |||
@@ -223,6 +223,7 @@ static const struct hc_driver ehci_au1xxx_hc_driver = { | |||
223 | .bus_suspend = ehci_bus_suspend, | 223 | .bus_suspend = ehci_bus_suspend, |
224 | .bus_resume = ehci_bus_resume, | 224 | .bus_resume = ehci_bus_resume, |
225 | .relinquish_port = ehci_relinquish_port, | 225 | .relinquish_port = ehci_relinquish_port, |
226 | .port_handed_over = ehci_port_handed_over, | ||
226 | }; | 227 | }; |
227 | 228 | ||
228 | /*-------------------------------------------------------------------------*/ | 229 | /*-------------------------------------------------------------------------*/ |
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index 6d9bed6c1f48..7370d6187c64 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c | |||
@@ -269,7 +269,7 @@ static int ehci_fsl_setup(struct usb_hcd *hcd) | |||
269 | if (retval) | 269 | if (retval) |
270 | return retval; | 270 | return retval; |
271 | 271 | ||
272 | ehci->is_tdi_rh_tt = 1; | 272 | hcd->has_tt = 1; |
273 | 273 | ||
274 | ehci->sbrn = 0x20; | 274 | ehci->sbrn = 0x20; |
275 | 275 | ||
@@ -295,10 +295,6 @@ static const struct hc_driver ehci_fsl_hc_driver = { | |||
295 | */ | 295 | */ |
296 | .reset = ehci_fsl_setup, | 296 | .reset = ehci_fsl_setup, |
297 | .start = ehci_run, | 297 | .start = ehci_run, |
298 | #ifdef CONFIG_PM | ||
299 | .suspend = ehci_bus_suspend, | ||
300 | .resume = ehci_bus_resume, | ||
301 | #endif | ||
302 | .stop = ehci_stop, | 298 | .stop = ehci_stop, |
303 | .shutdown = ehci_shutdown, | 299 | .shutdown = ehci_shutdown, |
304 | 300 | ||
@@ -322,6 +318,7 @@ static const struct hc_driver ehci_fsl_hc_driver = { | |||
322 | .bus_suspend = ehci_bus_suspend, | 318 | .bus_suspend = ehci_bus_suspend, |
323 | .bus_resume = ehci_bus_resume, | 319 | .bus_resume = ehci_bus_resume, |
324 | .relinquish_port = ehci_relinquish_port, | 320 | .relinquish_port = ehci_relinquish_port, |
321 | .port_handed_over = ehci_port_handed_over, | ||
325 | }; | 322 | }; |
326 | 323 | ||
327 | static int ehci_fsl_drv_probe(struct platform_device *pdev) | 324 | static int ehci_fsl_drv_probe(struct platform_device *pdev) |
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 382587c4457c..740835bb8575 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c | |||
@@ -609,7 +609,7 @@ static int ehci_hub_control ( | |||
609 | } | 609 | } |
610 | break; | 610 | break; |
611 | case USB_PORT_FEAT_C_SUSPEND: | 611 | case USB_PORT_FEAT_C_SUSPEND: |
612 | /* we auto-clear this feature */ | 612 | clear_bit(wIndex, &ehci->port_c_suspend); |
613 | break; | 613 | break; |
614 | case USB_PORT_FEAT_POWER: | 614 | case USB_PORT_FEAT_POWER: |
615 | if (HCS_PPC (ehci->hcs_params)) | 615 | if (HCS_PPC (ehci->hcs_params)) |
@@ -688,7 +688,7 @@ static int ehci_hub_control ( | |||
688 | /* resume completed? */ | 688 | /* resume completed? */ |
689 | else if (time_after_eq(jiffies, | 689 | else if (time_after_eq(jiffies, |
690 | ehci->reset_done[wIndex])) { | 690 | ehci->reset_done[wIndex])) { |
691 | status |= 1 << USB_PORT_FEAT_C_SUSPEND; | 691 | set_bit(wIndex, &ehci->port_c_suspend); |
692 | ehci->reset_done[wIndex] = 0; | 692 | ehci->reset_done[wIndex] = 0; |
693 | 693 | ||
694 | /* stop resume signaling */ | 694 | /* stop resume signaling */ |
@@ -765,6 +765,8 @@ static int ehci_hub_control ( | |||
765 | status |= 1 << USB_PORT_FEAT_RESET; | 765 | status |= 1 << USB_PORT_FEAT_RESET; |
766 | if (temp & PORT_POWER) | 766 | if (temp & PORT_POWER) |
767 | status |= 1 << USB_PORT_FEAT_POWER; | 767 | status |= 1 << USB_PORT_FEAT_POWER; |
768 | if (test_bit(wIndex, &ehci->port_c_suspend)) | ||
769 | status |= 1 << USB_PORT_FEAT_C_SUSPEND; | ||
768 | 770 | ||
769 | #ifndef VERBOSE_DEBUG | 771 | #ifndef VERBOSE_DEBUG |
770 | if (status & ~0xffff) /* only if wPortChange is interesting */ | 772 | if (status & ~0xffff) /* only if wPortChange is interesting */ |
@@ -875,3 +877,13 @@ static void ehci_relinquish_port(struct usb_hcd *hcd, int portnum) | |||
875 | set_owner(ehci, --portnum, PORT_OWNER); | 877 | set_owner(ehci, --portnum, PORT_OWNER); |
876 | } | 878 | } |
877 | 879 | ||
880 | static int ehci_port_handed_over(struct usb_hcd *hcd, int portnum) | ||
881 | { | ||
882 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | ||
883 | u32 __iomem *reg; | ||
884 | |||
885 | if (ehci_is_TDI(ehci)) | ||
886 | return 0; | ||
887 | reg = &ehci->regs->port_status[portnum - 1]; | ||
888 | return ehci_readl(ehci, reg) & PORT_OWNER; | ||
889 | } | ||
diff --git a/drivers/usb/host/ehci-ixp4xx.c b/drivers/usb/host/ehci-ixp4xx.c index 601c8795a854..9d042f220097 100644 --- a/drivers/usb/host/ehci-ixp4xx.c +++ b/drivers/usb/host/ehci-ixp4xx.c | |||
@@ -26,7 +26,7 @@ static int ixp4xx_ehci_init(struct usb_hcd *hcd) | |||
26 | + HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); | 26 | + HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); |
27 | ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); | 27 | ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); |
28 | 28 | ||
29 | ehci->is_tdi_rh_tt = 1; | 29 | hcd->has_tt = 1; |
30 | ehci_reset(ehci); | 30 | ehci_reset(ehci); |
31 | 31 | ||
32 | retval = ehci_init(hcd); | 32 | retval = ehci_init(hcd); |
@@ -58,6 +58,8 @@ static const struct hc_driver ixp4xx_ehci_hc_driver = { | |||
58 | .bus_suspend = ehci_bus_suspend, | 58 | .bus_suspend = ehci_bus_suspend, |
59 | .bus_resume = ehci_bus_resume, | 59 | .bus_resume = ehci_bus_resume, |
60 | #endif | 60 | #endif |
61 | .relinquish_port = ehci_relinquish_port, | ||
62 | .port_handed_over = ehci_port_handed_over, | ||
61 | }; | 63 | }; |
62 | 64 | ||
63 | static int ixp4xx_ehci_probe(struct platform_device *pdev) | 65 | static int ixp4xx_ehci_probe(struct platform_device *pdev) |
diff --git a/drivers/usb/host/ehci-orion.c b/drivers/usb/host/ehci-orion.c index d187d0313742..ab625f0ba1d9 100644 --- a/drivers/usb/host/ehci-orion.c +++ b/drivers/usb/host/ehci-orion.c | |||
@@ -115,6 +115,8 @@ static int ehci_orion_setup(struct usb_hcd *hcd) | |||
115 | if (retval) | 115 | if (retval) |
116 | return retval; | 116 | return retval; |
117 | 117 | ||
118 | hcd->has_tt = 1; | ||
119 | |||
118 | ehci_reset(ehci); | 120 | ehci_reset(ehci); |
119 | ehci_port_power(ehci, 0); | 121 | ehci_port_power(ehci, 0); |
120 | 122 | ||
@@ -137,10 +139,6 @@ static const struct hc_driver ehci_orion_hc_driver = { | |||
137 | */ | 139 | */ |
138 | .reset = ehci_orion_setup, | 140 | .reset = ehci_orion_setup, |
139 | .start = ehci_run, | 141 | .start = ehci_run, |
140 | #ifdef CONFIG_PM | ||
141 | .suspend = ehci_bus_suspend, | ||
142 | .resume = ehci_bus_resume, | ||
143 | #endif | ||
144 | .stop = ehci_stop, | 142 | .stop = ehci_stop, |
145 | .shutdown = ehci_shutdown, | 143 | .shutdown = ehci_shutdown, |
146 | 144 | ||
@@ -163,6 +161,8 @@ static const struct hc_driver ehci_orion_hc_driver = { | |||
163 | .hub_control = ehci_hub_control, | 161 | .hub_control = ehci_hub_control, |
164 | .bus_suspend = ehci_bus_suspend, | 162 | .bus_suspend = ehci_bus_suspend, |
165 | .bus_resume = ehci_bus_resume, | 163 | .bus_resume = ehci_bus_resume, |
164 | .relinquish_port = ehci_relinquish_port, | ||
165 | .port_handed_over = ehci_port_handed_over, | ||
166 | }; | 166 | }; |
167 | 167 | ||
168 | static void __init | 168 | static void __init |
@@ -248,7 +248,7 @@ static int __init ehci_orion_drv_probe(struct platform_device *pdev) | |||
248 | ehci->regs = hcd->regs + 0x100 + | 248 | ehci->regs = hcd->regs + 0x100 + |
249 | HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); | 249 | HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); |
250 | ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); | 250 | ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); |
251 | ehci->is_tdi_rh_tt = 1; | 251 | hcd->has_tt = 1; |
252 | ehci->sbrn = 0x20; | 252 | ehci->sbrn = 0x20; |
253 | 253 | ||
254 | /* | 254 | /* |
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 5bb7f6bb13f3..c46a58f9181d 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c | |||
@@ -129,7 +129,6 @@ static int ehci_pci_setup(struct usb_hcd *hcd) | |||
129 | switch (pdev->vendor) { | 129 | switch (pdev->vendor) { |
130 | case PCI_VENDOR_ID_TDI: | 130 | case PCI_VENDOR_ID_TDI: |
131 | if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) { | 131 | if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) { |
132 | ehci->is_tdi_rh_tt = 1; | ||
133 | hcd->has_tt = 1; | 132 | hcd->has_tt = 1; |
134 | tdi_reset(ehci); | 133 | tdi_reset(ehci); |
135 | } | 134 | } |
@@ -379,7 +378,8 @@ static const struct hc_driver ehci_pci_hc_driver = { | |||
379 | .hub_control = ehci_hub_control, | 378 | .hub_control = ehci_hub_control, |
380 | .bus_suspend = ehci_bus_suspend, | 379 | .bus_suspend = ehci_bus_suspend, |
381 | .bus_resume = ehci_bus_resume, | 380 | .bus_resume = ehci_bus_resume, |
382 | .relinquish_port = ehci_relinquish_port, | 381 | .relinquish_port = ehci_relinquish_port, |
382 | .port_handed_over = ehci_port_handed_over, | ||
383 | }; | 383 | }; |
384 | 384 | ||
385 | /*-------------------------------------------------------------------------*/ | 385 | /*-------------------------------------------------------------------------*/ |
diff --git a/drivers/usb/host/ehci-ppc-of.c b/drivers/usb/host/ehci-ppc-of.c index ee305b1f99ff..b018deed2e8f 100644 --- a/drivers/usb/host/ehci-ppc-of.c +++ b/drivers/usb/host/ehci-ppc-of.c | |||
@@ -76,6 +76,8 @@ static const struct hc_driver ehci_ppc_of_hc_driver = { | |||
76 | .bus_suspend = ehci_bus_suspend, | 76 | .bus_suspend = ehci_bus_suspend, |
77 | .bus_resume = ehci_bus_resume, | 77 | .bus_resume = ehci_bus_resume, |
78 | #endif | 78 | #endif |
79 | .relinquish_port = ehci_relinquish_port, | ||
80 | .port_handed_over = ehci_port_handed_over, | ||
79 | }; | 81 | }; |
80 | 82 | ||
81 | 83 | ||
diff --git a/drivers/usb/host/ehci-ppc-soc.c b/drivers/usb/host/ehci-ppc-soc.c index 6c76036783a1..529590eb4037 100644 --- a/drivers/usb/host/ehci-ppc-soc.c +++ b/drivers/usb/host/ehci-ppc-soc.c | |||
@@ -163,6 +163,7 @@ static const struct hc_driver ehci_ppc_soc_hc_driver = { | |||
163 | .bus_suspend = ehci_bus_suspend, | 163 | .bus_suspend = ehci_bus_suspend, |
164 | .bus_resume = ehci_bus_resume, | 164 | .bus_resume = ehci_bus_resume, |
165 | .relinquish_port = ehci_relinquish_port, | 165 | .relinquish_port = ehci_relinquish_port, |
166 | .port_handed_over = ehci_port_handed_over, | ||
166 | }; | 167 | }; |
167 | 168 | ||
168 | static int ehci_hcd_ppc_soc_drv_probe(struct platform_device *pdev) | 169 | static int ehci_hcd_ppc_soc_drv_probe(struct platform_device *pdev) |
diff --git a/drivers/usb/host/ehci-ps3.c b/drivers/usb/host/ehci-ps3.c index 69782221bcf3..37e6abeb794c 100644 --- a/drivers/usb/host/ehci-ps3.c +++ b/drivers/usb/host/ehci-ps3.c | |||
@@ -73,6 +73,7 @@ static const struct hc_driver ps3_ehci_hc_driver = { | |||
73 | .bus_resume = ehci_bus_resume, | 73 | .bus_resume = ehci_bus_resume, |
74 | #endif | 74 | #endif |
75 | .relinquish_port = ehci_relinquish_port, | 75 | .relinquish_port = ehci_relinquish_port, |
76 | .port_handed_over = ehci_port_handed_over, | ||
76 | }; | 77 | }; |
77 | 78 | ||
78 | static int ps3_ehci_probe(struct ps3_system_bus_device *dev) | 79 | static int ps3_ehci_probe(struct ps3_system_bus_device *dev) |
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index be575e46eac3..b7853c8bac0f 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c | |||
@@ -1349,18 +1349,27 @@ iso_stream_schedule ( | |||
1349 | /* when's the last uframe this urb could start? */ | 1349 | /* when's the last uframe this urb could start? */ |
1350 | max = now + mod; | 1350 | max = now + mod; |
1351 | 1351 | ||
1352 | /* typical case: reuse current schedule. stream is still active, | 1352 | /* Typical case: reuse current schedule, stream is still active. |
1353 | * and no gaps from host falling behind (irq delays etc) | 1353 | * Hopefully there are no gaps from the host falling behind |
1354 | * (irq delays etc), but if there are we'll take the next | ||
1355 | * slot in the schedule, implicitly assuming URB_ISO_ASAP. | ||
1354 | */ | 1356 | */ |
1355 | if (likely (!list_empty (&stream->td_list))) { | 1357 | if (likely (!list_empty (&stream->td_list))) { |
1356 | start = stream->next_uframe; | 1358 | start = stream->next_uframe; |
1357 | if (start < now) | 1359 | if (start < now) |
1358 | start += mod; | 1360 | start += mod; |
1359 | if (likely ((start + sched->span) < max)) | 1361 | |
1360 | goto ready; | 1362 | /* Fell behind (by up to twice the slop amount)? */ |
1361 | /* else fell behind; someday, try to reschedule */ | 1363 | if (start >= max - 2 * 8 * SCHEDULE_SLOP) |
1362 | status = -EL2NSYNC; | 1364 | start += stream->interval * DIV_ROUND_UP( |
1363 | goto fail; | 1365 | max - start, stream->interval) - mod; |
1366 | |||
1367 | /* Tried to schedule too far into the future? */ | ||
1368 | if (unlikely((start + sched->span) >= max)) { | ||
1369 | status = -EFBIG; | ||
1370 | goto fail; | ||
1371 | } | ||
1372 | goto ready; | ||
1364 | } | 1373 | } |
1365 | 1374 | ||
1366 | /* need to schedule; when's the next (u)frame we could start? | 1375 | /* need to schedule; when's the next (u)frame we could start? |
@@ -1613,6 +1622,9 @@ itd_complete ( | |||
1613 | } else if (likely ((t & EHCI_ISOC_ACTIVE) == 0)) { | 1622 | } else if (likely ((t & EHCI_ISOC_ACTIVE) == 0)) { |
1614 | desc->status = 0; | 1623 | desc->status = 0; |
1615 | desc->actual_length = EHCI_ITD_LENGTH (t); | 1624 | desc->actual_length = EHCI_ITD_LENGTH (t); |
1625 | } else { | ||
1626 | /* URB was too late */ | ||
1627 | desc->status = -EXDEV; | ||
1616 | } | 1628 | } |
1617 | } | 1629 | } |
1618 | 1630 | ||
@@ -2095,7 +2107,7 @@ done: | |||
2095 | static void | 2107 | static void |
2096 | scan_periodic (struct ehci_hcd *ehci) | 2108 | scan_periodic (struct ehci_hcd *ehci) |
2097 | { | 2109 | { |
2098 | unsigned frame, clock, now_uframe, mod; | 2110 | unsigned now_uframe, frame, clock, clock_frame, mod; |
2099 | unsigned modified; | 2111 | unsigned modified; |
2100 | 2112 | ||
2101 | mod = ehci->periodic_size << 3; | 2113 | mod = ehci->periodic_size << 3; |
@@ -2111,6 +2123,7 @@ scan_periodic (struct ehci_hcd *ehci) | |||
2111 | else | 2123 | else |
2112 | clock = now_uframe + mod - 1; | 2124 | clock = now_uframe + mod - 1; |
2113 | clock %= mod; | 2125 | clock %= mod; |
2126 | clock_frame = clock >> 3; | ||
2114 | 2127 | ||
2115 | for (;;) { | 2128 | for (;;) { |
2116 | union ehci_shadow q, *q_p; | 2129 | union ehci_shadow q, *q_p; |
@@ -2157,22 +2170,26 @@ restart: | |||
2157 | case Q_TYPE_ITD: | 2170 | case Q_TYPE_ITD: |
2158 | /* If this ITD is still active, leave it for | 2171 | /* If this ITD is still active, leave it for |
2159 | * later processing ... check the next entry. | 2172 | * later processing ... check the next entry. |
2173 | * No need to check for activity unless the | ||
2174 | * frame is current. | ||
2160 | */ | 2175 | */ |
2161 | rmb (); | 2176 | if (frame == clock_frame && live) { |
2162 | for (uf = 0; uf < 8 && live; uf++) { | 2177 | rmb(); |
2163 | if (0 == (q.itd->hw_transaction [uf] | 2178 | for (uf = 0; uf < 8; uf++) { |
2164 | & ITD_ACTIVE(ehci))) | 2179 | if (q.itd->hw_transaction[uf] & |
2165 | continue; | 2180 | ITD_ACTIVE(ehci)) |
2166 | incomplete = true; | 2181 | break; |
2167 | q_p = &q.itd->itd_next; | 2182 | } |
2168 | hw_p = &q.itd->hw_next; | 2183 | if (uf < 8) { |
2169 | type = Q_NEXT_TYPE(ehci, | 2184 | incomplete = true; |
2185 | q_p = &q.itd->itd_next; | ||
2186 | hw_p = &q.itd->hw_next; | ||
2187 | type = Q_NEXT_TYPE(ehci, | ||
2170 | q.itd->hw_next); | 2188 | q.itd->hw_next); |
2171 | q = *q_p; | 2189 | q = *q_p; |
2172 | break; | 2190 | break; |
2191 | } | ||
2173 | } | 2192 | } |
2174 | if (uf < 8 && live) | ||
2175 | break; | ||
2176 | 2193 | ||
2177 | /* Take finished ITDs out of the schedule | 2194 | /* Take finished ITDs out of the schedule |
2178 | * and process them: recycle, maybe report | 2195 | * and process them: recycle, maybe report |
@@ -2189,9 +2206,12 @@ restart: | |||
2189 | case Q_TYPE_SITD: | 2206 | case Q_TYPE_SITD: |
2190 | /* If this SITD is still active, leave it for | 2207 | /* If this SITD is still active, leave it for |
2191 | * later processing ... check the next entry. | 2208 | * later processing ... check the next entry. |
2209 | * No need to check for activity unless the | ||
2210 | * frame is current. | ||
2192 | */ | 2211 | */ |
2193 | if ((q.sitd->hw_results & SITD_ACTIVE(ehci)) | 2212 | if (frame == clock_frame && live && |
2194 | && live) { | 2213 | (q.sitd->hw_results & |
2214 | SITD_ACTIVE(ehci))) { | ||
2195 | incomplete = true; | 2215 | incomplete = true; |
2196 | q_p = &q.sitd->sitd_next; | 2216 | q_p = &q.sitd->sitd_next; |
2197 | hw_p = &q.sitd->hw_next; | 2217 | hw_p = &q.sitd->hw_next; |
@@ -2260,6 +2280,7 @@ restart: | |||
2260 | 2280 | ||
2261 | /* rescan the rest of this frame, then ... */ | 2281 | /* rescan the rest of this frame, then ... */ |
2262 | clock = now; | 2282 | clock = now; |
2283 | clock_frame = clock >> 3; | ||
2263 | } else { | 2284 | } else { |
2264 | now_uframe++; | 2285 | now_uframe++; |
2265 | now_uframe %= mod; | 2286 | now_uframe %= mod; |
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index bf92d209a1a9..35a03095757e 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h | |||
@@ -97,6 +97,8 @@ struct ehci_hcd { /* one per controller */ | |||
97 | dedicated to the companion controller */ | 97 | dedicated to the companion controller */ |
98 | unsigned long owned_ports; /* which ports are | 98 | unsigned long owned_ports; /* which ports are |
99 | owned by the companion during a bus suspend */ | 99 | owned by the companion during a bus suspend */ |
100 | unsigned long port_c_suspend; /* which ports have | ||
101 | the change-suspend feature turned on */ | ||
100 | 102 | ||
101 | /* per-HC memory pools (could be per-bus, but ...) */ | 103 | /* per-HC memory pools (could be per-bus, but ...) */ |
102 | struct dma_pool *qh_pool; /* qh per active urb */ | 104 | struct dma_pool *qh_pool; /* qh per active urb */ |
@@ -112,7 +114,6 @@ struct ehci_hcd { /* one per controller */ | |||
112 | u32 command; | 114 | u32 command; |
113 | 115 | ||
114 | /* SILICON QUIRKS */ | 116 | /* SILICON QUIRKS */ |
115 | unsigned is_tdi_rh_tt:1; /* TDI roothub with TT */ | ||
116 | unsigned no_selective_suspend:1; | 117 | unsigned no_selective_suspend:1; |
117 | unsigned has_fsl_port_bug:1; /* FreeScale */ | 118 | unsigned has_fsl_port_bug:1; /* FreeScale */ |
118 | unsigned big_endian_mmio:1; | 119 | unsigned big_endian_mmio:1; |
@@ -678,7 +679,7 @@ struct ehci_fstn { | |||
678 | * needed (mostly in root hub code). | 679 | * needed (mostly in root hub code). |
679 | */ | 680 | */ |
680 | 681 | ||
681 | #define ehci_is_TDI(e) ((e)->is_tdi_rh_tt) | 682 | #define ehci_is_TDI(e) (ehci_to_hcd(e)->has_tt) |
682 | 683 | ||
683 | /* Returns the speed of a device attached to a port on the root hub. */ | 684 | /* Returns the speed of a device attached to a port on the root hub. */ |
684 | static inline unsigned int | 685 | static inline unsigned int |
diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c index c9cec8738261..65aa5ecf569a 100644 --- a/drivers/usb/host/isp1760-hcd.c +++ b/drivers/usb/host/isp1760-hcd.c | |||
@@ -2207,14 +2207,14 @@ struct usb_hcd *isp1760_register(u64 res_start, u64 res_len, int irq, | |||
2207 | goto err_put; | 2207 | goto err_put; |
2208 | } | 2208 | } |
2209 | 2209 | ||
2210 | ret = usb_add_hcd(hcd, irq, irqflags); | ||
2211 | if (ret) | ||
2212 | goto err_unmap; | ||
2213 | |||
2214 | hcd->irq = irq; | 2210 | hcd->irq = irq; |
2215 | hcd->rsrc_start = res_start; | 2211 | hcd->rsrc_start = res_start; |
2216 | hcd->rsrc_len = res_len; | 2212 | hcd->rsrc_len = res_len; |
2217 | 2213 | ||
2214 | ret = usb_add_hcd(hcd, irq, irqflags); | ||
2215 | if (ret) | ||
2216 | goto err_unmap; | ||
2217 | |||
2218 | return hcd; | 2218 | return hcd; |
2219 | 2219 | ||
2220 | err_unmap: | 2220 | err_unmap: |
diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c index 440bf94f0d4c..c9db3fe98726 100644 --- a/drivers/usb/host/isp1760-if.c +++ b/drivers/usb/host/isp1760-if.c | |||
@@ -104,8 +104,8 @@ static u32 nxp_pci_io_base; | |||
104 | static u32 iolength; | 104 | static u32 iolength; |
105 | static u32 pci_mem_phy0; | 105 | static u32 pci_mem_phy0; |
106 | static u32 length; | 106 | static u32 length; |
107 | static u8 *chip_addr; | 107 | static u8 __iomem *chip_addr; |
108 | static u8 *iobase; | 108 | static u8 __iomem *iobase; |
109 | 109 | ||
110 | static int __devinit isp1761_pci_probe(struct pci_dev *dev, | 110 | static int __devinit isp1761_pci_probe(struct pci_dev *dev, |
111 | const struct pci_device_id *id) | 111 | const struct pci_device_id *id) |
diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig index a53db1d4e07a..001789c9a11a 100644 --- a/drivers/usb/misc/Kconfig +++ b/drivers/usb/misc/Kconfig | |||
@@ -269,3 +269,15 @@ config USB_TEST | |||
269 | See <http://www.linux-usb.org/usbtest/> for more information, | 269 | See <http://www.linux-usb.org/usbtest/> for more information, |
270 | including sample test device firmware and "how to use it". | 270 | including sample test device firmware and "how to use it". |
271 | 271 | ||
272 | config USB_ISIGHTFW | ||
273 | tristate "iSight firmware loading support" | ||
274 | depends on USB | ||
275 | select FW_LOADER | ||
276 | help | ||
277 | This driver loads firmware for USB Apple iSight cameras, allowing | ||
278 | them to be driven by the USB video class driver available at | ||
279 | http://linux-uvc.berlios.de | ||
280 | |||
281 | The firmware for this driver must be extracted from the MacOS | ||
282 | driver beforehand. Tools for doing so are available at | ||
283 | http://bersace03.free.fr | ||
diff --git a/drivers/usb/misc/Makefile b/drivers/usb/misc/Makefile index b68e6b774f1a..aba091cb5ec0 100644 --- a/drivers/usb/misc/Makefile +++ b/drivers/usb/misc/Makefile | |||
@@ -14,6 +14,7 @@ obj-$(CONFIG_USB_EMI62) += emi62.o | |||
14 | obj-$(CONFIG_USB_FTDI_ELAN) += ftdi-elan.o | 14 | obj-$(CONFIG_USB_FTDI_ELAN) += ftdi-elan.o |
15 | obj-$(CONFIG_USB_IDMOUSE) += idmouse.o | 15 | obj-$(CONFIG_USB_IDMOUSE) += idmouse.o |
16 | obj-$(CONFIG_USB_IOWARRIOR) += iowarrior.o | 16 | obj-$(CONFIG_USB_IOWARRIOR) += iowarrior.o |
17 | obj-$(CONFIG_USB_ISIGHTFW) += isight_firmware.o | ||
17 | obj-$(CONFIG_USB_LCD) += usblcd.o | 18 | obj-$(CONFIG_USB_LCD) += usblcd.o |
18 | obj-$(CONFIG_USB_LD) += ldusb.o | 19 | obj-$(CONFIG_USB_LD) += ldusb.o |
19 | obj-$(CONFIG_USB_LED) += usbled.o | 20 | obj-$(CONFIG_USB_LED) += usbled.o |
diff --git a/drivers/usb/misc/isight_firmware.c b/drivers/usb/misc/isight_firmware.c new file mode 100644 index 000000000000..9f30aa1f8a5d --- /dev/null +++ b/drivers/usb/misc/isight_firmware.c | |||
@@ -0,0 +1,140 @@ | |||
1 | /* | ||
2 | * Driver for loading USB isight firmware | ||
3 | * | ||
4 | * Copyright (C) 2008 Matthew Garrett <mjg@redhat.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the Free | ||
8 | * Software Foundation, version 2. | ||
9 | * | ||
10 | * The USB isight cameras in recent Apples are roughly compatible with the USB | ||
11 | * video class specification, and can be driven by uvcvideo. However, they | ||
12 | * need firmware to be loaded beforehand. After firmware loading, the device | ||
13 | * detaches from the USB bus and reattaches with a new device ID. It can then | ||
14 | * be claimed by the uvc driver. | ||
15 | * | ||
16 | * The firmware is non-free and must be extracted by the user. Tools to do this | ||
17 | * are available at http://bersace03.free.fr/ift/ | ||
18 | * | ||
19 | * The isight firmware loading was reverse engineered by Johannes Berg | ||
20 | * <johannes@sipsolutions.de>, and this driver is based on code by Ronald | ||
21 | * Bultje <rbultje@ronald.bitfreak.net> | ||
22 | */ | ||
23 | |||
24 | #include <linux/usb.h> | ||
25 | #include <linux/firmware.h> | ||
26 | #include <linux/errno.h> | ||
27 | #include <linux/module.h> | ||
28 | |||
29 | static struct usb_device_id id_table[] = { | ||
30 | {USB_DEVICE(0x05ac, 0x8300)}, | ||
31 | {}, | ||
32 | }; | ||
33 | |||
34 | MODULE_DEVICE_TABLE(usb, id_table); | ||
35 | |||
36 | static int isight_firmware_load(struct usb_interface *intf, | ||
37 | const struct usb_device_id *id) | ||
38 | { | ||
39 | struct usb_device *dev = interface_to_usbdev(intf); | ||
40 | int llen, len, req, ret = 0; | ||
41 | const struct firmware *firmware; | ||
42 | unsigned char *buf = kmalloc(50, GFP_KERNEL); | ||
43 | unsigned char data[4]; | ||
44 | u8 *ptr; | ||
45 | |||
46 | if (!buf) | ||
47 | return -ENOMEM; | ||
48 | |||
49 | if (request_firmware(&firmware, "isight.fw", &dev->dev) != 0) { | ||
50 | printk(KERN_ERR "Unable to load isight firmware\n"); | ||
51 | return -ENODEV; | ||
52 | } | ||
53 | |||
54 | ptr = firmware->data; | ||
55 | |||
56 | if (usb_control_msg | ||
57 | (dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, 0xe600, 0, "\1", 1, | ||
58 | 300) != 1) { | ||
59 | printk(KERN_ERR | ||
60 | "Failed to initialise isight firmware loader\n"); | ||
61 | ret = -ENODEV; | ||
62 | goto out; | ||
63 | } | ||
64 | |||
65 | while (ptr+4 <= firmware->data+firmware->size) { | ||
66 | memcpy(data, ptr, 4); | ||
67 | len = (data[0] << 8 | data[1]); | ||
68 | req = (data[2] << 8 | data[3]); | ||
69 | ptr += 4; | ||
70 | |||
71 | if (len == 0x8001) | ||
72 | break; /* success */ | ||
73 | else if (len == 0) | ||
74 | continue; | ||
75 | |||
76 | for (; len > 0; req += 50) { | ||
77 | llen = min(len, 50); | ||
78 | len -= llen; | ||
79 | if (ptr+llen > firmware->data+firmware->size) { | ||
80 | printk(KERN_ERR | ||
81 | "Malformed isight firmware"); | ||
82 | ret = -ENODEV; | ||
83 | goto out; | ||
84 | } | ||
85 | memcpy(buf, ptr, llen); | ||
86 | |||
87 | ptr += llen; | ||
88 | |||
89 | if (usb_control_msg | ||
90 | (dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, req, 0, | ||
91 | buf, llen, 300) != llen) { | ||
92 | printk(KERN_ERR | ||
93 | "Failed to load isight firmware\n"); | ||
94 | kfree(buf); | ||
95 | ret = -ENODEV; | ||
96 | goto out; | ||
97 | } | ||
98 | |||
99 | } | ||
100 | } | ||
101 | |||
102 | if (usb_control_msg | ||
103 | (dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, 0xe600, 0, "\0", 1, | ||
104 | 300) != 1) { | ||
105 | printk(KERN_ERR "isight firmware loading completion failed\n"); | ||
106 | ret = -ENODEV; | ||
107 | } | ||
108 | |||
109 | out: | ||
110 | kfree(buf); | ||
111 | release_firmware(firmware); | ||
112 | return ret; | ||
113 | } | ||
114 | |||
115 | static void isight_firmware_disconnect(struct usb_interface *intf) | ||
116 | { | ||
117 | } | ||
118 | |||
119 | static struct usb_driver isight_firmware_driver = { | ||
120 | .name = "isight_firmware", | ||
121 | .probe = isight_firmware_load, | ||
122 | .disconnect = isight_firmware_disconnect, | ||
123 | .id_table = id_table, | ||
124 | }; | ||
125 | |||
126 | static int __init isight_firmware_init(void) | ||
127 | { | ||
128 | return usb_register(&isight_firmware_driver); | ||
129 | } | ||
130 | |||
131 | static void __exit isight_firmware_exit(void) | ||
132 | { | ||
133 | usb_deregister(&isight_firmware_driver); | ||
134 | } | ||
135 | |||
136 | module_init(isight_firmware_init); | ||
137 | module_exit(isight_firmware_exit); | ||
138 | |||
139 | MODULE_LICENSE("GPL"); | ||
140 | MODULE_AUTHOR("Matthew Garrett <mjg@redhat.com>"); | ||
diff --git a/drivers/usb/misc/phidgetkit.c b/drivers/usb/misc/phidgetkit.c index 24230c638b8e..4cfa25b0f44e 100644 --- a/drivers/usb/misc/phidgetkit.c +++ b/drivers/usb/misc/phidgetkit.c | |||
@@ -595,14 +595,14 @@ static int interfacekit_probe(struct usb_interface *intf, const struct usb_devic | |||
595 | } while(value); | 595 | } while(value); |
596 | kit->dev_no = bit; | 596 | kit->dev_no = bit; |
597 | 597 | ||
598 | kit->dev = device_create(phidget_class, &kit->udev->dev, 0, | 598 | kit->dev = device_create_drvdata(phidget_class, &kit->udev->dev, |
599 | "interfacekit%d", kit->dev_no); | 599 | MKDEV(0, 0), kit, |
600 | "interfacekit%d", kit->dev_no); | ||
600 | if (IS_ERR(kit->dev)) { | 601 | if (IS_ERR(kit->dev)) { |
601 | rc = PTR_ERR(kit->dev); | 602 | rc = PTR_ERR(kit->dev); |
602 | kit->dev = NULL; | 603 | kit->dev = NULL; |
603 | goto out; | 604 | goto out; |
604 | } | 605 | } |
605 | dev_set_drvdata(kit->dev, kit); | ||
606 | 606 | ||
607 | if (usb_submit_urb(kit->irq, GFP_KERNEL)) { | 607 | if (usb_submit_urb(kit->irq, GFP_KERNEL)) { |
608 | rc = -EIO; | 608 | rc = -EIO; |
diff --git a/drivers/usb/misc/phidgetmotorcontrol.c b/drivers/usb/misc/phidgetmotorcontrol.c index f0113c17cc5a..9b4696f21b22 100644 --- a/drivers/usb/misc/phidgetmotorcontrol.c +++ b/drivers/usb/misc/phidgetmotorcontrol.c | |||
@@ -365,16 +365,15 @@ static int motorcontrol_probe(struct usb_interface *intf, const struct usb_devic | |||
365 | } while(value); | 365 | } while(value); |
366 | mc->dev_no = bit; | 366 | mc->dev_no = bit; |
367 | 367 | ||
368 | mc->dev = device_create(phidget_class, &mc->udev->dev, 0, | 368 | mc->dev = device_create_drvdata(phidget_class, &mc->udev->dev, |
369 | "motorcontrol%d", mc->dev_no); | 369 | MKDEV(0, 0), mc, |
370 | "motorcontrol%d", mc->dev_no); | ||
370 | if (IS_ERR(mc->dev)) { | 371 | if (IS_ERR(mc->dev)) { |
371 | rc = PTR_ERR(mc->dev); | 372 | rc = PTR_ERR(mc->dev); |
372 | mc->dev = NULL; | 373 | mc->dev = NULL; |
373 | goto out; | 374 | goto out; |
374 | } | 375 | } |
375 | 376 | ||
376 | dev_set_drvdata(mc->dev, mc); | ||
377 | |||
378 | if (usb_submit_urb(mc->irq, GFP_KERNEL)) { | 377 | if (usb_submit_urb(mc->irq, GFP_KERNEL)) { |
379 | rc = -EIO; | 378 | rc = -EIO; |
380 | goto out; | 379 | goto out; |
diff --git a/drivers/usb/misc/phidgetservo.c b/drivers/usb/misc/phidgetservo.c index 7d590c09434a..1ca7ddb41d4d 100644 --- a/drivers/usb/misc/phidgetservo.c +++ b/drivers/usb/misc/phidgetservo.c | |||
@@ -275,14 +275,14 @@ servo_probe(struct usb_interface *interface, const struct usb_device_id *id) | |||
275 | } while (value); | 275 | } while (value); |
276 | dev->dev_no = bit; | 276 | dev->dev_no = bit; |
277 | 277 | ||
278 | dev->dev = device_create(phidget_class, &dev->udev->dev, 0, | 278 | dev->dev = device_create_drvdata(phidget_class, &dev->udev->dev, |
279 | "servo%d", dev->dev_no); | 279 | MKDEV(0, 0), dev, |
280 | "servo%d", dev->dev_no); | ||
280 | if (IS_ERR(dev->dev)) { | 281 | if (IS_ERR(dev->dev)) { |
281 | rc = PTR_ERR(dev->dev); | 282 | rc = PTR_ERR(dev->dev); |
282 | dev->dev = NULL; | 283 | dev->dev = NULL; |
283 | goto out; | 284 | goto out; |
284 | } | 285 | } |
285 | dev_set_drvdata(dev->dev, dev); | ||
286 | 286 | ||
287 | servo_count = dev->type & SERVO_COUNT_QUAD ? 4 : 1; | 287 | servo_count = dev->type & SERVO_COUNT_QUAD ? 4 : 1; |
288 | 288 | ||
diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c index ba28fdc9ccd2..1f7c86bd8297 100644 --- a/drivers/usb/serial/ch341.c +++ b/drivers/usb/serial/ch341.c | |||
@@ -28,6 +28,7 @@ static int debug; | |||
28 | 28 | ||
29 | static struct usb_device_id id_table [] = { | 29 | static struct usb_device_id id_table [] = { |
30 | { USB_DEVICE(0x4348, 0x5523) }, | 30 | { USB_DEVICE(0x4348, 0x5523) }, |
31 | { USB_DEVICE(0x1a86, 0x7523) }, | ||
31 | { }, | 32 | { }, |
32 | }; | 33 | }; |
33 | MODULE_DEVICE_TABLE(usb, id_table); | 34 | MODULE_DEVICE_TABLE(usb, id_table); |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 5b349ece7247..5234e7a3bd2c 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -174,8 +174,270 @@ static struct usb_device_id id_table_combined [] = { | |||
174 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_4_PID) }, | 174 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_4_PID) }, |
175 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_5_PID) }, | 175 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_5_PID) }, |
176 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) }, | 176 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) }, |
177 | { USB_DEVICE(MTXORB_VK_VID, MTXORB_VK_PID), | 177 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0100_PID) }, |
178 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0101_PID) }, | ||
179 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0102_PID) }, | ||
180 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0103_PID) }, | ||
181 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0104_PID) }, | ||
182 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0105_PID) }, | ||
183 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0106_PID) }, | ||
184 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0107_PID) }, | ||
185 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0108_PID) }, | ||
186 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0109_PID) }, | ||
187 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_010A_PID) }, | ||
188 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_010B_PID) }, | ||
189 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_010C_PID) }, | ||
190 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_010D_PID) }, | ||
191 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_010E_PID) }, | ||
192 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_010F_PID) }, | ||
193 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0110_PID) }, | ||
194 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0111_PID) }, | ||
195 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0112_PID) }, | ||
196 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0113_PID) }, | ||
197 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0114_PID) }, | ||
198 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0115_PID) }, | ||
199 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0116_PID) }, | ||
200 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0117_PID) }, | ||
201 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0118_PID) }, | ||
202 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0119_PID) }, | ||
203 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_011A_PID) }, | ||
204 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_011B_PID) }, | ||
205 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_011C_PID) }, | ||
206 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_011D_PID) }, | ||
207 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_011E_PID) }, | ||
208 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_011F_PID) }, | ||
209 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0120_PID) }, | ||
210 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0121_PID) }, | ||
211 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0122_PID) }, | ||
212 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0123_PID) }, | ||
213 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0124_PID) }, | ||
214 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0125_PID) }, | ||
215 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0126_PID) }, | ||
216 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0127_PID), | ||
178 | .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk }, | 217 | .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk }, |
218 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0128_PID) }, | ||
219 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0129_PID) }, | ||
220 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_012A_PID) }, | ||
221 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_012B_PID) }, | ||
222 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_012C_PID), | ||
223 | .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk }, | ||
224 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_012D_PID) }, | ||
225 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_012E_PID) }, | ||
226 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_012F_PID) }, | ||
227 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0130_PID) }, | ||
228 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0131_PID) }, | ||
229 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0132_PID) }, | ||
230 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0133_PID) }, | ||
231 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0134_PID) }, | ||
232 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0135_PID) }, | ||
233 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0136_PID) }, | ||
234 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0137_PID) }, | ||
235 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0138_PID) }, | ||
236 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0139_PID) }, | ||
237 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_013A_PID) }, | ||
238 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_013B_PID) }, | ||
239 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_013C_PID) }, | ||
240 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_013D_PID) }, | ||
241 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_013E_PID) }, | ||
242 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_013F_PID) }, | ||
243 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0140_PID) }, | ||
244 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0141_PID) }, | ||
245 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0142_PID) }, | ||
246 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0143_PID) }, | ||
247 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0144_PID) }, | ||
248 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0145_PID) }, | ||
249 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0146_PID) }, | ||
250 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0147_PID) }, | ||
251 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0148_PID) }, | ||
252 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0149_PID) }, | ||
253 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_014A_PID) }, | ||
254 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_014B_PID) }, | ||
255 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_014C_PID) }, | ||
256 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_014D_PID) }, | ||
257 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_014E_PID) }, | ||
258 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_014F_PID) }, | ||
259 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0150_PID) }, | ||
260 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0151_PID) }, | ||
261 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0152_PID) }, | ||
262 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0153_PID), | ||
263 | .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk }, | ||
264 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0154_PID), | ||
265 | .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk }, | ||
266 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0155_PID), | ||
267 | .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk }, | ||
268 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0156_PID), | ||
269 | .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk }, | ||
270 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0157_PID), | ||
271 | .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk }, | ||
272 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0158_PID), | ||
273 | .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk }, | ||
274 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0159_PID) }, | ||
275 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_015A_PID) }, | ||
276 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_015B_PID) }, | ||
277 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_015C_PID) }, | ||
278 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_015D_PID) }, | ||
279 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_015E_PID) }, | ||
280 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_015F_PID) }, | ||
281 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0160_PID) }, | ||
282 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0161_PID) }, | ||
283 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0162_PID) }, | ||
284 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0163_PID) }, | ||
285 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0164_PID) }, | ||
286 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0165_PID) }, | ||
287 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0166_PID) }, | ||
288 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0167_PID) }, | ||
289 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0168_PID) }, | ||
290 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0169_PID) }, | ||
291 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_016A_PID) }, | ||
292 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_016B_PID) }, | ||
293 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_016C_PID) }, | ||
294 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_016D_PID) }, | ||
295 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_016E_PID) }, | ||
296 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_016F_PID) }, | ||
297 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0170_PID) }, | ||
298 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0171_PID) }, | ||
299 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0172_PID) }, | ||
300 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0173_PID) }, | ||
301 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0174_PID) }, | ||
302 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0175_PID) }, | ||
303 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0176_PID) }, | ||
304 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0177_PID) }, | ||
305 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0178_PID) }, | ||
306 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0179_PID) }, | ||
307 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_017A_PID) }, | ||
308 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_017B_PID) }, | ||
309 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_017C_PID) }, | ||
310 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_017D_PID) }, | ||
311 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_017E_PID) }, | ||
312 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_017F_PID) }, | ||
313 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0180_PID) }, | ||
314 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0181_PID) }, | ||
315 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0182_PID) }, | ||
316 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0183_PID) }, | ||
317 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0184_PID) }, | ||
318 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0185_PID) }, | ||
319 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0186_PID) }, | ||
320 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0187_PID) }, | ||
321 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0188_PID) }, | ||
322 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0189_PID) }, | ||
323 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_018A_PID) }, | ||
324 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_018B_PID) }, | ||
325 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_018C_PID) }, | ||
326 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_018D_PID) }, | ||
327 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_018E_PID) }, | ||
328 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_018F_PID) }, | ||
329 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0190_PID) }, | ||
330 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0191_PID) }, | ||
331 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0192_PID) }, | ||
332 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0193_PID) }, | ||
333 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0194_PID) }, | ||
334 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0195_PID) }, | ||
335 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0196_PID) }, | ||
336 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0197_PID) }, | ||
337 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0198_PID) }, | ||
338 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0199_PID) }, | ||
339 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_019A_PID) }, | ||
340 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_019B_PID) }, | ||
341 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_019C_PID) }, | ||
342 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_019D_PID) }, | ||
343 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_019E_PID) }, | ||
344 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_019F_PID) }, | ||
345 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A0_PID) }, | ||
346 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A1_PID) }, | ||
347 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A2_PID) }, | ||
348 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A3_PID) }, | ||
349 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A4_PID) }, | ||
350 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A5_PID) }, | ||
351 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A6_PID) }, | ||
352 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A7_PID) }, | ||
353 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A8_PID) }, | ||
354 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A9_PID) }, | ||
355 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01AA_PID) }, | ||
356 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01AB_PID) }, | ||
357 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01AC_PID) }, | ||
358 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01AD_PID) }, | ||
359 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01AE_PID) }, | ||
360 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01AF_PID) }, | ||
361 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B0_PID) }, | ||
362 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B1_PID) }, | ||
363 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B2_PID) }, | ||
364 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B3_PID) }, | ||
365 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B4_PID) }, | ||
366 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B5_PID) }, | ||
367 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B6_PID) }, | ||
368 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B7_PID) }, | ||
369 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B8_PID) }, | ||
370 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B9_PID) }, | ||
371 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01BA_PID) }, | ||
372 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01BB_PID) }, | ||
373 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01BC_PID) }, | ||
374 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01BD_PID) }, | ||
375 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01BE_PID) }, | ||
376 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01BF_PID) }, | ||
377 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C0_PID) }, | ||
378 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C1_PID) }, | ||
379 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C2_PID) }, | ||
380 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C3_PID) }, | ||
381 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C4_PID) }, | ||
382 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C5_PID) }, | ||
383 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C6_PID) }, | ||
384 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C7_PID) }, | ||
385 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C8_PID) }, | ||
386 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C9_PID) }, | ||
387 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01CA_PID) }, | ||
388 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01CB_PID) }, | ||
389 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01CC_PID) }, | ||
390 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01CD_PID) }, | ||
391 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01CE_PID) }, | ||
392 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01CF_PID) }, | ||
393 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D0_PID) }, | ||
394 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D1_PID) }, | ||
395 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D2_PID) }, | ||
396 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D3_PID) }, | ||
397 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D4_PID) }, | ||
398 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D5_PID) }, | ||
399 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D6_PID) }, | ||
400 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D7_PID) }, | ||
401 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D8_PID) }, | ||
402 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D9_PID) }, | ||
403 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01DA_PID) }, | ||
404 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01DB_PID) }, | ||
405 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01DC_PID) }, | ||
406 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01DD_PID) }, | ||
407 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01DE_PID) }, | ||
408 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01DF_PID) }, | ||
409 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E0_PID) }, | ||
410 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E1_PID) }, | ||
411 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E2_PID) }, | ||
412 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E3_PID) }, | ||
413 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E4_PID) }, | ||
414 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E5_PID) }, | ||
415 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E6_PID) }, | ||
416 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E7_PID) }, | ||
417 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E8_PID) }, | ||
418 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E9_PID) }, | ||
419 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01EA_PID) }, | ||
420 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01EB_PID) }, | ||
421 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01EC_PID) }, | ||
422 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01ED_PID) }, | ||
423 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01EE_PID) }, | ||
424 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01EF_PID) }, | ||
425 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F0_PID) }, | ||
426 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F1_PID) }, | ||
427 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F2_PID) }, | ||
428 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F3_PID) }, | ||
429 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F4_PID) }, | ||
430 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F5_PID) }, | ||
431 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F6_PID) }, | ||
432 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F7_PID) }, | ||
433 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F8_PID) }, | ||
434 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F9_PID) }, | ||
435 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01FA_PID) }, | ||
436 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01FB_PID) }, | ||
437 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01FC_PID) }, | ||
438 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01FD_PID) }, | ||
439 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01FE_PID) }, | ||
440 | { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01FF_PID) }, | ||
179 | { USB_DEVICE(FTDI_VID, FTDI_PERLE_ULTRAPORT_PID) }, | 441 | { USB_DEVICE(FTDI_VID, FTDI_PERLE_ULTRAPORT_PID) }, |
180 | { USB_DEVICE(FTDI_VID, FTDI_PIEGROUP_PID) }, | 442 | { USB_DEVICE(FTDI_VID, FTDI_PIEGROUP_PID) }, |
181 | { USB_DEVICE(FTDI_VID, FTDI_TNC_X_PID) }, | 443 | { USB_DEVICE(FTDI_VID, FTDI_TNC_X_PID) }, |
@@ -374,6 +636,7 @@ static struct usb_device_id id_table_combined [] = { | |||
374 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | 636 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
375 | { USB_DEVICE(FTDI_VID, FTDI_OOCDLINK_PID), | 637 | { USB_DEVICE(FTDI_VID, FTDI_OOCDLINK_PID), |
376 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | 638 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
639 | { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) }, | ||
377 | { }, /* Optional parameter entry */ | 640 | { }, /* Optional parameter entry */ |
378 | { } /* Terminating entry */ | 641 | { } /* Terminating entry */ |
379 | }; | 642 | }; |
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 504edf8c3a3f..06e0ecabb3eb 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h | |||
@@ -114,11 +114,268 @@ | |||
114 | #define FTDI_OOCDLINK_PID 0xbaf8 /* Amontec JTAGkey */ | 114 | #define FTDI_OOCDLINK_PID 0xbaf8 /* Amontec JTAGkey */ |
115 | 115 | ||
116 | /* | 116 | /* |
117 | * The following are the values for the Matrix Orbital VK204-25-USB | 117 | * The following are the values for the Matrix Orbital FTDI Range |
118 | * display, which use the FT232RL. | 118 | * Anything in this range will use an FT232RL. |
119 | */ | 119 | */ |
120 | #define MTXORB_VK_VID 0x1b3d | 120 | #define MTXORB_VID 0x1B3D |
121 | #define MTXORB_VK_PID 0x0158 | 121 | #define MTXORB_FTDI_RANGE_0100_PID 0x0100 |
122 | #define MTXORB_FTDI_RANGE_0101_PID 0x0101 | ||
123 | #define MTXORB_FTDI_RANGE_0102_PID 0x0102 | ||
124 | #define MTXORB_FTDI_RANGE_0103_PID 0x0103 | ||
125 | #define MTXORB_FTDI_RANGE_0104_PID 0x0104 | ||
126 | #define MTXORB_FTDI_RANGE_0105_PID 0x0105 | ||
127 | #define MTXORB_FTDI_RANGE_0106_PID 0x0106 | ||
128 | #define MTXORB_FTDI_RANGE_0107_PID 0x0107 | ||
129 | #define MTXORB_FTDI_RANGE_0108_PID 0x0108 | ||
130 | #define MTXORB_FTDI_RANGE_0109_PID 0x0109 | ||
131 | #define MTXORB_FTDI_RANGE_010A_PID 0x010A | ||
132 | #define MTXORB_FTDI_RANGE_010B_PID 0x010B | ||
133 | #define MTXORB_FTDI_RANGE_010C_PID 0x010C | ||
134 | #define MTXORB_FTDI_RANGE_010D_PID 0x010D | ||
135 | #define MTXORB_FTDI_RANGE_010E_PID 0x010E | ||
136 | #define MTXORB_FTDI_RANGE_010F_PID 0x010F | ||
137 | #define MTXORB_FTDI_RANGE_0110_PID 0x0110 | ||
138 | #define MTXORB_FTDI_RANGE_0111_PID 0x0111 | ||
139 | #define MTXORB_FTDI_RANGE_0112_PID 0x0112 | ||
140 | #define MTXORB_FTDI_RANGE_0113_PID 0x0113 | ||
141 | #define MTXORB_FTDI_RANGE_0114_PID 0x0114 | ||
142 | #define MTXORB_FTDI_RANGE_0115_PID 0x0115 | ||
143 | #define MTXORB_FTDI_RANGE_0116_PID 0x0116 | ||
144 | #define MTXORB_FTDI_RANGE_0117_PID 0x0117 | ||
145 | #define MTXORB_FTDI_RANGE_0118_PID 0x0118 | ||
146 | #define MTXORB_FTDI_RANGE_0119_PID 0x0119 | ||
147 | #define MTXORB_FTDI_RANGE_011A_PID 0x011A | ||
148 | #define MTXORB_FTDI_RANGE_011B_PID 0x011B | ||
149 | #define MTXORB_FTDI_RANGE_011C_PID 0x011C | ||
150 | #define MTXORB_FTDI_RANGE_011D_PID 0x011D | ||
151 | #define MTXORB_FTDI_RANGE_011E_PID 0x011E | ||
152 | #define MTXORB_FTDI_RANGE_011F_PID 0x011F | ||
153 | #define MTXORB_FTDI_RANGE_0120_PID 0x0120 | ||
154 | #define MTXORB_FTDI_RANGE_0121_PID 0x0121 | ||
155 | #define MTXORB_FTDI_RANGE_0122_PID 0x0122 | ||
156 | #define MTXORB_FTDI_RANGE_0123_PID 0x0123 | ||
157 | #define MTXORB_FTDI_RANGE_0124_PID 0x0124 | ||
158 | #define MTXORB_FTDI_RANGE_0125_PID 0x0125 | ||
159 | #define MTXORB_FTDI_RANGE_0126_PID 0x0126 | ||
160 | #define MTXORB_FTDI_RANGE_0127_PID 0x0127 | ||
161 | #define MTXORB_FTDI_RANGE_0128_PID 0x0128 | ||
162 | #define MTXORB_FTDI_RANGE_0129_PID 0x0129 | ||
163 | #define MTXORB_FTDI_RANGE_012A_PID 0x012A | ||
164 | #define MTXORB_FTDI_RANGE_012B_PID 0x012B | ||
165 | #define MTXORB_FTDI_RANGE_012C_PID 0x012C | ||
166 | #define MTXORB_FTDI_RANGE_012D_PID 0x012D | ||
167 | #define MTXORB_FTDI_RANGE_012E_PID 0x012E | ||
168 | #define MTXORB_FTDI_RANGE_012F_PID 0x012F | ||
169 | #define MTXORB_FTDI_RANGE_0130_PID 0x0130 | ||
170 | #define MTXORB_FTDI_RANGE_0131_PID 0x0131 | ||
171 | #define MTXORB_FTDI_RANGE_0132_PID 0x0132 | ||
172 | #define MTXORB_FTDI_RANGE_0133_PID 0x0133 | ||
173 | #define MTXORB_FTDI_RANGE_0134_PID 0x0134 | ||
174 | #define MTXORB_FTDI_RANGE_0135_PID 0x0135 | ||
175 | #define MTXORB_FTDI_RANGE_0136_PID 0x0136 | ||
176 | #define MTXORB_FTDI_RANGE_0137_PID 0x0137 | ||
177 | #define MTXORB_FTDI_RANGE_0138_PID 0x0138 | ||
178 | #define MTXORB_FTDI_RANGE_0139_PID 0x0139 | ||
179 | #define MTXORB_FTDI_RANGE_013A_PID 0x013A | ||
180 | #define MTXORB_FTDI_RANGE_013B_PID 0x013B | ||
181 | #define MTXORB_FTDI_RANGE_013C_PID 0x013C | ||
182 | #define MTXORB_FTDI_RANGE_013D_PID 0x013D | ||
183 | #define MTXORB_FTDI_RANGE_013E_PID 0x013E | ||
184 | #define MTXORB_FTDI_RANGE_013F_PID 0x013F | ||
185 | #define MTXORB_FTDI_RANGE_0140_PID 0x0140 | ||
186 | #define MTXORB_FTDI_RANGE_0141_PID 0x0141 | ||
187 | #define MTXORB_FTDI_RANGE_0142_PID 0x0142 | ||
188 | #define MTXORB_FTDI_RANGE_0143_PID 0x0143 | ||
189 | #define MTXORB_FTDI_RANGE_0144_PID 0x0144 | ||
190 | #define MTXORB_FTDI_RANGE_0145_PID 0x0145 | ||
191 | #define MTXORB_FTDI_RANGE_0146_PID 0x0146 | ||
192 | #define MTXORB_FTDI_RANGE_0147_PID 0x0147 | ||
193 | #define MTXORB_FTDI_RANGE_0148_PID 0x0148 | ||
194 | #define MTXORB_FTDI_RANGE_0149_PID 0x0149 | ||
195 | #define MTXORB_FTDI_RANGE_014A_PID 0x014A | ||
196 | #define MTXORB_FTDI_RANGE_014B_PID 0x014B | ||
197 | #define MTXORB_FTDI_RANGE_014C_PID 0x014C | ||
198 | #define MTXORB_FTDI_RANGE_014D_PID 0x014D | ||
199 | #define MTXORB_FTDI_RANGE_014E_PID 0x014E | ||
200 | #define MTXORB_FTDI_RANGE_014F_PID 0x014F | ||
201 | #define MTXORB_FTDI_RANGE_0150_PID 0x0150 | ||
202 | #define MTXORB_FTDI_RANGE_0151_PID 0x0151 | ||
203 | #define MTXORB_FTDI_RANGE_0152_PID 0x0152 | ||
204 | #define MTXORB_FTDI_RANGE_0153_PID 0x0153 | ||
205 | #define MTXORB_FTDI_RANGE_0154_PID 0x0154 | ||
206 | #define MTXORB_FTDI_RANGE_0155_PID 0x0155 | ||
207 | #define MTXORB_FTDI_RANGE_0156_PID 0x0156 | ||
208 | #define MTXORB_FTDI_RANGE_0157_PID 0x0157 | ||
209 | #define MTXORB_FTDI_RANGE_0158_PID 0x0158 | ||
210 | #define MTXORB_FTDI_RANGE_0159_PID 0x0159 | ||
211 | #define MTXORB_FTDI_RANGE_015A_PID 0x015A | ||
212 | #define MTXORB_FTDI_RANGE_015B_PID 0x015B | ||
213 | #define MTXORB_FTDI_RANGE_015C_PID 0x015C | ||
214 | #define MTXORB_FTDI_RANGE_015D_PID 0x015D | ||
215 | #define MTXORB_FTDI_RANGE_015E_PID 0x015E | ||
216 | #define MTXORB_FTDI_RANGE_015F_PID 0x015F | ||
217 | #define MTXORB_FTDI_RANGE_0160_PID 0x0160 | ||
218 | #define MTXORB_FTDI_RANGE_0161_PID 0x0161 | ||
219 | #define MTXORB_FTDI_RANGE_0162_PID 0x0162 | ||
220 | #define MTXORB_FTDI_RANGE_0163_PID 0x0163 | ||
221 | #define MTXORB_FTDI_RANGE_0164_PID 0x0164 | ||
222 | #define MTXORB_FTDI_RANGE_0165_PID 0x0165 | ||
223 | #define MTXORB_FTDI_RANGE_0166_PID 0x0166 | ||
224 | #define MTXORB_FTDI_RANGE_0167_PID 0x0167 | ||
225 | #define MTXORB_FTDI_RANGE_0168_PID 0x0168 | ||
226 | #define MTXORB_FTDI_RANGE_0169_PID 0x0169 | ||
227 | #define MTXORB_FTDI_RANGE_016A_PID 0x016A | ||
228 | #define MTXORB_FTDI_RANGE_016B_PID 0x016B | ||
229 | #define MTXORB_FTDI_RANGE_016C_PID 0x016C | ||
230 | #define MTXORB_FTDI_RANGE_016D_PID 0x016D | ||
231 | #define MTXORB_FTDI_RANGE_016E_PID 0x016E | ||
232 | #define MTXORB_FTDI_RANGE_016F_PID 0x016F | ||
233 | #define MTXORB_FTDI_RANGE_0170_PID 0x0170 | ||
234 | #define MTXORB_FTDI_RANGE_0171_PID 0x0171 | ||
235 | #define MTXORB_FTDI_RANGE_0172_PID 0x0172 | ||
236 | #define MTXORB_FTDI_RANGE_0173_PID 0x0173 | ||
237 | #define MTXORB_FTDI_RANGE_0174_PID 0x0174 | ||
238 | #define MTXORB_FTDI_RANGE_0175_PID 0x0175 | ||
239 | #define MTXORB_FTDI_RANGE_0176_PID 0x0176 | ||
240 | #define MTXORB_FTDI_RANGE_0177_PID 0x0177 | ||
241 | #define MTXORB_FTDI_RANGE_0178_PID 0x0178 | ||
242 | #define MTXORB_FTDI_RANGE_0179_PID 0x0179 | ||
243 | #define MTXORB_FTDI_RANGE_017A_PID 0x017A | ||
244 | #define MTXORB_FTDI_RANGE_017B_PID 0x017B | ||
245 | #define MTXORB_FTDI_RANGE_017C_PID 0x017C | ||
246 | #define MTXORB_FTDI_RANGE_017D_PID 0x017D | ||
247 | #define MTXORB_FTDI_RANGE_017E_PID 0x017E | ||
248 | #define MTXORB_FTDI_RANGE_017F_PID 0x017F | ||
249 | #define MTXORB_FTDI_RANGE_0180_PID 0x0180 | ||
250 | #define MTXORB_FTDI_RANGE_0181_PID 0x0181 | ||
251 | #define MTXORB_FTDI_RANGE_0182_PID 0x0182 | ||
252 | #define MTXORB_FTDI_RANGE_0183_PID 0x0183 | ||
253 | #define MTXORB_FTDI_RANGE_0184_PID 0x0184 | ||
254 | #define MTXORB_FTDI_RANGE_0185_PID 0x0185 | ||
255 | #define MTXORB_FTDI_RANGE_0186_PID 0x0186 | ||
256 | #define MTXORB_FTDI_RANGE_0187_PID 0x0187 | ||
257 | #define MTXORB_FTDI_RANGE_0188_PID 0x0188 | ||
258 | #define MTXORB_FTDI_RANGE_0189_PID 0x0189 | ||
259 | #define MTXORB_FTDI_RANGE_018A_PID 0x018A | ||
260 | #define MTXORB_FTDI_RANGE_018B_PID 0x018B | ||
261 | #define MTXORB_FTDI_RANGE_018C_PID 0x018C | ||
262 | #define MTXORB_FTDI_RANGE_018D_PID 0x018D | ||
263 | #define MTXORB_FTDI_RANGE_018E_PID 0x018E | ||
264 | #define MTXORB_FTDI_RANGE_018F_PID 0x018F | ||
265 | #define MTXORB_FTDI_RANGE_0190_PID 0x0190 | ||
266 | #define MTXORB_FTDI_RANGE_0191_PID 0x0191 | ||
267 | #define MTXORB_FTDI_RANGE_0192_PID 0x0192 | ||
268 | #define MTXORB_FTDI_RANGE_0193_PID 0x0193 | ||
269 | #define MTXORB_FTDI_RANGE_0194_PID 0x0194 | ||
270 | #define MTXORB_FTDI_RANGE_0195_PID 0x0195 | ||
271 | #define MTXORB_FTDI_RANGE_0196_PID 0x0196 | ||
272 | #define MTXORB_FTDI_RANGE_0197_PID 0x0197 | ||
273 | #define MTXORB_FTDI_RANGE_0198_PID 0x0198 | ||
274 | #define MTXORB_FTDI_RANGE_0199_PID 0x0199 | ||
275 | #define MTXORB_FTDI_RANGE_019A_PID 0x019A | ||
276 | #define MTXORB_FTDI_RANGE_019B_PID 0x019B | ||
277 | #define MTXORB_FTDI_RANGE_019C_PID 0x019C | ||
278 | #define MTXORB_FTDI_RANGE_019D_PID 0x019D | ||
279 | #define MTXORB_FTDI_RANGE_019E_PID 0x019E | ||
280 | #define MTXORB_FTDI_RANGE_019F_PID 0x019F | ||
281 | #define MTXORB_FTDI_RANGE_01A0_PID 0x01A0 | ||
282 | #define MTXORB_FTDI_RANGE_01A1_PID 0x01A1 | ||
283 | #define MTXORB_FTDI_RANGE_01A2_PID 0x01A2 | ||
284 | #define MTXORB_FTDI_RANGE_01A3_PID 0x01A3 | ||
285 | #define MTXORB_FTDI_RANGE_01A4_PID 0x01A4 | ||
286 | #define MTXORB_FTDI_RANGE_01A5_PID 0x01A5 | ||
287 | #define MTXORB_FTDI_RANGE_01A6_PID 0x01A6 | ||
288 | #define MTXORB_FTDI_RANGE_01A7_PID 0x01A7 | ||
289 | #define MTXORB_FTDI_RANGE_01A8_PID 0x01A8 | ||
290 | #define MTXORB_FTDI_RANGE_01A9_PID 0x01A9 | ||
291 | #define MTXORB_FTDI_RANGE_01AA_PID 0x01AA | ||
292 | #define MTXORB_FTDI_RANGE_01AB_PID 0x01AB | ||
293 | #define MTXORB_FTDI_RANGE_01AC_PID 0x01AC | ||
294 | #define MTXORB_FTDI_RANGE_01AD_PID 0x01AD | ||
295 | #define MTXORB_FTDI_RANGE_01AE_PID 0x01AE | ||
296 | #define MTXORB_FTDI_RANGE_01AF_PID 0x01AF | ||
297 | #define MTXORB_FTDI_RANGE_01B0_PID 0x01B0 | ||
298 | #define MTXORB_FTDI_RANGE_01B1_PID 0x01B1 | ||
299 | #define MTXORB_FTDI_RANGE_01B2_PID 0x01B2 | ||
300 | #define MTXORB_FTDI_RANGE_01B3_PID 0x01B3 | ||
301 | #define MTXORB_FTDI_RANGE_01B4_PID 0x01B4 | ||
302 | #define MTXORB_FTDI_RANGE_01B5_PID 0x01B5 | ||
303 | #define MTXORB_FTDI_RANGE_01B6_PID 0x01B6 | ||
304 | #define MTXORB_FTDI_RANGE_01B7_PID 0x01B7 | ||
305 | #define MTXORB_FTDI_RANGE_01B8_PID 0x01B8 | ||
306 | #define MTXORB_FTDI_RANGE_01B9_PID 0x01B9 | ||
307 | #define MTXORB_FTDI_RANGE_01BA_PID 0x01BA | ||
308 | #define MTXORB_FTDI_RANGE_01BB_PID 0x01BB | ||
309 | #define MTXORB_FTDI_RANGE_01BC_PID 0x01BC | ||
310 | #define MTXORB_FTDI_RANGE_01BD_PID 0x01BD | ||
311 | #define MTXORB_FTDI_RANGE_01BE_PID 0x01BE | ||
312 | #define MTXORB_FTDI_RANGE_01BF_PID 0x01BF | ||
313 | #define MTXORB_FTDI_RANGE_01C0_PID 0x01C0 | ||
314 | #define MTXORB_FTDI_RANGE_01C1_PID 0x01C1 | ||
315 | #define MTXORB_FTDI_RANGE_01C2_PID 0x01C2 | ||
316 | #define MTXORB_FTDI_RANGE_01C3_PID 0x01C3 | ||
317 | #define MTXORB_FTDI_RANGE_01C4_PID 0x01C4 | ||
318 | #define MTXORB_FTDI_RANGE_01C5_PID 0x01C5 | ||
319 | #define MTXORB_FTDI_RANGE_01C6_PID 0x01C6 | ||
320 | #define MTXORB_FTDI_RANGE_01C7_PID 0x01C7 | ||
321 | #define MTXORB_FTDI_RANGE_01C8_PID 0x01C8 | ||
322 | #define MTXORB_FTDI_RANGE_01C9_PID 0x01C9 | ||
323 | #define MTXORB_FTDI_RANGE_01CA_PID 0x01CA | ||
324 | #define MTXORB_FTDI_RANGE_01CB_PID 0x01CB | ||
325 | #define MTXORB_FTDI_RANGE_01CC_PID 0x01CC | ||
326 | #define MTXORB_FTDI_RANGE_01CD_PID 0x01CD | ||
327 | #define MTXORB_FTDI_RANGE_01CE_PID 0x01CE | ||
328 | #define MTXORB_FTDI_RANGE_01CF_PID 0x01CF | ||
329 | #define MTXORB_FTDI_RANGE_01D0_PID 0x01D0 | ||
330 | #define MTXORB_FTDI_RANGE_01D1_PID 0x01D1 | ||
331 | #define MTXORB_FTDI_RANGE_01D2_PID 0x01D2 | ||
332 | #define MTXORB_FTDI_RANGE_01D3_PID 0x01D3 | ||
333 | #define MTXORB_FTDI_RANGE_01D4_PID 0x01D4 | ||
334 | #define MTXORB_FTDI_RANGE_01D5_PID 0x01D5 | ||
335 | #define MTXORB_FTDI_RANGE_01D6_PID 0x01D6 | ||
336 | #define MTXORB_FTDI_RANGE_01D7_PID 0x01D7 | ||
337 | #define MTXORB_FTDI_RANGE_01D8_PID 0x01D8 | ||
338 | #define MTXORB_FTDI_RANGE_01D9_PID 0x01D9 | ||
339 | #define MTXORB_FTDI_RANGE_01DA_PID 0x01DA | ||
340 | #define MTXORB_FTDI_RANGE_01DB_PID 0x01DB | ||
341 | #define MTXORB_FTDI_RANGE_01DC_PID 0x01DC | ||
342 | #define MTXORB_FTDI_RANGE_01DD_PID 0x01DD | ||
343 | #define MTXORB_FTDI_RANGE_01DE_PID 0x01DE | ||
344 | #define MTXORB_FTDI_RANGE_01DF_PID 0x01DF | ||
345 | #define MTXORB_FTDI_RANGE_01E0_PID 0x01E0 | ||
346 | #define MTXORB_FTDI_RANGE_01E1_PID 0x01E1 | ||
347 | #define MTXORB_FTDI_RANGE_01E2_PID 0x01E2 | ||
348 | #define MTXORB_FTDI_RANGE_01E3_PID 0x01E3 | ||
349 | #define MTXORB_FTDI_RANGE_01E4_PID 0x01E4 | ||
350 | #define MTXORB_FTDI_RANGE_01E5_PID 0x01E5 | ||
351 | #define MTXORB_FTDI_RANGE_01E6_PID 0x01E6 | ||
352 | #define MTXORB_FTDI_RANGE_01E7_PID 0x01E7 | ||
353 | #define MTXORB_FTDI_RANGE_01E8_PID 0x01E8 | ||
354 | #define MTXORB_FTDI_RANGE_01E9_PID 0x01E9 | ||
355 | #define MTXORB_FTDI_RANGE_01EA_PID 0x01EA | ||
356 | #define MTXORB_FTDI_RANGE_01EB_PID 0x01EB | ||
357 | #define MTXORB_FTDI_RANGE_01EC_PID 0x01EC | ||
358 | #define MTXORB_FTDI_RANGE_01ED_PID 0x01ED | ||
359 | #define MTXORB_FTDI_RANGE_01EE_PID 0x01EE | ||
360 | #define MTXORB_FTDI_RANGE_01EF_PID 0x01EF | ||
361 | #define MTXORB_FTDI_RANGE_01F0_PID 0x01F0 | ||
362 | #define MTXORB_FTDI_RANGE_01F1_PID 0x01F1 | ||
363 | #define MTXORB_FTDI_RANGE_01F2_PID 0x01F2 | ||
364 | #define MTXORB_FTDI_RANGE_01F3_PID 0x01F3 | ||
365 | #define MTXORB_FTDI_RANGE_01F4_PID 0x01F4 | ||
366 | #define MTXORB_FTDI_RANGE_01F5_PID 0x01F5 | ||
367 | #define MTXORB_FTDI_RANGE_01F6_PID 0x01F6 | ||
368 | #define MTXORB_FTDI_RANGE_01F7_PID 0x01F7 | ||
369 | #define MTXORB_FTDI_RANGE_01F8_PID 0x01F8 | ||
370 | #define MTXORB_FTDI_RANGE_01F9_PID 0x01F9 | ||
371 | #define MTXORB_FTDI_RANGE_01FA_PID 0x01FA | ||
372 | #define MTXORB_FTDI_RANGE_01FB_PID 0x01FB | ||
373 | #define MTXORB_FTDI_RANGE_01FC_PID 0x01FC | ||
374 | #define MTXORB_FTDI_RANGE_01FD_PID 0x01FD | ||
375 | #define MTXORB_FTDI_RANGE_01FE_PID 0x01FE | ||
376 | #define MTXORB_FTDI_RANGE_01FF_PID 0x01FF | ||
377 | |||
378 | |||
122 | 379 | ||
123 | /* Interbiometrics USB I/O Board */ | 380 | /* Interbiometrics USB I/O Board */ |
124 | /* Developed for Interbiometrics by Rudolf Gugler */ | 381 | /* Developed for Interbiometrics by Rudolf Gugler */ |
@@ -592,6 +849,12 @@ | |||
592 | #define FIC_NEO1973_DEBUG_PID 0x5118 | 849 | #define FIC_NEO1973_DEBUG_PID 0x5118 |
593 | 850 | ||
594 | /* | 851 | /* |
852 | * RATOC REX-USB60F | ||
853 | */ | ||
854 | #define RATOC_VENDOR_ID 0x0584 | ||
855 | #define RATOC_PRODUCT_ID_USB60F 0xb020 | ||
856 | |||
857 | /* | ||
595 | * BmRequestType: 1100 0000b | 858 | * BmRequestType: 1100 0000b |
596 | * bRequest: FTDI_E2_READ | 859 | * bRequest: FTDI_E2_READ |
597 | * wValue: 0 | 860 | * wValue: 0 |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index e7e016e60333..43cfde83a93b 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -183,6 +183,7 @@ static int option_send_setup(struct usb_serial_port *port); | |||
183 | #define AXESSTEL_PRODUCT_MV110H 0x1000 | 183 | #define AXESSTEL_PRODUCT_MV110H 0x1000 |
184 | 184 | ||
185 | #define ONDA_VENDOR_ID 0x19d2 | 185 | #define ONDA_VENDOR_ID 0x19d2 |
186 | #define ONDA_PRODUCT_MSA501HS 0x0001 | ||
186 | #define ONDA_PRODUCT_ET502HS 0x0002 | 187 | #define ONDA_PRODUCT_ET502HS 0x0002 |
187 | 188 | ||
188 | #define BANDRICH_VENDOR_ID 0x1A8D | 189 | #define BANDRICH_VENDOR_ID 0x1A8D |
@@ -196,6 +197,9 @@ static int option_send_setup(struct usb_serial_port *port); | |||
196 | 197 | ||
197 | #define MAXON_VENDOR_ID 0x16d8 | 198 | #define MAXON_VENDOR_ID 0x16d8 |
198 | 199 | ||
200 | #define TELIT_VENDOR_ID 0x1bc7 | ||
201 | #define TELIT_PRODUCT_UC864E 0x1003 | ||
202 | |||
199 | static struct usb_device_id option_ids[] = { | 203 | static struct usb_device_id option_ids[] = { |
200 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, | 204 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, |
201 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, | 205 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, |
@@ -232,25 +236,25 @@ static struct usb_device_id option_ids[] = { | |||
232 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_NETWORK_EX) }, | 236 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_NETWORK_EX) }, |
233 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_KOI_MODEM) }, | 237 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_KOI_MODEM) }, |
234 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_KOI_NETWORK) }, | 238 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_KOI_NETWORK) }, |
235 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) }, | 239 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600, 0xff, 0xff, 0xff) }, |
236 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220, 0xff, 0xff, 0xff) }, | 240 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220, 0xff, 0xff, 0xff) }, |
237 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220BIS, 0xff, 0xff, 0xff) }, | 241 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220BIS, 0xff, 0xff, 0xff) }, |
238 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1401) }, | 242 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1401, 0xff, 0xff, 0xff) }, |
239 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1403) }, | 243 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1403, 0xff, 0xff, 0xff) }, |
240 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1405) }, | 244 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1405, 0xff, 0xff, 0xff) }, |
241 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1406) }, | 245 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1406, 0xff, 0xff, 0xff) }, |
242 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1408) }, | 246 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1408, 0xff, 0xff, 0xff) }, |
243 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1409) }, | 247 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1409, 0xff, 0xff, 0xff) }, |
244 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1410) }, | 248 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1410, 0xff, 0xff, 0xff) }, |
245 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1411) }, | 249 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1411, 0xff, 0xff, 0xff) }, |
246 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1412) }, | 250 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1412, 0xff, 0xff, 0xff) }, |
247 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1413) }, | 251 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1413, 0xff, 0xff, 0xff) }, |
248 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1414) }, | 252 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1414, 0xff, 0xff, 0xff) }, |
249 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1415) }, | 253 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1415, 0xff, 0xff, 0xff) }, |
250 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1416) }, | 254 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1416, 0xff, 0xff, 0xff) }, |
251 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1417) }, | 255 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1417, 0xff, 0xff, 0xff) }, |
252 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1418) }, | 256 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1418, 0xff, 0xff, 0xff) }, |
253 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1419) }, | 257 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1419, 0xff, 0xff, 0xff) }, |
254 | { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_9508) }, | 258 | { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_9508) }, |
255 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) }, /* Novatel Merlin V640/XV620 */ | 259 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) }, /* Novatel Merlin V640/XV620 */ |
256 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) }, /* Novatel Merlin V620/S620 */ | 260 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) }, /* Novatel Merlin V620/S620 */ |
@@ -297,13 +301,14 @@ static struct usb_device_id option_ids[] = { | |||
297 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, | 301 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, |
298 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, | 302 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, |
299 | { USB_DEVICE(AXESSTEL_VENDOR_ID, AXESSTEL_PRODUCT_MV110H) }, | 303 | { USB_DEVICE(AXESSTEL_VENDOR_ID, AXESSTEL_PRODUCT_MV110H) }, |
304 | { USB_DEVICE(ONDA_VENDOR_ID, ONDA_PRODUCT_MSA501HS) }, | ||
300 | { USB_DEVICE(ONDA_VENDOR_ID, ONDA_PRODUCT_ET502HS) }, | 305 | { USB_DEVICE(ONDA_VENDOR_ID, ONDA_PRODUCT_ET502HS) }, |
301 | { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) }, | 306 | { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) }, |
302 | { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) }, | 307 | { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) }, |
303 | { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) }, | 308 | { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) }, |
304 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ | 309 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ |
305 | { USB_DEVICE(MAXON_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */ | 310 | { USB_DEVICE(MAXON_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */ |
306 | { USB_DEVICE(0x19d2, 0x0001) }, /* Telstra NextG CDMA */ | 311 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) }, |
307 | { } /* Terminating entry */ | 312 | { } /* Terminating entry */ |
308 | }; | 313 | }; |
309 | MODULE_DEVICE_TABLE(usb, option_ids); | 314 | MODULE_DEVICE_TABLE(usb, option_ids); |
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index c605fb68f807..103195abd417 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c | |||
@@ -56,6 +56,7 @@ static struct usb_device_id id_table [] = { | |||
56 | { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_RSAQ3) }, | 56 | { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_RSAQ3) }, |
57 | { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_PHAROS) }, | 57 | { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_PHAROS) }, |
58 | { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_ALDIGA) }, | 58 | { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_ALDIGA) }, |
59 | { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_MMX) }, | ||
59 | { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID) }, | 60 | { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID) }, |
60 | { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID_RSAQ5) }, | 61 | { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID_RSAQ5) }, |
61 | { USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID) }, | 62 | { USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID) }, |
@@ -66,7 +67,6 @@ static struct usb_device_id id_table [] = { | |||
66 | { USB_DEVICE(ITEGNO_VENDOR_ID, ITEGNO_PRODUCT_ID_2080) }, | 67 | { USB_DEVICE(ITEGNO_VENDOR_ID, ITEGNO_PRODUCT_ID_2080) }, |
67 | { USB_DEVICE(MA620_VENDOR_ID, MA620_PRODUCT_ID) }, | 68 | { USB_DEVICE(MA620_VENDOR_ID, MA620_PRODUCT_ID) }, |
68 | { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID) }, | 69 | { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID) }, |
69 | { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) }, | ||
70 | { USB_DEVICE(TRIPP_VENDOR_ID, TRIPP_PRODUCT_ID) }, | 70 | { USB_DEVICE(TRIPP_VENDOR_ID, TRIPP_PRODUCT_ID) }, |
71 | { USB_DEVICE(RADIOSHACK_VENDOR_ID, RADIOSHACK_PRODUCT_ID) }, | 71 | { USB_DEVICE(RADIOSHACK_VENDOR_ID, RADIOSHACK_PRODUCT_ID) }, |
72 | { USB_DEVICE(DCU10_VENDOR_ID, DCU10_PRODUCT_ID) }, | 72 | { USB_DEVICE(DCU10_VENDOR_ID, DCU10_PRODUCT_ID) }, |
diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h index 10cf872e5ecb..cff160abb130 100644 --- a/drivers/usb/serial/pl2303.h +++ b/drivers/usb/serial/pl2303.h | |||
@@ -14,6 +14,7 @@ | |||
14 | #define PL2303_PRODUCT_ID_PHAROS 0xaaa0 | 14 | #define PL2303_PRODUCT_ID_PHAROS 0xaaa0 |
15 | #define PL2303_PRODUCT_ID_RSAQ3 0xaaa2 | 15 | #define PL2303_PRODUCT_ID_RSAQ3 0xaaa2 |
16 | #define PL2303_PRODUCT_ID_ALDIGA 0x0611 | 16 | #define PL2303_PRODUCT_ID_ALDIGA 0x0611 |
17 | #define PL2303_PRODUCT_ID_MMX 0x0612 | ||
17 | 18 | ||
18 | #define ATEN_VENDOR_ID 0x0557 | 19 | #define ATEN_VENDOR_ID 0x0557 |
19 | #define ATEN_VENDOR_ID2 0x0547 | 20 | #define ATEN_VENDOR_ID2 0x0547 |
@@ -36,7 +37,6 @@ | |||
36 | 37 | ||
37 | #define RATOC_VENDOR_ID 0x0584 | 38 | #define RATOC_VENDOR_ID 0x0584 |
38 | #define RATOC_PRODUCT_ID 0xb000 | 39 | #define RATOC_PRODUCT_ID 0xb000 |
39 | #define RATOC_PRODUCT_ID_USB60F 0xb020 | ||
40 | 40 | ||
41 | #define TRIPP_VENDOR_ID 0x2478 | 41 | #define TRIPP_VENDOR_ID 0x2478 |
42 | #define TRIPP_PRODUCT_ID 0x2008 | 42 | #define TRIPP_PRODUCT_ID 0x2008 |
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 1b09578cbb10..45fe3663fa7f 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
@@ -405,7 +405,7 @@ UNUSUAL_DEV( 0x04a5, 0x3010, 0x0100, 0x0100, | |||
405 | UNUSUAL_DEV( 0x04b4, 0x6830, 0x0000, 0x9999, | 405 | UNUSUAL_DEV( 0x04b4, 0x6830, 0x0000, 0x9999, |
406 | "Cypress", | 406 | "Cypress", |
407 | "Cypress AT2LP", | 407 | "Cypress AT2LP", |
408 | US_SC_CYP_ATACB, US_PR_BULK, NULL, | 408 | US_SC_CYP_ATACB, US_PR_DEVICE, NULL, |
409 | 0), | 409 | 0), |
410 | #endif | 410 | #endif |
411 | 411 | ||
@@ -1522,7 +1522,7 @@ UNUSUAL_DEV( 0x0fce, 0xe031, 0x0000, 0x0000, | |||
1522 | "Sony Ericsson", | 1522 | "Sony Ericsson", |
1523 | "M600i", | 1523 | "M600i", |
1524 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 1524 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
1525 | US_FL_FIX_CAPACITY ), | 1525 | US_FL_IGNORE_RESIDUE | US_FL_FIX_CAPACITY ), |
1526 | 1526 | ||
1527 | /* Reported by Kevin Cernekee <kpc-usbdev@gelato.uiuc.edu> | 1527 | /* Reported by Kevin Cernekee <kpc-usbdev@gelato.uiuc.edu> |
1528 | * Tested on hardware version 1.10. | 1528 | * Tested on hardware version 1.10. |
@@ -1716,10 +1716,12 @@ UNUSUAL_DEV( 0x22b8, 0x3010, 0x0001, 0x0001, | |||
1716 | /* | 1716 | /* |
1717 | * Patch by Pete Zaitcev <zaitcev@redhat.com> | 1717 | * Patch by Pete Zaitcev <zaitcev@redhat.com> |
1718 | * Report by Mark Patton. Red Hat bz#208928. | 1718 | * Report by Mark Patton. Red Hat bz#208928. |
1719 | * Added support for rev 0x0002 (Motorola ROKR W5) | ||
1720 | * by Javier Smaldone <javier@smaldone.com.ar> | ||
1719 | */ | 1721 | */ |
1720 | UNUSUAL_DEV( 0x22b8, 0x4810, 0x0001, 0x0001, | 1722 | UNUSUAL_DEV( 0x22b8, 0x4810, 0x0001, 0x0002, |
1721 | "Motorola", | 1723 | "Motorola", |
1722 | "RAZR V3i", | 1724 | "RAZR V3i/ROKR W5", |
1723 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 1725 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
1724 | US_FL_FIX_CAPACITY), | 1726 | US_FL_FIX_CAPACITY), |
1725 | 1727 | ||
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c index e4bcf5376a99..bd4ac0bafecb 100644 --- a/drivers/video/aty/atyfb_base.c +++ b/drivers/video/aty/atyfb_base.c | |||
@@ -3356,7 +3356,7 @@ static int __devinit atyfb_setup_generic(struct pci_dev *pdev, struct fb_info *i | |||
3356 | 3356 | ||
3357 | info->fix.mmio_start = raddr; | 3357 | info->fix.mmio_start = raddr; |
3358 | par->ati_regbase = ioremap(info->fix.mmio_start, 0x1000); | 3358 | par->ati_regbase = ioremap(info->fix.mmio_start, 0x1000); |
3359 | if (par->ati_regbase == 0) | 3359 | if (par->ati_regbase == NULL) |
3360 | return -ENOMEM; | 3360 | return -ENOMEM; |
3361 | 3361 | ||
3362 | info->fix.mmio_start += par->aux_start ? 0x400 : 0xc00; | 3362 | info->fix.mmio_start += par->aux_start ? 0x400 : 0xc00; |
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c index 72cd0d2f14ec..400e9264e456 100644 --- a/drivers/video/aty/radeon_base.c +++ b/drivers/video/aty/radeon_base.c | |||
@@ -2277,8 +2277,8 @@ static int __devinit radeonfb_pci_register (struct pci_dev *pdev, | |||
2277 | do { | 2277 | do { |
2278 | rinfo->fb_base = ioremap (rinfo->fb_base_phys, | 2278 | rinfo->fb_base = ioremap (rinfo->fb_base_phys, |
2279 | rinfo->mapped_vram); | 2279 | rinfo->mapped_vram); |
2280 | } while ( rinfo->fb_base == 0 && | 2280 | } while (rinfo->fb_base == NULL && |
2281 | ((rinfo->mapped_vram /=2) >= MIN_MAPPED_VRAM) ); | 2281 | ((rinfo->mapped_vram /= 2) >= MIN_MAPPED_VRAM)); |
2282 | 2282 | ||
2283 | if (rinfo->fb_base == NULL) { | 2283 | if (rinfo->fb_base == NULL) { |
2284 | printk (KERN_ERR "radeonfb (%s): cannot map FB\n", | 2284 | printk (KERN_ERR "radeonfb (%s): cannot map FB\n", |
diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c index 35ac9d956b3d..c14b2435d23e 100644 --- a/drivers/video/cirrusfb.c +++ b/drivers/video/cirrusfb.c | |||
@@ -2432,9 +2432,9 @@ static int cirrusfb_pci_register(struct pci_dev *pdev, | |||
2432 | info->screen_size = board_size; | 2432 | info->screen_size = board_size; |
2433 | cinfo->unmap = cirrusfb_pci_unmap; | 2433 | cinfo->unmap = cirrusfb_pci_unmap; |
2434 | 2434 | ||
2435 | printk(KERN_INFO " RAM (%lu kB) at 0xx%lx, ", | 2435 | printk(KERN_INFO "RAM (%lu kB) at 0x%lx, Cirrus " |
2436 | info->screen_size >> 10, board_addr); | 2436 | "Logic chipset on PCI bus\n", |
2437 | printk(KERN_INFO "Cirrus Logic chipset on PCI bus\n"); | 2437 | info->screen_size >> 10, board_addr); |
2438 | pci_set_drvdata(pdev, info); | 2438 | pci_set_drvdata(pdev, info); |
2439 | 2439 | ||
2440 | ret = cirrusfb_register(info); | 2440 | ret = cirrusfb_register(info); |
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 5fa8b76673cb..97aff8db10bf 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c | |||
@@ -2275,9 +2275,7 @@ static int fbcon_switch(struct vc_data *vc) | |||
2275 | * in fb_set_var() | 2275 | * in fb_set_var() |
2276 | */ | 2276 | */ |
2277 | info->var.activate = var.activate; | 2277 | info->var.activate = var.activate; |
2278 | var.yoffset = info->var.yoffset; | 2278 | var.vmode |= info->var.vmode & ~FB_VMODE_MASK; |
2279 | var.xoffset = info->var.xoffset; | ||
2280 | var.vmode = info->var.vmode; | ||
2281 | fb_set_var(info, &var); | 2279 | fb_set_var(info, &var); |
2282 | ops->var = info->var; | 2280 | ops->var = info->var; |
2283 | 2281 | ||
diff --git a/drivers/video/display/display-sysfs.c b/drivers/video/display/display-sysfs.c index 35477177bef4..6ef800bdf482 100644 --- a/drivers/video/display/display-sysfs.c +++ b/drivers/video/display/display-sysfs.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/ctype.h> | 26 | #include <linux/ctype.h> |
27 | #include <linux/idr.h> | 27 | #include <linux/idr.h> |
28 | #include <linux/err.h> | 28 | #include <linux/err.h> |
29 | #include <linux/kdev_t.h> | ||
29 | 30 | ||
30 | static ssize_t display_show_name(struct device *dev, | 31 | static ssize_t display_show_name(struct device *dev, |
31 | struct device_attribute *attr, char *buf) | 32 | struct device_attribute *attr, char *buf) |
@@ -152,10 +153,13 @@ struct display_device *display_device_register(struct display_driver *driver, | |||
152 | mutex_unlock(&allocated_dsp_lock); | 153 | mutex_unlock(&allocated_dsp_lock); |
153 | 154 | ||
154 | if (!ret) { | 155 | if (!ret) { |
155 | new_dev->dev = device_create(display_class, parent, 0, | 156 | new_dev->dev = device_create_drvdata(display_class, |
156 | "display%d", new_dev->idx); | 157 | parent, |
158 | MKDEV(0,0), | ||
159 | new_dev, | ||
160 | "display%d", | ||
161 | new_dev->idx); | ||
157 | if (!IS_ERR(new_dev->dev)) { | 162 | if (!IS_ERR(new_dev->dev)) { |
158 | dev_set_drvdata(new_dev->dev, new_dev); | ||
159 | new_dev->parent = parent; | 163 | new_dev->parent = parent; |
160 | new_dev->driver = driver; | 164 | new_dev->driver = driver; |
161 | mutex_init(&new_dev->lock); | 165 | mutex_init(&new_dev->lock); |
diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c index b50bb03cb5ab..0a2785361ca3 100644 --- a/drivers/video/fsl-diu-fb.c +++ b/drivers/video/fsl-diu-fb.c | |||
@@ -1320,7 +1320,7 @@ static void free_irq_local(int irq) | |||
1320 | * Power management hooks. Note that we won't be called from IRQ context, | 1320 | * Power management hooks. Note that we won't be called from IRQ context, |
1321 | * unlike the blank functions above, so we may sleep. | 1321 | * unlike the blank functions above, so we may sleep. |
1322 | */ | 1322 | */ |
1323 | static int fsl_diu_suspend(struct of_device *dev, pm_message_t state) | 1323 | static int fsl_diu_suspend(struct of_device *ofdev, pm_message_t state) |
1324 | { | 1324 | { |
1325 | struct fsl_diu_data *machine_data; | 1325 | struct fsl_diu_data *machine_data; |
1326 | 1326 | ||
@@ -1330,7 +1330,7 @@ static int fsl_diu_suspend(struct of_device *dev, pm_message_t state) | |||
1330 | return 0; | 1330 | return 0; |
1331 | } | 1331 | } |
1332 | 1332 | ||
1333 | static int fsl_diu_resume(struct of_device *dev) | 1333 | static int fsl_diu_resume(struct of_device *ofdev) |
1334 | { | 1334 | { |
1335 | struct fsl_diu_data *machine_data; | 1335 | struct fsl_diu_data *machine_data; |
1336 | 1336 | ||
diff --git a/drivers/video/hgafb.c b/drivers/video/hgafb.c index fb9e67228543..c18880d9db1f 100644 --- a/drivers/video/hgafb.c +++ b/drivers/video/hgafb.c | |||
@@ -279,7 +279,7 @@ static void hga_blank(int blank_mode) | |||
279 | 279 | ||
280 | static int __init hga_card_detect(void) | 280 | static int __init hga_card_detect(void) |
281 | { | 281 | { |
282 | int count=0; | 282 | int count = 0; |
283 | void __iomem *p, *q; | 283 | void __iomem *p, *q; |
284 | unsigned short p_save, q_save; | 284 | unsigned short p_save, q_save; |
285 | 285 | ||
@@ -303,20 +303,18 @@ static int __init hga_card_detect(void) | |||
303 | writew(0x55aa, p); if (readw(p) == 0x55aa) count++; | 303 | writew(0x55aa, p); if (readw(p) == 0x55aa) count++; |
304 | writew(p_save, p); | 304 | writew(p_save, p); |
305 | 305 | ||
306 | if (count != 2) { | 306 | if (count != 2) |
307 | return 0; | 307 | goto error; |
308 | } | ||
309 | 308 | ||
310 | /* Ok, there is definitely a card registering at the correct | 309 | /* Ok, there is definitely a card registering at the correct |
311 | * memory location, so now we do an I/O port test. | 310 | * memory location, so now we do an I/O port test. |
312 | */ | 311 | */ |
313 | 312 | ||
314 | if (!test_hga_b(0x66, 0x0f)) { /* cursor low register */ | 313 | if (!test_hga_b(0x66, 0x0f)) /* cursor low register */ |
315 | return 0; | 314 | goto error; |
316 | } | 315 | |
317 | if (!test_hga_b(0x99, 0x0f)) { /* cursor low register */ | 316 | if (!test_hga_b(0x99, 0x0f)) /* cursor low register */ |
318 | return 0; | 317 | goto error; |
319 | } | ||
320 | 318 | ||
321 | /* See if the card is a Hercules, by checking whether the vsync | 319 | /* See if the card is a Hercules, by checking whether the vsync |
322 | * bit of the status register is changing. This test lasts for | 320 | * bit of the status register is changing. This test lasts for |
@@ -331,7 +329,7 @@ static int __init hga_card_detect(void) | |||
331 | } | 329 | } |
332 | 330 | ||
333 | if (p_save == q_save) | 331 | if (p_save == q_save) |
334 | return 0; | 332 | goto error; |
335 | 333 | ||
336 | switch (inb_p(HGA_STATUS_PORT) & 0x70) { | 334 | switch (inb_p(HGA_STATUS_PORT) & 0x70) { |
337 | case 0x10: | 335 | case 0x10: |
@@ -348,6 +346,12 @@ static int __init hga_card_detect(void) | |||
348 | break; | 346 | break; |
349 | } | 347 | } |
350 | return 1; | 348 | return 1; |
349 | error: | ||
350 | if (release_io_ports) | ||
351 | release_region(0x3b0, 12); | ||
352 | if (release_io_port) | ||
353 | release_region(0x3bf, 1); | ||
354 | return 0; | ||
351 | } | 355 | } |
352 | 356 | ||
353 | /** | 357 | /** |
diff --git a/drivers/video/leo.c b/drivers/video/leo.c index 8bc46e930340..13fea61d6ae4 100644 --- a/drivers/video/leo.c +++ b/drivers/video/leo.c | |||
@@ -17,8 +17,8 @@ | |||
17 | #include <linux/fb.h> | 17 | #include <linux/fb.h> |
18 | #include <linux/mm.h> | 18 | #include <linux/mm.h> |
19 | #include <linux/of_device.h> | 19 | #include <linux/of_device.h> |
20 | #include <linux/io.h> | ||
20 | 21 | ||
21 | #include <asm/io.h> | ||
22 | #include <asm/fbio.h> | 22 | #include <asm/fbio.h> |
23 | 23 | ||
24 | #include "sbuslib.h" | 24 | #include "sbuslib.h" |
@@ -33,7 +33,6 @@ static int leo_blank(int, struct fb_info *); | |||
33 | 33 | ||
34 | static int leo_mmap(struct fb_info *, struct vm_area_struct *); | 34 | static int leo_mmap(struct fb_info *, struct vm_area_struct *); |
35 | static int leo_ioctl(struct fb_info *, unsigned int, unsigned long); | 35 | static int leo_ioctl(struct fb_info *, unsigned int, unsigned long); |
36 | static int leo_pan_display(struct fb_var_screeninfo *, struct fb_info *); | ||
37 | 36 | ||
38 | /* | 37 | /* |
39 | * Frame buffer operations | 38 | * Frame buffer operations |
@@ -43,7 +42,6 @@ static struct fb_ops leo_ops = { | |||
43 | .owner = THIS_MODULE, | 42 | .owner = THIS_MODULE, |
44 | .fb_setcolreg = leo_setcolreg, | 43 | .fb_setcolreg = leo_setcolreg, |
45 | .fb_blank = leo_blank, | 44 | .fb_blank = leo_blank, |
46 | .fb_pan_display = leo_pan_display, | ||
47 | .fb_fillrect = cfb_fillrect, | 45 | .fb_fillrect = cfb_fillrect, |
48 | .fb_copyarea = cfb_copyarea, | 46 | .fb_copyarea = cfb_copyarea, |
49 | .fb_imageblit = cfb_imageblit, | 47 | .fb_imageblit = cfb_imageblit, |
@@ -78,7 +76,7 @@ static struct fb_ops leo_ops = { | |||
78 | #define LEO_CUR_TYPE_CMAP 0x00000050 | 76 | #define LEO_CUR_TYPE_CMAP 0x00000050 |
79 | 77 | ||
80 | struct leo_cursor { | 78 | struct leo_cursor { |
81 | u8 xxx0[16]; | 79 | u8 xxx0[16]; |
82 | u32 cur_type; | 80 | u32 cur_type; |
83 | u32 cur_misc; | 81 | u32 cur_misc; |
84 | u32 cur_cursxy; | 82 | u32 cur_cursxy; |
@@ -105,7 +103,7 @@ struct leo_lx_krn { | |||
105 | 103 | ||
106 | struct leo_lc_ss0_krn { | 104 | struct leo_lc_ss0_krn { |
107 | u32 misc; | 105 | u32 misc; |
108 | u8 xxx0[0x800-4]; | 106 | u8 xxx0[0x800-4]; |
109 | u32 rev; | 107 | u32 rev; |
110 | }; | 108 | }; |
111 | 109 | ||
@@ -116,7 +114,7 @@ struct leo_lc_ss0_usr { | |||
116 | u32 fontt; | 114 | u32 fontt; |
117 | u32 extent; | 115 | u32 extent; |
118 | u32 src; | 116 | u32 src; |
119 | u32 dst; | 117 | u32 dst; |
120 | u32 copy; | 118 | u32 copy; |
121 | u32 fill; | 119 | u32 fill; |
122 | }; | 120 | }; |
@@ -129,8 +127,8 @@ struct leo_lc_ss1_usr { | |||
129 | u8 unknown; | 127 | u8 unknown; |
130 | }; | 128 | }; |
131 | 129 | ||
132 | struct leo_ld { | 130 | struct leo_ld_ss0 { |
133 | u8 xxx0[0xe00]; | 131 | u8 xxx0[0xe00]; |
134 | u32 csr; | 132 | u32 csr; |
135 | u32 wid; | 133 | u32 wid; |
136 | u32 wmask; | 134 | u32 wmask; |
@@ -144,13 +142,13 @@ struct leo_ld { | |||
144 | u32 src; /* Copy/Scroll (SS0 only) */ | 142 | u32 src; /* Copy/Scroll (SS0 only) */ |
145 | u32 dst; /* Copy/Scroll/Fill (SS0 only) */ | 143 | u32 dst; /* Copy/Scroll/Fill (SS0 only) */ |
146 | u32 extent; /* Copy/Scroll/Fill size (SS0 only) */ | 144 | u32 extent; /* Copy/Scroll/Fill size (SS0 only) */ |
147 | u32 xxx1[3]; | 145 | u32 xxx1[3]; |
148 | u32 setsem; /* SS1 only */ | 146 | u32 setsem; /* SS1 only */ |
149 | u32 clrsem; /* SS1 only */ | 147 | u32 clrsem; /* SS1 only */ |
150 | u32 clrpick; /* SS1 only */ | 148 | u32 clrpick; /* SS1 only */ |
151 | u32 clrdat; /* SS1 only */ | 149 | u32 clrdat; /* SS1 only */ |
152 | u32 alpha; /* SS1 only */ | 150 | u32 alpha; /* SS1 only */ |
153 | u8 xxx2[0x2c]; | 151 | u8 xxx2[0x2c]; |
154 | u32 winbg; | 152 | u32 winbg; |
155 | u32 planemask; | 153 | u32 planemask; |
156 | u32 rop; | 154 | u32 rop; |
@@ -199,11 +197,12 @@ struct leo_par { | |||
199 | static void leo_wait(struct leo_lx_krn __iomem *lx_krn) | 197 | static void leo_wait(struct leo_lx_krn __iomem *lx_krn) |
200 | { | 198 | { |
201 | int i; | 199 | int i; |
202 | 200 | ||
203 | for (i = 0; | 201 | for (i = 0; |
204 | (sbus_readl(&lx_krn->krn_csr) & LEO_KRN_CSR_PROGRESS) && i < 300000; | 202 | (sbus_readl(&lx_krn->krn_csr) & LEO_KRN_CSR_PROGRESS) && |
203 | i < 300000; | ||
205 | i++) | 204 | i++) |
206 | udelay (1); /* Busy wait at most 0.3 sec */ | 205 | udelay(1); /* Busy wait at most 0.3 sec */ |
207 | return; | 206 | return; |
208 | } | 207 | } |
209 | 208 | ||
@@ -221,7 +220,7 @@ static int leo_setcolreg(unsigned regno, | |||
221 | unsigned transp, struct fb_info *info) | 220 | unsigned transp, struct fb_info *info) |
222 | { | 221 | { |
223 | struct leo_par *par = (struct leo_par *) info->par; | 222 | struct leo_par *par = (struct leo_par *) info->par; |
224 | struct leo_lx_krn __iomem *lx_krn = par->lx_krn; | 223 | struct leo_lx_krn __iomem *lx_krn = par->lx_krn; |
225 | unsigned long flags; | 224 | unsigned long flags; |
226 | u32 val; | 225 | u32 val; |
227 | int i; | 226 | int i; |
@@ -408,7 +407,7 @@ static void leo_wid_put(struct fb_info *info, struct fb_wid_list *wl) | |||
408 | leo_wait(lx_krn); | 407 | leo_wait(lx_krn); |
409 | 408 | ||
410 | for (i = 0, wi = wl->wl_list; i < wl->wl_count; i++, wi++) { | 409 | for (i = 0, wi = wl->wl_list; i < wl->wl_count; i++, wi++) { |
411 | switch(wi->wi_type) { | 410 | switch (wi->wi_type) { |
412 | case FB_WID_DBL_8: | 411 | case FB_WID_DBL_8: |
413 | j = (wi->wi_index & 0xf) + 0x40; | 412 | j = (wi->wi_index & 0xf) + 0x40; |
414 | break; | 413 | break; |
@@ -453,13 +452,12 @@ static void leo_init_wids(struct fb_info *info) | |||
453 | wi.wi_index = 1; | 452 | wi.wi_index = 1; |
454 | wi.wi_values [0] = 0x30; | 453 | wi.wi_values [0] = 0x30; |
455 | leo_wid_put(info, &wl); | 454 | leo_wid_put(info, &wl); |
456 | |||
457 | } | 455 | } |
458 | 456 | ||
459 | static void leo_switch_from_graph(struct fb_info *info) | 457 | static void leo_switch_from_graph(struct fb_info *info) |
460 | { | 458 | { |
461 | struct leo_par *par = (struct leo_par *) info->par; | 459 | struct leo_par *par = (struct leo_par *) info->par; |
462 | struct leo_ld __iomem *ss = (struct leo_ld __iomem *) par->ld_ss0; | 460 | struct leo_ld_ss0 __iomem *ss = par->ld_ss0; |
463 | unsigned long flags; | 461 | unsigned long flags; |
464 | u32 val; | 462 | u32 val; |
465 | 463 | ||
@@ -485,19 +483,13 @@ static void leo_switch_from_graph(struct fb_info *info) | |||
485 | val = sbus_readl(&par->lc_ss0_usr->csr); | 483 | val = sbus_readl(&par->lc_ss0_usr->csr); |
486 | } while (val & 0x20000000); | 484 | } while (val & 0x20000000); |
487 | 485 | ||
488 | spin_unlock_irqrestore(&par->lock, flags); | 486 | /* setup screen buffer for cfb_* functions */ |
489 | } | 487 | sbus_writel(1, &ss->wid); |
490 | 488 | sbus_writel(0x00ffffff, &ss->planemask); | |
491 | static int leo_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) | 489 | sbus_writel(0x310b90, &ss->rop); |
492 | { | 490 | sbus_writel(0, &par->lc_ss0_usr->addrspace); |
493 | /* We just use this to catch switches out of | ||
494 | * graphics mode. | ||
495 | */ | ||
496 | leo_switch_from_graph(info); | ||
497 | 491 | ||
498 | if (var->xoffset || var->yoffset || var->vmode) | 492 | spin_unlock_irqrestore(&par->lock, flags); |
499 | return -EINVAL; | ||
500 | return 0; | ||
501 | } | 493 | } |
502 | 494 | ||
503 | static void leo_init_hw(struct fb_info *info) | 495 | static void leo_init_hw(struct fb_info *info) |
@@ -542,7 +534,8 @@ static void leo_unmap_regs(struct of_device *op, struct fb_info *info, | |||
542 | of_iounmap(&op->resource[0], info->screen_base, 0x800000); | 534 | of_iounmap(&op->resource[0], info->screen_base, 0x800000); |
543 | } | 535 | } |
544 | 536 | ||
545 | static int __devinit leo_probe(struct of_device *op, const struct of_device_id *match) | 537 | static int __devinit leo_probe(struct of_device *op, |
538 | const struct of_device_id *match) | ||
546 | { | 539 | { |
547 | struct device_node *dp = op->node; | 540 | struct device_node *dp = op->node; |
548 | struct fb_info *info; | 541 | struct fb_info *info; |
@@ -594,8 +587,9 @@ static int __devinit leo_probe(struct of_device *op, const struct of_device_id * | |||
594 | !info->screen_base) | 587 | !info->screen_base) |
595 | goto out_unmap_regs; | 588 | goto out_unmap_regs; |
596 | 589 | ||
597 | info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; | 590 | info->flags = FBINFO_DEFAULT; |
598 | info->fbops = &leo_ops; | 591 | info->fbops = &leo_ops; |
592 | info->pseudo_palette = par->clut_data; | ||
599 | 593 | ||
600 | leo_init_wids(info); | 594 | leo_init_wids(info); |
601 | leo_init_hw(info); | 595 | leo_init_hw(info); |
@@ -649,7 +643,7 @@ static int __devexit leo_remove(struct of_device *op) | |||
649 | 643 | ||
650 | static struct of_device_id leo_match[] = { | 644 | static struct of_device_id leo_match[] = { |
651 | { | 645 | { |
652 | .name = "leo", | 646 | .name = "SUNW,leo", |
653 | }, | 647 | }, |
654 | {}, | 648 | {}, |
655 | }; | 649 | }; |
diff --git a/drivers/video/matrox/matroxfb_base.h b/drivers/video/matrox/matroxfb_base.h index f3107ad7e545..95883236c0cd 100644 --- a/drivers/video/matrox/matroxfb_base.h +++ b/drivers/video/matrox/matroxfb_base.h | |||
@@ -200,7 +200,7 @@ static inline int mga_ioremap(unsigned long phys, unsigned long size, int flags, | |||
200 | virt->vaddr = ioremap_nocache(phys, size); | 200 | virt->vaddr = ioremap_nocache(phys, size); |
201 | else | 201 | else |
202 | virt->vaddr = ioremap(phys, size); | 202 | virt->vaddr = ioremap(phys, size); |
203 | return (virt->vaddr == 0); /* 0, !0... 0, error_code in future */ | 203 | return (virt->vaddr == NULL); /* 0, !0... 0, error_code in future */ |
204 | } | 204 | } |
205 | 205 | ||
206 | static inline void mga_iounmap(vaddr_t va) { | 206 | static inline void mga_iounmap(vaddr_t va) { |
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c index 473562191586..d3c3af53a290 100644 --- a/drivers/video/modedb.c +++ b/drivers/video/modedb.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #endif | 28 | #endif |
29 | 29 | ||
30 | const char *fb_mode_option; | 30 | const char *fb_mode_option; |
31 | EXPORT_SYMBOL_GPL(fb_mode_option); | ||
31 | 32 | ||
32 | /* | 33 | /* |
33 | * Standard video mode definitions (taken from XFree86) | 34 | * Standard video mode definitions (taken from XFree86) |
@@ -590,6 +591,7 @@ done: | |||
590 | "", (margins) ? " with margins" : "", (interlace) ? | 591 | "", (margins) ? " with margins" : "", (interlace) ? |
591 | " interlaced" : ""); | 592 | " interlaced" : ""); |
592 | 593 | ||
594 | memset(&cvt_mode, 0, sizeof(cvt_mode)); | ||
593 | cvt_mode.xres = xres; | 595 | cvt_mode.xres = xres; |
594 | cvt_mode.yres = yres; | 596 | cvt_mode.yres = yres; |
595 | cvt_mode.refresh = (refresh) ? refresh : 60; | 597 | cvt_mode.refresh = (refresh) ? refresh : 60; |
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index 3ee314beacc1..7dcda187d9ba 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c | |||
@@ -573,8 +573,8 @@ static int setup_frame_dma(struct pxafb_info *fbi, int dma, int pal, | |||
573 | dma_desc->fdadr = fbi->dma_buff_phys + dma_desc_off; | 573 | dma_desc->fdadr = fbi->dma_buff_phys + dma_desc_off; |
574 | fbi->fdadr[dma] = fbi->dma_buff_phys + dma_desc_off; | 574 | fbi->fdadr[dma] = fbi->dma_buff_phys + dma_desc_off; |
575 | } else { | 575 | } else { |
576 | pal_desc = &fbi->dma_buff->pal_desc[dma]; | 576 | pal_desc = &fbi->dma_buff->pal_desc[pal]; |
577 | pal_desc_off = offsetof(struct pxafb_dma_buff, dma_desc[pal]); | 577 | pal_desc_off = offsetof(struct pxafb_dma_buff, pal_desc[pal]); |
578 | 578 | ||
579 | pal_desc->fsadr = fbi->dma_buff_phys + pal * PALETTE_SIZE; | 579 | pal_desc->fsadr = fbi->dma_buff_phys + pal * PALETTE_SIZE; |
580 | pal_desc->fidr = 0; | 580 | pal_desc->fidr = 0; |
@@ -1276,6 +1276,8 @@ static int __init pxafb_map_video_memory(struct pxafb_info *fbi) | |||
1276 | fbi->dma_buff_phys = fbi->map_dma; | 1276 | fbi->dma_buff_phys = fbi->map_dma; |
1277 | fbi->palette_cpu = (u16 *) fbi->dma_buff->palette; | 1277 | fbi->palette_cpu = (u16 *) fbi->dma_buff->palette; |
1278 | 1278 | ||
1279 | pr_debug("pxafb: palette_mem_size = 0x%08lx\n", fbi->palette_size*sizeof(u16)); | ||
1280 | |||
1279 | #ifdef CONFIG_FB_PXA_SMARTPANEL | 1281 | #ifdef CONFIG_FB_PXA_SMARTPANEL |
1280 | fbi->smart_cmds = (uint16_t *) fbi->dma_buff->cmd_buff; | 1282 | fbi->smart_cmds = (uint16_t *) fbi->dma_buff->cmd_buff; |
1281 | fbi->n_smart_cmds = 0; | 1283 | fbi->n_smart_cmds = 0; |
@@ -1351,7 +1353,6 @@ static struct pxafb_info * __init pxafb_init_fbinfo(struct device *dev) | |||
1351 | struct pxafb_info *fbi; | 1353 | struct pxafb_info *fbi; |
1352 | void *addr; | 1354 | void *addr; |
1353 | struct pxafb_mach_info *inf = dev->platform_data; | 1355 | struct pxafb_mach_info *inf = dev->platform_data; |
1354 | struct pxafb_mode_info *mode = inf->modes; | ||
1355 | 1356 | ||
1356 | /* Alloc the pxafb_info and pseudo_palette in one step */ | 1357 | /* Alloc the pxafb_info and pseudo_palette in one step */ |
1357 | fbi = kmalloc(sizeof(struct pxafb_info) + sizeof(u32) * 16, GFP_KERNEL); | 1358 | fbi = kmalloc(sizeof(struct pxafb_info) + sizeof(u32) * 16, GFP_KERNEL); |
diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c index 13b38cbbe4cf..f0598961c6b0 100644 --- a/drivers/video/s3c2410fb.c +++ b/drivers/video/s3c2410fb.c | |||
@@ -1,75 +1,15 @@ | |||
1 | /* | 1 | /* linux/drivers/video/s3c2410fb.c |
2 | * linux/drivers/video/s3c2410fb.c | 2 | * Copyright (c) 2004,2005 Arnaud Patard |
3 | * Copyright (c) Arnaud Patard, Ben Dooks | 3 | * Copyright (c) 2004-2008 Ben Dooks |
4 | * | ||
5 | * S3C2410 LCD Framebuffer Driver | ||
4 | * | 6 | * |
5 | * This file is subject to the terms and conditions of the GNU General Public | 7 | * This file is subject to the terms and conditions of the GNU General Public |
6 | * License. See the file COPYING in the main directory of this archive for | 8 | * License. See the file COPYING in the main directory of this archive for |
7 | * more details. | 9 | * more details. |
8 | * | 10 | * |
9 | * S3C2410 LCD Controller Frame Buffer Driver | 11 | * Driver based on skeletonfb.c, sa1100fb.c and others. |
10 | * based on skeletonfb.c, sa1100fb.c and others | 12 | */ |
11 | * | ||
12 | * ChangeLog | ||
13 | * 2005-04-07: Arnaud Patard <arnaud.patard@rtp-net.org> | ||
14 | * - u32 state -> pm_message_t state | ||
15 | * - S3C2410_{VA,SZ}_LCD -> S3C24XX | ||
16 | * | ||
17 | * 2005-03-15: Arnaud Patard <arnaud.patard@rtp-net.org> | ||
18 | * - Removed the ioctl | ||
19 | * - use readl/writel instead of __raw_writel/__raw_readl | ||
20 | * | ||
21 | * 2004-12-04: Arnaud Patard <arnaud.patard@rtp-net.org> | ||
22 | * - Added the possibility to set on or off the | ||
23 | * debugging messages | ||
24 | * - Replaced 0 and 1 by on or off when reading the | ||
25 | * /sys files | ||
26 | * | ||
27 | * 2005-03-23: Ben Dooks <ben-linux@fluff.org> | ||
28 | * - added non 16bpp modes | ||
29 | * - updated platform information for range of x/y/bpp | ||
30 | * - add code to ensure palette is written correctly | ||
31 | * - add pixel clock divisor control | ||
32 | * | ||
33 | * 2004-11-11: Arnaud Patard <arnaud.patard@rtp-net.org> | ||
34 | * - Removed the use of currcon as it no more exists | ||
35 | * - Added LCD power sysfs interface | ||
36 | * | ||
37 | * 2004-11-03: Ben Dooks <ben-linux@fluff.org> | ||
38 | * - minor cleanups | ||
39 | * - add suspend/resume support | ||
40 | * - s3c2410fb_setcolreg() not valid in >8bpp modes | ||
41 | * - removed last CONFIG_FB_S3C2410_FIXED | ||
42 | * - ensure lcd controller stopped before cleanup | ||
43 | * - added sysfs interface for backlight power | ||
44 | * - added mask for gpio configuration | ||
45 | * - ensured IRQs disabled during GPIO configuration | ||
46 | * - disable TPAL before enabling video | ||
47 | * | ||
48 | * 2004-09-20: Arnaud Patard <arnaud.patard@rtp-net.org> | ||
49 | * - Suppress command line options | ||
50 | * | ||
51 | * 2004-09-15: Arnaud Patard <arnaud.patard@rtp-net.org> | ||
52 | * - code cleanup | ||
53 | * | ||
54 | * 2004-09-07: Arnaud Patard <arnaud.patard@rtp-net.org> | ||
55 | * - Renamed from h1940fb.c to s3c2410fb.c | ||
56 | * - Add support for different devices | ||
57 | * - Backlight support | ||
58 | * | ||
59 | * 2004-09-05: Herbert Pötzl <herbert@13thfloor.at> | ||
60 | * - added clock (de-)allocation code | ||
61 | * - added fixem fbmem option | ||
62 | * | ||
63 | * 2004-07-27: Arnaud Patard <arnaud.patard@rtp-net.org> | ||
64 | * - code cleanup | ||
65 | * - added a forgotten return in h1940fb_init | ||
66 | * | ||
67 | * 2004-07-19: Herbert Pötzl <herbert@13thfloor.at> | ||
68 | * - code cleanup and extended debugging | ||
69 | * | ||
70 | * 2004-07-15: Arnaud Patard <arnaud.patard@rtp-net.org> | ||
71 | * - First version | ||
72 | */ | ||
73 | 13 | ||
74 | #include <linux/module.h> | 14 | #include <linux/module.h> |
75 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
@@ -580,6 +520,27 @@ static int s3c2410fb_setcolreg(unsigned regno, | |||
580 | return 0; | 520 | return 0; |
581 | } | 521 | } |
582 | 522 | ||
523 | /* s3c2410fb_lcd_enable | ||
524 | * | ||
525 | * shutdown the lcd controller | ||
526 | */ | ||
527 | static void s3c2410fb_lcd_enable(struct s3c2410fb_info *fbi, int enable) | ||
528 | { | ||
529 | unsigned long flags; | ||
530 | |||
531 | local_irq_save(flags); | ||
532 | |||
533 | if (enable) | ||
534 | fbi->regs.lcdcon1 |= S3C2410_LCDCON1_ENVID; | ||
535 | else | ||
536 | fbi->regs.lcdcon1 &= ~S3C2410_LCDCON1_ENVID; | ||
537 | |||
538 | writel(fbi->regs.lcdcon1, fbi->io + S3C2410_LCDCON1); | ||
539 | |||
540 | local_irq_restore(flags); | ||
541 | } | ||
542 | |||
543 | |||
583 | /* | 544 | /* |
584 | * s3c2410fb_blank | 545 | * s3c2410fb_blank |
585 | * @blank_mode: the blank mode we want. | 546 | * @blank_mode: the blank mode we want. |
@@ -589,9 +550,6 @@ static int s3c2410fb_setcolreg(unsigned regno, | |||
589 | * blanking succeeded, != 0 if un-/blanking failed due to e.g. a | 550 | * blanking succeeded, != 0 if un-/blanking failed due to e.g. a |
590 | * video mode which doesn't support it. Implements VESA suspend | 551 | * video mode which doesn't support it. Implements VESA suspend |
591 | * and powerdown modes on hardware that supports disabling hsync/vsync: | 552 | * and powerdown modes on hardware that supports disabling hsync/vsync: |
592 | * blank_mode == 2: suspend vsync | ||
593 | * blank_mode == 3: suspend hsync | ||
594 | * blank_mode == 4: powerdown | ||
595 | * | 553 | * |
596 | * Returns negative errno on error, or zero on success. | 554 | * Returns negative errno on error, or zero on success. |
597 | * | 555 | * |
@@ -605,6 +563,12 @@ static int s3c2410fb_blank(int blank_mode, struct fb_info *info) | |||
605 | 563 | ||
606 | tpal_reg += is_s3c2412(fbi) ? S3C2412_TPAL : S3C2410_TPAL; | 564 | tpal_reg += is_s3c2412(fbi) ? S3C2412_TPAL : S3C2410_TPAL; |
607 | 565 | ||
566 | if (blank_mode == FB_BLANK_POWERDOWN) { | ||
567 | s3c2410fb_lcd_enable(fbi, 0); | ||
568 | } else { | ||
569 | s3c2410fb_lcd_enable(fbi, 1); | ||
570 | } | ||
571 | |||
608 | if (blank_mode == FB_BLANK_UNBLANK) | 572 | if (blank_mode == FB_BLANK_UNBLANK) |
609 | writel(0x0, tpal_reg); | 573 | writel(0x0, tpal_reg); |
610 | else { | 574 | else { |
@@ -948,7 +912,10 @@ static int __init s3c24xxfb_probe(struct platform_device *pdev, | |||
948 | } | 912 | } |
949 | 913 | ||
950 | /* create device files */ | 914 | /* create device files */ |
951 | device_create_file(&pdev->dev, &dev_attr_debug); | 915 | ret = device_create_file(&pdev->dev, &dev_attr_debug); |
916 | if (ret) { | ||
917 | printk(KERN_ERR "failed to add debug attribute\n"); | ||
918 | } | ||
952 | 919 | ||
953 | printk(KERN_INFO "fb%d: %s frame buffer device\n", | 920 | printk(KERN_INFO "fb%d: %s frame buffer device\n", |
954 | fbinfo->node, fbinfo->fix.id); | 921 | fbinfo->node, fbinfo->fix.id); |
@@ -983,21 +950,6 @@ static int __init s3c2412fb_probe(struct platform_device *pdev) | |||
983 | return s3c24xxfb_probe(pdev, DRV_S3C2412); | 950 | return s3c24xxfb_probe(pdev, DRV_S3C2412); |
984 | } | 951 | } |
985 | 952 | ||
986 | /* s3c2410fb_stop_lcd | ||
987 | * | ||
988 | * shutdown the lcd controller | ||
989 | */ | ||
990 | static void s3c2410fb_stop_lcd(struct s3c2410fb_info *fbi) | ||
991 | { | ||
992 | unsigned long flags; | ||
993 | |||
994 | local_irq_save(flags); | ||
995 | |||
996 | fbi->regs.lcdcon1 &= ~S3C2410_LCDCON1_ENVID; | ||
997 | writel(fbi->regs.lcdcon1, fbi->io + S3C2410_LCDCON1); | ||
998 | |||
999 | local_irq_restore(flags); | ||
1000 | } | ||
1001 | 953 | ||
1002 | /* | 954 | /* |
1003 | * Cleanup | 955 | * Cleanup |
@@ -1010,7 +962,7 @@ static int s3c2410fb_remove(struct platform_device *pdev) | |||
1010 | 962 | ||
1011 | unregister_framebuffer(fbinfo); | 963 | unregister_framebuffer(fbinfo); |
1012 | 964 | ||
1013 | s3c2410fb_stop_lcd(info); | 965 | s3c2410fb_lcd_enable(info, 0); |
1014 | msleep(1); | 966 | msleep(1); |
1015 | 967 | ||
1016 | s3c2410fb_unmap_video_memory(fbinfo); | 968 | s3c2410fb_unmap_video_memory(fbinfo); |
@@ -1043,7 +995,7 @@ static int s3c2410fb_suspend(struct platform_device *dev, pm_message_t state) | |||
1043 | struct fb_info *fbinfo = platform_get_drvdata(dev); | 995 | struct fb_info *fbinfo = platform_get_drvdata(dev); |
1044 | struct s3c2410fb_info *info = fbinfo->par; | 996 | struct s3c2410fb_info *info = fbinfo->par; |
1045 | 997 | ||
1046 | s3c2410fb_stop_lcd(info); | 998 | s3c2410fb_lcd_enable(info, 0); |
1047 | 999 | ||
1048 | /* sleep before disabling the clock, we need to ensure | 1000 | /* sleep before disabling the clock, we need to ensure |
1049 | * the LCD DMA engine is not going to get back on the bus | 1001 | * the LCD DMA engine is not going to get back on the bus |
@@ -1118,3 +1070,5 @@ MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>, " | |||
1118 | "Ben Dooks <ben-linux@fluff.org>"); | 1070 | "Ben Dooks <ben-linux@fluff.org>"); |
1119 | MODULE_DESCRIPTION("Framebuffer driver for the s3c2410"); | 1071 | MODULE_DESCRIPTION("Framebuffer driver for the s3c2410"); |
1120 | MODULE_LICENSE("GPL"); | 1072 | MODULE_LICENSE("GPL"); |
1073 | MODULE_ALIAS("platform:s3c2410-lcd"); | ||
1074 | MODULE_ALIAS("platform:s3c2412-lcd"); | ||
diff --git a/drivers/video/s3c2410fb.h b/drivers/video/s3c2410fb.h index dbb73b95e2ef..9a6ba3e9d1b8 100644 --- a/drivers/video/s3c2410fb.h +++ b/drivers/video/s3c2410fb.h | |||
@@ -1,26 +1,14 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/video/s3c2410fb.h | 2 | * linux/drivers/video/s3c2410fb.h |
3 | * Copyright (c) Arnaud Patard | 3 | * Copyright (c) 2004 Arnaud Patard |
4 | * | ||
5 | * S3C2410 LCD Framebuffer Driver | ||
4 | * | 6 | * |
5 | * This file is subject to the terms and conditions of the GNU General Public | 7 | * This file is subject to the terms and conditions of the GNU General Public |
6 | * License. See the file COPYING in the main directory of this archive for | 8 | * License. See the file COPYING in the main directory of this archive for |
7 | * more details. | 9 | * more details. |
8 | * | 10 | * |
9 | * S3C2410 LCD Controller Frame Buffer Driver | 11 | */ |
10 | * based on skeletonfb.c, sa1100fb.h | ||
11 | * | ||
12 | * ChangeLog | ||
13 | * | ||
14 | * 2004-12-04: Arnaud Patard <arnaud.patard@rtp-net.org> | ||
15 | * - Moved dprintk to s3c2410fb.c | ||
16 | * | ||
17 | * 2004-09-07: Arnaud Patard <arnaud.patard@rtp-net.org> | ||
18 | * - Renamed from h1940fb.h to s3c2410fb.h | ||
19 | * - Changed h1940 to s3c2410 | ||
20 | * | ||
21 | * 2004-07-15: Arnaud Patard <arnaud.patard@rtp-net.org> | ||
22 | * - First version | ||
23 | */ | ||
24 | 12 | ||
25 | #ifndef __S3C2410FB_H | 13 | #ifndef __S3C2410FB_H |
26 | #define __S3C2410FB_H | 14 | #define __S3C2410FB_H |
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c index 73803624c131..b9343844cd1f 100644 --- a/drivers/video/sis/sis_main.c +++ b/drivers/video/sis/sis_main.c | |||
@@ -5787,7 +5787,7 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
5787 | } else { | 5787 | } else { |
5788 | struct sis_video_info *countvideo = card_list; | 5788 | struct sis_video_info *countvideo = card_list; |
5789 | ivideo->cardnumber = 1; | 5789 | ivideo->cardnumber = 1; |
5790 | while((countvideo = countvideo->next) != 0) | 5790 | while((countvideo = countvideo->next) != NULL) |
5791 | ivideo->cardnumber++; | 5791 | ivideo->cardnumber++; |
5792 | } | 5792 | } |
5793 | 5793 | ||
diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c index 742b5c656d66..15d4a768b1f6 100644 --- a/drivers/video/sm501fb.c +++ b/drivers/video/sm501fb.c | |||
@@ -663,14 +663,14 @@ static void sm501fb_panel_power(struct sm501fb_info *fbi, int to) | |||
663 | sm501fb_sync_regs(fbi); | 663 | sm501fb_sync_regs(fbi); |
664 | mdelay(10); | 664 | mdelay(10); |
665 | 665 | ||
666 | if (pd->flags & SM501FB_FLAG_PANEL_USE_VBIASEN) { | 666 | if (!(pd->flags & SM501FB_FLAG_PANEL_NO_VBIASEN)) { |
667 | control |= SM501_DC_PANEL_CONTROL_BIAS; /* VBIASEN */ | 667 | control |= SM501_DC_PANEL_CONTROL_BIAS; /* VBIASEN */ |
668 | writel(control, ctrl_reg); | 668 | writel(control, ctrl_reg); |
669 | sm501fb_sync_regs(fbi); | 669 | sm501fb_sync_regs(fbi); |
670 | mdelay(10); | 670 | mdelay(10); |
671 | } | 671 | } |
672 | 672 | ||
673 | if (pd->flags & SM501FB_FLAG_PANEL_USE_FPEN) { | 673 | if (!(pd->flags & SM501FB_FLAG_PANEL_NO_FPEN)) { |
674 | control |= SM501_DC_PANEL_CONTROL_FPEN; | 674 | control |= SM501_DC_PANEL_CONTROL_FPEN; |
675 | writel(control, ctrl_reg); | 675 | writel(control, ctrl_reg); |
676 | sm501fb_sync_regs(fbi); | 676 | sm501fb_sync_regs(fbi); |
@@ -678,14 +678,14 @@ static void sm501fb_panel_power(struct sm501fb_info *fbi, int to) | |||
678 | } | 678 | } |
679 | } else if (!to && (control & SM501_DC_PANEL_CONTROL_VDD) != 0) { | 679 | } else if (!to && (control & SM501_DC_PANEL_CONTROL_VDD) != 0) { |
680 | /* disable panel power */ | 680 | /* disable panel power */ |
681 | if (pd->flags & SM501FB_FLAG_PANEL_USE_FPEN) { | 681 | if (!(pd->flags & SM501FB_FLAG_PANEL_NO_FPEN)) { |
682 | control &= ~SM501_DC_PANEL_CONTROL_FPEN; | 682 | control &= ~SM501_DC_PANEL_CONTROL_FPEN; |
683 | writel(control, ctrl_reg); | 683 | writel(control, ctrl_reg); |
684 | sm501fb_sync_regs(fbi); | 684 | sm501fb_sync_regs(fbi); |
685 | mdelay(10); | 685 | mdelay(10); |
686 | } | 686 | } |
687 | 687 | ||
688 | if (pd->flags & SM501FB_FLAG_PANEL_USE_VBIASEN) { | 688 | if (!(pd->flags & SM501FB_FLAG_PANEL_NO_VBIASEN)) { |
689 | control &= ~SM501_DC_PANEL_CONTROL_BIAS; | 689 | control &= ~SM501_DC_PANEL_CONTROL_BIAS; |
690 | writel(control, ctrl_reg); | 690 | writel(control, ctrl_reg); |
691 | sm501fb_sync_regs(fbi); | 691 | sm501fb_sync_regs(fbi); |
diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c index 13866789b356..7084e7e146c0 100644 --- a/drivers/virtio/virtio.c +++ b/drivers/virtio/virtio.c | |||
@@ -2,6 +2,9 @@ | |||
2 | #include <linux/spinlock.h> | 2 | #include <linux/spinlock.h> |
3 | #include <linux/virtio_config.h> | 3 | #include <linux/virtio_config.h> |
4 | 4 | ||
5 | /* Unique numbering for virtio devices. */ | ||
6 | static unsigned int dev_index; | ||
7 | |||
5 | static ssize_t device_show(struct device *_d, | 8 | static ssize_t device_show(struct device *_d, |
6 | struct device_attribute *attr, char *buf) | 9 | struct device_attribute *attr, char *buf) |
7 | { | 10 | { |
@@ -121,9 +124,9 @@ static int virtio_dev_probe(struct device *_d) | |||
121 | if (err) | 124 | if (err) |
122 | add_status(dev, VIRTIO_CONFIG_S_FAILED); | 125 | add_status(dev, VIRTIO_CONFIG_S_FAILED); |
123 | else { | 126 | else { |
124 | add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK); | ||
125 | /* They should never have set feature bits beyond 32 */ | 127 | /* They should never have set feature bits beyond 32 */ |
126 | dev->config->set_features(dev, dev->features[0]); | 128 | dev->config->set_features(dev, dev->features[0]); |
129 | add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK); | ||
127 | } | 130 | } |
128 | return err; | 131 | return err; |
129 | } | 132 | } |
@@ -166,7 +169,10 @@ int register_virtio_device(struct virtio_device *dev) | |||
166 | int err; | 169 | int err; |
167 | 170 | ||
168 | dev->dev.bus = &virtio_bus; | 171 | dev->dev.bus = &virtio_bus; |
169 | sprintf(dev->dev.bus_id, "%u", dev->index); | 172 | |
173 | /* Assign a unique device index and hence name. */ | ||
174 | dev->index = dev_index++; | ||
175 | sprintf(dev->dev.bus_id, "virtio%u", dev->index); | ||
170 | 176 | ||
171 | /* We always start by resetting the device, in case a previous | 177 | /* We always start by resetting the device, in case a previous |
172 | * driver messed it up. This also tests that code path a little. */ | 178 | * driver messed it up. This also tests that code path a little. */ |
diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c index 27e9fc9117cd..eae7236310e4 100644 --- a/drivers/virtio/virtio_pci.c +++ b/drivers/virtio/virtio_pci.c | |||
@@ -78,9 +78,6 @@ static struct device virtio_pci_root = { | |||
78 | .bus_id = "virtio-pci", | 78 | .bus_id = "virtio-pci", |
79 | }; | 79 | }; |
80 | 80 | ||
81 | /* Unique numbering for devices under the kvm root */ | ||
82 | static unsigned int dev_index; | ||
83 | |||
84 | /* Convert a generic virtio device to our structure */ | 81 | /* Convert a generic virtio device to our structure */ |
85 | static struct virtio_pci_device *to_vp_device(struct virtio_device *vdev) | 82 | static struct virtio_pci_device *to_vp_device(struct virtio_device *vdev) |
86 | { | 83 | { |
@@ -325,10 +322,6 @@ static int __devinit virtio_pci_probe(struct pci_dev *pci_dev, | |||
325 | if (vp_dev == NULL) | 322 | if (vp_dev == NULL) |
326 | return -ENOMEM; | 323 | return -ENOMEM; |
327 | 324 | ||
328 | snprintf(vp_dev->vdev.dev.bus_id, BUS_ID_SIZE, "virtio%d", dev_index); | ||
329 | vp_dev->vdev.index = dev_index; | ||
330 | dev_index++; | ||
331 | |||
332 | vp_dev->vdev.dev.parent = &virtio_pci_root; | 325 | vp_dev->vdev.dev.parent = &virtio_pci_root; |
333 | vp_dev->vdev.config = &virtio_pci_config_ops; | 326 | vp_dev->vdev.config = &virtio_pci_config_ops; |
334 | vp_dev->pci_dev = pci_dev; | 327 | vp_dev->pci_dev = pci_dev; |
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index 937a49d6772c..72bf8bc09014 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c | |||
@@ -227,7 +227,6 @@ static bool vring_enable_cb(struct virtqueue *_vq) | |||
227 | struct vring_virtqueue *vq = to_vvq(_vq); | 227 | struct vring_virtqueue *vq = to_vvq(_vq); |
228 | 228 | ||
229 | START_USE(vq); | 229 | START_USE(vq); |
230 | BUG_ON(!(vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT)); | ||
231 | 230 | ||
232 | /* We optimistically turn back on interrupts, then check if there was | 231 | /* We optimistically turn back on interrupts, then check if there was |
233 | * more to do. */ | 232 | * more to do. */ |
@@ -254,13 +253,6 @@ irqreturn_t vring_interrupt(int irq, void *_vq) | |||
254 | if (unlikely(vq->broken)) | 253 | if (unlikely(vq->broken)) |
255 | return IRQ_HANDLED; | 254 | return IRQ_HANDLED; |
256 | 255 | ||
257 | /* Other side may have missed us turning off the interrupt, | ||
258 | * but we should preserve disable semantic for virtio users. */ | ||
259 | if (unlikely(vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT)) { | ||
260 | pr_debug("virtqueue interrupt after disable for %p\n", vq); | ||
261 | return IRQ_HANDLED; | ||
262 | } | ||
263 | |||
264 | pr_debug("virtqueue callback for %p (%p)\n", vq, vq->vq.callback); | 256 | pr_debug("virtqueue callback for %p (%p)\n", vq, vq->vq.callback); |
265 | if (vq->vq.callback) | 257 | if (vq->vq.callback) |
266 | vq->vq.callback(&vq->vq); | 258 | vq->vq.callback(&vq->vq); |
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 254d115cafab..ccb78f66c2b6 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig | |||
@@ -295,6 +295,19 @@ config ALIM7101_WDT | |||
295 | 295 | ||
296 | Most people will say N. | 296 | Most people will say N. |
297 | 297 | ||
298 | config GEODE_WDT | ||
299 | tristate "AMD Geode CS5535/CS5536 Watchdog" | ||
300 | depends on MGEODE_LX | ||
301 | help | ||
302 | This driver enables a watchdog capability built into the | ||
303 | CS5535/CS5536 companion chips for the AMD Geode GX and LX | ||
304 | processors. This watchdog watches your kernel to make sure | ||
305 | it doesn't freeze, and if it does, it reboots your computer after | ||
306 | a certain amount of time. | ||
307 | |||
308 | You can compile this driver directly into the kernel, or use | ||
309 | it as a module. The module will be called geodewdt. | ||
310 | |||
298 | config SC520_WDT | 311 | config SC520_WDT |
299 | tristate "AMD Elan SC520 processor Watchdog" | 312 | tristate "AMD Elan SC520 processor Watchdog" |
300 | depends on X86 | 313 | depends on X86 |
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index f3fb170fe5c6..25b352b664d9 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile | |||
@@ -59,6 +59,7 @@ obj-$(CONFIG_ACQUIRE_WDT) += acquirewdt.o | |||
59 | obj-$(CONFIG_ADVANTECH_WDT) += advantechwdt.o | 59 | obj-$(CONFIG_ADVANTECH_WDT) += advantechwdt.o |
60 | obj-$(CONFIG_ALIM1535_WDT) += alim1535_wdt.o | 60 | obj-$(CONFIG_ALIM1535_WDT) += alim1535_wdt.o |
61 | obj-$(CONFIG_ALIM7101_WDT) += alim7101_wdt.o | 61 | obj-$(CONFIG_ALIM7101_WDT) += alim7101_wdt.o |
62 | obj-$(CONFIG_GEODE_WDT) += geodewdt.o | ||
62 | obj-$(CONFIG_SC520_WDT) += sc520_wdt.o | 63 | obj-$(CONFIG_SC520_WDT) += sc520_wdt.o |
63 | obj-$(CONFIG_EUROTECH_WDT) += eurotechwdt.o | 64 | obj-$(CONFIG_EUROTECH_WDT) += eurotechwdt.o |
64 | obj-$(CONFIG_IB700_WDT) += ib700wdt.o | 65 | obj-$(CONFIG_IB700_WDT) += ib700wdt.o |
diff --git a/drivers/watchdog/bfin_wdt.c b/drivers/watchdog/bfin_wdt.c index 1237113dc14a..03b3e3d91e7c 100644 --- a/drivers/watchdog/bfin_wdt.c +++ b/drivers/watchdog/bfin_wdt.c | |||
@@ -29,7 +29,8 @@ | |||
29 | 29 | ||
30 | #define stamp(fmt, args...) pr_debug("%s:%i: " fmt "\n", __func__, __LINE__, ## args) | 30 | #define stamp(fmt, args...) pr_debug("%s:%i: " fmt "\n", __func__, __LINE__, ## args) |
31 | #define stampit() stamp("here i am") | 31 | #define stampit() stamp("here i am") |
32 | #define pr_init(fmt, args...) ({ static const __initdata char __fmt[] = fmt; printk(__fmt, ## args); }) | 32 | #define pr_devinit(fmt, args...) ({ static const __devinitconst char __fmt[] = fmt; printk(__fmt, ## args); }) |
33 | #define pr_init(fmt, args...) ({ static const __initconst char __fmt[] = fmt; printk(__fmt, ## args); }) | ||
33 | 34 | ||
34 | #define WATCHDOG_NAME "bfin-wdt" | 35 | #define WATCHDOG_NAME "bfin-wdt" |
35 | #define PFX WATCHDOG_NAME ": " | 36 | #define PFX WATCHDOG_NAME ": " |
@@ -377,20 +378,6 @@ static int bfin_wdt_resume(struct platform_device *pdev) | |||
377 | # define bfin_wdt_resume NULL | 378 | # define bfin_wdt_resume NULL |
378 | #endif | 379 | #endif |
379 | 380 | ||
380 | static struct platform_device bfin_wdt_device = { | ||
381 | .name = WATCHDOG_NAME, | ||
382 | .id = -1, | ||
383 | }; | ||
384 | |||
385 | static struct platform_driver bfin_wdt_driver = { | ||
386 | .driver = { | ||
387 | .name = WATCHDOG_NAME, | ||
388 | .owner = THIS_MODULE, | ||
389 | }, | ||
390 | .suspend = bfin_wdt_suspend, | ||
391 | .resume = bfin_wdt_resume, | ||
392 | }; | ||
393 | |||
394 | static const struct file_operations bfin_wdt_fops = { | 381 | static const struct file_operations bfin_wdt_fops = { |
395 | .owner = THIS_MODULE, | 382 | .owner = THIS_MODULE, |
396 | .llseek = no_llseek, | 383 | .llseek = no_llseek, |
@@ -418,11 +405,67 @@ static struct notifier_block bfin_wdt_notifier = { | |||
418 | }; | 405 | }; |
419 | 406 | ||
420 | /** | 407 | /** |
421 | * bfin_wdt_init - Initialize module | 408 | * bfin_wdt_probe - Initialize module |
422 | * | 409 | * |
423 | * Registers the device and notifier handler. Actual device | 410 | * Registers the misc device and notifier handler. Actual device |
424 | * initialization is handled by bfin_wdt_open(). | 411 | * initialization is handled by bfin_wdt_open(). |
425 | */ | 412 | */ |
413 | static int __devinit bfin_wdt_probe(struct platform_device *pdev) | ||
414 | { | ||
415 | int ret; | ||
416 | |||
417 | ret = register_reboot_notifier(&bfin_wdt_notifier); | ||
418 | if (ret) { | ||
419 | pr_devinit(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", ret); | ||
420 | return ret; | ||
421 | } | ||
422 | |||
423 | ret = misc_register(&bfin_wdt_miscdev); | ||
424 | if (ret) { | ||
425 | pr_devinit(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", | ||
426 | WATCHDOG_MINOR, ret); | ||
427 | unregister_reboot_notifier(&bfin_wdt_notifier); | ||
428 | return ret; | ||
429 | } | ||
430 | |||
431 | pr_devinit(KERN_INFO PFX "initialized: timeout=%d sec (nowayout=%d)\n", | ||
432 | timeout, nowayout); | ||
433 | |||
434 | return 0; | ||
435 | } | ||
436 | |||
437 | /** | ||
438 | * bfin_wdt_remove - Initialize module | ||
439 | * | ||
440 | * Unregisters the misc device and notifier handler. Actual device | ||
441 | * deinitialization is handled by bfin_wdt_close(). | ||
442 | */ | ||
443 | static int __devexit bfin_wdt_remove(struct platform_device *pdev) | ||
444 | { | ||
445 | misc_deregister(&bfin_wdt_miscdev); | ||
446 | unregister_reboot_notifier(&bfin_wdt_notifier); | ||
447 | return 0; | ||
448 | } | ||
449 | |||
450 | static struct platform_device *bfin_wdt_device; | ||
451 | |||
452 | static struct platform_driver bfin_wdt_driver = { | ||
453 | .probe = bfin_wdt_probe, | ||
454 | .remove = __devexit_p(bfin_wdt_remove), | ||
455 | .suspend = bfin_wdt_suspend, | ||
456 | .resume = bfin_wdt_resume, | ||
457 | .driver = { | ||
458 | .name = WATCHDOG_NAME, | ||
459 | .owner = THIS_MODULE, | ||
460 | }, | ||
461 | }; | ||
462 | |||
463 | /** | ||
464 | * bfin_wdt_init - Initialize module | ||
465 | * | ||
466 | * Checks the module params and registers the platform device & driver. | ||
467 | * Real work is in the platform probe function. | ||
468 | */ | ||
426 | static int __init bfin_wdt_init(void) | 469 | static int __init bfin_wdt_init(void) |
427 | { | 470 | { |
428 | int ret; | 471 | int ret; |
@@ -436,44 +479,32 @@ static int __init bfin_wdt_init(void) | |||
436 | /* Since this is an on-chip device and needs no board-specific | 479 | /* Since this is an on-chip device and needs no board-specific |
437 | * resources, we'll handle all the platform device stuff here. | 480 | * resources, we'll handle all the platform device stuff here. |
438 | */ | 481 | */ |
439 | ret = platform_device_register(&bfin_wdt_device); | 482 | ret = platform_driver_register(&bfin_wdt_driver); |
440 | if (ret) | ||
441 | return ret; | ||
442 | |||
443 | ret = platform_driver_probe(&bfin_wdt_driver, NULL); | ||
444 | if (ret) | ||
445 | return ret; | ||
446 | |||
447 | ret = register_reboot_notifier(&bfin_wdt_notifier); | ||
448 | if (ret) { | 483 | if (ret) { |
449 | pr_init(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", ret); | 484 | pr_init(KERN_ERR PFX "unable to register driver\n"); |
450 | return ret; | 485 | return ret; |
451 | } | 486 | } |
452 | 487 | ||
453 | ret = misc_register(&bfin_wdt_miscdev); | 488 | bfin_wdt_device = platform_device_register_simple(WATCHDOG_NAME, -1, NULL, 0); |
454 | if (ret) { | 489 | if (IS_ERR(bfin_wdt_device)) { |
455 | pr_init(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", | 490 | pr_init(KERN_ERR PFX "unable to register device\n"); |
456 | WATCHDOG_MINOR, ret); | 491 | platform_driver_unregister(&bfin_wdt_driver); |
457 | unregister_reboot_notifier(&bfin_wdt_notifier); | 492 | return PTR_ERR(bfin_wdt_device); |
458 | return ret; | ||
459 | } | 493 | } |
460 | 494 | ||
461 | pr_init(KERN_INFO PFX "initialized: timeout=%d sec (nowayout=%d)\n", | ||
462 | timeout, nowayout); | ||
463 | |||
464 | return 0; | 495 | return 0; |
465 | } | 496 | } |
466 | 497 | ||
467 | /** | 498 | /** |
468 | * bfin_wdt_exit - Deinitialize module | 499 | * bfin_wdt_exit - Deinitialize module |
469 | * | 500 | * |
470 | * Unregisters the device and notifier handler. Actual device | 501 | * Back out the platform device & driver steps. Real work is in the |
471 | * deinitialization is handled by bfin_wdt_close(). | 502 | * platform remove function. |
472 | */ | 503 | */ |
473 | static void __exit bfin_wdt_exit(void) | 504 | static void __exit bfin_wdt_exit(void) |
474 | { | 505 | { |
475 | misc_deregister(&bfin_wdt_miscdev); | 506 | platform_device_unregister(bfin_wdt_device); |
476 | unregister_reboot_notifier(&bfin_wdt_notifier); | 507 | platform_driver_unregister(&bfin_wdt_driver); |
477 | } | 508 | } |
478 | 509 | ||
479 | module_init(bfin_wdt_init); | 510 | module_init(bfin_wdt_init); |
diff --git a/drivers/watchdog/booke_wdt.c b/drivers/watchdog/booke_wdt.c index d362f5bf658a..c1ba0db48501 100644 --- a/drivers/watchdog/booke_wdt.c +++ b/drivers/watchdog/booke_wdt.c | |||
@@ -1,12 +1,10 @@ | |||
1 | /* | 1 | /* |
2 | * drivers/char/watchdog/booke_wdt.c | ||
3 | * | ||
4 | * Watchdog timer for PowerPC Book-E systems | 2 | * Watchdog timer for PowerPC Book-E systems |
5 | * | 3 | * |
6 | * Author: Matthew McClintock | 4 | * Author: Matthew McClintock |
7 | * Maintainer: Kumar Gala <galak@kernel.crashing.org> | 5 | * Maintainer: Kumar Gala <galak@kernel.crashing.org> |
8 | * | 6 | * |
9 | * Copyright 2005 Freescale Semiconductor Inc. | 7 | * Copyright 2005, 2008 Freescale Semiconductor Inc. |
10 | * | 8 | * |
11 | * This program is free software; you can redistribute it and/or modify it | 9 | * This program is free software; you can redistribute it and/or modify it |
12 | * under the terms of the GNU General Public License as published by the | 10 | * under the terms of the GNU General Public License as published by the |
@@ -16,6 +14,7 @@ | |||
16 | 14 | ||
17 | #include <linux/module.h> | 15 | #include <linux/module.h> |
18 | #include <linux/fs.h> | 16 | #include <linux/fs.h> |
17 | #include <linux/smp.h> | ||
19 | #include <linux/miscdevice.h> | 18 | #include <linux/miscdevice.h> |
20 | #include <linux/notifier.h> | 19 | #include <linux/notifier.h> |
21 | #include <linux/watchdog.h> | 20 | #include <linux/watchdog.h> |
@@ -38,7 +37,7 @@ | |||
38 | #define WDT_PERIOD_DEFAULT 3 /* Refer to the PPC40x and PPC4xx manuals */ | 37 | #define WDT_PERIOD_DEFAULT 3 /* Refer to the PPC40x and PPC4xx manuals */ |
39 | #endif /* for timing information */ | 38 | #endif /* for timing information */ |
40 | 39 | ||
41 | u32 booke_wdt_enabled = 0; | 40 | u32 booke_wdt_enabled; |
42 | u32 booke_wdt_period = WDT_PERIOD_DEFAULT; | 41 | u32 booke_wdt_period = WDT_PERIOD_DEFAULT; |
43 | 42 | ||
44 | #ifdef CONFIG_FSL_BOOKE | 43 | #ifdef CONFIG_FSL_BOOKE |
@@ -47,33 +46,31 @@ u32 booke_wdt_period = WDT_PERIOD_DEFAULT; | |||
47 | #define WDTP(x) (TCR_WP(x)) | 46 | #define WDTP(x) (TCR_WP(x)) |
48 | #endif | 47 | #endif |
49 | 48 | ||
50 | /* | 49 | static DEFINE_SPINLOCK(booke_wdt_lock); |
51 | * booke_wdt_ping: | 50 | |
52 | */ | 51 | static void __booke_wdt_ping(void *data) |
53 | static __inline__ void booke_wdt_ping(void) | ||
54 | { | 52 | { |
55 | mtspr(SPRN_TSR, TSR_ENW|TSR_WIS); | 53 | mtspr(SPRN_TSR, TSR_ENW|TSR_WIS); |
56 | } | 54 | } |
57 | 55 | ||
58 | /* | 56 | static void booke_wdt_ping(void) |
59 | * booke_wdt_enable: | 57 | { |
60 | */ | 58 | on_each_cpu(__booke_wdt_ping, NULL, 0, 0); |
61 | static __inline__ void booke_wdt_enable(void) | 59 | } |
60 | |||
61 | static void __booke_wdt_enable(void *data) | ||
62 | { | 62 | { |
63 | u32 val; | 63 | u32 val; |
64 | 64 | ||
65 | /* clear status before enabling watchdog */ | 65 | /* clear status before enabling watchdog */ |
66 | booke_wdt_ping(); | 66 | __booke_wdt_ping(NULL); |
67 | val = mfspr(SPRN_TCR); | 67 | val = mfspr(SPRN_TCR); |
68 | val |= (TCR_WIE|TCR_WRC(WRC_CHIP)|WDTP(booke_wdt_period)); | 68 | val |= (TCR_WIE|TCR_WRC(WRC_CHIP)|WDTP(booke_wdt_period)); |
69 | 69 | ||
70 | mtspr(SPRN_TCR, val); | 70 | mtspr(SPRN_TCR, val); |
71 | } | 71 | } |
72 | 72 | ||
73 | /* | 73 | static ssize_t booke_wdt_write(struct file *file, const char __user *buf, |
74 | * booke_wdt_write: | ||
75 | */ | ||
76 | static ssize_t booke_wdt_write (struct file *file, const char __user *buf, | ||
77 | size_t count, loff_t *ppos) | 74 | size_t count, loff_t *ppos) |
78 | { | 75 | { |
79 | booke_wdt_ping(); | 76 | booke_wdt_ping(); |
@@ -81,15 +78,11 @@ static ssize_t booke_wdt_write (struct file *file, const char __user *buf, | |||
81 | } | 78 | } |
82 | 79 | ||
83 | static struct watchdog_info ident = { | 80 | static struct watchdog_info ident = { |
84 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, | 81 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, |
85 | .firmware_version = 0, | 82 | .identity = "PowerPC Book-E Watchdog", |
86 | .identity = "PowerPC Book-E Watchdog", | ||
87 | }; | 83 | }; |
88 | 84 | ||
89 | /* | 85 | static int booke_wdt_ioctl(struct inode *inode, struct file *file, |
90 | * booke_wdt_ioctl: | ||
91 | */ | ||
92 | static int booke_wdt_ioctl (struct inode *inode, struct file *file, | ||
93 | unsigned int cmd, unsigned long arg) | 86 | unsigned int cmd, unsigned long arg) |
94 | { | 87 | { |
95 | u32 tmp = 0; | 88 | u32 tmp = 0; |
@@ -97,7 +90,7 @@ static int booke_wdt_ioctl (struct inode *inode, struct file *file, | |||
97 | 90 | ||
98 | switch (cmd) { | 91 | switch (cmd) { |
99 | case WDIOC_GETSUPPORT: | 92 | case WDIOC_GETSUPPORT: |
100 | if (copy_to_user ((struct watchdog_info __user *) arg, &ident, | 93 | if (copy_to_user((struct watchdog_info __user *)arg, &ident, |
101 | sizeof(struct watchdog_info))) | 94 | sizeof(struct watchdog_info))) |
102 | return -EFAULT; | 95 | return -EFAULT; |
103 | case WDIOC_GETSTATUS: | 96 | case WDIOC_GETSTATUS: |
@@ -132,33 +125,33 @@ static int booke_wdt_ioctl (struct inode *inode, struct file *file, | |||
132 | 125 | ||
133 | return 0; | 126 | return 0; |
134 | } | 127 | } |
135 | /* | 128 | |
136 | * booke_wdt_open: | 129 | static int booke_wdt_open(struct inode *inode, struct file *file) |
137 | */ | ||
138 | static int booke_wdt_open (struct inode *inode, struct file *file) | ||
139 | { | 130 | { |
131 | spin_lock(&booke_wdt_lock); | ||
140 | if (booke_wdt_enabled == 0) { | 132 | if (booke_wdt_enabled == 0) { |
141 | booke_wdt_enabled = 1; | 133 | booke_wdt_enabled = 1; |
142 | booke_wdt_enable(); | 134 | on_each_cpu(__booke_wdt_enable, NULL, 0, 0); |
143 | printk (KERN_INFO "PowerPC Book-E Watchdog Timer Enabled (wdt_period=%d)\n", | 135 | printk(KERN_INFO "PowerPC Book-E Watchdog Timer Enabled " |
144 | booke_wdt_period); | 136 | "(wdt_period=%d)\n", booke_wdt_period); |
145 | } | 137 | } |
138 | spin_unlock(&booke_wdt_lock); | ||
146 | 139 | ||
147 | return nonseekable_open(inode, file); | 140 | return nonseekable_open(inode, file); |
148 | } | 141 | } |
149 | 142 | ||
150 | static const struct file_operations booke_wdt_fops = { | 143 | static const struct file_operations booke_wdt_fops = { |
151 | .owner = THIS_MODULE, | 144 | .owner = THIS_MODULE, |
152 | .llseek = no_llseek, | 145 | .llseek = no_llseek, |
153 | .write = booke_wdt_write, | 146 | .write = booke_wdt_write, |
154 | .ioctl = booke_wdt_ioctl, | 147 | .ioctl = booke_wdt_ioctl, |
155 | .open = booke_wdt_open, | 148 | .open = booke_wdt_open, |
156 | }; | 149 | }; |
157 | 150 | ||
158 | static struct miscdevice booke_wdt_miscdev = { | 151 | static struct miscdevice booke_wdt_miscdev = { |
159 | .minor = WATCHDOG_MINOR, | 152 | .minor = WATCHDOG_MINOR, |
160 | .name = "watchdog", | 153 | .name = "watchdog", |
161 | .fops = &booke_wdt_fops, | 154 | .fops = &booke_wdt_fops, |
162 | }; | 155 | }; |
163 | 156 | ||
164 | static void __exit booke_wdt_exit(void) | 157 | static void __exit booke_wdt_exit(void) |
@@ -166,28 +159,27 @@ static void __exit booke_wdt_exit(void) | |||
166 | misc_deregister(&booke_wdt_miscdev); | 159 | misc_deregister(&booke_wdt_miscdev); |
167 | } | 160 | } |
168 | 161 | ||
169 | /* | ||
170 | * booke_wdt_init: | ||
171 | */ | ||
172 | static int __init booke_wdt_init(void) | 162 | static int __init booke_wdt_init(void) |
173 | { | 163 | { |
174 | int ret = 0; | 164 | int ret = 0; |
175 | 165 | ||
176 | printk (KERN_INFO "PowerPC Book-E Watchdog Timer Loaded\n"); | 166 | printk(KERN_INFO "PowerPC Book-E Watchdog Timer Loaded\n"); |
177 | ident.firmware_version = cur_cpu_spec->pvr_value; | 167 | ident.firmware_version = cur_cpu_spec->pvr_value; |
178 | 168 | ||
179 | ret = misc_register(&booke_wdt_miscdev); | 169 | ret = misc_register(&booke_wdt_miscdev); |
180 | if (ret) { | 170 | if (ret) { |
181 | printk (KERN_CRIT "Cannot register miscdev on minor=%d (err=%d)\n", | 171 | printk(KERN_CRIT "Cannot register miscdev on minor=%d: %d\n", |
182 | WATCHDOG_MINOR, ret); | 172 | WATCHDOG_MINOR, ret); |
183 | return ret; | 173 | return ret; |
184 | } | 174 | } |
185 | 175 | ||
176 | spin_lock(&booke_wdt_lock); | ||
186 | if (booke_wdt_enabled == 1) { | 177 | if (booke_wdt_enabled == 1) { |
187 | printk (KERN_INFO "PowerPC Book-E Watchdog Timer Enabled (wdt_period=%d)\n", | 178 | printk(KERN_INFO "PowerPC Book-E Watchdog Timer Enabled " |
188 | booke_wdt_period); | 179 | "(wdt_period=%d)\n", booke_wdt_period); |
189 | booke_wdt_enable(); | 180 | on_each_cpu(__booke_wdt_enable, NULL, 0, 0); |
190 | } | 181 | } |
182 | spin_unlock(&booke_wdt_lock); | ||
191 | 183 | ||
192 | return ret; | 184 | return ret; |
193 | } | 185 | } |
diff --git a/drivers/watchdog/geodewdt.c b/drivers/watchdog/geodewdt.c new file mode 100644 index 000000000000..30d09cbbad94 --- /dev/null +++ b/drivers/watchdog/geodewdt.c | |||
@@ -0,0 +1,308 @@ | |||
1 | /* Watchdog timer for the Geode GX/LX with the CS5535/CS5536 companion chip | ||
2 | * | ||
3 | * Copyright (C) 2006-2007, Advanced Micro Devices, Inc. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License | ||
7 | * as published by the Free Software Foundation; either version | ||
8 | * 2 of the License, or (at your option) any later version. | ||
9 | */ | ||
10 | |||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/moduleparam.h> | ||
14 | #include <linux/types.h> | ||
15 | #include <linux/miscdevice.h> | ||
16 | #include <linux/watchdog.h> | ||
17 | #include <linux/fs.h> | ||
18 | #include <linux/platform_device.h> | ||
19 | #include <linux/reboot.h> | ||
20 | |||
21 | #include <asm/uaccess.h> | ||
22 | #include <asm/geode.h> | ||
23 | |||
24 | #define GEODEWDT_HZ 500 | ||
25 | #define GEODEWDT_SCALE 6 | ||
26 | #define GEODEWDT_MAX_SECONDS 131 | ||
27 | |||
28 | #define WDT_FLAGS_OPEN 1 | ||
29 | #define WDT_FLAGS_ORPHAN 2 | ||
30 | |||
31 | #define DRV_NAME "geodewdt" | ||
32 | #define WATCHDOG_NAME "Geode GX/LX WDT" | ||
33 | #define WATCHDOG_TIMEOUT 60 | ||
34 | |||
35 | static int timeout = WATCHDOG_TIMEOUT; | ||
36 | module_param(timeout, int, 0); | ||
37 | MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=131, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) "."); | ||
38 | |||
39 | static int nowayout = WATCHDOG_NOWAYOUT; | ||
40 | module_param(nowayout, int, 0); | ||
41 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
42 | |||
43 | static struct platform_device *geodewdt_platform_device; | ||
44 | static unsigned long wdt_flags; | ||
45 | static int wdt_timer; | ||
46 | static int safe_close; | ||
47 | |||
48 | static void geodewdt_ping(void) | ||
49 | { | ||
50 | /* Stop the counter */ | ||
51 | geode_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, 0); | ||
52 | |||
53 | /* Reset the counter */ | ||
54 | geode_mfgpt_write(wdt_timer, MFGPT_REG_COUNTER, 0); | ||
55 | |||
56 | /* Enable the counter */ | ||
57 | geode_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, MFGPT_SETUP_CNTEN); | ||
58 | } | ||
59 | |||
60 | static void geodewdt_disable(void) | ||
61 | { | ||
62 | geode_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, 0); | ||
63 | geode_mfgpt_write(wdt_timer, MFGPT_REG_COUNTER, 0); | ||
64 | } | ||
65 | |||
66 | static int geodewdt_set_heartbeat(int val) | ||
67 | { | ||
68 | if (val < 1 || val > GEODEWDT_MAX_SECONDS) | ||
69 | return -EINVAL; | ||
70 | |||
71 | geode_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, 0); | ||
72 | geode_mfgpt_write(wdt_timer, MFGPT_REG_CMP2, val * GEODEWDT_HZ); | ||
73 | geode_mfgpt_write(wdt_timer, MFGPT_REG_COUNTER, 0); | ||
74 | geode_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, MFGPT_SETUP_CNTEN); | ||
75 | |||
76 | timeout = val; | ||
77 | return 0; | ||
78 | } | ||
79 | |||
80 | static int | ||
81 | geodewdt_open(struct inode *inode, struct file *file) | ||
82 | { | ||
83 | if (test_and_set_bit(WDT_FLAGS_OPEN, &wdt_flags)) | ||
84 | return -EBUSY; | ||
85 | |||
86 | if (!test_and_clear_bit(WDT_FLAGS_ORPHAN, &wdt_flags)) | ||
87 | __module_get(THIS_MODULE); | ||
88 | |||
89 | geodewdt_ping(); | ||
90 | return nonseekable_open(inode, file); | ||
91 | } | ||
92 | |||
93 | static int | ||
94 | geodewdt_release(struct inode *inode, struct file *file) | ||
95 | { | ||
96 | if (safe_close) { | ||
97 | geodewdt_disable(); | ||
98 | module_put(THIS_MODULE); | ||
99 | } | ||
100 | else { | ||
101 | printk(KERN_CRIT "Unexpected close - watchdog is not stopping.\n"); | ||
102 | geodewdt_ping(); | ||
103 | |||
104 | set_bit(WDT_FLAGS_ORPHAN, &wdt_flags); | ||
105 | } | ||
106 | |||
107 | clear_bit(WDT_FLAGS_OPEN, &wdt_flags); | ||
108 | safe_close = 0; | ||
109 | return 0; | ||
110 | } | ||
111 | |||
112 | static ssize_t | ||
113 | geodewdt_write(struct file *file, const char __user *data, size_t len, | ||
114 | loff_t *ppos) | ||
115 | { | ||
116 | if(len) { | ||
117 | if (!nowayout) { | ||
118 | size_t i; | ||
119 | safe_close = 0; | ||
120 | |||
121 | for (i = 0; i != len; i++) { | ||
122 | char c; | ||
123 | |||
124 | if (get_user(c, data + i)) | ||
125 | return -EFAULT; | ||
126 | |||
127 | if (c == 'V') | ||
128 | safe_close = 1; | ||
129 | } | ||
130 | } | ||
131 | |||
132 | geodewdt_ping(); | ||
133 | } | ||
134 | return len; | ||
135 | } | ||
136 | |||
137 | static int | ||
138 | geodewdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | ||
139 | unsigned long arg) | ||
140 | { | ||
141 | void __user *argp = (void __user *)arg; | ||
142 | int __user *p = argp; | ||
143 | int interval; | ||
144 | |||
145 | static struct watchdog_info ident = { | ||
146 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | ||
147 | | WDIOF_MAGICCLOSE, | ||
148 | .firmware_version = 1, | ||
149 | .identity = WATCHDOG_NAME, | ||
150 | }; | ||
151 | |||
152 | switch(cmd) { | ||
153 | case WDIOC_GETSUPPORT: | ||
154 | return copy_to_user(argp, &ident, | ||
155 | sizeof(ident)) ? -EFAULT : 0; | ||
156 | break; | ||
157 | |||
158 | case WDIOC_GETSTATUS: | ||
159 | case WDIOC_GETBOOTSTATUS: | ||
160 | return put_user(0, p); | ||
161 | |||
162 | case WDIOC_KEEPALIVE: | ||
163 | geodewdt_ping(); | ||
164 | return 0; | ||
165 | |||
166 | case WDIOC_SETTIMEOUT: | ||
167 | if (get_user(interval, p)) | ||
168 | return -EFAULT; | ||
169 | |||
170 | if (geodewdt_set_heartbeat(interval)) | ||
171 | return -EINVAL; | ||
172 | |||
173 | /* Fall through */ | ||
174 | |||
175 | case WDIOC_GETTIMEOUT: | ||
176 | return put_user(timeout, p); | ||
177 | |||
178 | case WDIOC_SETOPTIONS: | ||
179 | { | ||
180 | int options, ret = -EINVAL; | ||
181 | |||
182 | if (get_user(options, p)) | ||
183 | return -EFAULT; | ||
184 | |||
185 | if (options & WDIOS_DISABLECARD) { | ||
186 | geodewdt_disable(); | ||
187 | ret = 0; | ||
188 | } | ||
189 | |||
190 | if (options & WDIOS_ENABLECARD) { | ||
191 | geodewdt_ping(); | ||
192 | ret = 0; | ||
193 | } | ||
194 | |||
195 | return ret; | ||
196 | } | ||
197 | default: | ||
198 | return -ENOTTY; | ||
199 | } | ||
200 | |||
201 | return 0; | ||
202 | } | ||
203 | |||
204 | static const struct file_operations geodewdt_fops = { | ||
205 | .owner = THIS_MODULE, | ||
206 | .llseek = no_llseek, | ||
207 | .write = geodewdt_write, | ||
208 | .ioctl = geodewdt_ioctl, | ||
209 | .open = geodewdt_open, | ||
210 | .release = geodewdt_release, | ||
211 | }; | ||
212 | |||
213 | static struct miscdevice geodewdt_miscdev = { | ||
214 | .minor = WATCHDOG_MINOR, | ||
215 | .name = "watchdog", | ||
216 | .fops = &geodewdt_fops | ||
217 | }; | ||
218 | |||
219 | static int __devinit | ||
220 | geodewdt_probe(struct platform_device *dev) | ||
221 | { | ||
222 | int ret, timer; | ||
223 | |||
224 | timer = geode_mfgpt_alloc_timer(MFGPT_TIMER_ANY, MFGPT_DOMAIN_WORKING); | ||
225 | |||
226 | if (timer == -1) { | ||
227 | printk(KERN_ERR "geodewdt: No timers were available\n"); | ||
228 | return -ENODEV; | ||
229 | } | ||
230 | |||
231 | wdt_timer = timer; | ||
232 | |||
233 | /* Set up the timer */ | ||
234 | |||
235 | geode_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, | ||
236 | GEODEWDT_SCALE | (3 << 8)); | ||
237 | |||
238 | /* Set up comparator 2 to reset when the event fires */ | ||
239 | geode_mfgpt_toggle_event(wdt_timer, MFGPT_CMP2, MFGPT_EVENT_RESET, 1); | ||
240 | |||
241 | /* Set up the initial timeout */ | ||
242 | |||
243 | geode_mfgpt_write(wdt_timer, MFGPT_REG_CMP2, | ||
244 | timeout * GEODEWDT_HZ); | ||
245 | |||
246 | ret = misc_register(&geodewdt_miscdev); | ||
247 | |||
248 | return ret; | ||
249 | } | ||
250 | |||
251 | static int __devexit | ||
252 | geodewdt_remove(struct platform_device *dev) | ||
253 | { | ||
254 | misc_deregister(&geodewdt_miscdev); | ||
255 | return 0; | ||
256 | } | ||
257 | |||
258 | static void | ||
259 | geodewdt_shutdown(struct platform_device *dev) | ||
260 | { | ||
261 | geodewdt_disable(); | ||
262 | } | ||
263 | |||
264 | static struct platform_driver geodewdt_driver = { | ||
265 | .probe = geodewdt_probe, | ||
266 | .remove = __devexit_p(geodewdt_remove), | ||
267 | .shutdown = geodewdt_shutdown, | ||
268 | .driver = { | ||
269 | .owner = THIS_MODULE, | ||
270 | .name = DRV_NAME, | ||
271 | }, | ||
272 | }; | ||
273 | |||
274 | static int __init | ||
275 | geodewdt_init(void) | ||
276 | { | ||
277 | int ret; | ||
278 | |||
279 | ret = platform_driver_register(&geodewdt_driver); | ||
280 | if (ret) | ||
281 | return ret; | ||
282 | |||
283 | geodewdt_platform_device = platform_device_register_simple(DRV_NAME, -1, NULL, 0); | ||
284 | if (IS_ERR(geodewdt_platform_device)) { | ||
285 | ret = PTR_ERR(geodewdt_platform_device); | ||
286 | goto err; | ||
287 | } | ||
288 | |||
289 | return 0; | ||
290 | err: | ||
291 | platform_driver_unregister(&geodewdt_driver); | ||
292 | return ret; | ||
293 | } | ||
294 | |||
295 | static void __exit | ||
296 | geodewdt_exit(void) | ||
297 | { | ||
298 | platform_device_unregister(geodewdt_platform_device); | ||
299 | platform_driver_unregister(&geodewdt_driver); | ||
300 | } | ||
301 | |||
302 | module_init(geodewdt_init); | ||
303 | module_exit(geodewdt_exit); | ||
304 | |||
305 | MODULE_AUTHOR("Advanced Micro Devices, Inc"); | ||
306 | MODULE_DESCRIPTION("Geode GX/LX Watchdog Driver"); | ||
307 | MODULE_LICENSE("GPL"); | ||
308 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); | ||
diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c index 6483d1066b95..6a63535fc04d 100644 --- a/drivers/watchdog/hpwdt.c +++ b/drivers/watchdog/hpwdt.c | |||
@@ -418,23 +418,20 @@ static int hpwdt_pretimeout(struct notifier_block *nb, unsigned long ulReason, | |||
418 | static unsigned long rom_pl; | 418 | static unsigned long rom_pl; |
419 | static int die_nmi_called; | 419 | static int die_nmi_called; |
420 | 420 | ||
421 | if (ulReason != DIE_NMI && ulReason != DIE_NMI_IPI) | 421 | if (ulReason == DIE_NMI || ulReason == DIE_NMI_IPI) { |
422 | return NOTIFY_OK; | 422 | spin_lock_irqsave(&rom_lock, rom_pl); |
423 | 423 | if (!die_nmi_called) | |
424 | spin_lock_irqsave(&rom_lock, rom_pl); | 424 | asminline_call(&cmn_regs, cru_rom_addr); |
425 | if (!die_nmi_called) | 425 | die_nmi_called = 1; |
426 | asminline_call(&cmn_regs, cru_rom_addr); | 426 | spin_unlock_irqrestore(&rom_lock, rom_pl); |
427 | die_nmi_called = 1; | 427 | if (cmn_regs.u1.ral != 0) { |
428 | spin_unlock_irqrestore(&rom_lock, rom_pl); | 428 | panic("An NMI occurred, please see the Integrated " |
429 | if (cmn_regs.u1.ral == 0) { | 429 | "Management Log for details.\n"); |
430 | printk(KERN_WARNING "hpwdt: An NMI occurred, " | 430 | } |
431 | "but unable to determine source.\n"); | ||
432 | } else { | ||
433 | panic("An NMI occurred, please see the Integrated " | ||
434 | "Management Log for details.\n"); | ||
435 | } | 431 | } |
436 | 432 | ||
437 | return NOTIFY_STOP; | 433 | die_nmi_called = 0; |
434 | return NOTIFY_DONE; | ||
438 | } | 435 | } |
439 | 436 | ||
440 | /* | 437 | /* |
diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c index a0e6809e369f..95ba985bd341 100644 --- a/drivers/watchdog/iTCO_wdt.c +++ b/drivers/watchdog/iTCO_wdt.c | |||
@@ -41,9 +41,10 @@ | |||
41 | * 82801HH (ICH8DH) : document number 313056-003, 313057-009, | 41 | * 82801HH (ICH8DH) : document number 313056-003, 313057-009, |
42 | * 82801HO (ICH8DO) : document number 313056-003, 313057-009, | 42 | * 82801HO (ICH8DO) : document number 313056-003, 313057-009, |
43 | * 82801HEM (ICH8M-E) : document number 313056-003, 313057-009, | 43 | * 82801HEM (ICH8M-E) : document number 313056-003, 313057-009, |
44 | * 82801IB (ICH9) : document number 316972-001, 316973-001, | 44 | * 82801IB (ICH9) : document number 316972-001, 316973-006, |
45 | * 82801IR (ICH9R) : document number 316972-001, 316973-001, | 45 | * 82801IR (ICH9R) : document number 316972-001, 316973-006, |
46 | * 82801IH (ICH9DH) : document number 316972-001, 316973-001, | 46 | * 82801IH (ICH9DH) : document number 316972-001, 316973-006, |
47 | * 82801IO (ICH9DO) : document number 316972-001, 316973-006, | ||
47 | * 6300ESB (6300ESB) : document number 300641-003, 300884-010, | 48 | * 6300ESB (6300ESB) : document number 300641-003, 300884-010, |
48 | * 631xESB (631xESB) : document number 313082-001, 313075-005, | 49 | * 631xESB (631xESB) : document number 313082-001, 313075-005, |
49 | * 632xESB (632xESB) : document number 313082-001, 313075-005 | 50 | * 632xESB (632xESB) : document number 313082-001, 313075-005 |
@@ -55,8 +56,8 @@ | |||
55 | 56 | ||
56 | /* Module and version information */ | 57 | /* Module and version information */ |
57 | #define DRV_NAME "iTCO_wdt" | 58 | #define DRV_NAME "iTCO_wdt" |
58 | #define DRV_VERSION "1.02" | 59 | #define DRV_VERSION "1.03" |
59 | #define DRV_RELDATE "26-Jul-2007" | 60 | #define DRV_RELDATE "30-Apr-2008" |
60 | #define PFX DRV_NAME ": " | 61 | #define PFX DRV_NAME ": " |
61 | 62 | ||
62 | /* Includes */ | 63 | /* Includes */ |
@@ -104,6 +105,7 @@ enum iTCO_chipsets { | |||
104 | TCO_ICH9, /* ICH9 */ | 105 | TCO_ICH9, /* ICH9 */ |
105 | TCO_ICH9R, /* ICH9R */ | 106 | TCO_ICH9R, /* ICH9R */ |
106 | TCO_ICH9DH, /* ICH9DH */ | 107 | TCO_ICH9DH, /* ICH9DH */ |
108 | TCO_ICH9DO, /* ICH9DO */ | ||
107 | TCO_631XESB, /* 631xESB/632xESB */ | 109 | TCO_631XESB, /* 631xESB/632xESB */ |
108 | }; | 110 | }; |
109 | 111 | ||
@@ -136,6 +138,7 @@ static struct { | |||
136 | {"ICH9", 2}, | 138 | {"ICH9", 2}, |
137 | {"ICH9R", 2}, | 139 | {"ICH9R", 2}, |
138 | {"ICH9DH", 2}, | 140 | {"ICH9DH", 2}, |
141 | {"ICH9DO", 2}, | ||
139 | {"631xESB/632xESB", 2}, | 142 | {"631xESB/632xESB", 2}, |
140 | {NULL,0} | 143 | {NULL,0} |
141 | }; | 144 | }; |
@@ -181,6 +184,7 @@ static struct pci_device_id iTCO_wdt_pci_tbl[] = { | |||
181 | { ITCO_PCI_DEVICE(0x2918, TCO_ICH9 )}, | 184 | { ITCO_PCI_DEVICE(0x2918, TCO_ICH9 )}, |
182 | { ITCO_PCI_DEVICE(0x2916, TCO_ICH9R )}, | 185 | { ITCO_PCI_DEVICE(0x2916, TCO_ICH9R )}, |
183 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH9_2, TCO_ICH9DH )}, | 186 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH9_2, TCO_ICH9DH )}, |
187 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH9_4, TCO_ICH9DO )}, | ||
184 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ESB2_0, TCO_631XESB)}, | 188 | { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ESB2_0, TCO_631XESB)}, |
185 | { ITCO_PCI_DEVICE(0x2671, TCO_631XESB)}, | 189 | { ITCO_PCI_DEVICE(0x2671, TCO_631XESB)}, |
186 | { ITCO_PCI_DEVICE(0x2672, TCO_631XESB)}, | 190 | { ITCO_PCI_DEVICE(0x2672, TCO_631XESB)}, |
diff --git a/drivers/watchdog/w83697hf_wdt.c b/drivers/watchdog/w83697hf_wdt.c index c622a0e6c9ae..528b882420b6 100644 --- a/drivers/watchdog/w83697hf_wdt.c +++ b/drivers/watchdog/w83697hf_wdt.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #define WATCHDOG_NAME "w83697hf/hg WDT" | 44 | #define WATCHDOG_NAME "w83697hf/hg WDT" |
45 | #define PFX WATCHDOG_NAME ": " | 45 | #define PFX WATCHDOG_NAME ": " |
46 | #define WATCHDOG_TIMEOUT 60 /* 60 sec default timeout */ | 46 | #define WATCHDOG_TIMEOUT 60 /* 60 sec default timeout */ |
47 | #define WATCHDOG_EARLY_DISABLE 1 /* Disable until userland kicks in */ | ||
47 | 48 | ||
48 | static unsigned long wdt_is_open; | 49 | static unsigned long wdt_is_open; |
49 | static char expect_close; | 50 | static char expect_close; |
@@ -56,12 +57,16 @@ MODULE_PARM_DESC(wdt_io, "w83697hf/hg WDT io port (default 0x2e, 0 = autodetect) | |||
56 | 57 | ||
57 | static int timeout = WATCHDOG_TIMEOUT; /* in seconds */ | 58 | static int timeout = WATCHDOG_TIMEOUT; /* in seconds */ |
58 | module_param(timeout, int, 0); | 59 | module_param(timeout, int, 0); |
59 | MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=255, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) "."); | 60 | MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=255 (default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); |
60 | 61 | ||
61 | static int nowayout = WATCHDOG_NOWAYOUT; | 62 | static int nowayout = WATCHDOG_NOWAYOUT; |
62 | module_param(nowayout, int, 0); | 63 | module_param(nowayout, int, 0); |
63 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 64 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); |
64 | 65 | ||
66 | static int early_disable = WATCHDOG_EARLY_DISABLE; | ||
67 | module_param(early_disable, int, 0); | ||
68 | MODULE_PARM_DESC(early_disable, "Watchdog gets disabled at boot time (default=" __MODULE_STRING(WATCHDOG_EARLY_DISABLE) ")"); | ||
69 | |||
65 | /* | 70 | /* |
66 | * Kernel methods. | 71 | * Kernel methods. |
67 | */ | 72 | */ |
@@ -140,7 +145,7 @@ w83697hf_init(void) | |||
140 | w83697hf_deselect_wdt(); | 145 | w83697hf_deselect_wdt(); |
141 | } | 146 | } |
142 | 147 | ||
143 | static int | 148 | static void |
144 | wdt_ping(void) | 149 | wdt_ping(void) |
145 | { | 150 | { |
146 | spin_lock(&io_lock); | 151 | spin_lock(&io_lock); |
@@ -150,10 +155,9 @@ wdt_ping(void) | |||
150 | 155 | ||
151 | w83697hf_deselect_wdt(); | 156 | w83697hf_deselect_wdt(); |
152 | spin_unlock(&io_lock); | 157 | spin_unlock(&io_lock); |
153 | return 0; | ||
154 | } | 158 | } |
155 | 159 | ||
156 | static int | 160 | static void |
157 | wdt_enable(void) | 161 | wdt_enable(void) |
158 | { | 162 | { |
159 | spin_lock(&io_lock); | 163 | spin_lock(&io_lock); |
@@ -164,10 +168,9 @@ wdt_enable(void) | |||
164 | 168 | ||
165 | w83697hf_deselect_wdt(); | 169 | w83697hf_deselect_wdt(); |
166 | spin_unlock(&io_lock); | 170 | spin_unlock(&io_lock); |
167 | return 0; | ||
168 | } | 171 | } |
169 | 172 | ||
170 | static int | 173 | static void |
171 | wdt_disable(void) | 174 | wdt_disable(void) |
172 | { | 175 | { |
173 | spin_lock(&io_lock); | 176 | spin_lock(&io_lock); |
@@ -178,7 +181,22 @@ wdt_disable(void) | |||
178 | 181 | ||
179 | w83697hf_deselect_wdt(); | 182 | w83697hf_deselect_wdt(); |
180 | spin_unlock(&io_lock); | 183 | spin_unlock(&io_lock); |
181 | return 0; | 184 | } |
185 | |||
186 | static unsigned char | ||
187 | wdt_running(void) | ||
188 | { | ||
189 | unsigned char t; | ||
190 | |||
191 | spin_lock(&io_lock); | ||
192 | w83697hf_select_wdt(); | ||
193 | |||
194 | t = w83697hf_get_reg(0xF4); /* Read timer */ | ||
195 | |||
196 | w83697hf_deselect_wdt(); | ||
197 | spin_unlock(&io_lock); | ||
198 | |||
199 | return t; | ||
182 | } | 200 | } |
183 | 201 | ||
184 | static int | 202 | static int |
@@ -397,7 +415,11 @@ wdt_init(void) | |||
397 | } | 415 | } |
398 | 416 | ||
399 | w83697hf_init(); | 417 | w83697hf_init(); |
400 | wdt_disable(); /* Disable watchdog until first use */ | 418 | if (early_disable) { |
419 | if (wdt_running()) | ||
420 | printk (KERN_WARNING PFX "Stopping previously enabled watchdog until userland kicks in\n"); | ||
421 | wdt_disable(); | ||
422 | } | ||
401 | 423 | ||
402 | if (wdt_set_heartbeat(timeout)) { | 424 | if (wdt_set_heartbeat(timeout)) { |
403 | wdt_set_heartbeat(WATCHDOG_TIMEOUT); | 425 | wdt_set_heartbeat(WATCHDOG_TIMEOUT); |