diff options
Diffstat (limited to 'drivers')
228 files changed, 2279 insertions, 2108 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index f1372de4ce7..4875f0149eb 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -68,6 +68,24 @@ config ACPI_PROCFS Say N to delete /proc/acpi/ files that have moved to /sys/ +config ACPI_PROC_EVENT + bool "Deprecated /proc/acpi/event support" + depends on PROC_FS + default y + ---help--- + A user-space daemon, acpi, typically read /proc/acpi/event + and handled all ACPI sub-system generated events. + + These events are now delivered to user-space via + either the input layer, or as netlink events. + + This build option enables the old code for legacy + user-space implementation. After some time, this will + be moved under CONFIG_ACPI_PROCFS, and then deleted. + + Say Y here to retain the old behaviour. Say N if your + user-space is newer than kernel 2.6.23 (September 2007). + config ACPI_AC tristate "AC Adapter" depends on X86 diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index d8b35093527..26d70702b31 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c @@ -204,7 +204,10 @@ static void acpi_ac_notify(acpi_handle handle, u32 event, void *data) case ACPI_NOTIFY_BUS_CHECK: case ACPI_NOTIFY_DEVICE_CHECK: acpi_ac_get_state(ac); - acpi_bus_generate_event(device, event, (u32) ac->state); + acpi_bus_generate_proc_event(device, event, (u32) ac->state); + acpi_bus_generate_netlink_event(device->pnp.device_class, + device->dev.bus_id, event, + (u32) ac->state); break; default: ACPI_DEBUG_PRINT((ACPI_DB_INFO, diff --git a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c index 86fd142f4bf..d915fec9bf6 100644 --- a/drivers/acpi/asus_acpi.c +++ b/drivers/acpi/asus_acpi.c @@ -1069,7 +1069,7 @@ static void asus_hotk_notify(acpi_handle handle, u32 event, void *data) hotk->brightness = (event & ~((u32) BR_DOWN)); } - acpi_bus_generate_event(hotk->device, event, + acpi_bus_generate_proc_event(hotk->device, event, hotk->event_count[event % 128]++); return; diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index d7b499fe0cd..9b2c0f74f86 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -113,7 +113,7 @@ struct acpi_battery_info { acpi_string oem_info; }; -enum acpi_battery_files { +enum acpi_battery_files{ ACPI_BATTERY_INFO = 0, ACPI_BATTERY_STATE, ACPI_BATTERY_ALARM, @@ -129,14 +129,13 @@ struct acpi_battery_flags { }; struct acpi_battery { + struct mutex mutex; struct acpi_device *device; struct acpi_battery_flags flags; struct acpi_buffer bif_data; struct acpi_buffer bst_data; - struct mutex lock; unsigned long alarm; unsigned long update_time[ACPI_BATTERY_NUMFILES]; - }; inline int acpi_battery_present(struct acpi_battery *battery) @@ -236,10 +235,10 @@ static int acpi_battery_get_info(struct acpi_battery *battery) return 0; /* Evaluate _BIF */ - mutex_lock(&battery->lock); - status = acpi_evaluate_object(acpi_battery_handle(battery), "_BIF", - NULL, &buffer); - mutex_unlock(&battery->lock); + + status = + acpi_evaluate_object(acpi_battery_handle(battery), "_BIF", NULL, + &buffer); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF")); return -ENODEV; @@ -286,10 +285,10 @@ static int acpi_battery_get_state(struct acpi_battery *battery) return 0; /* Evaluate _BST */ - mutex_lock(&battery->lock); - status = acpi_evaluate_object(acpi_battery_handle(battery), "_BST", - NULL, &buffer); - mutex_unlock(&battery->lock); + + status = + acpi_evaluate_object(acpi_battery_handle(battery), "_BST", NULL, + &buffer); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST")); return -ENODEV; @@ -337,10 +336,9 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery, arg0.integer.value = alarm; - mutex_lock(&battery->lock); - status = acpi_evaluate_object(acpi_battery_handle(battery), "_BTP", + status = + acpi_evaluate_object(acpi_battery_handle(battery), "_BTP", &arg_list, NULL); - mutex_unlock(&battery->lock); if (ACPI_FAILURE(status)) return -ENODEV; @@ -660,6 +658,8 @@ acpi_battery_write_alarm(struct file *file, if (!battery || (count > sizeof(alarm_string) - 1)) return -EINVAL; + mutex_lock(&battery->mutex); + result = acpi_battery_update(battery, 1, &update_result); if (result) { result = -ENODEV; @@ -688,7 +688,9 @@ acpi_battery_write_alarm(struct file *file, acpi_battery_check_result(battery, result); if (!result) - return count; + result = count; + + mutex_unlock(&battery->mutex); return result; } @@ -712,6 +714,8 @@ static int acpi_battery_read(int fid, struct seq_file *seq) int update_result = ACPI_BATTERY_NONE_UPDATE; int update = 0; + mutex_lock(&battery->mutex); + update = (get_seconds() - battery->update_time[fid] >= update_time); update = (update | battery->flags.update[fid]); @@ -729,6 +733,7 @@ static int acpi_battery_read(int fid, struct seq_file *seq) result = acpi_read_funcs[fid].print(seq, result); acpi_battery_check_result(battery, result); battery->flags.update[fid] = result; + mutex_unlock(&battery->mutex); return result; } @@ -867,8 +872,11 @@ static void acpi_battery_notify(acpi_handle handle, u32 event, void *data) case ACPI_NOTIFY_DEVICE_CHECK: device = battery->device; acpi_battery_notify_update(battery); - acpi_bus_generate_event(device, event, + acpi_bus_generate_proc_event(device, event, acpi_battery_present(battery)); + acpi_bus_generate_netlink_event(device->pnp.device_class, + device->dev.bus_id, event, + acpi_battery_present(battery)); break; default: ACPI_DEBUG_PRINT((ACPI_DB_INFO, @@ -892,7 +900,10 @@ static int acpi_battery_add(struct acpi_device *device) if (!battery) return -ENOMEM; - mutex_init(&battery->lock); + mutex_init(&battery->mutex); + + mutex_lock(&battery->mutex); + battery->device = device; strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME); strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS); @@ -928,6 +939,7 @@ static int acpi_battery_add(struct acpi_device *device) kfree(battery); } + mutex_unlock(&battery->mutex); return result; } @@ -942,6 +954,8 @@ static int acpi_battery_remove(struct acpi_device *device, int type) battery = acpi_driver_data(device); + mutex_lock(&battery->mutex); + status = acpi_remove_notify_handler(device->handle, ACPI_ALL_NOTIFY, acpi_battery_notify); @@ -952,7 +966,9 @@ static int acpi_battery_remove(struct acpi_device *device, int type) kfree(battery->bst_data.pointer); - mutex_destroy(&battery->lock); + mutex_unlock(&battery->mutex); + + mutex_destroy(&battery->mutex); kfree(battery); diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 6b2658c9624..9ba778a2b48 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -276,6 +276,7 @@ EXPORT_SYMBOL(acpi_bus_set_power); Event Management -------------------------------------------------------------------------- */ +#ifdef CONFIG_ACPI_PROC_EVENT static DEFINE_SPINLOCK(acpi_bus_event_lock); LIST_HEAD(acpi_bus_event_list); @@ -283,7 +284,7 @@ DECLARE_WAIT_QUEUE_HEAD(acpi_bus_event_queue); extern int event_is_open; -int acpi_bus_generate_event(struct acpi_device *device, u8 type, int data) +int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data) { struct acpi_bus_event *event = NULL; unsigned long flags = 0; @@ -292,10 +293,6 @@ int acpi_bus_generate_event(struct acpi_device *device, u8 type, int data) if (!device) return -EINVAL; - if (acpi_bus_generate_genetlink_event(device, type, data)) - printk(KERN_WARNING PREFIX - "Failed to generate an ACPI event via genetlink!\n"); - /* drop event on the floor if no one's listening */ if (!event_is_open) return 0; @@ -318,7 +315,7 @@ int acpi_bus_generate_event(struct acpi_device *device, u8 type, int data) return 0; } -EXPORT_SYMBOL(acpi_bus_generate_event); +EXPORT_SYMBOL(acpi_bus_generate_proc_event); int acpi_bus_receive_event(struct acpi_bus_event *event) { @@ -364,6 +361,7 @@ int acpi_bus_receive_event(struct acpi_bus_event *event) } EXPORT_SYMBOL(acpi_bus_receive_event); +#endif /* CONFIG_ACPI_PROC_EVENT */ /* -------------------------------------------------------------------------- Notification Handling diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index 540581338ef..2e79a3395ec 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c @@ -284,7 +284,7 @@ static void acpi_button_notify(acpi_handle handle, u32 event, void *data) } input_sync(input); - acpi_bus_generate_event(button->device, event, + acpi_bus_generate_proc_event(button->device, event, ++button->pushed); break; default: diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 56bee9e065c..43749c86861 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -696,14 +696,6 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval) return AE_CTRL_TERMINATE; } -static void ec_remove_handlers(struct acpi_ec *ec) -{ - acpi_remove_address_space_handler(ec->handle, - ACPI_ADR_SPACE_EC, - &acpi_ec_space_handler); - acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler); -} - static int acpi_ec_add(struct acpi_device *device) { struct acpi_ec *ec = NULL; @@ -727,13 +719,16 @@ static int acpi_ec_add(struct acpi_device *device) /* Check if we found the boot EC */ if (boot_ec) { if (boot_ec->gpe == ec->gpe) { - ec_remove_handlers(boot_ec); - mutex_destroy(&boot_ec->lock); - kfree(boot_ec); - first_ec = boot_ec = NULL; + /* We might have incorrect info for GL at boot time */ + mutex_lock(&boot_ec->lock); + boot_ec->global_lock = ec->global_lock; + /* Copy handlers from new ec into boot ec */ + list_splice(&ec->list, &boot_ec->list); + mutex_unlock(&boot_ec->lock); + kfree(ec); + ec = boot_ec; } - } - if (!first_ec) + } else first_ec = ec; ec->handle = device->handle; acpi_driver_data(device) = ec; @@ -762,6 +757,9 @@ static int acpi_ec_remove(struct acpi_device *device, int type) if (ec == first_ec) first_ec = NULL; + /* Don't touch boot EC */ + if (boot_ec != ec) + kfree(ec); return 0; } @@ -825,7 +823,9 @@ static int acpi_ec_start(struct acpi_device *device) if (!ec) return -EINVAL; - ret = ec_install_handlers(ec); + /* Boot EC is already working */ + if (ec != boot_ec) + ret = ec_install_handlers(ec); /* EC is fully operational, allow queries */ atomic_set(&ec->query_pending, 0); @@ -835,6 +835,7 @@ static int acpi_ec_start(struct acpi_device *device) static int acpi_ec_stop(struct acpi_device *device, int type) { + acpi_status status; struct acpi_ec *ec; if (!device) @@ -843,7 +844,21 @@ static int acpi_ec_stop(struct acpi_device *device, int type) ec = acpi_driver_data(device); if (!ec) return -EINVAL; - ec_remove_handlers(ec); + + /* Don't touch boot EC */ + if (ec == boot_ec) + return 0; + + status = acpi_remove_address_space_handler(ec->handle, + ACPI_ADR_SPACE_EC, + &acpi_ec_space_handler); + if (ACPI_FAILURE(status)) + return -ENODEV; + + status = acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler); + if (ACPI_FAILURE(status)) + return -ENODEV; + return 0; } diff --git a/drivers/acpi/event.c b/drivers/acpi/event.c index 95637a4ff78..a2b9304596c 100644 --- a/drivers/acpi/event.c +++ b/drivers/acpi/event.c @@ -17,6 +17,7 @@ #define _COMPONENT ACPI_SYSTEM_COMPONENT ACPI_MODULE_NAME("event"); +#ifdef CONFIG_ACPI_PROC_EVENT /* Global vars for handling event proc entry */ static DEFINE_SPINLOCK(acpi_system_event_lock); int event_is_open = 0; @@ -106,6 +107,7 @@ static const struct file_operations acpi_system_event_ops = { .release = acpi_system_close_event, .poll = acpi_system_poll_event, }; +#endif /* CONFIG_ACPI_PROC_EVENT */ #ifdef CONFIG_NET static unsigned int acpi_event_seqnum; @@ -147,7 +149,8 @@ static struct genl_multicast_group acpi_event_mcgrp = { .name = ACPI_GENL_MCAST_GROUP_NAME, }; -int acpi_bus_generate_genetlink_event(struct acpi_device *device, +int acpi_bus_generate_netlink_event(const char *device_class, + const char *bus_id, u8 type, int data) { struct sk_buff *skb; @@ -191,8 +194,8 @@ int acpi_bus_generate_genetlink_event(struct acpi_device *device, memset(event, 0, sizeof(struct acpi_genl_event)); - strcpy(event->device_class, device->pnp.device_class); - strcpy(event->bus_id, device->dev.bus_id); + strcpy(event->device_class, device_class); + strcpy(event->bus_id, bus_id); event->type = type; event->data = data; @@ -211,6 +214,8 @@ int acpi_bus_generate_genetlink_event(struct acpi_device *device, return 0; } +EXPORT_SYMBOL(acpi_bus_generate_netlink_event); + static int acpi_event_genetlink_init(void) { int result; @@ -228,12 +233,15 @@ static int acpi_event_genetlink_init(void) } #else -int acpi_bus_generate_genetlink_event(struct acpi_device *device, u8 type, - int data) +int acpi_bus_generate_netlink_event(const char *device_class, + const char *bus_id, + u8 type, int data) { return 0; } +EXPORT_SYMBOL(acpi_generate_netlink_event); + static int acpi_event_genetlink_init(void) { return -ENODEV; @@ -242,7 +250,9 @@ static int acpi_event_genetlink_init(void) static int __init acpi_event_init(void) { +#ifdef CONFIG_ACPI_PROC_EVENT struct proc_dir_entry *entry; +#endif int error = 0; if (acpi_disabled) @@ -254,12 +264,14 @@ static int __init acpi_event_init(void) printk(KERN_WARNING PREFIX "Failed to create genetlink family for ACPI event\n"); +#ifdef CONFIG_ACPI_PROC_EVENT /* 'event' [R] */ entry = create_proc_entry("event", S_IRUSR, acpi_root_dir); if (entry) entry->proc_fops = &acpi_system_event_ops; else return -ENODEV; +#endif return 0; } diff --git a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c index 76c525dc590..cf69c0040a3 100644 --- a/drivers/acpi/hardware/hwsleep.c +++ b/drivers/acpi/hardware/hwsleep.c @@ -576,13 +576,10 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state) ACPI_EXCEPTION((AE_INFO, status, "During Method _BFS")); } - status = acpi_evaluate_object(NULL, METHOD_NAME__WAK, &arg_list, NULL); - if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { - ACPI_EXCEPTION((AE_INFO, status, "During Method _WAK")); - } - /* TBD: _WAK "sometimes" returns stuff - do we want to look at it? */ - /* + * GPEs must be enabled before _WAK is called as GPEs + * might get fired there + * * Restore the GPEs: * 1) Disable/Clear all GPEs * 2) Enable all runtime GPEs @@ -591,13 +588,19 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state) if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } - acpi_gbl_system_awake_and_running = TRUE; - status = acpi_hw_enable_all_runtime_gpes(); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } + status = acpi_evaluate_object(NULL, METHOD_NAME__WAK, &arg_list, NULL); + if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { + ACPI_EXCEPTION((AE_INFO, status, "During Method _WAK")); + } + /* TBD: _WAK "sometimes" returns stuff - do we want to look at it? */ + + acpi_gbl_system_awake_and_running = TRUE; + /* Enable power button */ (void) diff --git a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c index ab65b2c2560..f39fbc6b923 100644 --- a/drivers/acpi/namespace/nsxfeval.c +++ b/drivers/acpi/namespace/nsxfeval.c @@ -540,7 +540,7 @@ acpi_ns_get_device_callback(acpi_handle obj_handle, ******************************************************************************/ acpi_status -acpi_get_devices(char *HID, +acpi_get_devices(const char *HID, acpi_walk_callback user_function, void *context, void **return_value) { diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 498422343f3..e944aaee4e0 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -698,16 +698,23 @@ static void acpi_processor_notify(acpi_handle handle, u32 event, void *data) switch (event) { case ACPI_PROCESSOR_NOTIFY_PERFORMANCE: acpi_processor_ppc_has_changed(pr); - acpi_bus_generate_event(device, event, + acpi_bus_generate_proc_event(device, event, pr->performance_platform_limit); + acpi_bus_generate_netlink_event(device->pnp.device_class, + device->dev.bus_id, event, + pr->performance_platform_limit); break; case ACPI_PROCESSOR_NOTIFY_POWER: acpi_processor_cst_has_changed(pr); - acpi_bus_generate_event(device, event, 0); + acpi_bus_generate_proc_event(device, event, 0); + acpi_bus_generate_netlink_event(device->pnp.device_class, + device->dev.bus_id, event, 0); break; case ACPI_PROCESSOR_NOTIFY_THROTTLING: acpi_processor_tstate_has_changed(pr); - acpi_bus_generate_event(device, event, 0); + acpi_bus_generate_proc_event(device, event, 0); + acpi_bus_generate_netlink_event(device->pnp.device_class, + device->dev.bus_id, event, 0); default: ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Unsupported event [0x%x]\n", event)); diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index a8634a0655f..d9b8af763e1 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -63,6 +63,7 @@ ACPI_MODULE_NAME("processor_idle"); #define ACPI_PROCESSOR_FILE_POWER "power" #define US_TO_PM_TIMER_TICKS(t) ((t * (PM_TIMER_FREQUENCY/1000)) / 1000) +#define PM_TIMER_TICK_NS (1000000000ULL/PM_TIMER_FREQUENCY) #define C2_OVERHEAD 4 /* 1us (3.579 ticks per us) */ #define C3_OVERHEAD 4 /* 1us (3.579 ticks per us) */ static void (*pm_idle_save) (void) __read_mostly; @@ -462,6 +463,9 @@ static void acpi_processor_idle(void) * TBD: Can't get time duration while in C1, as resumes * go to an ISR rather than here. Need to instrument * base interrupt handler. + * + * Note: the TSC better not stop in C1, sched_clock() will + * skew otherwise. */ sleep_ticks = 0xFFFFFFFF; break; @@ -469,6 +473,8 @@ static void acpi_processor_idle(void) case ACPI_STATE_C2: /* Get start time (ticks) */ t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); + /* Tell the scheduler that we are going deep-idle: */ + sched_clock_idle_sleep_event(); /* Invoke C2 */ acpi_state_timer_broadcast(pr, cx, 1); acpi_cstate_enter(cx); @@ -479,17 +485,22 @@ static void acpi_processor_idle(void) /* TSC halts in C2, so notify users */ mark_tsc_unstable("possible TSC halt in C2"); #endif + /* Compute time (ticks) that we were actually asleep */ + sleep_ticks = ticks_elapsed(t1, t2); + + /* Tell the scheduler how much we idled: */ + sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS); + /* Re-enable interrupts */ local_irq_enable(); + /* Do not account our idle-switching overhead: */ + sleep_ticks -= cx->latency_ticks + C2_OVERHEAD; + current_thread_info()->status |= TS_POLLING; - /* Compute time (ticks) that we were actually asleep */ - sleep_ticks = - ticks_elapsed(t1, t2) - cx->latency_ticks - C2_OVERHEAD; acpi_state_timer_broadcast(pr, cx, 0); break; case ACPI_STATE_C3: - /* * disable bus master * bm_check implies we need ARB_DIS @@ -518,6 +529,8 @@ static void acpi_processor_idle(void) t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); /* Invoke C3 */ acpi_state_timer_broadcast(pr, cx, 1); + /* Tell the scheduler that we are going deep-idle: */ + sched_clock_idle_sleep_event(); acpi_cstate_enter(cx); /* Get end time (ticks) */ t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); @@ -531,12 +544,17 @@ static void acpi_processor_idle(void) /* TSC halts in C3, so notify users */ mark_tsc_unstable("TSC halts in C3"); #endif + /* Compute time (ticks) that we were actually asleep */ + sleep_ticks = ticks_elapsed(t1, t2); + /* Tell the scheduler how much we idled: */ + sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS); + /* Re-enable interrupts */ local_irq_enable(); + /* Do not account our idle-switching overhead: */ + sleep_ticks -= cx->latency_ticks + C3_OVERHEAD; + current_thread_info()->status |= TS_POLLING; - /* Compute time (ticks) that we were actually asleep */ - sleep_ticks = - ticks_elapsed(t1, t2) - cx->latency_ticks - C3_OVERHEAD; acpi_state_timer_broadcast(pr, cx, 0); break; diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index 82c3a550016..a578986e321 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c @@ -440,11 +440,12 @@ static int acpi_sbs_generate_event(struct acpi_device *device, strcpy(acpi_device_bid(device), bid); strcpy(acpi_device_class(device), class); - result = acpi_bus_generate_event(device, event, state); + result = acpi_bus_generate_proc_event(device, event, state); strcpy(acpi_device_bid(device), bid_saved); strcpy(acpi_device_class(device), class_saved); + acpi_bus_generate_netlink_event(class, bid, event, state); return result; } diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index be74347d135..64620d66874 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -35,8 +35,9 @@ struct acpi_device_bus_id{ * e.g. on a device with hid:IBM0001 and cid:ACPI0001 you get: * char *modalias: "acpi:IBM0001:ACPI0001" */ -int create_modalias(struct acpi_device *acpi_dev, char *modalias, int size){ - +static int create_modalias(struct acpi_device *acpi_dev, char *modalias, + int size) +{ int len; if (!acpi_dev->flags.hardware_id) diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c index e8cff5dd4cb..c52ade816fb 100644 --- a/drivers/acpi/sleep/main.c +++ b/drivers/acpi/sleep/main.c @@ -305,7 +305,7 @@ int acpi_pm_device_sleep_state(struct device *dev, int wake, int *d_min_p) unsigned long d_min, d_max; if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) { - printk(KERN_ERR "ACPI handle has no context!\n"); + printk(KERN_DEBUG "ACPI handle has no context!\n"); return -ENODEV; } diff --git a/drivers/acpi/tables/tbutils.c b/drivers/acpi/tables/tbutils.c index 1da64b4518c..8cc9492ffbf 100644 --- a/drivers/acpi/tables/tbutils.c +++ b/drivers/acpi/tables/tbutils.c @@ -51,6 +51,65 @@ ACPI_MODULE_NAME("tbutils") static acpi_physical_address acpi_tb_get_root_table_entry(u8 * table_entry, acpi_native_uint table_entry_size); +/******************************************************************************* + * + * FUNCTION: acpi_tb_check_xsdt + * + * PARAMETERS: address - Pointer to the XSDT + * + * RETURN: status + * AE_OK - XSDT is okay + * AE_NO_MEMORY - can't map XSDT + * AE_INVALID_TABLE_LENGTH - invalid table length + * AE_NULL_ENTRY - XSDT has NULL entry + * + * DESCRIPTION: validate XSDT +******************************************************************************/ + +static acpi_status +acpi_tb_check_xsdt(acpi_physical_address address) +{ + struct acpi_table_header *table; + u32 length; + u64 xsdt_entry_address; + u8 *table_entry; + u32 table_count; + int i; + + table = acpi_os_map_memory(address, sizeof(struct acpi_table_header)); + if (!table) + return AE_NO_MEMORY; + + length = table->length; + acpi_os_unmap_memory(table, sizeof(struct acpi_table_header)); + if (length < sizeof(struct acpi_table_header)) + return AE_INVALID_TABLE_LENGTH; + + table = acpi_os_map_memory(address, length); + if (!table) + return AE_NO_MEMORY; + + /* Calculate the number of tables described in XSDT */ + table_count = + (u32) ((table->length - + sizeof(struct acpi_table_header)) / sizeof(u64)); + table_entry = + ACPI_CAST_PTR(u8, table) + sizeof(struct acpi_table_header); + for (i = 0; i < table_count; i++) { + ACPI_MOVE_64_TO_64(&xsdt_entry_address, table_entry); + if (!xsdt_entry_address) { + /* XSDT has NULL entry */ + break; + } + table_entry += sizeof(u64); + } + acpi_os_unmap_memory(table, length); + + if (i < table_count) + return AE_NULL_ENTRY; + else + return AE_OK; +} /******************************************************************************* * @@ -341,6 +400,7 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags) u32 table_count; struct acpi_table_header *table; acpi_physical_address address; + acpi_physical_address rsdt_address; u32 length; u8 *table_entry; acpi_status status; @@ -369,6 +429,8 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags) */ address = (acpi_physical_address) rsdp->xsdt_physical_address; table_entry_size = sizeof(u64); + rsdt_address = (acpi_physical_address) + rsdp->rsdt_physical_address; } else { /* Root table is an RSDT (32-bit physical addresses) */ @@ -382,6 +444,15 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags) */ acpi_os_unmap_memory(rsdp, sizeof(struct acpi_table_rsdp)); + if (table_entry_size == sizeof(u64)) { + if (acpi_tb_check_xsdt(address) == AE_NULL_ENTRY) { + /* XSDT has NULL entry, RSDT is used */ + address = rsdt_address; + table_entry_size = sizeof(u32); + ACPI_WARNING((AE_INFO, "BIOS XSDT has NULL entry," + "using RSDT")); + } + } /* Map the RSDT/XSDT table header to get the full table length */ table = acpi_os_map_memory(address, sizeof(struct acpi_table_header)); diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 1e06159fd9c..bc6d5866ef9 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -77,23 +77,27 @@ MODULE_LICENSE("GPL"); static int act; module_param(act, int, 0644); -MODULE_PARM_DESC(act, "Disable or override all lowest active trip points.\n"); +MODULE_PARM_DESC(act, "Disable or override all lowest active trip points."); + +static int crt; +module_param(crt, int, 0644); +MODULE_PARM_DESC(crt, "Disable or lower all critical trip points."); static int tzp; module_param(tzp, int, 0444); -MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds.\n"); +MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds."); static int nocrt; module_param(nocrt, int, 0); -MODULE_PARM_DESC(nocrt, "Set to disable action on ACPI thermal zone critical and hot trips.\n"); +MODULE_PARM_DESC(nocrt, "Set to take no action upon ACPI thermal zone critical trips points."); static int off; module_param(off, int, 0); -MODULE_PARM_DESC(off, "Set to disable ACPI thermal support.\n"); +MODULE_PARM_DESC(off, "Set to disable ACPI thermal support."); static int psv; module_param(psv, int, 0644); -MODULE_PARM_DESC(psv, "Disable or override all passive trip points.\n"); +MODULE_PARM_DESC(psv, "Disable or override all passive trip points."); static int acpi_thermal_add(struct acpi_device *device); static int acpi_thermal_remove(struct acpi_device *device, int type); @@ -340,6 +344,20 @@ static int acpi_thermal_get_trip_points(struct acpi_thermal *tz) tz->trips.critical.temperature)); } + if (tz->trips.critical.flags.valid == 1) { + if (crt == -1) { + tz->trips.critical.flags.valid = 0; + } else if (crt > 0) { + unsigned long crt_k = CELSIUS_TO_KELVIN(crt); + + /* + * Allow override to lower critical threshold + */ + if (crt_k < tz->trips.critical.temperature) + tz->trips.critical.temperature = crt_k; + } + } + /* Critical Sleep (optional) */ status = @@ -485,8 +503,12 @@ static int acpi_thermal_critical(struct acpi_thermal *tz) printk(KERN_EMERG "Critical temperature reached (%ld C), shutting down.\n", KELVIN_TO_CELSIUS(tz->temperature)); - acpi_bus_generate_event(tz->device, ACPI_THERMAL_NOTIFY_CRITICAL, + acpi_bus_generate_proc_event(tz->device, ACPI_THERMAL_NOTIFY_CRITICAL, tz->trips.critical.flags.enabled); + acpi_bus_generate_netlink_event(tz->device->pnp.device_class, + tz->device->dev.bus_id, + ACPI_THERMAL_NOTIFY_CRITICAL, + tz->trips.critical.flags.enabled); orderly_poweroff(true); @@ -504,8 +526,12 @@ static int acpi_thermal_hot(struct acpi_thermal *tz) } else if (tz->trips.hot.flags.enabled) tz->trips.hot.flags.enabled = 0; - acpi_bus_generate_event(tz->device, ACPI_THERMAL_NOTIFY_HOT, + acpi_bus_generate_proc_event(tz->device, ACPI_THERMAL_NOTIFY_HOT, tz->trips.hot.flags.enabled); + acpi_bus_generate_netlink_event(tz->device->pnp.device_class, + tz->device->dev.bus_id, + ACPI_THERMAL_NOTIFY_HOT, + tz->trips.hot.flags.enabled); /* TBD: Call user-mode "sleep(S4)" function */ @@ -1067,9 +1093,9 @@ static int acpi_thermal_add_fs(struct acpi_device *device) entry->owner = THIS_MODULE; } - /* 'trip_points' [R/W] */ + /* 'trip_points' [R] */ entry = create_proc_entry(ACPI_THERMAL_FILE_TRIP_POINTS, - S_IFREG | S_IRUGO | S_IWUSR, + S_IRUGO, acpi_device_dir(device)); if (!entry) return -ENODEV; @@ -1149,12 +1175,16 @@ static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data) case ACPI_THERMAL_NOTIFY_THRESHOLDS: acpi_thermal_get_trip_points(tz); acpi_thermal_check(tz); - acpi_bus_generate_event(device, event, 0); + acpi_bus_generate_proc_event(device, event, 0); + acpi_bus_generate_netlink_event(device->pnp.device_class, + device->dev.bus_id, event, 0); break; case ACPI_THERMAL_NOTIFY_DEVICES: if (tz->flags.devices) acpi_thermal_get_devices(tz); - acpi_bus_generate_event(device, event, 0); + acpi_bus_generate_proc_event(device, event, 0); + acpi_bus_generate_netlink_event(device->pnp.device_class, + device->dev.bus_id, event, 0); break; default: ACPI_DEBUG_PRINT((ACPI_DB_INFO, @@ -1339,6 +1369,13 @@ static int thermal_act(struct dmi_system_id *d) { } return 0; } +static int thermal_nocrt(struct dmi_system_id *d) { + + printk(KERN_NOTICE "ACPI: %s detected: " + "disabling all critical thermal trip point actions.\n", d->ident); + nocrt = 1; + return 0; +} static int thermal_tzp(struct dmi_system_id *d) { if (tzp == 0) { @@ -1387,6 +1424,14 @@ static struct dmi_system_id thermal_dmi_table[] __initdata = { DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"), }, }, + { + .callback = thermal_nocrt, + .ident = "Gigabyte GA-7ZX", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co., Ltd."), + DMI_MATCH(DMI_BOARD_NAME, "7ZX"), + }, + }, {} }; #endif /* CONFIG_DMI */ diff --git a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c index 1621655d6e2..93ea8290b4f 100644 --- a/drivers/acpi/utilities/utglobal.c +++ b/drivers/acpi/utilities/utglobal.c @@ -126,6 +126,7 @@ const char *acpi_format_exception(acpi_status status) "Unknown exception code: 0x%8.8X", status)); exception = "UNKNOWN_STATUS_CODE"; + dump_stack(); } return (ACPI_CAST_PTR(const char, exception)); diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index d9870194198..3c9bb85a6a9 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -31,7 +31,7 @@ #include <linux/list.h> #include <linux/proc_fs.h> #include <linux/seq_file.h> - +#include <linux/input.h> #include <linux/backlight.h> #include <linux/video_output.h> #include <asm/uaccess.h> @@ -138,6 +138,8 @@ struct acpi_video_bus { struct semaphore sem; struct list_head video_device_list; struct proc_dir_entry *dir; + struct input_dev *input; + char phys[32]; /* for input device */ }; struct acpi_video_device_flags { @@ -1764,6 +1766,9 @@ static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data) { struct acpi_video_bus *video = data; struct acpi_device *device = NULL; + struct input_dev *input; + int keycode; + printk("video bus notify\n"); @@ -1771,11 +1776,13 @@ static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data) return; device = video->device; + input = video->input; switch (event) { case ACPI_VIDEO_NOTIFY_SWITCH: /* User requested a switch, * most likely via hotkey. */ - acpi_bus_generate_event(device, event, 0); + acpi_bus_generate_proc_event(device, event, 0); + keycode = KEY_SWITCHVIDEOMODE; break; case ACPI_VIDEO_NOTIFY_PROBE: /* User plugged in or removed a video @@ -1783,22 +1790,38 @@ static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data) acpi_video_device_enumerate(video); acpi_video_device_rebind(video); acpi_video_switch_output(video, event); - acpi_bus_generate_event(device, event, 0); + acpi_bus_generate_proc_event(device, event, 0); + keycode = KEY_SWITCHVIDEOMODE; break; case ACPI_VIDEO_NOTIFY_CYCLE: /* Cycle Display output hotkey pressed. */ + acpi_video_switch_output(video, event); + acpi_bus_generate_proc_event(device, event, 0); + keycode = KEY_SWITCHVIDEOMODE; + break; case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT: /* Next Display output hotkey pressed. */ + acpi_video_switch_output(video, event); + acpi_bus_generate_proc_event(device, event, 0); + keycode = KEY_VIDEO_NEXT; + break; case ACPI_VIDEO_NOTIFY_PREV_OUTPUT: /* previous Display output hotkey pressed. */ acpi_video_switch_output(video, event); - acpi_bus_generate_event(device, event, 0); + acpi_bus_generate_proc_event(device, event, 0); + keycode = KEY_VIDEO_PREV; break; default: + keycode = KEY_UNKNOWN; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Unsupported event [0x%x]\n", event)); break; } + input_report_key(input, keycode, 1); + input_sync(input); + input_report_key(input, keycode, 0); + input_sync(input); + return; } @@ -1806,38 +1829,65 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data) { struct acpi_video_device *video_device = data; struct acpi_device *device = NULL; + struct acpi_video_bus *bus; + struct input_dev *input; + int keycode; if (!video_device) return; device = video_device->dev; + bus = video_device->video; + input = bus->input; switch (event) { - case ACPI_VIDEO_NOTIFY_SWITCH: /* change in status (cycle output device) */ - case ACPI_VIDEO_NOTIFY_PROBE: /* change in status (output device status) */ - acpi_bus_generate_event(device, event, 0); - break; case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS: /* Cycle brightness */ + acpi_video_switch_brightness(video_device, event); + acpi_bus_generate_proc_event(device, event, 0); + keycode = KEY_BRIGHTNESS_CYCLE; + break; case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS: /* Increase brightness */ + acpi_video_switch_brightness(video_device, event); + acpi_bus_generate_proc_event(device, event, 0); + keycode = KEY_BRIGHTNESSUP; + break; case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS: /* Decrease brightness */ + acpi_video_switch_brightness(video_device, event); + acpi_bus_generate_proc_event(device, event, 0); + keycode = KEY_BRIGHTNESSDOWN; + break; case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: /* zero brightnesss */ + acpi_video_switch_brightness(video_device, event); + acpi_bus_generate_proc_event(device, event, 0); + keycode = KEY_BRIGHTNESS_ZERO; + break; case ACPI_VIDEO_NOTIFY_DISPLAY_OFF: /* display device off */ acpi_video_switch_brightness(video_device, event); - acpi_bus_generate_event(device, event, 0); + acpi_bus_generate_proc_event(device, event, 0); + keycode = KEY_DISPLAY_OFF; break; default: + keycode = KEY_UNKNOWN; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Unsupported event [0x%x]\n", event)); break; } + + input_report_key(input, keycode, 1); + input_sync(input); + input_report_key(input, keycode, 0); + input_sync(input); + return; } +static int instance; static int acpi_video_bus_add(struct acpi_device *device) { int result = 0; acpi_status status = 0; struct acpi_video_bus *video = NULL; + struct input_dev *input; if (!device) @@ -1847,6 +1897,13 @@ static int acpi_video_bus_add(struct acpi_device *device) if (!video) return -ENOMEM; + /* a hack to fix the duplicate name "VID" problem on T61 */ + if (!strcmp(device->pnp.bus_id, "VID")) { + if (instance) + device->pnp.bus_id[3] = '0' + instance; + instance ++; + } + video->device = device; strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME); strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS); @@ -1881,6 +1938,39 @@ static int acpi_video_bus_add(struct acpi_device *device) goto end; } + + video->input = input = input_allocate_device(); + + snprintf(video->phys, sizeof(video->phys), + "%s/video/input0", acpi_device_hid(video->device)); + + input->name = acpi_device_name(video->device); + input->phys = video->phys; + input->id.bustype = BUS_HOST; + input->id.product = 0x06; + input->evbit[0] = BIT(EV_KEY); + set_bit(KEY_SWITCHVIDEOMODE, input->keybit); + set_bit(KEY_VIDEO_NEXT, input->keybit); + set_bit(KEY_VIDEO_PREV, input->keybit); + set_bit(KEY_BRIGHTNESS_CYCLE, input->keybit); + set_bit(KEY_BRIGHTNESSUP, input->keybit); + set_bit(KEY_BRIGHTNESSDOWN, input->keybit); + set_bit(KEY_BRIGHTNESS_ZERO, input->keybit); + set_bit(KEY_DISPLAY_OFF, input->keybit); + set_bit(KEY_UNKNOWN, input->keybit); + result = input_register_device(input); + if (result) { + acpi_remove_notify_handler(video->device->handle, + ACPI_DEVICE_NOTIFY, + acpi_video_bus_notify); + acpi_video_bus_stop_devices(video); + acpi_video_bus_put_devices(video); + kfree(video->attached_array); + acpi_video_bus_remove_fs(device); + goto end; + } + + printk(KERN_INFO PREFIX "%s [%s] (multi-head: %s rom: %s post: %s)\n", ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device), video->flags.multihead ? "yes" : "no", @@ -1914,6 +2004,7 @@ static int acpi_video_bus_remove(struct acpi_device *device, int type) acpi_video_bus_put_devices(video); acpi_video_bus_remove_fs(device); + input_unregister_device(video->input); kfree(video->attached_array); kfree(video); diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index a78832ea81f..071d274afaa 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -436,7 +436,7 @@ static const struct piix_map_db ich8_map_db = { /* PM PS SM SS MAP */ { P0, P2, P1, P3 }, /* 00b (hardwired when in AHCI) */ { RV, RV, RV, RV }, - { IDE, IDE, NA, NA }, /* 10b (IDE mode) */ + { P0, P2, IDE, IDE }, /* 10b (IDE mode) */ { RV, RV, RV, RV }, }, }; @@ -901,6 +901,13 @@ static int piix_broken_suspend(void) }, }, { + .ident = "TECRA M7", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME, "TECRA M7"), + }, + }, + { .ident = "Satellite U205", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 60e78bef469..2ad4dda6d4a 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -1723,7 +1723,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, tf.protocol = ATA_PROT_NODATA; tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0); - if (err_mask) { + if (err_mask && id[2] != 0x738c) { rc = -EIO; reason = "SPINUP failed"; goto err_out; @@ -3700,11 +3700,16 @@ int ata_dev_revalidate(struct ata_device *dev, unsigned int readid_flags) goto fail; /* verify n_sectors hasn't changed */ - if (dev->class == ATA_DEV_ATA && dev->n_sectors != n_sectors) { + if (dev->class == ATA_DEV_ATA && n_sectors && + dev->n_sectors != n_sectors) { ata_dev_printk(dev, KERN_INFO, "n_sectors mismatch " "%llu != %llu\n", (unsigned long long)n_sectors, (unsigned long long)dev->n_sectors); + + /* restore original n_sectors */ + dev->n_sectors = n_sectors; + rc = -ENODEV; goto fail; } diff --git a/drivers/ata/pata_artop.c b/drivers/ata/pata_artop.c index ce589d96ca4..b5352ebecef 100644 --- a/drivers/ata/pata_artop.c +++ b/drivers/ata/pata_artop.c @@ -2,6 +2,7 @@ * pata_artop.c - ARTOP ATA controller driver * * (C) 2006 Red Hat <alan@redhat.com> + * (C) 2007 Bartlomiej Zolnierkiewicz * * Based in part on drivers/ide/pci/aec62xx.c * Copyright (C) 1999-2002 Andre Hedrick <andre@linux-ide.org> @@ -28,7 +29,7 @@ #include <linux/ata.h> #define DRV_NAME "pata_artop" -#define DRV_VERSION "0.4.3" +#define DRV_VERSION "0.4.4" /* * The ARTOP has 33 Mhz and "over clocked" timing tables. Until we @@ -430,7 +431,7 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id) .udma_mask = ATA_UDMA4, .port_ops = &artop6260_ops, }; - static const struct ata_port_info info_626x_fast = { + static const struct ata_port_info info_628x = { .sht = &artop_sht, .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, /* pio0-4 */ @@ -438,6 +439,14 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id) .udma_mask = ATA_UDMA5, .port_ops = &artop6260_ops, }; + static const struct ata_port_info info_628x_fast = { + .sht = &artop_sht, + .flags = ATA_FLAG_SLAVE_POSS, + .pio_mask = 0x1f, /* pio0-4 */ + .mwdma_mask = 0x07, /* mwdma0-2 */ + .udma_mask = ATA_UDMA6, + .port_ops = &artop6260_ops, + }; const struct ata_port_info *ppi[] = { NULL, NULL }; if (!printed_version++) @@ -455,13 +464,13 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id) } else if (id->driver_data == 1) /* 6260 */ ppi[0] = &info_626x; - else if (id->driver_data == 2) { /* 6260 or 6260 + fast */ + else if (id->driver_data == 2) { /* 6280 or 6280 + fast */ unsigned long io = pci_resource_start(pdev, 4); u8 reg; - ppi[0] = &info_626x; + ppi[0] = &info_628x; if (inb(io) & 0x10) - ppi[0] = &info_626x_fast; + ppi[0] = &info_628x_fast; /* Mac systems come up with some registers not set as we will need them */ diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c index 84d9c556856..c5ddd937dbf 100644 --- a/drivers/ata/pata_hpt37x.c +++ b/drivers/ata/pata_hpt37x.c @@ -8,12 +8,10 @@ * Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org> * Portions Copyright (C) 2001 Sun Microsystems, Inc. * Portions Copyright (C) 2003 Red Hat Inc - * Portions Copyright (C) 2005-2006 MontaVista Software, Inc. + * Portions Copyright (C) 2005-2007 MontaVista Software, Inc. * * TODO - * PLL mode - * Look into engine reset on timeout errors. Should not be - * required. + * Look into engine reset on timeout errors. Should not be required. */ #include <linux/kernel.h> @@ -26,7 +24,7 @@ #include <linux/libata.h> #define DRV_NAME "pata_hpt37x" -#define DRV_VERSION "0.6.7" +#define DRV_VERSION "0.6.9" struct hpt_clock { u8 xfer_speed; @@ -1092,9 +1090,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) int dpll, adjust; /* Compute DPLL */ - dpll = 2; - if (port->udma_mask & 0xE0) - dpll = 3; + dpll = (port->udma_mask & 0xC0) ? 3 : 2; f_low = (MHz[clock_slot] * 48) / MHz[dpll]; f_high = f_low + 2; @@ -1116,7 +1112,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low | 0x100); } if (adjust == 8) { - printk(KERN_WARNING "hpt37x: DPLL did not stabilize.\n"); + printk(KERN_ERR "pata_hpt37x: DPLL did not stabilize!\n"); return -ENODEV; } if (dpll == 3) @@ -1124,7 +1120,8 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) else private_data = (void *)hpt37x_timings_50; - printk(KERN_INFO "hpt37x: Bus clock %dMHz, using DPLL.\n", MHz[dpll]); + printk(KERN_INFO "pata_hpt37x: bus clock %dMHz, using %dMHz DPLL.\n", + MHz[clock_slot], MHz[dpll]); } else { private_data = (void *)chip_table->clocks[clock_slot]; /* @@ -1137,7 +1134,8 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) port = &info_hpt370_33; if (clock_slot < 2 && port == &info_hpt370a) port = &info_hpt370a_33; - printk(KERN_INFO "hpt37x: %s: Bus clock %dMHz.\n", chip_table->name, MHz[clock_slot]); + printk(KERN_INFO "pata_hpt37x: %s using %dMHz bus clock.\n", + chip_table->name, MHz[clock_slot]); } /* Now kick off ATA set up */ diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c index aa29cde09f8..f8f234bfc8c 100644 --- a/drivers/ata/pata_hpt3x2n.c +++ b/drivers/ata/pata_hpt3x2n.c @@ -8,7 +8,7 @@ * Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org> * Portions Copyright (C) 2001 Sun Microsystems, Inc. * Portions Copyright (C) 2003 Red Hat Inc - * Portions Copyright (C) 2005-2006 MontaVista Software, Inc. + * Portions Copyright (C) 2005-2007 MontaVista Software, Inc. * * * TODO @@ -25,7 +25,7 @@ #include <linux/libata.h> #define DRV_NAME "pata_hpt3x2n" -#define DRV_VERSION "0.3.3" +#define DRV_VERSION "0.3.4" enum { HPT_PCI_FAST = (1 << 31), @@ -579,10 +579,12 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low); } if (adjust == 8) { - printk(KERN_WARNING "hpt3x2n: DPLL did not stabilize.\n"); + printk(KERN_ERR "pata_hpt3x2n: DPLL did not stabilize!\n"); return -ENODEV; } + printk(KERN_INFO "pata_hpt37x: bus clock %dMHz, using 66MHz DPLL.\n", + pci_mhz); /* Set our private data up. We only need a few flags so we use it directly */ port.private_data = NULL; diff --git a/drivers/ata/pata_isapnp.c b/drivers/ata/pata_isapnp.c index 5525518204e..91a396fa5b2 100644 --- a/drivers/ata/pata_isapnp.c +++ b/drivers/ata/pata_isapnp.c @@ -139,6 +139,8 @@ static struct pnp_device_id isapnp_devices[] = { {.id = ""} }; +MODULE_DEVICE_TABLE(pnp, isapnp_devices); + static struct pnp_driver isapnp_driver = { .name = DRV_NAME, .id_table = isapnp_devices, diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c index 430673be1df..7225124d96c 100644 --- a/drivers/ata/pata_it821x.c +++ b/drivers/ata/pata_it821x.c @@ -587,7 +587,7 @@ static int it821x_port_start(struct ata_port *ap) itdev->want[1][1] = ATA_ANY; itdev->last_device = -1; - if (pdev->revision == 0x11) { + if (pdev->revision == 0x10) { itdev->timing10 = 1; /* Need to disable ATAPI DMA for this case */ if (!itdev->smart) diff --git a/drivers/ata/pata_pdc2027x.c b/drivers/ata/pata_pdc2027x.c index 69a5aa4949f..e3245b36269 100644 --- a/drivers/ata/pata_pdc2027x.c +++ b/drivers/ata/pata_pdc2027x.c @@ -563,13 +563,13 @@ static long pdc_read_counter(struct ata_host *host) u32 bccrl, bccrh, bccrlv, bccrhv; retry: - bccrl = readl(mmio_base + PDC_BYTE_COUNT) & 0xffff; - bccrh = readl(mmio_base + PDC_BYTE_COUNT + 0x100) & 0xffff; + bccrl = readl(mmio_base + PDC_BYTE_COUNT) & 0x7fff; + bccrh = readl(mmio_base + PDC_BYTE_COUNT + 0x100) & 0x7fff; rmb(); /* Read the counter values again for verification */ - bccrlv = readl(mmio_base + PDC_BYTE_COUNT) & 0xffff; - bccrhv = readl(mmio_base + PDC_BYTE_COUNT + 0x100) & 0xffff; + bccrlv = readl(mmio_base + PDC_BYTE_COUNT) & 0x7fff; + bccrhv = readl(mmio_base + PDC_BYTE_COUNT + 0x100) & 0x7fff; rmb(); counter = (bccrh << 15) | bccrl; @@ -692,16 +692,16 @@ static long pdc_detect_pll_input_clock(struct ata_host *host) struct timeval start_time, end_time; long pll_clock, usec_elapsed; - /* Read current counter value */ - start_count = pdc_read_counter(host); - do_gettimeofday(&start_time); - /* Start the test mode */ scr = readl(mmio_base + PDC_SYS_CTL); PDPRINTK("scr[%X]\n", scr); writel(scr | (0x01 << 14), mmio_base + PDC_SYS_CTL); readl(mmio_base + PDC_SYS_CTL); /* flush */ + /* Read current counter value */ + start_count = pdc_read_counter(host); + do_gettimeofday(&start_time); + /* Let the counter run for 100 ms. */ mdelay(100); @@ -719,7 +719,7 @@ static long pdc_detect_pll_input_clock(struct ata_host *host) usec_elapsed = (end_time.tv_sec - start_time.tv_sec) * 1000000 + (end_time.tv_usec - start_time.tv_usec); - pll_clock = (start_count - end_count) / 100 * + pll_clock = ((start_count - end_count) & 0x3fffffff) / 100 * (100000000 / usec_elapsed); PDPRINTK("start[%ld] end[%ld] \n", start_count, end_count); diff --git a/drivers/ata/pata_sis.c b/drivers/ata/pata_sis.c index 66bd0e83ac0..2bd7645f1a8 100644 --- a/drivers/ata/pata_sis.c +++ b/drivers/ata/pata_sis.c @@ -54,6 +54,7 @@ struct sis_laptop { static const struct sis_laptop sis_laptop[] = { /* devid, subvendor, subdev */ { 0x5513, 0x1043, 0x1107 }, /* ASUS A6K */ + { 0x5513, 0x1734, 0x105F }, /* FSC Amilo A1630 */ /* end marker */ { 0, } }; diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c index f645fe22cd1..ea18e33f50e 100644 --- a/drivers/ata/pata_via.c +++ b/drivers/ata/pata_via.c @@ -63,7 +63,7 @@ #include <linux/dmi.h> #define DRV_NAME "pata_via" -#define DRV_VERSION "0.3.1" +#define DRV_VERSION "0.3.2" /* * The following comes directly from Vojtech Pavlik's ide/pci/via82cxxx @@ -144,6 +144,9 @@ static int via_cable_override(struct pci_dev *pdev) /* Systems by DMI */ if (dmi_check_system(cable_dmi_table)) return 1; + /* Arima W730-K8/Targa Visionary 811/... */ + if (pdev->subsystem_vendor == 0x161F && pdev->subsystem_device == 0x2032) + return 1; return 0; } diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 8ec520885b9..3acf65e75eb 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -621,6 +621,9 @@ static const struct pci_device_id mv_pci_tbl[] = { { PCI_VDEVICE(MARVELL, 0x5041), chip_504x }, { PCI_VDEVICE(MARVELL, 0x5080), chip_5080 }, { PCI_VDEVICE(MARVELL, 0x5081), chip_508x }, + /* RocketRAID 1740/174x have different identifiers */ + { PCI_VDEVICE(TTI, 0x1740), chip_508x }, + { PCI_VDEVICE(TTI, 0x1742), chip_508x }, { PCI_VDEVICE(MARVELL, 0x6040), chip_604x }, { PCI_VDEVICE(MARVELL, 0x6041), chip_604x }, diff --git a/drivers/atm/Kconfig b/drivers/atm/Kconfig index bed9f58c2d5..b554edac1ce 100644 --- a/drivers/atm/Kconfig +++ b/drivers/atm/Kconfig @@ -6,6 +6,11 @@ menuconfig ATM_DRIVERS bool "ATM drivers" depends on NETDEVICES && ATM default y + ---help--- + Say Y here to get to see options for Asynchronous Transfer Mode + device drivers. This option alone does not add any kernel code. + + If you say N, all options in this submenu will be skipped and disabled. if ATM_DRIVERS && NETDEVICES && ATM diff --git a/drivers/auxdisplay/Kconfig b/drivers/auxdisplay/Kconfig index de2fcce10ba..043353bd060 100644 --- a/drivers/auxdisplay/Kconfig +++ b/drivers/auxdisplay/Kconfig @@ -8,6 +8,11 @@ menuconfig AUXDISPLAY depends on PARPORT bool "Auxiliary Display support" + ---help--- + Say Y here to get to see options for auxiliary display drivers. + This option alone does not add any kernel code. + + If you say N, all options in this submenu will be skipped and disabled. if AUXDISPLAY && PARPORT diff --git a/drivers/auxdisplay/cfag12864b.c b/drivers/auxdisplay/cfag12864b.c index cb44cb4f6a4..80bb0610538 100644 --- a/drivers/auxdisplay/cfag12864b.c +++ b/drivers/auxdisplay/cfag12864b.c @@ -355,7 +355,7 @@ static int __init cfag12864b_init(void) cfag12864b_cache = kmalloc(sizeof(unsigned char) * CFAG12864B_SIZE, GFP_KERNEL); - if (cfag12864b_buffer == NULL) { + if (cfag12864b_cache == NULL) { printk(KERN_ERR CFAG12864B_NAME ": ERROR: " "can't alloc cache buffer (%i bytes)\n", CFAG12864B_SIZE); diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index a4a31199240..4245b7f80a4 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -6,6 +6,12 @@ menuconfig BLK_DEV bool "Block devices" depends on BLOCK default y + ---help--- + Say Y here to get to see options for various different block device + drivers. This option alone does not add any kernel code. + + If you say N, all options in this submenu will be skipped and disabled; + only do this if you know what you are doing. if BLK_DEV @@ -62,6 +68,7 @@ config AMIGA_Z2RAM config BLK_DEV_XD tristate "XT hard disk support" depends on ISA && ISA_DMA_API + select CHECK_SIGNATURE help Very old 8 bit hard disk controllers used in the IBM XT computer will be supported if you say Y here. diff --git a/drivers/block/lguest_blk.c b/drivers/block/lguest_blk.c index 93e3c4001bf..160cf14431a 100644 --- a/drivers/block/lguest_blk.c +++ b/drivers/block/lguest_blk.c @@ -308,9 +308,12 @@ static int lguestblk_probe(struct lguest_device *lgdev) } /* This allocates a "struct gendisk" where we pack all the information - * about the disk which the rest of Linux sees. We ask for one minor - * number; I do wonder if we should be asking for more. */ - bd->disk = alloc_disk(1); + * about the disk which the rest of Linux sees. The argument is the + * number of minor devices desired: we need one minor for the main + * disk, and one for each partition. Of course, we can't possibly know + * how many partitions are on the disk (add_disk does that). + */ + bd->disk = alloc_disk(16); if (!bd->disk) { err = -ENOMEM; goto out_unregister_blkdev; diff --git a/drivers/block/sunvdc.c b/drivers/block/sunvdc.c index 4dff49256ac..317a790c153 100644 --- a/drivers/block/sunvdc.c +++ b/drivers/block/sunvdc.c @@ -417,7 +417,7 @@ static int __send_request(struct request *req) desc->req_id = port->req_id; desc->operation = op; if (port->vdisk_type == VD_DISK_TYPE_DISK) { - desc->slice = 2; + desc->slice = 0xff; } else { desc->slice = 0; } diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c index df0ddf14b85..f60bca70d1f 100644 --- a/drivers/char/agp/amd-k7-agp.c +++ b/drivers/char/agp/amd-k7-agp.c @@ -223,6 +223,8 @@ static int amd_irongate_configure(void) pci_read_config_dword(agp_bridge->dev, AMD_MMBASE, &temp); temp = (temp & PCI_BASE_ADDRESS_MEM_MASK); amd_irongate_private.registers = (volatile u8 __iomem *) ioremap(temp, 4096); + if (!amd_irongate_private.registers) + return -ENOMEM; /* Write out the address of the gatt table */ writel(agp_bridge->gatt_bus_addr, amd_irongate_private.registers+AMD_ATTBASE); diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c index da7513d7b4e..2d46b713c8f 100644 --- a/drivers/char/agp/ati-agp.c +++ b/drivers/char/agp/ati-agp.c @@ -213,6 +213,9 @@ static int ati_configure(void) temp = (temp & 0xfffff000); ati_generic_private.registers = (volatile u8 __iomem *) ioremap(temp, 4096); + if (!ati_generic_private.registers) + return -ENOMEM; + if (is_r200()) pci_write_config_dword(agp_bridge->dev, ATI_RS100_IG_AGPMODE, 0x20000); else diff --git a/drivers/char/agp/efficeon-agp.c b/drivers/char/agp/efficeon-agp.c index df8da726285..d78cd09186a 100644 --- a/drivers/char/agp/efficeon-agp.c +++ b/drivers/char/agp/efficeon-agp.c @@ -375,6 +375,7 @@ static int __devinit agp_efficeon_probe(struct pci_dev *pdev, if (!r->start && r->end) { if (pci_assign_resource(pdev, 0)) { printk(KERN_ERR PFX "could not assign resource 0\n"); + agp_put_bridge(bridge); return -ENODEV; } } @@ -386,6 +387,7 @@ static int __devinit agp_efficeon_probe(struct pci_dev *pdev, */ if (pci_enable_device(pdev)) { printk(KERN_ERR PFX "Unable to Enable PCI device\n"); + agp_put_bridge(bridge); return -ENODEV; } diff --git a/drivers/char/agp/hp-agp.c b/drivers/char/agp/hp-agp.c index bcdb149c817..313a133a117 100644 --- a/drivers/char/agp/hp-agp.c +++ b/drivers/char/agp/hp-agp.c @@ -221,6 +221,7 @@ hp_zx1_lba_init (u64 hpa) if (cap != PCI_CAP_ID_AGP) { printk(KERN_ERR PFX "Invalid capability ID 0x%02x at 0x%x\n", cap, hp->lba_cap_offset); + iounmap(hp->lba_regs); return -ENODEV; } diff --git a/drivers/char/agp/i460-agp.c b/drivers/char/agp/i460-agp.c index 53354bf83af..75d2aca6353 100644 --- a/drivers/char/agp/i460-agp.c +++ b/drivers/char/agp/i460-agp.c @@ -249,6 +249,10 @@ static int i460_create_gatt_table (struct agp_bridge_data *bridge) num_entries = A_SIZE_8(temp)->num_entries; i460.gatt = ioremap(INTEL_I460_ATTBASE, PAGE_SIZE << page_order); + if (!i460.gatt) { + printk(KERN_ERR PFX "ioremap failed\n"); + return -ENOMEM; + } /* These are no good, the should be removed from the agp_bridge strucure... */ agp_bridge->gatt_table_real = NULL; diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index 294cdbf4d44..2c9ca2c6462 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c @@ -930,8 +930,10 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge) temp &= 0xfff80000; intel_private.registers = ioremap(temp,128 * 4096); - if (!intel_private.registers) + if (!intel_private.registers) { + iounmap(intel_private.gtt); return -ENOMEM; + } temp = readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000; global_cache_flush(); /* FIXME: ? */ @@ -985,13 +987,15 @@ static int intel_i965_create_gatt_table(struct agp_bridge_data *bridge) temp &= 0xfff00000; intel_private.gtt = ioremap((temp + (512 * 1024)) , 512 * 1024); - if (!intel_private.gtt) - return -ENOMEM; + if (!intel_private.gtt) + return -ENOMEM; intel_private.registers = ioremap(temp,128 * 4096); - if (!intel_private.registers) - return -ENOMEM; + if (!intel_private.registers) { + iounmap(intel_private.gtt); + return -ENOMEM; + } temp = readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000; global_cache_flush(); /* FIXME: ? */ diff --git a/drivers/char/agp/nvidia-agp.c b/drivers/char/agp/nvidia-agp.c index 6cd7373dcdf..225ed2a53d4 100644 --- a/drivers/char/agp/nvidia-agp.c +++ b/drivers/char/agp/nvidia-agp.c @@ -157,6 +157,9 @@ static int nvidia_configure(void) nvidia_private.aperture = (volatile u32 __iomem *) ioremap(apbase, 33 * PAGE_SIZE); + if (!nvidia_private.aperture) + return -ENOMEM; + return 0; } diff --git a/drivers/char/agp/via-agp.c b/drivers/char/agp/via-agp.c index 9aaf401a897..0ecc54d327b 100644 --- a/drivers/char/agp/via-agp.c +++ b/drivers/char/agp/via-agp.c @@ -399,6 +399,11 @@ static struct agp_device_ids via_agp_device_ids[] __devinitdata = .device_id = PCI_DEVICE_ID_VIA_P4M890, .chipset_name = "P4M890", }, + /* P4M900 */ + { + .device_id = PCI_DEVICE_ID_VIA_VT3364, + .chipset_name = "P4M900", + }, { }, /* dummy final entry, always present */ }; diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c index 923174c54a1..c115b39b851 100644 --- a/drivers/char/drm/drm_bufs.c +++ b/drivers/char/drm/drm_bufs.c @@ -177,8 +177,14 @@ static int drm_addmap_core(struct drm_device * dev, unsigned int offset, MTRR_TYPE_WRCOMB, 1); } } - if (map->type == _DRM_REGISTERS) + if (map->type == _DRM_REGISTERS) { map->handle = ioremap(map->offset, map->size); + if (!map->handle) { + drm_free(map, sizeof(*map), DRM_MEM_MAPS); + return -ENOMEM; + } + } + break; case _DRM_SHM: list = drm_find_matching_map(dev, map); @@ -479,11 +485,6 @@ int drm_rmmap_ioctl(struct inode *inode, struct file *filp, return -EINVAL; } - if (!map) { - mutex_unlock(&dev->struct_mutex); - return -EINVAL; - } - /* Register and framebuffer maps are permanent */ if ((map->type == _DRM_REGISTERS) || (map->type == _DRM_FRAME_BUFFER)) { mutex_unlock(&dev->struct_mutex); diff --git a/drivers/char/drm/via_dmablit.c b/drivers/char/drm/via_dmablit.c index 832de1d9ba7..3dd1ed3d1bf 100644 --- a/drivers/char/drm/via_dmablit.c +++ b/drivers/char/drm/via_dmablit.c @@ -560,7 +560,7 @@ via_init_dmablit(struct drm_device *dev) blitq->head = 0; blitq->cur = 0; blitq->serviced = 0; - blitq->num_free = VIA_NUM_BLIT_SLOTS; + blitq->num_free = VIA_NUM_BLIT_SLOTS - 1; blitq->num_outstanding = 0; blitq->is_active = 0; blitq->aborting = 0; diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index d57083a9e4e..f2e5cb1bedf 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -2292,7 +2292,7 @@ static int __devinit ipmi_of_probe(struct of_device *dev, info->irq = irq_of_parse_and_map(dev->node, 0); info->dev = &dev->dev; - dev_dbg(&dev->dev, "addr 0x%lx regsize %ld spacing %ld irq %x\n", + dev_dbg(&dev->dev, "addr 0x%lx regsize %d spacing %d irq %x\n", info->io.addr_data, info->io.regsize, info->io.regspacing, info->irq); diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index 2ce0af1bd58..d95f316afb5 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c @@ -1022,10 +1022,6 @@ static const unsigned short x86_keycodes[256] = 308,310,313,314,315,317,318,319,320,357,322,323,324,325,276,330, 332,340,365,342,343,344,345,346,356,270,341,368,369,370,371,372 }; -#ifdef CONFIG_MAC_EMUMOUSEBTN -extern int mac_hid_mouse_emulate_buttons(int, int, int); -#endif /* CONFIG_MAC_EMUMOUSEBTN */ - #ifdef CONFIG_SPARC static int sparc_l1_a_state = 0; extern void sun_do_break(void); diff --git a/drivers/char/lcd.c b/drivers/char/lcd.c index 1f0962616ee..4fe9206f84d 100644 --- a/drivers/char/lcd.c +++ b/drivers/char/lcd.c @@ -25,7 +25,6 @@ #include <asm/io.h> #include <asm/uaccess.h> #include <asm/system.h> -#include <linux/delay.h> #include "lcd.h" diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index aeec67e2726..859858561ab 100644 --- a/drivers/char/sonypi.c +++ b/drivers/char/sonypi.c @@ -875,7 +875,7 @@ found: #ifdef CONFIG_ACPI if (sonypi_acpi_device) - acpi_bus_generate_event(sonypi_acpi_device, 1, event); + acpi_bus_generate_proc_event(sonypi_acpi_device, 1, event); #endif kfifo_put(sonypi_device.fifo, (unsigned char *)&event, sizeof(event)); diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c index bbb7f129266..2f97d2f8f91 100644 --- a/drivers/char/synclink_gt.c +++ b/drivers/char/synclink_gt.c @@ -1565,6 +1565,9 @@ static int hdlcdev_open(struct net_device *dev) int rc; unsigned long flags; + if (!try_module_get(THIS_MODULE)) + return -EBUSY; + DBGINFO(("%s hdlcdev_open\n", dev->name)); /* generic HDLC layer open processing */ @@ -1634,6 +1637,7 @@ static int hdlcdev_close(struct net_device *dev) info->netcount=0; spin_unlock_irqrestore(&info->netlock, flags); + module_put(THIS_MODULE); return 0; } diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 9bb542913b8..39564b76d4a 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -7,7 +7,7 @@ * Reiner Sailer <sailer@watson.ibm.com> * Kylene Hall <kjhall@us.ibm.com> * - * Maintained by: <tpmdd_devel@lists.sourceforge.net> + * Maintained by: <tpmdd-devel@lists.sourceforge.net> * * Device driver for TCG/TCPA TPM (trusted platform module). * Specifications at www.trustedcomputinggroup.org diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index b2e2b002a1b..d15ccddc92e 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h @@ -7,7 +7,7 @@ * Reiner Sailer <sailer@watson.ibm.com> * Kylene Hall <kjhall@us.ibm.com> * - * Maintained by: <tpmdd_devel@lists.sourceforge.net> + * Maintained by: <tpmdd-devel@lists.sourceforge.net> * * Device driver for TCG/TCPA TPM (trusted platform module). * Specifications at www.trustedcomputinggroup.org diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c index 1ab0896070b..d0e7926eb48 100644 --- a/drivers/char/tpm/tpm_atmel.c +++ b/drivers/char/tpm/tpm_atmel.c @@ -7,7 +7,7 @@ * Reiner Sailer <sailer@watson.ibm.com> * Kylene Hall <kjhall@us.ibm.com> * - * Maintained by: <tpmdd_devel@lists.sourceforge.net> + * Maintained by: <tpmdd-devel@lists.sourceforge.net> * * Device driver for TCG/TCPA TPM (trusted platform module). * Specifications at www.trustedcomputinggroup.org diff --git a/drivers/char/tpm/tpm_atmel.h b/drivers/char/tpm/tpm_atmel.h index 9363bcf0a40..6c831f9466b 100644 --- a/drivers/char/tpm/tpm_atmel.h +++ b/drivers/char/tpm/tpm_atmel.h @@ -4,7 +4,7 @@ * Authors: * Kylene Hall <kjhall@us.ibm.com> * - * Maintained by: <tpmdd_devel@lists.sourceforge.net> + * Maintained by: <tpmdd-devel@lists.sourceforge.net> * * Device driver for TCG/TCPA TPM (trusted platform module). * Specifications at www.trustedcomputinggroup.org diff --git a/drivers/char/tpm/tpm_bios.c b/drivers/char/tpm/tpm_bios.c index 8677fc6a545..60a2d2630e3 100644 --- a/drivers/char/tpm/tpm_bios.c +++ b/drivers/char/tpm/tpm_bios.c @@ -7,6 +7,8 @@ * Reiner Sailer <sailer@watson.ibm.com> * Kylene Hall <kjhall@us.ibm.com> * + * Maintained by: <tpmdd-devel@lists.sourceforge.net> + * * Access to the eventlog extended by the TCG BIOS of PC platform * * This program is free software; you can redistribute it and/or diff --git a/drivers/char/tpm/tpm_nsc.c b/drivers/char/tpm/tpm_nsc.c index 608f73071be..6313326bc41 100644 --- a/drivers/char/tpm/tpm_nsc.c +++ b/drivers/char/tpm/tpm_nsc.c @@ -7,7 +7,7 @@ * Reiner Sailer <sailer@watson.ibm.com> * Kylene Hall <kjhall@us.ibm.com> * - * Maintained by: <tpmdd_devel@lists.sourceforge.net> + * Maintained by: <tpmdd-devel@lists.sourceforge.net> * * Device driver for TCG/TCPA TPM (trusted platform module). * Specifications at www.trustedcomputinggroup.org diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index 483f3f60013..23fa18a6654 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c @@ -5,6 +5,8 @@ * Leendert van Doorn <leendert@watson.ibm.com> * Kylene Hall <kjhall@us.ibm.com> * + * Maintained by: <tpmdd-devel@lists.sourceforge.net> + * * Device driver for TCG/TCPA TPM (trusted platform module). * Specifications at www.trustedcomputinggroup.org * diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 51ea93cab6c..9c867cf6de6 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -2063,8 +2063,7 @@ static int init_dev(struct tty_driver *driver, int idx, } if (!*tp_loc) { - tp = (struct ktermios *) kmalloc(sizeof(struct ktermios), - GFP_KERNEL); + tp = kmalloc(sizeof(struct ktermios), GFP_KERNEL); if (!tp) goto free_mem_out; *tp = driver->init_termios; @@ -2094,8 +2093,7 @@ static int init_dev(struct tty_driver *driver, int idx, } if (!*o_tp_loc) { - o_tp = (struct ktermios *) - kmalloc(sizeof(struct ktermios), GFP_KERNEL); + o_tp = kmalloc(sizeof(struct ktermios), GFP_KERNEL); if (!o_tp) goto free_mem_out; *o_tp = driver->other->init_termios; diff --git a/drivers/char/watchdog/alim1535_wdt.c b/drivers/char/watchdog/alim1535_wdt.c index e3f6a7d0c83..c404fc69e7e 100644 --- a/drivers/char/watchdog/alim1535_wdt.c +++ b/drivers/char/watchdog/alim1535_wdt.c @@ -312,6 +312,7 @@ static int ali_notify_sys(struct notifier_block *this, unsigned long code, void */ static struct pci_device_id ali_pci_tbl[] = { + { PCI_VENDOR_ID_AL, 0x1533, PCI_ANY_ID, PCI_ANY_ID,}, { PCI_VENDOR_ID_AL, 0x1535, PCI_ANY_ID, PCI_ANY_ID,}, { 0, }, }; @@ -329,9 +330,11 @@ static int __init ali_find_watchdog(void) struct pci_dev *pdev; u32 wdog; - /* Check for a 1535 series bridge */ + /* Check for a 1533/1535 series bridge */ pdev = pci_get_device(PCI_VENDOR_ID_AL, 0x1535, NULL); - if(pdev == NULL) + if (pdev == NULL) + pdev = pci_get_device(PCI_VENDOR_ID_AL, 0x1533, NULL); + if (pdev == NULL) return -ENODEV; pci_dev_put(pdev); diff --git a/drivers/char/watchdog/eurotechwdt.c b/drivers/char/watchdog/eurotechwdt.c index b070324e27a..b14e9d1f164 100644 --- a/drivers/char/watchdog/eurotechwdt.c +++ b/drivers/char/watchdog/eurotechwdt.c @@ -1,5 +1,5 @@ /* - * Eurotech CPU-1220/1410 on board WDT driver + * Eurotech CPU-1220/1410/1420 on board WDT driver * * (c) Copyright 2001 Ascensit <support@ascensit.com> * (c) Copyright 2001 Rodolfo Giometti <giometti@ascensit.com> @@ -25,6 +25,9 @@ /* Changelog: * + * 2001 - Rodolfo Giometti + * Initial release + * * 2002/04/25 - Rob Radez * clean up #includes * clean up locking @@ -33,13 +36,15 @@ * add WDIOC_GETSTATUS and WDIOC_SETOPTIONS ioctls * add expect_close support * - * 2001 - Rodolfo Giometti - * Initial release - * * 2002.05.30 - Joel Becker <joel.becker@oracle.com> * Added Matt Domsch's nowayout module option. */ +/* + * The eurotech CPU-1220/1410/1420's watchdog is a part + * of the on-board SUPER I/O device SMSC FDC 37B782. + */ + #include <linux/interrupt.h> #include <linux/module.h> #include <linux/moduleparam.h> diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index 84ebfcc1ffb..c0fc4aeb859 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -2,6 +2,11 @@ menuconfig CRYPTO_HW bool "Hardware crypto devices" default y + ---help--- + Say Y here to get to see options for hardware crypto devices and + processors. This option alone does not add any kernel code. + + If you say N, all options in this submenu will be skipped and disabled. if CRYPTO_HW diff --git a/drivers/dma/ioatdma.c b/drivers/dma/ioatdma.c index 5fbe56b5cea..41b18c5a314 100644 --- a/drivers/dma/ioatdma.c +++ b/drivers/dma/ioatdma.c @@ -191,17 +191,12 @@ static int ioat_dma_alloc_chan_resources(struct dma_chan *chan) int i; LIST_HEAD(tmp_list); - /* - * In-use bit automatically set by reading chanctrl - * If 0, we got it, if 1, someone else did - */ - chanctrl = readw(ioat_chan->reg_base + IOAT_CHANCTRL_OFFSET); - if (chanctrl & IOAT_CHANCTRL_CHANNEL_IN_USE) - return -EBUSY; + /* have we already been set up? */ + if (!list_empty(&ioat_chan->free_desc)) + return INITIAL_IOAT_DESC_COUNT; /* Setup register to interrupt and write completion status on error */ - chanctrl = IOAT_CHANCTRL_CHANNEL_IN_USE | - IOAT_CHANCTRL_ERR_INT_EN | + chanctrl = IOAT_CHANCTRL_ERR_INT_EN | IOAT_CHANCTRL_ANY_ERR_ABORT_EN | IOAT_CHANCTRL_ERR_COMPLETION_EN; writew(chanctrl, ioat_chan->reg_base + IOAT_CHANCTRL_OFFSET); @@ -282,11 +277,6 @@ static void ioat_dma_free_chan_resources(struct dma_chan *chan) in_use_descs - 1); ioat_chan->last_completion = ioat_chan->completion_addr = 0; - - /* Tell hw the chan is free */ - chanctrl = readw(ioat_chan->reg_base + IOAT_CHANCTRL_OFFSET); - chanctrl &= ~IOAT_CHANCTRL_CHANNEL_IN_USE; - writew(chanctrl, ioat_chan->reg_base + IOAT_CHANCTRL_OFFSET); } static struct dma_async_tx_descriptor * @@ -347,8 +337,7 @@ ioat_dma_prep_memcpy(struct dma_chan *chan, size_t len, int int_en) new->async_tx.ack = 0; /* client is in control of this ack */ new->async_tx.cookie = -EBUSY; - pci_unmap_len_set(new, src_len, orig_len); - pci_unmap_len_set(new, dst_len, orig_len); + pci_unmap_len_set(new, len, orig_len); spin_unlock_bh(&ioat_chan->desc_lock); return new ? &new->async_tx : NULL; @@ -423,11 +412,11 @@ static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *chan) */ pci_unmap_page(chan->device->pdev, pci_unmap_addr(desc, dst), - pci_unmap_len(desc, dst_len), + pci_unmap_len(desc, len), PCI_DMA_FROMDEVICE); pci_unmap_page(chan->device->pdev, pci_unmap_addr(desc, src), - pci_unmap_len(desc, src_len), + pci_unmap_len(desc, len), PCI_DMA_TODEVICE); } diff --git a/drivers/dma/ioatdma.h b/drivers/dma/ioatdma.h index d3726478031..bf4dad70e0f 100644 --- a/drivers/dma/ioatdma.h +++ b/drivers/dma/ioatdma.h @@ -111,10 +111,9 @@ struct ioat_desc_sw { struct ioat_dma_descriptor *hw; struct list_head node; int tx_cnt; + DECLARE_PCI_UNMAP_LEN(len) DECLARE_PCI_UNMAP_ADDR(src) - DECLARE_PCI_UNMAP_LEN(src_len) DECLARE_PCI_UNMAP_ADDR(dst) - DECLARE_PCI_UNMAP_LEN(dst_len) struct dma_async_tx_descriptor async_tx; }; diff --git a/drivers/firewire/fw-card.c b/drivers/firewire/fw-card.c index 0aeab3218bb..3e9719948a8 100644 --- a/drivers/firewire/fw-card.c +++ b/drivers/firewire/fw-card.c @@ -510,9 +510,11 @@ fw_core_remove_card(struct fw_card *card) /* Set up the dummy driver. */ card->driver = &dummy_driver; - fw_flush_transactions(card); - fw_destroy_nodes(card); + flush_scheduled_work(); + + fw_flush_transactions(card); + del_timer_sync(&card->flush_timer); fw_card_put(card); } diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index ba816ef6def..238730f75db 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -159,6 +159,7 @@ struct sbp2_pointer { struct sbp2_orb { struct fw_transaction t; + struct kref kref; dma_addr_t request_bus; int rcode; struct sbp2_pointer pointer; @@ -280,6 +281,14 @@ static const struct { }; static void +free_orb(struct kref *kref) +{ + struct sbp2_orb *orb = container_of(kref, struct sbp2_orb, kref); + + kfree(orb); +} + +static void sbp2_status_write(struct fw_card *card, struct fw_request *request, int tcode, int destination, int source, int generation, int speed, @@ -312,8 +321,8 @@ sbp2_status_write(struct fw_card *card, struct fw_request *request, spin_lock_irqsave(&card->lock, flags); list_for_each_entry(orb, &sd->orb_list, link) { if (STATUS_GET_ORB_HIGH(status) == 0 && - STATUS_GET_ORB_LOW(status) == orb->request_bus && - orb->rcode == RCODE_COMPLETE) { + STATUS_GET_ORB_LOW(status) == orb->request_bus) { + orb->rcode = RCODE_COMPLETE; list_del(&orb->link); break; } @@ -325,6 +334,8 @@ sbp2_status_write(struct fw_card *card, struct fw_request *request, else fw_error("status write for unknown orb\n"); + kref_put(&orb->kref, free_orb); + fw_send_response(card, request, RCODE_COMPLETE); } @@ -335,13 +346,27 @@ complete_transaction(struct fw_card *card, int rcode, struct sbp2_orb *orb = data; unsigned long flags; - orb->rcode = rcode; - if (rcode != RCODE_COMPLETE) { - spin_lock_irqsave(&card->lock, flags); + /* + * This is a little tricky. We can get the status write for + * the orb before we get this callback. The status write + * handler above will assume the orb pointer transaction was + * successful and set the rcode to RCODE_COMPLETE for the orb. + * So this callback only sets the rcode if it hasn't already + * been set and only does the cleanup if the transaction + * failed and we didn't already get a status write. + */ + spin_lock_irqsave(&card->lock, flags); + + if (orb->rcode == -1) + orb->rcode = rcode; + if (orb->rcode != RCODE_COMPLETE) { list_del(&orb->link); - spin_unlock_irqrestore(&card->lock, flags); orb->callback(orb, NULL); } + + spin_unlock_irqrestore(&card->lock, flags); + + kref_put(&orb->kref, free_orb); } static void @@ -360,6 +385,10 @@ sbp2_send_orb(struct sbp2_orb *orb, struct fw_unit *unit, list_add_tail(&orb->link, &sd->orb_list); spin_unlock_irqrestore(&device->card->lock, flags); + /* Take a ref for the orb list and for the transaction callback. */ + kref_get(&orb->kref); + kref_get(&orb->kref); + fw_send_request(device->card, &orb->t, TCODE_WRITE_BLOCK_REQUEST, node_id, generation, device->max_speed, offset, &orb->pointer, sizeof(orb->pointer), @@ -416,6 +445,7 @@ sbp2_send_management_orb(struct fw_unit *unit, int node_id, int generation, if (orb == NULL) return -ENOMEM; + kref_init(&orb->base.kref); orb->response_bus = dma_map_single(device->card->device, &orb->response, sizeof(orb->response), DMA_FROM_DEVICE); @@ -490,7 +520,7 @@ sbp2_send_management_orb(struct fw_unit *unit, int node_id, int generation, if (response) fw_memcpy_from_be32(response, orb->response, sizeof(orb->response)); - kfree(orb); + kref_put(&orb->base.kref, free_orb); return retval; } @@ -886,7 +916,6 @@ complete_command_orb(struct sbp2_orb *base_orb, struct sbp2_status *status) orb->cmd->result = result; orb->done(orb->cmd); - kfree(orb); } static int sbp2_command_orb_map_scatterlist(struct sbp2_command_orb *orb) @@ -1005,6 +1034,7 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done) /* Initialize rcode to something not RCODE_COMPLETE. */ orb->base.rcode = -1; + kref_init(&orb->base.kref); orb->unit = unit; orb->done = done; @@ -1051,10 +1081,11 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done) sbp2_send_orb(&orb->base, unit, sd->node_id, sd->generation, sd->command_block_agent_address + SBP2_ORB_POINTER); + kref_put(&orb->base.kref, free_orb); return 0; fail_mapping: - kfree(orb); + kref_put(&orb->base.kref, free_orb); fail_alloc: return SCSI_MLQUEUE_HOST_BUSY; } diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 3b63b0b7812..19667fcc722 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -5,6 +5,11 @@ menuconfig HID_SUPPORT bool "HID Devices" depends on INPUT default y + ---help--- + Say Y here to get to see options for various computer-human interface + device drivers. This option alone does not add any kernel code. + + If you say N, all options in this submenu will be skipped and disabled. if HID_SUPPORT diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c index 338ee4f5461..d3181967f16 100644 --- a/drivers/hwmon/smsc47m1.c +++ b/drivers/hwmon/smsc47m1.c @@ -585,6 +585,8 @@ static int __devinit smsc47m1_probe(struct platform_device *pdev) if ((err = device_create_file(dev, &dev_attr_alarms))) goto error_remove_files; + if ((err = device_create_file(dev, &dev_attr_name))) + goto error_remove_files; data->class_dev = hwmon_device_register(dev); if (IS_ERR(data->class_dev)) { diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index c51ae2e1775..d9a9ec7dd84 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c @@ -309,18 +309,16 @@ static inline int is_word_sized(u16 reg) || (reg & 0x00ff) == 0x55)); } -/* We assume that the default bank is 0, thus the following two functions do - nothing for registers which live in bank 0. For others, they respectively - set the bank register to the correct value (before the register is - accessed), and back to 0 (afterwards). */ +/* Registers 0x50-0x5f are banked */ static inline void w83627ehf_set_bank(struct w83627ehf_data *data, u16 reg) { - if (reg & 0xff00) { + if ((reg & 0x00f0) == 0x50) { outb_p(W83627EHF_REG_BANK, data->addr + ADDR_REG_OFFSET); outb_p(reg >> 8, data->addr + DATA_REG_OFFSET); } } +/* Not strictly necessary, but play it safe for now */ static inline void w83627ehf_reset_bank(struct w83627ehf_data *data, u16 reg) { if (reg & 0xff00) { @@ -421,6 +419,31 @@ static void w83627ehf_write_fan_div(struct w83627ehf_data *data, int nr) } } +static void w83627ehf_update_fan_div(struct w83627ehf_data *data) +{ + int i; + + i = w83627ehf_read_value(data, W83627EHF_REG_FANDIV1); + data->fan_div[0] = (i >> 4) & 0x03; + data->fan_div[1] = (i >> 6) & 0x03; + i = w83627ehf_read_value(data, W83627EHF_REG_FANDIV2); + data->fan_div[2] = (i >> 6) & 0x03; + i = w83627ehf_read_value(data, W83627EHF_REG_VBAT); + data->fan_div[0] |= (i >> 3) & 0x04; + data->fan_div[1] |= (i >> 4) & 0x04; + data->fan_div[2] |= (i >> 5) & 0x04; + if (data->has_fan & ((1 << 3) | (1 << 4))) { + i = w83627ehf_read_value(data, W83627EHF_REG_DIODE); + data->fan_div[3] = i & 0x03; + data->fan_div[4] = ((i >> 2) & 0x03) + | ((i >> 5) & 0x04); + } + if (data->has_fan & (1 << 3)) { + i = w83627ehf_read_value(data, W83627EHF_REG_SMI_OVT); + data->fan_div[3] |= (i >> 5) & 0x04; + } +} + static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) { struct w83627ehf_data *data = dev_get_drvdata(dev); @@ -432,25 +455,7 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) if (time_after(jiffies, data->last_updated + HZ + HZ/2) || !data->valid) { /* Fan clock dividers */ - i = w83627ehf_read_value(data, W83627EHF_REG_FANDIV1); - data->fan_div[0] = (i >> 4) & 0x03; - data->fan_div[1] = (i >> 6) & 0x03; - i = w83627ehf_read_value(data, W83627EHF_REG_FANDIV2); - data->fan_div[2] = (i >> 6) & 0x03; - i = w83627ehf_read_value(data, W83627EHF_REG_VBAT); - data->fan_div[0] |= (i >> 3) & 0x04; - data->fan_div[1] |= (i >> 4) & 0x04; - data->fan_div[2] |= (i >> 5) & 0x04; - if (data->has_fan & ((1 << 3) | (1 << 4))) { - i = w83627ehf_read_value(data, W83627EHF_REG_DIODE); - data->fan_div[3] = i & 0x03; - data->fan_div[4] = ((i >> 2) & 0x03) - | ((i >> 5) & 0x04); - } - if (data->has_fan & (1 << 3)) { - i = w83627ehf_read_value(data, W83627EHF_REG_SMI_OVT); - data->fan_div[3] |= (i >> 5) & 0x04; - } + w83627ehf_update_fan_div(data); /* Measured voltages and limits */ for (i = 0; i < data->in_num; i++) { @@ -1312,6 +1317,9 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) if (!(i & (1 << 1)) && (!fan5pin)) data->has_fan |= (1 << 4); + /* Read fan clock dividers immediately */ + w83627ehf_update_fan_div(data); + /* Register sysfs hooks */ for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays); i++) if ((err = device_create_file(dev, diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c index f85b48fea1c..c95909cc1d2 100644 --- a/drivers/hwmon/w83781d.c +++ b/drivers/hwmon/w83781d.c @@ -740,9 +740,9 @@ store_sensor(struct device *dev, struct device_attribute *da, static SENSOR_DEVICE_ATTR(temp1_type, S_IRUGO | S_IWUSR, show_sensor, store_sensor, 0); static SENSOR_DEVICE_ATTR(temp2_type, S_IRUGO | S_IWUSR, - show_sensor, store_sensor, 0); + show_sensor, store_sensor, 1); static SENSOR_DEVICE_ATTR(temp3_type, S_IRUGO | S_IWUSR, - show_sensor, store_sensor, 0); + show_sensor, store_sensor, 2); /* I2C devices get this name attribute automatically, but for ISA devices we must create it by ourselves. */ diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index e049f65bc3a..7adb61bad6a 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -304,9 +304,9 @@ comment "IDE chipset support/bugfixes" config IDE_GENERIC tristate "generic/default IDE chipset support" - default y + default H8300 help - If unsure, say Y. + If unsure, say N. config BLK_DEV_CMD640 bool "CMD640 chipset bugfix/support" @@ -345,6 +345,7 @@ config BLK_DEV_CMD640_ENHANCED config BLK_DEV_IDEPNP bool "PNP EIDE support" depends on PNP + select IDE_GENERIC help If you have a PnP (Plug and Play) compatible EIDE card and would like the kernel to automatically detect and activate @@ -834,6 +835,7 @@ config BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ config IDE_ARM def_bool ARM && (ARCH_CLPS7500 || ARCH_RPC || ARCH_SHARK) + select IDE_GENERIC config BLK_DEV_IDE_ICSIDE tristate "ICS IDE interface support" @@ -867,6 +869,7 @@ config BLK_DEV_IDE_BAST config BLK_DEV_GAYLE bool "Amiga Gayle IDE interface support" depends on AMIGA + select IDE_GENERIC help This is the IDE driver for the Amiga Gayle IDE interface. It supports both the `A1200 style' and `A4000 style' of the Gayle IDE interface, @@ -898,6 +901,7 @@ config BLK_DEV_IDEDOUBLER config BLK_DEV_BUDDHA bool "Buddha/Catweasel/X-Surf IDE interface support (EXPERIMENTAL)" depends on ZORRO && EXPERIMENTAL + select IDE_GENERIC help This is the IDE driver for the IDE interfaces on the Buddha, Catweasel and X-Surf expansion boards. It supports up to two interfaces @@ -910,6 +914,7 @@ config BLK_DEV_BUDDHA config BLK_DEV_FALCON_IDE bool "Falcon IDE interface support" depends on ATARI + select IDE_GENERIC help This is the IDE driver for the builtin IDE interface on the Atari Falcon. Say Y if you have a Falcon and want to use IDE devices (hard @@ -919,6 +924,7 @@ config BLK_DEV_FALCON_IDE config BLK_DEV_MAC_IDE bool "Macintosh Quadra/Powerbook IDE interface support" depends on MAC + select IDE_GENERIC help This is the IDE driver for the builtin IDE interface on some m68k Macintosh models. It supports both the `Quadra style' (used in @@ -932,6 +938,7 @@ config BLK_DEV_MAC_IDE config BLK_DEV_Q40IDE bool "Q40/Q60 IDE interface support" depends on Q40 + select IDE_GENERIC help Enable the on-board IDE controller in the Q40/Q60. This should normally be on; disable it only if you are running a custom hard @@ -940,6 +947,7 @@ config BLK_DEV_Q40IDE config BLK_DEV_MPC8xx_IDE bool "MPC8xx IDE support" depends on 8xx && IDE=y && BLK_DEV_IDE=y + select IDE_GENERIC help This option provides support for IDE on Motorola MPC8xx Systems. Please see 'Type of MPC8xx IDE interface' for details. diff --git a/drivers/ide/cris/ide-cris.c b/drivers/ide/cris/ide-cris.c index fbfea46a34f..04636f7eaae 100644 --- a/drivers/ide/cris/ide-cris.c +++ b/drivers/ide/cris/ide-cris.c @@ -718,6 +718,8 @@ static void tune_cris_ide(ide_drive_t *drive, u8 pio) } cris_ide_set_speed(TYPE_PIO, setup, strobe, hold); + + (void)ide_config_drive_speed(drive, XFER_PIO_0 + pio); } static int speed_cris_ide(ide_drive_t *drive, u8 speed) diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 5ce4216f72a..eba1adbc1b6 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c @@ -481,6 +481,15 @@ static inline int idedisk_supports_lba48(const struct hd_driveid *id) && id->lba_capacity_2; } +/* + * Some disks report total number of sectors instead of + * maximum sector address. We list them here. + */ +static const struct drive_list_entry hpa_list[] = { + { "ST340823A", NULL }, + { NULL, NULL } +}; + static void idedisk_check_hpa(ide_drive_t *drive) { unsigned long long capacity, set_max; @@ -492,6 +501,15 @@ static void idedisk_check_hpa(ide_drive_t *drive) else set_max = idedisk_read_native_max_address(drive); + if (ide_in_drive_list(drive->id, hpa_list)) { + /* + * Since we are inclusive wrt to firmware revisions do this + * extra check and apply the workaround only when needed. + */ + if (set_max == capacity + 1) + set_max--; + } + if (set_max <= capacity) return; diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index 5fe1d72ab45..ff644a5e12c 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c @@ -135,25 +135,6 @@ static const struct drive_list_entry drive_blacklist [] = { }; /** - * ide_in_drive_list - look for drive in black/white list - * @id: drive identifier - * @drive_table: list to inspect - * - * Look for a drive in the blacklist and the whitelist tables - * Returns 1 if the drive is found in the table. - */ - -int ide_in_drive_list(struct hd_driveid *id, const struct drive_list_entry *drive_table) -{ - for ( ; drive_table->id_model ; drive_table++) - if ((!strcmp(drive_table->id_model, id->model)) && - (!drive_table->id_firmware || - strstr(id->fw_rev, drive_table->id_firmware))) - return 1; - return 0; -} - -/** * ide_dma_intr - IDE DMA interrupt handler * @drive: the drive the interrupt is for * @@ -349,9 +330,17 @@ EXPORT_SYMBOL_GPL(ide_destroy_dmatable); static int config_drive_for_dma (ide_drive_t *drive) { + ide_hwif_t *hwif = drive->hwif; struct hd_driveid *id = drive->id; - if ((id->capability & 1) && drive->hwif->autodma) { + /* consult the list of known "bad" drives */ + if (__ide_dma_bad_drive(drive)) + return -1; + + if (drive->media != ide_disk && hwif->atapi_dma == 0) + return -1; + + if ((id->capability & 1) && drive->autodma) { /* * Enable DMA on any drive that has * UltraDMA (mode 0/1/2/3/4/5/6) enabled @@ -514,20 +503,6 @@ int __ide_dma_on (ide_drive_t *drive) EXPORT_SYMBOL(__ide_dma_on); /** - * __ide_dma_check - check DMA setup - * @drive: drive to check - * - * Don't use - due for extermination - */ - -int __ide_dma_check (ide_drive_t *drive) -{ - return config_drive_for_dma(drive); -} - -EXPORT_SYMBOL(__ide_dma_check); - -/** * ide_dma_setup - begin a DMA phase * @drive: target device * @@ -1021,7 +996,7 @@ void ide_setup_dma (ide_hwif_t *hwif, unsigned long dma_base, unsigned int num_p if (!hwif->dma_host_on) hwif->dma_host_on = &ide_dma_host_on; if (!hwif->ide_dma_check) - hwif->ide_dma_check = &__ide_dma_check; + hwif->ide_dma_check = &config_drive_for_dma; if (!hwif->dma_setup) hwif->dma_setup = &ide_dma_setup; if (!hwif->dma_exec_cmd) diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index 92578b6832e..f4cd2700cae 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c @@ -565,6 +565,36 @@ int ide_wait_stat (ide_startstop_t *startstop, ide_drive_t *drive, u8 good, u8 b EXPORT_SYMBOL(ide_wait_stat); +/** + * ide_in_drive_list - look for drive in black/white list + * @id: drive identifier + * @drive_table: list to inspect + * + * Look for a drive in the blacklist and the whitelist tables + * Returns 1 if the drive is found in the table. + */ + +int ide_in_drive_list(struct hd_driveid *id, const struct drive_list_entry *drive_table) +{ + for ( ; drive_table->id_model; drive_table++) + if ((!strcmp(drive_table->id_model, id->model)) && + (!drive_table->id_firmware || + strstr(id->fw_rev, drive_table->id_firmware))) + return 1; + return 0; +} + +EXPORT_SYMBOL_GPL(ide_in_drive_list); + +/* + * Early UDMA66 devices don't set bit14 to 1, only bit13 is valid. + * We list them here and depend on the device side cable detection for them. + */ +static const struct drive_list_entry ivb_list[] = { + { "QUANTUM FIREBALLlct10 05" , "A03.0900" }, + { NULL , NULL } +}; + /* * All hosts that use the 80c ribbon must use! * The name is derived from upper byte of word 93 and the 80c ribbon. @@ -573,11 +603,16 @@ u8 eighty_ninty_three (ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; struct hd_driveid *id = drive->id; + int ivb = ide_in_drive_list(id, ivb_list); if (hwif->cbl == ATA_CBL_PATA40_SHORT) return 1; - if (hwif->cbl != ATA_CBL_PATA80) + if (ivb) + printk(KERN_DEBUG "%s: skipping word 93 validity check\n", + drive->name); + + if (hwif->cbl != ATA_CBL_PATA80 && !ivb) goto no_80w; /* Check for SATA but only if we are ATA5 or higher */ @@ -587,11 +622,11 @@ u8 eighty_ninty_three (ide_drive_t *drive) /* * FIXME: * - change master/slave IDENTIFY order - * - force bit13 (80c cable present) check + * - force bit13 (80c cable present) check also for !ivb devices * (unless the slave device is pre-ATA3) */ #ifndef CONFIG_IDEDMA_IVB - if (id->hw_config & 0x4000) + if ((id->hw_config & 0x4000) || (ivb && (id->hw_config & 0x2000))) #else if (id->hw_config & 0x6000) #endif @@ -795,7 +830,7 @@ int ide_config_drive_speed (ide_drive_t *drive, u8 speed) hwif->OUTB(drive->ctl | 2, IDE_CONTROL_REG); hwif->OUTB(speed, IDE_NSECTOR_REG); hwif->OUTB(SETFEATURES_XFER, IDE_FEATURE_REG); - hwif->OUTB(WIN_SETFEATURES, IDE_COMMAND_REG); + hwif->OUTBSYNC(drive, WIN_SETFEATURES, IDE_COMMAND_REG); if ((IDE_CONTROL_REG) && (drive->quirk_list == 2)) hwif->OUTB(drive->ctl, IDE_CONTROL_REG); udelay(1); @@ -822,7 +857,7 @@ int ide_config_drive_speed (ide_drive_t *drive, u8 speed) */ for (i = 0; i < 10; i++) { udelay(1); - if (OK_STAT((stat = hwif->INB(IDE_STATUS_REG)), DRIVE_READY, BUSY_STAT|DRQ_STAT|ERR_STAT)) { + if (OK_STAT((stat = hwif->INB(IDE_STATUS_REG)), drive->ready_stat, BUSY_STAT|DRQ_STAT|ERR_STAT)) { error = 0; break; } diff --git a/drivers/ide/pci/cs5530.c b/drivers/ide/pci/cs5530.c index acaf71fd4c0..e5949b1d3fb 100644 --- a/drivers/ide/pci/cs5530.c +++ b/drivers/ide/pci/cs5530.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/cs5530.c Version 0.73 Mar 10 2007 + * linux/drivers/ide/pci/cs5530.c Version 0.74 Jul 28 2007 * * Copyright (C) 2000 Andre Hedrick <andre@linux-ide.org> * Copyright (C) 2000 Mark Lord <mlord@pobox.com> @@ -207,6 +207,9 @@ static unsigned int __devinit init_chipset_cs5530 (struct pci_dev *dev, const ch struct pci_dev *master_0 = NULL, *cs5530_0 = NULL; unsigned long flags; + if (pci_resource_start(dev, 4) == 0) + return -EFAULT; + dev = NULL; while ((dev = pci_get_device(PCI_VENDOR_ID_CYRIX, PCI_ANY_ID, dev)) != NULL) { switch (dev->device) { @@ -325,6 +328,9 @@ static void __devinit init_hwif_cs5530 (ide_hwif_t *hwif) /* needs autotuning later */ } + if (hwif->dma_base == 0) + return; + hwif->atapi_dma = 1; hwif->ultra_mask = 0x07; hwif->mwdma_mask = 0x07; diff --git a/drivers/ide/pci/hpt34x.c b/drivers/ide/pci/hpt34x.c index 19778c5fe71..cb8fe5643d3 100644 --- a/drivers/ide/pci/hpt34x.c +++ b/drivers/ide/pci/hpt34x.c @@ -89,11 +89,7 @@ static int hpt34x_config_drive_xfer_rate (ide_drive_t *drive) drive->init_speed = 0; if (ide_tune_dma(drive)) -#ifndef CONFIG_HPT34X_AUTODMA return -1; -#else - return 0; -#endif if (ide_use_fast_pio(drive)) hpt34x_tune_drive(drive, 255); @@ -160,9 +156,11 @@ static void __devinit init_hwif_hpt34x(ide_hwif_t *hwif) if (!hwif->dma_base) return; +#ifdef CONFIG_HPT34X_AUTODMA hwif->ultra_mask = 0x07; hwif->mwdma_mask = 0x07; hwif->swdma_mask = 0x07; +#endif hwif->ide_dma_check = &hpt34x_config_drive_xfer_rate; if (!noautodma) diff --git a/drivers/ide/pci/ns87415.c b/drivers/ide/pci/ns87415.c index 09941f37d63..465c935fdf2 100644 --- a/drivers/ide/pci/ns87415.c +++ b/drivers/ide/pci/ns87415.c @@ -187,14 +187,6 @@ static int ns87415_ide_dma_setup(ide_drive_t *drive) return 1; } -static int ns87415_ide_dma_check (ide_drive_t *drive) -{ - if (drive->media != ide_disk) - return -1; - - return __ide_dma_check(drive); -} - static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif) { struct pci_dev *dev = hwif->pci_dev; @@ -266,7 +258,6 @@ static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif) outb(0x60, hwif->dma_status); hwif->dma_setup = &ns87415_ide_dma_setup; - hwif->ide_dma_check = &ns87415_ide_dma_check; hwif->ide_dma_end = &ns87415_ide_dma_end; if (!noautodma) diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c index 8a66a2871b3..f6db2f37efa 100644 --- a/drivers/ide/pci/pdc202xx_new.c +++ b/drivers/ide/pci/pdc202xx_new.c @@ -378,6 +378,9 @@ static unsigned int __devinit init_chipset_pdcnew(struct pci_dev *dev, const cha int f, r; u8 pll_ctl0, pll_ctl1; + if (dma_base == 0) + return -EFAULT; + #ifdef CONFIG_PPC_PMAC apple_kiwi_init(dev); #endif @@ -494,15 +497,18 @@ static void __devinit init_hwif_pdc202new(ide_hwif_t *hwif) hwif->speedproc = &pdcnew_tune_chipset; hwif->resetproc = &pdcnew_reset; + hwif->err_stops_fifo = 1; + hwif->drives[0].autotune = hwif->drives[1].autotune = 1; + if (hwif->dma_base == 0) + return; + hwif->atapi_dma = 1; hwif->ultra_mask = hwif->cds->udma_mask; hwif->mwdma_mask = 0x07; - hwif->err_stops_fifo = 1; - hwif->ide_dma_check = &pdcnew_config_drive_xfer_rate; if (hwif->cbl != ATA_CBL_PATA40_SHORT) diff --git a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c index fbcb0bb9c95..e19a891171c 100644 --- a/drivers/ide/pci/pdc202xx_old.c +++ b/drivers/ide/pci/pdc202xx_old.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/pdc202xx_old.c Version 0.50 Mar 3, 2007 + * linux/drivers/ide/pci/pdc202xx_old.c Version 0.51 Jul 27, 2007 * * Copyright (C) 1998-2002 Andre Hedrick <andre@linux-ide.org> * Copyright (C) 2006-2007 MontaVista Software, Inc. @@ -337,15 +337,18 @@ static void __devinit init_hwif_pdc202xx(ide_hwif_t *hwif) hwif->speedproc = &pdc202xx_tune_chipset; + hwif->err_stops_fifo = 1; + hwif->drives[0].autotune = hwif->drives[1].autotune = 1; + if (hwif->dma_base == 0) + return; + hwif->ultra_mask = hwif->cds->udma_mask; hwif->mwdma_mask = 0x07; hwif->swdma_mask = 0x07; hwif->atapi_dma = 1; - hwif->err_stops_fifo = 1; - hwif->ide_dma_check = &pdc202xx_config_drive_xfer_rate; hwif->dma_lost_irq = &pdc202xx_dma_lost_irq; hwif->dma_timeout = &pdc202xx_dma_timeout; diff --git a/drivers/ide/pci/triflex.c b/drivers/ide/pci/triflex.c index 024bbfae042..098692a6d61 100644 --- a/drivers/ide/pci/triflex.c +++ b/drivers/ide/pci/triflex.c @@ -115,6 +115,9 @@ static void __devinit init_hwif_triflex(ide_hwif_t *hwif) hwif->tuneproc = &triflex_tune_drive; hwif->speedproc = &triflex_tune_chipset; + if (hwif->dma_base == 0) + return; + hwif->atapi_dma = 1; hwif->mwdma_mask = 0x07; hwif->swdma_mask = 0x07; diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c index 33630ad3e79..4b13cd9a027 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/ppc/pmac.c @@ -604,6 +604,9 @@ out: drive->id->dma_1word |= 0x0101; break; default: break; } + if (!drive->init_speed) + drive->init_speed = command; + drive->current_speed = command; } enable_irq(hwif->irq); return result; @@ -986,7 +989,6 @@ pmac_ide_tune_chipset (ide_drive_t *drive, byte speed) return ret; pmac_ide_do_update_timings(drive); - drive->current_speed = speed; return 0; } @@ -1737,11 +1739,6 @@ pmac_ide_mdma_enable(ide_drive_t *drive, u16 mode) /* Apply timings to controller */ *timings = timing_local[0]; *timings2 = timing_local[1]; - - /* Set speed info in drive */ - drive->current_speed = mode; - if (!drive->init_speed) - drive->init_speed = mode; return 1; } @@ -1793,11 +1790,6 @@ pmac_ide_udma_enable(ide_drive_t *drive, u16 mode) *timings = timing_local[0]; *timings2 = timing_local[1]; - /* Set speed info in drive */ - drive->current_speed = mode; - if (!drive->init_speed) - drive->init_speed = mode; - return 1; } diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c index 47dbe8f17e8..a81ba8fca0d 100644 --- a/drivers/ieee1394/sbp2.c +++ b/drivers/ieee1394/sbp2.c @@ -513,9 +513,9 @@ static int sbp2util_create_command_orb_pool(struct sbp2_lu *lu) return 0; } -static void sbp2util_remove_command_orb_pool(struct sbp2_lu *lu) +static void sbp2util_remove_command_orb_pool(struct sbp2_lu *lu, + struct hpsb_host *host) { - struct hpsb_host *host = lu->hi->host; struct list_head *lh, *next; struct sbp2_command_info *cmd; unsigned long flags; @@ -922,15 +922,16 @@ static void sbp2_remove_device(struct sbp2_lu *lu) if (!lu) return; - hi = lu->hi; + if (!hi) + goto no_hi; if (lu->shost) { scsi_remove_host(lu->shost); scsi_host_put(lu->shost); } flush_scheduled_work(); - sbp2util_remove_command_orb_pool(lu); + sbp2util_remove_command_orb_pool(lu, hi->host); list_del(&lu->lu_list); @@ -971,9 +972,8 @@ static void sbp2_remove_device(struct sbp2_lu *lu) lu->ud->device.driver_data = NULL; - if (hi) - module_put(hi->host->driver->owner); - + module_put(hi->host->driver->owner); +no_hi: kfree(lu); } diff --git a/drivers/infiniband/core/agent.c b/drivers/infiniband/core/agent.c index db2633e4aae..ae7c2880e62 100644 --- a/drivers/infiniband/core/agent.c +++ b/drivers/infiniband/core/agent.c @@ -78,15 +78,14 @@ ib_get_agent_port(struct ib_device *device, int port_num) return entry; } -int agent_send_response(struct ib_mad *mad, struct ib_grh *grh, - struct ib_wc *wc, struct ib_device *device, - int port_num, int qpn) +void agent_send_response(struct ib_mad *mad, struct ib_grh *grh, + struct ib_wc *wc, struct ib_device *device, + int port_num, int qpn) { struct ib_agent_port_private *port_priv; struct ib_mad_agent *agent; struct ib_mad_send_buf *send_buf; struct ib_ah *ah; - int ret; struct ib_mad_send_wr_private *mad_send_wr; if (device->node_type == RDMA_NODE_IB_SWITCH) @@ -96,23 +95,21 @@ int agent_send_response(struct ib_mad *mad, struct ib_grh *grh, if (!port_priv) { printk(KERN_ERR SPFX "Unable to find port agent\n"); - return -ENODEV; + return; } agent = port_priv->agent[qpn]; ah = ib_create_ah_from_wc(agent->qp->pd, wc, grh, port_num); if (IS_ERR(ah)) { - ret = PTR_ERR(ah); - printk(KERN_ERR SPFX "ib_create_ah_from_wc error:%d\n", ret); - return ret; + printk(KERN_ERR SPFX "ib_create_ah_from_wc error\n"); + return; } send_buf = ib_create_send_mad(agent, wc->src_qp, wc->pkey_index, 0, IB_MGMT_MAD_HDR, IB_MGMT_MAD_DATA, GFP_KERNEL); if (IS_ERR(send_buf)) { - ret = PTR_ERR(send_buf); - printk(KERN_ERR SPFX "ib_create_send_mad error:%d\n", ret); + printk(KERN_ERR SPFX "ib_create_send_mad error\n"); goto err1; } @@ -126,16 +123,15 @@ int agent_send_response(struct ib_mad *mad, struct ib_grh *grh, mad_send_wr->send_wr.wr.ud.port_num = port_num; } - if ((ret = ib_post_send_mad(send_buf, NULL))) { - printk(KERN_ERR SPFX "ib_post_send_mad error:%d\n", ret); + if (ib_post_send_mad(send_buf, NULL)) { + printk(KERN_ERR SPFX "ib_post_send_mad error\n"); goto err2; } - return 0; + return; err2: ib_free_send_mad(send_buf); err1: ib_destroy_ah(ah); - return ret; } static void agent_send_handler(struct ib_mad_agent *mad_agent, diff --git a/drivers/infiniband/core/agent.h b/drivers/infiniband/core/agent.h index 86d72fab37b..fb9ed1489f9 100644 --- a/drivers/infiniband/core/agent.h +++ b/drivers/infiniband/core/agent.h @@ -46,8 +46,8 @@ extern int ib_agent_port_open(struct ib_device *device, int port_num); extern int ib_agent_port_close(struct ib_device *device, int port_num); -extern int agent_send_response(struct ib_mad *mad, struct ib_grh *grh, - struct ib_wc *wc, struct ib_device *device, - int port_num, int qpn); +extern void agent_send_response(struct ib_mad *mad, struct ib_grh *grh, + struct ib_wc *wc, struct ib_device *device, + int port_num, int qpn); #endif /* __AGENT_H_ */ diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c index 3ada17c0f23..2506c43ba04 100644 --- a/drivers/infiniband/core/device.c +++ b/drivers/infiniband/core/device.c @@ -702,7 +702,7 @@ int ib_find_pkey(struct ib_device *device, if (ret) return ret; - if (pkey == tmp_pkey) { + if ((pkey & 0x7fff) == (tmp_pkey & 0x7fff)) { *index = i; return 0; } diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c index bc547f1d34b..6f4287716ab 100644 --- a/drivers/infiniband/core/mad.c +++ b/drivers/infiniband/core/mad.c @@ -1842,16 +1842,11 @@ static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv, { struct ib_mad_qp_info *qp_info; struct ib_mad_private_header *mad_priv_hdr; - struct ib_mad_private *recv, *response; + struct ib_mad_private *recv, *response = NULL; struct ib_mad_list_head *mad_list; struct ib_mad_agent_private *mad_agent; int port_num; - response = kmem_cache_alloc(ib_mad_cache, GFP_KERNEL); - if (!response) - printk(KERN_ERR PFX "ib_mad_recv_done_handler no memory " - "for response buffer\n"); - mad_list = (struct ib_mad_list_head *)(unsigned long)wc->wr_id; qp_info = mad_list->mad_queue->qp_info; dequeue_mad(mad_list); @@ -1879,6 +1874,13 @@ static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv, if (!validate_mad(&recv->mad.mad, qp_info->qp->qp_num)) goto out; + response = kmem_cache_alloc(ib_mad_cache, GFP_KERNEL); + if (!response) { + printk(KERN_ERR PFX "ib_mad_recv_done_handler no memory " + "for response buffer\n"); + goto out; + } + if (port_priv->device->node_type == RDMA_NODE_IB_SWITCH) port_num = wc->port_num; else @@ -1914,12 +1916,11 @@ static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv, response->header.recv_wc.recv_buf.mad = &response->mad.mad; response->header.recv_wc.recv_buf.grh = &response->grh; - if (!agent_send_response(&response->mad.mad, - &response->grh, wc, - port_priv->device, - smi_get_fwd_port(&recv->mad.smp), - qp_info->qp->qp_num)) - response = NULL; + agent_send_response(&response->mad.mad, + &response->grh, wc, + port_priv->device, + smi_get_fwd_port(&recv->mad.smp), + qp_info->qp->qp_num); goto out; } diff --git a/drivers/infiniband/core/mad_rmpp.c b/drivers/infiniband/core/mad_rmpp.c index 3663fd7022b..d43bc62005b 100644 --- a/drivers/infiniband/core/mad_rmpp.c +++ b/drivers/infiniband/core/mad_rmpp.c @@ -163,8 +163,10 @@ static struct ib_mad_send_buf *alloc_response_msg(struct ib_mad_agent *agent, hdr_len, 0, GFP_KERNEL); if (IS_ERR(msg)) ib_destroy_ah(ah); - else + else { msg->ah = ah; + msg->context[0] = ah; + } return msg; } @@ -197,9 +199,7 @@ static void ack_ds_ack(struct ib_mad_agent_private *agent, void ib_rmpp_send_handler(struct ib_mad_send_wc *mad_send_wc) { - struct ib_rmpp_mad *rmpp_mad = mad_send_wc->send_buf->mad; - - if (rmpp_mad->rmpp_hdr.rmpp_type != IB_MGMT_RMPP_TYPE_ACK) + if (mad_send_wc->send_buf->context[0] == mad_send_wc->send_buf->ah) ib_destroy_ah(mad_send_wc->send_buf->ah); ib_free_send_mad(mad_send_wc->send_buf); } diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c index 20ab6b3e484..d271bd715c1 100644 --- a/drivers/infiniband/core/sa_query.c +++ b/drivers/infiniband/core/sa_query.c @@ -385,9 +385,7 @@ static void update_sm_ah(struct work_struct *work) new_ah->pkey_index = 0; if (ib_find_pkey(port->agent->device, port->port_num, - IB_DEFAULT_PKEY_FULL, &new_ah->pkey_index) && - ib_find_pkey(port->agent->device, port->port_num, - IB_DEFAULT_PKEY_PARTIAL, &new_ah->pkey_index)) + IB_DEFAULT_PKEY_FULL, &new_ah->pkey_index)) printk(KERN_ERR "Couldn't find index for default PKey\n"); memset(&ah_attr, 0, sizeof ah_attr); diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c index 26d0470eef6..664d2faa9e7 100644 --- a/drivers/infiniband/core/umem.c +++ b/drivers/infiniband/core/umem.c @@ -40,6 +40,11 @@ #include "uverbs.h" +#define IB_UMEM_MAX_PAGE_CHUNK \ + ((PAGE_SIZE - offsetof(struct ib_umem_chunk, page_list)) / \ + ((void *) &((struct ib_umem_chunk *) 0)->page_list[1] - \ + (void *) &((struct ib_umem_chunk *) 0)->page_list[0])) + static void __ib_umem_release(struct ib_device *dev, struct ib_umem *umem, int dirty) { struct ib_umem_chunk *chunk, *tmp; diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c index 9574088f0d4..1cdfcd43b0b 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_cm.c +++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c @@ -139,7 +139,7 @@ static void release_tid(struct t3cdev *tdev, u32 hwtid, struct sk_buff *skb) req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_TID_RELEASE, hwtid)); skb->priority = CPL_PRIORITY_SETUP; - tdev->send(tdev, skb); + cxgb3_ofld_send(tdev, skb); return; } @@ -161,7 +161,7 @@ int iwch_quiesce_tid(struct iwch_ep *ep) req->val = cpu_to_be64(1 << S_TCB_RX_QUIESCE); skb->priority = CPL_PRIORITY_DATA; - ep->com.tdev->send(ep->com.tdev, skb); + cxgb3_ofld_send(ep->com.tdev, skb); return 0; } @@ -183,7 +183,7 @@ int iwch_resume_tid(struct iwch_ep *ep) req->val = 0; skb->priority = CPL_PRIORITY_DATA; - ep->com.tdev->send(ep->com.tdev, skb); + cxgb3_ofld_send(ep->com.tdev, skb); return 0; } @@ -784,7 +784,7 @@ static int update_rx_credits(struct iwch_ep *ep, u32 credits) OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_RX_DATA_ACK, ep->hwtid)); req->credit_dack = htonl(V_RX_CREDITS(credits) | V_RX_FORCE_ACK(1)); skb->priority = CPL_PRIORITY_ACK; - ep->com.tdev->send(ep->com.tdev, skb); + cxgb3_ofld_send(ep->com.tdev, skb); return credits; } @@ -1152,7 +1152,7 @@ static int listen_start(struct iwch_listen_ep *ep) req->opt1 = htonl(V_CONN_POLICY(CPL_CONN_POLICY_ASK)); skb->priority = 1; - ep->com.tdev->send(ep->com.tdev, skb); + cxgb3_ofld_send(ep->com.tdev, skb); return 0; } @@ -1186,7 +1186,7 @@ static int listen_stop(struct iwch_listen_ep *ep) req->cpu_idx = 0; OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_CLOSE_LISTSRV_REQ, ep->stid)); skb->priority = 1; - ep->com.tdev->send(ep->com.tdev, skb); + cxgb3_ofld_send(ep->com.tdev, skb); return 0; } @@ -1264,7 +1264,7 @@ static void reject_cr(struct t3cdev *tdev, u32 hwtid, __be32 peer_ip, rpl->opt0l_status = htonl(CPL_PASS_OPEN_REJECT); rpl->opt2 = 0; rpl->rsvd = rpl->opt2; - tdev->send(tdev, skb); + cxgb3_ofld_send(tdev, skb); } } @@ -1557,7 +1557,7 @@ static int peer_abort(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) rpl->wr.wr_lo = htonl(V_WR_TID(ep->hwtid)); OPCODE_TID(rpl) = htonl(MK_OPCODE_TID(CPL_ABORT_RPL, ep->hwtid)); rpl->cmd = CPL_ABORT_NO_RST; - ep->com.tdev->send(ep->com.tdev, rpl_skb); + cxgb3_ofld_send(ep->com.tdev, rpl_skb); if (state != ABORTING) { state_set(&ep->com, DEAD); release_ep_resources(ep); diff --git a/drivers/infiniband/hw/mlx4/cq.c b/drivers/infiniband/hw/mlx4/cq.c index 660b27aecae..8bf44daf45e 100644 --- a/drivers/infiniband/hw/mlx4/cq.c +++ b/drivers/infiniband/hw/mlx4/cq.c @@ -389,7 +389,7 @@ static int mlx4_ib_poll_one(struct mlx4_ib_cq *cq, wc->opcode = IB_WC_SEND; break; case MLX4_OPCODE_RDMA_READ: - wc->opcode = IB_WC_SEND; + wc->opcode = IB_WC_RDMA_READ; wc->byte_len = be32_to_cpu(cqe->byte_cnt); break; case MLX4_OPCODE_ATOMIC_CS: diff --git a/drivers/infiniband/hw/mlx4/mad.c b/drivers/infiniband/hw/mlx4/mad.c index 333091787c5..0ed02b7834d 100644 --- a/drivers/infiniband/hw/mlx4/mad.c +++ b/drivers/infiniband/hw/mlx4/mad.c @@ -109,7 +109,7 @@ int mlx4_MAD_IFC(struct mlx4_ib_dev *dev, int ignore_mkey, int ignore_bkey, in_modifier, op_modifier, MLX4_CMD_MAD_IFC, MLX4_CMD_TIME_CLASS_C); - if (!err); + if (!err) memcpy(response_mad, outmailbox->buf, 256); mlx4_free_cmd_mailbox(dev->dev, inmailbox); diff --git a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c index 982eb88e27e..563aeacf9e1 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c @@ -211,6 +211,7 @@ out_free_cq: out_free_mr: ib_dereg_mr(priv->mr); + ipoib_cm_dev_cleanup(dev); out_free_pd: ib_dealloc_pd(priv->pd); diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index f01ca182f22..f6a05142814 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -75,16 +75,12 @@ module_param(topspin_workarounds, int, 0444); MODULE_PARM_DESC(topspin_workarounds, "Enable workarounds for Topspin/Cisco SRP target bugs if != 0"); -static const u8 topspin_oui[3] = { 0x00, 0x05, 0xad }; - static int mellanox_workarounds = 1; module_param(mellanox_workarounds, int, 0444); MODULE_PARM_DESC(mellanox_workarounds, "Enable workarounds for Mellanox SRP target bugs if != 0"); -static const u8 mellanox_oui[3] = { 0x00, 0x02, 0xc9 }; - static void srp_add_one(struct ib_device *device); static void srp_remove_one(struct ib_device *device); static void srp_completion(struct ib_cq *cq, void *target_ptr); @@ -108,6 +104,24 @@ static const char *srp_target_info(struct Scsi_Host *host) return host_to_target(host)->target_name; } +static int srp_target_is_topspin(struct srp_target_port *target) +{ + static const u8 topspin_oui[3] = { 0x00, 0x05, 0xad }; + static const u8 cisco_oui[3] = { 0x00, 0x1b, 0x0d }; + + return topspin_workarounds && + (!memcmp(&target->ioc_guid, topspin_oui, sizeof topspin_oui) || + !memcmp(&target->ioc_guid, cisco_oui, sizeof cisco_oui)); +} + +static int srp_target_is_mellanox(struct srp_target_port *target) +{ + static const u8 mellanox_oui[3] = { 0x00, 0x02, 0xc9 }; + + return mellanox_workarounds && + !memcmp(&target->ioc_guid, mellanox_oui, sizeof mellanox_oui); +} + static struct srp_iu *srp_alloc_iu(struct srp_host *host, size_t size, gfp_t gfp_mask, enum dma_data_direction direction) @@ -360,7 +374,7 @@ static int srp_send_req(struct srp_target_port *target) * zero out the first 8 bytes of our initiator port ID and set * the second 8 bytes to the local node GUID. */ - if (topspin_workarounds && !memcmp(&target->ioc_guid, topspin_oui, 3)) { + if (srp_target_is_topspin(target)) { printk(KERN_DEBUG PFX "Topspin/Cisco initiator port ID workaround " "activated for target GUID %016llx\n", (unsigned long long) be64_to_cpu(target->ioc_guid)); @@ -585,8 +599,8 @@ static int srp_map_fmr(struct srp_target_port *target, struct scatterlist *scat, if (!dev->fmr_pool) return -ENODEV; - if ((ib_sg_dma_address(ibdev, &scat[0]) & ~dev->fmr_page_mask) && - mellanox_workarounds && !memcmp(&target->ioc_guid, mellanox_oui, 3)) + if (srp_target_is_mellanox(target) && + (ib_sg_dma_address(ibdev, &scat[0]) & ~dev->fmr_page_mask)) return -EINVAL; len = page_cnt = 0; @@ -1087,8 +1101,7 @@ static void srp_cm_rej_handler(struct ib_cm_id *cm_id, break; case IB_CM_REJ_PORT_REDIRECT: - if (topspin_workarounds && - !memcmp(&target->ioc_guid, topspin_oui, 3)) { + if (srp_target_is_topspin(target)) { /* * Topspin/Cisco SRP gateways incorrectly send * reject reason code 25 when they mean 24 diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 9b26574f146..d602b8fa7d4 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -68,6 +68,7 @@ config INPUT_WISTRON_BTNS select INPUT_POLLDEV select NEW_LEDS select LEDS_CLASS + select CHECK_SIGNATURE help Say Y here for support of Winstron laptop button interface, used on laptops of various brands, including Acer and Fujitsu-Siemens. If diff --git a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c index b1a26e02df0..60843b3f3b6 100644 --- a/drivers/isdn/hisax/hfc_usb.c +++ b/drivers/isdn/hisax/hfc_usb.c @@ -1,12 +1,12 @@ /* * hfc_usb.c * - * $Id: hfc_usb.c,v 2.3.2.13 2006/02/17 17:17:22 mbachem Exp $ + * $Id: hfc_usb.c,v 2.3.2.20 2007/08/20 14:07:54 mbachem Exp $ * * modular HiSax ISDN driver for Colognechip HFC-S USB chip * - * Authors : Peter Sprenger (sprenger@moving-bytes.de) - * Martin Bachem (info@colognechip.com) + * Authors : Peter Sprenger (sprenger@moving-bytes.de) + * Martin Bachem (m.bachem@gmx.de, info@colognechip.com) * * based on the first hfc_usb driver of * Werner Cornelius (werner@isdn-development.de) @@ -37,24 +37,25 @@ #include <linux/kernel_stat.h> #include <linux/usb.h> #include <linux/kernel.h> +#include <linux/smp_lock.h> +#include <linux/sched.h> +#include <linux/moduleparam.h> #include "hisax.h" #include "hisax_if.h" #include "hfc_usb.h" static const char *hfcusb_revision = - "$Revision: 2.3.2.13 $ $Date: 2006/02/17 17:17:22 $ "; + "$Revision: 2.3.2.20 $ $Date: 2007/08/20 14:07:54 $ "; /* Hisax debug support -* use "modprobe debug=x" where x is bitfield of USB_DBG & ISDN_DBG +* debug flags defined in hfc_usb.h as HFCUSB_DBG_[*] */ -#ifdef CONFIG_HISAX_DEBUG -#include <linux/moduleparam.h> #define __debug_variable hfc_debug #include "hisax_debug.h" static u_int debug; module_param(debug, uint, 0); static int hfc_debug; -#endif + /* private vendor specific data */ typedef struct { @@ -63,9 +64,7 @@ typedef struct { char *vend_name; // device name } hfcsusb_vdata; -/****************************************/ -/* data defining the devices to be used */ -/****************************************/ +/* VID/PID device list */ static struct usb_device_id hfcusb_idtab[] = { { USB_DEVICE(0x0959, 0x2bd0), @@ -90,49 +89,47 @@ static struct usb_device_id hfcusb_idtab[] = { .driver_info = (unsigned long) &((hfcsusb_vdata) {LED_SCHEME1, {4, 0, 2, 1}, "Stollmann USB TA"}), - }, + }, { USB_DEVICE(0x0742, 0x2009), .driver_info = (unsigned long) &((hfcsusb_vdata) {LED_SCHEME1, {4, 0, 2, 1}, "Aceex USB ISDN TA"}), - }, + }, { USB_DEVICE(0x0742, 0x200A), .driver_info = (unsigned long) &((hfcsusb_vdata) {LED_SCHEME1, {4, 0, 2, 1}, "OEM USB ISDN TA"}), - }, + }, { USB_DEVICE(0x08e3, 0x0301), .driver_info = (unsigned long) &((hfcsusb_vdata) {LED_SCHEME1, {2, 0, 1, 4}, "Olitec USB RNIS"}), - }, + }, { USB_DEVICE(0x07fa, 0x0846), .driver_info = (unsigned long) &((hfcsusb_vdata) {LED_SCHEME1, {0x80, -64, -32, -16}, "Bewan Modem RNIS USB"}), - }, + }, { USB_DEVICE(0x07fa, 0x0847), .driver_info = (unsigned long) &((hfcsusb_vdata) {LED_SCHEME1, {0x80, -64, -32, -16}, "Djinn Numeris USB"}), - }, + }, { USB_DEVICE(0x07b0, 0x0006), .driver_info = (unsigned long) &((hfcsusb_vdata) {LED_SCHEME1, {0x80, -64, -32, -16}, "Twister ISDN TA"}), - }, + }, { } }; -/***************************************************************/ /* structure defining input+output fifos (interrupt/bulk mode) */ -/***************************************************************/ struct usb_fifo; /* forward definition */ typedef struct iso_urb_struct { struct urb *purb; @@ -140,8 +137,8 @@ typedef struct iso_urb_struct { struct usb_fifo *owner_fifo; /* pointer to owner fifo */ } iso_urb_struct; - struct hfcusb_data; /* forward definition */ + typedef struct usb_fifo { int fifonum; /* fifo index attached to this structure */ int active; /* fifo is currently active */ @@ -160,15 +157,12 @@ typedef struct usb_fifo { struct hisax_if *hif; /* hisax interface */ int delete_flg; /* only delete skbuff once */ int last_urblen; /* remember length of last packet */ - } usb_fifo; -/*********************************************/ /* structure holding all data for one device */ -/*********************************************/ typedef struct hfcusb_data { /* HiSax Interface for loadable Layer1 drivers */ - struct hisax_d_if d_if; /* see hisax_if.h */ + struct hisax_d_if d_if; /* see hisax_if.h */ struct hisax_b_if b_if[2]; /* see hisax_if.h */ int protocol; @@ -176,12 +170,13 @@ typedef struct hfcusb_data { int if_used; /* used interface number */ int alt_used; /* used alternate config */ int ctrl_paksize; /* control pipe packet size */ - int ctrl_in_pipe, ctrl_out_pipe; /* handles for control pipe */ + int ctrl_in_pipe, /* handles for control pipe */ + ctrl_out_pipe; int cfg_used; /* configuration index used */ int vend_idx; /* vendor found */ int b_mode[2]; /* B-channel mode */ int l1_activated; /* layer 1 activated */ - int disc_flag; /* 'true' if device was disonnected to avoid some USB actions */ + int disc_flag; /* TRUE if device was disonnected to avoid some USB actions */ int packet_size, iso_packet_size; /* control pipe background handling */ @@ -208,7 +203,6 @@ typedef struct hfcusb_data { static void collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish); - static inline const char * symbolic(struct hfcusb_symbolic_list list[], const int num) { @@ -219,10 +213,6 @@ symbolic(struct hfcusb_symbolic_list list[], const int num) return "<unknown ERROR>"; } - -/******************************************************/ -/* start next background transfer for control channel */ -/******************************************************/ static void ctrl_start_transfer(hfcusb_data * hfc) { @@ -240,10 +230,6 @@ ctrl_start_transfer(hfcusb_data * hfc) } } /* ctrl_start_transfer */ -/************************************/ -/* queue a control transfer request */ -/* return 0 on success. */ -/************************************/ static int queue_control_request(hfcusb_data * hfc, __u8 reg, __u8 val, int action) { @@ -260,19 +246,8 @@ queue_control_request(hfcusb_data * hfc, __u8 reg, __u8 val, int action) if (++hfc->ctrl_cnt == 1) ctrl_start_transfer(hfc); return (0); -} /* queue_control_request */ - -static int -control_action_handler(hfcusb_data * hfc, int reg, int val, int action) -{ - if (!action) - return (1); /* no action defined */ - return (0); } -/***************************************************************/ -/* control completion routine handling background control cmds */ -/***************************************************************/ static void ctrl_complete(struct urb *urb) { @@ -282,9 +257,6 @@ ctrl_complete(struct urb *urb) urb->dev = hfc->dev; if (hfc->ctrl_cnt) { buf = &hfc->ctrl_buff[hfc->ctrl_out_idx]; - control_action_handler(hfc, buf->hfc_reg, buf->reg_val, - buf->action); - hfc->ctrl_cnt--; /* decrement actual count */ if (++hfc->ctrl_out_idx >= HFC_CTRL_BUFSIZE) hfc->ctrl_out_idx = 0; /* pointer wrap */ @@ -293,9 +265,7 @@ ctrl_complete(struct urb *urb) } } /* ctrl_complete */ -/***************************************************/ /* write led data to auxport & invert if necessary */ -/***************************************************/ static void write_led(hfcusb_data * hfc, __u8 led_state) { @@ -305,9 +275,6 @@ write_led(hfcusb_data * hfc, __u8 led_state) } } -/**************************/ -/* handle LED bits */ -/**************************/ static void set_led_bit(hfcusb_data * hfc, signed short led_bits, int unset) { @@ -324,9 +291,7 @@ set_led_bit(hfcusb_data * hfc, signed short led_bits, int unset) } } -/**************************/ -/* handle LED requests */ -/**************************/ +/* handle LED requests */ static void handle_led(hfcusb_data * hfc, int event) { @@ -339,85 +304,73 @@ handle_led(hfcusb_data * hfc, int event) switch (event) { case LED_POWER_ON: - set_led_bit(hfc, driver_info->led_bits[0], - 0); - set_led_bit(hfc, driver_info->led_bits[1], - 1); - set_led_bit(hfc, driver_info->led_bits[2], - 1); - set_led_bit(hfc, driver_info->led_bits[3], - 1); + set_led_bit(hfc, driver_info->led_bits[0], 0); + set_led_bit(hfc, driver_info->led_bits[1], 1); + set_led_bit(hfc, driver_info->led_bits[2], 1); + set_led_bit(hfc, driver_info->led_bits[3], 1); break; - case LED_POWER_OFF: /* no Power off handling */ + case LED_POWER_OFF: + set_led_bit(hfc, driver_info->led_bits[0], 1); + set_led_bit(hfc, driver_info->led_bits[1], 1); + set_led_bit(hfc, driver_info->led_bits[2], 1); + set_led_bit(hfc, driver_info->led_bits[3], 1); break; case LED_S0_ON: - set_led_bit(hfc, driver_info->led_bits[1], - 0); + set_led_bit(hfc, driver_info->led_bits[1], 0); break; case LED_S0_OFF: - set_led_bit(hfc, driver_info->led_bits[1], - 1); + set_led_bit(hfc, driver_info->led_bits[1], 1); break; case LED_B1_ON: - set_led_bit(hfc, driver_info->led_bits[2], - 0); + set_led_bit(hfc, driver_info->led_bits[2], 0); break; case LED_B1_OFF: - set_led_bit(hfc, driver_info->led_bits[2], - 1); + set_led_bit(hfc, driver_info->led_bits[2], 1); break; case LED_B2_ON: - set_led_bit(hfc, driver_info->led_bits[3], - 0); + set_led_bit(hfc, driver_info->led_bits[3], 0); break; case LED_B2_OFF: - set_led_bit(hfc, driver_info->led_bits[3], - 1); + set_led_bit(hfc, driver_info->led_bits[3], 1); break; } write_led(hfc, hfc->led_state); } -/********************************/ -/* called when timer t3 expires */ -/********************************/ +/* ISDN l1 timer T3 expires */ static void l1_timer_expire_t3(hfcusb_data * hfc) { hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, PH_DEACTIVATE | INDICATION, NULL); -#ifdef CONFIG_HISAX_DEBUG - DBG(ISDN_DBG, + + DBG(HFCUSB_DBG_STATES, "HFC-S USB: PH_DEACTIVATE | INDICATION sent (T3 expire)"); -#endif - hfc->l1_activated = false; + + hfc->l1_activated = 0; handle_led(hfc, LED_S0_OFF); /* deactivate : */ queue_control_request(hfc, HFCUSB_STATES, 0x10, 1); queue_control_request(hfc, HFCUSB_STATES, 3, 1); } -/********************************/ -/* called when timer t4 expires */ -/********************************/ +/* ISDN l1 timer T4 expires */ static void l1_timer_expire_t4(hfcusb_data * hfc) { hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, PH_DEACTIVATE | INDICATION, NULL); -#ifdef CONFIG_HISAX_DEBUG - DBG(ISDN_DBG, + + DBG(HFCUSB_DBG_STATES, "HFC-S USB: PH_DEACTIVATE | INDICATION sent (T4 expire)"); -#endif - hfc->l1_activated = false; + + hfc->l1_activated = 0; handle_led(hfc, LED_S0_OFF); } -/*****************************/ -/* handle S0 state changes */ -/*****************************/ +/* S0 state changed */ static void -state_handler(hfcusb_data * hfc, __u8 state) +s0_state_handler(hfcusb_data * hfc, __u8 state) { __u8 old_state; @@ -425,38 +378,29 @@ state_handler(hfcusb_data * hfc, __u8 state) if (state == old_state || state < 1 || state > 8) return; -#ifdef CONFIG_HISAX_DEBUG - DBG(ISDN_DBG, "HFC-S USB: new S0 state:%d old_state:%d", state, - old_state); -#endif + DBG(HFCUSB_DBG_STATES, "HFC-S USB: S0 statechange(%d -> %d)", + old_state, state); + if (state < 4 || state == 7 || state == 8) { if (timer_pending(&hfc->t3_timer)) del_timer(&hfc->t3_timer); -#ifdef CONFIG_HISAX_DEBUG - DBG(ISDN_DBG, "HFC-S USB: T3 deactivated"); -#endif + DBG(HFCUSB_DBG_STATES, "HFC-S USB: T3 deactivated"); } if (state >= 7) { if (timer_pending(&hfc->t4_timer)) del_timer(&hfc->t4_timer); -#ifdef CONFIG_HISAX_DEBUG - DBG(ISDN_DBG, "HFC-S USB: T4 deactivated"); -#endif + DBG(HFCUSB_DBG_STATES, "HFC-S USB: T4 deactivated"); } if (state == 7 && !hfc->l1_activated) { hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, PH_ACTIVATE | INDICATION, NULL); -#ifdef CONFIG_HISAX_DEBUG - DBG(ISDN_DBG, "HFC-S USB: PH_ACTIVATE | INDICATION sent"); -#endif - hfc->l1_activated = true; + DBG(HFCUSB_DBG_STATES, "HFC-S USB: PH_ACTIVATE | INDICATION sent"); + hfc->l1_activated = 1; handle_led(hfc, LED_S0_ON); } else if (state <= 3 /* && activated */ ) { if (old_state == 7 || old_state == 8) { -#ifdef CONFIG_HISAX_DEBUG - DBG(ISDN_DBG, "HFC-S USB: T4 activated"); -#endif + DBG(HFCUSB_DBG_STATES, "HFC-S USB: T4 activated"); if (!timer_pending(&hfc->t4_timer)) { hfc->t4_timer.expires = jiffies + (HFC_TIMER_T4 * HZ) / 1000; @@ -466,18 +410,15 @@ state_handler(hfcusb_data * hfc, __u8 state) hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, PH_DEACTIVATE | INDICATION, NULL); -#ifdef CONFIG_HISAX_DEBUG - DBG(ISDN_DBG, + DBG(HFCUSB_DBG_STATES, "HFC-S USB: PH_DEACTIVATE | INDICATION sent"); -#endif - hfc->l1_activated = false; + hfc->l1_activated = 0; handle_led(hfc, LED_S0_OFF); } } hfc->l1_state = state; } -/* prepare iso urb */ static void fill_isoc_urb(struct urb *urb, struct usb_device *dev, unsigned int pipe, void *buf, int num_packets, int packet_size, int interval, @@ -503,15 +444,16 @@ fill_isoc_urb(struct urb *urb, struct usb_device *dev, unsigned int pipe, } /* allocs urbs and start isoc transfer with two pending urbs to avoid - gaps in the transfer chain */ + * gaps in the transfer chain + */ static int start_isoc_chain(usb_fifo * fifo, int num_packets_per_urb, usb_complete_t complete, int packet_size) { int i, k, errcode; - printk(KERN_INFO "HFC-S USB: starting ISO-chain for Fifo %i\n", - fifo->fifonum); + DBG(HFCUSB_DBG_INIT, "HFC-S USB: starting ISO-URBs for fifo:%d\n", + fifo->fifonum); /* allocate Memory for Iso out Urbs */ for (i = 0; i < 2; i++) { @@ -556,10 +498,9 @@ start_isoc_chain(usb_fifo * fifo, int num_packets_per_urb, errcode = usb_submit_urb(fifo->iso[i].purb, GFP_KERNEL); fifo->active = (errcode >= 0) ? 1 : 0; - if (errcode < 0) { - printk(KERN_INFO "HFC-S USB: %s URB nr:%d\n", - symbolic(urb_errlist, errcode), i); - }; + if (errcode < 0) + printk(KERN_INFO "HFC-S USB: usb_submit_urb URB nr:%d, error(%i): '%s'\n", + i, errcode, symbolic(urb_errlist, errcode)); } return (fifo->active); } @@ -572,16 +513,15 @@ stop_isoc_chain(usb_fifo * fifo) for (i = 0; i < 2; i++) { if (fifo->iso[i].purb) { -#ifdef CONFIG_HISAX_DEBUG - DBG(USB_DBG, + DBG(HFCUSB_DBG_INIT, "HFC-S USB: Stopping iso chain for fifo %i.%i", fifo->fifonum, i); -#endif usb_kill_urb(fifo->iso[i].purb); usb_free_urb(fifo->iso[i].purb); fifo->iso[i].purb = NULL; } } + usb_kill_urb(fifo->urb); usb_free_urb(fifo->urb); fifo->urb = NULL; @@ -594,9 +534,6 @@ static int iso_packets[8] = ISOC_PACKETS_D, ISOC_PACKETS_D, ISOC_PACKETS_D, ISOC_PACKETS_D }; -/*****************************************************/ -/* transmit completion routine for all ISO tx fifos */ -/*****************************************************/ static void tx_iso_complete(struct urb *urb) { @@ -607,20 +544,38 @@ tx_iso_complete(struct urb *urb) errcode; int frame_complete, transp_mode, fifon, status; __u8 threshbit; - __u8 threshtable[8] = { 1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80 }; fifon = fifo->fifonum; status = urb->status; tx_offset = 0; + /* ISO transfer only partially completed, + look at individual frame status for details */ + if (status == -EXDEV) { + DBG(HFCUSB_DBG_VERBOSE_USB, "HFC-S USB: tx_iso_complete with -EXDEV" + ", urb->status %d, fifonum %d\n", + status, fifon); + + for (k = 0; k < iso_packets[fifon]; ++k) { + errcode = urb->iso_frame_desc[k].status; + if (errcode) + DBG(HFCUSB_DBG_VERBOSE_USB, "HFC-S USB: tx_iso_complete " + "packet %i, status: %i\n", + k, errcode); + } + + // clear status, so go on with ISO transfers + status = 0; + } + if (fifo->active && !status) { transp_mode = 0; if (fifon < 4 && hfc->b_mode[fifon / 2] == L1_MODE_TRANS) - transp_mode = true; + transp_mode = 1; /* is FifoFull-threshold set for our channel? */ - threshbit = threshtable[fifon] & hfc->threshold_mask; + threshbit = (hfc->threshold_mask & (1 << fifon)); num_isoc_packets = iso_packets[fifon]; /* predict dataflow to avoid fifo overflow */ @@ -635,8 +590,9 @@ tx_iso_complete(struct urb *urb) tx_iso_complete, urb->context); memset(context_iso_urb->buffer, 0, sizeof(context_iso_urb->buffer)); - frame_complete = false; - /* Generate next Iso Packets */ + frame_complete = 0; + + /* Generate next ISO Packets */ for (k = 0; k < num_isoc_packets; ++k) { if (fifo->skbuff) { len = fifo->skbuff->len; @@ -661,7 +617,7 @@ tx_iso_complete(struct urb *urb) /* add 2 byte flags and 16bit CRC at end of ISDN frame */ fifo->bit_line += 32; } - frame_complete = true; + frame_complete = 1; } memcpy(context_iso_urb->buffer + @@ -688,7 +644,7 @@ tx_iso_complete(struct urb *urb) } if (frame_complete) { - fifo->delete_flg = true; + fifo->delete_flg = 1; fifo->hif->l1l2(fifo->hif, PH_DATA | CONFIRM, (void *) (unsigned long) fifo->skbuff-> @@ -696,30 +652,26 @@ tx_iso_complete(struct urb *urb) if (fifo->skbuff && fifo->delete_flg) { dev_kfree_skb_any(fifo->skbuff); fifo->skbuff = NULL; - fifo->delete_flg = false; + fifo->delete_flg = 0; } - frame_complete = false; + frame_complete = 0; } } errcode = usb_submit_urb(urb, GFP_ATOMIC); if (errcode < 0) { printk(KERN_INFO - "HFC-S USB: error submitting ISO URB: %d \n", + "HFC-S USB: error submitting ISO URB: %d\n", errcode); } } else { if (status && !hfc->disc_flag) { printk(KERN_INFO - "HFC-S USB: tx_iso_complete : urb->status %s (%i), fifonum=%d\n", - symbolic(urb_errlist, status), status, - fifon); + "HFC-S USB: tx_iso_complete: error(%i): '%s', fifonum=%d\n", + status, symbolic(urb_errlist, status), fifon); } } -} /* tx_iso_complete */ +} -/*****************************************************/ -/* receive completion routine for all ISO tx fifos */ -/*****************************************************/ static void rx_iso_complete(struct urb *urb) { @@ -731,21 +683,25 @@ rx_iso_complete(struct urb *urb) unsigned int iso_status; __u8 *buf; static __u8 eof[8]; -#ifdef CONFIG_HISAX_DEBUG - __u8 i; -#endif fifon = fifo->fifonum; status = urb->status; if (urb->status == -EOVERFLOW) { -#ifdef CONFIG_HISAX_DEBUG - DBG(USB_DBG, - "HFC-USB: ignoring USB DATAOVERRUN for fifo %i \n", - fifon); -#endif + DBG(HFCUSB_DBG_VERBOSE_USB, + "HFC-USB: ignoring USB DATAOVERRUN fifo(%i)", fifon); + status = 0; + } + + /* ISO transfer only partially completed, + look at individual frame status for details */ + if (status == -EXDEV) { + DBG(HFCUSB_DBG_VERBOSE_USB, "HFC-S USB: rx_iso_complete with -EXDEV " + "urb->status %d, fifonum %d\n", + status, fifon); status = 0; } + if (fifo->active && !status) { num_isoc_packets = iso_packets[fifon]; maxlen = fifo->usb_packet_maxlen; @@ -754,40 +710,38 @@ rx_iso_complete(struct urb *urb) offset = urb->iso_frame_desc[k].offset; buf = context_iso_urb->buffer + offset; iso_status = urb->iso_frame_desc[k].status; -#ifdef CONFIG_HISAX_DEBUG + if (iso_status && !hfc->disc_flag) - DBG(USB_DBG, - "HFC-S USB: ISO packet failure - status:%x", - iso_status); + DBG(HFCUSB_DBG_VERBOSE_USB, + "HFC-S USB: rx_iso_complete " + "ISO packet %i, status: %i\n", + k, iso_status); - if ((fifon == 5) && (debug > 1)) { - printk(KERN_INFO + if (fifon == HFCUSB_D_RX) { + DBG(HFCUSB_DBG_VERBOSE_USB, "HFC-S USB: ISO-D-RX lst_urblen:%2d " - "act_urblen:%2d max-urblen:%2d " - "EOF:0x%0x DATA: ", + "act_urblen:%2d max-urblen:%2d EOF:0x%0x", fifo->last_urblen, len, maxlen, eof[5]); - for (i = 0; i < len; i++) - printk("%.2x ", buf[i]); - printk("\n"); + + DBG_PACKET(HFCUSB_DBG_VERBOSE_USB, buf, len); } -#endif + if (fifo->last_urblen != maxlen) { /* the threshold mask is in the 2nd status byte */ hfc->threshold_mask = buf[1]; /* care for L1 state only for D-Channel to avoid overlapped iso completions */ - if (fifon == 5) { + if (fifon == HFCUSB_D_RX) { /* the S0 state is in the upper half of the 1st status byte */ - state_handler(hfc, buf[0] >> 4); + s0_state_handler(hfc, buf[0] >> 4); } eof[fifon] = buf[0] & 1; if (len > 2) collect_rx_frame(fifo, buf + 2, len - 2, - (len < - maxlen) ? + (len < maxlen) ? eof[fifon] : 0); } else { collect_rx_frame(fifo, buf, len, @@ -804,41 +758,37 @@ rx_iso_complete(struct urb *urb) rx_iso_complete, urb->context); errcode = usb_submit_urb(urb, GFP_ATOMIC); if (errcode < 0) { - printk(KERN_INFO - "HFC-S USB: error submitting ISO URB: %d \n", + printk(KERN_ERR + "HFC-S USB: error submitting ISO URB: %d\n", errcode); } } else { if (status && !hfc->disc_flag) { - printk(KERN_INFO + printk(KERN_ERR "HFC-S USB: rx_iso_complete : " "urb->status %d, fifonum %d\n", status, fifon); } } -} /* rx_iso_complete */ +} -/*****************************************************/ -/* collect data from interrupt or isochron in */ -/*****************************************************/ +/* collect rx data from INT- and ISO-URBs */ static void collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish) { hfcusb_data *hfc = fifo->hfc; int transp_mode, fifon; -#ifdef CONFIG_HISAX_DEBUG - int i; -#endif + fifon = fifo->fifonum; transp_mode = 0; if (fifon < 4 && hfc->b_mode[fifon / 2] == L1_MODE_TRANS) - transp_mode = true; + transp_mode = 1; if (!fifo->skbuff) { fifo->skbuff = dev_alloc_skb(fifo->max_size + 3); if (!fifo->skbuff) { - printk(KERN_INFO - "HFC-S USB: cannot allocate buffer (dev_alloc_skb) fifo:%d\n", + printk(KERN_ERR + "HFC-S USB: cannot allocate buffer for fifo(%d)\n", fifon); return; } @@ -847,17 +797,11 @@ collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish) if (fifo->skbuff->len + len < fifo->max_size) { memcpy(skb_put(fifo->skbuff, len), data, len); } else { -#ifdef CONFIG_HISAX_DEBUG - printk(KERN_INFO "HFC-S USB: "); - for (i = 0; i < 15; i++) - printk("%.2x ", - fifo->skbuff->data[fifo->skbuff-> - len - 15 + i]); - printk("\n"); -#endif - printk(KERN_INFO - "HCF-USB: got frame exceeded fifo->max_size:%d on fifo:%d\n", + DBG(HFCUSB_DBG_FIFO_ERR, + "HCF-USB: got frame exceeded fifo->max_size(%d) fifo(%d)", fifo->max_size, fifon); + DBG_SKB(HFCUSB_DBG_VERBOSE_USB, fifo->skbuff); + skb_trim(fifo->skbuff, 0); } } if (transp_mode && fifo->skbuff->len >= 128) { @@ -870,6 +814,13 @@ collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish) if (finish) { if ((!fifo->skbuff->data[fifo->skbuff->len - 1]) && (fifo->skbuff->len > 3)) { + + if (fifon == HFCUSB_D_RX) { + DBG(HFCUSB_DBG_DCHANNEL, + "HFC-S USB: D-RX len(%d)", fifo->skbuff->len); + DBG_SKB(HFCUSB_DBG_DCHANNEL, fifo->skbuff); + } + /* remove CRC & status */ skb_trim(fifo->skbuff, fifo->skbuff->len - 3); if (fifon == HFCUSB_PCM_RX) { @@ -882,39 +833,17 @@ collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish) fifo->skbuff); fifo->skbuff = NULL; /* buffer was freed from upper layer */ } else { - if (fifo->skbuff->len > 3) { - printk(KERN_INFO - "HFC-S USB: got frame %d bytes but CRC ERROR on fifo:%d!!!\n", - fifo->skbuff->len, fifon); -#ifdef CONFIG_HISAX_DEBUG - if (debug > 1) { - printk(KERN_INFO "HFC-S USB: "); - for (i = 0; i < 15; i++) - printk("%.2x ", - fifo->skbuff-> - data[fifo->skbuff-> - len - 15 + i]); - printk("\n"); - } -#endif - } -#ifdef CONFIG_HISAX_DEBUG - else { - printk(KERN_INFO - "HFC-S USB: frame to small (%d bytes)!!!\n", - fifo->skbuff->len); - } -#endif + DBG(HFCUSB_DBG_FIFO_ERR, + "HFC-S USB: ERROR frame len(%d) fifo(%d)", + fifo->skbuff->len, fifon); + DBG_SKB(HFCUSB_DBG_VERBOSE_USB, fifo->skbuff); skb_trim(fifo->skbuff, 0); } } } -/***********************************************/ -/* receive completion routine for all rx fifos */ -/***********************************************/ static void -rx_complete(struct urb *urb) +rx_int_complete(struct urb *urb) { int len; int status; @@ -922,18 +851,14 @@ rx_complete(struct urb *urb) usb_fifo *fifo = (usb_fifo *) urb->context; hfcusb_data *hfc = fifo->hfc; static __u8 eof[8]; -#ifdef CONFIG_HISAX_DEBUG - __u8 i; -#endif urb->dev = hfc->dev; /* security init */ fifon = fifo->fifonum; if ((!fifo->active) || (urb->status)) { -#ifdef CONFIG_HISAX_DEBUG - DBG(USB_DBG, "HFC-S USB: RX-Fifo %i is going down (%i)", + DBG(HFCUSB_DBG_INIT, "HFC-S USB: RX-Fifo %i is going down (%i)", fifon, urb->status); -#endif + fifo->urb->interval = 0; /* cancel automatic rescheduling */ if (fifo->skbuff) { dev_kfree_skb_any(fifo->skbuff); @@ -945,22 +870,20 @@ rx_complete(struct urb *urb) buf = fifo->buffer; maxlen = fifo->usb_packet_maxlen; -#ifdef CONFIG_HISAX_DEBUG - if ((fifon == 5) && (debug > 1)) { - printk(KERN_INFO - "HFC-S USB: INT-D-RX lst_urblen:%2d act_urblen:%2d max-urblen:%2d EOF:0x%0x DATA: ", - fifo->last_urblen, len, maxlen, eof[5]); - for (i = 0; i < len; i++) - printk("%.2x ", buf[i]); - printk("\n"); + if (fifon == HFCUSB_D_RX) { + DBG(HFCUSB_DBG_VERBOSE_USB, + "HFC-S USB: INT-D-RX lst_urblen:%2d " + "act_urblen:%2d max-urblen:%2d EOF:0x%0x", + fifo->last_urblen, len, maxlen, + eof[5]); + DBG_PACKET(HFCUSB_DBG_VERBOSE_USB, buf, len); } -#endif if (fifo->last_urblen != fifo->usb_packet_maxlen) { /* the threshold mask is in the 2nd status byte */ hfc->threshold_mask = buf[1]; /* the S0 state is in the upper half of the 1st status byte */ - state_handler(hfc, buf[0] >> 4); + s0_state_handler(hfc, buf[0] >> 4); eof[fifon] = buf[0] & 1; /* if we have more than the 2 status bytes -> collect data */ if (len > 2) @@ -975,20 +898,19 @@ rx_complete(struct urb *urb) status = usb_submit_urb(urb, GFP_ATOMIC); if (status) { printk(KERN_INFO - "HFC-S USB: error resubmitting URN at rx_complete...\n"); + "HFC-S USB: %s error resubmitting URB fifo(%d)\n", + __FUNCTION__, fifon); } -} /* rx_complete */ +} -/***************************************************/ -/* start the interrupt transfer for the given fifo */ -/***************************************************/ +/* start initial INT-URB for certain fifo */ static void start_int_fifo(usb_fifo * fifo) { int errcode; - printk(KERN_INFO "HFC-S USB: starting intr IN fifo:%d\n", - fifo->fifonum); + DBG(HFCUSB_DBG_INIT, "HFC-S USB: starting RX INT-URB for fifo:%d\n", + fifo->fifonum); if (!fifo->urb) { fifo->urb = usb_alloc_urb(0, GFP_KERNEL); @@ -997,33 +919,28 @@ start_int_fifo(usb_fifo * fifo) } usb_fill_int_urb(fifo->urb, fifo->hfc->dev, fifo->pipe, fifo->buffer, fifo->usb_packet_maxlen, - rx_complete, fifo, fifo->intervall); + rx_int_complete, fifo, fifo->intervall); fifo->active = 1; /* must be marked active */ errcode = usb_submit_urb(fifo->urb, GFP_KERNEL); if (errcode) { - printk(KERN_INFO + printk(KERN_ERR "HFC-S USB: submit URB error(start_int_info): status:%i\n", errcode); fifo->active = 0; fifo->skbuff = NULL; } -} /* start_int_fifo */ +} -/*****************************/ -/* set the B-channel mode */ -/*****************************/ static void -set_hfcmode(hfcusb_data * hfc, int channel, int mode) +setup_bchannel(hfcusb_data * hfc, int channel, int mode) { __u8 val, idx_table[2] = { 0, 2 }; if (hfc->disc_flag) { return; } -#ifdef CONFIG_HISAX_DEBUG - DBG(ISDN_DBG, "HFC-S USB: setting channel %d to mode %d", channel, - mode); -#endif + DBG(HFCUSB_DBG_STATES, "HFC-S USB: setting channel %d to mode %d", + channel, mode); hfc->b_mode[channel] = mode; /* setup CON_HDLC */ @@ -1080,20 +997,17 @@ hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg) switch (pr) { case PH_ACTIVATE | REQUEST: if (fifo->fifonum == HFCUSB_D_TX) { -#ifdef CONFIG_HISAX_DEBUG - DBG(ISDN_DBG, + DBG(HFCUSB_DBG_STATES, "HFC_USB: hfc_usb_d_l2l1 D-chan: PH_ACTIVATE | REQUEST"); -#endif + if (hfc->l1_state != 3 && hfc->l1_state != 7) { hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, PH_DEACTIVATE | INDICATION, NULL); -#ifdef CONFIG_HISAX_DEBUG - DBG(ISDN_DBG, + DBG(HFCUSB_DBG_STATES, "HFC-S USB: PH_DEACTIVATE | INDICATION sent (not state 3 or 7)"); -#endif } else { if (hfc->l1_state == 7) { /* l1 already active */ hfc->d_if.ifc.l1l2(&hfc-> @@ -1103,10 +1017,8 @@ hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg) | INDICATION, NULL); -#ifdef CONFIG_HISAX_DEBUG - DBG(ISDN_DBG, + DBG(HFCUSB_DBG_STATES, "HFC-S USB: PH_ACTIVATE | INDICATION sent again ;)"); -#endif } else { /* force sending sending INFO1 */ queue_control_request(hfc, @@ -1132,11 +1044,9 @@ hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg) } } } else { -#ifdef CONFIG_HISAX_DEBUG - DBG(ISDN_DBG, - "HFC_USB: hfc_usb_d_l2l1 Bx-chan: PH_ACTIVATE | REQUEST"); -#endif - set_hfcmode(hfc, + DBG(HFCUSB_DBG_STATES, + "HFC_USB: hfc_usb_d_l2l1 B-chan: PH_ACTIVATE | REQUEST"); + setup_bchannel(hfc, (fifo->fifonum == HFCUSB_B1_TX) ? 0 : 1, (long) arg); @@ -1147,18 +1057,12 @@ hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg) break; case PH_DEACTIVATE | REQUEST: if (fifo->fifonum == HFCUSB_D_TX) { -#ifdef CONFIG_HISAX_DEBUG - DBG(ISDN_DBG, + DBG(HFCUSB_DBG_STATES, "HFC_USB: hfc_usb_d_l2l1 D-chan: PH_DEACTIVATE | REQUEST"); -#endif - printk(KERN_INFO - "HFC-S USB: ISDN TE device should not deativate...\n"); } else { -#ifdef CONFIG_HISAX_DEBUG - DBG(ISDN_DBG, + DBG(HFCUSB_DBG_STATES, "HFC_USB: hfc_usb_d_l2l1 Bx-chan: PH_DEACTIVATE | REQUEST"); -#endif - set_hfcmode(hfc, + setup_bchannel(hfc, (fifo->fifonum == HFCUSB_B1_TX) ? 0 : 1, (int) L1_MODE_NULL); @@ -1171,25 +1075,20 @@ hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg) if (fifo->skbuff && fifo->delete_flg) { dev_kfree_skb_any(fifo->skbuff); fifo->skbuff = NULL; - fifo->delete_flg = false; + fifo->delete_flg = 0; } fifo->skbuff = arg; /* we have a new buffer */ break; default: - printk(KERN_INFO - "HFC_USB: hfc_usb_d_l2l1: unkown state : %#x\n", - pr); + DBG(HFCUSB_DBG_STATES, + "HFC_USB: hfc_usb_d_l2l1: unkown state : %#x", pr); break; } } -/***************************************************************************/ -/* usb_init is called once when a new matching device is detected to setup */ -/* main parameters. It registers the driver at the main hisax module. */ -/* on success 0 is returned. */ -/***************************************************************************/ +/* initial init HFC-S USB chip registers, HiSax interface, USB URBs */ static int -usb_init(hfcusb_data * hfc) +hfc_usb_init(hfcusb_data * hfc) { usb_fifo *fifo; int i, err; @@ -1214,11 +1113,11 @@ usb_init(hfcusb_data * hfc) /* aux = output, reset off */ write_usb(hfc, HFCUSB_CIRM, 0x10); - /* set USB_SIZE to match the wMaxPacketSize for INT or BULK transfers */ + /* set USB_SIZE to match wMaxPacketSize for INT or BULK transfers */ write_usb(hfc, HFCUSB_USB_SIZE, (hfc->packet_size / 8) | ((hfc->packet_size / 8) << 4)); - /* set USB_SIZE_I to match the wMaxPacketSize for ISO transfers */ + /* set USB_SIZE_I to match wMaxPacketSize for ISO transfers */ write_usb(hfc, HFCUSB_USB_SIZE_I, hfc->iso_packet_size); /* enable PCM/GCI master mode */ @@ -1257,8 +1156,8 @@ usb_init(hfcusb_data * hfc) hfc->b_mode[0] = L1_MODE_NULL; hfc->b_mode[1] = L1_MODE_NULL; - hfc->l1_activated = false; - hfc->disc_flag = false; + hfc->l1_activated = 0; + hfc->disc_flag = 0; hfc->led_state = 0; hfc->led_new_data = 0; hfc->old_led_state = 0; @@ -1349,11 +1248,9 @@ usb_init(hfcusb_data * hfc) handle_led(hfc, LED_POWER_ON); return (0); -} /* usb_init */ +} -/*************************************************/ -/* function called to probe a new plugged device */ -/*************************************************/ +/* initial callback for each plugged USB device */ static int hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { @@ -1378,11 +1275,6 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) } } -#ifdef CONFIG_HISAX_DEBUG - DBG(USB_DBG, - "HFC-USB: probing interface(%d) actalt(%d) minor(%d)\n", ifnum, - iface->desc.bAlternateSetting, intf->minor); -#endif printk(KERN_INFO "HFC-S USB: probing interface(%d) actalt(%d) minor(%d)\n", ifnum, iface->desc.bAlternateSetting, intf->minor); @@ -1403,15 +1295,11 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) /* check for config EOL element */ while (validconf[cfg_used][0]) { - cfg_found = true; + cfg_found = 1; vcf = validconf[cfg_used]; /* first endpoint descriptor */ ep = iface->endpoint; -#ifdef CONFIG_HISAX_DEBUG - DBG(USB_DBG, - "HFC-S USB: (if=%d alt=%d cfg_used=%d)\n", - ifnum, probe_alt_setting, cfg_used); -#endif + memcpy(cmptbl, vcf, 16 * sizeof(int)); /* check for all endpoints in this alternate setting */ @@ -1425,7 +1313,7 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) idx++; attr = ep->desc.bmAttributes; if (cmptbl[idx] == EP_NUL) { - cfg_found = false; + cfg_found = 0; } if (attr == USB_ENDPOINT_XFER_INT && cmptbl[idx] == EP_INT) @@ -1438,16 +1326,9 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) cmptbl[idx] = EP_NUL; /* check if all INT endpoints match minimum interval */ - if (attr == USB_ENDPOINT_XFER_INT - && ep->desc.bInterval < - vcf[17]) { -#ifdef CONFIG_HISAX_DEBUG - if (cfg_found) - DBG(USB_DBG, - "HFC-S USB: Interrupt Endpoint interval < %d found - skipping config", - vcf[17]); -#endif - cfg_found = false; + if ((attr == USB_ENDPOINT_XFER_INT) + && (ep->desc.bInterval < vcf[17])) { + cfg_found = 0; } ep++; } @@ -1455,7 +1336,7 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) /* all entries must be EP_NOP or EP_NUL for a valid config */ if (cmptbl[i] != EP_NOP && cmptbl[i] != EP_NUL) - cfg_found = false; + cfg_found = 0; } if (cfg_found) { if (cfg_used < small_match) { @@ -1464,23 +1345,16 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) probe_alt_setting; iface_used = iface; } -#ifdef CONFIG_HISAX_DEBUG - DBG(USB_DBG, - "HFC-USB: small_match=%x %x\n", - small_match, alt_used); -#endif } cfg_used++; } alt_idx++; - } /* (alt_idx < intf->num_altsetting) */ + } /* (alt_idx < intf->num_altsetting) */ /* found a valid USB Ta Endpint config */ if (small_match != 0xffff) { iface = iface_used; - if (! - (context = - kzalloc(sizeof(hfcusb_data), GFP_KERNEL))) + if (!(context = kzalloc(sizeof(hfcusb_data), GFP_KERNEL))) return (-ENOMEM); /* got no mem */ ep = iface->endpoint; @@ -1613,20 +1487,15 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) driver_info; printk(KERN_INFO "HFC-S USB: detected \"%s\"\n", driver_info->vend_name); -#ifdef CONFIG_HISAX_DEBUG - DBG(USB_DBG, - "HFC-S USB: Endpoint-Config: %s (if=%d alt=%d)\n", + + DBG(HFCUSB_DBG_INIT, + "HFC-S USB: Endpoint-Config: %s (if=%d alt=%d), E-Channel(%d)", conf_str[small_match], context->if_used, - context->alt_used); - printk(KERN_INFO - "HFC-S USB: E-channel (\"ECHO:\") logging "); - if (validconf[small_match][18]) - printk(" possible\n"); - else - printk("NOT possible\n"); -#endif + context->alt_used, + validconf[small_match][18]); + /* init the chip and register the driver */ - if (usb_init(context)) { + if (hfc_usb_init(context)) { usb_kill_urb(context->ctrl_urb); usb_free_urb(context->ctrl_urb); context->ctrl_urb = NULL; @@ -1643,17 +1512,19 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) return (-EIO); } -/****************************************************/ -/* function called when an active device is removed */ -/****************************************************/ +/* callback for unplugged USB device */ static void hfc_usb_disconnect(struct usb_interface *intf) { hfcusb_data *context = usb_get_intfdata(intf); int i; + + handle_led(context, LED_POWER_OFF); + schedule_timeout((10 * HZ) / 1000); + printk(KERN_INFO "HFC-S USB: device disconnect\n"); - context->disc_flag = true; + context->disc_flag = 1; usb_set_intfdata(intf, NULL); if (!context) return; @@ -1661,25 +1532,22 @@ hfc_usb_disconnect(struct usb_interface del_timer(&context->t3_timer); if (timer_pending(&context->t4_timer)) del_timer(&context->t4_timer); + /* tell all fifos to terminate */ for (i = 0; i < HFCUSB_NUM_FIFOS; i++) { if (context->fifos[i].usb_transfer_mode == USB_ISOC) { if (context->fifos[i].active > 0) { stop_isoc_chain(&context->fifos[i]); -#ifdef CONFIG_HISAX_DEBUG - DBG(USB_DBG, - "HFC-S USB: hfc_usb_disconnect: stopping ISOC chain Fifo no %i", - i); -#endif + DBG(HFCUSB_DBG_INIT, + "HFC-S USB: %s stopping ISOC chain Fifo(%i)", + __FUNCTION__, i); } } else { if (context->fifos[i].active > 0) { context->fifos[i].active = 0; -#ifdef CONFIG_HISAX_DEBUG - DBG(USB_DBG, - "HFC-S USB: hfc_usb_disconnect: unlinking URB for Fifo no %i", - i); -#endif + DBG(HFCUSB_DBG_INIT, + "HFC-S USB: %s unlinking URB for Fifo(%i)", + __FUNCTION__, i); } usb_kill_urb(context->fifos[i].urb); usb_free_urb(context->fifos[i].urb); @@ -1692,34 +1560,29 @@ hfc_usb_disconnect(struct usb_interface context->ctrl_urb = NULL; hisax_unregister(&context->d_if); kfree(context); /* free our structure again */ -} /* hfc_usb_disconnect */ +} -/************************************/ -/* our driver information structure */ -/************************************/ static struct usb_driver hfc_drv = { .name = "hfc_usb", .id_table = hfcusb_idtab, .probe = hfc_usb_probe, .disconnect = hfc_usb_disconnect, }; + static void __exit -hfc_usb_exit(void) +hfc_usb_mod_exit(void) { -#ifdef CONFIG_HISAX_DEBUG - DBG(USB_DBG, "HFC-S USB: calling \"hfc_usb_exit\" ..."); -#endif - usb_deregister(&hfc_drv); /* release our driver */ + usb_deregister(&hfc_drv); /* release our driver */ printk(KERN_INFO "HFC-S USB: module removed\n"); } static int __init -hfc_usb_init(void) +hfc_usb_mod_init(void) { + char revstr[30], datestr[30], dummy[30]; #ifndef CONFIG_HISAX_DEBUG - unsigned int debug = -1; + hfc_debug = debug; #endif - char revstr[30], datestr[30], dummy[30]; sscanf(hfcusb_revision, "%s %s $ %s %s %s $ ", dummy, revstr, dummy, datestr, dummy); @@ -1734,8 +1597,8 @@ hfc_usb_init(void) return (0); } -module_init(hfc_usb_init); -module_exit(hfc_usb_exit); +module_init(hfc_usb_mod_init); +module_exit(hfc_usb_mod_exit); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); diff --git a/drivers/isdn/hisax/hfc_usb.h b/drivers/isdn/hisax/hfc_usb.h index 471f2354dfd..e79f56568d3 100644 --- a/drivers/isdn/hisax/hfc_usb.h +++ b/drivers/isdn/hisax/hfc_usb.h @@ -1,8 +1,8 @@ /* -* hfc_usb.h -* -* $Id: hfc_usb.h,v 4.2 2005/04/07 15:27:17 martinb1 Exp $ -*/ + * hfc_usb.h + * + * $Id: hfc_usb.h,v 1.1.2.5 2007/08/20 14:36:03 mbachem Exp $ + */ #ifndef __HFC_USB_H__ #define __HFC_USB_H__ @@ -10,25 +10,20 @@ #define DRIVER_AUTHOR "Peter Sprenger (sprenger@moving-byters.de)" #define DRIVER_DESC "HFC-S USB based HiSAX ISDN driver" -#define VERBOSE_USB_DEBUG +#define HFC_CTRL_TIMEOUT 20 /* 5ms timeout writing/reading regs */ +#define HFC_TIMER_T3 8000 /* timeout for l1 activation timer */ +#define HFC_TIMER_T4 500 /* time for state change interval */ -/***********/ -/* defines */ -/***********/ -#define HFC_CTRL_TIMEOUT 20 /* 5ms timeout writing/reading regs */ -#define HFC_TIMER_T3 8000 /* timeout for l1 activation timer */ -#define HFC_TIMER_T4 500 /* time for state change interval */ +#define HFCUSB_L1_STATECHANGE 0 /* L1 state changed */ +#define HFCUSB_L1_DRX 1 /* D-frame received */ +#define HFCUSB_L1_ERX 2 /* E-frame received */ +#define HFCUSB_L1_DTX 4 /* D-frames completed */ -#define HFCUSB_L1_STATECHANGE 0 /* L1 state changed */ -#define HFCUSB_L1_DRX 1 /* D-frame received */ -#define HFCUSB_L1_ERX 2 /* E-frame received */ -#define HFCUSB_L1_DTX 4 /* D-frames completed */ +#define MAX_BCH_SIZE 2048 /* allowed B-channel packet size */ -#define MAX_BCH_SIZE 2048 /* allowed B-channel packet size */ - -#define HFCUSB_RX_THRESHOLD 64 /* threshold for fifo report bit rx */ -#define HFCUSB_TX_THRESHOLD 64 /* threshold for fifo report bit tx */ +#define HFCUSB_RX_THRESHOLD 64 /* threshold for fifo report bit rx */ +#define HFCUSB_TX_THRESHOLD 64 /* threshold for fifo report bit tx */ #define HFCUSB_CHIP_ID 0x16 /* Chip ID register index */ #define HFCUSB_CIRM 0x00 /* cirm register index */ @@ -52,9 +47,8 @@ #define HFCUSB_CHIPID 0x40 /* ID value of HFC-S USB */ -/******************/ + /* fifo registers */ -/******************/ #define HFCUSB_NUM_FIFOS 8 /* maximum number of fifos */ #define HFCUSB_B1_TX 0 /* index for B1 transmit bulk/int */ #define HFCUSB_B1_RX 1 /* index for B1 receive bulk/int */ @@ -66,9 +60,9 @@ #define HFCUSB_PCM_RX 7 /* -* used to switch snd_transfer_mode for different TA modes e.g. the Billion USB TA just -* supports ISO out, while the Cologne Chip EVAL TA just supports BULK out -*/ + * used to switch snd_transfer_mode for different TA modes e.g. the Billion USB TA just + * supports ISO out, while the Cologne Chip EVAL TA just supports BULK out + */ #define USB_INT 0 #define USB_BULK 1 #define USB_ISOC 2 @@ -77,49 +71,36 @@ #define ISOC_PACKETS_B 8 #define ISO_BUFFER_SIZE 128 -// ISO send definitions +/* Fifo flow Control for TX ISO */ #define SINK_MAX 68 #define SINK_MIN 48 #define SINK_DMIN 12 #define SINK_DMAX 18 #define BITLINE_INF (-64*8) - -/**********/ -/* macros */ -/**********/ +/* HFC-S USB register access by Control-URSs */ #define write_usb(a,b,c)usb_control_msg((a)->dev,(a)->ctrl_out_pipe,0,0x40,(c),(b),NULL,0,HFC_CTRL_TIMEOUT) #define read_usb(a,b,c) usb_control_msg((a)->dev,(a)->ctrl_in_pipe,1,0xC0,0,(b),(c),1,HFC_CTRL_TIMEOUT) - - -/*******************/ -/* Debugging Flags */ -/*******************/ -#define USB_DBG 1 -#define ISDN_DBG 2 - - -/* *********************/ -/* USB related defines */ -/***********************/ #define HFC_CTRL_BUFSIZE 32 - - -/*************************************************/ /* entry and size of output/input control buffer */ -/*************************************************/ typedef struct { __u8 hfc_reg; /* register number */ __u8 reg_val; /* value to be written (or read) */ int action; /* data for action handler */ } ctrl_buft; +/* Debugging Flags */ +#define HFCUSB_DBG_INIT 0x0001 +#define HFCUSB_DBG_STATES 0x0002 +#define HFCUSB_DBG_DCHANNEL 0x0080 +#define HFCUSB_DBG_FIFO_ERR 0x4000 +#define HFCUSB_DBG_VERBOSE_USB 0x8000 -/********************/ -/* URB error codes: */ -/********************/ -/* Used to represent a list of values and their respective symbolic names */ +/* + * URB error codes: + * Used to represent a list of values and their respective symbolic names + */ struct hfcusb_symbolic_list { const int num; const char *name; @@ -134,20 +115,20 @@ static struct hfcusb_symbolic_list urb_errlist[] = { {-ENXIO, "URB already queued"}, {-EFBIG, "Too much ISO frames requested"}, {-ENOSR, "Buffer error (overrun)"}, - {-EPIPE, "Specified endpoint is stalled"}, + {-EPIPE, "Specified endpoint is stalled (device not responding)"}, {-EOVERFLOW, "Babble (bad cable?)"}, {-EPROTO, "Bit-stuff error (bad cable?)"}, - {-EILSEQ, "CRC or missing token"}, - {-ETIME, "Device did not respond"}, + {-EILSEQ, "CRC/Timeout"}, + {-ETIMEDOUT, "NAK (device does not respond)"}, {-ESHUTDOWN, "Device unplugged"}, {-1, NULL} }; -/*****************************************************/ -/* device dependant information to support different */ -/* ISDN Ta's using the HFC-S USB chip */ -/*****************************************************/ +/* + * device dependant information to support different + * ISDN Ta's using the HFC-S USB chip + */ /* USB descriptor need to contain one of the following EndPoint combination: */ #define CNF_4INT3ISO 1 // 4 INT IN, 3 ISO OUT @@ -155,16 +136,19 @@ static struct hfcusb_symbolic_list urb_errlist[] = { #define CNF_4ISO3ISO 3 // 4 ISO IN, 3 ISO OUT #define CNF_3ISO3ISO 4 // 3 ISO IN, 3 ISO OUT -#define EP_NUL 1 // Endpoint at this position not allowed -#define EP_NOP 2 // all type of endpoints allowed at this position -#define EP_ISO 3 // Isochron endpoint mandatory at this position -#define EP_BLK 4 // Bulk endpoint mandatory at this position -#define EP_INT 5 // Interrupt endpoint mandatory at this position +#define EP_NUL 1 // Endpoint at this position not allowed +#define EP_NOP 2 // all type of endpoints allowed at this position +#define EP_ISO 3 // Isochron endpoint mandatory at this position +#define EP_BLK 4 // Bulk endpoint mandatory at this position +#define EP_INT 5 // Interrupt endpoint mandatory at this position -/* this array represents all endpoints possible in the HCF-USB the last -* 3 entries are the configuration number, the minimum interval for -* Interrupt endpoints & boolean if E-channel logging possible -*/ +/* + * List of all supported endpoint configuration sets, used to find the + * best matching endpoint configuration within a devices' USB descriptor. + * We need at least 3 RX endpoints, and 3 TX endpoints, either + * INT-in and ISO-out, or ISO-in and ISO-out) + * with 4 RX endpoints even E-Channel logging is possible + */ static int validconf[][19] = { // INT in, ISO out config {EP_NUL, EP_INT, EP_NUL, EP_INT, EP_NUL, EP_INT, EP_NOP, EP_INT, @@ -193,7 +177,6 @@ static char *conf_str[] = { }; #endif - typedef struct { int vendor; // vendor id int prod_id; // product id @@ -202,9 +185,9 @@ typedef struct { signed short led_bits[8]; // array of 8 possible LED bitmask settings } vendor_data; -#define LED_OFF 0 // no LED support -#define LED_SCHEME1 1 // LED standard scheme -#define LED_SCHEME2 2 // not used yet... +#define LED_OFF 0 // no LED support +#define LED_SCHEME1 1 // LED standard scheme +#define LED_SCHEME2 2 // not used yet... #define LED_POWER_ON 1 #define LED_POWER_OFF 2 @@ -217,11 +200,8 @@ typedef struct { #define LED_B2_OFF 9 #define LED_B2_DATA 10 -#define LED_NORMAL 0 // LEDs are normal -#define LED_INVERTED 1 // LEDs are inverted - -/* time in ms to perform a Flashing LED when B-Channel has traffic */ -#define LED_TIME 250 +#define LED_NORMAL 0 // LEDs are normal +#define LED_INVERTED 1 // LEDs are inverted -#endif // __HFC_USB_H__ +#endif // __HFC_USB_H__ diff --git a/drivers/isdn/i4l/isdn_bsdcomp.c b/drivers/isdn/i4l/isdn_bsdcomp.c index 90a23795db7..02d9918705d 100644 --- a/drivers/isdn/i4l/isdn_bsdcomp.c +++ b/drivers/isdn/i4l/isdn_bsdcomp.c @@ -341,7 +341,7 @@ static void *bsd_alloc (struct isdn_ppp_comp_data *data) * Allocate space for the dictionary. This may be more than one page in * length. */ - db->dict = (struct bsd_dict *) vmalloc (hsize * sizeof (struct bsd_dict)); + db->dict = vmalloc(hsize * sizeof(struct bsd_dict)); if (!db->dict) { bsd_free (db); return NULL; @@ -354,8 +354,7 @@ static void *bsd_alloc (struct isdn_ppp_comp_data *data) if (!decomp) db->lens = NULL; else { - db->lens = (unsigned short *) vmalloc ((maxmaxcode + 1) * - sizeof (db->lens[0])); + db->lens = vmalloc((maxmaxcode + 1) * sizeof(db->lens[0])); if (!db->lens) { bsd_free (db); return (NULL); diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c index c97330b1987..ec5f4046412 100644 --- a/drivers/isdn/i4l/isdn_common.c +++ b/drivers/isdn/i4l/isdn_common.c @@ -2291,7 +2291,7 @@ static int __init isdn_init(void) int i; char tmprev[50]; - if (!(dev = (isdn_dev *) vmalloc(sizeof(isdn_dev)))) { + if (!(dev = vmalloc(sizeof(isdn_dev)))) { printk(KERN_WARNING "isdn: Could not allocate device-struct.\n"); return -EIO; } diff --git a/drivers/kvm/Kconfig b/drivers/kvm/Kconfig index 6cecc396e04..7b64fd4aa2f 100644 --- a/drivers/kvm/Kconfig +++ b/drivers/kvm/Kconfig @@ -5,6 +5,11 @@ menuconfig VIRTUALIZATION bool "Virtualization" depends on X86 default y + ---help--- + Say Y here to get to see options for virtualization guest drivers. + This option alone does not add any kernel code. + + If you say N, all options in this submenu will be skipped and disabled. if VIRTUALIZATION diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c index 96856097d15..cd0557954e5 100644 --- a/drivers/kvm/kvm_main.c +++ b/drivers/kvm/kvm_main.c @@ -2974,6 +2974,10 @@ static int kvm_cpu_hotplug(struct notifier_block *notifier, unsigned long val, switch (val) { case CPU_DYING: case CPU_DYING_FROZEN: + printk(KERN_INFO "kvm: disabling virtualization on CPU%d\n", + cpu); + hardware_disable(NULL); + break; case CPU_UP_CANCELED: case CPU_UP_CANCELED_FROZEN: printk(KERN_INFO "kvm: disabling virtualization on CPU%d\n", diff --git a/drivers/lguest/Kconfig b/drivers/lguest/Kconfig index fd6925f4164..41e2250613a 100644 --- a/drivers/lguest/Kconfig +++ b/drivers/lguest/Kconfig @@ -1,6 +1,6 @@ config LGUEST tristate "Linux hypervisor example code" - depends on X86 && PARAVIRT && EXPERIMENTAL && !X86_PAE + depends on X86 && PARAVIRT && EXPERIMENTAL && !X86_PAE && FUTEX select LGUEST_GUEST select HVC_DRIVER ---help--- diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig index dbe96268866..56cd8998fe4 100644 --- a/drivers/macintosh/Kconfig +++ b/drivers/macintosh/Kconfig @@ -3,6 +3,11 @@ menuconfig MACINTOSH_DRIVERS bool "Macintosh device drivers" depends on PPC || MAC || X86 default y if (PPC_PMAC || MAC) + ---help--- + Say Y here to get to see options for devices used with Macintosh + computers. This option alone does not add any kernel code. + + If you say N, all options in this submenu will be skipped and disabled. if MACINTOSH_DRIVERS diff --git a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c index bc77c5e2ca9..5c742a52608 100644 --- a/drivers/macintosh/adb.c +++ b/drivers/macintosh/adb.c @@ -89,7 +89,7 @@ static int sleepy_trackpad; static int autopoll_devs; int __adb_probe_sync; -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP static void adb_notify_sleep(struct pmu_sleep_notifier *self, int when); static struct pmu_sleep_notifier adb_sleep_notifier = { adb_notify_sleep, @@ -313,7 +313,7 @@ int __init adb_init(void) printk(KERN_WARNING "Warning: no ADB interface detected\n"); adb_controller = NULL; } else { -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP pmu_register_sleep_notifier(&adb_sleep_notifier); #endif /* CONFIG_PM */ #ifdef CONFIG_PPC diff --git a/drivers/macintosh/mac_hid.c b/drivers/macintosh/mac_hid.c index 76c1e8e4a48..33dee3a773e 100644 --- a/drivers/macintosh/mac_hid.c +++ b/drivers/macintosh/mac_hid.c @@ -13,6 +13,7 @@ #include <linux/sysctl.h> #include <linux/input.h> #include <linux/module.h> +#include <linux/kbd_kern.h> static struct input_dev *emumousebtn; diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index 5eee480245f..f7c509b7a8e 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c @@ -152,10 +152,10 @@ static spinlock_t pmu_lock; static u8 pmu_intr_mask; static int pmu_version; static int drop_interrupts; -#if defined(CONFIG_PM) && defined(CONFIG_PPC32) +#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32) static int option_lid_wakeup = 1; -#endif /* CONFIG_PM && CONFIG_PPC32 */ -#if (defined(CONFIG_PM)&&defined(CONFIG_PPC32))||defined(CONFIG_PMAC_BACKLIGHT_LEGACY) +#endif /* CONFIG_PM_SLEEP && CONFIG_PPC32 */ +#if (defined(CONFIG_PM_SLEEP)&&defined(CONFIG_PPC32))||defined(CONFIG_PMAC_BACKLIGHT_LEGACY) static int sleep_in_progress; #endif static unsigned long async_req_locks; @@ -875,7 +875,7 @@ proc_read_options(char *page, char **start, off_t off, { char *p = page; -#if defined(CONFIG_PM) && defined(CONFIG_PPC32) +#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32) if (pmu_kind == PMU_KEYLARGO_BASED && pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) >= 0) p += sprintf(p, "lid_wakeup=%d\n", option_lid_wakeup); @@ -916,7 +916,7 @@ proc_write_options(struct file *file, const char __user *buffer, *(val++) = 0; while(*val == ' ') val++; -#if defined(CONFIG_PM) && defined(CONFIG_PPC32) +#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32) if (pmu_kind == PMU_KEYLARGO_BASED && pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) >= 0) if (!strcmp(label, "lid_wakeup")) @@ -1738,7 +1738,7 @@ pmu_present(void) return via != 0; } -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP static LIST_HEAD(sleep_notifiers); @@ -1769,9 +1769,9 @@ pmu_unregister_sleep_notifier(struct pmu_sleep_notifier* n) return 0; } EXPORT_SYMBOL(pmu_unregister_sleep_notifier); -#endif /* CONFIG_PM */ +#endif /* CONFIG_PM_SLEEP */ -#if defined(CONFIG_PM) && defined(CONFIG_PPC32) +#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32) /* Sleep is broadcast last-to-first */ static void broadcast_sleep(int when) @@ -2390,7 +2390,7 @@ powerbook_sleep_3400(void) return 0; } -#endif /* CONFIG_PM && CONFIG_PPC32 */ +#endif /* CONFIG_PM_SLEEP && CONFIG_PPC32 */ /* * Support for /dev/pmu device @@ -2573,7 +2573,7 @@ pmu_ioctl(struct inode * inode, struct file *filp, int error = -EINVAL; switch (cmd) { -#if defined(CONFIG_PM) && defined(CONFIG_PPC32) +#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32) case PMU_IOC_SLEEP: if (!capable(CAP_SYS_ADMIN)) return -EACCES; @@ -2601,7 +2601,7 @@ pmu_ioctl(struct inode * inode, struct file *filp, return put_user(0, argp); else return put_user(1, argp); -#endif /* CONFIG_PM && CONFIG_PPC32 */ +#endif /* CONFIG_PM_SLEEP && CONFIG_PPC32 */ #ifdef CONFIG_PMAC_BACKLIGHT_LEGACY /* Compatibility ioctl's for backlight */ @@ -2757,7 +2757,7 @@ pmu_polled_request(struct adb_request *req) * to do suspend-to-disk. */ -#if defined(CONFIG_PM) && defined(CONFIG_PPC32) +#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32) int pmu_sys_suspended; @@ -2792,7 +2792,7 @@ static int pmu_sys_resume(struct sys_device *sysdev) return 0; } -#endif /* CONFIG_PM && CONFIG_PPC32 */ +#endif /* CONFIG_PM_SLEEP && CONFIG_PPC32 */ static struct sysdev_class pmu_sysclass = { set_kset_name("pmu"), @@ -2803,10 +2803,10 @@ static struct sys_device device_pmu = { }; static struct sysdev_driver driver_pmu = { -#if defined(CONFIG_PM) && defined(CONFIG_PPC32) +#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32) .suspend = &pmu_sys_suspend, .resume = &pmu_sys_resume, -#endif /* CONFIG_PM && CONFIG_PPC32 */ +#endif /* CONFIG_PM_SLEEP && CONFIG_PPC32 */ }; static int __init init_pmu_sysfs(void) @@ -2841,10 +2841,10 @@ EXPORT_SYMBOL(pmu_wait_complete); EXPORT_SYMBOL(pmu_suspend); EXPORT_SYMBOL(pmu_resume); EXPORT_SYMBOL(pmu_unlock); -#if defined(CONFIG_PM) && defined(CONFIG_PPC32) +#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32) EXPORT_SYMBOL(pmu_enable_irled); EXPORT_SYMBOL(pmu_battery_count); EXPORT_SYMBOL(pmu_batteries); EXPORT_SYMBOL(pmu_power_flags); -#endif /* CONFIG_PM && CONFIG_PPC32 */ +#endif /* CONFIG_PM_SLEEP && CONFIG_PPC32 */ diff --git a/drivers/macintosh/via-pmu68k.c b/drivers/macintosh/via-pmu68k.c index dfdf11c1eec..e2f84da09e7 100644 --- a/drivers/macintosh/via-pmu68k.c +++ b/drivers/macintosh/via-pmu68k.c @@ -818,243 +818,3 @@ pmu_present(void) { return (pmu_kind != PMU_UNKNOWN); } - -#if 0 /* needs some work for 68K */ - -/* - * This struct is used to store config register values for - * PCI devices which may get powered off when we sleep. - */ -static struct pci_save { - u16 command; - u16 cache_lat; - u16 intr; -} *pbook_pci_saves; -static int n_pbook_pci_saves; - -static inline void -pbook_pci_save(void) -{ - int npci; - struct pci_dev *pd = NULL; - struct pci_save *ps; - - npci = 0; - while ((pd = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) - ++npci; - n_pbook_pci_saves = npci; - if (npci == 0) - return; - ps = kmalloc(npci * sizeof(*ps), GFP_KERNEL); - pbook_pci_saves = ps; - if (ps == NULL) - return; - - pd = NULL; - while ((pd = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) { - pci_read_config_word(pd, PCI_COMMAND, &ps->command); - pci_read_config_word(pd, PCI_CACHE_LINE_SIZE, &ps->cache_lat); - pci_read_config_word(pd, PCI_INTERRUPT_LINE, &ps->intr); - ++ps; - --npci; - } -} - -static inline void -pbook_pci_restore(void) -{ - u16 cmd; - struct pci_save *ps = pbook_pci_saves; - struct pci_dev *pd = NULL; - int j; - - while ((pd = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) { - if (ps->command == 0) - continue; - pci_read_config_word(pd, PCI_COMMAND, &cmd); - if ((ps->command & ~cmd) == 0) - continue; - switch (pd->hdr_type) { - case PCI_HEADER_TYPE_NORMAL: - for (j = 0; j < 6; ++j) - pci_write_config_dword(pd, - PCI_BASE_ADDRESS_0 + j*4, - pd->resource[j].start); - pci_write_config_dword(pd, PCI_ROM_ADDRESS, - pd->resource[PCI_ROM_RESOURCE].start); - pci_write_config_word(pd, PCI_CACHE_LINE_SIZE, - ps->cache_lat); - pci_write_config_word(pd, PCI_INTERRUPT_LINE, - ps->intr); - pci_write_config_word(pd, PCI_COMMAND, ps->command); - break; - /* other header types not restored at present */ - } - } -} - -/* - * Put the powerbook to sleep. - */ -#define IRQ_ENABLE ((unsigned int *)0xf3000024) -#define MEM_CTRL ((unsigned int *)0xf8000070) - -int powerbook_sleep(void) -{ - int ret, i, x; - static int save_backlight; - static unsigned int save_irqen; - unsigned long msr; - unsigned int hid0; - unsigned long p, wait; - struct adb_request sleep_req; - - /* Notify device drivers */ - ret = blocking_notifier_call_chain(&sleep_notifier_list, - PBOOK_SLEEP, NULL); - if (ret & NOTIFY_STOP_MASK) - return -EBUSY; - - /* Sync the disks. */ - /* XXX It would be nice to have some way to ensure that - * nobody is dirtying any new buffers while we wait. */ - sys_sync(); - - /* Turn off the display backlight */ - save_backlight = backlight_enabled; - if (save_backlight) - pmu_enable_backlight(0); - - /* Give the disks a little time to actually finish writing */ - for (wait = jiffies + (HZ/4); time_before(jiffies, wait); ) - mb(); - - /* Disable all interrupts except pmu */ - save_irqen = in_le32(IRQ_ENABLE); - for (i = 0; i < 32; ++i) - if (i != vias->intrs[0].line && (save_irqen & (1 << i))) - disable_irq(i); - asm volatile("mtdec %0" : : "r" (0x7fffffff)); - - /* Save the state of PCI config space for some slots */ - pbook_pci_save(); - - /* Set the memory controller to keep the memory refreshed - while we're asleep */ - for (i = 0x403f; i >= 0x4000; --i) { - out_be32(MEM_CTRL, i); - do { - x = (in_be32(MEM_CTRL) >> 16) & 0x3ff; - } while (x == 0); - if (x >= 0x100) - break; - } - - /* Ask the PMU to put us to sleep */ - pmu_request(&sleep_req, NULL, 5, PMU_SLEEP, 'M', 'A', 'T', 'T'); - while (!sleep_req.complete) - mb(); - /* displacement-flush the L2 cache - necessary? */ - for (p = KERNELBASE; p < KERNELBASE + 0x100000; p += 0x1000) - i = *(volatile int *)p; - asleep = 1; - - /* Put the CPU into sleep mode */ - asm volatile("mfspr %0,1008" : "=r" (hid0) :); - hid0 = (hid0 & ~(HID0_NAP | HID0_DOZE)) | HID0_SLEEP; - asm volatile("mtspr 1008,%0" : : "r" (hid0)); - local_save_flags(msr); - msr |= MSR_POW | MSR_EE; - local_irq_restore(msr); - udelay(10); - - /* OK, we're awake again, start restoring things */ - out_be32(MEM_CTRL, 0x3f); - pbook_pci_restore(); - - /* wait for the PMU interrupt sequence to complete */ - while (asleep) - mb(); - - /* reenable interrupts */ - for (i = 0; i < 32; ++i) - if (i != vias->intrs[0].line && (save_irqen & (1 << i))) - enable_irq(i); - - /* Notify drivers */ - blocking_notifier_call_chain(&sleep_notifier_list, PBOOK_WAKE, NULL); - - /* reenable ADB autopoll */ - pmu_adb_autopoll(adb_dev_map); - - /* Turn on the screen backlight, if it was on before */ - if (save_backlight) - pmu_enable_backlight(1); - - /* Wait for the hard disk to spin up */ - - return 0; -} - -/* - * Support for /dev/pmu device - */ -static int pmu_open(struct inode *inode, struct file *file) -{ - return 0; -} - -static ssize_t pmu_read(struct file *file, char *buf, - size_t count, loff_t *ppos) -{ - return 0; -} - -static ssize_t pmu_write(struct file *file, const char *buf, - size_t count, loff_t *ppos) -{ - return 0; -} - -static int pmu_ioctl(struct inode * inode, struct file *filp, - u_int cmd, u_long arg) -{ - int error; - __u32 value; - - switch (cmd) { - case PMU_IOC_SLEEP: - return -ENOSYS; - case PMU_IOC_GET_BACKLIGHT: - return put_user(backlight_level, (__u32 *)arg); - case PMU_IOC_SET_BACKLIGHT: - error = get_user(value, (__u32 *)arg); - if (!error) - pmu_set_brightness(value); - return error; - case PMU_IOC_GET_MODEL: - return put_user(pmu_kind, (__u32 *)arg); - } - return -EINVAL; -} - -static const struct file_operations pmu_device_fops = { - .read = pmu_read, - .write = pmu_write, - .ioctl = pmu_ioctl, - .open = pmu_open, -}; - -static struct miscdevice pmu_device = { - PMU_MINOR, "pmu", &pmu_device_fops -}; - -void pmu_device_init(void) -{ - if (!via) - return; - if (misc_register(&pmu_device) < 0) - printk(KERN_ERR "via-pmu68k: cannot register misc device.\n"); -} -#endif /* CONFIG_PMAC_PBOOK */ - diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig index 531d4d17d01..34a8c60a254 100644 --- a/drivers/md/Kconfig +++ b/drivers/md/Kconfig @@ -263,7 +263,7 @@ config DM_MULTIPATH_EMC config DM_MULTIPATH_RDAC tristate "LSI/Engenio RDAC multipath support (EXPERIMENTAL)" - depends on DM_MULTIPATH && BLK_DEV_DM && EXPERIMENTAL + depends on DM_MULTIPATH && BLK_DEV_DM && SCSI && EXPERIMENTAL ---help--- Multipath support for LSI/Engenio RDAC. diff --git a/drivers/md/dm-mpath-rdac.c b/drivers/md/dm-mpath-rdac.c index 8b776b8cb7f..16b16134577 100644 --- a/drivers/md/dm-mpath-rdac.c +++ b/drivers/md/dm-mpath-rdac.c @@ -292,7 +292,7 @@ static struct request *get_rdac_req(struct rdac_handler *h, rq->end_io_data = h; rq->timeout = h->timeout; rq->cmd_type = REQ_TYPE_BLOCK_PC; - rq->cmd_flags = REQ_FAILFAST | REQ_NOMERGE; + rq->cmd_flags |= REQ_FAILFAST | REQ_NOMERGE; return rq; } diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 650991bddd8..f33a729960c 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -1972,7 +1972,8 @@ static int run(mddev_t *mddev) !test_bit(In_sync, &disk->rdev->flags)) { disk->head_position = 0; mddev->degraded++; - conf->fullsync = 1; + if (disk->rdev) + conf->fullsync = 1; } } if (mddev->degraded == conf->raid_disks) { @@ -2153,11 +2154,25 @@ static int raid1_reshape(mddev_t *mddev) oldpool = conf->r1bio_pool; conf->r1bio_pool = newpool; - for (d=d2=0; d < conf->raid_disks; d++) - if (conf->mirrors[d].rdev) { - conf->mirrors[d].rdev->raid_disk = d2; - newmirrors[d2++].rdev = conf->mirrors[d].rdev; + for (d = d2 = 0; d < conf->raid_disks; d++) { + mdk_rdev_t *rdev = conf->mirrors[d].rdev; + if (rdev && rdev->raid_disk != d2) { + char nm[20]; + sprintf(nm, "rd%d", rdev->raid_disk); + sysfs_remove_link(&mddev->kobj, nm); + rdev->raid_disk = d2; + sprintf(nm, "rd%d", rdev->raid_disk); + sysfs_remove_link(&mddev->kobj, nm); + if (sysfs_create_link(&mddev->kobj, + &rdev->kobj, nm)) + printk(KERN_WARNING + "md/raid1: cannot register " + "%s for %s\n", + nm, mdname(mddev)); } + if (rdev) + newmirrors[d2++].rdev = rdev; + } kfree(conf->mirrors); conf->mirrors = newmirrors; kfree(conf->poolinfo); diff --git a/drivers/media/dvb/b2c2/flexcop-i2c.c b/drivers/media/dvb/b2c2/flexcop-i2c.c index 02a0ea6e1c1..6bf858a436c 100644 --- a/drivers/media/dvb/b2c2/flexcop-i2c.c +++ b/drivers/media/dvb/b2c2/flexcop-i2c.c @@ -135,6 +135,13 @@ static int flexcop_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs struct flexcop_device *fc = i2c_get_adapdata(i2c_adap); int i, ret = 0; + /* Some drivers use 1 byte or 0 byte reads as probes, which this + * driver doesn't support. These probes will always fail, so this + * hack makes them always succeed. If one knew how, it would of + * course be better to actually do the read. */ + if (num == 1 && msgs[0].flags == I2C_M_RD && msgs[0].len <= 1) + return 1; + if (mutex_lock_interruptible(&fc->i2c_mutex)) return -ERESTARTSYS; diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c index acf026342ec..bdd797071cb 100644 --- a/drivers/media/dvb/dvb-core/dvb_net.c +++ b/drivers/media/dvb/dvb-core/dvb_net.c @@ -800,7 +800,8 @@ static int dvb_net_ts_callback(const u8 *buffer1, size_t buffer1_len, } -static void dvb_net_sec(struct net_device *dev, u8 *pkt, int pkt_len) +static void dvb_net_sec(struct net_device *dev, const u8 *pkt, int +pkt_len) { u8 *eth; struct sk_buff *skb; @@ -902,7 +903,7 @@ static int dvb_net_sec_callback(const u8 *buffer1, size_t buffer1_len, * we rely on the DVB API definition where exactly one complete * section is delivered in buffer1 */ - dvb_net_sec (dev, (u8*) buffer1, buffer1_len); + dvb_net_sec (dev, buffer1, buffer1_len); return 0; } diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c index ca99e439c97..11f7d5939bd 100644 --- a/drivers/media/dvb/frontends/dvb-pll.c +++ b/drivers/media/dvb/frontends/dvb-pll.c @@ -784,7 +784,7 @@ struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, strncpy(fe->ops.tuner_ops.info.name, desc->name, sizeof(fe->ops.tuner_ops.info.name)); fe->ops.tuner_ops.info.frequency_min = desc->min; - fe->ops.tuner_ops.info.frequency_min = desc->max; + fe->ops.tuner_ops.info.frequency_max = desc->max; if (!desc->initdata) fe->ops.tuner_ops.init = NULL; if (!desc->sleepdata) diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c index c08f650df42..ef5361824f8 100644 --- a/drivers/media/video/cafe_ccic.c +++ b/drivers/media/video/cafe_ccic.c @@ -356,6 +356,7 @@ static int cafe_smbus_write_data(struct cafe_camera *cam, { unsigned int rval; unsigned long flags; + DEFINE_WAIT(the_wait); spin_lock_irqsave(&cam->dev_lock, flags); rval = TWSIC0_EN | ((addr << TWSIC0_SID_SHIFT) & TWSIC0_SID); @@ -369,10 +370,29 @@ static int cafe_smbus_write_data(struct cafe_camera *cam, rval = value | ((command << TWSIC1_ADDR_SHIFT) & TWSIC1_ADDR); cafe_reg_write(cam, REG_TWSIC1, rval); spin_unlock_irqrestore(&cam->dev_lock, flags); - msleep(2); /* Required or things flake */ + /* + * Time to wait for the write to complete. THIS IS A RACY + * WAY TO DO IT, but the sad fact is that reading the TWSIC1 + * register too quickly after starting the operation sends + * the device into a place that may be kinder and better, but + * which is absolutely useless for controlling the sensor. In + * practice we have plenty of time to get into our sleep state + * before the interrupt hits, and the worst case is that we + * time out and then see that things completed, so this seems + * the best way for now. + */ + do { + prepare_to_wait(&cam->smbus_wait, &the_wait, + TASK_UNINTERRUPTIBLE); + schedule_timeout(1); /* even 1 jiffy is too long */ + finish_wait(&cam->smbus_wait, &the_wait); + } while (!cafe_smbus_write_done(cam)); + +#ifdef IF_THE_CAFE_HARDWARE_WORKED_RIGHT wait_event_timeout(cam->smbus_wait, cafe_smbus_write_done(cam), CAFE_SMBUS_TIMEOUT); +#endif spin_lock_irqsave(&cam->dev_lock, flags); rval = cafe_reg_read(cam, REG_TWSIC1); spin_unlock_irqrestore(&cam->dev_lock, flags); @@ -710,7 +730,7 @@ static void cafe_ctlr_init(struct cafe_camera *cam) * Here we must wait a bit for the controller to come around. */ spin_unlock_irqrestore(&cam->dev_lock, flags); - mdelay(5); /* FIXME revisit this */ + msleep(5); spin_lock_irqsave(&cam->dev_lock, flags); cafe_reg_write(cam, REG_GL_CSR, GCSR_CCIC_EN|GCSR_SRC|GCSR_MRC); @@ -2233,12 +2253,21 @@ static int cafe_pci_resume(struct pci_dev *pdev) if (ret) return ret; ret = pci_enable_device(pdev); + if (ret) { cam_warn(cam, "Unable to re-enable device on resume!\n"); return ret; } cafe_ctlr_init(cam); - cafe_ctlr_power_up(cam); + cafe_ctlr_power_down(cam); + + mutex_lock(&cam->s_mutex); + if (cam->users > 0) { + cafe_ctlr_power_up(cam); + __cafe_cam_reset(cam); + } + mutex_unlock(&cam->s_mutex); + set_bit(CF_CONFIG_NEEDED, &cam->flags); if (cam->state == S_SPECREAD) cam->state = S_IDLE; /* Don't bother restarting */ diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index 2c7b158ce7e..40307f3f6fe 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c @@ -1772,6 +1772,7 @@ static int em28xx_usb_probe(struct usb_interface *interface, if (dev->alt_max_pkt_size == NULL) { em28xx_errdev("out of memory!\n"); em28xx_devused&=~(1<<nr); + kfree(dev); return -ENOMEM; } diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index 047624b9e27..5977a79619c 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c @@ -1190,6 +1190,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0; itv->osd_local_alpha_state = (fb->flags & V4L2_FBUF_FLAG_LOCAL_ALPHA) != 0; itv->osd_color_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0; + ivtv_set_osd_alpha(itv); break; } @@ -1234,7 +1235,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void IVTV_INFO("Tuner: %s\n", test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV"); cx2341x_log_status(&itv->params, itv->name); - IVTV_INFO("Status flags: 0x%08lx\n", itv->i_flags); + IVTV_INFO("Version: %s Status flags: 0x%08lx\n", IVTV_VERSION, itv->i_flags); for (i = 0; i < IVTV_MAX_STREAMS; i++) { struct ivtv_stream *s = &itv->streams[i]; diff --git a/drivers/media/video/ov7670.c b/drivers/media/video/ov7670.c index f8f21ddd984..c4c5bd67f79 100644 --- a/drivers/media/video/ov7670.c +++ b/drivers/media/video/ov7670.c @@ -416,7 +416,10 @@ static int ov7670_read(struct i2c_client *c, unsigned char reg, static int ov7670_write(struct i2c_client *c, unsigned char reg, unsigned char value) { - return i2c_smbus_write_byte_data(c, reg, value); + int ret = i2c_smbus_write_byte_data(c, reg, value); + if (reg == REG_COM7 && (value & COM7_RESET)) + msleep(2); /* Wait for reset to run */ + return ret; } diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c index 9c0e8d18c2f..3d81966d8c4 100644 --- a/drivers/media/video/pwc/pwc-if.c +++ b/drivers/media/video/pwc/pwc-if.c @@ -1196,12 +1196,19 @@ static int pwc_video_open(struct inode *inode, struct file *file) return 0; } + +static void pwc_cleanup(struct pwc_device *pdev) +{ + pwc_remove_sysfs_files(pdev->vdev); + video_unregister_device(pdev->vdev); +} + /* Note that all cleanup is done in the reverse order as in _open */ static int pwc_video_close(struct inode *inode, struct file *file) { struct video_device *vdev = file->private_data; struct pwc_device *pdev; - int i; + int i, hint; PWC_DEBUG_OPEN(">> video_close called(vdev = 0x%p).\n", vdev); @@ -1224,8 +1231,9 @@ static int pwc_video_close(struct inode *inode, struct file *file) pwc_isoc_cleanup(pdev); pwc_free_buffers(pdev); + lock_kernel(); /* Turn off LEDS and power down camera, but only when not unplugged */ - if (pdev->error_status != EPIPE) { + if (!pdev->unplugged) { /* Turn LEDs off */ if (pwc_set_leds(pdev, 0, 0) < 0) PWC_DEBUG_MODULE("Failed to set LED on/off time.\n"); @@ -1234,9 +1242,19 @@ static int pwc_video_close(struct inode *inode, struct file *file) if (i < 0) PWC_ERROR("Failed to power down camera (%d)\n", i); } + pdev->vopen--; + PWC_DEBUG_OPEN("<< video_close() vopen=%d\n", i); + } else { + pwc_cleanup(pdev); + /* Free memory (don't set pdev to 0 just yet) */ + kfree(pdev); + /* search device_hint[] table if we occupy a slot, by any chance */ + for (hint = 0; hint < MAX_DEV_HINTS; hint++) + if (device_hint[hint].pdev == pdev) + device_hint[hint].pdev = NULL; } - pdev->vopen--; - PWC_DEBUG_OPEN("<< video_close() vopen=%d\n", pdev->vopen); + unlock_kernel(); + return 0; } @@ -1791,21 +1809,21 @@ static void usb_pwc_disconnect(struct usb_interface *intf) /* Alert waiting processes */ wake_up_interruptible(&pdev->frameq); /* Wait until device is closed */ - while (pdev->vopen) - schedule(); - /* Device is now closed, so we can safely unregister it */ - PWC_DEBUG_PROBE("Unregistering video device in disconnect().\n"); - pwc_remove_sysfs_files(pdev->vdev); - video_unregister_device(pdev->vdev); - - /* Free memory (don't set pdev to 0 just yet) */ - kfree(pdev); + if(pdev->vopen) { + pdev->unplugged = 1; + } else { + /* Device is closed, so we can safely unregister it */ + PWC_DEBUG_PROBE("Unregistering video device in disconnect().\n"); + pwc_cleanup(pdev); + /* Free memory (don't set pdev to 0 just yet) */ + kfree(pdev); disconnect_out: - /* search device_hint[] table if we occupy a slot, by any chance */ - for (hint = 0; hint < MAX_DEV_HINTS; hint++) - if (device_hint[hint].pdev == pdev) - device_hint[hint].pdev = NULL; + /* search device_hint[] table if we occupy a slot, by any chance */ + for (hint = 0; hint < MAX_DEV_HINTS; hint++) + if (device_hint[hint].pdev == pdev) + device_hint[hint].pdev = NULL; + } unlock_kernel(); } diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h index 910a04f5392..8e8e5b27e77 100644 --- a/drivers/media/video/pwc/pwc.h +++ b/drivers/media/video/pwc/pwc.h @@ -193,6 +193,7 @@ struct pwc_device char vsnapshot; /* snapshot mode */ char vsync; /* used by isoc handler */ char vmirror; /* for ToUCaM series */ + char unplugged; int cmd_len; unsigned char cmd_buf[13]; diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 518d5d33546..a26655881e6 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -5,6 +5,11 @@ menuconfig MISC_DEVICES bool "Misc devices" default y + ---help--- + Say Y here to get to see options for device drivers from various + different categories. This option alone does not add any kernel code. + + If you say N, all options in this submenu will be skipped and disabled. if MISC_DEVICES diff --git a/drivers/misc/asus-laptop.c b/drivers/misc/asus-laptop.c index d0fc4fd212e..7dce318df1b 100644 --- a/drivers/misc/asus-laptop.c +++ b/drivers/misc/asus-laptop.c @@ -732,7 +732,7 @@ static void asus_hotk_notify(acpi_handle handle, u32 event, void *data) lcd_blank(FB_BLANK_POWERDOWN); } - acpi_bus_generate_event(hotk->device, event, + acpi_bus_generate_proc_event(hotk->device, event, hotk->event_count[event % 128]++); return; @@ -1072,7 +1072,8 @@ static void asus_backlight_exit(void) } #define ASUS_LED_UNREGISTER(object) \ - led_classdev_unregister(&object##_led) + if (object##_led.dev) \ + led_classdev_unregister(&object##_led) static void asus_led_exit(void) { diff --git a/drivers/misc/sony-laptop.c b/drivers/misc/sony-laptop.c index 91da6880ae9..d38ddce592c 100644 --- a/drivers/misc/sony-laptop.c +++ b/drivers/misc/sony-laptop.c @@ -856,6 +856,15 @@ static struct dmi_system_id sony_nc_ids[] = { }, }, { + .ident = "Sony Vaio FZ Series", + .callback = sony_nc_C_enable, + .driver_data = sony_C_events, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), + DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ"), + }, + }, + { .ident = "Sony Vaio C Series", .callback = sony_nc_C_enable, .driver_data = sony_C_events, @@ -904,7 +913,7 @@ static void sony_acpi_notify(acpi_handle handle, u32 event, void *data) dprintk("sony_acpi_notify, event: 0x%.2x\n", ev); sony_laptop_report_input_event(ev); - acpi_bus_generate_event(sony_nc_acpi_device, 1, ev); + acpi_bus_generate_proc_event(sony_nc_acpi_device, 1, ev); } static acpi_status sony_walk_callback(acpi_handle handle, u32 level, @@ -2292,7 +2301,7 @@ static irqreturn_t sony_pic_irq(int irq, void *dev_id) found: sony_laptop_report_input_event(device_event); - acpi_bus_generate_event(spic_dev.acpi_dev, 1, device_event); + acpi_bus_generate_proc_event(spic_dev.acpi_dev, 1, device_event); sonypi_compat_report_event(device_event); return IRQ_HANDLED; @@ -2308,8 +2317,6 @@ static int sony_pic_remove(struct acpi_device *device, int type) struct sony_pic_ioport *io, *tmp_io; struct sony_pic_irq *irq, *tmp_irq; - sonypi_compat_exit(); - if (sony_pic_disable(device)) { printk(KERN_ERR DRV_PFX "Couldn't disable device.\n"); return -ENXIO; @@ -2319,6 +2326,8 @@ static int sony_pic_remove(struct acpi_device *device, int type) release_region(spic_dev.cur_ioport->io.minimum, spic_dev.cur_ioport->io.address_length); + sonypi_compat_exit(); + sony_laptop_remove_input(); /* pf attrs */ @@ -2384,6 +2393,9 @@ static int sony_pic_add(struct acpi_device *device) goto err_free_resources; } + if (sonypi_compat_init()) + goto err_remove_input; + /* request io port */ list_for_each_entry(io, &spic_dev.ioports, list) { if (request_region(io->io.minimum, io->io.address_length, @@ -2398,7 +2410,7 @@ static int sony_pic_add(struct acpi_device *device) if (!spic_dev.cur_ioport) { printk(KERN_ERR DRV_PFX "Failed to request_region.\n"); result = -ENODEV; - goto err_remove_input; + goto err_remove_compat; } /* request IRQ */ @@ -2438,9 +2450,6 @@ static int sony_pic_add(struct acpi_device *device) if (result) goto err_remove_pf; - if (sonypi_compat_init()) - goto err_remove_pf; - return 0; err_remove_pf: @@ -2456,6 +2465,9 @@ err_release_region: release_region(spic_dev.cur_ioport->io.minimum, spic_dev.cur_ioport->io.address_length); +err_remove_compat: + sonypi_compat_exit(); + err_remove_input: sony_laptop_remove_input(); diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c index f6cd34a3dba..bb8956d0c10 100644 --- a/drivers/misc/thinkpad_acpi.c +++ b/drivers/misc/thinkpad_acpi.c @@ -1190,10 +1190,10 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event) } if (sendacpi) - acpi_bus_generate_event(ibm->acpi->device, event, hkey); + acpi_bus_generate_proc_event(ibm->acpi->device, event, hkey); } else { printk(IBM_ERR "unknown hotkey notification event %d\n", event); - acpi_bus_generate_event(ibm->acpi->device, event, 0); + acpi_bus_generate_proc_event(ibm->acpi->device, event, 0); } } @@ -2162,22 +2162,27 @@ static void dock_notify(struct ibm_struct *ibm, u32 event) int docked = dock_docked(); int pci = ibm->acpi->hid && ibm->acpi->device && acpi_match_device_ids(ibm->acpi->device, ibm_pci_device_ids); + int data; if (event == 1 && !pci) /* 570 */ - acpi_bus_generate_event(ibm->acpi->device, event, 1); /* button */ + data = 1; /* button */ else if (event == 1 && pci) /* 570 */ - acpi_bus_generate_event(ibm->acpi->device, event, 3); /* dock */ + data = 3; /* dock */ else if (event == 3 && docked) - acpi_bus_generate_event(ibm->acpi->device, event, 1); /* button */ + data = 1; /* button */ else if (event == 3 && !docked) - acpi_bus_generate_event(ibm->acpi->device, event, 2); /* undock */ + data = 2; /* undock */ else if (event == 0 && docked) - acpi_bus_generate_event(ibm->acpi->device, event, 3); /* dock */ + data = 3; /* dock */ else { printk(IBM_ERR "unknown dock event %d, status %d\n", event, _sta(dock_handle)); - acpi_bus_generate_event(ibm->acpi->device, event, 0); /* unknown */ + data = 0; /* unknown */ } + acpi_bus_generate_proc_event(ibm->acpi->device, event, data); + acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class, + ibm->acpi->device->dev.bus_id, + event, data); } static int dock_read(char *p) @@ -2275,7 +2280,10 @@ static int __init bay_init(struct ibm_init_struct *iibm) static void bay_notify(struct ibm_struct *ibm, u32 event) { - acpi_bus_generate_event(ibm->acpi->device, event, 0); + acpi_bus_generate_proc_event(ibm->acpi->device, event, 0); + acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class, + ibm->acpi->device->dev.bus_id, + event, 0); } #define bay_occupied(b) (_sta(b##_handle) & 1) diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index fe0e785ed7d..817a79462b3 100644 --- a/drivers/mmc/core/bus.c +++ b/drivers/mmc/core/bus.c @@ -186,12 +186,10 @@ struct mmc_card *mmc_alloc_card(struct mmc_host *host) { struct mmc_card *card; - card = kmalloc(sizeof(struct mmc_card), GFP_KERNEL); + card = kzalloc(sizeof(struct mmc_card), GFP_KERNEL); if (!card) return ERR_PTR(-ENOMEM); - memset(card, 0, sizeof(struct mmc_card)); - card->host = host; device_initialize(&card->dev); diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index 6a7e2984960..2c7ce8f43a9 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c @@ -58,12 +58,10 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev) { struct mmc_host *host; - host = kmalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL); + host = kzalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL); if (!host) return NULL; - memset(host, 0, sizeof(struct mmc_host) + extra); - host->parent = dev; host->class_dev.parent = dev; host->class_dev.class = &mmc_host_class; diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index f2bc87ac24f..20a7d89e01b 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -385,6 +385,9 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data) BUG_ON(data->blksz > host->mmc->max_blk_size); BUG_ON(data->blocks > 65535); + host->data = data; + host->data_early = 0; + /* timeout in us */ target_timeout = data->timeout_ns / 1000 + data->timeout_clks / host->clock; @@ -443,11 +446,11 @@ static void sdhci_set_transfer_mode(struct sdhci_host *host, { u16 mode; - WARN_ON(host->data); - if (data == NULL) return; + WARN_ON(!host->data); + mode = SDHCI_TRNS_BLK_CNT_EN; if (data->blocks > 1) mode |= SDHCI_TRNS_MULTI; @@ -477,8 +480,8 @@ static void sdhci_finish_data(struct sdhci_host *host) /* * Controller doesn't count down when in single block mode. */ - if ((data->blocks == 1) && (data->error == MMC_ERR_NONE)) - blocks = 0; + if (data->blocks == 1) + blocks = (data->error == MMC_ERR_NONE) ? 0 : 1; else blocks = readw(host->ioaddr + SDHCI_BLOCK_COUNT); data->bytes_xfered = data->blksz * (data->blocks - blocks); @@ -600,9 +603,10 @@ static void sdhci_finish_command(struct sdhci_host *host) host->cmd->error = MMC_ERR_NONE; - if (host->cmd->data) - host->data = host->cmd->data; - else + if (host->data && host->data_early) + sdhci_finish_data(host); + + if (!host->cmd->data) tasklet_schedule(&host->finish_tasklet); host->cmd = NULL; @@ -929,9 +933,9 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask) BUG_ON(intmask == 0); if (!host->cmd) { - printk(KERN_ERR "%s: Got command interrupt even though no " - "command operation was in progress.\n", - mmc_hostname(host->mmc)); + printk(KERN_ERR "%s: Got command interrupt 0x%08x even " + "though no command operation was in progress.\n", + mmc_hostname(host->mmc), (unsigned)intmask); sdhci_dumpregs(host); return; } @@ -961,9 +965,9 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) if (intmask & SDHCI_INT_DATA_END) return; - printk(KERN_ERR "%s: Got data interrupt even though no " - "data operation was in progress.\n", - mmc_hostname(host->mmc)); + printk(KERN_ERR "%s: Got data interrupt 0x%08x even " + "though no data operation was in progress.\n", + mmc_hostname(host->mmc), (unsigned)intmask); sdhci_dumpregs(host); return; @@ -991,8 +995,18 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) writel(readl(host->ioaddr + SDHCI_DMA_ADDRESS), host->ioaddr + SDHCI_DMA_ADDRESS); - if (intmask & SDHCI_INT_DATA_END) - sdhci_finish_data(host); + if (intmask & SDHCI_INT_DATA_END) { + if (host->cmd) { + /* + * Data managed to finish before the + * command completed. Make sure we do + * things in the proper order. + */ + host->data_early = 1; + } else { + sdhci_finish_data(host); + } + } } } @@ -1347,12 +1361,11 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot) */ mmc->max_blk_size = (caps & SDHCI_MAX_BLOCK_MASK) >> SDHCI_MAX_BLOCK_SHIFT; if (mmc->max_blk_size >= 3) { - printk(KERN_ERR "%s: Invalid maximum block size.\n", + printk(KERN_WARNING "%s: Invalid maximum block size, assuming 512\n", host->slot_descr); - ret = -ENODEV; - goto unmap; - } - mmc->max_blk_size = 512 << mmc->max_blk_size; + mmc->max_blk_size = 512; + } else + mmc->max_blk_size = 512 << mmc->max_blk_size; /* * Maximum block count. diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index d157776c114..e28987d6d2e 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -182,6 +182,7 @@ struct sdhci_host { struct mmc_request *mrq; /* Current request */ struct mmc_command *cmd; /* Current command */ struct mmc_data *data; /* Current data request */ + int data_early:1; /* Data finished before cmd */ struct scatterlist *cur_sg; /* We're working on this */ int num_sg; /* Entries left */ diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 81ef81c9a58..5b9e17bf174 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -1968,6 +1968,16 @@ menuconfig NETDEV_1000 bool "Ethernet (1000 Mbit)" depends on !UML default y + ---help--- + Ethernet (also called IEEE 802.3 or ISO 8802-2) is the most common + type of Local Area Network (LAN) in universities and companies. + + Say Y here to get to see options for Gigabit Ethernet drivers. + This option alone does not add any kernel code. + Note that drivers supporting both 100 and 1000 MBit may be listed + under "Ethernet (10 or 100MBit)" instead. + + If you say N, all options in this submenu will be skipped and disabled. if NETDEV_1000 @@ -2339,6 +2349,11 @@ menuconfig NETDEV_10000 bool "Ethernet (10000 Mbit)" depends on !UML default y + ---help--- + Say Y here to get to see options for 10 Gigabit Ethernet drivers. + This option alone does not add any kernel code. + + If you say N, all options in this submenu will be skipped and disabled. if NETDEV_10000 diff --git a/drivers/net/bsd_comp.c b/drivers/net/bsd_comp.c index 202d4a4ef75..88edb986691 100644 --- a/drivers/net/bsd_comp.c +++ b/drivers/net/bsd_comp.c @@ -406,8 +406,7 @@ static void *bsd_alloc (unsigned char *options, int opt_len, int decomp) * Allocate space for the dictionary. This may be more than one page in * length. */ - db->dict = (struct bsd_dict *) vmalloc (hsize * - sizeof (struct bsd_dict)); + db->dict = vmalloc(hsize * sizeof(struct bsd_dict)); if (!db->dict) { bsd_free (db); @@ -426,8 +425,7 @@ static void *bsd_alloc (unsigned char *options, int opt_len, int decomp) */ else { - db->lens = (unsigned short *) vmalloc ((maxmaxcode + 1) * - sizeof (db->lens[0])); + db->lens = vmalloc((maxmaxcode + 1) * sizeof(db->lens[0])); if (!db->lens) { bsd_free (db); diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c index c3de81bf090..738aa590651 100644 --- a/drivers/net/dm9000.c +++ b/drivers/net/dm9000.c @@ -700,6 +700,7 @@ dm9000_init_dm9000(struct net_device *dev) static int dm9000_start_xmit(struct sk_buff *skb, struct net_device *dev) { + unsigned long flags; board_info_t *db = (board_info_t *) dev->priv; PRINTK3("dm9000_start_xmit\n"); @@ -707,10 +708,7 @@ dm9000_start_xmit(struct sk_buff *skb, struct net_device *dev) if (db->tx_pkt_cnt > 1) return 1; - netif_stop_queue(dev); - - /* Disable all interrupts */ - iow(db, DM9000_IMR, IMR_PAR); + spin_lock_irqsave(&db->lock, flags); /* Move data to DM9000 TX RAM */ writeb(DM9000_MWCMD, db->io_addr); @@ -718,12 +716,9 @@ dm9000_start_xmit(struct sk_buff *skb, struct net_device *dev) (db->outblk)(db->io_data, skb->data, skb->len); db->stats.tx_bytes += skb->len; + db->tx_pkt_cnt++; /* TX control: First packet immediately send, second packet queue */ - if (db->tx_pkt_cnt == 0) { - - /* First Packet */ - db->tx_pkt_cnt++; - + if (db->tx_pkt_cnt == 1) { /* Set TX length to DM9000 */ iow(db, DM9000_TXPLL, skb->len & 0xff); iow(db, DM9000_TXPLH, (skb->len >> 8) & 0xff); @@ -732,23 +727,17 @@ dm9000_start_xmit(struct sk_buff *skb, struct net_device *dev) iow(db, DM9000_TCR, TCR_TXREQ); /* Cleared after TX complete */ dev->trans_start = jiffies; /* save the time stamp */ - } else { /* Second packet */ - db->tx_pkt_cnt++; db->queue_pkt_len = skb->len; + netif_stop_queue(dev); } + spin_unlock_irqrestore(&db->lock, flags); + /* free this SKB */ dev_kfree_skb(skb); - /* Re-enable resource check */ - if (db->tx_pkt_cnt == 1) - netif_wake_queue(dev); - - /* Re-enable interrupt */ - iow(db, DM9000_IMR, IMR_PAR | IMR_PTM | IMR_PRM); - return 0; } diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 9756211e83c..db5747490a0 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -76,7 +76,7 @@ MODULE_PARM_DESC(rq1_entries, "Number of entries for Receive Queue 1 " MODULE_PARM_DESC(sq_entries, " Number of entries for the Send Queue " "[2^x - 1], x = [6..14]. Default = " __MODULE_STRING(EHEA_DEF_ENTRIES_SQ) ")"); -MODULE_PARM_DESC(use_mcs, " 0:NAPI, 1:Multiple receive queues, Default = 1 "); +MODULE_PARM_DESC(use_mcs, " 0:NAPI, 1:Multiple receive queues, Default = 0 "); static int port_name_cnt = 0; static LIST_HEAD(adapter_list); @@ -2490,7 +2490,7 @@ static ssize_t ehea_show_port_id(struct device *dev, struct device_attribute *attr, char *buf) { struct ehea_port *port = container_of(dev, struct ehea_port, ofdev.dev); - return sprintf(buf, "0x%X", port->logical_port_id); + return sprintf(buf, "%d", port->logical_port_id); } static DEVICE_ATTR(log_port_id, S_IRUSR | S_IRGRP | S_IROTH, ehea_show_port_id, @@ -2781,7 +2781,7 @@ static ssize_t ehea_probe_port(struct device *dev, u32 logical_port_id; - sscanf(buf, "%X", &logical_port_id); + sscanf(buf, "%d", &logical_port_id); port = ehea_get_port(adapter, logical_port_id); @@ -2834,7 +2834,7 @@ static ssize_t ehea_remove_port(struct device *dev, int i; u32 logical_port_id; - sscanf(buf, "%X", &logical_port_id); + sscanf(buf, "%d", &logical_port_id); port = ehea_get_port(adapter, logical_port_id); diff --git a/drivers/net/ehea/ehea_qmr.c b/drivers/net/ehea/ehea_qmr.c index a36fa6c23fd..c82e2459607 100644 --- a/drivers/net/ehea/ehea_qmr.c +++ b/drivers/net/ehea/ehea_qmr.c @@ -235,6 +235,8 @@ int ehea_destroy_cq(struct ehea_cq *cq) if (!cq) return 0; + hcp_epas_dtor(&cq->epas); + if ((hret = ehea_destroy_cq_res(cq, NORMAL_FREE)) == H_R_STATE) { ehea_error_data(cq->adapter, cq->fw_handle); hret = ehea_destroy_cq_res(cq, FORCE_FREE); @@ -361,6 +363,8 @@ int ehea_destroy_eq(struct ehea_eq *eq) if (!eq) return 0; + hcp_epas_dtor(&eq->epas); + if ((hret = ehea_destroy_eq_res(eq, NORMAL_FREE)) == H_R_STATE) { ehea_error_data(eq->adapter, eq->fw_handle); hret = ehea_destroy_eq_res(eq, FORCE_FREE); @@ -541,6 +545,8 @@ int ehea_destroy_qp(struct ehea_qp *qp) if (!qp) return 0; + hcp_epas_dtor(&qp->epas); + if ((hret = ehea_destroy_qp_res(qp, NORMAL_FREE)) == H_R_STATE) { ehea_error_data(qp->adapter, qp->fw_handle); hret = ehea_destroy_qp_res(qp, FORCE_FREE); diff --git a/drivers/net/eql.c b/drivers/net/eql.c index a93700e5661..102218c4a90 100644 --- a/drivers/net/eql.c +++ b/drivers/net/eql.c @@ -391,7 +391,7 @@ static int __eql_insert_slave(slave_queue_t *queue, slave_t *slave) slave_t *duplicate_slave = NULL; duplicate_slave = __eql_find_slave_dev(queue, slave->dev); - if (duplicate_slave != 0) + if (duplicate_slave) eql_kill_one_slave(queue, duplicate_slave); list_add(&slave->list, &queue->all_slaves); diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 69f5f365239..1938d6dfc86 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -552,7 +552,7 @@ union ring_type { #define PHY_OUI_MARVELL 0x5043 #define PHY_OUI_CICADA 0x03f1 #define PHY_OUI_VITESSE 0x01c1 -#define PHY_OUI_REALTEK 0x01c1 +#define PHY_OUI_REALTEK 0x0732 #define PHYID1_OUI_MASK 0x03ff #define PHYID1_OUI_SHFT 6 #define PHYID2_OUI_MASK 0xfc00 @@ -3068,8 +3068,8 @@ static irqreturn_t nv_nic_irq(int foo, void *data) np->nic_poll_irq = np->irqmask; mod_timer(&np->nic_poll, jiffies + POLL_WAIT); } - printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq.\n", dev->name, i); spin_unlock(&np->lock); + printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq.\n", dev->name, i); break; } @@ -3186,8 +3186,8 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data) np->nic_poll_irq = np->irqmask; mod_timer(&np->nic_poll, jiffies + POLL_WAIT); } - printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq.\n", dev->name, i); spin_unlock(&np->lock); + printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq.\n", dev->name, i); break; } @@ -3233,8 +3233,8 @@ static irqreturn_t nv_nic_irq_tx(int foo, void *data) np->nic_poll_irq |= NVREG_IRQ_TX_ALL; mod_timer(&np->nic_poll, jiffies + POLL_WAIT); } - printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_tx.\n", dev->name, i); spin_unlock_irqrestore(&np->lock, flags); + printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_tx.\n", dev->name, i); break; } @@ -3348,8 +3348,8 @@ static irqreturn_t nv_nic_irq_rx(int foo, void *data) np->nic_poll_irq |= NVREG_IRQ_RX_ALL; mod_timer(&np->nic_poll, jiffies + POLL_WAIT); } - printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_rx.\n", dev->name, i); spin_unlock_irqrestore(&np->lock, flags); + printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_rx.\n", dev->name, i); break; } } @@ -3421,8 +3421,8 @@ static irqreturn_t nv_nic_irq_other(int foo, void *data) np->nic_poll_irq |= NVREG_IRQ_OTHER; mod_timer(&np->nic_poll, jiffies + POLL_WAIT); } - printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_other.\n", dev->name, i); spin_unlock_irqrestore(&np->lock, flags); + printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_other.\n", dev->name, i); break; } diff --git a/drivers/net/irda/kingsun-sir.c b/drivers/net/irda/kingsun-sir.c index bdd5c979bea..4e5101a45c3 100644 --- a/drivers/net/irda/kingsun-sir.c +++ b/drivers/net/irda/kingsun-sir.c @@ -509,12 +509,12 @@ static int kingsun_probe(struct usb_interface *intf, spin_lock_init(&kingsun->lock); /* Allocate input buffer */ - kingsun->in_buf = (__u8 *)kmalloc(kingsun->max_rx, GFP_KERNEL); + kingsun->in_buf = kmalloc(kingsun->max_rx, GFP_KERNEL); if (!kingsun->in_buf) goto free_mem; /* Allocate output buffer */ - kingsun->out_buf = (__u8 *)kmalloc(KINGSUN_FIFO_SIZE, GFP_KERNEL); + kingsun->out_buf = kmalloc(KINGSUN_FIFO_SIZE, GFP_KERNEL); if (!kingsun->out_buf) goto free_mem; diff --git a/drivers/net/meth.c b/drivers/net/meth.c index 92b403bf38b..32bed6bc6c0 100644 --- a/drivers/net/meth.c +++ b/drivers/net/meth.c @@ -405,7 +405,7 @@ static void meth_rx(struct net_device* dev, unsigned long int_status) priv->stats.rx_length_errors++; skb = priv->rx_skbs[priv->rx_write]; } else { - skb = alloc_skb(METH_RX_BUFF_SIZE, GFP_ATOMIC | GFP_DMA); + skb = alloc_skb(METH_RX_BUFF_SIZE, GFP_ATOMIC); if (!skb) { /* Ouch! No memory! Drop packet on the floor */ DPRINTK("No mem: dropping packet\n"); diff --git a/drivers/net/mlx4/reset.c b/drivers/net/mlx4/reset.c index e4dfd4b11a4..e199715fabd 100644 --- a/drivers/net/mlx4/reset.c +++ b/drivers/net/mlx4/reset.c @@ -119,6 +119,9 @@ int mlx4_reset(struct mlx4_dev *dev) writel(MLX4_RESET_VALUE, reset + MLX4_RESET_OFFSET); iounmap(reset); + /* Docs say to wait one second before accessing device */ + msleep(1000); + end = jiffies + MLX4_RESET_TIMEOUT_JIFFIES; do { if (!pci_read_config_word(dev->pdev, PCI_VENDOR_ID, &vendor) && diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index ae9bb7b7fd6..1c42266bf88 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -72,7 +72,7 @@ #include "myri10ge_mcp.h" #include "myri10ge_mcp_gen_header.h" -#define MYRI10GE_VERSION_STR "1.3.1-1.248" +#define MYRI10GE_VERSION_STR "1.3.2-1.269" MODULE_DESCRIPTION("Myricom 10G driver (10GbE)"); MODULE_AUTHOR("Maintainer: help@myri.com"); @@ -2514,26 +2514,20 @@ static void myri10ge_firmware_probe(struct myri10ge_priv *mgp) { struct pci_dev *pdev = mgp->pdev; struct device *dev = &pdev->dev; - int cap, status; - u16 val; + int status; mgp->tx.boundary = 4096; /* * Verify the max read request size was set to 4KB * before trying the test with 4KB. */ - cap = pci_find_capability(pdev, PCI_CAP_ID_EXP); - if (cap < 64) { - dev_err(dev, "Bad PCI_CAP_ID_EXP location %d\n", cap); - goto abort; - } - status = pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &val); - if (status != 0) { + status = pcie_get_readrq(pdev); + if (status < 0) { dev_err(dev, "Couldn't read max read req size: %d\n", status); goto abort; } - if ((val & (5 << 12)) != (5 << 12)) { - dev_warn(dev, "Max Read Request size != 4096 (0x%x)\n", val); + if (status != 4096) { + dev_warn(dev, "Max Read Request size != 4096 (%d)\n", status); mgp->tx.boundary = 2048; } /* @@ -2850,9 +2844,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) size_t bytes; int i; int status = -ENXIO; - int cap; int dac_enabled; - u16 val; netdev = alloc_etherdev(sizeof(*mgp)); if (netdev == NULL) { @@ -2884,19 +2876,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) = pci_find_capability(pdev, PCI_CAP_ID_VNDR); /* Set our max read request to 4KB */ - cap = pci_find_capability(pdev, PCI_CAP_ID_EXP); - if (cap < 64) { - dev_err(&pdev->dev, "Bad PCI_CAP_ID_EXP location %d\n", cap); - goto abort_with_netdev; - } - status = pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &val); - if (status != 0) { - dev_err(&pdev->dev, "Error %d reading PCI_EXP_DEVCTL\n", - status); - goto abort_with_netdev; - } - val = (val & ~PCI_EXP_DEVCTL_READRQ) | (5 << 12); - status = pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL, val); + status = pcie_set_readrq(pdev, 4096); if (status != 0) { dev_err(&pdev->dev, "Error %d writing PCI_EXP_DEVCTL\n", status); diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index a8b74cdab1e..e275df8c55b 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -364,7 +364,7 @@ EXPORT_SYMBOL(genphy_config_advert); */ int genphy_setup_forced(struct phy_device *phydev) { - int ctl = BMCR_RESET; + int ctl = 0; phydev->pause = phydev->asym_pause = 0; diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index ef3325b6923..9293c82ef2a 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c @@ -1726,7 +1726,7 @@ ppp_decompress_frame(struct ppp *ppp, struct sk_buff *skb) } /* the decompressor still expects the A/C bytes in the hdr */ len = ppp->rcomp->decompress(ppp->rc_state, skb->data - 2, - skb->len + 2, ns->data, ppp->mru + PPP_HDRLEN); + skb->len + 2, ns->data, obuff_size); if (len < 0) { /* Pass the compressed frame to pppd as an error indication. */ diff --git a/drivers/net/sgiseeq.c b/drivers/net/sgiseeq.c index 384b4685e97..0fb74cb51c4 100644 --- a/drivers/net/sgiseeq.c +++ b/drivers/net/sgiseeq.c @@ -726,7 +726,7 @@ err_out: return err; } -static void __exit sgiseeq_remove(struct platform_device *pdev) +static int __exit sgiseeq_remove(struct platform_device *pdev) { struct net_device *dev = platform_get_drvdata(pdev); struct sgiseeq_private *sp = netdev_priv(dev); @@ -735,6 +735,8 @@ static void __exit sgiseeq_remove(struct platform_device *pdev) free_page((unsigned long) sp->srings); free_netdev(dev); platform_set_drvdata(pdev, NULL); + + return 0; } static struct platform_driver sgiseeq_driver = { diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index e7a2eadcc3b..e6d937ec688 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -51,7 +51,7 @@ #include "sky2.h" #define DRV_NAME "sky2" -#define DRV_VERSION "1.16" +#define DRV_VERSION "1.17" #define PFX DRV_NAME " " /* @@ -99,10 +99,6 @@ static int disable_msi = 0; module_param(disable_msi, int, 0); MODULE_PARM_DESC(disable_msi, "Disable Message Signaled Interrupt (MSI)"); -static int idle_timeout = 100; -module_param(idle_timeout, int, 0); -MODULE_PARM_DESC(idle_timeout, "Watchdog timer for lost interrupts (ms)"); - static const struct pci_device_id sky2_id_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9000) }, /* SK-9Sxx */ { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) }, /* SK-9Exx */ @@ -219,9 +215,12 @@ static void sky2_power_on(struct sky2_hw *hw) else sky2_write8(hw, B2_Y2_CLK_GATE, 0); - if (hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX) { + if (hw->chip_id == CHIP_ID_YUKON_EC_U || + hw->chip_id == CHIP_ID_YUKON_EX) { u32 reg; + sky2_pci_write32(hw, PCI_DEV_REG3, 0); + reg = sky2_pci_read32(hw, PCI_DEV_REG4); /* set all bits to 0 except bits 15..12 and 8 */ reg &= P_ASPM_CONTROL_MSK; @@ -238,6 +237,8 @@ static void sky2_power_on(struct sky2_hw *hw) reg = sky2_read32(hw, B2_GP_IO); reg |= GLB_GPIO_STAT_RACE_DIS; sky2_write32(hw, B2_GP_IO, reg); + + sky2_read32(hw, B2_GP_IO); } } @@ -696,8 +697,8 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port) int i; const u8 *addr = hw->dev[port]->dev_addr; - sky2_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET); - sky2_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR); + sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET); + sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR); sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_CLR); @@ -1619,6 +1620,9 @@ static int sky2_down(struct net_device *dev) if (netif_msg_ifdown(sky2)) printk(KERN_INFO PFX "%s: disabling interface\n", dev->name); + if (netif_carrier_ok(dev) && --hw->active == 0) + del_timer(&hw->watchdog_timer); + /* Stop more packets from being queued */ netif_stop_queue(dev); @@ -1739,6 +1743,10 @@ static void sky2_link_up(struct sky2_port *sky2) netif_carrier_on(sky2->netdev); + if (hw->active++ == 0) + mod_timer(&hw->watchdog_timer, jiffies + 1); + + /* Turn on link LED */ sky2_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_ON | LINKLED_BLINK_OFF | LINKLED_LINKSYNC_OFF); @@ -1790,6 +1798,11 @@ static void sky2_link_down(struct sky2_port *sky2) netif_carrier_off(sky2->netdev); + /* Stop watchdog if both ports are not active */ + if (--hw->active == 0) + del_timer(&hw->watchdog_timer); + + /* Turn on link LED */ sky2_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF); @@ -2421,25 +2434,20 @@ static void sky2_le_error(struct sky2_hw *hw, unsigned port, sky2_write32(hw, Q_ADDR(q, Q_CSR), BMU_CLR_IRQ_CHK); } -/* If idle then force a fake soft NAPI poll once a second - * to work around cases where sharing an edge triggered interrupt. - */ -static inline void sky2_idle_start(struct sky2_hw *hw) -{ - if (idle_timeout > 0) - mod_timer(&hw->idle_timer, - jiffies + msecs_to_jiffies(idle_timeout)); -} - -static void sky2_idle(unsigned long arg) +/* Check for lost IRQ once a second */ +static void sky2_watchdog(unsigned long arg) { struct sky2_hw *hw = (struct sky2_hw *) arg; - struct net_device *dev = hw->dev[0]; - if (__netif_rx_schedule_prep(dev)) - __netif_rx_schedule(dev); + if (sky2_read32(hw, B0_ISRC)) { + struct net_device *dev = hw->dev[0]; - mod_timer(&hw->idle_timer, jiffies + msecs_to_jiffies(idle_timeout)); + if (__netif_rx_schedule_prep(dev)) + __netif_rx_schedule(dev); + } + + if (hw->active > 0) + mod_timer(&hw->watchdog_timer, round_jiffies(jiffies + HZ)); } /* Hardware/software error handling */ @@ -2727,8 +2735,6 @@ static void sky2_restart(struct work_struct *work) struct net_device *dev; int i, err; - del_timer_sync(&hw->idle_timer); - rtnl_lock(); sky2_write32(hw, B0_IMSK, 0); sky2_read32(hw, B0_IMSK); @@ -2757,8 +2763,6 @@ static void sky2_restart(struct work_struct *work) } } - sky2_idle_start(hw); - rtnl_unlock(); } @@ -4025,11 +4029,9 @@ static int __devinit sky2_probe(struct pci_dev *pdev, sky2_show_addr(dev1); } - setup_timer(&hw->idle_timer, sky2_idle, (unsigned long) hw); + setup_timer(&hw->watchdog_timer, sky2_watchdog, (unsigned long) hw); INIT_WORK(&hw->restart_work, sky2_restart); - sky2_idle_start(hw); - pci_set_drvdata(pdev, hw); return 0; @@ -4064,7 +4066,7 @@ static void __devexit sky2_remove(struct pci_dev *pdev) if (!hw) return; - del_timer_sync(&hw->idle_timer); + del_timer_sync(&hw->watchdog_timer); flush_scheduled_work(); @@ -4108,7 +4110,6 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state) if (!hw) return 0; - del_timer_sync(&hw->idle_timer); netif_poll_disable(hw->dev[0]); for (i = 0; i < hw->ports; i++) { @@ -4174,7 +4175,7 @@ static int sky2_resume(struct pci_dev *pdev) } netif_poll_enable(hw->dev[0]); - sky2_idle_start(hw); + return 0; out: dev_err(&pdev->dev, "resume failed (%d)\n", err); @@ -4191,7 +4192,6 @@ static void sky2_shutdown(struct pci_dev *pdev) if (!hw) return; - del_timer_sync(&hw->idle_timer); netif_poll_disable(hw->dev[0]); for (i = 0; i < hw->ports; i++) { diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h index dce4d276d44..72e12b7cfa4 100644 --- a/drivers/net/sky2.h +++ b/drivers/net/sky2.h @@ -2045,12 +2045,13 @@ struct sky2_hw { u8 chip_rev; u8 pmd_type; u8 ports; + u8 active; struct sky2_status_le *st_le; u32 st_idx; dma_addr_t st_dma; - struct timer_list idle_timer; + struct timer_list watchdog_timer; struct work_struct restart_work; int msi; wait_queue_head_t msi_wait; diff --git a/drivers/net/slip.c b/drivers/net/slip.c index 65bd20fac82..3fd4735006f 100644 --- a/drivers/net/slip.c +++ b/drivers/net/slip.c @@ -957,7 +957,7 @@ slip_close(struct tty_struct *tty) * STANDARD SLIP ENCAPSULATION * ************************************************************************/ -int +static int slip_esc(unsigned char *s, unsigned char *d, int len) { unsigned char *ptr = d; diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c index 70db38c0ced..56829f82be4 100644 --- a/drivers/pci/hotplug/acpiphp_ibm.c +++ b/drivers/pci/hotplug/acpiphp_ibm.c @@ -267,7 +267,10 @@ static void ibm_handle_events(acpi_handle handle, u32 event, void *context) if (subevent == 0x80) { dbg("%s: generationg bus event\n", __FUNCTION__); - acpi_bus_generate_event(note->device, note->event, detail); + acpi_bus_generate_proc_event(note->device, note->event, detail); + acpi_bus_generate_netlink_event(note->device->pnp.device_class, + note->device->dev.bus_id, + note->event, detail); } else note->event = event; } @@ -399,7 +402,7 @@ static acpi_status __init ibm_find_acpi_device(acpi_handle handle, status = acpi_get_object_info(handle, &info_buffer); if (ACPI_FAILURE(status)) { - err("%s: Failed to get device information", __FUNCTION__); + err("%s: Failed to get device information\n", __FUNCTION__); return 0; } info.hardware_id.value[sizeof(info.hardware_id.value) - 1] = '\0'; diff --git a/drivers/pci/hotplug/cpqphp_ctrl.c b/drivers/pci/hotplug/cpqphp_ctrl.c index 79ff6b4de3a..37d72f123a8 100644 --- a/drivers/pci/hotplug/cpqphp_ctrl.c +++ b/drivers/pci/hotplug/cpqphp_ctrl.c @@ -1746,10 +1746,8 @@ static void pushbutton_helper_thread(unsigned long data) static int event_thread(void* data) { struct controller *ctrl; - lock_kernel(); + daemonize("phpd_event"); - - unlock_kernel(); while (1) { dbg("!!!!event_thread sleeping\n"); diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index c6e132d7c0f..4c36e80f6d2 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -5,12 +5,7 @@ extern int pci_uevent(struct device *dev, char **envp, int num_envp, extern int pci_create_sysfs_dev_files(struct pci_dev *pdev); extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev); extern void pci_cleanup_rom(struct pci_dev *dev); -extern int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, - resource_size_t size, resource_size_t align, - resource_size_t min, unsigned int type_mask, - void (*alignf)(void *, struct resource *, - resource_size_t, resource_size_t), - void *alignf_data); + /* Firmware callbacks */ extern pci_power_t (*platform_pci_choose_state)(struct pci_dev *dev, pm_message_t state); extern int (*platform_pci_set_power_state)(struct pci_dev *dev, pci_power_t state); @@ -35,7 +30,6 @@ static inline int pci_proc_detach_bus(struct pci_bus *bus) { return 0; } /* Functions for PCI Hotplug drivers to use */ extern unsigned int pci_do_scan_bus(struct pci_bus *bus); -extern int pci_bus_find_capability (struct pci_bus *bus, unsigned int devfn, int cap); extern void pci_remove_legacy_files(struct pci_bus *bus); diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 34b8dae0d90..27e00b2d7b5 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -653,20 +653,20 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass sprintf(child->name, (is_cardbus ? "PCI CardBus #%02x" : "PCI Bus #%02x"), child->number); + /* Has only triggered on CardBus, fixup is in yenta_socket */ while (bus->parent) { if ((child->subordinate > bus->subordinate) || (child->number > bus->subordinate) || (child->number < bus->number) || (child->subordinate < bus->number)) { - printk(KERN_WARNING "PCI: Bus #%02x (-#%02x) is " - "hidden behind%s bridge #%02x (-#%02x)%s\n", - child->number, child->subordinate, - bus->self->transparent ? " transparent" : " ", - bus->number, bus->subordinate, - pcibios_assign_all_busses() ? " " : - " (try 'pci=assign-busses')"); - printk(KERN_WARNING "Please report the result to " - "<bk@suse.de> to fix this permanently\n"); + pr_debug("PCI: Bus #%02x (-#%02x) is %s" + "hidden behind%s bridge #%02x (-#%02x)\n", + child->number, child->subordinate, + (bus->number > child->subordinate && + bus->subordinate < child->number) ? + "wholly " : " partially", + bus->self->transparent ? " transparent" : " ", + bus->number, bus->subordinate); } bus = bus->parent; } diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index c559085c89a..2d40f437b9f 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -947,7 +947,7 @@ static void k8t_sound_hostbridge(struct pci_dev *dev) unsigned char val; pci_read_config_byte(dev, 0x50, &val); - if (val == 0x88 || val == 0xc8) { + if (val == 0xc8) { /* Assume it's probably a MSI-K8T-Neo2Fir */ printk(KERN_INFO "PCI: MSI-K8T-Neo2Fir, attempting to turn soundcard ON\n"); pci_write_config_byte(dev, 0x50, val & (~0x40)); @@ -1485,7 +1485,7 @@ static void __devinit quirk_e100_interrupt(struct pci_dev *dev) iounmap(csr); } -DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, quirk_e100_interrupt); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, quirk_e100_interrupt); static void __devinit fixup_rev1_53c810(struct pci_dev* dev) { @@ -1650,6 +1650,9 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_GCN DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1000_PCIX, quirk_disable_all_msi); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS400_200, quirk_disable_all_msi); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS480, quirk_disable_all_msi); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RD580, quirk_disable_all_msi); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RX790, quirk_disable_all_msi); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS690, quirk_disable_all_msi); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT3351, quirk_disable_all_msi); /* Disable MSI on chipsets that are known to not support it */ diff --git a/drivers/pnp/card.c b/drivers/pnp/card.c index b6a4f02b01d..6c0440c20e3 100644 --- a/drivers/pnp/card.c +++ b/drivers/pnp/card.c @@ -25,13 +25,13 @@ static const struct pnp_card_device_id *match_card(struct pnp_card_driver *drv, int found; struct pnp_dev *dev; - if (i == PNP_MAX_DEVICES - || !*drv_id->devs[i].id) + if (i == PNP_MAX_DEVICES || + !*drv_id->devs[i].id) return drv_id; found = 0; card_for_each_dev(card, dev) { - if (compare_pnp_id - (dev->id, drv_id->devs[i].id)) { + if (compare_pnp_id(dev->id, + drv_id->devs[i].id)) { found = 1; break; } @@ -183,7 +183,7 @@ static int pnp_interface_attach_card(struct pnp_card *card) return 0; - err_name: +err_name: device_remove_file(&card->dev, &dev_attr_name); return rc; } @@ -321,10 +321,10 @@ struct pnp_dev *pnp_request_card_device(struct pnp_card_link *clink, pos = pos->next; } - done: +done: return NULL; - found: +found: dev->card_link = clink; dev->dev.driver = &drv->link.driver; if (pnp_bus_type.probe(&dev->dev)) @@ -334,7 +334,7 @@ struct pnp_dev *pnp_request_card_device(struct pnp_card_link *clink, return dev; - err_out: +err_out: dev->dev.driver = NULL; dev->card_link = NULL; return NULL; diff --git a/drivers/pnp/core.c b/drivers/pnp/core.c index 61066fdb9e6..d5964feb14d 100644 --- a/drivers/pnp/core.c +++ b/drivers/pnp/core.c @@ -52,9 +52,6 @@ int pnp_register_protocol(struct pnp_protocol *protocol) int nodenum; struct list_head *pos; - if (!protocol) - return -EINVAL; - INIT_LIST_HEAD(&protocol->devices); INIT_LIST_HEAD(&protocol->cards); nodenum = 0; @@ -94,8 +91,6 @@ static void pnp_free_ids(struct pnp_dev *dev) struct pnp_id *id; struct pnp_id *next; - if (!dev) - return; id = dev->id; while (id) { next = id->next; @@ -143,7 +138,7 @@ int __pnp_add_device(struct pnp_dev *dev) */ int pnp_add_device(struct pnp_dev *dev) { - if (!dev || !dev->protocol || dev->card) + if (dev->card) return -EINVAL; dev->dev.parent = &dev->protocol->dev; sprintf(dev->dev.bus_id, "%02x:%02x", dev->protocol->number, diff --git a/drivers/pnp/driver.c b/drivers/pnp/driver.c index 30b8f6f3258..2fa64a6b25c 100644 --- a/drivers/pnp/driver.c +++ b/drivers/pnp/driver.c @@ -118,7 +118,7 @@ static int pnp_device_probe(struct device *dev) goto fail; return error; - fail: +fail: pnp_device_detach(pnp_dev); return error; } @@ -232,10 +232,6 @@ int pnp_add_id(struct pnp_id *id, struct pnp_dev *dev) { struct pnp_id *ptr; - if (!id) - return -EINVAL; - if (!dev) - return -EINVAL; id->next = NULL; ptr = dev->id; while (ptr && ptr->next) diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c index fe6684e13e8..a0cfb75bbb8 100644 --- a/drivers/pnp/interface.c +++ b/drivers/pnp/interface.c @@ -459,7 +459,8 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr, up(&pnp_res_mutex); goto done; } - done: + +done: if (retval < 0) return retval; return count; @@ -499,10 +500,10 @@ int pnp_interface_attach_device(struct pnp_dev *dev) return 0; - err_res: +err_res: device_remove_file(&dev->dev, &dev_attr_resources); - err_opt: +err_opt: device_remove_file(&dev->dev, &dev_attr_options); - err: +err: return rc; } diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c index b4e2aa995b5..b035d60a1dc 100644 --- a/drivers/pnp/isapnp/core.c +++ b/drivers/pnp/isapnp/core.c @@ -47,9 +47,6 @@ #if 0 #define ISAPNP_REGION_OK #endif -#if 0 -#define ISAPNP_DEBUG -#endif int isapnp_disable; /* Disable ISA PnP */ static int isapnp_rdp; /* Read Data Port */ @@ -93,7 +90,6 @@ MODULE_LICENSE("GPL"); static unsigned char isapnp_checksum_value; static DEFINE_MUTEX(isapnp_cfg_mutex); -static int isapnp_detected; static int isapnp_csn_count; /* some prototypes */ @@ -335,7 +331,7 @@ static int __init isapnp_isolate(void) } else if (iteration > 1) { break; } - __next: +__next: if (csn == 255) break; checksum = 0x6a; @@ -733,7 +729,7 @@ static int __init isapnp_create_device(struct pnp_card *card, "isapnp: unexpected or unknown tag type 0x%x for logical device %i (device %i), ignored\n", type, dev->number, card->number); } - __skip: +__skip: if (size > 0) isapnp_skip_bytes(size); } @@ -788,7 +784,7 @@ static void __init isapnp_parse_resource_map(struct pnp_card *card) "isapnp: unexpected or unknown tag type 0x%x for device %i, ignored\n", type, card->number); } - __skip: +__skip: if (size > 0) isapnp_skip_bytes(size); } @@ -940,9 +936,6 @@ EXPORT_SYMBOL(isapnp_protocol); EXPORT_SYMBOL(isapnp_present); EXPORT_SYMBOL(isapnp_cfg_begin); EXPORT_SYMBOL(isapnp_cfg_end); -#if 0 -EXPORT_SYMBOL(isapnp_read_byte); -#endif EXPORT_SYMBOL(isapnp_write_byte); static int isapnp_read_resources(struct pnp_dev *dev, @@ -993,6 +986,7 @@ static int isapnp_get_resources(struct pnp_dev *dev, struct pnp_resource_table *res) { int ret; + pnp_init_resource_table(res); isapnp_cfg_begin(dev->card->number, dev->number); ret = isapnp_read_resources(dev, res); @@ -1046,7 +1040,7 @@ static int isapnp_set_resources(struct pnp_dev *dev, static int isapnp_disable_resources(struct pnp_dev *dev) { - if (!dev || !dev->active) + if (!dev->active) return -EINVAL; isapnp_cfg_begin(dev->card->number, dev->number); isapnp_deactivate(dev->number); @@ -1069,7 +1063,6 @@ static int __init isapnp_init(void) struct pnp_dev *dev; if (isapnp_disable) { - isapnp_detected = 0; printk(KERN_INFO "isapnp: ISA Plug & Play support disabled\n"); return 0; } @@ -1117,7 +1110,6 @@ static int __init isapnp_init(void) } isapnp_set_rdp(); } - isapnp_detected = 1; if (isapnp_rdp < 0x203 || isapnp_rdp > 0x3ff) { cards = isapnp_isolate(); if (cards < 0 || (isapnp_rdp < 0x203 || isapnp_rdp > 0x3ff)) { @@ -1125,7 +1117,6 @@ static int __init isapnp_init(void) release_region(_PIDXR, 1); #endif release_region(_PNPWRP, 1); - isapnp_detected = 0; printk(KERN_INFO "isapnp: No Plug & Play device found\n"); return 0; @@ -1148,13 +1139,12 @@ static int __init isapnp_init(void) } } } - if (cards) { + if (cards) printk(KERN_INFO "isapnp: %i Plug & Play card%s detected total\n", cards, cards > 1 ? "s" : ""); - } else { + else printk(KERN_INFO "isapnp: No Plug & Play card found\n"); - } isapnp_proc_init(); return 0; diff --git a/drivers/pnp/isapnp/proc.c b/drivers/pnp/isapnp/proc.c index 3fbc0f9ffc2..560ccb64081 100644 --- a/drivers/pnp/isapnp/proc.c +++ b/drivers/pnp/isapnp/proc.c @@ -112,33 +112,6 @@ static int isapnp_proc_attach_device(struct pnp_dev *dev) return 0; } -#ifdef MODULE -static int __exit isapnp_proc_detach_device(struct pnp_dev *dev) -{ - struct pnp_card *bus = dev->card; - struct proc_dir_entry *de; - char name[16]; - - if (!(de = bus->procdir)) - return -EINVAL; - sprintf(name, "%02x", dev->number); - remove_proc_entry(name, de); - return 0; -} - -static int __exit isapnp_proc_detach_bus(struct pnp_card *bus) -{ - struct proc_dir_entry *de; - char name[16]; - - if (!(de = bus->procdir)) - return -EINVAL; - sprintf(name, "%02x", bus->number); - remove_proc_entry(name, isapnp_proc_bus_dir); - return 0; -} -#endif /* MODULE */ - int __init isapnp_proc_init(void) { struct pnp_dev *dev; @@ -149,21 +122,3 @@ int __init isapnp_proc_init(void) } return 0; } - -#ifdef MODULE -int __exit isapnp_proc_done(void) -{ - struct pnp_dev *dev; - struct pnp_bus *card; - - isapnp_for_each_dev(dev) { - isapnp_proc_detach_device(dev); - } - isapnp_for_each_card(card) { - isapnp_proc_detach_bus(card); - } - if (isapnp_proc_bus_dir) - remove_proc_entry("isapnp", proc_bus); - return 0; -} -#endif /* MODULE */ diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c index 3bda513a6bd..0826287eef5 100644 --- a/drivers/pnp/manager.c +++ b/drivers/pnp/manager.c @@ -21,9 +21,6 @@ static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx) resource_size_t *start, *end; unsigned long *flags; - if (!dev || !rule) - return -EINVAL; - if (idx >= PNP_MAX_PORT) { pnp_err ("More than 4 ports is incompatible with pnp specifications."); @@ -66,9 +63,6 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx) resource_size_t *start, *end; unsigned long *flags; - if (!dev || !rule) - return -EINVAL; - if (idx >= PNP_MAX_MEM) { pnp_err ("More than 8 mems is incompatible with pnp specifications."); @@ -127,9 +121,6 @@ static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx) 5, 10, 11, 12, 9, 14, 15, 7, 3, 4, 13, 0, 1, 6, 8, 2 }; - if (!dev || !rule) - return -EINVAL; - if (idx >= PNP_MAX_IRQ) { pnp_err ("More than 2 irqs is incompatible with pnp specifications."); @@ -181,9 +172,6 @@ static int pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx) 1, 3, 5, 6, 7, 0, 2, 4 }; - if (!dev || !rule) - return -EINVAL; - if (idx >= PNP_MAX_DMA) { pnp_err ("More than 2 dmas is incompatible with pnp specifications."); @@ -390,7 +378,7 @@ static int pnp_assign_resources(struct pnp_dev *dev, int depnum) up(&pnp_res_mutex); return 1; - fail: +fail: pnp_clean_resource_table(&dev->res); up(&pnp_res_mutex); return 0; @@ -410,8 +398,6 @@ int pnp_manual_config_dev(struct pnp_dev *dev, struct pnp_resource_table *res, int i; struct pnp_resource_table *bak; - if (!dev || !res) - return -EINVAL; if (!pnp_can_configure(dev)) return -ENODEV; bak = pnp_alloc(sizeof(struct pnp_resource_table)); @@ -444,7 +430,7 @@ int pnp_manual_config_dev(struct pnp_dev *dev, struct pnp_resource_table *res, kfree(bak); return 0; - fail: +fail: dev->res = *bak; up(&pnp_res_mutex); kfree(bak); @@ -460,9 +446,6 @@ int pnp_auto_config_dev(struct pnp_dev *dev) struct pnp_option *dep; int i = 1; - if (!dev) - return -EINVAL; - if (!pnp_can_configure(dev)) { pnp_dbg("Device %s does not support resource configuration.", dev->dev.bus_id); @@ -541,8 +524,6 @@ int pnp_activate_dev(struct pnp_dev *dev) { int error; - if (!dev) - return -EINVAL; if (dev->active) return 0; /* the device is already active */ @@ -568,8 +549,6 @@ int pnp_disable_dev(struct pnp_dev *dev) { int error; - if (!dev) - return -EINVAL; if (!dev->active) return 0; /* the device is already disabled */ @@ -596,8 +575,6 @@ int pnp_disable_dev(struct pnp_dev *dev) void pnp_resource_change(struct resource *resource, resource_size_t start, resource_size_t size) { - if (resource == NULL) - return; resource->flags &= ~(IORESOURCE_AUTO | IORESOURCE_UNSET); resource->start = start; resource->end = start + size - 1; diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c index 616fc72190b..a5a372222d6 100644 --- a/drivers/pnp/pnpacpi/core.c +++ b/drivers/pnp/pnpacpi/core.c @@ -248,9 +248,9 @@ static int __init pnpacpi_add_device(struct acpi_device *device) num++; return AE_OK; - err1: +err1: kfree(dev_id); - err: +err: kfree(dev); return -EINVAL; } diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index ce5027feb3d..0e3b8d0ff06 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c @@ -34,19 +34,17 @@ */ static int irq_flags(int triggering, int polarity) { - int flag; if (triggering == ACPI_LEVEL_SENSITIVE) { if (polarity == ACPI_ACTIVE_LOW) - flag = IORESOURCE_IRQ_LOWLEVEL; + return IORESOURCE_IRQ_LOWLEVEL; else - flag = IORESOURCE_IRQ_HIGHLEVEL; + return IORESOURCE_IRQ_HIGHLEVEL; } else { if (polarity == ACPI_ACTIVE_LOW) - flag = IORESOURCE_IRQ_LOWEDGE; + return IORESOURCE_IRQ_LOWEDGE; else - flag = IORESOURCE_IRQ_HIGHEDGE; + return IORESOURCE_IRQ_HIGHEDGE; } - return flag; } static void decode_irq_flags(int flag, int *triggering, int *polarity) @@ -242,8 +240,7 @@ static void pnpacpi_parse_allocated_address_space(struct pnp_resource_table *res static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, void *data) { - struct pnp_resource_table *res_table = - (struct pnp_resource_table *)data; + struct pnp_resource_table *res_table = data; int i; switch (res->type) { @@ -566,8 +563,7 @@ static acpi_status pnpacpi_option_resource(struct acpi_resource *res, void *data) { int priority = 0; - struct acpipnp_parse_option_s *parse_data = - (struct acpipnp_parse_option_s *)data; + struct acpipnp_parse_option_s *parse_data = data; struct pnp_dev *dev = parse_data->dev; struct pnp_option *option = parse_data->option; @@ -705,7 +701,7 @@ static int pnpacpi_supported_resource(struct acpi_resource *res) static acpi_status pnpacpi_count_resources(struct acpi_resource *res, void *data) { - int *res_cnt = (int *)data; + int *res_cnt = data; if (pnpacpi_supported_resource(res)) (*res_cnt)++; @@ -714,7 +710,7 @@ static acpi_status pnpacpi_count_resources(struct acpi_resource *res, static acpi_status pnpacpi_type_resources(struct acpi_resource *res, void *data) { - struct acpi_resource **resource = (struct acpi_resource **)data; + struct acpi_resource **resource = data; if (pnpacpi_supported_resource(res)) { (*resource)->type = res->type; @@ -886,8 +882,7 @@ int pnpacpi_encode_resources(struct pnp_resource_table *res_table, int i = 0; /* pnpacpi_build_resource_template allocates extra mem */ int res_cnt = (buffer->length - 1) / sizeof(struct acpi_resource) - 1; - struct acpi_resource *resource = - (struct acpi_resource *)buffer->pointer; + struct acpi_resource *resource = buffer->pointer; int port = 0, irq = 0, dma = 0, mem = 0; pnp_dbg("res cnt %d", res_cnt); diff --git a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c index 3692a099b45..0691f473e9d 100644 --- a/drivers/pnp/pnpbios/core.c +++ b/drivers/pnp/pnpbios/core.c @@ -419,7 +419,6 @@ static void __init build_devlist(void) static int pnpbios_disabled; int pnpbios_dont_use_current_config; -#ifndef MODULE static int __init pnpbios_setup(char *str) { int invert; @@ -443,7 +442,6 @@ static int __init pnpbios_setup(char *str) } __setup("pnpbios=", pnpbios_setup); -#endif /* PnP BIOS signature: "$PnP" */ #define PNP_SIGNATURE (('$' << 0) + ('P' << 8) + ('n' << 16) + ('P' << 24)) @@ -591,6 +589,7 @@ subsys_initcall(pnpbios_init); static int __init pnpbios_thread_init(void) { struct task_struct *task; + #if defined(CONFIG_PPC_MERGE) if (check_legacy_ioport(PNPBIOS_BASE)) return 0; @@ -606,48 +605,7 @@ static int __init pnpbios_thread_init(void) return 0; } -#ifndef MODULE - -/* init/main.c calls pnpbios_init early */ - /* Start the kernel thread later: */ module_init(pnpbios_thread_init); -#else - -/* - * N.B.: Building pnpbios as a module hasn't been fully implemented - */ - -MODULE_LICENSE("GPL"); - -static int __init pnpbios_init_all(void) -{ - int r; - - r = pnpbios_init(); - if (r) - return r; - r = pnpbios_thread_init(); - if (r) - return r; - return 0; -} - -static void __exit pnpbios_exit(void) -{ -#ifdef CONFIG_HOTPLUG - unloading = 1; - wait_for_completion(&unload_sem); -#endif - pnpbios_proc_exit(); - /* We ought to free resources here */ - return; -} - -module_init(pnpbios_init_all); -module_exit(pnpbios_exit); - -#endif - EXPORT_SYMBOL(pnpbios_protocol); diff --git a/drivers/pnp/pnpbios/proc.c b/drivers/pnp/pnpbios/proc.c index 9c8c07701b6..9d9841f24a8 100644 --- a/drivers/pnp/pnpbios/proc.c +++ b/drivers/pnp/pnpbios/proc.c @@ -212,7 +212,7 @@ static int proc_write_node(struct file *file, const char __user * buf, goto out; } ret = count; - out: +out: kfree(node); return ret; } diff --git a/drivers/pnp/pnpbios/rsparser.c b/drivers/pnp/pnpbios/rsparser.c index 04ecd7b6723..3fabf11b002 100644 --- a/drivers/pnp/pnpbios/rsparser.c +++ b/drivers/pnp/pnpbios/rsparser.c @@ -238,7 +238,7 @@ static unsigned char *pnpbios_parse_allocated_resource_data(unsigned char *p, break; default: /* an unkown tag */ - len_err: +len_err: printk(KERN_ERR "PnPBIOS: Unknown tag '0x%x', length '%d'.\n", tag, len); @@ -298,6 +298,7 @@ static void pnpbios_parse_fixed_mem32_option(unsigned char *p, int size, struct pnp_option *option) { struct pnp_mem *mem; + mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL); if (!mem) return; @@ -468,7 +469,7 @@ static unsigned char *pnpbios_parse_resource_option_data(unsigned char *p, return p + 2; default: /* an unkown tag */ - len_err: +len_err: printk(KERN_ERR "PnPBIOS: Unknown tag '0x%x', length '%d'.\n", tag, len); @@ -562,7 +563,7 @@ static unsigned char *pnpbios_parse_compatible_ids(unsigned char *p, break; default: /* an unkown tag */ - len_err: +len_err: printk(KERN_ERR "PnPBIOS: Unknown tag '0x%x', length '%d'.\n", tag, len); @@ -756,7 +757,7 @@ static unsigned char *pnpbios_encode_allocated_resource_data(unsigned char *p, break; default: /* an unkown tag */ - len_err: +len_err: printk(KERN_ERR "PnPBIOS: Unknown tag '0x%x', length '%d'.\n", tag, len); diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c index ea6ec14a055..ef1286900db 100644 --- a/drivers/pnp/resource.c +++ b/drivers/pnp/resource.c @@ -47,9 +47,6 @@ struct pnp_option *pnp_register_independent_option(struct pnp_dev *dev) { struct pnp_option *option; - if (!dev) - return NULL; - option = pnp_build_option(PNP_RES_PRIORITY_PREFERRED); /* this should never happen but if it does we'll try to continue */ @@ -64,9 +61,6 @@ struct pnp_option *pnp_register_dependent_option(struct pnp_dev *dev, { struct pnp_option *option; - if (!dev) - return NULL; - option = pnp_build_option(priority); if (dev->dependent) { @@ -83,11 +77,6 @@ int pnp_register_irq_resource(struct pnp_option *option, struct pnp_irq *data) { struct pnp_irq *ptr; - if (!option) - return -EINVAL; - if (!data) - return -EINVAL; - ptr = option->irq; while (ptr && ptr->next) ptr = ptr->next; @@ -112,11 +101,6 @@ int pnp_register_dma_resource(struct pnp_option *option, struct pnp_dma *data) { struct pnp_dma *ptr; - if (!option) - return -EINVAL; - if (!data) - return -EINVAL; - ptr = option->dma; while (ptr && ptr->next) ptr = ptr->next; @@ -132,11 +116,6 @@ int pnp_register_port_resource(struct pnp_option *option, struct pnp_port *data) { struct pnp_port *ptr; - if (!option) - return -EINVAL; - if (!data) - return -EINVAL; - ptr = option->port; while (ptr && ptr->next) ptr = ptr->next; @@ -152,11 +131,6 @@ int pnp_register_mem_resource(struct pnp_option *option, struct pnp_mem *data) { struct pnp_mem *ptr; - if (!option) - return -EINVAL; - if (!data) - return -EINVAL; - ptr = option->mem; while (ptr && ptr->next) ptr = ptr->next; diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index 80c4a846306..1cb33cac123 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c @@ -892,7 +892,7 @@ static int m41t80_remove(struct i2c_client *client) static struct i2c_driver m41t80_driver = { .driver = { - .name = "m41t80", + .name = "rtc-m41t80", }, .probe = m41t80_probe, .remove = m41t80_remove, diff --git a/drivers/rtc/rtc-max6902.c b/drivers/rtc/rtc-max6902.c index d9417072807..3e183cfee10 100644 --- a/drivers/rtc/rtc-max6902.c +++ b/drivers/rtc/rtc-max6902.c @@ -13,7 +13,7 @@ * * 24-May-2006: Raphael Assenat <raph@8d.com> * - Major rework - * Converted to rtc_device and uses the SPI layer. + * Converted to rtc_device and uses the SPI layer. * * ??-???-2005: Someone at Compulab * - Initial driver creation. @@ -259,11 +259,11 @@ static int __devexit max6902_remove(struct spi_device *spi) static struct spi_driver max6902_driver = { .driver = { - .name = "max6902", + .name = "rtc-max6902", .bus = &spi_bus_type, .owner = THIS_MODULE, }, - .probe = max6902_probe, + .probe = max6902_probe, .remove = __devexit_p(max6902_remove), }; diff --git a/drivers/rtc/rtc-rs5c348.c b/drivers/rtc/rtc-rs5c348.c index f50f3fc353c..839462659af 100644 --- a/drivers/rtc/rtc-rs5c348.c +++ b/drivers/rtc/rtc-rs5c348.c @@ -226,7 +226,7 @@ static int __devexit rs5c348_remove(struct spi_device *spi) static struct spi_driver rs5c348_driver = { .driver = { - .name = "rs5c348", + .name = "rtc-rs5c348", .bus = &spi_bus_type, .owner = THIS_MODULE, }, diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c index eccac1c3b71..d32c60dbdd8 100644 --- a/drivers/s390/block/dasd_diag.c +++ b/drivers/s390/block/dasd_diag.c @@ -24,6 +24,7 @@ #include <asm/s390_ext.h> #include <asm/todclk.h> #include <asm/vtoc.h> +#include <asm/diag.h> #include "dasd_int.h" #include "dasd_diag.h" diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c index 4f2f81b16cf..2edd5fb6d3d 100644 --- a/drivers/s390/char/raw3270.c +++ b/drivers/s390/char/raw3270.c @@ -21,6 +21,7 @@ #include <asm/ccwdev.h> #include <asm/cio.h> #include <asm/ebcdic.h> +#include <asm/diag.h> #include "raw3270.h" diff --git a/drivers/s390/char/vmur.c b/drivers/s390/char/vmur.c index 04b19bdc09d..d70a6e65bf1 100644 --- a/drivers/s390/char/vmur.c +++ b/drivers/s390/char/vmur.c @@ -14,6 +14,7 @@ #include <asm/cio.h> #include <asm/ccwdev.h> #include <asm/debug.h> +#include <asm/diag.h> #include "vmur.h" @@ -68,8 +69,26 @@ static struct ccw_driver ur_driver = { .set_offline = ur_set_offline, }; +static DEFINE_MUTEX(vmur_mutex); + /* * Allocation, freeing, getting and putting of urdev structures + * + * Each ur device (urd) contains a reference to its corresponding ccw device + * (cdev) using the urd->cdev pointer. Each ccw device has a reference to the + * ur device using the cdev->dev.driver_data pointer. + * + * urd references: + * - ur_probe gets a urd reference, ur_remove drops the reference + * (cdev->dev.driver_data) + * - ur_open gets a urd reference, ur_relase drops the reference + * (urf->urd) + * + * cdev references: + * - urdev_alloc get a cdev reference (urd->cdev) + * - urdev_free drops the cdev reference (urd->cdev) + * + * Setting and clearing of cdev->dev.driver_data is protected by the ccwdev lock */ static struct urdev *urdev_alloc(struct ccw_device *cdev) { @@ -78,42 +97,61 @@ static struct urdev *urdev_alloc(struct ccw_device *cdev) urd = kzalloc(sizeof(struct urdev), GFP_KERNEL); if (!urd) return NULL; - urd->cdev = cdev; urd->reclen = cdev->id.driver_info; ccw_device_get_id(cdev, &urd->dev_id); mutex_init(&urd->io_mutex); mutex_init(&urd->open_mutex); + atomic_set(&urd->ref_count, 1); + urd->cdev = cdev; + get_device(&cdev->dev); return urd; } static void urdev_free(struct urdev *urd) { + TRACE("urdev_free: %p\n", urd); + if (urd->cdev) + put_device(&urd->cdev->dev); kfree(urd); } -/* - * This is how the character device driver gets a reference to a - * ur device. When this call returns successfully, a reference has - * been taken (by get_device) on the underlying kobject. The recipient - * of this urdev pointer must eventually drop it with urdev_put(urd) - * which does the corresponding put_device(). - */ +static void urdev_get(struct urdev *urd) +{ + atomic_inc(&urd->ref_count); +} + +static struct urdev *urdev_get_from_cdev(struct ccw_device *cdev) +{ + struct urdev *urd; + unsigned long flags; + + spin_lock_irqsave(get_ccwdev_lock(cdev), flags); + urd = cdev->dev.driver_data; + if (urd) + urdev_get(urd); + spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags); + return urd; +} + static struct urdev *urdev_get_from_devno(u16 devno) { char bus_id[16]; struct ccw_device *cdev; + struct urdev *urd; sprintf(bus_id, "0.0.%04x", devno); cdev = get_ccwdev_by_busid(&ur_driver, bus_id); if (!cdev) return NULL; - - return cdev->dev.driver_data; + urd = urdev_get_from_cdev(cdev); + put_device(&cdev->dev); + return urd; } static void urdev_put(struct urdev *urd) { - put_device(&urd->cdev->dev); + if (atomic_dec_and_test(&urd->ref_count)) + urdev_free(urd); } /* @@ -245,6 +283,7 @@ static void ur_int_handler(struct ccw_device *cdev, unsigned long intparm, return; } urd = cdev->dev.driver_data; + BUG_ON(!urd); /* On special conditions irb is an error pointer */ if (IS_ERR(irb)) urd->io_request_rc = PTR_ERR(irb); @@ -262,9 +301,15 @@ static void ur_int_handler(struct ccw_device *cdev, unsigned long intparm, static ssize_t ur_attr_reclen_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct urdev *urd = dev->driver_data; + struct urdev *urd; + int rc; - return sprintf(buf, "%zu\n", urd->reclen); + urd = urdev_get_from_cdev(to_ccwdev(dev)); + if (!urd) + return -ENODEV; + rc = sprintf(buf, "%zu\n", urd->reclen); + urdev_put(urd); + return rc; } static DEVICE_ATTR(reclen, 0444, ur_attr_reclen_show, NULL); @@ -379,31 +424,6 @@ static ssize_t ur_write(struct file *file, const char __user *udata, return do_write(urf->urd, udata, count, urf->dev_reclen, ppos); } -static int do_diag_14(unsigned long rx, unsigned long ry1, - unsigned long subcode) -{ - register unsigned long _ry1 asm("2") = ry1; - register unsigned long _ry2 asm("3") = subcode; - int rc = 0; - - asm volatile( -#ifdef CONFIG_64BIT - " sam31\n" - " diag %2,2,0x14\n" - " sam64\n" -#else - " diag %2,2,0x14\n" -#endif - " ipm %0\n" - " srl %0,28\n" - : "=d" (rc), "+d" (_ry2) - : "d" (rx), "d" (_ry1) - : "cc"); - - TRACE("diag 14: subcode=0x%lx, cc=%i\n", subcode, rc); - return rc; -} - /* * diagnose code 0x14 subcode 0x0028 - position spool file to designated * record @@ -415,7 +435,7 @@ static int diag_position_to_record(int devno, int record) { int cc; - cc = do_diag_14(record, devno, 0x28); + cc = diag14(record, devno, 0x28); switch (cc) { case 0: return 0; @@ -440,7 +460,7 @@ static int diag_read_file(int devno, char *buf) { int cc; - cc = do_diag_14((unsigned long) buf, devno, 0x00); + cc = diag14((unsigned long) buf, devno, 0x00); switch (cc) { case 0: return 0; @@ -533,7 +553,7 @@ static int diag_read_next_file_info(struct file_control_block *buf, int spid) { int cc; - cc = do_diag_14((unsigned long) buf, spid, 0xfff); + cc = diag14((unsigned long) buf, spid, 0xfff); switch (cc) { case 0: return 0; @@ -750,64 +770,63 @@ static struct file_operations ur_fops = { /* * ccw_device infrastructure: - * ur_probe gets its own ref to the device (i.e. get_device), - * creates the struct urdev, the device attributes, sets up - * the interrupt handler and validates the virtual unit record device. - * ur_remove removes the device attributes, frees the struct urdev - * and drops (put_device) the ref to the device we got in ur_probe. + * ur_probe creates the struct urdev (with refcount = 1), the device + * attributes, sets up the interrupt handler and validates the virtual + * unit record device. + * ur_remove removes the device attributes and drops the reference to + * struct urdev. + * + * ur_probe, ur_remove, ur_set_online and ur_set_offline are serialized + * by the vmur_mutex lock. + * + * urd->char_device is used as indication that the online function has + * been completed successfully. */ static int ur_probe(struct ccw_device *cdev) { struct urdev *urd; int rc; - TRACE("ur_probe: cdev=%p state=%d\n", cdev, *(int *) cdev->private); - - if (!get_device(&cdev->dev)) - return -ENODEV; + TRACE("ur_probe: cdev=%p\n", cdev); + mutex_lock(&vmur_mutex); urd = urdev_alloc(cdev); if (!urd) { rc = -ENOMEM; - goto fail; + goto fail_unlock; } + rc = ur_create_attributes(&cdev->dev); if (rc) { rc = -ENOMEM; - goto fail; + goto fail_urdev_put; } - cdev->dev.driver_data = urd; cdev->handler = ur_int_handler; /* validate virtual unit record device */ urd->class = get_urd_class(urd); if (urd->class < 0) { rc = urd->class; - goto fail; + goto fail_remove_attr; } if ((urd->class != DEV_CLASS_UR_I) && (urd->class != DEV_CLASS_UR_O)) { rc = -ENOTSUPP; - goto fail; + goto fail_remove_attr; } + spin_lock_irq(get_ccwdev_lock(cdev)); + cdev->dev.driver_data = urd; + spin_unlock_irq(get_ccwdev_lock(cdev)); + mutex_unlock(&vmur_mutex); return 0; -fail: - urdev_free(urd); - put_device(&cdev->dev); - return rc; -} - -static void ur_remove(struct ccw_device *cdev) -{ - struct urdev *urd = cdev->dev.driver_data; - - TRACE("ur_remove\n"); - if (cdev->online) - ur_set_offline(cdev); +fail_remove_attr: ur_remove_attributes(&cdev->dev); - urdev_free(urd); - put_device(&cdev->dev); +fail_urdev_put: + urdev_put(urd); +fail_unlock: + mutex_unlock(&vmur_mutex); + return rc; } static int ur_set_online(struct ccw_device *cdev) @@ -816,20 +835,29 @@ static int ur_set_online(struct ccw_device *cdev) int minor, major, rc; char node_id[16]; - TRACE("ur_set_online: cdev=%p state=%d\n", cdev, - *(int *) cdev->private); + TRACE("ur_set_online: cdev=%p\n", cdev); - if (!try_module_get(ur_driver.owner)) - return -EINVAL; + mutex_lock(&vmur_mutex); + urd = urdev_get_from_cdev(cdev); + if (!urd) { + /* ur_remove already deleted our urd */ + rc = -ENODEV; + goto fail_unlock; + } + + if (urd->char_device) { + /* Another ur_set_online was faster */ + rc = -EBUSY; + goto fail_urdev_put; + } - urd = (struct urdev *) cdev->dev.driver_data; minor = urd->dev_id.devno; major = MAJOR(ur_first_dev_maj_min); urd->char_device = cdev_alloc(); if (!urd->char_device) { rc = -ENOMEM; - goto fail_module_put; + goto fail_urdev_put; } cdev_init(urd->char_device, &ur_fops); @@ -858,29 +886,79 @@ static int ur_set_online(struct ccw_device *cdev) TRACE("ur_set_online: device_create rc=%d\n", rc); goto fail_free_cdev; } - + urdev_put(urd); + mutex_unlock(&vmur_mutex); return 0; fail_free_cdev: cdev_del(urd->char_device); -fail_module_put: - module_put(ur_driver.owner); - + urd->char_device = NULL; +fail_urdev_put: + urdev_put(urd); +fail_unlock: + mutex_unlock(&vmur_mutex); return rc; } -static int ur_set_offline(struct ccw_device *cdev) +static int ur_set_offline_force(struct ccw_device *cdev, int force) { struct urdev *urd; + int rc; - TRACE("ur_set_offline: cdev=%p cdev->private=%p state=%d\n", - cdev, cdev->private, *(int *) cdev->private); - urd = (struct urdev *) cdev->dev.driver_data; + TRACE("ur_set_offline: cdev=%p\n", cdev); + urd = urdev_get_from_cdev(cdev); + if (!urd) + /* ur_remove already deleted our urd */ + return -ENODEV; + if (!urd->char_device) { + /* Another ur_set_offline was faster */ + rc = -EBUSY; + goto fail_urdev_put; + } + if (!force && (atomic_read(&urd->ref_count) > 2)) { + /* There is still a user of urd (e.g. ur_open) */ + TRACE("ur_set_offline: BUSY\n"); + rc = -EBUSY; + goto fail_urdev_put; + } device_destroy(vmur_class, urd->char_device->dev); cdev_del(urd->char_device); - module_put(ur_driver.owner); + urd->char_device = NULL; + rc = 0; - return 0; +fail_urdev_put: + urdev_put(urd); + return rc; +} + +static int ur_set_offline(struct ccw_device *cdev) +{ + int rc; + + mutex_lock(&vmur_mutex); + rc = ur_set_offline_force(cdev, 0); + mutex_unlock(&vmur_mutex); + return rc; +} + +static void ur_remove(struct ccw_device *cdev) +{ + unsigned long flags; + + TRACE("ur_remove\n"); + + mutex_lock(&vmur_mutex); + + if (cdev->online) + ur_set_offline_force(cdev, 1); + ur_remove_attributes(&cdev->dev); + + spin_lock_irqsave(get_ccwdev_lock(cdev), flags); + urdev_put(cdev->dev.driver_data); + cdev->dev.driver_data = NULL; + spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags); + + mutex_unlock(&vmur_mutex); } /* diff --git a/drivers/s390/char/vmur.h b/drivers/s390/char/vmur.h index 2b3c564e047..fa959644735 100644 --- a/drivers/s390/char/vmur.h +++ b/drivers/s390/char/vmur.h @@ -70,6 +70,7 @@ struct urdev { size_t reclen; /* Record length for *write* CCWs */ int class; /* VM device class */ int io_request_rc; /* return code from I/O request */ + atomic_t ref_count; /* reference counter */ }; /* diff --git a/drivers/s390/cio/cmf.c b/drivers/s390/cio/cmf.c index 02fd00b55e1..34a796913b0 100644 --- a/drivers/s390/cio/cmf.c +++ b/drivers/s390/cio/cmf.c @@ -594,6 +594,9 @@ alloc_cmb (struct ccw_device *cdev) free_pages((unsigned long)mem, get_order(size)); } else if (!mem) { /* no luck */ + printk(KERN_WARNING "cio: failed to allocate area " + "for measuring %d subchannels\n", + cmb_area.num_channels); ret = -ENOMEM; goto out; } else { @@ -1279,13 +1282,6 @@ init_cmf(void) case CMF_BASIC: format_string = "basic"; cmbops = &cmbops_basic; - if (cmb_area.num_channels > 4096 || cmb_area.num_channels < 1) { - printk(KERN_ERR "cio: Basic channel measurement " - "facility can only use 1 to 4096 devices\n" - KERN_ERR "when the cmf driver is built" - " as a loadable module\n"); - return 1; - } break; case CMF_EXTENDED: format_string = "extended"; diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index 297659fa0e2..e44d92eac8e 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c @@ -117,7 +117,10 @@ static int ccw_uevent(struct device *dev, char **envp, int num_envp, snprint_alias(modalias_buf, sizeof(modalias_buf), id, ""); ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len, "MODALIAS=%s", modalias_buf); - return ret; + if (ret) + return ret; + envp[i] = NULL; + return 0; } struct bus_type ccw_bus_type; diff --git a/drivers/s390/cio/device_id.c b/drivers/s390/cio/device_id.c index 60b9347f7c9..f232832f2b2 100644 --- a/drivers/s390/cio/device_id.c +++ b/drivers/s390/cio/device_id.c @@ -17,6 +17,7 @@ #include <asm/delay.h> #include <asm/cio.h> #include <asm/lowcore.h> +#include <asm/diag.h> #include "cio.h" #include "cio_debug.h" @@ -25,51 +26,6 @@ #include "ioasm.h" /* - * diag210 is used under VM to get information about a virtual device - */ -int -diag210(struct diag210 * addr) -{ - /* - * diag 210 needs its data below the 2GB border, so we - * use a static data area to be sure - */ - static struct diag210 diag210_tmp; - static DEFINE_SPINLOCK(diag210_lock); - unsigned long flags; - int ccode; - - spin_lock_irqsave(&diag210_lock, flags); - diag210_tmp = *addr; - -#ifdef CONFIG_64BIT - asm volatile( - " lhi %0,-1\n" - " sam31\n" - " diag %1,0,0x210\n" - "0: ipm %0\n" - " srl %0,28\n" - "1: sam64\n" - EX_TABLE(0b,1b) - : "=&d" (ccode) : "a" (&diag210_tmp) : "cc", "memory"); -#else - asm volatile( - " lhi %0,-1\n" - " diag %1,0,0x210\n" - "0: ipm %0\n" - " srl %0,28\n" - "1:\n" - EX_TABLE(0b,1b) - : "=&d" (ccode) : "a" (&diag210_tmp) : "cc", "memory"); -#endif - - *addr = diag210_tmp; - spin_unlock_irqrestore(&diag210_lock, flags); - - return ccode; -} - -/* * Input : * devno - device number * ps - pointer to sense ID data area @@ -349,5 +305,3 @@ ccw_device_sense_id_irq(struct ccw_device *cdev, enum dev_event dev_event) break; } } - -EXPORT_SYMBOL(diag210); diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c index 03347aed2b3..d8d479876ec 100644 --- a/drivers/s390/cio/qdio.c +++ b/drivers/s390/cio/qdio.c @@ -195,6 +195,8 @@ qdio_do_eqbs(struct qdio_q *q, unsigned char *state, again: ccq = do_eqbs(irq->sch_token, state, q_no, start, cnt); rc = qdio_check_ccq(q, ccq); + if ((ccq == 96) && (tmp_cnt != *cnt)) + rc = 0; if (rc == 1) { QDIO_DBF_TEXT5(1,trace,"eqAGAIN"); goto again; @@ -740,7 +742,8 @@ qdio_get_outbound_buffer_frontier(struct qdio_q *q) first_not_to_check=f+qdio_min(atomic_read(&q->number_of_buffers_used), (QDIO_MAX_BUFFERS_PER_Q-1)); - if ((!q->is_iqdio_q)&&(!q->hydra_gives_outbound_pcis)) + if (((!q->is_iqdio_q) && (!q->hydra_gives_outbound_pcis)) || + (q->queue_type == QDIO_IQDIO_QFMT_ASYNCH)) SYNC_MEMORY; check_next: diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index d2b3898b750..6f2c71ef47e 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -367,6 +367,7 @@ config SCSI_3W_9XXX config SCSI_7000FASST tristate "7000FASST SCSI support" depends on ISA && SCSI && ISA_DMA_API + select CHECK_SIGNATURE help This driver supports the Western Digital 7000 SCSI host adapter family. Some information is in the source: @@ -388,6 +389,7 @@ config SCSI_AHA152X tristate "Adaptec AHA152X/2825 support" depends on ISA && SCSI && !64BIT select SCSI_SPI_ATTRS + select CHECK_SIGNATURE ---help--- This is a driver for the AHA-1510, AHA-1520, AHA-1522, and AHA-2825 SCSI host adapters. It also works for the AVA-1505, but the IRQ etc. @@ -583,6 +585,7 @@ config SCSI_DTC3280 tristate "DTC3180/3280 SCSI support" depends on ISA && SCSI select SCSI_SPI_ATTRS + select CHECK_SIGNATURE help This is support for DTC 3180/3280 SCSI Host Adapters. Please read the SCSI-HOWTO, available from @@ -657,6 +660,7 @@ config SCSI_EATA_PIO config SCSI_FUTURE_DOMAIN tristate "Future Domain 16xx SCSI/AHA-2920A support" depends on (ISA || PCI) && SCSI + select CHECK_SIGNATURE ---help--- This is support for Future Domain's 16-bit SCSI host adapters (TMC-1660/1680, TMC-1650/1670, TMC-3260, TMC-1610M/MER/MEX) and @@ -1324,6 +1328,7 @@ config SCSI_LPFC config SCSI_SEAGATE tristate "Seagate ST-02 and Future Domain TMC-8xx SCSI support" depends on X86 && ISA && SCSI + select CHECK_SIGNATURE ---help--- These are 8-bit SCSI controllers; the ST-01 is also supported by this driver. It is explained in section 3.9 of the SCSI-HOWTO, @@ -1397,6 +1402,7 @@ config SCSI_T128 tristate "Trantor T128/T128F/T228 SCSI support" depends on ISA && SCSI select SCSI_SPI_ATTRS + select CHECK_SIGNATURE ---help--- This is support for a SCSI host adapter. It is explained in section 3.11 of the SCSI-HOWTO, available from @@ -1561,7 +1567,7 @@ config A3000_SCSI built-in SCSI controller, say Y. Otherwise, say N. To compile this driver as a module, choose M here: the - module will be called wd33c93. + module will be called a3000. config A2091_SCSI tristate "A2091/A590 WD33C93A support" @@ -1571,7 +1577,7 @@ config A2091_SCSI say N. To compile this driver as a module, choose M here: the - module will be called wd33c93. + module will be called a2091. config GVP11_SCSI tristate "GVP Series II WD33C93A support" diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 301313002f6..f94109cbb46 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c @@ -129,7 +129,16 @@ struct uart_8250_port { unsigned char mcr; unsigned char mcr_mask; /* mask of user bits */ unsigned char mcr_force; /* mask of forced bits */ - unsigned char lsr_break_flag; + + /* + * Some bits in registers are cleared on a read, so they must + * be saved whenever the register is read but the bits will not + * be immediately processed. + */ +#define LSR_SAVE_FLAGS UART_LSR_BRK_ERROR_BITS + unsigned char lsr_saved_flags; +#define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA + unsigned char msr_saved_flags; /* * We provide a per-port pm hook. @@ -1238,6 +1247,7 @@ static void serial8250_start_tx(struct uart_port *port) if (up->bugs & UART_BUG_TXEN) { unsigned char lsr, iir; lsr = serial_in(up, UART_LSR); + up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; iir = serial_in(up, UART_IIR) & 0x0f; if ((up->port.type == PORT_RM9000) ? (lsr & UART_LSR_THRE && @@ -1290,18 +1300,10 @@ receive_chars(struct uart_8250_port *up, unsigned int *status) flag = TTY_NORMAL; up->port.icount.rx++; -#ifdef CONFIG_SERIAL_8250_CONSOLE - /* - * Recover the break flag from console xmit - */ - if (up->port.line == up->port.cons->index) { - lsr |= up->lsr_break_flag; - up->lsr_break_flag = 0; - } -#endif + lsr |= up->lsr_saved_flags; + up->lsr_saved_flags = 0; - if (unlikely(lsr & (UART_LSR_BI | UART_LSR_PE | - UART_LSR_FE | UART_LSR_OE))) { + if (unlikely(lsr & UART_LSR_BRK_ERROR_BITS)) { /* * For statistics only */ @@ -1392,6 +1394,8 @@ static unsigned int check_modem_status(struct uart_8250_port *up) { unsigned int status = serial_in(up, UART_MSR); + status |= up->msr_saved_flags; + up->msr_saved_flags = 0; if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI && up->port.info != NULL) { if (status & UART_MSR_TERI) @@ -1591,7 +1595,8 @@ static void serial8250_timeout(unsigned long data) static void serial8250_backup_timeout(unsigned long data) { struct uart_8250_port *up = (struct uart_8250_port *)data; - unsigned int iir, ier = 0; + unsigned int iir, ier = 0, lsr; + unsigned long flags; /* * Must disable interrupts or else we risk racing with the interrupt @@ -1610,9 +1615,13 @@ static void serial8250_backup_timeout(unsigned long data) * the "Diva" UART used on the management processor on many HP * ia64 and parisc boxes. */ + spin_lock_irqsave(&up->port.lock, flags); + lsr = serial_in(up, UART_LSR); + up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; + spin_unlock_irqrestore(&up->port.lock, flags); if ((iir & UART_IIR_NO_INT) && (up->ier & UART_IER_THRI) && (!uart_circ_empty(&up->port.info->xmit) || up->port.x_char) && - (serial_in(up, UART_LSR) & UART_LSR_THRE)) { + (lsr & UART_LSR_THRE)) { iir &= ~(UART_IIR_ID | UART_IIR_NO_INT); iir |= UART_IIR_THRI; } @@ -1631,13 +1640,14 @@ static unsigned int serial8250_tx_empty(struct uart_port *port) { struct uart_8250_port *up = (struct uart_8250_port *)port; unsigned long flags; - unsigned int ret; + unsigned int lsr; spin_lock_irqsave(&up->port.lock, flags); - ret = serial_in(up, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0; + lsr = serial_in(up, UART_LSR); + up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; spin_unlock_irqrestore(&up->port.lock, flags); - return ret; + return lsr & UART_LSR_TEMT ? TIOCSER_TEMT : 0; } static unsigned int serial8250_get_mctrl(struct uart_port *port) @@ -1708,8 +1718,7 @@ static inline void wait_for_xmitr(struct uart_8250_port *up, int bits) do { status = serial_in(up, UART_LSR); - if (status & UART_LSR_BI) - up->lsr_break_flag = UART_LSR_BI; + up->lsr_saved_flags |= status & LSR_SAVE_FLAGS; if (--tmout == 0) break; @@ -1718,8 +1727,12 @@ static inline void wait_for_xmitr(struct uart_8250_port *up, int bits) /* Wait up to 1s for flow control if necessary */ if (up->port.flags & UPF_CONS_FLOW) { - tmout = 1000000; - while (!(serial_in(up, UART_MSR) & UART_MSR_CTS) && --tmout) { + unsigned int tmout; + for (tmout = 1000000; tmout; tmout--) { + unsigned int msr = serial_in(up, UART_MSR); + up->msr_saved_flags |= msr & MSR_SAVE_FLAGS; + if (msr & UART_MSR_CTS) + break; udelay(1); touch_nmi_watchdog(); } @@ -1889,6 +1902,18 @@ static int serial8250_startup(struct uart_port *port) spin_unlock_irqrestore(&up->port.lock, flags); /* + * Clear the interrupt registers again for luck, and clear the + * saved flags to avoid getting false values from polling + * routines or the previous session. + */ + serial_inp(up, UART_LSR); + serial_inp(up, UART_RX); + serial_inp(up, UART_IIR); + serial_inp(up, UART_MSR); + up->lsr_saved_flags = 0; + up->msr_saved_flags = 0; + + /* * Finally, enable interrupts. Note: Modem status interrupts * are set via set_termios(), which will be occurring imminently * anyway, so we don't enable them here. @@ -1906,14 +1931,6 @@ static int serial8250_startup(struct uart_port *port) (void) inb_p(icp); } - /* - * And clear the interrupt registers again for luck. - */ - (void) serial_inp(up, UART_LSR); - (void) serial_inp(up, UART_RX); - (void) serial_inp(up, UART_IIR); - (void) serial_inp(up, UART_MSR); - return 0; } @@ -2484,6 +2501,16 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count) wait_for_xmitr(up, BOTH_EMPTY); serial_out(up, UART_IER, ier); + /* + * The receive handling will happen properly because the + * receive ready bit will still be set; it is not cleared + * on read. However, modem control will not, we must + * call it if we have saved something in the saved flags + * while processing with interrupts off. + */ + if (up->msr_saved_flags) + check_modem_status(up); + if (locked) spin_unlock(&up->port.lock); local_irq_restore(flags); diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c index 5e485876f54..bd66339f7a3 100644 --- a/drivers/serial/8250_pci.c +++ b/drivers/serial/8250_pci.c @@ -580,6 +580,138 @@ static int pci_netmos_init(struct pci_dev *dev) return num_serial; } +/* + * ITE support by Niels de Vos <niels.devos@wincor-nixdorf.com> + * + * These chips are available with optionally one parallel port and up to + * two serial ports. Unfortunately they all have the same product id. + * + * Basic configuration is done over a region of 32 I/O ports. The base + * ioport is called INTA or INTC, depending on docs/other drivers. + * + * The region of the 32 I/O ports is configured in POSIO0R... + */ + +/* registers */ +#define ITE_887x_MISCR 0x9c +#define ITE_887x_INTCBAR 0x78 +#define ITE_887x_UARTBAR 0x7c +#define ITE_887x_PS0BAR 0x10 +#define ITE_887x_POSIO0 0x60 + +/* I/O space size */ +#define ITE_887x_IOSIZE 32 +/* I/O space size (bits 26-24; 8 bytes = 011b) */ +#define ITE_887x_POSIO_IOSIZE_8 (3 << 24) +/* I/O space size (bits 26-24; 32 bytes = 101b) */ +#define ITE_887x_POSIO_IOSIZE_32 (5 << 24) +/* Decoding speed (1 = slow, 2 = medium, 3 = fast) */ +#define ITE_887x_POSIO_SPEED (3 << 29) +/* enable IO_Space bit */ +#define ITE_887x_POSIO_ENABLE (1 << 31) + +static int __devinit pci_ite887x_init(struct pci_dev *dev) +{ + /* inta_addr are the configuration addresses of the ITE */ + static const short inta_addr[] = { 0x2a0, 0x2c0, 0x220, 0x240, 0x1e0, + 0x200, 0x280, 0 }; + int ret, i, type; + struct resource *iobase = NULL; + u32 miscr, uartbar, ioport; + + /* search for the base-ioport */ + i = 0; + while (inta_addr[i] && iobase == NULL) { + iobase = request_region(inta_addr[i], ITE_887x_IOSIZE, + "ite887x"); + if (iobase != NULL) { + /* write POSIO0R - speed | size | ioport */ + pci_write_config_dword(dev, ITE_887x_POSIO0, + ITE_887x_POSIO_ENABLE | ITE_887x_POSIO_SPEED | + ITE_887x_POSIO_IOSIZE_32 | inta_addr[i]); + /* write INTCBAR - ioport */ + pci_write_config_dword(dev, ITE_887x_INTCBAR, inta_addr[i]); + ret = inb(inta_addr[i]); + if (ret != 0xff) { + /* ioport connected */ + break; + } + release_region(iobase->start, ITE_887x_IOSIZE); + iobase = NULL; + } + i++; + } + + if (!inta_addr[i]) { + printk(KERN_ERR "ite887x: could not find iobase\n"); + return -ENODEV; + } + + /* start of undocumented type checking (see parport_pc.c) */ + type = inb(iobase->start + 0x18) & 0x0f; + + switch (type) { + case 0x2: /* ITE8871 (1P) */ + case 0xa: /* ITE8875 (1P) */ + ret = 0; + break; + case 0xe: /* ITE8872 (2S1P) */ + ret = 2; + break; + case 0x6: /* ITE8873 (1S) */ + ret = 1; + break; + case 0x8: /* ITE8874 (2S) */ + ret = 2; + break; + default: + moan_device("Unknown ITE887x", dev); + ret = -ENODEV; + } + + /* configure all serial ports */ + for (i = 0; i < ret; i++) { + /* read the I/O port from the device */ + pci_read_config_dword(dev, ITE_887x_PS0BAR + (0x4 * (i + 1)), + &ioport); + ioport &= 0x0000FF00; /* the actual base address */ + pci_write_config_dword(dev, ITE_887x_POSIO0 + (0x4 * (i + 1)), + ITE_887x_POSIO_ENABLE | ITE_887x_POSIO_SPEED | + ITE_887x_POSIO_IOSIZE_8 | ioport); + + /* write the ioport to the UARTBAR */ + pci_read_config_dword(dev, ITE_887x_UARTBAR, &uartbar); + uartbar &= ~(0xffff << (16 * i)); /* clear half the reg */ + uartbar |= (ioport << (16 * i)); /* set the ioport */ + pci_write_config_dword(dev, ITE_887x_UARTBAR, uartbar); + + /* get current config */ + pci_read_config_dword(dev, ITE_887x_MISCR, &miscr); + /* disable interrupts (UARTx_Routing[3:0]) */ + miscr &= ~(0xf << (12 - 4 * i)); + /* activate the UART (UARTx_En) */ + miscr |= 1 << (23 - i); + /* write new config with activated UART */ + pci_write_config_dword(dev, ITE_887x_MISCR, miscr); + } + + if (ret <= 0) { + /* the device has no UARTs if we get here */ + release_region(iobase->start, ITE_887x_IOSIZE); + } + + return ret; +} + +static void __devexit pci_ite887x_exit(struct pci_dev *dev) +{ + u32 ioport; + /* the ioport is bit 0-15 in POSIO0R */ + pci_read_config_dword(dev, ITE_887x_POSIO0, &ioport); + ioport &= 0xffff; + release_region(ioport, ITE_887x_IOSIZE); +} + static int pci_default_setup(struct serial_private *priv, struct pciserial_board *board, struct uart_port *port, int idx) @@ -653,6 +785,18 @@ static struct pci_serial_quirk pci_serial_quirks[] = { .setup = pci_default_setup, }, /* + * ITE + */ + { + .vendor = PCI_VENDOR_ID_ITE, + .device = PCI_DEVICE_ID_ITE_8872, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .init = pci_ite887x_init, + .setup = pci_default_setup, + .exit = __devexit_p(pci_ite887x_exit), + }, + /* * Panacom */ { @@ -933,6 +1077,7 @@ enum pci_board_num_t { pbn_b1_2_1250000, + pbn_b1_bt_1_115200, pbn_b1_bt_2_921600, pbn_b1_1_1382400, @@ -983,6 +1128,7 @@ enum pci_board_num_t { pbn_exar_XR17C152, pbn_exar_XR17C154, pbn_exar_XR17C158, + pbn_pasemi_1682M, }; /* @@ -1211,6 +1357,13 @@ static struct pciserial_board pci_boards[] __devinitdata = { .uart_offset = 8, }, + [pbn_b1_bt_1_115200] = { + .flags = FL_BASE1|FL_BASE_BARS, + .num_ports = 1, + .base_baud = 115200, + .uart_offset = 8, + }, + [pbn_b1_bt_2_921600] = { .flags = FL_BASE1|FL_BASE_BARS, .num_ports = 2, @@ -1498,6 +1651,18 @@ static struct pciserial_board pci_boards[] __devinitdata = { .base_baud = 921600, .uart_offset = 0x200, }, + /* + * PA Semi PWRficient PA6T-1682M on-chip UART + */ + [pbn_pasemi_1682M] = { + .flags = FL_BASE0, + .num_ports = 1, + .base_baud = 8333333, + }, +}; + +static const struct pci_device_id softmodem_blacklist[] = { + { PCI_VDEVICE ( AL, 0x5457 ), }, /* ALi Corporation M5457 AC'97 Modem */ }; /* @@ -1508,6 +1673,7 @@ static struct pciserial_board pci_boards[] __devinitdata = { static int __devinit serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board) { + const struct pci_device_id *blacklist; int num_iomem, num_port, first_port = -1, i; /* @@ -1522,6 +1688,18 @@ serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board) (dev->class & 0xff) > 6) return -ENODEV; + /* + * Do not access blacklisted devices that are known not to + * feature serial ports. + */ + for (blacklist = softmodem_blacklist; + blacklist < softmodem_blacklist + ARRAY_SIZE(softmodem_blacklist); + blacklist++) { + if (dev->vendor == blacklist->vendor && + dev->device == blacklist->device) + return -ENODEV; + } + num_iomem = num_port = 0; for (i = 0; i < PCI_NUM_BAR_RESOURCES; i++) { if (pci_resource_flags(dev, i) & IORESOURCE_IO) { @@ -2364,6 +2542,13 @@ static struct pci_device_id serial_pci_tbl[] = { { PCI_VENDOR_ID_TOPIC, PCI_DEVICE_ID_TOPIC_TP560, PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_b0_1_115200 }, + /* + * ITE + */ + { PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_8872, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b1_bt_1_115200 }, /* * IntaShield IS-200 @@ -2382,6 +2567,13 @@ static struct pci_device_id serial_pci_tbl[] = { PCI_SUBVENDOR_ID_PERLE, PCI_SUBDEVICE_ID_PCI_RAS8, 0, 0, pbn_b2_8_921600 }, /* + * PA Semi PA6T-1682M on-chip UART + */ + { PCI_VENDOR_ID_PASEMI, 0xa004, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, + pbn_pasemi_1682M }, + + /* * These entries match devices with class COMMUNICATION_SERIAL, * COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL */ diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index 030a6063541..a055f58f342 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/serial/serial_core.c @@ -1146,11 +1146,14 @@ static void uart_set_termios(struct tty_struct *tty, struct ktermios *old_termio /* * These are the bits that are used to setup various - * flags in the low level driver. + * flags in the low level driver. We can ignore the Bfoo + * bits in c_cflag; c_[io]speed will always be set + * appropriately by set_termios() in tty_ioctl.c */ #define RELEVANT_IFLAG(iflag) ((iflag) & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) - if ((cflag ^ old_termios->c_cflag) == 0 && + tty->termios->c_ospeed == old_termios->c_ospeed && + tty->termios->c_ispeed == old_termios->c_ispeed && RELEVANT_IFLAG(tty->termios->c_iflag ^ old_termios->c_iflag) == 0) return; diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c index b8f91e018b2..0930e2a8551 100644 --- a/drivers/serial/serial_txx9.c +++ b/drivers/serial/serial_txx9.c @@ -37,7 +37,7 @@ #include <asm/io.h> -static char *serial_version = "1.09"; +static char *serial_version = "1.10"; static char *serial_name = "TX39/49 Serial driver"; #define PASS_LIMIT 256 @@ -436,8 +436,10 @@ static unsigned int serial_txx9_get_mctrl(struct uart_port *port) struct uart_txx9_port *up = (struct uart_txx9_port *)port; unsigned int ret; - ret = ((sio_in(up, TXX9_SIFLCR) & TXX9_SIFLCR_RTSSC) ? 0 : TIOCM_RTS) - | ((sio_in(up, TXX9_SICISR) & TXX9_SICISR_CTSS) ? 0 : TIOCM_CTS); + /* no modem control lines */ + ret = TIOCM_CAR | TIOCM_DSR; + ret |= (sio_in(up, TXX9_SIFLCR) & TXX9_SIFLCR_RTSSC) ? 0 : TIOCM_RTS; + ret |= (sio_in(up, TXX9_SICISR) & TXX9_SICISR_CTSS) ? 0 : TIOCM_CTS; return ret; } @@ -557,6 +559,12 @@ serial_txx9_set_termios(struct uart_port *port, struct ktermios *termios, unsigned long flags; unsigned int baud, quot; + /* + * We don't support modem control lines. + */ + termios->c_cflag &= ~(HUPCL | CMSPAR); + termios->c_cflag |= CLOCAL; + cval = sio_in(up, TXX9_SILCR); /* byte size and parity */ cval &= ~TXX9_SILCR_UMODE_MASK; diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c index 79b13685bdf..e074943feff 100644 --- a/drivers/serial/sunsu.c +++ b/drivers/serial/sunsu.c @@ -1198,10 +1198,11 @@ static int __init sunsu_kbd_ms_init(struct uart_sunsu_port *up) if (up->port.type == PORT_UNKNOWN) return -ENODEV; - printk("%s: %s port at %lx, irq %u\n", + printk("%s: %s port at %llx, irq %u\n", to_of_device(up->port.dev)->node->full_name, (up->su_type == SU_PORT_KBD) ? "Keyboard" : "Mouse", - up->port.mapbase, up->port.irq); + (unsigned long long) up->port.mapbase, + up->port.irq); #ifdef CONFIG_SERIO serio = &up->serio; diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c index 1d262c0c613..283bef0d24c 100644 --- a/drivers/serial/sunzilog.c +++ b/drivers/serial/sunzilog.c @@ -1431,14 +1431,16 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m return err; } } else { - printk(KERN_INFO "%s: Keyboard at MMIO 0x%lx (irq = %d) " + printk(KERN_INFO "%s: Keyboard at MMIO 0x%llx (irq = %d) " "is a %s\n", - op->dev.bus_id, up[0].port.mapbase, op->irqs[0], - sunzilog_type (&up[0].port)); - printk(KERN_INFO "%s: Mouse at MMIO 0x%lx (irq = %d) " + op->dev.bus_id, + (unsigned long long) up[0].port.mapbase, + op->irqs[0], sunzilog_type(&up[0].port)); + printk(KERN_INFO "%s: Mouse at MMIO 0x%llx (irq = %d) " "is a %s\n", - op->dev.bus_id, up[1].port.mapbase, op->irqs[0], - sunzilog_type (&up[1].port)); + op->dev.bus_id, + (unsigned long long) up[1].port.mapbase, + op->irqs[0], sunzilog_type(&up[1].port)); } dev_set_drvdata(&op->dev, &up[0]); diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index 7dd73546bf4..7580aa5da0f 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig @@ -6,6 +6,9 @@ menuconfig USB_SUPPORT bool "USB support" depends on HAS_IOMEM default y + ---help--- + This option adds core support for Universal Serial Bus (USB). + You will also need drivers from the following menu to make use of it. if USB_SUPPORT @@ -18,6 +21,7 @@ config USB_ARCH_HAS_HCD default y if USB_ARCH_HAS_EHCI default y if PCMCIA && !M32R # sl811_cs default y if ARM # SL-811 + default y if SUPERH # r8a66597-hcd default PCI # many non-PCI SOC chips embed OHCI diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c index 02c52f8d5db..a73e714288e 100644 --- a/drivers/usb/atm/cxacru.c +++ b/drivers/usb/atm/cxacru.c @@ -456,7 +456,6 @@ static int cxacru_start_wait_urb(struct urb *urb, struct completion *done, int* actual_length) { struct timer_list timer; - int status = urb->status; init_timer(&timer); timer.expires = jiffies + msecs_to_jiffies(CMD_TIMEOUT); @@ -468,7 +467,7 @@ static int cxacru_start_wait_urb(struct urb *urb, struct completion *done, if (actual_length) *actual_length = urb->actual_length; - return status; + return urb->status; /* must read status after completion */ } static int cxacru_cm(struct cxacru_data *instance, enum cxacru_cm_request cm, diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c index a1a1c9d467e..29807d048b0 100644 --- a/drivers/usb/atm/ueagle-atm.c +++ b/drivers/usb/atm/ueagle-atm.c @@ -1721,9 +1721,12 @@ static int uea_bind(struct usbatm_data *usbatm, struct usb_interface *intf, ret = uea_boot(sc); if (ret < 0) - goto error; + goto error_rm_grp; return 0; + +error_rm_grp: + sysfs_remove_group(&intf->dev.kobj, &attr_grp); error: kfree(sc); return ret; diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index fe940e0536e..f51e22490ed 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -921,6 +921,10 @@ skip_normal_probe: return -EINVAL; } } + + /* Accept probe requests only for the control interface */ + if (intf != control_interface) + return -ENODEV; if (usb_interface_claimed(data_interface)) { /* valid in this context */ dev_dbg(&intf->dev,"The data interface isn't available"); @@ -1109,10 +1113,12 @@ static void acm_disconnect(struct usb_interface *intf) return; } if (acm->country_codes){ - device_remove_file(&intf->dev, &dev_attr_wCountryCodes); - device_remove_file(&intf->dev, &dev_attr_iCountryCodeRelDate); + device_remove_file(&acm->control->dev, + &dev_attr_wCountryCodes); + device_remove_file(&acm->control->dev, + &dev_attr_iCountryCodeRelDate); } - device_remove_file(&intf->dev, &dev_attr_bmCapabilities); + device_remove_file(&acm->control->dev, &dev_attr_bmCapabilities); acm->dev = NULL; usb_set_intfdata(acm->control, NULL); usb_set_intfdata(acm->data, NULL); diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 654857493a8..a1ad11d0c47 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -1224,6 +1224,8 @@ static int usb_autopm_do_device(struct usb_device *udev, int inc_usage_cnt) udev->auto_pm = 1; udev->pm_usage_cnt += inc_usage_cnt; WARN_ON(udev->pm_usage_cnt < 0); + if (inc_usage_cnt) + udev->last_busy = jiffies; if (inc_usage_cnt >= 0 && udev->pm_usage_cnt > 0) { if (udev->state == USB_STATE_SUSPENDED) status = usb_resume_both(udev); @@ -1232,8 +1234,6 @@ static int usb_autopm_do_device(struct usb_device *udev, int inc_usage_cnt) else if (inc_usage_cnt) udev->last_busy = jiffies; } else if (inc_usage_cnt <= 0 && udev->pm_usage_cnt <= 0) { - if (inc_usage_cnt) - udev->last_busy = jiffies; status = usb_suspend_both(udev, PMSG_SUSPEND); } usb_pm_unlock(udev); @@ -1342,16 +1342,15 @@ static int usb_autopm_do_interface(struct usb_interface *intf, else { udev->auto_pm = 1; intf->pm_usage_cnt += inc_usage_cnt; + udev->last_busy = jiffies; if (inc_usage_cnt >= 0 && intf->pm_usage_cnt > 0) { if (udev->state == USB_STATE_SUSPENDED) status = usb_resume_both(udev); if (status != 0) intf->pm_usage_cnt -= inc_usage_cnt; - else if (inc_usage_cnt) + else udev->last_busy = jiffies; } else if (inc_usage_cnt <= 0 && intf->pm_usage_cnt <= 0) { - if (inc_usage_cnt) - udev->last_busy = jiffies; status = usb_suspend_both(udev, PMSG_SUSPEND); } } diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index e341a1da517..f7b337feb3e 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1644,9 +1644,10 @@ static int finish_port_resume(struct usb_device *udev) * and device drivers will know about any resume quirks. */ if (status == 0) { + devstatus = 0; status = usb_get_status(udev, USB_RECIP_DEVICE, 0, &devstatus); if (status >= 0) - status = (status == 2 ? 0 : -ENODEV); + status = (status > 0 ? 0 : -ENODEV); } if (status) { diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index b6bd05e3d43..d8f7b089a8f 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -637,12 +637,12 @@ int usb_get_descriptor(struct usb_device *dev, unsigned char type, unsigned char memset(buf,0,size); // Make sure we parse really received data for (i = 0; i < 3; ++i) { - /* retry on length 0 or stall; some devices are flakey */ + /* retry on length 0 or error; some devices are flakey */ result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, (type << 8) + index, 0, buf, size, USB_CTRL_GET_TIMEOUT); - if (result == 0 || result == -EPIPE) + if (result <= 0 && result != -ETIMEDOUT) continue; if (result > 1 && ((u8 *)buf)[1] != type) { result = -EPROTO; @@ -1358,6 +1358,30 @@ static int usb_if_uevent(struct device *dev, char **envp, int num_envp, usb_dev = interface_to_usbdev(intf); alt = intf->cur_altsetting; +#ifdef CONFIG_USB_DEVICEFS + if (add_uevent_var(envp, num_envp, &i, + buffer, buffer_size, &length, + "DEVICE=/proc/bus/usb/%03d/%03d", + usb_dev->bus->busnum, usb_dev->devnum)) + return -ENOMEM; +#endif + + if (add_uevent_var(envp, num_envp, &i, + buffer, buffer_size, &length, + "PRODUCT=%x/%x/%x", + le16_to_cpu(usb_dev->descriptor.idVendor), + le16_to_cpu(usb_dev->descriptor.idProduct), + le16_to_cpu(usb_dev->descriptor.bcdDevice))) + return -ENOMEM; + + if (add_uevent_var(envp, num_envp, &i, + buffer, buffer_size, &length, + "TYPE=%d/%d/%d", + usb_dev->descriptor.bDeviceClass, + usb_dev->descriptor.bDeviceSubClass, + usb_dev->descriptor.bDeviceProtocol)) + return -ENOMEM; + if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length, "INTERFACE=%d/%d/%d", diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index b7917c5a3c6..9e467118dc9 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -30,6 +30,8 @@ static const struct usb_device_id usb_quirk_list[] = { /* HP 5300/5370C scanner */ { USB_DEVICE(0x03f0, 0x0701), .driver_info = USB_QUIRK_STRING_FETCH_255 }, + /* Hewlett-Packard PhotoSmart 720 / PhotoSmart 935 (storage) */ + { USB_DEVICE(0x03f0, 0x4002), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, /* Acer Peripherals Inc. (now BenQ Corp.) Prisa 640BU */ { USB_DEVICE(0x04a5, 0x207e), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, /* Benq S2W 3300U */ @@ -56,6 +58,8 @@ static const struct usb_device_id usb_quirk_list[] = { { USB_DEVICE(0x04b8, 0x0121), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, /* Seiko Epson Corp.*/ { USB_DEVICE(0x04b8, 0x0122), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, + /* Samsung ML-2010 printer */ + { USB_DEVICE(0x04e8, 0x326c), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, /* Samsung ML-2510 Series printer */ { USB_DEVICE(0x04e8, 0x327e), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, /* Elsa MicroLink 56k (V.250) */ @@ -64,12 +68,20 @@ static const struct usb_device_id usb_quirk_list[] = { { USB_DEVICE(0x05d8, 0x4005), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, /* Agfa Snapscan1212u */ { USB_DEVICE(0x06bd, 0x2061), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, + /* Seagate RSS LLC */ + { USB_DEVICE(0x0bc2, 0x3000), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, /* Umax [hex] Astra 3400U */ { USB_DEVICE(0x1606, 0x0060), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, /* Philips PSC805 audio device */ { USB_DEVICE(0x0471, 0x0155), .driver_info = USB_QUIRK_RESET_RESUME }, + /* Alcor multi-card reader */ + { USB_DEVICE(0x058f, 0x6366), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, + + /* Canon EOS 5D in PC Connection mode */ + { USB_DEVICE(0x04a9, 0x3101), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, + /* RIM Blackberry */ { USB_DEVICE(0x0fca, 0x0001), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, { USB_DEVICE(0x0fca, 0x0004), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index f2fbdc7fe37..d008d1360a7 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -34,8 +34,6 @@ * bypassing some hardware (and driver) issues. UML could help too. */ -#define DEBUG - #include <linux/module.h> #include <linux/kernel.h> #include <linux/delay.h> diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index be7a1bd2823..965ad7bec7b 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c @@ -599,7 +599,6 @@ enum fsg_buffer_state { struct fsg_buffhd { void *buf; - dma_addr_t dma; enum fsg_buffer_state state; struct fsg_buffhd *next; @@ -1295,6 +1294,7 @@ static int class_setup_req(struct fsg_dev *fsg, struct usb_request *req = fsg->ep0req; int value = -EOPNOTSUPP; u16 w_index = le16_to_cpu(ctrl->wIndex); + u16 w_value = le16_to_cpu(ctrl->wValue); u16 w_length = le16_to_cpu(ctrl->wLength); if (!fsg->config) @@ -1308,7 +1308,7 @@ static int class_setup_req(struct fsg_dev *fsg, if (ctrl->bRequestType != (USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE)) break; - if (w_index != 0) { + if (w_index != 0 || w_value != 0) { value = -EDOM; break; } @@ -1324,7 +1324,7 @@ static int class_setup_req(struct fsg_dev *fsg, if (ctrl->bRequestType != (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE)) break; - if (w_index != 0) { + if (w_index != 0 || w_value != 0) { value = -EDOM; break; } @@ -1343,7 +1343,7 @@ static int class_setup_req(struct fsg_dev *fsg, if (ctrl->bRequestType != (USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE)) break; - if (w_index != 0) { + if (w_index != 0 || w_value != 0) { value = -EDOM; break; } @@ -2611,7 +2611,6 @@ static int send_status(struct fsg_dev *fsg) fsg->intr_buffhd = bh; // Point to the right buffhd fsg->intreq->buf = bh->inreq->buf; - fsg->intreq->dma = bh->inreq->dma; fsg->intreq->context = bh; start_transfer(fsg, fsg->intr_in, fsg->intreq, &fsg->intreq_busy, &bh->state); @@ -3200,7 +3199,6 @@ reset: if ((rc = alloc_request(fsg, fsg->bulk_out, &bh->outreq)) != 0) goto reset; bh->inreq->buf = bh->outreq->buf = bh->buf; - bh->inreq->dma = bh->outreq->dma = bh->dma; bh->inreq->context = bh->outreq->context = bh; bh->inreq->complete = bulk_in_complete; bh->outreq->complete = bulk_out_complete; diff --git a/drivers/usb/gadget/fsl_usb2_udc.c b/drivers/usb/gadget/fsl_usb2_udc.c index 10b2b33b869..d57bcfbc08a 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.c +++ b/drivers/usb/gadget/fsl_usb2_udc.c @@ -1277,31 +1277,32 @@ static void setup_received_irq(struct fsl_udc *udc, udc_reset_ep_queue(udc, 0); + /* We process some stardard setup requests here */ switch (setup->bRequest) { - /* Request that need Data+Status phase from udc */ case USB_REQ_GET_STATUS: - if ((setup->bRequestType & (USB_DIR_IN | USB_TYPE_STANDARD)) + /* Data+Status phase from udc */ + if ((setup->bRequestType & (USB_DIR_IN | USB_TYPE_MASK)) != (USB_DIR_IN | USB_TYPE_STANDARD)) break; ch9getstatus(udc, setup->bRequestType, wValue, wIndex, wLength); - break; + return; - /* Requests that need Status phase from udc */ case USB_REQ_SET_ADDRESS: + /* Status phase from udc */ if (setup->bRequestType != (USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE)) break; ch9setaddress(udc, wValue, wIndex, wLength); - break; + return; - /* Handled by udc, no data, status by udc */ case USB_REQ_CLEAR_FEATURE: case USB_REQ_SET_FEATURE: - { /* status transaction */ + /* Status phase from udc */ + { int rc = -EOPNOTSUPP; - if ((setup->bRequestType & USB_RECIP_MASK) - == USB_RECIP_ENDPOINT) { + if ((setup->bRequestType & (USB_RECIP_MASK | USB_TYPE_MASK)) + == (USB_RECIP_ENDPOINT | USB_TYPE_STANDARD)) { int pipe = get_pipe_by_windex(wIndex); struct fsl_ep *ep; @@ -1315,8 +1316,9 @@ static void setup_received_irq(struct fsl_udc *udc, ? 1 : 0); spin_lock(&udc->lock); - } else if ((setup->bRequestType & USB_RECIP_MASK) - == USB_RECIP_DEVICE) { + } else if ((setup->bRequestType & (USB_RECIP_MASK + | USB_TYPE_MASK)) == (USB_RECIP_DEVICE + | USB_TYPE_STANDARD)) { /* Note: The driver has not include OTG support yet. * This will be set when OTG support is added */ if (!udc->gadget.is_otg) @@ -1329,39 +1331,42 @@ static void setup_received_irq(struct fsl_udc *udc, USB_DEVICE_A_ALT_HNP_SUPPORT) udc->gadget.a_alt_hnp_support = 1; rc = 0; - } + } else + break; + if (rc == 0) { if (ep0_prime_status(udc, EP_DIR_IN)) ep0stall(udc); } - break; + return; } - /* Requests handled by gadget */ - default: - if (wLength) { - /* Data phase from gadget, status phase from udc */ - udc->ep0_dir = (setup->bRequestType & USB_DIR_IN) - ? USB_DIR_IN : USB_DIR_OUT; - spin_unlock(&udc->lock); - if (udc->driver->setup(&udc->gadget, - &udc->local_setup_buff) < 0) - ep0stall(udc); - spin_lock(&udc->lock); - udc->ep0_state = (setup->bRequestType & USB_DIR_IN) - ? DATA_STATE_XMIT : DATA_STATE_RECV; - } else { - /* No data phase, IN status from gadget */ - udc->ep0_dir = USB_DIR_IN; - spin_unlock(&udc->lock); - if (udc->driver->setup(&udc->gadget, - &udc->local_setup_buff) < 0) - ep0stall(udc); - spin_lock(&udc->lock); - udc->ep0_state = WAIT_FOR_OUT_STATUS; - } + default: break; } + + /* Requests handled by gadget */ + if (wLength) { + /* Data phase from gadget, status phase from udc */ + udc->ep0_dir = (setup->bRequestType & USB_DIR_IN) + ? USB_DIR_IN : USB_DIR_OUT; + spin_unlock(&udc->lock); + if (udc->driver->setup(&udc->gadget, + &udc->local_setup_buff) < 0) + ep0stall(udc); + spin_lock(&udc->lock); + udc->ep0_state = (setup->bRequestType & USB_DIR_IN) + ? DATA_STATE_XMIT : DATA_STATE_RECV; + } else { + /* No data phase, IN status from gadget */ + udc->ep0_dir = USB_DIR_IN; + spin_unlock(&udc->lock); + if (udc->driver->setup(&udc->gadget, + &udc->local_setup_buff) < 0) + ep0stall(udc); + spin_lock(&udc->lock); + udc->ep0_state = WAIT_FOR_OUT_STATUS; + } } /* Process request for Data or Status phase of ep0 diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c index 72b4ebbf132..1407ad1c812 100644 --- a/drivers/usb/gadget/pxa2xx_udc.c +++ b/drivers/usb/gadget/pxa2xx_udc.c @@ -967,7 +967,7 @@ static int pxa2xx_udc_pullup(struct usb_gadget *_gadget, int is_active) udc = container_of(_gadget, struct pxa2xx_udc, gadget); /* not all boards support pullup control */ - if (!udc->mach->udc_command) + if (!udc->mach->gpio_pullup && !udc->mach->udc_command) return -EOPNOTSUPP; is_active = (is_active != 0); @@ -2309,7 +2309,7 @@ static int pxa2xx_udc_suspend(struct platform_device *dev, pm_message_t state) { struct pxa2xx_udc *udc = platform_get_drvdata(dev); - if (!udc->mach->udc_command) + if (!udc->mach->gpio_pullup && !udc->mach->udc_command) WARN("USB host won't detect disconnect!\n"); pullup(udc, 0); diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 2f529828c74..565d6ef4c4c 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -237,7 +237,7 @@ config USB_SL811_CS module will be called "sl811_cs". config USB_R8A66597_HCD - tristate "R8A66597 HCD suppoort" + tristate "R8A66597 HCD support" depends on USB help The R8A66597 is a USB 2.0 host and peripheral controller. diff --git a/drivers/usb/host/ehci-au1xxx.c b/drivers/usb/host/ehci-au1xxx.c index 5d1b12aad77..b1d19268cb2 100644 --- a/drivers/usb/host/ehci-au1xxx.c +++ b/drivers/usb/host/ehci-au1xxx.c @@ -1,8 +1,6 @@ /* * EHCI HCD (Host Controller Driver) for USB. * - * (C) Copyright 2000-2004 David Brownell <dbrownell@users.sourceforge.net> - * * Bus Glue for AMD Alchemy Au1xxx * * Based on "ohci-au1xxx.c" by Matt Porter <mporter@kernel.crashing.org> @@ -196,6 +194,9 @@ static const struct hc_driver ehci_au1xxx_hc_driver = { /* * basic lifecycle operations + * + * FIXME -- ehci_init() doesn't do enough here. + * See ehci-ppc-soc for a complete implementation. */ .reset = ehci_init, .start = ehci_run, diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index c4e15ed1405..35cdba10411 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -275,58 +275,6 @@ static void ehci_work(struct ehci_hcd *ehci); /*-------------------------------------------------------------------------*/ -#ifdef CONFIG_CPU_FREQ - -#include <linux/cpufreq.h> - -static void ehci_cpufreq_pause (struct ehci_hcd *ehci) -{ - unsigned long flags; - - spin_lock_irqsave(&ehci->lock, flags); - if (!ehci->cpufreq_changing++) - qh_inactivate_split_intr_qhs(ehci); - spin_unlock_irqrestore(&ehci->lock, flags); -} - -static void ehci_cpufreq_unpause (struct ehci_hcd *ehci) -{ - unsigned long flags; - - spin_lock_irqsave(&ehci->lock, flags); - if (!--ehci->cpufreq_changing) - qh_reactivate_split_intr_qhs(ehci); - spin_unlock_irqrestore(&ehci->lock, flags); -} - -/* - * ehci_cpufreq_notifier is needed to avoid MMF errors that occur when - * EHCI controllers that don't cache many uframes get delayed trying to - * read main memory during CPU frequency transitions. This can cause - * split interrupt transactions to not be completed in the required uframe. - * This has been observed on the Broadcom/ServerWorks HT1000 controller. - */ -static int ehci_cpufreq_notifier(struct notifier_block *nb, unsigned long val, - void *data) -{ - struct ehci_hcd *ehci = container_of(nb, struct ehci_hcd, - cpufreq_transition); - - switch (val) { - case CPUFREQ_PRECHANGE: - ehci_cpufreq_pause(ehci); - break; - case CPUFREQ_POSTCHANGE: - ehci_cpufreq_unpause(ehci); - break; - } - return 0; -} - -#endif - -/*-------------------------------------------------------------------------*/ - static void ehci_watchdog (unsigned long param) { struct ehci_hcd *ehci = (struct ehci_hcd *) param; @@ -460,10 +408,6 @@ static void ehci_stop (struct usb_hcd *hcd) ehci_writel(ehci, 0, &ehci->regs->intr_enable); spin_unlock_irq(&ehci->lock); -#ifdef CONFIG_CPU_FREQ - cpufreq_unregister_notifier(&ehci->cpufreq_transition, - CPUFREQ_TRANSITION_NOTIFIER); -#endif /* let companion controllers work when we aren't */ ehci_writel(ehci, 0, &ehci->regs->configured_flag); @@ -569,17 +513,6 @@ static int ehci_init(struct usb_hcd *hcd) } ehci->command = temp; -#ifdef CONFIG_CPU_FREQ - INIT_LIST_HEAD(&ehci->split_intr_qhs); - /* - * If the EHCI controller caches enough uframes, this probably - * isn't needed unless there are so many low/full speed devices - * that the controller's can't cache it all. - */ - ehci->cpufreq_transition.notifier_call = ehci_cpufreq_notifier; - cpufreq_register_notifier(&ehci->cpufreq_transition, - CPUFREQ_TRANSITION_NOTIFIER); -#endif return 0; } diff --git a/drivers/usb/host/ehci-mem.c b/drivers/usb/host/ehci-mem.c index 8816d09903d..0431397836f 100644 --- a/drivers/usb/host/ehci-mem.c +++ b/drivers/usb/host/ehci-mem.c @@ -94,9 +94,6 @@ static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, gfp_t flags) qh->qh_dma = dma; // INIT_LIST_HEAD (&qh->qh_list); INIT_LIST_HEAD (&qh->qtd_list); -#ifdef CONFIG_CPU_FREQ - INIT_LIST_HEAD (&qh->split_intr_qhs); -#endif /* dummy td enables safe urb queuing */ qh->dummy = ehci_qtd_alloc (ehci, flags); diff --git a/drivers/usb/host/ehci-ppc-soc.c b/drivers/usb/host/ehci-ppc-soc.c index c2cedb09ed8..4f99b0eb27b 100644 --- a/drivers/usb/host/ehci-ppc-soc.c +++ b/drivers/usb/host/ehci-ppc-soc.c @@ -6,7 +6,7 @@ * Bus Glue for PPC On-Chip EHCI driver * Tested on AMCC 440EPx * - * Based on "ehci-au12xx.c" by David Brownell <dbrownell@users.sourceforge.net> + * Based on "ehci-au1xxx.c" by K.Boge <karsten.boge@amd.com> * * This file is licenced under the GPL. */ @@ -15,6 +15,24 @@ extern int usb_disabled(void); +/* called during probe() after chip reset completes */ +static int ehci_ppc_soc_setup(struct usb_hcd *hcd) +{ + struct ehci_hcd *ehci = hcd_to_ehci(hcd); + int retval; + + retval = ehci_halt(ehci); + if (retval) + return retval; + + retval = ehci_init(hcd); + if (retval) + return retval; + + ehci->sbrn = 0x20; + return ehci_reset(ehci); +} + /** * usb_ehci_ppc_soc_probe - initialize PPC-SoC-based HCDs * Context: !in_interrupt() @@ -120,7 +138,7 @@ static const struct hc_driver ehci_ppc_soc_hc_driver = { /* * basic lifecycle operations */ - .reset = ehci_init, + .reset = ehci_ppc_soc_setup, .start = ehci_run, .stop = ehci_stop, .shutdown = ehci_shutdown, diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 2284028f8aa..140bfa423e0 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -312,10 +312,6 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) struct urb *urb; u32 token = 0; - /* ignore QHs that are currently inactive */ - if (qh->hw_info1 & __constant_cpu_to_le32(QH_INACTIVATE)) - break; - qtd = list_entry (entry, struct ehci_qtd, qtd_list); urb = qtd->urb; diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index d4a8ace4967..e682f2342ef 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -479,109 +479,6 @@ static int disable_periodic (struct ehci_hcd *ehci) } /*-------------------------------------------------------------------------*/ -#ifdef CONFIG_CPU_FREQ - -static int safe_to_modify_i (struct ehci_hcd *ehci, struct ehci_qh *qh) -{ - int now; /* current (frame * 8) + uframe */ - int prev_start, next_start; /* uframes from/to split start */ - int start_uframe = ffs(le32_to_cpup (&qh->hw_info2) & QH_SMASK); - int end_uframe = fls((le32_to_cpup (&qh->hw_info2) & QH_CMASK) >> 8); - int split_duration = end_uframe - start_uframe; - - now = readl(&ehci->regs->frame_index) % (ehci->periodic_size << 3); - - next_start = ((1024 << 3) + (qh->start << 3) + start_uframe - now) - % (qh->period << 3); - prev_start = (qh->period << 3) - next_start; - - /* - * Make sure there will be at least one uframe when qh is safe. - */ - if ((qh->period << 3) <= (ehci->i_thresh + 2 + split_duration)) - /* never safe */ - return -EINVAL; - - /* - * Wait 1 uframe after transaction should have started, to make - * sure controller has time to write back overlay, so we can - * check QTD_STS_STS to see if transaction is in progress. - */ - if ((next_start > ehci->i_thresh) && (prev_start > 1)) - /* safe to set "i" bit if split isn't in progress */ - return (qh->hw_token & STATUS_BIT(ehci)) ? 0 : 1; - else - return 0; -} - -/* Set inactivate bit for all the split interrupt QHs. */ -static void qh_inactivate_split_intr_qhs (struct ehci_hcd *ehci) -{ - struct ehci_qh *qh; - int not_done, safe; - u32 inactivate = INACTIVATE_BIT(ehci); - u32 active = ACTIVE_BIT(ehci); - - do { - not_done = 0; - list_for_each_entry(qh, &ehci->split_intr_qhs, - split_intr_qhs) { - if (qh->hw_info1 & inactivate) - /* already off */ - continue; - /* - * To avoid setting "I" after the start split happens, - * don't set it if the QH might be cached in the - * controller. Some HCs (Broadcom/ServerWorks HT1000) - * will stop in the middle of a split transaction when - * the "I" bit is set. - */ - safe = safe_to_modify_i(ehci, qh); - if (safe == 0) { - not_done = 1; - } else if (safe > 0) { - qh->was_active = qh->hw_token & active; - qh->hw_info1 |= inactivate; - } - } - } while (not_done); - wmb(); -} - -static void qh_reactivate_split_intr_qhs (struct ehci_hcd *ehci) -{ - struct ehci_qh *qh; - u32 token; - int not_done, safe; - u32 inactivate = INACTIVATE_BIT(ehci); - u32 active = ACTIVE_BIT(ehci); - u32 halt = HALT_BIT(ehci); - - do { - not_done = 0; - list_for_each_entry(qh, &ehci->split_intr_qhs, split_intr_qhs) { - if (!(qh->hw_info1 & inactivate)) /* already on */ - continue; - /* - * Don't reactivate if cached, or controller might - * overwrite overlay after we modify it! - */ - safe = safe_to_modify_i(ehci, qh); - if (safe == 0) { - not_done = 1; - } else if (safe > 0) { - /* See EHCI 1.0 section 4.15.2.4. */ - token = qh->hw_token; - qh->hw_token = (token | halt) & ~active; - wmb(); - qh->hw_info1 &= ~inactivate; - wmb(); - qh->hw_token = (token & ~halt) | qh->was_active; - } - } - } while (not_done); -} -#endif /* periodic schedule slots have iso tds (normal or split) first, then a * sparse tree for active interrupt transfers. @@ -599,17 +496,6 @@ static int qh_link_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh) period, hc32_to_cpup(ehci, &qh->hw_info2) & (QH_CMASK | QH_SMASK), qh, qh->start, qh->usecs, qh->c_usecs); -#ifdef CONFIG_CPU_FREQ - /* - * If low/full speed interrupt QHs are inactive (because of - * cpufreq changing processor speeds), start QH with I flag set-- - * it will automatically be cleared when cpufreq is done. - */ - if (ehci->cpufreq_changing) - if (!(qh->hw_info1 & (cpu_to_le32(1 << 13)))) - qh->hw_info1 |= INACTIVATE_BIT(ehci); -#endif - /* high bandwidth, or otherwise every microframe */ if (period == 0) period = 1; @@ -658,12 +544,6 @@ static int qh_link_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh) ? ((qh->usecs + qh->c_usecs) / qh->period) : (qh->usecs * 8); -#ifdef CONFIG_CPU_FREQ - /* add qh to list of low/full speed interrupt QHs, if applicable */ - if (!(qh->hw_info1 & (cpu_to_le32(1 << 13)))) { - list_add(&qh->split_intr_qhs, &ehci->split_intr_qhs); - } -#endif /* maybe enable periodic schedule processing */ if (!ehci->periodic_sched++) return enable_periodic (ehci); @@ -683,13 +563,6 @@ static void qh_unlink_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh) // THEN // qh->hw_info1 |= __constant_cpu_to_hc32(1 << 7 /* "ignore" */); -#ifdef CONFIG_CPU_FREQ - /* remove qh from list of low/full speed interrupt QHs */ - if (!(qh->hw_info1 & (cpu_to_le32(1 << 13)))) { - list_del_init(&qh->split_intr_qhs); - } -#endif - /* high bandwidth, or otherwise part of every microframe */ if ((period = qh->period) == 0) period = 1; diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 2c68a04230c..951d69fec51 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -71,12 +71,6 @@ struct ehci_hcd { /* one per controller */ __u32 hcs_params; /* cached register copy */ spinlock_t lock; -#ifdef CONFIG_CPU_FREQ - struct notifier_block cpufreq_transition; - int cpufreq_changing; - struct list_head split_intr_qhs; -#endif - /* async schedule support */ struct ehci_qh *async; struct ehci_qh *reclaim; @@ -439,10 +433,6 @@ struct ehci_qh { __hc32 hw_next; /* see EHCI 3.6.1 */ __hc32 hw_info1; /* see EHCI 3.6.2 */ #define QH_HEAD 0x00008000 -#define QH_INACTIVATE 0x00000080 - -#define INACTIVATE_BIT(ehci) cpu_to_hc32(ehci, QH_INACTIVATE) - __hc32 hw_info2; /* see EHCI 3.6.2 */ #define QH_SMASK 0x000000ff #define QH_CMASK 0x0000ff00 @@ -492,10 +482,6 @@ struct ehci_qh { unsigned short start; /* where polling starts */ #define NO_FRAME ((unsigned short)~0) /* pick new start */ struct usb_device *dev; /* access to TT */ -#ifdef CONFIG_CPU_FREQ - struct list_head split_intr_qhs; /* list of split qhs */ - __le32 was_active; /* active bit before "i" set */ -#endif } __attribute__ ((aligned (32))); /*-------------------------------------------------------------------------*/ diff --git a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c index 6f9e43e9a6c..f61c6cdd06f 100644 --- a/drivers/usb/host/ohci-dbg.c +++ b/drivers/usb/host/ohci-dbg.c @@ -74,7 +74,7 @@ urb_print (struct urb * urb, char * str, int small) #define ohci_dbg_sw(ohci, next, size, format, arg...) \ do { \ - if (next) { \ + if (next != NULL) { \ unsigned s_len; \ s_len = scnprintf (*next, *size, format, ## arg ); \ *size -= s_len; *next += s_len; \ diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index d60f1985320..40a1de4c256 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c @@ -2208,8 +2208,6 @@ static int __init r8a66597_probe(struct platform_device *pdev) clean_up: if (reg) iounmap(reg); - if (res) - release_mem_region(res->start, 1); return ret; } diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c index 7f765ec038c..b88eb3c62c0 100644 --- a/drivers/usb/host/u132-hcd.c +++ b/drivers/usb/host/u132-hcd.c @@ -1520,12 +1520,15 @@ static void u132_hcd_endp_work_scheduler(struct work_struct *work) } } } +#ifdef CONFIG_PM static void port_power(struct u132 *u132, int pn, int is_on) { u132->port[pn].power = is_on; } +#endif + static void u132_power(struct u132 *u132, int is_on) { struct usb_hcd *hcd = u132_to_hcd(u132) diff --git a/drivers/usb/serial/airprime.c b/drivers/usb/serial/airprime.c index cff6fd190a2..77bb893bf2e 100644 --- a/drivers/usb/serial/airprime.c +++ b/drivers/usb/serial/airprime.c @@ -18,7 +18,6 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(0x0c88, 0x17da) }, /* Kyocera Wireless KPC650/Passport */ - { USB_DEVICE(0x413c, 0x8115) }, /* Dell Wireless HSDPA 5500 */ { }, }; MODULE_DEVICE_TABLE(usb, id_table); diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c index e67ce25f751..86724e88570 100644 --- a/drivers/usb/serial/belkin_sa.c +++ b/drivers/usb/serial/belkin_sa.c @@ -383,6 +383,10 @@ static void belkin_sa_set_termios (struct usb_serial_port *port, struct ktermios } baud = tty_get_baud_rate(port->tty); + if (baud == 0) { + dbg("%s - tty_get_baud_rate says 0 baud", __FUNCTION__); + return; + } urb_value = BELKIN_SA_BAUD(baud); /* Clip to maximum speed */ if (urb_value == 0) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 7b1673a4407..1370c423d7c 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -538,6 +538,8 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_TERATRONIK_VCP_PID) }, { USB_DEVICE(FTDI_VID, FTDI_TERATRONIK_D2XX_PID) }, { USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) }, + { USB_DEVICE(EVOLUTION_VID, EVO_HYBRID_PID) }, + { USB_DEVICE(EVOLUTION_VID, EVO_RCM4_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ARTEMIS_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16C_PID) }, diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index d9e49716db1..c70e1de6389 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h @@ -430,6 +430,9 @@ */ #define EVOLUTION_VID 0xDEEE /* Vendor ID */ #define EVOLUTION_ER1_PID 0x0300 /* ER1 Control Module */ +#define EVO_8U232AM_PID 0x02FF /* Evolution robotics RCM2 (FT232AM)*/ +#define EVO_HYBRID_PID 0x0302 /* Evolution robotics RCM4 PID (FT232BM)*/ +#define EVO_RCM4_PID 0x0303 /* Evolution robotics RCM4 PID */ /* Pyramid Computer GmbH */ #define FTDI_PYRAMID_PID 0xE6C8 /* Pyramid Appliance Display */ diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c index 04bd3b7a298..f1c90cfe725 100644 --- a/drivers/usb/serial/garmin_gps.c +++ b/drivers/usb/serial/garmin_gps.c @@ -1,7 +1,7 @@ /* * Garmin GPS driver * - * Copyright (C) 2006 Hermann Kneissel herkne@users.sourceforge.net + * Copyright (C) 2006,2007 Hermann Kneissel herkne@users.sourceforge.net * * The latest version of the driver can be found at * http://sourceforge.net/projects/garmin-gps/ @@ -34,6 +34,7 @@ #include <linux/module.h> #include <linux/spinlock.h> #include <asm/uaccess.h> +#include <asm/atomic.h> #include <linux/usb.h> #include <linux/usb/serial.h> @@ -52,7 +53,7 @@ static int debug = 0; */ #define VERSION_MAJOR 0 -#define VERSION_MINOR 28 +#define VERSION_MINOR 31 #define _STR(s) #s #define _DRIVER_VERSION(a,b) "v" _STR(a) "." _STR(b) @@ -141,6 +142,8 @@ struct garmin_data { __u8 inbuffer [GPS_IN_BUFSIZ]; /* tty -> usb */ __u8 outbuffer[GPS_OUT_BUFSIZ]; /* usb -> tty */ __u8 privpkt[4*6]; + atomic_t req_count; + atomic_t resp_count; spinlock_t lock; struct list_head pktlist; }; @@ -171,8 +174,6 @@ struct garmin_data { #define CLEAR_HALT_REQUIRED 0x0001 #define FLAGS_QUEUING 0x0100 -#define FLAGS_APP_RESP_SEEN 0x0200 -#define FLAGS_APP_REQ_SEEN 0x0400 #define FLAGS_DROP_DATA 0x0800 #define FLAGS_GSP_SKIP 0x1000 @@ -186,7 +187,8 @@ struct garmin_data { /* function prototypes */ static void gsp_next_packet(struct garmin_data * garmin_data_p); static int garmin_write_bulk(struct usb_serial_port *port, - const unsigned char *buf, int count); + const unsigned char *buf, int count, + int dismiss_ack); /* some special packets to be send or received */ static unsigned char const GARMIN_START_SESSION_REQ[] @@ -233,9 +235,7 @@ static struct usb_driver garmin_driver = { static inline int noResponseFromAppLayer(struct garmin_data * garmin_data_p) { - return ((garmin_data_p->flags - & (FLAGS_APP_REQ_SEEN|FLAGS_APP_RESP_SEEN)) - == FLAGS_APP_REQ_SEEN); + return atomic_read(&garmin_data_p->req_count) == atomic_read(&garmin_data_p->resp_count); } @@ -463,7 +463,7 @@ static int gsp_rec_packet(struct garmin_data * garmin_data_p, int count) usbdata[2] = __cpu_to_le32(size); garmin_write_bulk (garmin_data_p->port, garmin_data_p->inbuffer, - GARMIN_PKTHDR_LENGTH+size); + GARMIN_PKTHDR_LENGTH+size, 0); /* if this was an abort-transfer command, flush all queued data. */ @@ -818,7 +818,7 @@ static int nat_receive(struct garmin_data * garmin_data_p, if (garmin_data_p->insize >= len) { garmin_write_bulk (garmin_data_p->port, garmin_data_p->inbuffer, - len); + len, 0); garmin_data_p->insize = 0; /* if this was an abort-transfer command, @@ -893,10 +893,11 @@ static int garmin_clear(struct garmin_data * garmin_data_p) struct usb_serial_port *port = garmin_data_p->port; - if (port != NULL && garmin_data_p->flags & FLAGS_APP_RESP_SEEN) { + if (port != NULL && atomic_read(&garmin_data_p->resp_count)) { /* send a terminate command */ status = garmin_write_bulk(port, GARMIN_STOP_TRANSFER_REQ, - sizeof(GARMIN_STOP_TRANSFER_REQ)); + sizeof(GARMIN_STOP_TRANSFER_REQ), + 1); } /* flush all queued data */ @@ -939,7 +940,8 @@ static int garmin_init_session(struct usb_serial_port *port) dbg("%s - starting session ...", __FUNCTION__); garmin_data_p->state = STATE_ACTIVE; status = garmin_write_bulk(port, GARMIN_START_SESSION_REQ, - sizeof(GARMIN_START_SESSION_REQ)); + sizeof(GARMIN_START_SESSION_REQ), + 0); if (status >= 0) { @@ -950,7 +952,8 @@ static int garmin_init_session(struct usb_serial_port *port) /* not needed, but the win32 driver does it too ... */ status = garmin_write_bulk(port, GARMIN_START_SESSION_REQ2, - sizeof(GARMIN_START_SESSION_REQ2)); + sizeof(GARMIN_START_SESSION_REQ2), + 0); if (status >= 0) { status = 0; spin_lock_irqsave(&garmin_data_p->lock, flags); @@ -987,6 +990,8 @@ static int garmin_open (struct usb_serial_port *port, struct file *filp) garmin_data_p->mode = initial_mode; garmin_data_p->count = 0; garmin_data_p->flags = 0; + atomic_set(&garmin_data_p->req_count, 0); + atomic_set(&garmin_data_p->resp_count, 0); spin_unlock_irqrestore(&garmin_data_p->lock, flags); /* shutdown any bulk reads that might be going on */ @@ -1035,28 +1040,39 @@ static void garmin_write_bulk_callback (struct urb *urb) { unsigned long flags; struct usb_serial_port *port = (struct usb_serial_port *)urb->context; - struct garmin_data * garmin_data_p = usb_get_serial_port_data(port); int status = urb->status; - /* free up the transfer buffer, as usb_free_urb() does not do this */ - kfree (urb->transfer_buffer); + if (port) { + struct garmin_data * garmin_data_p = usb_get_serial_port_data(port); - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __FUNCTION__, port->number); - if (status) { - dbg("%s - nonzero write bulk status received: %d", - __FUNCTION__, status); - spin_lock_irqsave(&garmin_data_p->lock, flags); - garmin_data_p->flags |= CLEAR_HALT_REQUIRED; - spin_unlock_irqrestore(&garmin_data_p->lock, flags); + if (GARMIN_LAYERID_APPL == getLayerId(urb->transfer_buffer) + && (garmin_data_p->mode == MODE_GARMIN_SERIAL)) { + gsp_send_ack(garmin_data_p, ((__u8 *)urb->transfer_buffer)[4]); + } + + if (status) { + dbg("%s - nonzero write bulk status received: %d", + __FUNCTION__, urb->status); + spin_lock_irqsave(&garmin_data_p->lock, flags); + garmin_data_p->flags |= CLEAR_HALT_REQUIRED; + spin_unlock_irqrestore(&garmin_data_p->lock, flags); + } + + usb_serial_port_softint(port); } - usb_serial_port_softint(port); + /* Ignore errors that resulted from garmin_write_bulk with dismiss_ack=1 */ + + /* free up the transfer buffer, as usb_free_urb() does not do this */ + kfree (urb->transfer_buffer); } static int garmin_write_bulk (struct usb_serial_port *port, - const unsigned char *buf, int count) + const unsigned char *buf, int count, + int dismiss_ack) { unsigned long flags; struct usb_serial *serial = port->serial; @@ -1093,13 +1109,12 @@ static int garmin_write_bulk (struct usb_serial_port *port, usb_sndbulkpipe (serial->dev, port->bulk_out_endpointAddress), buffer, count, - garmin_write_bulk_callback, port); + garmin_write_bulk_callback, + dismiss_ack ? NULL : port); urb->transfer_flags |= URB_ZERO_PACKET; if (GARMIN_LAYERID_APPL == getLayerId(buffer)) { - spin_lock_irqsave(&garmin_data_p->lock, flags); - garmin_data_p->flags |= FLAGS_APP_REQ_SEEN; - spin_unlock_irqrestore(&garmin_data_p->lock, flags); + atomic_inc(&garmin_data_p->req_count); if (garmin_data_p->mode == MODE_GARMIN_SERIAL) { pkt_clear(garmin_data_p); garmin_data_p->state = STATE_GSP_WAIT_DATA; @@ -1114,13 +1129,6 @@ static int garmin_write_bulk (struct usb_serial_port *port, "failed with status = %d\n", __FUNCTION__, status); count = status; - } else { - - if (GARMIN_LAYERID_APPL == getLayerId(buffer) - && (garmin_data_p->mode == MODE_GARMIN_SERIAL)) { - - gsp_send_ack(garmin_data_p, buffer[4]); - } } /* we are done with this urb, so let the host driver @@ -1135,7 +1143,6 @@ static int garmin_write_bulk (struct usb_serial_port *port, static int garmin_write (struct usb_serial_port *port, const unsigned char *buf, int count) { - unsigned long flags; int pktid, pktsiz, len; struct garmin_data * garmin_data_p = usb_get_serial_port_data(port); __le32 *privpkt = (__le32 *)garmin_data_p->privpkt; @@ -1186,9 +1193,7 @@ static int garmin_write (struct usb_serial_port *port, break; case PRIV_PKTID_RESET_REQ: - spin_lock_irqsave(&garmin_data_p->lock, flags); - garmin_data_p->flags |= FLAGS_APP_REQ_SEEN; - spin_unlock_irqrestore(&garmin_data_p->lock, flags); + atomic_inc(&garmin_data_p->req_count); break; case PRIV_PKTID_SET_DEF_MODE: @@ -1241,8 +1246,6 @@ static int garmin_chars_in_buffer (struct usb_serial_port *port) static void garmin_read_process(struct garmin_data * garmin_data_p, unsigned char *data, unsigned data_length) { - unsigned long flags; - if (garmin_data_p->flags & FLAGS_DROP_DATA) { /* abort-transfer cmd is actice */ dbg("%s - pkt dropped", __FUNCTION__); @@ -1254,9 +1257,7 @@ static void garmin_read_process(struct garmin_data * garmin_data_p, the device */ if (0 == memcmp(data, GARMIN_APP_LAYER_REPLY, sizeof(GARMIN_APP_LAYER_REPLY))) { - spin_lock_irqsave(&garmin_data_p->lock, flags); - garmin_data_p->flags |= FLAGS_APP_RESP_SEEN; - spin_unlock_irqrestore(&garmin_data_p->lock, flags); + atomic_inc(&garmin_data_p->resp_count); } /* if throttling is active or postprecessing is required diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index 0455c1552ae..6a3a704b584 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c @@ -545,6 +545,7 @@ static struct usb_device_id ipaq_id_table [] = { { USB_DEVICE(0x413C, 0x4009) }, /* Dell Axim USB Sync */ { USB_DEVICE(0x4505, 0x0010) }, /* Smartphone */ { USB_DEVICE(0x5E04, 0xCE00) }, /* SAGEM Wireless Assistant */ + { USB_DEVICE(0x0BB4, 0x00CF) }, /* HTC smartphone modems */ { } /* Terminating entry */ }; diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 84c12b5f127..4cb3c165742 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -110,6 +110,7 @@ static int option_send_setup(struct usb_serial_port *port); #define HUAWEI_PRODUCT_E220 0x1003 #define NOVATELWIRELESS_VENDOR_ID 0x1410 +#define DELL_VENDOR_ID 0x413C #define ANYDATA_VENDOR_ID 0x16d5 #define ANYDATA_PRODUCT_ADU_E100A 0x6501 @@ -119,8 +120,6 @@ static int option_send_setup(struct usb_serial_port *port); #define BANDRICH_PRODUCT_C100_1 0x1002 #define BANDRICH_PRODUCT_C100_2 0x1003 -#define DELL_VENDOR_ID 0x413C - static struct usb_device_id option_ids[] = { { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, @@ -171,11 +170,16 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2110) }, /* Novatel Merlin ES620 / Merlin ES720 / Ovation U720 */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2130) }, /* Novatel Merlin ES620 SM Bus */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2410) }, /* Novatel EU740 */ + { USB_DEVICE(DELL_VENDOR_ID, 0x8114) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite EV620 CDMA/EV-DO */ + { USB_DEVICE(DELL_VENDOR_ID, 0x8115) }, /* Dell Wireless 5500 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */ + { USB_DEVICE(DELL_VENDOR_ID, 0x8116) }, /* Dell Wireless 5505 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */ + { USB_DEVICE(DELL_VENDOR_ID, 0x8117) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO ExpressCard == Novatel Merlin XV620 CDMA/EV-DO */ + { USB_DEVICE(DELL_VENDOR_ID, 0x8118) }, /* Dell Wireless 5510 Mobile Broadband HSDPA ExpressCard == Novatel Merlin XU870 HSDPA/3G */ + { USB_DEVICE(DELL_VENDOR_ID, 0x8128) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite E720 CDMA/EV-DO */ { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) }, { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) }, - { USB_DEVICE(DELL_VENDOR_ID, 0x8118) }, /* Dell Wireless 5510 Mobile Broadband HSDPA ExpressCard */ { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, option_ids); diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c index d7db71eca52..833ada47fc5 100644 --- a/drivers/usb/serial/oti6858.c +++ b/drivers/usb/serial/oti6858.c @@ -818,19 +818,17 @@ static int oti6858_ioctl(struct usb_serial_port *port, struct file *file, switch (cmd) { case TCGETS: - if (copy_to_user(user_arg, port->tty->termios, - sizeof(struct ktermios))) { + if (kernel_termios_to_user_termios((struct ktermios __user *)arg, + port->tty->termios)) return -EFAULT; - } return 0; case TCSETS: case TCSETSW: /* FIXME: this is not the same! */ case TCSETSF: /* FIXME: this is not the same! */ - if (copy_from_user(port->tty->termios, user_arg, - sizeof(struct ktermios))) { + if (user_termios_to_kernel_termios(port->tty->termios, + (struct ktermios __user *)arg)) return -EFAULT; - } oti6858_set_termios(port, NULL); return 0; diff --git a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c index 86899d55d8d..51669b7622b 100644 --- a/drivers/usb/serial/safe_serial.c +++ b/drivers/usb/serial/safe_serial.c @@ -74,13 +74,13 @@ #include <linux/usb/serial.h> -#ifndef CONFIG_USB_SAFE_PADDED -#define CONFIG_USB_SAFE_PADDED 0 +#ifndef CONFIG_USB_SERIAL_SAFE_PADDED +#define CONFIG_USB_SERIAL_SAFE_PADDED 0 #endif static int debug; static int safe = 1; -static int padded = CONFIG_USB_SAFE_PADDED; +static int padded = CONFIG_USB_SERIAL_SAFE_PADDED; #define DRIVER_VERSION "v0.0b" #define DRIVER_AUTHOR "sl@lineo.com, tbr@lineo.com" diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index 7d84a7647e8..30e08c0bcdc 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c @@ -104,6 +104,8 @@ static struct usb_device_id id_table [] = { .driver_info = (kernel_ulong_t)&palm_os_4_probe }, { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_TJ25_ID), .driver_info = (kernel_ulong_t)&palm_os_4_probe }, + { USB_DEVICE(ACER_VENDOR_ID, ACER_S10_ID), + .driver_info = (kernel_ulong_t)&palm_os_4_probe }, { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SCH_I330_ID), .driver_info = (kernel_ulong_t)&palm_os_4_probe }, { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SPH_I500_ID), diff --git a/drivers/usb/serial/visor.h b/drivers/usb/serial/visor.h index 4ce6f62a6f3..57229cf6647 100644 --- a/drivers/usb/serial/visor.h +++ b/drivers/usb/serial/visor.h @@ -48,6 +48,9 @@ #define SONY_CLIE_UX50_ID 0x0144 #define SONY_CLIE_TJ25_ID 0x0169 +#define ACER_VENDOR_ID 0x0502 +#define ACER_S10_ID 0x0001 + #define SAMSUNG_VENDOR_ID 0x04E8 #define SAMSUNG_SCH_I330_ID 0x8001 #define SAMSUNG_SPH_I500_ID 0x6601 diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index d8d008d4294..2d92ce31018 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -342,7 +342,7 @@ UNUSUAL_DEV( 0x04b0, 0x040d, 0x0100, 0x0100, US_FL_FIX_CAPACITY), /* Reported by Emil Larsson <emil@swip.net> */ -UNUSUAL_DEV( 0x04b0, 0x0411, 0x0100, 0x0100, +UNUSUAL_DEV( 0x04b0, 0x0411, 0x0100, 0x0101, "NIKON", "NIKON DSC D80", US_SC_DEVICE, US_PR_DEVICE, NULL, diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 28842d208bb..25e557d4fe6 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -112,13 +112,6 @@ module_param(delay_use, uint, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(delay_use, "seconds to delay before using a new device"); -/* These are used to make sure the module doesn't unload before all the - * threads have exited. - */ -static atomic_t total_threads = ATOMIC_INIT(0); -static DECLARE_COMPLETION(threads_gone); - - /* * The entries in this table correspond, line for line, * with the entries of us_unusual_dev_list[]. @@ -879,9 +872,6 @@ static void quiesce_and_remove_host(struct us_data *us) usb_stor_stop_transport(us); wake_up(&us->delay_wait); - /* It doesn't matter if the SCSI-scanning thread is still running. - * The thread will exit when it sees the DISCONNECTING flag. */ - /* queuecommand won't accept any new commands and the control * thread won't execute a previously-queued command. If there * is such a command pending, complete it with an error. */ @@ -891,12 +881,16 @@ static void quiesce_and_remove_host(struct us_data *us) scsi_lock(host); us->srb->scsi_done(us->srb); us->srb = NULL; + complete(&us->notify); /* in case of an abort */ scsi_unlock(host); } mutex_unlock(&us->dev_mutex); /* Now we own no commands so it's safe to remove the SCSI host */ scsi_remove_host(host); + + /* Wait for the SCSI-scanning thread to stop */ + wait_for_completion(&us->scanning_done); } /* Second stage of disconnect processing: deallocate all resources */ @@ -947,9 +941,8 @@ retry: /* Should we unbind if no devices were detected? */ } - scsi_host_put(us_to_host(us)); usb_autopm_put_interface(us->pusb_intf); - complete_and_exit(&threads_gone, 0); + complete_and_exit(&us->scanning_done, 0); } @@ -984,6 +977,7 @@ static int storage_probe(struct usb_interface *intf, init_MUTEX_LOCKED(&(us->sema)); init_completion(&(us->notify)); init_waitqueue_head(&us->delay_wait); + init_completion(&us->scanning_done); /* Associate the us_data structure with the USB device */ result = associate_dev(us, intf); @@ -1033,11 +1027,6 @@ static int storage_probe(struct usb_interface *intf, goto BadDevice; } - /* Take a reference to the host for the scanning thread and - * count it among all the threads we have launched. Then - * start it up. */ - scsi_host_get(us_to_host(us)); - atomic_inc(&total_threads); usb_autopm_get_interface(intf); /* dropped in the scanning thread */ wake_up_process(th); @@ -1104,16 +1093,6 @@ static void __exit usb_stor_exit(void) US_DEBUGP("-- calling usb_deregister()\n"); usb_deregister(&usb_storage_driver) ; - /* Don't return until all of our control and scanning threads - * have exited. Since each thread signals threads_gone as its - * last act, we have to call wait_for_completion the right number - * of times. - */ - while (atomic_read(&total_threads) > 0) { - wait_for_completion(&threads_gone); - atomic_dec(&total_threads); - } - usb_usual_clear_present(USB_US_TYPE_STOR); } diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h index 6445665b157..8d87503e256 100644 --- a/drivers/usb/storage/usb.h +++ b/drivers/usb/storage/usb.h @@ -150,6 +150,7 @@ struct us_data { struct semaphore sema; /* to sleep thread on */ struct completion notify; /* thread begin/end */ wait_queue_head_t delay_wait; /* wait during scan, reset */ + struct completion scanning_done; /* wait for scan thread */ /* subdriver information */ void *extra; /* Any extra data */ diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c index 80a81eccad3..832e4613673 100644 --- a/drivers/video/au1100fb.c +++ b/drivers/video/au1100fb.c @@ -115,6 +115,52 @@ static int nocursor = 0; module_param(nocursor, int, 0644); MODULE_PARM_DESC(nocursor, "cursor enable/disable"); +/* fb_blank + * Blank the screen. Depending on the mode, the screen will be + * activated with the backlight color, or desactivated + */ +static int au1100fb_fb_blank(int blank_mode, struct fb_info *fbi) +{ + struct au1100fb_device *fbdev = to_au1100fb_device(fbi); + + print_dbg("fb_blank %d %p", blank_mode, fbi); + + switch (blank_mode) { + + case VESA_NO_BLANKING: + /* Turn on panel */ + fbdev->regs->lcd_control |= LCD_CONTROL_GO; +#ifdef CONFIG_MIPS_PB1100 + if (drv_info.panel_idx == 1) { + au_writew(au_readw(PB1100_G_CONTROL) + | (PB1100_G_CONTROL_BL | PB1100_G_CONTROL_VDD), + PB1100_G_CONTROL); + } +#endif + au_sync(); + break; + + case VESA_VSYNC_SUSPEND: + case VESA_HSYNC_SUSPEND: + case VESA_POWERDOWN: + /* Turn off panel */ + fbdev->regs->lcd_control &= ~LCD_CONTROL_GO; +#ifdef CONFIG_MIPS_PB1100 + if (drv_info.panel_idx == 1) { + au_writew(au_readw(PB1100_G_CONTROL) + & ~(PB1100_G_CONTROL_BL | PB1100_G_CONTROL_VDD), + PB1100_G_CONTROL); + } +#endif + au_sync(); + break; + default: + break; + + } + return 0; +} + /* * Set hardware with var settings. This will enable the controller with a specific * mode, normally validated with the fb_check_var method @@ -272,52 +318,6 @@ int au1100fb_fb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned return 0; } -/* fb_blank - * Blank the screen. Depending on the mode, the screen will be - * activated with the backlight color, or desactivated - */ -int au1100fb_fb_blank(int blank_mode, struct fb_info *fbi) -{ - struct au1100fb_device *fbdev = to_au1100fb_device(fbi); - - print_dbg("fb_blank %d %p", blank_mode, fbi); - - switch (blank_mode) { - - case VESA_NO_BLANKING: - /* Turn on panel */ - fbdev->regs->lcd_control |= LCD_CONTROL_GO; -#ifdef CONFIG_MIPS_PB1100 - if (drv_info.panel_idx == 1) { - au_writew(au_readw(PB1100_G_CONTROL) - | (PB1100_G_CONTROL_BL | PB1100_G_CONTROL_VDD), - PB1100_G_CONTROL); - } -#endif - au_sync(); - break; - - case VESA_VSYNC_SUSPEND: - case VESA_HSYNC_SUSPEND: - case VESA_POWERDOWN: - /* Turn off panel */ - fbdev->regs->lcd_control &= ~LCD_CONTROL_GO; -#ifdef CONFIG_MIPS_PB1100 - if (drv_info.panel_idx == 1) { - au_writew(au_readw(PB1100_G_CONTROL) - & ~(PB1100_G_CONTROL_BL | PB1100_G_CONTROL_VDD), - PB1100_G_CONTROL); - } -#endif - au_sync(); - break; - default: - break; - - } - return 0; -} - /* fb_pan_display * Pan display in x and/or y as specified */ diff --git a/drivers/video/bw2.c b/drivers/video/bw2.c index 718b9f83736..833b10c8406 100644 --- a/drivers/video/bw2.c +++ b/drivers/video/bw2.c @@ -233,9 +233,9 @@ static u8 bw2regs_66hz[] __devinitdata = { 0x10, 0x20, 0 }; -static void __devinit bw2_do_default_mode(struct bw2_par *par, - struct fb_info *info, - int *linebytes) +static int __devinit bw2_do_default_mode(struct bw2_par *par, + struct fb_info *info, + int *linebytes) { u8 status, mon; u8 *p; @@ -266,17 +266,18 @@ static void __devinit bw2_do_default_mode(struct bw2_par *par, break; case BWTWO_SR_ID_NOCONN: - return; + return 0; default: - prom_printf("bw2: can't handle SR %02x\n", - status); - prom_halt(); + printk(KERN_ERR "bw2: can't handle SR %02x\n", + status); + return -EINVAL; } for ( ; *p; p += 2) { u8 __iomem *regp = &((u8 __iomem *)par->regs)[p[0]]; sbus_writeb(p[1], regp); } + return 0; } static int __devinit bw2_probe(struct of_device *op, const struct of_device_id *match) @@ -312,8 +313,11 @@ static int __devinit bw2_probe(struct of_device *op, const struct of_device_id * if (!par->regs) goto out_release_fb; - if (!of_find_property(dp, "width", NULL)) - bw2_do_default_mode(par, info, &linebytes); + if (!of_find_property(dp, "width", NULL)) { + err = bw2_do_default_mode(par, info, &linebytes); + if (err) + goto out_unmap_regs; + } par->fbsize = PAGE_ALIGN(linebytes * info->var.yres); diff --git a/drivers/video/cg3.c b/drivers/video/cg3.c index 5741b46ade1..a5c7fb33152 100644 --- a/drivers/video/cg3.c +++ b/drivers/video/cg3.c @@ -315,7 +315,7 @@ static u_char cg3_dacvals[] __devinitdata = { 4, 0xff, 5, 0x00, 6, 0x70, 7, 0x00, 0 }; -static void __devinit cg3_do_default_mode(struct cg3_par *par) +static int __devinit cg3_do_default_mode(struct cg3_par *par) { enum cg3_type type; u8 *p; @@ -332,10 +332,9 @@ static void __devinit cg3_do_default_mode(struct cg3_par *par) else type = CG3_AT_66HZ; } else { - prom_printf("cgthree: can't handle SR %02x\n", - status); - prom_halt(); - return; + printk(KERN_ERR "cgthree: can't handle SR %02x\n", + status); + return -EINVAL; } } @@ -351,6 +350,7 @@ static void __devinit cg3_do_default_mode(struct cg3_par *par) regp = (u8 __iomem *)&par->regs->cmap.control; sbus_writeb(p[1], regp); } + return 0; } static int __devinit cg3_probe(struct of_device *op, @@ -400,8 +400,11 @@ static int __devinit cg3_probe(struct of_device *op, cg3_blank(0, info); - if (!of_find_property(dp, "width", NULL)) - cg3_do_default_mode(par); + if (!of_find_property(dp, "width", NULL)) { + err = cg3_do_default_mode(par); + if (err) + goto out_unmap_screen; + } if (fb_alloc_cmap(&info->cmap, 256, 0)) goto out_unmap_screen; diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index 49643969f9f..5db6b1e489b 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig @@ -145,7 +145,7 @@ config FRAMEBUFFER_CONSOLE_ROTATION oriented. config STI_CONSOLE - tristate "STI text console" + bool "STI text console" depends on PARISC default y help diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c index 7fa1afeae8d..dda0586ab3f 100644 --- a/drivers/video/console/newport_con.c +++ b/drivers/video/console/newport_con.c @@ -738,9 +738,8 @@ const struct consw newport_con = { #ifdef MODULE static int __init newport_console_init(void) { - if (!sgi_gfxaddr) - return NULL; + return 0; if (!npregs) npregs = (struct newport_regs *)/* ioremap cannot fail */ diff --git a/drivers/video/console/sticore.c b/drivers/video/console/sticore.c index 870017d4497..e9ab657f0bb 100644 --- a/drivers/video/console/sticore.c +++ b/drivers/video/console/sticore.c @@ -232,18 +232,14 @@ sti_bmove(struct sti_struct *sti, int src_y, int src_x, } -/* FIXME: Do we have another solution for this ? */ -static void sti_flush(unsigned long from, unsigned long len) +static void sti_flush(unsigned long start, unsigned long end) { - flush_data_cache(); - flush_kernel_dcache_range(from, len); - flush_icache_range(from, from+len); + flush_icache_range(start, end); } void __devinit sti_rom_copy(unsigned long base, unsigned long count, void *dest) { - unsigned long dest_len = count; unsigned long dest_start = (unsigned long) dest; /* this still needs to be revisited (see arch/parisc/mm/init.c:246) ! */ @@ -260,7 +256,7 @@ sti_rom_copy(unsigned long base, unsigned long count, void *dest) dest++; } - sti_flush(dest_start, dest_len); + sti_flush(dest_start, (unsigned long)dest); } @@ -663,7 +659,6 @@ sti_bmode_font_raw(struct sti_cooked_font *f) static void __devinit sti_bmode_rom_copy(unsigned long base, unsigned long count, void *dest) { - unsigned long dest_len = count; unsigned long dest_start = (unsigned long) dest; while (count) { @@ -672,7 +667,8 @@ sti_bmode_rom_copy(unsigned long base, unsigned long count, void *dest) base += 4; dest++; } - sti_flush(dest_start, dest_len); + + sti_flush(dest_start, (unsigned long)dest); } static struct sti_rom * __devinit diff --git a/drivers/video/imsttfb.c b/drivers/video/imsttfb.c index 5715b8ad0dd..94f4511023d 100644 --- a/drivers/video/imsttfb.c +++ b/drivers/video/imsttfb.c @@ -1391,7 +1391,7 @@ init_imstt(struct fb_info *info) } } -#if USE_NV_MODES && defined(CONFIG_PPC) +#if USE_NV_MODES && defined(CONFIG_PPC32) { int vmode = init_vmode, cmode = init_cmode; diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index 81e571d59b5..a280a52f8ef 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c @@ -66,7 +66,7 @@ static void set_ctrlr_state(struct pxafb_info *fbi, u_int state); #ifdef CONFIG_FB_PXA_PARAMETERS #define PXAFB_OPTIONS_SIZE 256 -static char g_options[PXAFB_OPTIONS_SIZE] __initdata = ""; +static char g_options[PXAFB_OPTIONS_SIZE] __devinitdata = ""; #endif static inline void pxafb_schedule_work(struct pxafb_info *fbi, u_int state) diff --git a/drivers/w1/w1_int.c b/drivers/w1/w1_int.c index 2fbd8dd16df..6840dfebe4d 100644 --- a/drivers/w1/w1_int.c +++ b/drivers/w1/w1_int.c @@ -170,22 +170,24 @@ void __w1_remove_master_device(struct w1_master *dev) void w1_remove_master_device(struct w1_bus_master *bm) { - struct w1_master *dev = NULL; + struct w1_master *dev, *found = NULL; list_for_each_entry(dev, &w1_masters, w1_master_entry) { if (!dev->initialized) continue; - if (dev->bus_master->data == bm->data) + if (dev->bus_master->data == bm->data) { + found = dev; break; + } } - if (!dev) { + if (!found) { printk(KERN_ERR "Device doesn't exist.\n"); return; } - __w1_remove_master_device(dev); + __w1_remove_master_device(found); } EXPORT_SYMBOL(w1_add_master_device); diff --git a/drivers/zorro/zorro-sysfs.c b/drivers/zorro/zorro-sysfs.c index 9130f1c12c2..808b4f8675c 100644 --- a/drivers/zorro/zorro-sysfs.c +++ b/drivers/zorro/zorro-sysfs.c @@ -78,7 +78,7 @@ static ssize_t zorro_read_config(struct kobject *kobj, static struct bin_attribute zorro_config_attr = { .attr = { .name = "config", - .mode = S_IRUGO | S_IWUSR, + .mode = S_IRUGO, }, .size = sizeof(struct ConfigDev), .read = zorro_read_config, |