diff --git a/[refs] b/[refs] index 626d19a056b3..0d91347542ca 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: dd8856bda5f1308beb113281b248683992998a9e +refs/heads/master: 9d4436a6fbc8c5eccdfcb8f5884e0a7b4a57f6d2 diff --git a/trunk/Documentation/kernel-parameters.txt b/trunk/Documentation/kernel-parameters.txt index 2e1898e4e8fd..15e4fed127f6 100644 --- a/trunk/Documentation/kernel-parameters.txt +++ b/trunk/Documentation/kernel-parameters.txt @@ -1416,11 +1416,6 @@ and is between 256 and 4096 characters. It is defined in the file scsi_logging= [SCSI] - scsi_mod.scan= [SCSI] sync (default) scans SCSI busses as they are - discovered. async scans them in kernel threads, - allowing boot to proceed. none ignores them, expecting - user space to do the scan. - selinux [SELINUX] Disable or enable SELinux at boot time. Format: { "0" | "1" } See security/selinux/Kconfig help text. diff --git a/trunk/Documentation/scsi/scsi_mid_low_api.txt b/trunk/Documentation/scsi/scsi_mid_low_api.txt index 6f70f2b9327e..75a535a975c3 100644 --- a/trunk/Documentation/scsi/scsi_mid_low_api.txt +++ b/trunk/Documentation/scsi/scsi_mid_low_api.txt @@ -375,6 +375,7 @@ Summary: scsi_add_device - creates new scsi device (lu) instance scsi_add_host - perform sysfs registration and set up transport class scsi_adjust_queue_depth - change the queue depth on a SCSI device + scsi_assign_lock - replace default host_lock with given lock scsi_bios_ptable - return copy of block device's partition table scsi_block_requests - prevent further commands being queued to given host scsi_deactivate_tcq - turn off tag command queueing @@ -487,6 +488,20 @@ void scsi_adjust_queue_depth(struct scsi_device * sdev, int tagged, int tags) +/** + * scsi_assign_lock - replace default host_lock with given lock + * @shost: a pointer to a scsi host instance + * @lock: pointer to lock to replace host_lock for this host + * + * Returns nothing + * + * Might block: no + * + * Defined in: include/scsi/scsi_host.h . + **/ +void scsi_assign_lock(struct Scsi_Host *shost, spinlock_t *lock) + + /** * scsi_bios_ptable - return copy of block device's partition table * @dev: pointer to block device @@ -1351,11 +1366,17 @@ Locks Each struct Scsi_Host instance has a spin_lock called struct Scsi_Host::default_lock which is initialized in scsi_host_alloc() [found in hosts.c]. Within the same function the struct Scsi_Host::host_lock pointer -is initialized to point at default_lock. Thereafter lock and unlock -operations performed by the mid level use the struct Scsi_Host::host_lock -pointer. Previously drivers could override the host_lock pointer but -this is not allowed anymore. - +is initialized to point at default_lock with the scsi_assign_lock() function. +Thereafter lock and unlock operations performed by the mid level use the +struct Scsi_Host::host_lock pointer. + +LLDs can override the use of struct Scsi_Host::default_lock by +using scsi_assign_lock(). The earliest opportunity to do this would +be in the detect() function after it has invoked scsi_register(). It +could be replaced by a coarser grain lock (e.g. per driver) or a +lock of equal granularity (i.e. per host). Using finer grain locks +(e.g. per SCSI device) may be possible by juggling locks in +queuecommand(). Autosense ========= diff --git a/trunk/arch/arm/common/sharpsl_pm.c b/trunk/arch/arm/common/sharpsl_pm.c index b3599743093b..605dedf96790 100644 --- a/trunk/arch/arm/common/sharpsl_pm.c +++ b/trunk/arch/arm/common/sharpsl_pm.c @@ -60,16 +60,16 @@ static int sharpsl_ac_check(void); static int sharpsl_fatal_check(void); static int sharpsl_average_value(int ad); static void sharpsl_average_clear(void); -static void sharpsl_charge_toggle(struct work_struct *private_); -static void sharpsl_battery_thread(struct work_struct *private_); +static void sharpsl_charge_toggle(void *private_); +static void sharpsl_battery_thread(void *private_); /* * Variables */ struct sharpsl_pm_status sharpsl_pm; -DECLARE_DELAYED_WORK(toggle_charger, sharpsl_charge_toggle); -DECLARE_DELAYED_WORK(sharpsl_bat, sharpsl_battery_thread); +DECLARE_WORK(toggle_charger, sharpsl_charge_toggle, NULL); +DECLARE_WORK(sharpsl_bat, sharpsl_battery_thread, NULL); DEFINE_LED_TRIGGER(sharpsl_charge_led_trigger); @@ -116,7 +116,7 @@ void sharpsl_battery_kick(void) EXPORT_SYMBOL(sharpsl_battery_kick); -static void sharpsl_battery_thread(struct work_struct *private_) +static void sharpsl_battery_thread(void *private_) { int voltage, percent, apm_status, i = 0; @@ -128,7 +128,7 @@ static void sharpsl_battery_thread(struct work_struct *private_) /* Corgi cannot confirm when battery fully charged so periodically kick! */ if (!sharpsl_pm.machinfo->batfull_irq && (sharpsl_pm.charge_mode == CHRG_ON) && time_after(jiffies, sharpsl_pm.charge_start_time + SHARPSL_CHARGE_ON_TIME_INTERVAL)) - schedule_delayed_work(&toggle_charger, 0); + schedule_work(&toggle_charger); while(1) { voltage = sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_VOLT); @@ -212,7 +212,7 @@ static void sharpsl_charge_off(void) sharpsl_pm_led(SHARPSL_LED_OFF); sharpsl_pm.charge_mode = CHRG_OFF; - schedule_delayed_work(&sharpsl_bat, 0); + schedule_work(&sharpsl_bat); } static void sharpsl_charge_error(void) @@ -222,7 +222,7 @@ static void sharpsl_charge_error(void) sharpsl_pm.charge_mode = CHRG_ERROR; } -static void sharpsl_charge_toggle(struct work_struct *private_) +static void sharpsl_charge_toggle(void *private_) { dev_dbg(sharpsl_pm.dev, "Toogling Charger at time: %lx\n", jiffies); @@ -254,7 +254,7 @@ static void sharpsl_ac_timer(unsigned long data) else if (sharpsl_pm.charge_mode == CHRG_ON) sharpsl_charge_off(); - schedule_delayed_work(&sharpsl_bat, 0); + schedule_work(&sharpsl_bat); } @@ -279,10 +279,10 @@ static void sharpsl_chrg_full_timer(unsigned long data) sharpsl_charge_off(); } else if (sharpsl_pm.full_count < 2) { dev_dbg(sharpsl_pm.dev, "Charge Full: Count too low\n"); - schedule_delayed_work(&toggle_charger, 0); + schedule_work(&toggle_charger); } else if (time_after(jiffies, sharpsl_pm.charge_start_time + SHARPSL_CHARGE_FINISH_TIME)) { dev_dbg(sharpsl_pm.dev, "Charge Full: Interrupt generated too slowly - retry.\n"); - schedule_delayed_work(&toggle_charger, 0); + schedule_work(&toggle_charger); } else { sharpsl_charge_off(); sharpsl_pm.charge_mode = CHRG_DONE; diff --git a/trunk/arch/arm/mach-omap1/board-h3.c b/trunk/arch/arm/mach-omap1/board-h3.c index 9d2346fb68f4..f225a083dee1 100644 --- a/trunk/arch/arm/mach-omap1/board-h3.c +++ b/trunk/arch/arm/mach-omap1/board-h3.c @@ -323,8 +323,7 @@ static int h3_transceiver_mode(struct device *dev, int mode) cancel_delayed_work(&irda_config->gpio_expa); PREPARE_WORK(&irda_config->gpio_expa, set_trans_mode, &mode); -#error this is not permitted - mode is an argument variable - schedule_delayed_work(&irda_config->gpio_expa, 0); + schedule_work(&irda_config->gpio_expa); return 0; } diff --git a/trunk/arch/arm/mach-omap1/board-nokia770.c b/trunk/arch/arm/mach-omap1/board-nokia770.c index cbe909bad79b..dbc555d209ff 100644 --- a/trunk/arch/arm/mach-omap1/board-nokia770.c +++ b/trunk/arch/arm/mach-omap1/board-nokia770.c @@ -74,7 +74,7 @@ static struct omap_kp_platform_data nokia770_kp_data = { .rows = 8, .cols = 8, .keymap = nokia770_keymap, - .keymapsize = ARRAY_SIZE(nokia770_keymap), + .keymapsize = ARRAY_SIZE(nokia770_keymap) .delay = 4, }; @@ -191,7 +191,7 @@ static void nokia770_audio_pwr_up(void) printk("HP connected\n"); } -static void codec_delayed_power_down(struct work_struct *work) +static void codec_delayed_power_down(void *arg) { down(&audio_pwr_sem); if (audio_pwr_state == -1) @@ -200,7 +200,7 @@ static void codec_delayed_power_down(struct work_struct *work) up(&audio_pwr_sem); } -static DECLARE_DELAYED_WORK(codec_power_down_work, codec_delayed_power_down); +static DECLARE_WORK(codec_power_down_work, codec_delayed_power_down, NULL); static void nokia770_audio_pwr_down(void) { diff --git a/trunk/arch/arm/mach-omap1/leds-osk.c b/trunk/arch/arm/mach-omap1/leds-osk.c index 0cbf1b0071f8..3b29e59b0e6f 100644 --- a/trunk/arch/arm/mach-omap1/leds-osk.c +++ b/trunk/arch/arm/mach-omap1/leds-osk.c @@ -35,7 +35,7 @@ static u8 hw_led_state; static u8 tps_leds_change; -static void tps_work(struct work_struct *unused) +static void tps_work(void *unused) { for (;;) { u8 leds; @@ -61,7 +61,7 @@ static void tps_work(struct work_struct *unused) } } -static DECLARE_WORK(work, tps_work); +static DECLARE_WORK(work, tps_work, NULL); #ifdef CONFIG_OMAP_OSK_MISTRAL diff --git a/trunk/arch/arm/mach-omap2/board-h4.c b/trunk/arch/arm/mach-omap2/board-h4.c index 3b1ad1d981a3..26a95a642ad7 100644 --- a/trunk/arch/arm/mach-omap2/board-h4.c +++ b/trunk/arch/arm/mach-omap2/board-h4.c @@ -206,8 +206,7 @@ static int h4_transceiver_mode(struct device *dev, int mode) cancel_delayed_work(&irda_config->gpio_expa); PREPARE_WORK(&irda_config->gpio_expa, set_trans_mode, &mode); -#error this is not permitted - mode is an argument variable - schedule_delayed_work(&irda_config->gpio_expa, 0); + schedule_work(&irda_config->gpio_expa); return 0; } diff --git a/trunk/arch/arm/mach-pxa/akita-ioexp.c b/trunk/arch/arm/mach-pxa/akita-ioexp.c index 12d2fe0ceff6..1b398742ab56 100644 --- a/trunk/arch/arm/mach-pxa/akita-ioexp.c +++ b/trunk/arch/arm/mach-pxa/akita-ioexp.c @@ -36,11 +36,11 @@ I2C_CLIENT_INSMOD; static int max7310_write(struct i2c_client *client, int address, int data); static struct i2c_client max7310_template; -static void akita_ioexp_work(struct work_struct *private_); +static void akita_ioexp_work(void *private_); static struct device *akita_ioexp_device; static unsigned char ioexp_output_value = AKITA_IOEXP_IO_OUT; -DECLARE_WORK(akita_ioexp, akita_ioexp_work); +DECLARE_WORK(akita_ioexp, akita_ioexp_work, NULL); /* @@ -158,7 +158,7 @@ void akita_reset_ioexp(struct device *dev, unsigned char bit) EXPORT_SYMBOL(akita_set_ioexp); EXPORT_SYMBOL(akita_reset_ioexp); -static void akita_ioexp_work(struct work_struct *private_) +static void akita_ioexp_work(void *private_) { if (akita_ioexp_device) max7310_set_ouputs(akita_ioexp_device, ioexp_output_value); diff --git a/trunk/arch/i386/kernel/cpu/mcheck/non-fatal.c b/trunk/arch/i386/kernel/cpu/mcheck/non-fatal.c index 6b5d3518a1c0..1f9153ae5b03 100644 --- a/trunk/arch/i386/kernel/cpu/mcheck/non-fatal.c +++ b/trunk/arch/i386/kernel/cpu/mcheck/non-fatal.c @@ -51,10 +51,10 @@ static void mce_checkregs (void *info) } } -static void mce_work_fn(struct work_struct *work); -static DECLARE_DELAYED_WORK(mce_work, mce_work_fn); +static void mce_work_fn(void *data); +static DECLARE_WORK(mce_work, mce_work_fn, NULL); -static void mce_work_fn(struct work_struct *work) +static void mce_work_fn(void *data) { on_each_cpu(mce_checkregs, NULL, 1, 1); schedule_delayed_work(&mce_work, MCE_RATE); diff --git a/trunk/arch/i386/kernel/smpboot.c b/trunk/arch/i386/kernel/smpboot.c index 02a9b66b6ac3..4bb8b77cd65b 100644 --- a/trunk/arch/i386/kernel/smpboot.c +++ b/trunk/arch/i386/kernel/smpboot.c @@ -1049,15 +1049,13 @@ void cpu_exit_clear(void) struct warm_boot_cpu_info { struct completion *complete; - struct work_struct task; int apicid; int cpu; }; -static void __cpuinit do_warm_boot_cpu(struct work_struct *work) +static void __cpuinit do_warm_boot_cpu(void *p) { - struct warm_boot_cpu_info *info = - container_of(work, struct warm_boot_cpu_info, task); + struct warm_boot_cpu_info *info = p; do_boot_cpu(info->apicid, info->cpu); complete(info->complete); } @@ -1066,6 +1064,7 @@ static int __cpuinit __smp_prepare_cpu(int cpu) { DECLARE_COMPLETION_ONSTACK(done); struct warm_boot_cpu_info info; + struct work_struct task; int apicid, ret; struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu); @@ -1090,7 +1089,7 @@ static int __cpuinit __smp_prepare_cpu(int cpu) info.complete = &done; info.apicid = apicid; info.cpu = cpu; - INIT_WORK(&info.task, do_warm_boot_cpu); + INIT_WORK(&task, do_warm_boot_cpu, &info); tsc_sync_disabled = 1; @@ -1098,7 +1097,7 @@ static int __cpuinit __smp_prepare_cpu(int cpu) clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS, KERNEL_PGD_PTRS); flush_tlb_all(); - schedule_work(&info.task); + schedule_work(&task); wait_for_completion(&done); tsc_sync_disabled = 0; diff --git a/trunk/arch/i386/kernel/tsc.c b/trunk/arch/i386/kernel/tsc.c index 9810c8c90750..fbc95828cd74 100644 --- a/trunk/arch/i386/kernel/tsc.c +++ b/trunk/arch/i386/kernel/tsc.c @@ -217,7 +217,7 @@ static unsigned int cpufreq_delayed_issched = 0; static unsigned int cpufreq_init = 0; static struct work_struct cpufreq_delayed_get_work; -static void handle_cpufreq_delayed_get(struct work_struct *work) +static void handle_cpufreq_delayed_get(void *v) { unsigned int cpu; @@ -306,7 +306,7 @@ static int __init cpufreq_tsc(void) { int ret; - INIT_WORK(&cpufreq_delayed_get_work, handle_cpufreq_delayed_get); + INIT_WORK(&cpufreq_delayed_get_work, handle_cpufreq_delayed_get, NULL); ret = cpufreq_register_notifier(&time_cpufreq_notifier_block, CPUFREQ_TRANSITION_NOTIFIER); if (!ret) diff --git a/trunk/arch/ia64/hp/sim/simserial.c b/trunk/arch/ia64/hp/sim/simserial.c index b62f0c4d2c7c..caab986af70c 100644 --- a/trunk/arch/ia64/hp/sim/simserial.c +++ b/trunk/arch/ia64/hp/sim/simserial.c @@ -209,7 +209,7 @@ static void do_serial_bh(void) } #endif -static void do_softint(struct work_struct *private_) +static void do_softint(void *private_) { printk(KERN_ERR "simserial: do_softint called\n"); } @@ -698,7 +698,7 @@ static int get_async_struct(int line, struct async_struct **ret_info) info->flags = sstate->flags; info->xmit_fifo_size = sstate->xmit_fifo_size; info->line = line; - INIT_WORK(&info->work, do_softint); + INIT_WORK(&info->work, do_softint, info); info->state = sstate; if (sstate->info) { kfree(info); diff --git a/trunk/arch/ia64/kernel/mca.c b/trunk/arch/ia64/kernel/mca.c index 6bedd97570ca..7cfa63a98cb3 100644 --- a/trunk/arch/ia64/kernel/mca.c +++ b/trunk/arch/ia64/kernel/mca.c @@ -678,7 +678,7 @@ ia64_mca_cmc_vector_enable (void *dummy) * disable the cmc interrupt vector. */ static void -ia64_mca_cmc_vector_disable_keventd(struct work_struct *unused) +ia64_mca_cmc_vector_disable_keventd(void *unused) { on_each_cpu(ia64_mca_cmc_vector_disable, NULL, 1, 0); } @@ -690,7 +690,7 @@ ia64_mca_cmc_vector_disable_keventd(struct work_struct *unused) * enable the cmc interrupt vector. */ static void -ia64_mca_cmc_vector_enable_keventd(struct work_struct *unused) +ia64_mca_cmc_vector_enable_keventd(void *unused) { on_each_cpu(ia64_mca_cmc_vector_enable, NULL, 1, 0); } @@ -1247,8 +1247,8 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw, monarch_cpu = -1; } -static DECLARE_WORK(cmc_disable_work, ia64_mca_cmc_vector_disable_keventd); -static DECLARE_WORK(cmc_enable_work, ia64_mca_cmc_vector_enable_keventd); +static DECLARE_WORK(cmc_disable_work, ia64_mca_cmc_vector_disable_keventd, NULL); +static DECLARE_WORK(cmc_enable_work, ia64_mca_cmc_vector_enable_keventd, NULL); /* * ia64_mca_cmc_int_handler diff --git a/trunk/arch/ia64/kernel/smpboot.c b/trunk/arch/ia64/kernel/smpboot.c index b21ddecea943..f7d7f5668144 100644 --- a/trunk/arch/ia64/kernel/smpboot.c +++ b/trunk/arch/ia64/kernel/smpboot.c @@ -463,17 +463,15 @@ struct pt_regs * __devinit idle_regs(struct pt_regs *regs) } struct create_idle { - struct work_struct work; struct task_struct *idle; struct completion done; int cpu; }; void -do_fork_idle(struct work_struct *work) +do_fork_idle(void *_c_idle) { - struct create_idle *c_idle = - container_of(work, struct create_idle, work); + struct create_idle *c_idle = _c_idle; c_idle->idle = fork_idle(c_idle->cpu); complete(&c_idle->done); @@ -484,10 +482,10 @@ do_boot_cpu (int sapicid, int cpu) { int timeout; struct create_idle c_idle = { - .work = __WORK_INITIALIZER(c_idle.work, do_fork_idle), .cpu = cpu, .done = COMPLETION_INITIALIZER(c_idle.done), }; + DECLARE_WORK(work, do_fork_idle, &c_idle); c_idle.idle = get_idle_for_cpu(cpu); if (c_idle.idle) { @@ -499,9 +497,9 @@ do_boot_cpu (int sapicid, int cpu) * We can't use kernel_thread since we must avoid to reschedule the child. */ if (!keventd_up() || current_is_keventd()) - c_idle.work.func(&c_idle.work); + work.func(work.data); else { - schedule_work(&c_idle.work); + schedule_work(&work); wait_for_completion(&c_idle.done); } diff --git a/trunk/arch/m68knommu/platform/5307/timers.c b/trunk/arch/m68knommu/platform/5307/timers.c index e5668af19789..24781f009337 100644 --- a/trunk/arch/m68knommu/platform/5307/timers.c +++ b/trunk/arch/m68knommu/platform/5307/timers.c @@ -3,7 +3,7 @@ /* * timers.c -- generic ColdFire hardware timer support. * - * Copyright (C) 1999-2006, Greg Ungerer (gerg@snapgear.com) + * Copyright (C) 1999-2003, Greg Ungerer (gerg@snapgear.com) */ /***************************************************************************/ @@ -44,14 +44,6 @@ unsigned int mcf_timerlevel = 5; extern void mcf_settimericr(int timer, int level); extern int mcf_timerirqpending(int timer); -#if defined(CONFIG_M532x) -#define __raw_readtrr __raw_readl -#define __raw_writetrr __raw_writel -#else -#define __raw_readtrr __raw_readw -#define __raw_writetrr __raw_writew -#endif - /***************************************************************************/ void coldfire_tick(void) @@ -65,7 +57,7 @@ void coldfire_tick(void) void coldfire_timer_init(irqreturn_t (*handler)(int, void *, struct pt_regs *)) { __raw_writew(MCFTIMER_TMR_DISABLE, TA(MCFTIMER_TMR)); - __raw_writetrr(((MCF_BUSCLK / 16) / HZ), TA(MCFTIMER_TRR)); + __raw_writew(((MCF_BUSCLK / 16) / HZ), TA(MCFTIMER_TRR)); __raw_writew(MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 | MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE, TA(MCFTIMER_TMR)); @@ -84,7 +76,7 @@ unsigned long coldfire_timer_offset(void) unsigned long trr, tcn, offset; tcn = __raw_readw(TA(MCFTIMER_TCN)); - trr = __raw_readtrr(TA(MCFTIMER_TRR)); + trr = __raw_readw(TA(MCFTIMER_TRR)); offset = (tcn * (1000000 / HZ)) / trr; /* Check if we just wrapped the counters and maybe missed a tick */ @@ -128,7 +120,7 @@ void coldfire_profile_init(void) /* Set up TIMER 2 as high speed profile clock */ __raw_writew(MCFTIMER_TMR_DISABLE, PA(MCFTIMER_TMR)); - __raw_writetrr(((MCF_CLK / 16) / PROFILEHZ), PA(MCFTIMER_TRR)); + __raw_writew(((MCF_CLK / 16) / PROFILEHZ), PA(MCFTIMER_TRR)); __raw_writew(MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 | MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE, PA(MCFTIMER_TMR)); diff --git a/trunk/arch/m68knommu/platform/68360/config.c b/trunk/arch/m68knommu/platform/68360/config.c index 1b36f6261764..c5482e3622eb 100644 --- a/trunk/arch/m68knommu/platform/68360/config.c +++ b/trunk/arch/m68knommu/platform/68360/config.c @@ -114,7 +114,7 @@ void BSP_gettod (int *yearp, int *monp, int *dayp, { } -int BSP_hwclk(int op, struct rtc_time *t) +int BSP_hwclk(int op, struct hwclk_time *t) { if (!op) { /* read */ diff --git a/trunk/arch/mips/kernel/kspd.c b/trunk/arch/mips/kernel/kspd.c index 2c82412b9efe..f06a144c7881 100644 --- a/trunk/arch/mips/kernel/kspd.c +++ b/trunk/arch/mips/kernel/kspd.c @@ -319,7 +319,7 @@ static void sp_cleanup(void) static int channel_open = 0; /* the work handler */ -static void sp_work(struct work_struct *unused) +static void sp_work(void *data) { if (!channel_open) { if( rtlx_open(RTLX_CHANNEL_SYSIO, 1) != 0) { @@ -354,7 +354,7 @@ static void startwork(int vpe) return; } - INIT_WORK(&work, sp_work); + INIT_WORK(&work, sp_work, NULL); queue_work(workqueue, &work); } else queue_work(workqueue, &work); diff --git a/trunk/arch/powerpc/platforms/embedded6xx/ls_uart.c b/trunk/arch/powerpc/platforms/embedded6xx/ls_uart.c index 0e837762cc5b..31bcdae84823 100644 --- a/trunk/arch/powerpc/platforms/embedded6xx/ls_uart.c +++ b/trunk/arch/powerpc/platforms/embedded6xx/ls_uart.c @@ -14,7 +14,7 @@ static unsigned long avr_clock; static struct work_struct wd_work; -static void wd_stop(struct work_struct *unused) +static void wd_stop(void *unused) { const char string[] = "AAAAFFFFJJJJ>>>>VVVV>>>>ZZZZVVVVKKKK"; int i = 0, rescue = 8; @@ -122,7 +122,7 @@ static int __init ls_uarts_init(void) ls_uart_init(); - INIT_WORK(&wd_work, wd_stop); + INIT_WORK(&wd_work, wd_stop, NULL); schedule_work(&wd_work); return 0; diff --git a/trunk/arch/powerpc/platforms/powermac/backlight.c b/trunk/arch/powerpc/platforms/powermac/backlight.c index c3a89414ddc0..afa593a8544a 100644 --- a/trunk/arch/powerpc/platforms/powermac/backlight.c +++ b/trunk/arch/powerpc/platforms/powermac/backlight.c @@ -18,11 +18,11 @@ #define OLD_BACKLIGHT_MAX 15 -static void pmac_backlight_key_worker(struct work_struct *work); -static void pmac_backlight_set_legacy_worker(struct work_struct *work); +static void pmac_backlight_key_worker(void *data); +static void pmac_backlight_set_legacy_worker(void *data); -static DECLARE_WORK(pmac_backlight_key_work, pmac_backlight_key_worker); -static DECLARE_WORK(pmac_backlight_set_legacy_work, pmac_backlight_set_legacy_worker); +static DECLARE_WORK(pmac_backlight_key_work, pmac_backlight_key_worker, NULL); +static DECLARE_WORK(pmac_backlight_set_legacy_work, pmac_backlight_set_legacy_worker, NULL); /* Although these variables are used in interrupt context, it makes no sense to * protect them. No user is able to produce enough key events per second and @@ -94,7 +94,7 @@ int pmac_backlight_curve_lookup(struct fb_info *info, int value) return level; } -static void pmac_backlight_key_worker(struct work_struct *work) +static void pmac_backlight_key_worker(void *data) { if (atomic_read(&kernel_backlight_disabled)) return; @@ -166,7 +166,7 @@ static int __pmac_backlight_set_legacy_brightness(int brightness) return error; } -static void pmac_backlight_set_legacy_worker(struct work_struct *work) +static void pmac_backlight_set_legacy_worker(void *data) { if (atomic_read(&kernel_backlight_disabled)) return; diff --git a/trunk/arch/powerpc/platforms/pseries/eeh_event.c b/trunk/arch/powerpc/platforms/pseries/eeh_event.c index 49037edf7d39..137077451316 100644 --- a/trunk/arch/powerpc/platforms/pseries/eeh_event.c +++ b/trunk/arch/powerpc/platforms/pseries/eeh_event.c @@ -37,8 +37,8 @@ /* EEH event workqueue setup. */ static DEFINE_SPINLOCK(eeh_eventlist_lock); LIST_HEAD(eeh_eventlist); -static void eeh_thread_launcher(struct work_struct *); -DECLARE_WORK(eeh_event_wq, eeh_thread_launcher); +static void eeh_thread_launcher(void *); +DECLARE_WORK(eeh_event_wq, eeh_thread_launcher, NULL); /* Serialize reset sequences for a given pci device */ DEFINE_MUTEX(eeh_event_mutex); @@ -103,7 +103,7 @@ static int eeh_event_handler(void * dummy) * eeh_thread_launcher * @dummy - unused */ -static void eeh_thread_launcher(struct work_struct *dummy) +static void eeh_thread_launcher(void *dummy) { if (kernel_thread(eeh_event_handler, NULL, CLONE_KERNEL) < 0) printk(KERN_ERR "Failed to start EEH daemon\n"); diff --git a/trunk/arch/ppc/8260_io/fcc_enet.c b/trunk/arch/ppc/8260_io/fcc_enet.c index 709952c25f29..2e1943e27819 100644 --- a/trunk/arch/ppc/8260_io/fcc_enet.c +++ b/trunk/arch/ppc/8260_io/fcc_enet.c @@ -385,7 +385,6 @@ struct fcc_enet_private { phy_info_t *phy; struct work_struct phy_relink; struct work_struct phy_display_config; - struct net_device *dev; uint sequence_done; @@ -1392,11 +1391,10 @@ static phy_info_t *phy_info[] = { NULL }; -static void mii_display_status(struct work_struct *work) +static void mii_display_status(void *data) { - volatile struct fcc_enet_private *fep = - container_of(work, struct fcc_enet_private, phy_relink); - struct net_device *dev = fep->dev; + struct net_device *dev = data; + volatile struct fcc_enet_private *fep = dev->priv; uint s = fep->phy_status; if (!fep->link && !fep->old_link) { @@ -1430,12 +1428,10 @@ static void mii_display_status(struct work_struct *work) printk(".\n"); } -static void mii_display_config(struct work_struct *work) +static void mii_display_config(void *data) { - volatile struct fcc_enet_private *fep = - container_of(work, struct fcc_enet_private, - phy_display_config); - struct net_device *dev = fep->dev; + struct net_device *dev = data; + volatile struct fcc_enet_private *fep = dev->priv; uint s = fep->phy_status; printk("%s: config: auto-negotiation ", dev->name); @@ -1762,9 +1758,8 @@ static int __init fec_enet_init(void) cep->phy_id_done = 0; cep->phy_addr = fip->fc_phyaddr; mii_queue(dev, mk_mii_read(MII_PHYSID1), mii_discover_phy); - INIT_WORK(&cep->phy_relink, mii_display_status); - INIT_WORK(&cep->phy_display_config, mii_display_config); - cep->dev = dev; + INIT_WORK(&cep->phy_relink, mii_display_status, dev); + INIT_WORK(&cep->phy_display_config, mii_display_config, dev); #endif /* CONFIG_USE_MDIO */ fip++; diff --git a/trunk/arch/ppc/8xx_io/fec.c b/trunk/arch/ppc/8xx_io/fec.c index e6c28fb423b2..2f9fa9e3d331 100644 --- a/trunk/arch/ppc/8xx_io/fec.c +++ b/trunk/arch/ppc/8xx_io/fec.c @@ -173,7 +173,6 @@ struct fec_enet_private { uint phy_speed; phy_info_t *phy; struct work_struct phy_task; - struct net_device *dev; uint sequence_done; @@ -1264,11 +1263,10 @@ static void mii_display_status(struct net_device *dev) printk(".\n"); } -static void mii_display_config(struct work_struct *work) +static void mii_display_config(void *priv) { - struct fec_enet_private *fep = - container_of(work, struct fec_enet_private, phy_task); - struct net_device *dev = fep->dev; + struct net_device *dev = (struct net_device *)priv; + struct fec_enet_private *fep = dev->priv; volatile uint *s = &(fep->phy_status); printk("%s: config: auto-negotiation ", dev->name); @@ -1297,11 +1295,10 @@ static void mii_display_config(struct work_struct *work) fep->sequence_done = 1; } -static void mii_relink(struct work_struct *work) +static void mii_relink(void *priv) { - struct fec_enet_private *fep = - container_of(work, struct fec_enet_private, phy_task); - struct net_device *dev = fep->dev; + struct net_device *dev = (struct net_device *)priv; + struct fec_enet_private *fep = dev->priv; int duplex; fep->link = (fep->phy_status & PHY_STAT_LINK) ? 1 : 0; @@ -1328,8 +1325,7 @@ static void mii_queue_relink(uint mii_reg, struct net_device *dev) { struct fec_enet_private *fep = dev->priv; - fep->dev = dev; - INIT_WORK(&fep->phy_task, mii_relink); + INIT_WORK(&fep->phy_task, mii_relink, (void *)dev); schedule_work(&fep->phy_task); } @@ -1337,8 +1333,7 @@ static void mii_queue_config(uint mii_reg, struct net_device *dev) { struct fec_enet_private *fep = dev->priv; - fep->dev = dev; - INIT_WORK(&fep->phy_task, mii_display_config); + INIT_WORK(&fep->phy_task, mii_display_config, (void *)dev); schedule_work(&fep->phy_task); } diff --git a/trunk/arch/s390/appldata/appldata_base.c b/trunk/arch/s390/appldata/appldata_base.c index 67d5cf9cba83..af1e8fc7d985 100644 --- a/trunk/arch/s390/appldata/appldata_base.c +++ b/trunk/arch/s390/appldata/appldata_base.c @@ -92,8 +92,8 @@ static int appldata_timer_active; * Work queue */ static struct workqueue_struct *appldata_wq; -static void appldata_work_fn(struct work_struct *work); -static DECLARE_WORK(appldata_work, appldata_work_fn); +static void appldata_work_fn(void *data); +static DECLARE_WORK(appldata_work, appldata_work_fn, NULL); /* @@ -125,7 +125,7 @@ static void appldata_timer_function(unsigned long data) * * call data gathering function for each (active) module */ -static void appldata_work_fn(struct work_struct *work) +static void appldata_work_fn(void *data) { struct list_head *lh; struct appldata_ops *ops; diff --git a/trunk/arch/sh/Kconfig b/trunk/arch/sh/Kconfig index bffc7e176970..ba7a15016307 100644 --- a/trunk/arch/sh/Kconfig +++ b/trunk/arch/sh/Kconfig @@ -219,6 +219,20 @@ config SH_SHMIN help Select SHMIN if configuring for the SHMIN board. +config SH_7206_SOLUTION_ENGINE + bool "SolutionEngine7206" + select CPU_SUBTYPE_SH7206 + help + Select 7206 SolutionEngine if configuring for a Hitachi SH7206 + evaluation board. + +config SH_7619_SOLUTION_ENGINE + bool "SolutionEngine7619" + select CPU_SUBTYPE_SH7619 + help + Select 7619 SolutionEngine if configuring for a Hitachi SH7619 + evaluation board. + config SH_UNKNOWN bool "BareCPU" help @@ -364,10 +378,25 @@ depends on !GENERIC_TIME config SH_TMU bool "TMU timer support" + depends on CPU_SH3 || CPU_SH4 default y help This enables the use of the TMU as the system timer. +config SH_CMT + bool "CMT timer support" + depends on CPU_SH2 + default y + help + This enables the use of the CMT as the system timer. + +config SH_MTU2 + bool "MTU2 timer support" + depends on CPU_SH2A + default n + help + This enables the use of the MTU2 as the system timer. + endmenu source "arch/sh/boards/renesas/hs7751rvoip/Kconfig" @@ -378,17 +407,25 @@ source "arch/sh/boards/renesas/r7780rp/Kconfig" config SH_PCLK_FREQ int "Peripheral clock frequency (in Hz)" + default "27000000" if CPU_SUBTYPE_SH73180 || CPU_SUBTYPE_SH7343 + default "31250000" if CPU_SUBTYPE_SH7619 + default "33333333" if CPU_SUBTYPE_SH7300 || CPU_SUBTYPE_SH7770 || \ + CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7705 || \ + CPU_SUBTYPE_SH7206 default "50000000" if CPU_SUBTYPE_SH7750 || CPU_SUBTYPE_SH7780 default "60000000" if CPU_SUBTYPE_SH7751 - default "33333333" if CPU_SUBTYPE_SH7300 || CPU_SUBTYPE_SH7770 || \ - CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7705 - default "27000000" if CPU_SUBTYPE_SH73180 || CPU_SUBTYPE_SH7343 default "66000000" if CPU_SUBTYPE_SH4_202 help This option is used to specify the peripheral clock frequency. This is necessary for determining the reference clock value on platforms lacking an RTC. +config SH_CLK_MD + int "CPU Mode Pin Setting" + depends on CPU_SUBTYPE_SH7619 || CPU_SUBTYPE_SH7206 + help + MD2 - MD0 Setting. + menu "CPU Frequency scaling" source "drivers/cpufreq/Kconfig" diff --git a/trunk/arch/sh/Makefile b/trunk/arch/sh/Makefile index 26d62ff51a64..dc43984bd4be 100644 --- a/trunk/arch/sh/Makefile +++ b/trunk/arch/sh/Makefile @@ -109,6 +109,8 @@ machdir-$(CONFIG_SH_SH4202_MICRODEV) := superh/microdev machdir-$(CONFIG_SH_LANDISK) := landisk machdir-$(CONFIG_SH_TITAN) := titan machdir-$(CONFIG_SH_SHMIN) := shmin +machdir-$(CONFIG_SH_7206_SOLUTION_ENGINE) := se/7206 +machdir-$(CONFIG_SH_7619_SOLUTION_ENGINE) := se/7619 machdir-$(CONFIG_SH_UNKNOWN) := unknown incdir-y := $(notdir $(machdir-y)) @@ -124,6 +126,7 @@ core-$(CONFIG_HD64465) += arch/sh/cchips/hd6446x/hd64465/ core-$(CONFIG_VOYAGERGX) += arch/sh/cchips/voyagergx/ cpuincdir-$(CONFIG_CPU_SH2) := cpu-sh2 +cpuincdir-$(CONFIG_CPU_SH2A) := cpu-sh2a cpuincdir-$(CONFIG_CPU_SH3) := cpu-sh3 cpuincdir-$(CONFIG_CPU_SH4) := cpu-sh4 diff --git a/trunk/arch/sh/boot/compressed/misc.c b/trunk/arch/sh/boot/compressed/misc.c index f2fed5ce5cc3..35452d85b7f7 100644 --- a/trunk/arch/sh/boot/compressed/misc.c +++ b/trunk/arch/sh/boot/compressed/misc.c @@ -12,6 +12,7 @@ */ #include +#include #ifdef CONFIG_SH_STANDARD_BIOS #include #endif @@ -228,7 +229,7 @@ long* stack_start = &user_stack[STACK_SIZE]; void decompress_kernel(void) { output_data = 0; - output_ptr = (unsigned long)&_text+0x20001000; + output_ptr = P2SEGADDR((unsigned long)&_text+0x1000); free_mem_ptr = (unsigned long)&_end; free_mem_end_ptr = free_mem_ptr + HEAP_SIZE; diff --git a/trunk/arch/sh/kernel/Makefile b/trunk/arch/sh/kernel/Makefile index 5da88a43d350..50d54c24d76a 100644 --- a/trunk/arch/sh/kernel/Makefile +++ b/trunk/arch/sh/kernel/Makefile @@ -4,7 +4,7 @@ extra-y := head.o init_task.o vmlinux.lds -obj-y := process.o signal.o entry.o traps.o irq.o \ +obj-y := process.o signal.o traps.o irq.o \ ptrace.o setup.o time.o sys_sh.o semaphore.o \ io.o io_generic.o sh_ksyms.o syscalls.o diff --git a/trunk/arch/sh/kernel/cpu/Makefile b/trunk/arch/sh/kernel/cpu/Makefile index fb5dac069382..0582e6712b79 100644 --- a/trunk/arch/sh/kernel/cpu/Makefile +++ b/trunk/arch/sh/kernel/cpu/Makefile @@ -2,11 +2,12 @@ # Makefile for the Linux/SuperH CPU-specifc backends. # -obj-y += irq/ init.o clock.o - -obj-$(CONFIG_CPU_SH2) += sh2/ -obj-$(CONFIG_CPU_SH3) += sh3/ -obj-$(CONFIG_CPU_SH4) += sh4/ +obj-$(CONFIG_CPU_SH2) = sh2/ +obj-$(CONFIG_CPU_SH2A) = sh2a/ +obj-$(CONFIG_CPU_SH3) = sh3/ +obj-$(CONFIG_CPU_SH4) = sh4/ obj-$(CONFIG_UBC_WAKEUP) += ubc.o obj-$(CONFIG_SH_ADC) += adc.o + +obj-y += irq/ init.o clock.o diff --git a/trunk/arch/sh/kernel/cpu/init.c b/trunk/arch/sh/kernel/cpu/init.c index bfb90eb0b7a6..48121766e8d2 100644 --- a/trunk/arch/sh/kernel/cpu/init.c +++ b/trunk/arch/sh/kernel/cpu/init.c @@ -68,12 +68,14 @@ static void __init cache_init(void) waysize = cpu_data->dcache.sets; +#ifdef CCR_CACHE_ORA /* * If the OC is already in RAM mode, we only have * half of the entries to flush.. */ if (ccr & CCR_CACHE_ORA) waysize >>= 1; +#endif waysize <<= cpu_data->dcache.entry_shift; diff --git a/trunk/arch/sh/kernel/cpu/irq/imask.c b/trunk/arch/sh/kernel/cpu/irq/imask.c index a33ae3e0a5a5..301b505c4278 100644 --- a/trunk/arch/sh/kernel/cpu/irq/imask.c +++ b/trunk/arch/sh/kernel/cpu/irq/imask.c @@ -53,7 +53,10 @@ void static inline set_interrupt_registers(int ip) { unsigned long __dummy; - asm volatile("ldc %2, r6_bank\n\t" + asm volatile( +#ifdef CONFIG_CPU_HAS_SR_RB + "ldc %2, r6_bank\n\t" +#endif "stc sr, %0\n\t" "and #0xf0, %0\n\t" "shlr2 %0\n\t" diff --git a/trunk/arch/sh/kernel/cpu/irq/ipr.c b/trunk/arch/sh/kernel/cpu/irq/ipr.c index a0089563cbfc..f7a2bae1df94 100644 --- a/trunk/arch/sh/kernel/cpu/irq/ipr.c +++ b/trunk/arch/sh/kernel/cpu/irq/ipr.c @@ -62,6 +62,10 @@ void make_ipr_irq(struct ipr_data *table, unsigned int nr_irqs) } EXPORT_SYMBOL(make_ipr_irq); +/* + * XXX: Move this garbage in to the drivers, and kill off the ridiculous CPU + * subtype checks. + */ static struct ipr_data sys_ipr_map[] = { #ifndef CONFIG_CPU_SUBTYPE_SH7780 { TIMER_IRQ, TIMER_IPR_ADDR, TIMER_IPR_POS, TIMER_PRIORITY }, @@ -80,6 +84,18 @@ static struct ipr_data sys_ipr_map[] = { { SCIF1_BRI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY }, { SCIF1_TXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY }, #endif +#ifdef SCIF2_ERI_IRQ + { SCIF2_ERI_IRQ, SCIF2_IPR_ADDR, SCIF2_IPR_POS, SCIF2_PRIORITY }, + { SCIF2_RXI_IRQ, SCIF2_IPR_ADDR, SCIF2_IPR_POS, SCIF2_PRIORITY }, + { SCIF2_BRI_IRQ, SCIF2_IPR_ADDR, SCIF2_IPR_POS, SCIF2_PRIORITY }, + { SCIF2_TXI_IRQ, SCIF2_IPR_ADDR, SCIF2_IPR_POS, SCIF2_PRIORITY }, +#endif +#ifdef SCIF3_ERI_IRQ + { SCIF3_ERI_IRQ, SCIF3_IPR_ADDR, SCIF3_IPR_POS, SCIF3_PRIORITY }, + { SCIF3_RXI_IRQ, SCIF3_IPR_ADDR, SCIF3_IPR_POS, SCIF3_PRIORITY }, + { SCIF3_BRI_IRQ, SCIF3_IPR_ADDR, SCIF3_IPR_POS, SCIF3_PRIORITY }, + { SCIF3_TXI_IRQ, SCIF3_IPR_ADDR, SCIF3_IPR_POS, SCIF3_PRIORITY }, +#endif #if defined(CONFIG_CPU_SUBTYPE_SH7300) { SCIF0_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY }, { DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY }, diff --git a/trunk/arch/sh/kernel/cpu/sh2/Makefile b/trunk/arch/sh/kernel/cpu/sh2/Makefile index 389353fba608..f0f059acfcfb 100644 --- a/trunk/arch/sh/kernel/cpu/sh2/Makefile +++ b/trunk/arch/sh/kernel/cpu/sh2/Makefile @@ -2,5 +2,6 @@ # Makefile for the Linux/SuperH SH-2 backends. # -obj-y := probe.o +obj-y := ex.o probe.o entry.o +obj-$(CONFIG_CPU_SUBTYPE_SH7619) += setup-sh7619.o clock-sh7619.o diff --git a/trunk/arch/sh/kernel/cpu/sh2/clock-sh7619.c b/trunk/arch/sh/kernel/cpu/sh2/clock-sh7619.c new file mode 100644 index 000000000000..d0440b269702 --- /dev/null +++ b/trunk/arch/sh/kernel/cpu/sh2/clock-sh7619.c @@ -0,0 +1,81 @@ +/* + * arch/sh/kernel/cpu/sh2/clock-sh7619.c + * + * SH7619 support for the clock framework + * + * Copyright (C) 2006 Yoshinori Sato + * + * Based on clock-sh4.c + * Copyright (C) 2005 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include +#include + +const static int pll1rate[]={1,2}; +const static int pfc_divisors[]={1,2,0,4}; + +#if (CONFIG_SH_CLK_MD == 1) || (CONFIG_SH_CLK_MD == 2) +#define PLL2 (4) +#elif (CONFIG_SH_CLK_MD == 5) || (CONFIG_SH_CLK_MD == 6) +#define PLL2 (2) +#else +#error "Illigal Clock Mode!" +#endif + +static void master_clk_init(struct clk *clk) +{ + clk->rate *= PLL2 * pll1rate[(ctrl_inw(FREQCR) >> 8) & 7]; +} + +static struct clk_ops sh7619_master_clk_ops = { + .init = master_clk_init, +}; + +static void module_clk_recalc(struct clk *clk) +{ + int idx = (ctrl_inw(FREQCR) & 0x0007); + clk->rate = clk->parent->rate / pfc_divisors[idx]; +} + +static struct clk_ops sh7619_module_clk_ops = { + .recalc = module_clk_recalc, +}; + +static void bus_clk_recalc(struct clk *clk) +{ + clk->rate = clk->parent->rate / pll1rate[(ctrl_inw(FREQCR) >> 8) & 7]; +} + +static struct clk_ops sh7619_bus_clk_ops = { + .recalc = bus_clk_recalc, +}; + +static void cpu_clk_recalc(struct clk *clk) +{ + clk->rate = clk->parent->rate; +} + +static struct clk_ops sh7619_cpu_clk_ops = { + .recalc = cpu_clk_recalc, +}; + +static struct clk_ops *sh7619_clk_ops[] = { + &sh7619_master_clk_ops, + &sh7619_module_clk_ops, + &sh7619_bus_clk_ops, + &sh7619_cpu_clk_ops, +}; + +void __init arch_init_clk_ops(struct clk_ops **ops, int idx) +{ + if (idx < ARRAY_SIZE(sh7619_clk_ops)) + *ops = sh7619_clk_ops[idx]; +} + diff --git a/trunk/arch/sh/kernel/cpu/sh2/probe.c b/trunk/arch/sh/kernel/cpu/sh2/probe.c index f17a2a0d588e..ba527d9b5024 100644 --- a/trunk/arch/sh/kernel/cpu/sh2/probe.c +++ b/trunk/arch/sh/kernel/cpu/sh2/probe.c @@ -17,17 +17,23 @@ int __init detect_cpu_and_cache_system(void) { - /* - * For now, assume SH7604 .. fix this later. - */ +#if defined(CONFIG_CPU_SUBTYPE_SH7604) cpu_data->type = CPU_SH7604; cpu_data->dcache.ways = 4; - cpu_data->dcache.way_shift = 6; + cpu_data->dcache.way_incr = (1<<10); cpu_data->dcache.sets = 64; cpu_data->dcache.entry_shift = 4; cpu_data->dcache.linesz = L1_CACHE_BYTES; cpu_data->dcache.flags = 0; - +#elif defined(CONFIG_CPU_SUBTYPE_SH7619) + cpu_data->type = CPU_SH7619; + cpu_data->dcache.ways = 4; + cpu_data->dcache.way_incr = (1<<12); + cpu_data->dcache.sets = 256; + cpu_data->dcache.entry_shift = 4; + cpu_data->dcache.linesz = L1_CACHE_BYTES; + cpu_data->dcache.flags = 0; +#endif /* * SH-2 doesn't have separate caches */ diff --git a/trunk/arch/sh/kernel/cpu/sh2/setup-sh7619.c b/trunk/arch/sh/kernel/cpu/sh2/setup-sh7619.c new file mode 100644 index 000000000000..82c2d905152f --- /dev/null +++ b/trunk/arch/sh/kernel/cpu/sh2/setup-sh7619.c @@ -0,0 +1,53 @@ +/* + * SH7619 Setup + * + * Copyright (C) 2006 Yoshinori Sato + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include + +static struct plat_sci_port sci_platform_data[] = { + { + .mapbase = 0xf8400000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 88, 89, 91, 90}, + }, { + .mapbase = 0xf8410000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 92, 93, 95, 94}, + }, { + .mapbase = 0xf8420000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 96, 97, 99, 98}, + }, { + .flags = 0, + } +}; + +static struct platform_device sci_device = { + .name = "sh-sci", + .id = -1, + .dev = { + .platform_data = sci_platform_data, + }, +}; + +static struct platform_device *sh7619_devices[] __initdata = { + &sci_device, +}; + +static int __init sh7619_devices_setup(void) +{ + return platform_add_devices(sh7619_devices, + ARRAY_SIZE(sh7619_devices)); +} +__initcall(sh7619_devices_setup); diff --git a/trunk/arch/sh/kernel/cpu/sh2a/Makefile b/trunk/arch/sh/kernel/cpu/sh2a/Makefile new file mode 100644 index 000000000000..350972ae9410 --- /dev/null +++ b/trunk/arch/sh/kernel/cpu/sh2a/Makefile @@ -0,0 +1,10 @@ +# +# Makefile for the Linux/SuperH SH-2A backends. +# + +obj-y := common.o probe.o + +common-y += $(addprefix ../sh2/, ex.o) +common-y += $(addprefix ../sh2/, entry.o) + +obj-$(CONFIG_CPU_SUBTYPE_SH7206) += setup-sh7206.o clock-sh7206.o diff --git a/trunk/arch/sh/kernel/cpu/sh2a/clock-sh7206.c b/trunk/arch/sh/kernel/cpu/sh2a/clock-sh7206.c new file mode 100644 index 000000000000..a9ad309c6a33 --- /dev/null +++ b/trunk/arch/sh/kernel/cpu/sh2a/clock-sh7206.c @@ -0,0 +1,85 @@ +/* + * arch/sh/kernel/cpu/sh2a/clock-sh7206.c + * + * SH7206 support for the clock framework + * + * Copyright (C) 2006 Yoshinori Sato + * + * Based on clock-sh4.c + * Copyright (C) 2005 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include +#include + +const static int pll1rate[]={1,2,3,4,6,8}; +const static int pfc_divisors[]={1,2,3,4,6,8,12}; +#define ifc_divisors pfc_divisors + +#if (CONFIG_SH_CLK_MD == 2) +#define PLL2 (4) +#elif (CONFIG_SH_CLK_MD == 6) +#define PLL2 (2) +#elif (CONFIG_SH_CLK_MD == 7) +#define PLL2 (1) +#else +#error "Illigal Clock Mode!" +#endif + +static void master_clk_init(struct clk *clk) +{ + clk->rate *= PLL2 * pll1rate[(ctrl_inw(FREQCR) >> 8) & 0x0007]; +} + +static struct clk_ops sh7206_master_clk_ops = { + .init = master_clk_init, +}; + +static void module_clk_recalc(struct clk *clk) +{ + int idx = (ctrl_inw(FREQCR) & 0x0007); + clk->rate = clk->parent->rate / pfc_divisors[idx]; +} + +static struct clk_ops sh7206_module_clk_ops = { + .recalc = module_clk_recalc, +}; + +static void bus_clk_recalc(struct clk *clk) +{ + clk->rate = clk->parent->rate / pll1rate[(ctrl_inw(FREQCR) >> 8) & 0x0007]; +} + +static struct clk_ops sh7206_bus_clk_ops = { + .recalc = bus_clk_recalc, +}; + +static void cpu_clk_recalc(struct clk *clk) +{ + int idx = (ctrl_inw(FREQCR) & 0x0007); + clk->rate = clk->parent->rate / ifc_divisors[idx]; +} + +static struct clk_ops sh7206_cpu_clk_ops = { + .recalc = cpu_clk_recalc, +}; + +static struct clk_ops *sh7206_clk_ops[] = { + &sh7206_master_clk_ops, + &sh7206_module_clk_ops, + &sh7206_bus_clk_ops, + &sh7206_cpu_clk_ops, +}; + +void __init arch_init_clk_ops(struct clk_ops **ops, int idx) +{ + if (idx < ARRAY_SIZE(sh7206_clk_ops)) + *ops = sh7206_clk_ops[idx]; +} + diff --git a/trunk/arch/sh/kernel/cpu/sh2a/probe.c b/trunk/arch/sh/kernel/cpu/sh2a/probe.c new file mode 100644 index 000000000000..87c6c0542089 --- /dev/null +++ b/trunk/arch/sh/kernel/cpu/sh2a/probe.c @@ -0,0 +1,39 @@ +/* + * arch/sh/kernel/cpu/sh2a/probe.c + * + * CPU Subtype Probing for SH-2A. + * + * Copyright (C) 2004, 2005 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include +#include +#include + +int __init detect_cpu_and_cache_system(void) +{ + /* Just SH7206 for now .. */ + cpu_data->type = CPU_SH7206; + + cpu_data->dcache.ways = 4; + cpu_data->dcache.way_incr = (1 << 11); + cpu_data->dcache.sets = 128; + cpu_data->dcache.entry_shift = 4; + cpu_data->dcache.linesz = L1_CACHE_BYTES; + cpu_data->dcache.flags = 0; + + /* + * The icache is the same as the dcache as far as this setup is + * concerned. The only real difference in hardware is that the icache + * lacks the U bit that the dcache has, none of this has any bearing + * on the cache info. + */ + cpu_data->icache = cpu_data->dcache; + + return 0; +} + diff --git a/trunk/arch/sh/kernel/cpu/sh2a/setup-sh7206.c b/trunk/arch/sh/kernel/cpu/sh2a/setup-sh7206.c new file mode 100644 index 000000000000..cdfeef49e62e --- /dev/null +++ b/trunk/arch/sh/kernel/cpu/sh2a/setup-sh7206.c @@ -0,0 +1,58 @@ +/* + * SH7206 Setup + * + * Copyright (C) 2006 Yoshinori Sato + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include + +static struct plat_sci_port sci_platform_data[] = { + { + .mapbase = 0xfffe8000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 240, 241, 242, 243}, + }, { + .mapbase = 0xfffe8800, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 244, 245, 246, 247}, + }, { + .mapbase = 0xfffe9000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 248, 249, 250, 251}, + }, { + .mapbase = 0xfffe9800, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 252, 253, 254, 255}, + }, { + .flags = 0, + } +}; + +static struct platform_device sci_device = { + .name = "sh-sci", + .id = -1, + .dev = { + .platform_data = sci_platform_data, + }, +}; + +static struct platform_device *sh7206_devices[] __initdata = { + &sci_device, +}; + +static int __init sh7206_devices_setup(void) +{ + return platform_add_devices(sh7206_devices, + ARRAY_SIZE(sh7206_devices)); +} +__initcall(sh7206_devices_setup); diff --git a/trunk/arch/sh/kernel/setup.c b/trunk/arch/sh/kernel/setup.c index 36d86f9ac38a..c24f6390007b 100644 --- a/trunk/arch/sh/kernel/setup.c +++ b/trunk/arch/sh/kernel/setup.c @@ -404,6 +404,7 @@ static const char *cpu_name[] = { [CPU_SH4_202] = "SH4-202", [CPU_SH4_501] = "SH4-501", [CPU_SH7770] = "SH7770", [CPU_SH7780] = "SH7780", [CPU_SH7781] = "SH7781", [CPU_SH7343] = "SH7343", + [CPU_SH7206] = "SH7206", [CPU_SH7619] = "SH7619", [CPU_SH_NONE] = "Unknown" }; diff --git a/trunk/arch/sh/kernel/signal.c b/trunk/arch/sh/kernel/signal.c index 5213f5bc6ce0..764886b4bcf1 100644 --- a/trunk/arch/sh/kernel/signal.c +++ b/trunk/arch/sh/kernel/signal.c @@ -98,7 +98,11 @@ sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, */ #define MOVW(n) (0x9300|((n)-2)) /* Move mem word at PC+n to R3 */ -#define TRAP16 0xc310 /* Syscall w/no args (NR in R3) */ +#if defined(CONFIG_CPU_SH2) || defined(CONFIG_CPU_SH2A) +#define TRAP_NOARG 0xc320 /* Syscall w/no args (NR in R3) */ +#else +#define TRAP_NOARG 0xc310 /* Syscall w/no args (NR in R3) */ +#endif #define OR_R0_R0 0x200b /* or r0,r0 (insert to avoid hardware bug) */ struct sigframe @@ -350,7 +354,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, } else { /* Generate return code (system call to sigreturn) */ err |= __put_user(MOVW(7), &frame->retcode[0]); - err |= __put_user(TRAP16, &frame->retcode[1]); + err |= __put_user(TRAP_NOARG, &frame->retcode[1]); err |= __put_user(OR_R0_R0, &frame->retcode[2]); err |= __put_user(OR_R0_R0, &frame->retcode[3]); err |= __put_user(OR_R0_R0, &frame->retcode[4]); @@ -430,7 +434,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, } else { /* Generate return code (system call to rt_sigreturn) */ err |= __put_user(MOVW(7), &frame->retcode[0]); - err |= __put_user(TRAP16, &frame->retcode[1]); + err |= __put_user(TRAP_NOARG, &frame->retcode[1]); err |= __put_user(OR_R0_R0, &frame->retcode[2]); err |= __put_user(OR_R0_R0, &frame->retcode[3]); err |= __put_user(OR_R0_R0, &frame->retcode[4]); diff --git a/trunk/arch/sh/kernel/timers/Makefile b/trunk/arch/sh/kernel/timers/Makefile index 151a6a304cec..bcf244ff6a12 100644 --- a/trunk/arch/sh/kernel/timers/Makefile +++ b/trunk/arch/sh/kernel/timers/Makefile @@ -5,4 +5,6 @@ obj-y := timer.o obj-$(CONFIG_SH_TMU) += timer-tmu.o +obj-$(CONFIG_SH_MTU2) += timer-mtu2.o +obj-$(CONFIG_SH_CMT) += timer-cmt.o diff --git a/trunk/arch/sh/kernel/timers/timer-cmt.c b/trunk/arch/sh/kernel/timers/timer-cmt.c new file mode 100644 index 000000000000..9eab395cd341 --- /dev/null +++ b/trunk/arch/sh/kernel/timers/timer-cmt.c @@ -0,0 +1,256 @@ +/* + * arch/sh/kernel/timers/timer-cmt.c - CMT Timer Support + * + * Copyright (C) 2005 Yoshinori Sato + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_CPU_SUBTYPE_SH7619) +#define CMT_CMSTR 0xf84a0070 +#define CMT_CMCSR_0 0xf84a0072 +#define CMT_CMCNT_0 0xf84a0074 +#define CMT_CMCOR_0 0xf84a0076 +#define CMT_CMCSR_1 0xf84a0078 +#define CMT_CMCNT_1 0xf84a007a +#define CMT_CMCOR_1 0xf84a007c + +#define STBCR3 0xf80a0000 +#define cmt_clock_enable() do { ctrl_outb(ctrl_inb(STBCR3) & ~0x10, STBCR3); } while(0) +#define CMT_CMCSR_INIT 0x0040 +#define CMT_CMCSR_CALIB 0x0000 +#elif defined(CONFIG_CPU_SUBTYPE_SH7206) +#define CMT_CMSTR 0xfffec000 +#define CMT_CMCSR_0 0xfffec002 +#define CMT_CMCNT_0 0xfffec004 +#define CMT_CMCOR_0 0xfffec006 + +#define STBCR4 0xfffe040c +#define cmt_clock_enable() do { ctrl_outb(ctrl_inb(STBCR4) & ~0x04, STBCR4); } while(0) +#define CMT_CMCSR_INIT 0x0040 +#define CMT_CMCSR_CALIB 0x0000 +#else +#error "Unknown CPU SUBTYPE" +#endif + +static DEFINE_SPINLOCK(cmt0_lock); + +static unsigned long cmt_timer_get_offset(void) +{ + int count; + unsigned long flags; + + static unsigned short count_p = 0xffff; /* for the first call after boot */ + static unsigned long jiffies_p = 0; + + /* + * cache volatile jiffies temporarily; we have IRQs turned off. + */ + unsigned long jiffies_t; + + spin_lock_irqsave(&cmt0_lock, flags); + /* timer count may underflow right here */ + count = ctrl_inw(CMT_CMCOR_0); + count -= ctrl_inw(CMT_CMCNT_0); + + jiffies_t = jiffies; + + /* + * avoiding timer inconsistencies (they are rare, but they happen)... + * there is one kind of problem that must be avoided here: + * 1. the timer counter underflows + */ + + if (jiffies_t == jiffies_p) { + if (count > count_p) { + /* the nutcase */ + if (ctrl_inw(CMT_CMCSR_0) & 0x80) { /* Check CMF bit */ + count -= LATCH; + } else { + printk("%s (): hardware timer problem?\n", + __FUNCTION__); + } + } + } else + jiffies_p = jiffies_t; + + count_p = count; + spin_unlock_irqrestore(&cmt0_lock, flags); + + count = ((LATCH-1) - count) * TICK_SIZE; + count = (count + LATCH/2) / LATCH; + + return count; +} + +static irqreturn_t cmt_timer_interrupt(int irq, void *dev_id, + struct pt_regs *regs) +{ + unsigned long timer_status; + + /* Clear CMF bit */ + timer_status = ctrl_inw(CMT_CMCSR_0); + timer_status &= ~0x80; + ctrl_outw(timer_status, CMT_CMCSR_0); + + /* + * Here we are in the timer irq handler. We just have irqs locally + * disabled but we don't know if the timer_bh is running on the other + * CPU. We need to avoid to SMP race with it. NOTE: we don' t need + * the irq version of write_lock because as just said we have irq + * locally disabled. -arca + */ + write_seqlock(&xtime_lock); + handle_timer_tick(regs); + write_sequnlock(&xtime_lock); + + return IRQ_HANDLED; +} + +static struct irqaction cmt_irq = { + .name = "timer", + .handler = cmt_timer_interrupt, + .flags = SA_INTERRUPT, + .mask = CPU_MASK_NONE, +}; + +/* + * Hah! We'll see if this works (switching from usecs to nsecs). + */ +static unsigned long cmt_timer_get_frequency(void) +{ + u32 freq; + struct timespec ts1, ts2; + unsigned long diff_nsec; + unsigned long factor; + + /* Setup the timer: We don't want to generate interrupts, just + * have it count down at its natural rate. + */ + + ctrl_outw(ctrl_inw(CMT_CMSTR) & ~0x01, CMT_CMSTR); + ctrl_outw(CMT_CMCSR_CALIB, CMT_CMCSR_0); + ctrl_outw(0xffff, CMT_CMCOR_0); + ctrl_outw(0xffff, CMT_CMCNT_0); + + rtc_sh_get_time(&ts2); + + do { + rtc_sh_get_time(&ts1); + } while (ts1.tv_nsec == ts2.tv_nsec && ts1.tv_sec == ts2.tv_sec); + + /* actually start the timer */ + ctrl_outw(ctrl_inw(CMT_CMSTR) | 0x01, CMT_CMSTR); + + do { + rtc_sh_get_time(&ts2); + } while (ts1.tv_nsec == ts2.tv_nsec && ts1.tv_sec == ts2.tv_sec); + + freq = 0xffff - ctrl_inw(CMT_CMCNT_0); + if (ts2.tv_nsec < ts1.tv_nsec) { + ts2.tv_nsec += 1000000000; + ts2.tv_sec--; + } + + diff_nsec = (ts2.tv_sec - ts1.tv_sec) * 1000000000 + (ts2.tv_nsec - ts1.tv_nsec); + + /* this should work well if the RTC has a precision of n Hz, where + * n is an integer. I don't think we have to worry about the other + * cases. */ + factor = (1000000000 + diff_nsec/2) / diff_nsec; + + if (factor * diff_nsec > 1100000000 || + factor * diff_nsec < 900000000) + panic("weird RTC (diff_nsec %ld)", diff_nsec); + + return freq * factor; +} + +static void cmt_clk_init(struct clk *clk) +{ + u8 divisor = CMT_CMCSR_INIT & 0x3; + ctrl_inw(CMT_CMCSR_0); + ctrl_outw(CMT_CMCSR_INIT, CMT_CMCSR_0); + clk->parent = clk_get("module_clk"); + clk->rate = clk->parent->rate / (8 << (divisor << 1)); +} + +static void cmt_clk_recalc(struct clk *clk) +{ + u8 divisor = ctrl_inw(CMT_CMCSR_0) & 0x3; + clk->rate = clk->parent->rate / (8 << (divisor << 1)); +} + +static struct clk_ops cmt_clk_ops = { + .init = cmt_clk_init, + .recalc = cmt_clk_recalc, +}; + +static struct clk cmt0_clk = { + .name = "cmt0_clk", + .ops = &cmt_clk_ops, +}; + +static int cmt_timer_start(void) +{ + ctrl_outw(ctrl_inw(CMT_CMSTR) | 0x01, CMT_CMSTR); + return 0; +} + +static int cmt_timer_stop(void) +{ + ctrl_outw(ctrl_inw(CMT_CMSTR) & ~0x01, CMT_CMSTR); + return 0; +} + +static int cmt_timer_init(void) +{ + unsigned long interval; + + cmt_clock_enable(); + + setup_irq(TIMER_IRQ, &cmt_irq); + + cmt0_clk.parent = clk_get("module_clk"); + + cmt_timer_stop(); + + interval = cmt0_clk.parent->rate / 8 / HZ; + printk(KERN_INFO "Interval = %ld\n", interval); + + ctrl_outw(interval, CMT_CMCOR_0); + + clk_register(&cmt0_clk); + clk_enable(&cmt0_clk); + + cmt_timer_start(); + + return 0; +} + +struct sys_timer_ops cmt_timer_ops = { + .init = cmt_timer_init, + .start = cmt_timer_start, + .stop = cmt_timer_stop, + .get_frequency = cmt_timer_get_frequency, + .get_offset = cmt_timer_get_offset, +}; + +struct sys_timer cmt_timer = { + .name = "cmt", + .ops = &cmt_timer_ops, +}; + diff --git a/trunk/arch/sh/kernel/timers/timer-mtu2.c b/trunk/arch/sh/kernel/timers/timer-mtu2.c new file mode 100644 index 000000000000..73a5ef3c457d --- /dev/null +++ b/trunk/arch/sh/kernel/timers/timer-mtu2.c @@ -0,0 +1,260 @@ +/* + * arch/sh/kernel/timers/timer-mtu2.c - MTU2 Timer Support + * + * Copyright (C) 2005 Paul Mundt + * + * Based off of arch/sh/kernel/timers/timer-tmu.c + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * We use channel 1 for our lowly system timer. Channel 2 would be the other + * likely candidate, but we leave it alone as it has higher divisors that + * would be of more use to other more interesting applications. + * + * TODO: Presently we only implement a 16-bit single-channel system timer. + * However, we can implement channel cascade if we go the overflow route and + * get away with using 2 MTU2 channels as a 32-bit timer. + */ + +static DEFINE_SPINLOCK(mtu2_lock); + +#define MTU2_TSTR 0xfffe4280 +#define MTU2_TCR_1 0xfffe4380 +#define MTU2_TMDR_1 0xfffe4381 +#define MTU2_TIOR_1 0xfffe4382 +#define MTU2_TIER_1 0xfffe4384 +#define MTU2_TSR_1 0xfffe4385 +#define MTU2_TCNT_1 0xfffe4386 /* 16-bit counter */ +#define MTU2_TGRA_1 0xfffe438a + +#define STBCR3 0xfffe0408 + +#define MTU2_TSTR_CST1 (1 << 1) /* Counter Start 1 */ + +#define MTU2_TSR_TGFA (1 << 0) /* GRA compare match */ + +#define MTU2_TIER_TGIEA (1 << 0) /* GRA compare match interrupt enable */ + +#define MTU2_TCR_INIT 0x22 + +#define MTU2_TCR_CALIB 0x00 + +static unsigned long mtu2_timer_get_offset(void) +{ + int count; + unsigned long flags; + + static int count_p = 0x7fff; /* for the first call after boot */ + static unsigned long jiffies_p = 0; + + /* + * cache volatile jiffies temporarily; we have IRQs turned off. + */ + unsigned long jiffies_t; + + spin_lock_irqsave(&mtu2_lock, flags); + /* timer count may underflow right here */ + count = ctrl_inw(MTU2_TCNT_1); /* read the latched count */ + + jiffies_t = jiffies; + + /* + * avoiding timer inconsistencies (they are rare, but they happen)... + * there is one kind of problem that must be avoided here: + * 1. the timer counter underflows + */ + + if (jiffies_t == jiffies_p) { + if (count > count_p) { + if (ctrl_inb(MTU2_TSR_1) & MTU2_TSR_TGFA) { + count -= LATCH; + } else { + printk("%s (): hardware timer problem?\n", + __FUNCTION__); + } + } + } else + jiffies_p = jiffies_t; + + count_p = count; + spin_unlock_irqrestore(&mtu2_lock, flags); + + count = ((LATCH-1) - count) * TICK_SIZE; + count = (count + LATCH/2) / LATCH; + + return count; +} + +static irqreturn_t mtu2_timer_interrupt(int irq, void *dev_id, + struct pt_regs *regs) +{ + unsigned long timer_status; + + /* Clear TGFA bit */ + timer_status = ctrl_inb(MTU2_TSR_1); + timer_status &= ~MTU2_TSR_TGFA; + ctrl_outb(timer_status, MTU2_TSR_1); + + /* Do timer tick */ + write_seqlock(&xtime_lock); + handle_timer_tick(regs); + write_sequnlock(&xtime_lock); + + return IRQ_HANDLED; +} + +static struct irqaction mtu2_irq = { + .name = "timer", + .handler = mtu2_timer_interrupt, + .flags = SA_INTERRUPT, + .mask = CPU_MASK_NONE, +}; + +/* + * Hah! We'll see if this works (switching from usecs to nsecs). + */ +static unsigned long mtu2_timer_get_frequency(void) +{ + u32 freq; + struct timespec ts1, ts2; + unsigned long diff_nsec; + unsigned long factor; + + /* Setup the timer: We don't want to generate interrupts, just + * have it count down at its natural rate. + */ + + ctrl_outb(ctrl_inb(MTU2_TSTR) & ~MTU2_TSTR_CST1, MTU2_TSTR); + ctrl_outb(MTU2_TCR_CALIB, MTU2_TCR_1); + ctrl_outb(ctrl_inb(MTU2_TIER_1) & ~MTU2_TIER_TGIEA, MTU2_TIER_1); + ctrl_outw(0, MTU2_TCNT_1); + + rtc_get_time(&ts2); + + do { + rtc_get_time(&ts1); + } while (ts1.tv_nsec == ts2.tv_nsec && ts1.tv_sec == ts2.tv_sec); + + /* actually start the timer */ + ctrl_outw(ctrl_inw(CMT_CMSTR) | 0x01, CMT_CMSTR); + + do { + rtc_get_time(&ts2); + } while (ts1.tv_nsec == ts2.tv_nsec && ts1.tv_sec == ts2.tv_sec); + + freq = ctrl_inw(MTU2_TCNT_0); + if (ts2.tv_nsec < ts1.tv_nsec) { + ts2.tv_nsec += 1000000000; + ts2.tv_sec--; + } + + diff_nsec = (ts2.tv_sec - ts1.tv_sec) * 1000000000 + (ts2.tv_nsec - ts1.tv_nsec); + + /* this should work well if the RTC has a precision of n Hz, where + * n is an integer. I don't think we have to worry about the other + * cases. */ + factor = (1000000000 + diff_nsec/2) / diff_nsec; + + if (factor * diff_nsec > 1100000000 || + factor * diff_nsec < 900000000) + panic("weird RTC (diff_nsec %ld)", diff_nsec); + + return freq * factor; +} + +static unsigned int divisors[] = { 1, 4, 16, 64, 1, 1, 256 }; + +static void mtu2_clk_init(struct clk *clk) +{ + u8 idx = MTU2_TCR_INIT & 0x7; + + clk->rate = clk->parent->rate / divisors[idx]; + /* Start TCNT counting */ + ctrl_outb(ctrl_inb(MTU2_TSTR) | MTU2_TSTR_CST1, MTU2_TSTR); + +} + +static void mtu2_clk_recalc(struct clk *clk) +{ + u8 idx = ctrl_inb(MTU2_TCR_1) & 0x7; + clk->rate = clk->parent->rate / divisors[idx]; +} + +static struct clk_ops mtu2_clk_ops = { + .init = mtu2_clk_init, + .recalc = mtu2_clk_recalc, +}; + +static struct clk mtu2_clk1 = { + .name = "mtu2_clk1", + .ops = &mtu2_clk_ops, +}; + +static int mtu2_timer_start(void) +{ + ctrl_outb(ctrl_inb(MTU2_TSTR) | MTU2_TSTR_CST1, MTU2_TSTR); + return 0; +} + +static int mtu2_timer_stop(void) +{ + ctrl_outb(ctrl_inb(MTU2_TSTR) & ~MTU2_TSTR_CST1, MTU2_TSTR); + return 0; +} + +static int mtu2_timer_init(void) +{ + u8 tmp; + unsigned long interval; + + setup_irq(TIMER_IRQ, &mtu2_irq); + + mtu2_clk1.parent = clk_get("module_clk"); + + ctrl_outb(ctrl_inb(STBCR3) & (~0x20), STBCR3); + + /* Normal operation */ + ctrl_outb(0, MTU2_TMDR_1); + ctrl_outb(MTU2_TCR_INIT, MTU2_TCR_1); + ctrl_outb(0x01, MTU2_TIOR_1); + + /* Enable underflow interrupt */ + ctrl_outb(ctrl_inb(MTU2_TIER_1) | MTU2_TIER_TGIEA, MTU2_TIER_1); + + interval = CONFIG_SH_PCLK_FREQ / 16 / HZ; + printk(KERN_INFO "Interval = %ld\n", interval); + + ctrl_outw(interval, MTU2_TGRA_1); + ctrl_outw(0, MTU2_TCNT_1); + + clk_register(&mtu2_clk1); + clk_enable(&mtu2_clk1); + + return 0; +} + +struct sys_timer_ops mtu2_timer_ops = { + .init = mtu2_timer_init, + .start = mtu2_timer_start, + .stop = mtu2_timer_stop, + .get_frequency = mtu2_timer_get_frequency, + .get_offset = mtu2_timer_get_offset, +}; + +struct sys_timer mtu2_timer = { + .name = "mtu2", + .ops = &mtu2_timer_ops, +}; diff --git a/trunk/arch/sh/kernel/timers/timer.c b/trunk/arch/sh/kernel/timers/timer.c index dc1f631053a8..a6bcc913d25e 100644 --- a/trunk/arch/sh/kernel/timers/timer.c +++ b/trunk/arch/sh/kernel/timers/timer.c @@ -16,6 +16,12 @@ static struct sys_timer *sys_timers[] __initdata = { #ifdef CONFIG_SH_TMU &tmu_timer, +#endif +#ifdef CONFIG_SH_MTU2 + &mtu2_timer, +#endif +#ifdef CONFIG_SH_CMT + &cmt_timer, #endif NULL, }; diff --git a/trunk/arch/sh/mm/Kconfig b/trunk/arch/sh/mm/Kconfig index 9dd606464d23..814a17586974 100644 --- a/trunk/arch/sh/mm/Kconfig +++ b/trunk/arch/sh/mm/Kconfig @@ -4,8 +4,12 @@ menu "Processor selection" # Processor families # config CPU_SH2 + select SH_WRITETHROUGH if !CPU_SH2A bool - select SH_WRITETHROUGH + +config CPU_SH2A + bool + select CPU_SH2 config CPU_SH3 bool @@ -40,6 +44,16 @@ config CPU_SUBTYPE_SH7604 bool "Support SH7604 processor" select CPU_SH2 +config CPU_SUBTYPE_SH7619 + bool "Support SH7619 processor" + select CPU_SH2 + +comment "SH-2A Processor Support" + +config CPU_SUBTYPE_SH7206 + bool "Support SH7206 processor" + select CPU_SH2A + comment "SH-3 Processor Support" config CPU_SUBTYPE_SH7300 @@ -274,7 +288,6 @@ config SH_DIRECT_MAPPED config SH_WRITETHROUGH bool "Use write-through caching" - default y if CPU_SH2 help Selecting this option will configure the caches in write-through mode, as opposed to the default write-back configuration. diff --git a/trunk/arch/sh/mm/cache-sh2.c b/trunk/arch/sh/mm/cache-sh2.c index 2689cb24ea2b..6614033f6be9 100644 --- a/trunk/arch/sh/mm/cache-sh2.c +++ b/trunk/arch/sh/mm/cache-sh2.c @@ -5,6 +5,7 @@ * * Released under the terms of the GNU GPL v2.0. */ + #include #include @@ -14,37 +15,43 @@ #include #include -/* - * Calculate the OC address and set the way bit on the SH-2. - * - * We must have already jump_to_P2()'ed prior to calling this - * function, since we rely on CCR manipulation to do the - * Right Thing(tm). - */ -unsigned long __get_oc_addr(unsigned long set, unsigned long way) +void __flush_wback_region(void *start, int size) { - unsigned long ccr; - - /* - * On SH-2 the way bit isn't tracked in the address field - * if we're doing address array access .. instead, we need - * to manually switch out the way in the CCR. - */ - ccr = ctrl_inl(CCR); - ccr &= ~0x00c0; - ccr |= way << cpu_data->dcache.way_shift; - - /* - * Despite the number of sets being halved, we end up losing - * the first 2 ways to OCRAM instead of the last 2 (if we're - * 4-way). As a result, forcibly setting the W1 bit handily - * bumps us up 2 ways. - */ - if (ccr & CCR_CACHE_ORA) - ccr |= 1 << (cpu_data->dcache.way_shift + 1); - - ctrl_outl(ccr, CCR); - - return CACHE_OC_ADDRESS_ARRAY | (set << cpu_data->dcache.entry_shift); + unsigned long v; + unsigned long begin, end; + + begin = (unsigned long)start & ~(L1_CACHE_BYTES-1); + end = ((unsigned long)start + size + L1_CACHE_BYTES-1) + & ~(L1_CACHE_BYTES-1); + for (v = begin; v < end; v+=L1_CACHE_BYTES) { + /* FIXME cache purge */ + ctrl_outl((v & 0x1ffffc00), (v & 0x00000ff0) | 0x00000008); + } +} + +void __flush_purge_region(void *start, int size) +{ + unsigned long v; + unsigned long begin, end; + + begin = (unsigned long)start & ~(L1_CACHE_BYTES-1); + end = ((unsigned long)start + size + L1_CACHE_BYTES-1) + & ~(L1_CACHE_BYTES-1); + for (v = begin; v < end; v+=L1_CACHE_BYTES) { + ctrl_outl((v & 0x1ffffc00), (v & 0x00000ff0) | 0x00000008); + } +} + +void __flush_invalidate_region(void *start, int size) +{ + unsigned long v; + unsigned long begin, end; + + begin = (unsigned long)start & ~(L1_CACHE_BYTES-1); + end = ((unsigned long)start + size + L1_CACHE_BYTES-1) + & ~(L1_CACHE_BYTES-1); + for (v = begin; v < end; v+=L1_CACHE_BYTES) { + ctrl_outl((v & 0x1ffffc00), (v & 0x00000ff0) | 0x00000008); + } } diff --git a/trunk/arch/sh/tools/mach-types b/trunk/arch/sh/tools/mach-types index ac57638977ee..0571755e9a84 100644 --- a/trunk/arch/sh/tools/mach-types +++ b/trunk/arch/sh/tools/mach-types @@ -30,3 +30,5 @@ R7780MP SH_R7780MP TITAN SH_TITAN SHMIN SH_SHMIN 7710VOIPGW SH_7710VOIPGW +7206SE SH_7206_SOLUTION_ENGINE +7619SE SH_7619_SOLUTION_ENGINE diff --git a/trunk/arch/um/drivers/chan_kern.c b/trunk/arch/um/drivers/chan_kern.c index 7d4190e55654..3576b3cc505e 100644 --- a/trunk/arch/um/drivers/chan_kern.c +++ b/trunk/arch/um/drivers/chan_kern.c @@ -638,7 +638,7 @@ int chan_out_fd(struct list_head *chans) return -1; } -void chan_interrupt(struct list_head *chans, struct delayed_work *task, +void chan_interrupt(struct list_head *chans, struct work_struct *task, struct tty_struct *tty, int irq) { struct list_head *ele, *next; diff --git a/trunk/arch/um/drivers/mconsole_kern.c b/trunk/arch/um/drivers/mconsole_kern.c index 96f0189327af..7b172160fe04 100644 --- a/trunk/arch/um/drivers/mconsole_kern.c +++ b/trunk/arch/um/drivers/mconsole_kern.c @@ -56,7 +56,7 @@ static struct notifier_block reboot_notifier = { static LIST_HEAD(mc_requests); -static void mc_work_proc(struct work_struct *unused) +static void mc_work_proc(void *unused) { struct mconsole_entry *req; unsigned long flags; @@ -72,7 +72,7 @@ static void mc_work_proc(struct work_struct *unused) } } -static DECLARE_WORK(mconsole_work, mc_work_proc); +static DECLARE_WORK(mconsole_work, mc_work_proc, NULL); static irqreturn_t mconsole_interrupt(int irq, void *dev_id) { diff --git a/trunk/arch/um/drivers/net_kern.c b/trunk/arch/um/drivers/net_kern.c index 286bc0b3207f..ec9eb8bd9432 100644 --- a/trunk/arch/um/drivers/net_kern.c +++ b/trunk/arch/um/drivers/net_kern.c @@ -99,7 +99,6 @@ irqreturn_t uml_net_interrupt(int irq, void *dev_id) * same device, since it tests for (dev->flags & IFF_UP). So * there's no harm in delaying the device shutdown. */ schedule_work(&close_work); -#error this is not permitted - close_work will go out of scope goto out; } reactivate_fd(lp->fd, UM_ETH_IRQ); diff --git a/trunk/arch/um/drivers/port_kern.c b/trunk/arch/um/drivers/port_kern.c index 6dfe632f1c14..ce9f3733f73e 100644 --- a/trunk/arch/um/drivers/port_kern.c +++ b/trunk/arch/um/drivers/port_kern.c @@ -132,7 +132,7 @@ static int port_accept(struct port_list *port) DECLARE_MUTEX(ports_sem); struct list_head ports = LIST_HEAD_INIT(ports); -void port_work_proc(struct work_struct *unused) +void port_work_proc(void *unused) { struct port_list *port; struct list_head *ele; @@ -150,7 +150,7 @@ void port_work_proc(struct work_struct *unused) local_irq_restore(flags); } -DECLARE_WORK(port_work, port_work_proc); +DECLARE_WORK(port_work, port_work_proc, NULL); static irqreturn_t port_interrupt(int irq, void *data) { diff --git a/trunk/arch/x86_64/kernel/mce.c b/trunk/arch/x86_64/kernel/mce.c index c7587fc39015..bbea88801d88 100644 --- a/trunk/arch/x86_64/kernel/mce.c +++ b/trunk/arch/x86_64/kernel/mce.c @@ -306,8 +306,8 @@ void mce_log_therm_throt_event(unsigned int cpu, __u64 status) */ static int check_interval = 5 * 60; /* 5 minutes */ -static void mcheck_timer(struct work_struct *work); -static DECLARE_DELAYED_WORK(mcheck_work, mcheck_timer); +static void mcheck_timer(void *data); +static DECLARE_WORK(mcheck_work, mcheck_timer, NULL); static void mcheck_check_cpu(void *info) { @@ -315,7 +315,7 @@ static void mcheck_check_cpu(void *info) do_machine_check(NULL, 0); } -static void mcheck_timer(struct work_struct *work) +static void mcheck_timer(void *data) { on_each_cpu(mcheck_check_cpu, NULL, 1, 1); schedule_delayed_work(&mcheck_work, check_interval * HZ); diff --git a/trunk/arch/x86_64/kernel/smpboot.c b/trunk/arch/x86_64/kernel/smpboot.c index 9800147c4c68..62c2e747af58 100644 --- a/trunk/arch/x86_64/kernel/smpboot.c +++ b/trunk/arch/x86_64/kernel/smpboot.c @@ -753,16 +753,14 @@ static int __cpuinit wakeup_secondary_via_INIT(int phys_apicid, unsigned int sta } struct create_idle { - struct work_struct work; struct task_struct *idle; struct completion done; int cpu; }; -void do_fork_idle(struct work_struct *work) +void do_fork_idle(void *_c_idle) { - struct create_idle *c_idle = - container_of(work, struct create_idle, work); + struct create_idle *c_idle = _c_idle; c_idle->idle = fork_idle(c_idle->cpu); complete(&c_idle->done); @@ -777,10 +775,10 @@ static int __cpuinit do_boot_cpu(int cpu, int apicid) int timeout; unsigned long start_rip; struct create_idle c_idle = { - .work = __WORK_INITIALIZER(c_idle.work, do_fork_idle), .cpu = cpu, .done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done), }; + DECLARE_WORK(work, do_fork_idle, &c_idle); /* allocate memory for gdts of secondary cpus. Hotplug is considered */ if (!cpu_gdt_descr[cpu].address && @@ -827,9 +825,9 @@ static int __cpuinit do_boot_cpu(int cpu, int apicid) * thread. */ if (!keventd_up() || current_is_keventd()) - c_idle.work.func(&c_idle.work); + work.func(work.data); else { - schedule_work(&c_idle.work); + schedule_work(&work); wait_for_completion(&c_idle.done); } diff --git a/trunk/arch/x86_64/kernel/time.c b/trunk/arch/x86_64/kernel/time.c index 9f05bc9b2dad..e3ef544d2cfb 100644 --- a/trunk/arch/x86_64/kernel/time.c +++ b/trunk/arch/x86_64/kernel/time.c @@ -563,7 +563,7 @@ static unsigned int cpufreq_delayed_issched = 0; static unsigned int cpufreq_init = 0; static struct work_struct cpufreq_delayed_get_work; -static void handle_cpufreq_delayed_get(struct work_struct *v) +static void handle_cpufreq_delayed_get(void *v) { unsigned int cpu; for_each_online_cpu(cpu) { @@ -639,7 +639,7 @@ static struct notifier_block time_cpufreq_notifier_block = { static int __init cpufreq_tsc(void) { - INIT_WORK(&cpufreq_delayed_get_work, handle_cpufreq_delayed_get); + INIT_WORK(&cpufreq_delayed_get_work, handle_cpufreq_delayed_get, NULL); if (!cpufreq_register_notifier(&time_cpufreq_notifier_block, CPUFREQ_TRANSITION_NOTIFIER)) cpufreq_init = 1; diff --git a/trunk/block/as-iosched.c b/trunk/block/as-iosched.c index 5934c4bfd52a..00242111a457 100644 --- a/trunk/block/as-iosched.c +++ b/trunk/block/as-iosched.c @@ -1274,10 +1274,9 @@ static void as_merged_requests(request_queue_t *q, struct request *req, * * FIXME! dispatch queue is not a queue at all! */ -static void as_work_handler(struct work_struct *work) +static void as_work_handler(void *data) { - struct as_data *ad = container_of(work, struct as_data, antic_work); - struct request_queue *q = ad->q; + struct request_queue *q = data; unsigned long flags; spin_lock_irqsave(q->queue_lock, flags); @@ -1333,7 +1332,7 @@ static void *as_init_queue(request_queue_t *q) ad->antic_timer.function = as_antic_timeout; ad->antic_timer.data = (unsigned long)q; init_timer(&ad->antic_timer); - INIT_WORK(&ad->antic_work, as_work_handler); + INIT_WORK(&ad->antic_work, as_work_handler, q); INIT_LIST_HEAD(&ad->fifo_list[REQ_SYNC]); INIT_LIST_HEAD(&ad->fifo_list[REQ_ASYNC]); diff --git a/trunk/block/cfq-iosched.c b/trunk/block/cfq-iosched.c index 84e9be073180..e9019ed39b73 100644 --- a/trunk/block/cfq-iosched.c +++ b/trunk/block/cfq-iosched.c @@ -1840,11 +1840,9 @@ cfq_set_request(request_queue_t *q, struct request *rq, gfp_t gfp_mask) return 1; } -static void cfq_kick_queue(struct work_struct *work) +static void cfq_kick_queue(void *data) { - struct cfq_data *cfqd = - container_of(work, struct cfq_data, unplug_work); - request_queue_t *q = cfqd->queue; + request_queue_t *q = data; unsigned long flags; spin_lock_irqsave(q->queue_lock, flags); @@ -1988,7 +1986,7 @@ static void *cfq_init_queue(request_queue_t *q) cfqd->idle_class_timer.function = cfq_idle_class_timer; cfqd->idle_class_timer.data = (unsigned long) cfqd; - INIT_WORK(&cfqd->unplug_work, cfq_kick_queue); + INIT_WORK(&cfqd->unplug_work, cfq_kick_queue, q); cfqd->cfq_quantum = cfq_quantum; cfqd->cfq_fifo_expire[0] = cfq_fifo_expire[0]; diff --git a/trunk/block/ll_rw_blk.c b/trunk/block/ll_rw_blk.c index cc6e95f8e5d9..0f82e12f7b67 100644 --- a/trunk/block/ll_rw_blk.c +++ b/trunk/block/ll_rw_blk.c @@ -34,7 +34,7 @@ */ #include -static void blk_unplug_work(struct work_struct *work); +static void blk_unplug_work(void *data); static void blk_unplug_timeout(unsigned long data); static void drive_stat_acct(struct request *rq, int nr_sectors, int new_io); static void init_request_from_bio(struct request *req, struct bio *bio); @@ -227,7 +227,7 @@ void blk_queue_make_request(request_queue_t * q, make_request_fn * mfn) if (q->unplug_delay == 0) q->unplug_delay = 1; - INIT_WORK(&q->unplug_work, blk_unplug_work); + INIT_WORK(&q->unplug_work, blk_unplug_work, q); q->unplug_timer.function = blk_unplug_timeout; q->unplug_timer.data = (unsigned long)q; @@ -1631,9 +1631,9 @@ static void blk_backing_dev_unplug(struct backing_dev_info *bdi, } } -static void blk_unplug_work(struct work_struct *work) +static void blk_unplug_work(void *data) { - request_queue_t *q = container_of(work, request_queue_t, unplug_work); + request_queue_t *q = data; blk_add_trace_pdu_int(q, BLK_TA_UNPLUG_IO, NULL, q->rq.count[READ] + q->rq.count[WRITE]); diff --git a/trunk/block/scsi_ioctl.c b/trunk/block/scsi_ioctl.c index b3e210723a71..5493c2fbbab1 100644 --- a/trunk/block/scsi_ioctl.c +++ b/trunk/block/scsi_ioctl.c @@ -277,7 +277,7 @@ static int sg_io(struct file *file, request_queue_t *q, if (rq->bio) blk_queue_bounce(q, &rq->bio); - rq->timeout = jiffies_to_msecs(hdr->timeout); + rq->timeout = (hdr->timeout * HZ) / 1000; if (!rq->timeout) rq->timeout = q->sg_timeout; if (!rq->timeout) diff --git a/trunk/crypto/cryptomgr.c b/trunk/crypto/cryptomgr.c index 2ebffb84f1d9..9b5b15601068 100644 --- a/trunk/crypto/cryptomgr.c +++ b/trunk/crypto/cryptomgr.c @@ -40,10 +40,9 @@ struct cryptomgr_param { char template[CRYPTO_MAX_ALG_NAME]; }; -static void cryptomgr_probe(struct work_struct *work) +static void cryptomgr_probe(void *data) { - struct cryptomgr_param *param = - container_of(work, struct cryptomgr_param, work); + struct cryptomgr_param *param = data; struct crypto_template *tmpl; struct crypto_instance *inst; int err; @@ -113,7 +112,7 @@ static int cryptomgr_schedule_probe(struct crypto_larval *larval) param->larval.type = larval->alg.cra_flags; param->larval.mask = larval->mask; - INIT_WORK(¶m->work, cryptomgr_probe); + INIT_WORK(¶m->work, cryptomgr_probe, param); schedule_work(¶m->work); return NOTIFY_STOP; diff --git a/trunk/drivers/acpi/osl.c b/trunk/drivers/acpi/osl.c index 02b30ae6a68e..068fe4f100b0 100644 --- a/trunk/drivers/acpi/osl.c +++ b/trunk/drivers/acpi/osl.c @@ -50,7 +50,6 @@ ACPI_MODULE_NAME("osl") struct acpi_os_dpc { acpi_osd_exec_callback function; void *context; - struct work_struct work; }; #ifdef CONFIG_ACPI_CUSTOM_DSDT @@ -565,9 +564,12 @@ void acpi_os_derive_pci_id(acpi_handle rhandle, /* upper bound */ acpi_os_derive_pci_id_2(rhandle, chandle, id, &is_bridge, &bus_number); } -static void acpi_os_execute_deferred(struct work_struct *work) +static void acpi_os_execute_deferred(void *context) { - struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work); + struct acpi_os_dpc *dpc = NULL; + + + dpc = (struct acpi_os_dpc *)context; if (!dpc) { printk(KERN_ERR PREFIX "Invalid (NULL) context\n"); return; @@ -600,6 +602,7 @@ acpi_status acpi_os_execute(acpi_execute_type type, { acpi_status status = AE_OK; struct acpi_os_dpc *dpc; + struct work_struct *task; ACPI_FUNCTION_TRACE("os_queue_for_execution"); @@ -612,22 +615,28 @@ acpi_status acpi_os_execute(acpi_execute_type type, /* * Allocate/initialize DPC structure. Note that this memory will be - * freed by the callee. The kernel handles the work_struct list in a + * freed by the callee. The kernel handles the tq_struct list in a * way that allows us to also free its memory inside the callee. * Because we may want to schedule several tasks with different * parameters we can't use the approach some kernel code uses of - * having a static work_struct. + * having a static tq_struct. + * We can save time and code by allocating the DPC and tq_structs + * from the same memory. */ - dpc = kmalloc(sizeof(struct acpi_os_dpc), GFP_ATOMIC); + dpc = + kmalloc(sizeof(struct acpi_os_dpc) + sizeof(struct work_struct), + GFP_ATOMIC); if (!dpc) return_ACPI_STATUS(AE_NO_MEMORY); dpc->function = function; dpc->context = context; - INIT_WORK(&dpc->work, acpi_os_execute_deferred); - if (!queue_work(kacpid_wq, &dpc->work)) { + task = (void *)(dpc + 1); + INIT_WORK(task, acpi_os_execute_deferred, (void *)dpc); + + if (!queue_work(kacpid_wq, task)) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Call to queue_work() failed.\n")); kfree(dpc); diff --git a/trunk/drivers/ata/libata-core.c b/trunk/drivers/ata/libata-core.c index 8816e30fb7a4..f8ec3896b793 100644 --- a/trunk/drivers/ata/libata-core.c +++ b/trunk/drivers/ata/libata-core.c @@ -1081,7 +1081,7 @@ static unsigned int ata_id_xfermask(const u16 *id) * ata_port_queue_task - Queue port_task * @ap: The ata_port to queue port_task for * @fn: workqueue function to be scheduled - * @data: data for @fn to use + * @data: data value to pass to workqueue function * @delay: delay time for workqueue function * * Schedule @fn(@data) for execution after @delay jiffies using @@ -1096,7 +1096,7 @@ static unsigned int ata_id_xfermask(const u16 *id) * LOCKING: * Inherited from caller. */ -void ata_port_queue_task(struct ata_port *ap, work_func_t fn, void *data, +void ata_port_queue_task(struct ata_port *ap, void (*fn)(void *), void *data, unsigned long delay) { int rc; @@ -1104,10 +1104,12 @@ void ata_port_queue_task(struct ata_port *ap, work_func_t fn, void *data, if (ap->pflags & ATA_PFLAG_FLUSH_PORT_TASK) return; - PREPARE_DELAYED_WORK(&ap->port_task, fn); - ap->port_task_data = data; + PREPARE_WORK(&ap->port_task, fn, data); - rc = queue_delayed_work(ata_wq, &ap->port_task, delay); + if (!delay) + rc = queue_work(ata_wq, &ap->port_task); + else + rc = queue_delayed_work(ata_wq, &ap->port_task, delay); /* rc == 0 means that another user is using port task */ WARN_ON(rc == 0); @@ -4586,11 +4588,10 @@ int ata_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc, return poll_next; } -static void ata_pio_task(struct work_struct *work) +static void ata_pio_task(void *_data) { - struct ata_port *ap = - container_of(work, struct ata_port, port_task.work); - struct ata_queued_cmd *qc = ap->port_task_data; + struct ata_queued_cmd *qc = _data; + struct ata_port *ap = qc->ap; u8 status; int poll_next; @@ -5634,9 +5635,9 @@ void ata_port_init(struct ata_port *ap, struct ata_host *host, ap->msg_enable = ATA_MSG_DRV | ATA_MSG_ERR | ATA_MSG_WARN; #endif - INIT_DELAYED_WORK(&ap->port_task, NULL); - INIT_DELAYED_WORK(&ap->hotplug_task, ata_scsi_hotplug); - INIT_WORK(&ap->scsi_rescan_task, ata_scsi_dev_rescan); + INIT_WORK(&ap->port_task, NULL, NULL); + INIT_WORK(&ap->hotplug_task, ata_scsi_hotplug, ap); + INIT_WORK(&ap->scsi_rescan_task, ata_scsi_dev_rescan, ap); INIT_LIST_HEAD(&ap->eh_done_q); init_waitqueue_head(&ap->eh_wait_q); diff --git a/trunk/drivers/ata/libata-eh.c b/trunk/drivers/ata/libata-eh.c index 08ad44b3e48f..76a85dfb7307 100644 --- a/trunk/drivers/ata/libata-eh.c +++ b/trunk/drivers/ata/libata-eh.c @@ -332,7 +332,7 @@ void ata_scsi_error(struct Scsi_Host *host) if (ap->pflags & ATA_PFLAG_LOADING) ap->pflags &= ~ATA_PFLAG_LOADING; else if (ap->pflags & ATA_PFLAG_SCSI_HOTPLUG) - queue_delayed_work(ata_aux_wq, &ap->hotplug_task, 0); + queue_work(ata_aux_wq, &ap->hotplug_task); if (ap->pflags & ATA_PFLAG_RECOVERED) ata_port_printk(ap, KERN_INFO, "EH complete\n"); diff --git a/trunk/drivers/ata/libata-scsi.c b/trunk/drivers/ata/libata-scsi.c index 664e1377b54c..8eaace94d963 100644 --- a/trunk/drivers/ata/libata-scsi.c +++ b/trunk/drivers/ata/libata-scsi.c @@ -2963,7 +2963,7 @@ static void ata_scsi_remove_dev(struct ata_device *dev) /** * ata_scsi_hotplug - SCSI part of hotplug - * @work: Pointer to ATA port to perform SCSI hotplug on + * @data: Pointer to ATA port to perform SCSI hotplug on * * Perform SCSI part of hotplug. It's executed from a separate * workqueue after EH completes. This is necessary because SCSI @@ -2973,10 +2973,9 @@ static void ata_scsi_remove_dev(struct ata_device *dev) * LOCKING: * Kernel thread context (may sleep). */ -void ata_scsi_hotplug(struct work_struct *work) +void ata_scsi_hotplug(void *data) { - struct ata_port *ap = - container_of(work, struct ata_port, hotplug_task.work); + struct ata_port *ap = data; int i; if (ap->pflags & ATA_PFLAG_UNLOADING) { @@ -3077,7 +3076,7 @@ static int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel, /** * ata_scsi_dev_rescan - initiate scsi_rescan_device() - * @work: Pointer to ATA port to perform scsi_rescan_device() + * @data: Pointer to ATA port to perform scsi_rescan_device() * * After ATA pass thru (SAT) commands are executed successfully, * libata need to propagate the changes to SCSI layer. This @@ -3087,10 +3086,9 @@ static int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel, * LOCKING: * Kernel thread context (may sleep). */ -void ata_scsi_dev_rescan(struct work_struct *work) +void ata_scsi_dev_rescan(void *data) { - struct ata_port *ap = - container_of(work, struct ata_port, scsi_rescan_task); + struct ata_port *ap = data; unsigned long flags; unsigned int i; diff --git a/trunk/drivers/ata/libata.h b/trunk/drivers/ata/libata.h index 81ae41d5f23f..107b2b565229 100644 --- a/trunk/drivers/ata/libata.h +++ b/trunk/drivers/ata/libata.h @@ -94,7 +94,7 @@ extern struct scsi_transport_template ata_scsi_transport_template; extern void ata_scsi_scan_host(struct ata_port *ap); extern int ata_scsi_offline_dev(struct ata_device *dev); -extern void ata_scsi_hotplug(struct work_struct *work); +extern void ata_scsi_hotplug(void *data); extern unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf, unsigned int buflen); @@ -124,7 +124,7 @@ extern void ata_scsi_rbuf_fill(struct ata_scsi_args *args, unsigned int (*actor) (struct ata_scsi_args *args, u8 *rbuf, unsigned int buflen)); extern void ata_schedule_scsi_eh(struct Scsi_Host *shost); -extern void ata_scsi_dev_rescan(struct work_struct *work); +extern void ata_scsi_dev_rescan(void *data); extern int ata_bus_probe(struct ata_port *ap); /* libata-eh.c */ diff --git a/trunk/drivers/ata/pata_pcmcia.c b/trunk/drivers/ata/pata_pcmcia.c index 9ed7f58424a3..4ca6fa5dcb42 100644 --- a/trunk/drivers/ata/pata_pcmcia.c +++ b/trunk/drivers/ata/pata_pcmcia.c @@ -154,12 +154,19 @@ static int pcmcia_init_one(struct pcmcia_device *pdev) tuple.TupleOffset = 0; tuple.TupleDataMax = 255; tuple.Attributes = 0; + tuple.DesiredTuple = CISTPL_CONFIG; + + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(pdev, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(pdev, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(pdev, &tuple, &stk->parse)); + pdev->conf.ConfigBase = stk->parse.config.base; + pdev->conf.Present = stk->parse.config.rmask[0]; /* See if we have a manufacturer identifier. Use it to set is_kme for vendor quirks */ - is_kme = ((pdev->manf_id == MANFID_KME) && - ((pdev->card_id == PRODID_KME_KXLC005_A) || - (pdev->card_id == PRODID_KME_KXLC005_B))); + tuple.DesiredTuple = CISTPL_MANFID; + if (!pcmcia_get_first_tuple(pdev, &tuple) && !pcmcia_get_tuple_data(pdev, &tuple) && !pcmcia_parse_tuple(pdev, &tuple, &stk->parse)) + is_kme = ((stk->parse.manfid.manf == MANFID_KME) && ((stk->parse.manfid.card == PRODID_KME_KXLC005_A) || (stk->parse.manfid.card == PRODID_KME_KXLC005_B))); /* Not sure if this is right... look up the current Vcc */ CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(pdev, &stk->conf)); @@ -349,10 +356,8 @@ static struct pcmcia_device_id pcmcia_devices[] = { PCMCIA_DEVICE_PROD_ID12("SMI VENDOR", "SMI PRODUCT", 0x30896c92, 0x703cc5f6), PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003), PCMCIA_DEVICE_PROD_ID1("TRANSCEND 512M ", 0xd0909443), - PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS1GCF80", 0x709b1bf1, 0x2a54d4b1), PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF120", 0x709b1bf1, 0xf54a91c8), PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852), - PCMCIA_DEVICE_PROD_ID12("WEIDA", "TWTTI", 0xcc7cf69c, 0x212bb918), PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209), PCMCIA_DEVICE_PROD_ID12("STI", "Flash 5.0", 0xbf2df18d, 0x8cb57a0e), PCMCIA_MFC_DEVICE_PROD_ID12(1, "SanDisk", "ConnectPlus", 0x7a954bd9, 0x74be00c6), diff --git a/trunk/drivers/atm/idt77252.c b/trunk/drivers/atm/idt77252.c index f40786121948..87b17c33b3f9 100644 --- a/trunk/drivers/atm/idt77252.c +++ b/trunk/drivers/atm/idt77252.c @@ -135,7 +135,7 @@ static int idt77252_change_qos(struct atm_vcc *vcc, struct atm_qos *qos, int flags); static int idt77252_proc_read(struct atm_dev *dev, loff_t * pos, char *page); -static void idt77252_softint(struct work_struct *work); +static void idt77252_softint(void *dev_id); static struct atmdev_ops idt77252_ops = @@ -2866,10 +2866,9 @@ idt77252_interrupt(int irq, void *dev_id) } static void -idt77252_softint(struct work_struct *work) +idt77252_softint(void *dev_id) { - struct idt77252_dev *card = - container_of(work, struct idt77252_dev, tqueue); + struct idt77252_dev *card = dev_id; u32 stat; int done; @@ -3698,7 +3697,7 @@ idt77252_init_one(struct pci_dev *pcidev, const struct pci_device_id *id) card->pcidev = pcidev; sprintf(card->name, "idt77252-%d", card->index); - INIT_WORK(&card->tqueue, idt77252_softint); + INIT_WORK(&card->tqueue, idt77252_softint, (void *)card); membase = pci_resource_start(pcidev, 1); srambase = pci_resource_start(pcidev, 2); diff --git a/trunk/drivers/block/aoe/aoe.h b/trunk/drivers/block/aoe/aoe.h index 2308e83e5f33..6d111228cfac 100644 --- a/trunk/drivers/block/aoe/aoe.h +++ b/trunk/drivers/block/aoe/aoe.h @@ -159,7 +159,7 @@ void aoecmd_work(struct aoedev *d); void aoecmd_cfg(ushort aoemajor, unsigned char aoeminor); void aoecmd_ata_rsp(struct sk_buff *); void aoecmd_cfg_rsp(struct sk_buff *); -void aoecmd_sleepwork(struct work_struct *); +void aoecmd_sleepwork(void *vp); struct sk_buff *new_skb(ulong); int aoedev_init(void); diff --git a/trunk/drivers/block/aoe/aoecmd.c b/trunk/drivers/block/aoe/aoecmd.c index 97f7f535f412..8a13b1af8bab 100644 --- a/trunk/drivers/block/aoe/aoecmd.c +++ b/trunk/drivers/block/aoe/aoecmd.c @@ -408,9 +408,9 @@ rexmit_timer(ulong vp) /* this function performs work that has been deferred until sleeping is OK */ void -aoecmd_sleepwork(struct work_struct *work) +aoecmd_sleepwork(void *vp) { - struct aoedev *d = container_of(work, struct aoedev, work); + struct aoedev *d = (struct aoedev *) vp; if (d->flags & DEVFL_GDALLOC) aoeblk_gdalloc(d); diff --git a/trunk/drivers/block/aoe/aoedev.c b/trunk/drivers/block/aoe/aoedev.c index 05a97197c918..6125921bbec4 100644 --- a/trunk/drivers/block/aoe/aoedev.c +++ b/trunk/drivers/block/aoe/aoedev.c @@ -88,7 +88,7 @@ aoedev_newdev(ulong nframes) kfree(d); return NULL; } - INIT_WORK(&d->work, aoecmd_sleepwork); + INIT_WORK(&d->work, aoecmd_sleepwork, d); spin_lock_init(&d->lock); init_timer(&d->timer); d->timer.data = (ulong) d; diff --git a/trunk/drivers/block/floppy.c b/trunk/drivers/block/floppy.c index 3f1b38276e96..9e6d3a87cbe3 100644 --- a/trunk/drivers/block/floppy.c +++ b/trunk/drivers/block/floppy.c @@ -992,11 +992,11 @@ static void empty(void) { } -static DECLARE_WORK(floppy_work, NULL); +static DECLARE_WORK(floppy_work, NULL, NULL); static void schedule_bh(void (*handler) (void)) { - PREPARE_WORK(&floppy_work, (work_func_t)handler); + PREPARE_WORK(&floppy_work, (void (*)(void *))handler, NULL); schedule_work(&floppy_work); } @@ -1008,7 +1008,7 @@ static void cancel_activity(void) spin_lock_irqsave(&floppy_lock, flags); do_floppy = NULL; - PREPARE_WORK(&floppy_work, (work_func_t)empty); + PREPARE_WORK(&floppy_work, (void *)empty, NULL); del_timer(&fd_timer); spin_unlock_irqrestore(&floppy_lock, flags); } @@ -1868,7 +1868,7 @@ static void show_floppy(void) printk("fdc_busy=%lu\n", fdc_busy); if (do_floppy) printk("do_floppy=%p\n", do_floppy); - if (work_pending(&floppy_work)) + if (floppy_work.pending) printk("floppy_work.func=%p\n", floppy_work.func); if (timer_pending(&fd_timer)) printk("fd_timer.function=%p\n", fd_timer.function); @@ -4498,7 +4498,7 @@ static void floppy_release_irq_and_dma(void) printk("floppy timer still active:%s\n", timeout_message); if (timer_pending(&fd_timer)) printk("auxiliary floppy timer still active\n"); - if (work_pending(&floppy_work)) + if (floppy_work.pending) printk("work still pending\n"); #endif old_fdc = fdc; diff --git a/trunk/drivers/block/paride/pd.c b/trunk/drivers/block/paride/pd.c index 9d9bff23f426..40a11e567970 100644 --- a/trunk/drivers/block/paride/pd.c +++ b/trunk/drivers/block/paride/pd.c @@ -352,19 +352,19 @@ static enum action (*phase)(void); static void run_fsm(void); -static void ps_tq_int(struct work_struct *work); +static void ps_tq_int( void *data); -static DECLARE_DELAYED_WORK(fsm_tq, ps_tq_int); +static DECLARE_WORK(fsm_tq, ps_tq_int, NULL); static void schedule_fsm(void) { if (!nice) - schedule_delayed_work(&fsm_tq, 0); + schedule_work(&fsm_tq); else schedule_delayed_work(&fsm_tq, nice-1); } -static void ps_tq_int(struct work_struct *work) +static void ps_tq_int(void *data) { run_fsm(); } diff --git a/trunk/drivers/block/paride/pseudo.h b/trunk/drivers/block/paride/pseudo.h index bc3703294143..932342d7a8eb 100644 --- a/trunk/drivers/block/paride/pseudo.h +++ b/trunk/drivers/block/paride/pseudo.h @@ -35,7 +35,7 @@ #include #include -static void ps_tq_int(struct work_struct *work); +static void ps_tq_int( void *data); static void (* ps_continuation)(void); static int (* ps_ready)(void); @@ -45,7 +45,7 @@ static int ps_nice = 0; static DEFINE_SPINLOCK(ps_spinlock __attribute__((unused))); -static DECLARE_DELAYED_WORK(ps_tq, ps_tq_int); +static DECLARE_WORK(ps_tq, ps_tq_int, NULL); static void ps_set_intr(void (*continuation)(void), int (*ready)(void), @@ -63,14 +63,14 @@ static void ps_set_intr(void (*continuation)(void), if (!ps_tq_active) { ps_tq_active = 1; if (!ps_nice) - schedule_delayed_work(&ps_tq, 0); + schedule_work(&ps_tq); else schedule_delayed_work(&ps_tq, ps_nice-1); } spin_unlock_irqrestore(&ps_spinlock,flags); } -static void ps_tq_int(struct work_struct *work) +static void ps_tq_int(void *data) { void (*con)(void); unsigned long flags; @@ -92,7 +92,7 @@ static void ps_tq_int(struct work_struct *work) } ps_tq_active = 1; if (!ps_nice) - schedule_delayed_work(&ps_tq, 0); + schedule_work(&ps_tq); else schedule_delayed_work(&ps_tq, ps_nice-1); spin_unlock_irqrestore(&ps_spinlock,flags); diff --git a/trunk/drivers/block/sx8.c b/trunk/drivers/block/sx8.c index 54509eb3391b..47d6975268ff 100644 --- a/trunk/drivers/block/sx8.c +++ b/trunk/drivers/block/sx8.c @@ -1244,10 +1244,9 @@ static irqreturn_t carm_interrupt(int irq, void *__host) return IRQ_RETVAL(handled); } -static void carm_fsm_task (struct work_struct *work) +static void carm_fsm_task (void *_data) { - struct carm_host *host = - container_of(work, struct carm_host, fsm_task); + struct carm_host *host = _data; unsigned long flags; unsigned int state; int rc, i, next_dev; @@ -1620,7 +1619,7 @@ static int carm_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) host->pdev = pdev; host->flags = pci_dac ? FL_DAC : 0; spin_lock_init(&host->lock); - INIT_WORK(&host->fsm_task, carm_fsm_task); + INIT_WORK(&host->fsm_task, carm_fsm_task, host); init_completion(&host->probe_comp); for (i = 0; i < ARRAY_SIZE(host->req); i++) diff --git a/trunk/drivers/block/ub.c b/trunk/drivers/block/ub.c index 2098eff91e14..0d5c73f07265 100644 --- a/trunk/drivers/block/ub.c +++ b/trunk/drivers/block/ub.c @@ -376,7 +376,7 @@ static int ub_submit_clear_stall(struct ub_dev *sc, struct ub_scsi_cmd *cmd, int stalled_pipe); static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd); static void ub_reset_enter(struct ub_dev *sc, int try); -static void ub_reset_task(struct work_struct *work); +static void ub_reset_task(void *arg); static int ub_sync_tur(struct ub_dev *sc, struct ub_lun *lun); static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun, struct ub_capacity *ret); @@ -1558,9 +1558,9 @@ static void ub_reset_enter(struct ub_dev *sc, int try) schedule_work(&sc->reset_work); } -static void ub_reset_task(struct work_struct *work) +static void ub_reset_task(void *arg) { - struct ub_dev *sc = container_of(work, struct ub_dev, reset_work); + struct ub_dev *sc = arg; unsigned long flags; struct list_head *p; struct ub_lun *lun; @@ -2179,7 +2179,7 @@ static int ub_probe(struct usb_interface *intf, usb_init_urb(&sc->work_urb); tasklet_init(&sc->tasklet, ub_scsi_action, (unsigned long)sc); atomic_set(&sc->poison, 0); - INIT_WORK(&sc->reset_work, ub_reset_task); + INIT_WORK(&sc->reset_work, ub_reset_task, sc); init_waitqueue_head(&sc->reset_wait); init_timer(&sc->work_timer); diff --git a/trunk/drivers/bluetooth/bcm203x.c b/trunk/drivers/bluetooth/bcm203x.c index 9256985cbe36..516751754aa9 100644 --- a/trunk/drivers/bluetooth/bcm203x.c +++ b/trunk/drivers/bluetooth/bcm203x.c @@ -157,10 +157,9 @@ static void bcm203x_complete(struct urb *urb) } } -static void bcm203x_work(struct work_struct *work) +static void bcm203x_work(void *user_data) { - struct bcm203x_data *data = - container_of(work, struct bcm203x_data, work); + struct bcm203x_data *data = user_data; if (usb_submit_urb(data->urb, GFP_ATOMIC) < 0) BT_ERR("Can't submit URB"); @@ -247,7 +246,7 @@ static int bcm203x_probe(struct usb_interface *intf, const struct usb_device_id release_firmware(firmware); - INIT_WORK(&data->work, bcm203x_work); + INIT_WORK(&data->work, bcm203x_work, (void *) data); usb_set_intfdata(intf, data); diff --git a/trunk/drivers/bluetooth/bluecard_cs.c b/trunk/drivers/bluetooth/bluecard_cs.c index acfb6a430dcc..cbc07250b898 100644 --- a/trunk/drivers/bluetooth/bluecard_cs.c +++ b/trunk/drivers/bluetooth/bluecard_cs.c @@ -892,10 +892,43 @@ static void bluecard_detach(struct pcmcia_device *link) } +static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) +{ + int i; + + i = pcmcia_get_first_tuple(handle, tuple); + if (i != CS_SUCCESS) + return CS_NO_MORE_ITEMS; + + i = pcmcia_get_tuple_data(handle, tuple); + if (i != CS_SUCCESS) + return i; + + return pcmcia_parse_tuple(handle, tuple, parse); +} + static int bluecard_config(struct pcmcia_device *link) { bluecard_info_t *info = link->priv; - int i, n; + tuple_t tuple; + u_short buf[256]; + cisparse_t parse; + int i, n, last_ret, last_fn; + + tuple.TupleData = (cisdata_t *)buf; + tuple.TupleOffset = 0; + tuple.TupleDataMax = 255; + tuple.Attributes = 0; + + /* Get configuration register information */ + tuple.DesiredTuple = CISTPL_CONFIG; + last_ret = first_tuple(link, &tuple, &parse); + if (last_ret != CS_SUCCESS) { + last_fn = ParseTuple; + goto cs_failed; + } + link->conf.ConfigBase = parse.config.base; + link->conf.Present = parse.config.rmask[0]; link->conf.ConfigIndex = 0x20; link->io.NumPorts1 = 64; @@ -933,6 +966,9 @@ static int bluecard_config(struct pcmcia_device *link) return 0; +cs_failed: + cs_error(link, last_fn, last_ret); + failed: bluecard_release(link); return -ENODEV; diff --git a/trunk/drivers/bluetooth/bt3c_cs.c b/trunk/drivers/bluetooth/bt3c_cs.c index aae3abace586..3a96a0babc6a 100644 --- a/trunk/drivers/bluetooth/bt3c_cs.c +++ b/trunk/drivers/bluetooth/bt3c_cs.c @@ -713,7 +713,22 @@ static int bt3c_config(struct pcmcia_device *link) u_short buf[256]; cisparse_t parse; cistpl_cftable_entry_t *cf = &parse.cftable_entry; - int i, j, try; + int i, j, try, last_ret, last_fn; + + tuple.TupleData = (cisdata_t *)buf; + tuple.TupleOffset = 0; + tuple.TupleDataMax = 255; + tuple.Attributes = 0; + + /* Get configuration register information */ + tuple.DesiredTuple = CISTPL_CONFIG; + last_ret = first_tuple(link, &tuple, &parse); + if (last_ret != CS_SUCCESS) { + last_fn = ParseTuple; + goto cs_failed; + } + link->conf.ConfigBase = parse.config.base; + link->conf.Present = parse.config.rmask[0]; /* First pass: look for a config entry that looks normal. */ tuple.TupleData = (cisdata_t *)buf; @@ -787,6 +802,9 @@ static int bt3c_config(struct pcmcia_device *link) return 0; +cs_failed: + cs_error(link, last_fn, last_ret); + failed: bt3c_release(link); return -ENODEV; diff --git a/trunk/drivers/bluetooth/btuart_cs.c b/trunk/drivers/bluetooth/btuart_cs.c index 92648ef2f5d0..3b29086b7c3f 100644 --- a/trunk/drivers/bluetooth/btuart_cs.c +++ b/trunk/drivers/bluetooth/btuart_cs.c @@ -644,7 +644,22 @@ static int btuart_config(struct pcmcia_device *link) u_short buf[256]; cisparse_t parse; cistpl_cftable_entry_t *cf = &parse.cftable_entry; - int i, j, try; + int i, j, try, last_ret, last_fn; + + tuple.TupleData = (cisdata_t *)buf; + tuple.TupleOffset = 0; + tuple.TupleDataMax = 255; + tuple.Attributes = 0; + + /* Get configuration register information */ + tuple.DesiredTuple = CISTPL_CONFIG; + last_ret = first_tuple(link, &tuple, &parse); + if (last_ret != CS_SUCCESS) { + last_fn = ParseTuple; + goto cs_failed; + } + link->conf.ConfigBase = parse.config.base; + link->conf.Present = parse.config.rmask[0]; /* First pass: look for a config entry that looks normal. */ tuple.TupleData = (cisdata_t *) buf; @@ -719,6 +734,9 @@ static int btuart_config(struct pcmcia_device *link) return 0; +cs_failed: + cs_error(link, last_fn, last_ret); + failed: btuart_release(link); return -ENODEV; diff --git a/trunk/drivers/bluetooth/dtl1_cs.c b/trunk/drivers/bluetooth/dtl1_cs.c index 77b99eecbc49..07eafbc5dc3a 100644 --- a/trunk/drivers/bluetooth/dtl1_cs.c +++ b/trunk/drivers/bluetooth/dtl1_cs.c @@ -626,7 +626,22 @@ static int dtl1_config(struct pcmcia_device *link) u_short buf[256]; cisparse_t parse; cistpl_cftable_entry_t *cf = &parse.cftable_entry; - int i; + int i, last_ret, last_fn; + + tuple.TupleData = (cisdata_t *)buf; + tuple.TupleOffset = 0; + tuple.TupleDataMax = 255; + tuple.Attributes = 0; + + /* Get configuration register information */ + tuple.DesiredTuple = CISTPL_CONFIG; + last_ret = first_tuple(link, &tuple, &parse); + if (last_ret != CS_SUCCESS) { + last_fn = ParseTuple; + goto cs_failed; + } + link->conf.ConfigBase = parse.config.base; + link->conf.Present = parse.config.rmask[0]; tuple.TupleData = (cisdata_t *)buf; tuple.TupleOffset = 0; @@ -675,6 +690,9 @@ static int dtl1_config(struct pcmcia_device *link) return 0; +cs_failed: + cs_error(link, last_fn, last_ret); + failed: dtl1_release(link); return -ENODEV; diff --git a/trunk/drivers/char/cyclades.c b/trunk/drivers/char/cyclades.c index acb2de5e3a98..e608dadece2f 100644 --- a/trunk/drivers/char/cyclades.c +++ b/trunk/drivers/char/cyclades.c @@ -926,10 +926,9 @@ cy_sched_event(struct cyclades_port *info, int event) * had to poll every port to see if that port needed servicing. */ static void -do_softint(struct work_struct *work) +do_softint(void *private_) { - struct cyclades_port *info = - container_of(work, struct cyclades_port, tqueue); + struct cyclades_port *info = (struct cyclades_port *) private_; struct tty_struct *tty; tty = info->tty; @@ -5329,7 +5328,7 @@ cy_init(void) info->blocked_open = 0; info->default_threshold = 0; info->default_timeout = 0; - INIT_WORK(&info->tqueue, do_softint); + INIT_WORK(&info->tqueue, do_softint, info); init_waitqueue_head(&info->open_wait); init_waitqueue_head(&info->close_wait); init_waitqueue_head(&info->shutdown_wait); @@ -5404,7 +5403,7 @@ cy_init(void) info->blocked_open = 0; info->default_threshold = 0; info->default_timeout = 0; - INIT_WORK(&info->tqueue, do_softint); + INIT_WORK(&info->tqueue, do_softint, info); init_waitqueue_head(&info->open_wait); init_waitqueue_head(&info->close_wait); init_waitqueue_head(&info->shutdown_wait); diff --git a/trunk/drivers/char/drm/via_dmablit.c b/trunk/drivers/char/drm/via_dmablit.c index 806f9ce5f47b..60c1695db300 100644 --- a/trunk/drivers/char/drm/via_dmablit.c +++ b/trunk/drivers/char/drm/via_dmablit.c @@ -500,9 +500,9 @@ via_dmablit_timer(unsigned long data) static void -via_dmablit_workqueue(struct work_struct *work) +via_dmablit_workqueue(void *data) { - drm_via_blitq_t *blitq = container_of(work, drm_via_blitq_t, wq); + drm_via_blitq_t *blitq = (drm_via_blitq_t *) data; drm_device_t *dev = blitq->dev; unsigned long irqsave; drm_via_sg_info_t *cur_sg; @@ -571,7 +571,7 @@ via_init_dmablit(drm_device_t *dev) DRM_INIT_WAITQUEUE(blitq->blit_queue + j); } DRM_INIT_WAITQUEUE(&blitq->busy_queue); - INIT_WORK(&blitq->wq, via_dmablit_workqueue); + INIT_WORK(&blitq->wq, via_dmablit_workqueue, blitq); init_timer(&blitq->poll_timer); blitq->poll_timer.function = &via_dmablit_timer; blitq->poll_timer.data = (unsigned long) blitq; diff --git a/trunk/drivers/char/epca.c b/trunk/drivers/char/epca.c index 7c71eb779802..706733c0b36a 100644 --- a/trunk/drivers/char/epca.c +++ b/trunk/drivers/char/epca.c @@ -200,7 +200,7 @@ static int pc_ioctl(struct tty_struct *, struct file *, static int info_ioctl(struct tty_struct *, struct file *, unsigned int, unsigned long); static void pc_set_termios(struct tty_struct *, struct termios *); -static void do_softint(struct work_struct *work); +static void do_softint(void *); static void pc_stop(struct tty_struct *); static void pc_start(struct tty_struct *); static void pc_throttle(struct tty_struct * tty); @@ -1505,7 +1505,7 @@ static void post_fep_init(unsigned int crd) ch->brdchan = bc; ch->mailbox = gd; - INIT_WORK(&ch->tqueue, do_softint); + INIT_WORK(&ch->tqueue, do_softint, ch); ch->board = &boards[crd]; spin_lock_irqsave(&epca_lock, flags); @@ -2566,9 +2566,9 @@ static void pc_set_termios(struct tty_struct *tty, struct termios *old_termios) /* --------------------- Begin do_softint ----------------------- */ -static void do_softint(struct work_struct *work) +static void do_softint(void *private_) { /* Begin do_softint */ - struct channel *ch = container_of(work, struct channel, tqueue); + struct channel *ch = (struct channel *) private_; /* Called in response to a modem change event */ if (ch && ch->magic == EPCA_MAGIC) { /* Begin EPCA_MAGIC */ struct tty_struct *tty = ch->tty; diff --git a/trunk/drivers/char/esp.c b/trunk/drivers/char/esp.c index 93b551962513..15a4ea896328 100644 --- a/trunk/drivers/char/esp.c +++ b/trunk/drivers/char/esp.c @@ -723,10 +723,9 @@ static irqreturn_t rs_interrupt_single(int irq, void *dev_id) * ------------------------------------------------------------------- */ -static void do_softint(struct work_struct *work) +static void do_softint(void *private_) { - struct esp_struct *info = - container_of(work, struct esp_struct, tqueue); + struct esp_struct *info = (struct esp_struct *) private_; struct tty_struct *tty; tty = info->tty; @@ -747,10 +746,9 @@ static void do_softint(struct work_struct *work) * do_serial_hangup() -> tty->hangup() -> esp_hangup() * */ -static void do_serial_hangup(struct work_struct *work) +static void do_serial_hangup(void *private_) { - struct esp_struct *info = - container_of(work, struct esp_struct, tqueue_hangup); + struct esp_struct *info = (struct esp_struct *) private_; struct tty_struct *tty; tty = info->tty; @@ -2503,8 +2501,8 @@ static int __init espserial_init(void) info->magic = ESP_MAGIC; info->close_delay = 5*HZ/10; info->closing_wait = 30*HZ; - INIT_WORK(&info->tqueue, do_softint); - INIT_WORK(&info->tqueue_hangup, do_serial_hangup); + INIT_WORK(&info->tqueue, do_softint, info); + INIT_WORK(&info->tqueue_hangup, do_serial_hangup, info); info->config.rx_timeout = rx_timeout; info->config.flow_on = flow_on; info->config.flow_off = flow_off; diff --git a/trunk/drivers/char/genrtc.c b/trunk/drivers/char/genrtc.c index 23b25ada65ea..817dc409ac20 100644 --- a/trunk/drivers/char/genrtc.c +++ b/trunk/drivers/char/genrtc.c @@ -102,7 +102,7 @@ static void gen_rtc_interrupt(unsigned long arg); * Routine to poll RTC seconds field for change as often as possible, * after first RTC_UIE use timer to reduce polling */ -static void genrtc_troutine(struct work_struct *work) +static void genrtc_troutine(void *data) { unsigned int tmp = get_rtc_ss(); @@ -255,7 +255,7 @@ static inline int gen_set_rtc_irq_bit(unsigned char bit) irq_active = 1; stop_rtc_timers = 0; lostint = 0; - INIT_WORK(&genrtc_task, genrtc_troutine); + INIT_WORK(&genrtc_task, genrtc_troutine, NULL); oldsecs = get_rtc_ss(); init_timer(&timer_task); diff --git a/trunk/drivers/char/hvsi.c b/trunk/drivers/char/hvsi.c index 82a41d5b4ed0..2cf63e7305a3 100644 --- a/trunk/drivers/char/hvsi.c +++ b/trunk/drivers/char/hvsi.c @@ -69,7 +69,7 @@ #define __ALIGNED__ __attribute__((__aligned__(sizeof(long)))) struct hvsi_struct { - struct delayed_work writer; + struct work_struct writer; struct work_struct handshaker; wait_queue_head_t emptyq; /* woken when outbuf is emptied */ wait_queue_head_t stateq; /* woken when HVSI state changes */ @@ -744,10 +744,9 @@ static int hvsi_handshake(struct hvsi_struct *hp) return 0; } -static void hvsi_handshaker(struct work_struct *work) +static void hvsi_handshaker(void *arg) { - struct hvsi_struct *hp = - container_of(work, struct hvsi_struct, handshaker); + struct hvsi_struct *hp = (struct hvsi_struct *)arg; if (hvsi_handshake(hp) >= 0) return; @@ -952,10 +951,9 @@ static void hvsi_push(struct hvsi_struct *hp) } /* hvsi_write_worker will keep rescheduling itself until outbuf is empty */ -static void hvsi_write_worker(struct work_struct *work) +static void hvsi_write_worker(void *arg) { - struct hvsi_struct *hp = - container_of(work, struct hvsi_struct, writer.work); + struct hvsi_struct *hp = (struct hvsi_struct *)arg; unsigned long flags; #ifdef DEBUG static long start_j = 0; @@ -1289,8 +1287,8 @@ static int __init hvsi_console_init(void) } hp = &hvsi_ports[hvsi_count]; - INIT_DELAYED_WORK(&hp->writer, hvsi_write_worker); - INIT_WORK(&hp->handshaker, hvsi_handshaker); + INIT_WORK(&hp->writer, hvsi_write_worker, hp); + INIT_WORK(&hp->handshaker, hvsi_handshaker, hp); init_waitqueue_head(&hp->emptyq); init_waitqueue_head(&hp->stateq); spin_lock_init(&hp->lock); diff --git a/trunk/drivers/char/ip2/i2lib.c b/trunk/drivers/char/ip2/i2lib.c index c213fdbdb2b0..54d93f0345e8 100644 --- a/trunk/drivers/char/ip2/i2lib.c +++ b/trunk/drivers/char/ip2/i2lib.c @@ -84,8 +84,8 @@ static void iiSendPendingMail(i2eBordStrPtr); static void serviceOutgoingFifo(i2eBordStrPtr); // Functions defined in ip2.c as part of interrupt handling -static void do_input(struct work_struct *); -static void do_status(struct work_struct *); +static void do_input(void *); +static void do_status(void *); //*************** //* Debug Data * @@ -331,8 +331,8 @@ i2InitChannels ( i2eBordStrPtr pB, int nChannels, i2ChanStrPtr pCh) pCh->ClosingWaitTime = 30*HZ; // Initialize task queue objects - INIT_WORK(&pCh->tqueue_input, do_input); - INIT_WORK(&pCh->tqueue_status, do_status); + INIT_WORK(&pCh->tqueue_input, do_input, pCh); + INIT_WORK(&pCh->tqueue_status, do_status, pCh); #ifdef IP2DEBUG_TRACE pCh->trace = ip2trace; @@ -1573,7 +1573,7 @@ i2StripFifo(i2eBordStrPtr pB) #ifdef USE_IQ schedule_work(&pCh->tqueue_input); #else - do_input(&pCh->tqueue_input); + do_input(pCh); #endif // Note we do not need to maintain any flow-control credits at this @@ -1810,7 +1810,7 @@ i2StripFifo(i2eBordStrPtr pB) #ifdef USE_IQ schedule_work(&pCh->tqueue_status); #else - do_status(&pCh->tqueue_status); + do_status(pCh); #endif } } diff --git a/trunk/drivers/char/ip2/ip2main.c b/trunk/drivers/char/ip2/ip2main.c index cda2459c1d60..a3f32d46d2f8 100644 --- a/trunk/drivers/char/ip2/ip2main.c +++ b/trunk/drivers/char/ip2/ip2main.c @@ -189,12 +189,12 @@ static int ip2_tiocmset(struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear); static void set_irq(int, int); -static void ip2_interrupt_bh(struct work_struct *work); +static void ip2_interrupt_bh(i2eBordStrPtr pB); static irqreturn_t ip2_interrupt(int irq, void *dev_id); static void ip2_poll(unsigned long arg); static inline void service_all_boards(void); -static void do_input(struct work_struct *); -static void do_status(struct work_struct *); +static void do_input(void *p); +static void do_status(void *p); static void ip2_wait_until_sent(PTTY,int); @@ -918,7 +918,7 @@ ip2_init_board( int boardnum ) pCh++; } ex_exit: - INIT_WORK(&pB->tqueue_interrupt, ip2_interrupt_bh); + INIT_WORK(&pB->tqueue_interrupt, (void(*)(void*)) ip2_interrupt_bh, pB); return; err_release_region: @@ -1125,8 +1125,8 @@ service_all_boards(void) /******************************************************************************/ -/* Function: ip2_interrupt_bh(work) */ -/* Parameters: work - pointer to the board structure */ +/* Function: ip2_interrupt_bh(pB) */ +/* Parameters: pB - pointer to the board structure */ /* Returns: Nothing */ /* */ /* Description: */ @@ -1135,9 +1135,8 @@ service_all_boards(void) /* */ /******************************************************************************/ static void -ip2_interrupt_bh(struct work_struct *work) +ip2_interrupt_bh(i2eBordStrPtr pB) { - i2eBordStrPtr pB = container_of(work, i2eBordStr, tqueue_interrupt); // pB better well be set or we have a problem! We can only get // here from the IMMEDIATE queue. Here, we process the boards. // Checking pB doesn't cost much and it saves us from the sanity checkers. @@ -1246,9 +1245,9 @@ ip2_poll(unsigned long arg) ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 ); } -static void do_input(struct work_struct *work) +static void do_input(void *p) { - i2ChanStrPtr pCh = container_of(work, i2ChanStr, tqueue_input); + i2ChanStrPtr pCh = p; unsigned long flags; ip2trace(CHANN, ITRC_INPUT, 21, 0 ); @@ -1280,9 +1279,9 @@ static inline void isig(int sig, struct tty_struct *tty, int flush) } } -static void do_status(struct work_struct *work) +static void do_status(void *p) { - i2ChanStrPtr pCh = container_of(work, i2ChanStr, tqueue_status); + i2ChanStrPtr pCh = p; int status; status = i2GetStatus( pCh, (I2_BRK|I2_PAR|I2_FRA|I2_OVR) ); diff --git a/trunk/drivers/char/isicom.c b/trunk/drivers/char/isicom.c index 1637c1d9a4ba..58c955e390b3 100644 --- a/trunk/drivers/char/isicom.c +++ b/trunk/drivers/char/isicom.c @@ -530,9 +530,9 @@ static void isicom_tx(unsigned long _data) /* Interrupt handlers */ -static void isicom_bottomhalf(struct work_struct *work) +static void isicom_bottomhalf(void *data) { - struct isi_port *port = container_of(work, struct isi_port, bh_tqueue); + struct isi_port *port = (struct isi_port *) data; struct tty_struct *tty = port->tty; if (!tty) @@ -1474,9 +1474,9 @@ static void isicom_start(struct tty_struct *tty) } /* hangup et all */ -static void do_isicom_hangup(struct work_struct *work) +static void do_isicom_hangup(void *data) { - struct isi_port *port = container_of(work, struct isi_port, hangup_tq); + struct isi_port *port = data; struct tty_struct *tty; tty = port->tty; @@ -1966,8 +1966,8 @@ static int __devinit isicom_setup(void) port->channel = channel; port->close_delay = 50 * HZ/100; port->closing_wait = 3000 * HZ/100; - INIT_WORK(&port->hangup_tq, do_isicom_hangup); - INIT_WORK(&port->bh_tqueue, isicom_bottomhalf); + INIT_WORK(&port->hangup_tq, do_isicom_hangup, port); + INIT_WORK(&port->bh_tqueue, isicom_bottomhalf, port); port->status = 0; init_waitqueue_head(&port->open_wait); init_waitqueue_head(&port->close_wait); diff --git a/trunk/drivers/char/moxa.c b/trunk/drivers/char/moxa.c index 2d025a9fd14d..96cb1f07332b 100644 --- a/trunk/drivers/char/moxa.c +++ b/trunk/drivers/char/moxa.c @@ -222,7 +222,7 @@ static struct semaphore moxaBuffSem; /* * static functions: */ -static void do_moxa_softint(struct work_struct *); +static void do_moxa_softint(void *); static int moxa_open(struct tty_struct *, struct file *); static void moxa_close(struct tty_struct *, struct file *); static int moxa_write(struct tty_struct *, const unsigned char *, int); @@ -363,7 +363,7 @@ static int __init moxa_init(void) for (i = 0, ch = moxaChannels; i < MAX_PORTS; i++, ch++) { ch->type = PORT_16550A; ch->port = i; - INIT_WORK(&ch->tqueue, do_moxa_softint); + INIT_WORK(&ch->tqueue, do_moxa_softint, ch); ch->tty = NULL; ch->close_delay = 5 * HZ / 10; ch->closing_wait = 30 * HZ; @@ -509,9 +509,9 @@ static void __exit moxa_exit(void) module_init(moxa_init); module_exit(moxa_exit); -static void do_moxa_softint(struct work_struct *work) +static void do_moxa_softint(void *private_) { - struct moxa_str *ch = container_of(work, struct moxa_str, tqueue); + struct moxa_str *ch = (struct moxa_str *) private_; struct tty_struct *tty; if (ch && (tty = ch->tty)) { diff --git a/trunk/drivers/char/mxser.c b/trunk/drivers/char/mxser.c index 5ed2486b7581..048d91142c17 100644 --- a/trunk/drivers/char/mxser.c +++ b/trunk/drivers/char/mxser.c @@ -389,7 +389,7 @@ static int mxser_init(void); /* static void mxser_poll(unsigned long); */ static int mxser_get_ISA_conf(int, struct mxser_hwconf *); static int mxser_get_PCI_conf(int, int, int, struct mxser_hwconf *); -static void mxser_do_softint(struct work_struct *); +static void mxser_do_softint(void *); static int mxser_open(struct tty_struct *, struct file *); static void mxser_close(struct tty_struct *, struct file *); static int mxser_write(struct tty_struct *, const unsigned char *, int); @@ -590,7 +590,7 @@ static int mxser_initbrd(int board, struct mxser_hwconf *hwconf) info->custom_divisor = hwconf->baud_base[i] * 16; info->close_delay = 5 * HZ / 10; info->closing_wait = 30 * HZ; - INIT_WORK(&info->tqueue, mxser_do_softint); + INIT_WORK(&info->tqueue, mxser_do_softint, info); info->normal_termios = mxvar_sdriver->init_termios; init_waitqueue_head(&info->open_wait); init_waitqueue_head(&info->close_wait); @@ -917,10 +917,9 @@ static int mxser_init(void) return 0; } -static void mxser_do_softint(struct work_struct *work) +static void mxser_do_softint(void *private_) { - struct mxser_struct *info = - container_of(work, struct mxser_struct, tqueue); + struct mxser_struct *info = private_; struct tty_struct *tty; tty = info->tty; diff --git a/trunk/drivers/char/pcmcia/cm4000_cs.c b/trunk/drivers/char/pcmcia/cm4000_cs.c index 211c93fda6fc..50d20aafeb18 100644 --- a/trunk/drivers/char/pcmcia/cm4000_cs.c +++ b/trunk/drivers/char/pcmcia/cm4000_cs.c @@ -1764,11 +1764,29 @@ static int cm4000_config(struct pcmcia_device * link, int devno) int rc; /* read the config-tuples */ + tuple.DesiredTuple = CISTPL_CONFIG; tuple.Attributes = 0; tuple.TupleData = buf; tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; + if ((fail_rc = pcmcia_get_first_tuple(link, &tuple)) != CS_SUCCESS) { + fail_fn = GetFirstTuple; + goto cs_failed; + } + if ((fail_rc = pcmcia_get_tuple_data(link, &tuple)) != CS_SUCCESS) { + fail_fn = GetTupleData; + goto cs_failed; + } + if ((fail_rc = + pcmcia_parse_tuple(link, &tuple, &parse)) != CS_SUCCESS) { + fail_fn = ParseTuple; + goto cs_failed; + } + + link->conf.ConfigBase = parse.config.base; + link->conf.Present = parse.config.rmask[0]; + link->io.BasePort2 = 0; link->io.NumPorts2 = 0; link->io.Attributes2 = 0; @@ -1823,6 +1841,8 @@ static int cm4000_config(struct pcmcia_device * link, int devno) return 0; +cs_failed: + cs_error(link, fail_fn, fail_rc); cs_release: cm4000_release(link); return -ENODEV; @@ -1953,14 +1973,14 @@ static int __init cmm_init(void) printk(KERN_INFO "%s\n", version); cmm_class = class_create(THIS_MODULE, "cardman_4000"); - if (IS_ERR(cmm_class)) - return PTR_ERR(cmm_class); + if (!cmm_class) + return -1; major = register_chrdev(0, DEVICE_NAME, &cm4000_fops); if (major < 0) { printk(KERN_WARNING MODULE_NAME ": could not get major number\n"); - return major; + return -1; } rc = pcmcia_register_driver(&cm4000_driver); diff --git a/trunk/drivers/char/pcmcia/cm4040_cs.c b/trunk/drivers/char/pcmcia/cm4040_cs.c index 9b1ff7e8f896..55cf4be42976 100644 --- a/trunk/drivers/char/pcmcia/cm4040_cs.c +++ b/trunk/drivers/char/pcmcia/cm4040_cs.c @@ -523,11 +523,29 @@ static int reader_config(struct pcmcia_device *link, int devno) int fail_fn, fail_rc; int rc; + tuple.DesiredTuple = CISTPL_CONFIG; tuple.Attributes = 0; tuple.TupleData = buf; tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; + if ((fail_rc = pcmcia_get_first_tuple(link, &tuple)) != CS_SUCCESS) { + fail_fn = GetFirstTuple; + goto cs_failed; + } + if ((fail_rc = pcmcia_get_tuple_data(link, &tuple)) != CS_SUCCESS) { + fail_fn = GetTupleData; + goto cs_failed; + } + if ((fail_rc = pcmcia_parse_tuple(link, &tuple, &parse)) + != CS_SUCCESS) { + fail_fn = ParseTuple; + goto cs_failed; + } + + link->conf.ConfigBase = parse.config.base; + link->conf.Present = parse.config.rmask[0]; + link->io.BasePort2 = 0; link->io.NumPorts2 = 0; link->io.Attributes2 = 0; @@ -591,6 +609,8 @@ static int reader_config(struct pcmcia_device *link, int devno) return 0; +cs_failed: + cs_error(link, fail_fn, fail_rc); cs_release: reader_release(link); return -ENODEV; @@ -701,14 +721,14 @@ static int __init cm4040_init(void) printk(KERN_INFO "%s\n", version); cmx_class = class_create(THIS_MODULE, "cardman_4040"); - if (IS_ERR(cmx_class)) - return PTR_ERR(cmx_class); + if (!cmx_class) + return -1; major = register_chrdev(0, DEVICE_NAME, &reader_fops); if (major < 0) { printk(KERN_WARNING MODULE_NAME ": could not get major number\n"); - return major; + return -1; } rc = pcmcia_register_driver(&reader_driver); diff --git a/trunk/drivers/char/pcmcia/synclink_cs.c b/trunk/drivers/char/pcmcia/synclink_cs.c index 1bd12296dca5..1a0bc30b79d1 100644 --- a/trunk/drivers/char/pcmcia/synclink_cs.c +++ b/trunk/drivers/char/pcmcia/synclink_cs.c @@ -421,7 +421,7 @@ static irqreturn_t mgslpc_isr(int irq, void *dev_id); /* * Bottom half interrupt handlers */ -static void bh_handler(struct work_struct *work); +static void bh_handler(void* Context); static void bh_transmit(MGSLPC_INFO *info); static void bh_status(MGSLPC_INFO *info); @@ -547,7 +547,7 @@ static int mgslpc_probe(struct pcmcia_device *link) memset(info, 0, sizeof(MGSLPC_INFO)); info->magic = MGSLPC_MAGIC; - INIT_WORK(&info->task, bh_handler); + INIT_WORK(&info->task, bh_handler, info); info->max_frame_size = 4096; info->close_delay = 5*HZ/10; info->closing_wait = 30*HZ; @@ -604,10 +604,17 @@ static int mgslpc_config(struct pcmcia_device *link) if (debug_level >= DEBUG_LEVEL_INFO) printk("mgslpc_config(0x%p)\n", link); + /* read CONFIG tuple to find its configuration registers */ + tuple.DesiredTuple = CISTPL_CONFIG; tuple.Attributes = 0; tuple.TupleData = buf; tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + link->conf.ConfigBase = parse.config.base; + link->conf.Present = parse.config.rmask[0]; /* get CIS configuration entry */ @@ -835,9 +842,9 @@ static int bh_action(MGSLPC_INFO *info) return rc; } -static void bh_handler(struct work_struct *work) +static void bh_handler(void* Context) { - MGSLPC_INFO *info = container_of(work, MGSLPC_INFO, task); + MGSLPC_INFO *info = (MGSLPC_INFO*)Context; int action; if (!info) diff --git a/trunk/drivers/char/random.c b/trunk/drivers/char/random.c index 4c6782a1ecdb..d40df30c2b10 100644 --- a/trunk/drivers/char/random.c +++ b/trunk/drivers/char/random.c @@ -1422,9 +1422,9 @@ static struct keydata { static unsigned int ip_cnt; -static void rekey_seq_generator(struct work_struct *work); +static void rekey_seq_generator(void *private_); -static DECLARE_DELAYED_WORK(rekey_work, rekey_seq_generator); +static DECLARE_WORK(rekey_work, rekey_seq_generator, NULL); /* * Lock avoidance: @@ -1438,7 +1438,7 @@ static DECLARE_DELAYED_WORK(rekey_work, rekey_seq_generator); * happen, and even if that happens only a not perfectly compliant * ISN is generated, nothing fatal. */ -static void rekey_seq_generator(struct work_struct *work) +static void rekey_seq_generator(void *private_) { struct keydata *keyptr = &ip_keydata[1 ^ (ip_cnt & 1)]; diff --git a/trunk/drivers/char/sonypi.c b/trunk/drivers/char/sonypi.c index fc87070f1866..c084149153de 100644 --- a/trunk/drivers/char/sonypi.c +++ b/trunk/drivers/char/sonypi.c @@ -765,7 +765,7 @@ static void sonypi_setbluetoothpower(u8 state) sonypi_device.bluetooth_power = state; } -static void input_keyrelease(struct work_struct *work) +static void input_keyrelease(void *data) { struct sonypi_keypress kp; @@ -1412,7 +1412,7 @@ static int __devinit sonypi_probe(struct platform_device *dev) goto err_inpdev_unregister; } - INIT_WORK(&sonypi_device.input_work, input_keyrelease); + INIT_WORK(&sonypi_device.input_work, input_keyrelease, NULL); } sonypi_enable(0); diff --git a/trunk/drivers/char/specialix.c b/trunk/drivers/char/specialix.c index 99137ab66b62..7e1bd9562c2a 100644 --- a/trunk/drivers/char/specialix.c +++ b/trunk/drivers/char/specialix.c @@ -2261,10 +2261,9 @@ static void sx_start(struct tty_struct * tty) * do_sx_hangup() -> tty->hangup() -> sx_hangup() * */ -static void do_sx_hangup(struct work_struct *work) +static void do_sx_hangup(void *private_) { - struct specialix_port *port = - container_of(work, struct specialix_port, tqueue_hangup); + struct specialix_port *port = (struct specialix_port *) private_; struct tty_struct *tty; func_enter(); @@ -2337,10 +2336,9 @@ static void sx_set_termios(struct tty_struct * tty, struct termios * old_termios } -static void do_softint(struct work_struct *work) +static void do_softint(void *private_) { - struct specialix_port *port = - container_of(work, struct specialix_port, tqueue); + struct specialix_port *port = (struct specialix_port *) private_; struct tty_struct *tty; func_enter(); @@ -2413,8 +2411,8 @@ static int sx_init_drivers(void) memset(sx_port, 0, sizeof(sx_port)); for (i = 0; i < SX_NPORT * SX_NBOARD; i++) { sx_port[i].magic = SPECIALIX_MAGIC; - INIT_WORK(&sx_port[i].tqueue, do_softint); - INIT_WORK(&sx_port[i].tqueue_hangup, do_sx_hangup); + INIT_WORK(&sx_port[i].tqueue, do_softint, &sx_port[i]); + INIT_WORK(&sx_port[i].tqueue_hangup, do_sx_hangup, &sx_port[i]); sx_port[i].close_delay = 50 * HZ/100; sx_port[i].closing_wait = 3000 * HZ/100; init_waitqueue_head(&sx_port[i].open_wait); diff --git a/trunk/drivers/char/synclink.c b/trunk/drivers/char/synclink.c index 147c30da81ea..06784adcc35c 100644 --- a/trunk/drivers/char/synclink.c +++ b/trunk/drivers/char/synclink.c @@ -802,7 +802,7 @@ static int save_tx_buffer_request(struct mgsl_struct *info,const char *Buffer, u /* * Bottom half interrupt handlers */ -static void mgsl_bh_handler(struct work_struct *work); +static void mgsl_bh_handler(void* Context); static void mgsl_bh_receive(struct mgsl_struct *info); static void mgsl_bh_transmit(struct mgsl_struct *info); static void mgsl_bh_status(struct mgsl_struct *info); @@ -1071,10 +1071,9 @@ static int mgsl_bh_action(struct mgsl_struct *info) /* * Perform bottom half processing of work items queued by ISR. */ -static void mgsl_bh_handler(struct work_struct *work) +static void mgsl_bh_handler(void* Context) { - struct mgsl_struct *info = - container_of(work, struct mgsl_struct, task); + struct mgsl_struct *info = (struct mgsl_struct*)Context; int action; if (!info) @@ -4338,7 +4337,7 @@ static struct mgsl_struct* mgsl_allocate_device(void) } else { memset(info, 0, sizeof(struct mgsl_struct)); info->magic = MGSL_MAGIC; - INIT_WORK(&info->task, mgsl_bh_handler); + INIT_WORK(&info->task, mgsl_bh_handler, info); info->max_frame_size = 4096; info->close_delay = 5*HZ/10; info->closing_wait = 30*HZ; diff --git a/trunk/drivers/char/synclink_gt.c b/trunk/drivers/char/synclink_gt.c index 07f34d43dc7f..d4334c79f8d4 100644 --- a/trunk/drivers/char/synclink_gt.c +++ b/trunk/drivers/char/synclink_gt.c @@ -485,7 +485,7 @@ static void enable_loopback(struct slgt_info *info); static void set_rate(struct slgt_info *info, u32 data_rate); static int bh_action(struct slgt_info *info); -static void bh_handler(struct work_struct *work); +static void bh_handler(void* context); static void bh_transmit(struct slgt_info *info); static void isr_serial(struct slgt_info *info); static void isr_rdma(struct slgt_info *info); @@ -1878,9 +1878,9 @@ static int bh_action(struct slgt_info *info) /* * perform bottom half processing */ -static void bh_handler(struct work_struct *work) +static void bh_handler(void* context) { - struct slgt_info *info = container_of(work, struct slgt_info, task); + struct slgt_info *info = context; int action; if (!info) @@ -3326,7 +3326,7 @@ static struct slgt_info *alloc_dev(int adapter_num, int port_num, struct pci_dev } else { memset(info, 0, sizeof(struct slgt_info)); info->magic = MGSL_MAGIC; - INIT_WORK(&info->task, bh_handler); + INIT_WORK(&info->task, bh_handler, info); info->max_frame_size = 4096; info->raw_rx_size = DMABUFSIZE; info->close_delay = 5*HZ/10; @@ -4799,6 +4799,6 @@ static void rx_timeout(unsigned long context) spin_lock_irqsave(&info->lock, flags); info->pending_bh |= BH_RECEIVE; spin_unlock_irqrestore(&info->lock, flags); - bh_handler(&info->task); + bh_handler(info); } diff --git a/trunk/drivers/char/synclinkmp.c b/trunk/drivers/char/synclinkmp.c index 13a57245cf2e..3e932b681371 100644 --- a/trunk/drivers/char/synclinkmp.c +++ b/trunk/drivers/char/synclinkmp.c @@ -602,7 +602,7 @@ static void enable_loopback(SLMP_INFO *info, int enable); static void set_rate(SLMP_INFO *info, u32 data_rate); static int bh_action(SLMP_INFO *info); -static void bh_handler(struct work_struct *work); +static void bh_handler(void* Context); static void bh_receive(SLMP_INFO *info); static void bh_transmit(SLMP_INFO *info); static void bh_status(SLMP_INFO *info); @@ -2063,9 +2063,9 @@ int bh_action(SLMP_INFO *info) /* Perform bottom half processing of work items queued by ISR. */ -void bh_handler(struct work_struct *work) +void bh_handler(void* Context) { - SLMP_INFO *info = container_of(work, SLMP_INFO, task); + SLMP_INFO *info = (SLMP_INFO*)Context; int action; if (!info) @@ -3805,7 +3805,7 @@ static SLMP_INFO *alloc_dev(int adapter_num, int port_num, struct pci_dev *pdev) } else { memset(info, 0, sizeof(SLMP_INFO)); info->magic = MGSL_MAGIC; - INIT_WORK(&info->task, bh_handler); + INIT_WORK(&info->task, bh_handler, info); info->max_frame_size = 4096; info->close_delay = 5*HZ/10; info->closing_wait = 30*HZ; diff --git a/trunk/drivers/char/sysrq.c b/trunk/drivers/char/sysrq.c index c64f5bcff947..5f49280779fb 100644 --- a/trunk/drivers/char/sysrq.c +++ b/trunk/drivers/char/sysrq.c @@ -219,13 +219,13 @@ static struct sysrq_key_op sysrq_term_op = { .enable_mask = SYSRQ_ENABLE_SIGNAL, }; -static void moom_callback(struct work_struct *ignored) +static void moom_callback(void *ignored) { out_of_memory(&NODE_DATA(0)->node_zonelists[ZONE_NORMAL], GFP_KERNEL, 0); } -static DECLARE_WORK(moom_work, moom_callback); +static DECLARE_WORK(moom_work, moom_callback, NULL); static void sysrq_handle_moom(int key, struct tty_struct *tty) { diff --git a/trunk/drivers/char/tpm/tpm.c b/trunk/drivers/char/tpm/tpm.c index 774fa861169a..6e1329d404d2 100644 --- a/trunk/drivers/char/tpm/tpm.c +++ b/trunk/drivers/char/tpm/tpm.c @@ -325,9 +325,9 @@ static void user_reader_timeout(unsigned long ptr) schedule_work(&chip->work); } -static void timeout_work(struct work_struct *work) +static void timeout_work(void *ptr) { - struct tpm_chip *chip = container_of(work, struct tpm_chip, work); + struct tpm_chip *chip = ptr; down(&chip->buffer_mutex); atomic_set(&chip->data_pending, 0); @@ -1105,7 +1105,7 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vend init_MUTEX(&chip->tpm_mutex); INIT_LIST_HEAD(&chip->list); - INIT_WORK(&chip->work, timeout_work); + INIT_WORK(&chip->work, timeout_work, chip); init_timer(&chip->user_read_timer); chip->user_read_timer.function = user_reader_timeout; diff --git a/trunk/drivers/char/tty_io.c b/trunk/drivers/char/tty_io.c index b3cfc8bc613c..50dc49205a23 100644 --- a/trunk/drivers/char/tty_io.c +++ b/trunk/drivers/char/tty_io.c @@ -1254,7 +1254,7 @@ EXPORT_SYMBOL_GPL(tty_ldisc_flush); /** * do_tty_hangup - actual handler for hangup events - * @work: tty device + * @data: tty device * * This can be called by the "eventd" kernel thread. That is process * synchronous but doesn't hold any locks, so we need to make sure we @@ -1274,10 +1274,9 @@ EXPORT_SYMBOL_GPL(tty_ldisc_flush); * tasklist_lock to walk task list for hangup event * */ -static void do_tty_hangup(struct work_struct *work) +static void do_tty_hangup(void *data) { - struct tty_struct *tty = - container_of(work, struct tty_struct, hangup_work); + struct tty_struct *tty = (struct tty_struct *) data; struct file * cons_filp = NULL; struct file *filp, *f = NULL; struct task_struct *p; @@ -1434,7 +1433,7 @@ void tty_vhangup(struct tty_struct * tty) printk(KERN_DEBUG "%s vhangup...\n", tty_name(tty, buf)); #endif - do_tty_hangup(&tty->hangup_work); + do_tty_hangup((void *) tty); } EXPORT_SYMBOL(tty_vhangup); @@ -3305,13 +3304,12 @@ int tty_ioctl(struct inode * inode, struct file * file, * Nasty bug: do_SAK is being called in interrupt context. This can * deadlock. We punt it up to process context. AKPM - 16Mar2001 */ -static void __do_SAK(struct work_struct *work) +static void __do_SAK(void *arg) { - struct tty_struct *tty = - container_of(work, struct tty_struct, SAK_work); #ifdef TTY_SOFT_SAK tty_hangup(tty); #else + struct tty_struct *tty = arg; struct task_struct *g, *p; int session; int i; @@ -3390,7 +3388,7 @@ void do_SAK(struct tty_struct *tty) { if (!tty) return; - PREPARE_WORK(&tty->SAK_work, __do_SAK); + PREPARE_WORK(&tty->SAK_work, __do_SAK, tty); schedule_work(&tty->SAK_work); } @@ -3398,7 +3396,7 @@ EXPORT_SYMBOL(do_SAK); /** * flush_to_ldisc - * @work: tty structure passed from work queue. + * @private_: tty structure passed from work queue. * * This routine is called out of the software interrupt to flush data * from the buffer chain to the line discipline. @@ -3408,10 +3406,9 @@ EXPORT_SYMBOL(do_SAK); * receive_buf method is single threaded for each tty instance. */ -static void flush_to_ldisc(struct work_struct *work) +static void flush_to_ldisc(void *private_) { - struct tty_struct *tty = - container_of(work, struct tty_struct, buf.work.work); + struct tty_struct *tty = (struct tty_struct *) private_; unsigned long flags; struct tty_ldisc *disc; struct tty_buffer *tbuf, *head; @@ -3556,7 +3553,7 @@ void tty_flip_buffer_push(struct tty_struct *tty) spin_unlock_irqrestore(&tty->buf.lock, flags); if (tty->low_latency) - flush_to_ldisc(&tty->buf.work.work); + flush_to_ldisc((void *) tty); else schedule_delayed_work(&tty->buf.work, 1); } @@ -3583,17 +3580,17 @@ static void initialize_tty_struct(struct tty_struct *tty) tty->overrun_time = jiffies; tty->buf.head = tty->buf.tail = NULL; tty_buffer_init(tty); - INIT_DELAYED_WORK(&tty->buf.work, flush_to_ldisc); + INIT_WORK(&tty->buf.work, flush_to_ldisc, tty); init_MUTEX(&tty->buf.pty_sem); mutex_init(&tty->termios_mutex); init_waitqueue_head(&tty->write_wait); init_waitqueue_head(&tty->read_wait); - INIT_WORK(&tty->hangup_work, do_tty_hangup); + INIT_WORK(&tty->hangup_work, do_tty_hangup, tty); mutex_init(&tty->atomic_read_lock); mutex_init(&tty->atomic_write_lock); spin_lock_init(&tty->read_lock); INIT_LIST_HEAD(&tty->tty_files); - INIT_WORK(&tty->SAK_work, NULL); + INIT_WORK(&tty->SAK_work, NULL, NULL); } /* diff --git a/trunk/drivers/char/vt.c b/trunk/drivers/char/vt.c index 75ff0286e1ad..87587b4385ab 100644 --- a/trunk/drivers/char/vt.c +++ b/trunk/drivers/char/vt.c @@ -155,7 +155,7 @@ static void con_flush_chars(struct tty_struct *tty); static void set_vesa_blanking(char __user *p); static void set_cursor(struct vc_data *vc); static void hide_cursor(struct vc_data *vc); -static void console_callback(struct work_struct *ignored); +static void console_callback(void *ignored); static void blank_screen_t(unsigned long dummy); static void set_palette(struct vc_data *vc); @@ -174,7 +174,7 @@ static int vesa_blank_mode; /* 0:none 1:suspendV 2:suspendH 3:powerdown */ static int blankinterval = 10*60*HZ; static int vesa_off_interval; -static DECLARE_WORK(console_work, console_callback); +static DECLARE_WORK(console_work, console_callback, NULL); /* * fg_console is the current virtual console, @@ -2154,7 +2154,7 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co * with other console code and prevention of re-entrancy is * ensured with console_sem. */ -static void console_callback(struct work_struct *ignored) +static void console_callback(void *ignored) { acquire_console_sem(); diff --git a/trunk/drivers/connector/cn_queue.c b/trunk/drivers/connector/cn_queue.c index b418b16e910e..05f8ce2cfb4a 100644 --- a/trunk/drivers/connector/cn_queue.c +++ b/trunk/drivers/connector/cn_queue.c @@ -31,11 +31,9 @@ #include #include -void cn_queue_wrapper(struct work_struct *work) +void cn_queue_wrapper(void *data) { - struct cn_callback_entry *cbq = - container_of(work, struct cn_callback_entry, work.work); - struct cn_callback_data *d = &cbq->data; + struct cn_callback_data *d = data; d->callback(d->callback_priv); @@ -59,7 +57,7 @@ static struct cn_callback_entry *cn_queue_alloc_callback_entry(char *name, struc memcpy(&cbq->id.id, id, sizeof(struct cb_id)); cbq->data.callback = callback; - INIT_DELAYED_WORK(&cbq->work, &cn_queue_wrapper); + INIT_WORK(&cbq->work, &cn_queue_wrapper, &cbq->data); return cbq; } diff --git a/trunk/drivers/connector/connector.c b/trunk/drivers/connector/connector.c index 5e7cd45d10ee..b49bacfd8de8 100644 --- a/trunk/drivers/connector/connector.c +++ b/trunk/drivers/connector/connector.c @@ -135,39 +135,40 @@ static int cn_call_callback(struct cn_msg *msg, void (*destruct_data)(void *), v spin_lock_bh(&dev->cbdev->queue_lock); list_for_each_entry(__cbq, &dev->cbdev->queue_list, callback_entry) { if (cn_cb_equal(&__cbq->id.id, &msg->id)) { - if (likely(!test_bit(WORK_STRUCT_PENDING, - &__cbq->work.work.management) && + if (likely(!test_bit(0, &__cbq->work.pending) && __cbq->data.ddata == NULL)) { __cbq->data.callback_priv = msg; __cbq->data.ddata = data; __cbq->data.destruct_data = destruct_data; - if (queue_delayed_work( - dev->cbdev->cn_queue, - &__cbq->work, 0)) + if (queue_work(dev->cbdev->cn_queue, + &__cbq->work)) err = 0; } else { + struct work_struct *w; struct cn_callback_data *d; - __cbq = kzalloc(sizeof(*__cbq), GFP_ATOMIC); - if (__cbq) { - d = &__cbq->data; + w = kzalloc(sizeof(*w) + sizeof(*d), GFP_ATOMIC); + if (w) { + d = (struct cn_callback_data *)(w+1); + d->callback_priv = msg; d->callback = __cbq->data.callback; d->ddata = data; d->destruct_data = destruct_data; - d->free = __cbq; + d->free = w; - INIT_DELAYED_WORK(&__cbq->work, - &cn_queue_wrapper); + INIT_LIST_HEAD(&w->entry); + w->pending = 0; + w->func = &cn_queue_wrapper; + w->data = d; + init_timer(&w->timer); - if (queue_delayed_work( - dev->cbdev->cn_queue, - &__cbq->work, 0)) + if (queue_work(dev->cbdev->cn_queue, w)) err = 0; else { - kfree(__cbq); + kfree(w); err = -EINVAL; } } else diff --git a/trunk/drivers/cpufreq/cpufreq.c b/trunk/drivers/cpufreq/cpufreq.c index 7a7c6e6dfe4f..dd0c2623e27b 100644 --- a/trunk/drivers/cpufreq/cpufreq.c +++ b/trunk/drivers/cpufreq/cpufreq.c @@ -42,7 +42,7 @@ static DEFINE_SPINLOCK(cpufreq_driver_lock); /* internal prototypes */ static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event); -static void handle_update(struct work_struct *work); +static void handle_update(void *data); /** * Two notifier lists: the "policy" list is involved in the @@ -665,7 +665,7 @@ static int cpufreq_add_dev (struct sys_device * sys_dev) mutex_init(&policy->lock); mutex_lock(&policy->lock); init_completion(&policy->kobj_unregister); - INIT_WORK(&policy->update, handle_update); + INIT_WORK(&policy->update, handle_update, (void *)(long)cpu); /* call driver. From then on the cpufreq must be able * to accept all calls to ->verify and ->setpolicy for this CPU @@ -895,11 +895,9 @@ static int cpufreq_remove_dev (struct sys_device * sys_dev) } -static void handle_update(struct work_struct *work) +static void handle_update(void *data) { - struct cpufreq_policy *policy = - container_of(work, struct cpufreq_policy, update); - unsigned int cpu = policy->cpu; + unsigned int cpu = (unsigned int)(long)data; dprintk("handle_update for cpu %u called\n", cpu); cpufreq_update_policy(cpu); } diff --git a/trunk/drivers/cpufreq/cpufreq_conservative.c b/trunk/drivers/cpufreq/cpufreq_conservative.c index 5ef5ede5b884..c4c578defabf 100644 --- a/trunk/drivers/cpufreq/cpufreq_conservative.c +++ b/trunk/drivers/cpufreq/cpufreq_conservative.c @@ -59,7 +59,7 @@ static unsigned int def_sampling_rate; #define MAX_SAMPLING_DOWN_FACTOR (10) #define TRANSITION_LATENCY_LIMIT (10 * 1000) -static void do_dbs_timer(struct work_struct *work); +static void do_dbs_timer(void *data); struct cpu_dbs_info_s { struct cpufreq_policy *cur_policy; @@ -82,7 +82,7 @@ static unsigned int dbs_enable; /* number of CPUs using this policy */ * is recursive for the same process. -Venki */ static DEFINE_MUTEX (dbs_mutex); -static DECLARE_DELAYED_WORK(dbs_work, do_dbs_timer); +static DECLARE_WORK (dbs_work, do_dbs_timer, NULL); struct dbs_tuners { unsigned int sampling_rate; @@ -420,7 +420,7 @@ static void dbs_check_cpu(int cpu) } } -static void do_dbs_timer(struct work_struct *work) +static void do_dbs_timer(void *data) { int i; lock_cpu_hotplug(); @@ -435,6 +435,7 @@ static void do_dbs_timer(struct work_struct *work) static inline void dbs_timer_init(void) { + INIT_WORK(&dbs_work, do_dbs_timer, NULL); schedule_delayed_work(&dbs_work, usecs_to_jiffies(dbs_tuners_ins.sampling_rate)); return; diff --git a/trunk/drivers/cpufreq/cpufreq_ondemand.c b/trunk/drivers/cpufreq/cpufreq_ondemand.c index e1cc5113c2ae..bf8aa45d4f01 100644 --- a/trunk/drivers/cpufreq/cpufreq_ondemand.c +++ b/trunk/drivers/cpufreq/cpufreq_ondemand.c @@ -47,17 +47,13 @@ static unsigned int def_sampling_rate; #define DEF_SAMPLING_RATE_LATENCY_MULTIPLIER (1000) #define TRANSITION_LATENCY_LIMIT (10 * 1000) -static void do_dbs_timer(struct work_struct *work); - -/* Sampling types */ -enum dbs_sample {DBS_NORMAL_SAMPLE, DBS_SUB_SAMPLE}; +static void do_dbs_timer(void *data); struct cpu_dbs_info_s { cputime64_t prev_cpu_idle; cputime64_t prev_cpu_wall; struct cpufreq_policy *cur_policy; - struct delayed_work work; - enum dbs_sample sample_type; + struct work_struct work; unsigned int enable; struct cpufreq_frequency_table *freq_table; unsigned int freq_lo; @@ -411,31 +407,30 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info) } } -static void do_dbs_timer(struct work_struct *work) +/* Sampling types */ +enum {DBS_NORMAL_SAMPLE, DBS_SUB_SAMPLE}; + +static void do_dbs_timer(void *data) { unsigned int cpu = smp_processor_id(); struct cpu_dbs_info_s *dbs_info = &per_cpu(cpu_dbs_info, cpu); - enum dbs_sample sample_type = dbs_info->sample_type; /* We want all CPUs to do sampling nearly on same jiffy */ int delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate); - - /* Permit rescheduling of this work item */ - work_release(work); - delay -= jiffies % delay; if (!dbs_info->enable) return; /* Common NORMAL_SAMPLE setup */ - dbs_info->sample_type = DBS_NORMAL_SAMPLE; + INIT_WORK(&dbs_info->work, do_dbs_timer, (void *)DBS_NORMAL_SAMPLE); if (!dbs_tuners_ins.powersave_bias || - sample_type == DBS_NORMAL_SAMPLE) { + (unsigned long) data == DBS_NORMAL_SAMPLE) { lock_cpu_hotplug(); dbs_check_cpu(dbs_info); unlock_cpu_hotplug(); if (dbs_info->freq_lo) { /* Setup timer for SUB_SAMPLE */ - dbs_info->sample_type = DBS_SUB_SAMPLE; + INIT_WORK(&dbs_info->work, do_dbs_timer, + (void *)DBS_SUB_SAMPLE); delay = dbs_info->freq_hi_jiffies; } } else { @@ -454,8 +449,7 @@ static inline void dbs_timer_init(unsigned int cpu) delay -= jiffies % delay; ondemand_powersave_bias_init(); - INIT_DELAYED_WORK_NAR(&dbs_info->work, do_dbs_timer); - dbs_info->sample_type = DBS_NORMAL_SAMPLE; + INIT_WORK(&dbs_info->work, do_dbs_timer, NULL); queue_delayed_work_on(cpu, kondemand_wq, &dbs_info->work, delay); } diff --git a/trunk/drivers/i2c/chips/ds1374.c b/trunk/drivers/i2c/chips/ds1374.c index 15edf40828b4..4630f1969a09 100644 --- a/trunk/drivers/i2c/chips/ds1374.c +++ b/trunk/drivers/i2c/chips/ds1374.c @@ -140,14 +140,12 @@ ulong ds1374_get_rtc_time(void) return t1; } -static ulong new_time; - -static void ds1374_set_work(struct work_struct *work) +static void ds1374_set_work(void *arg) { ulong t1, t2; int limit = 10; /* arbitrary retry limit */ - t1 = new_time; + t1 = *(ulong *) arg; mutex_lock(&ds1374_mutex); @@ -169,9 +167,11 @@ static void ds1374_set_work(struct work_struct *work) "can't confirm time set from rtc chip\n"); } +static ulong new_time; + static struct workqueue_struct *ds1374_workqueue; -static DECLARE_WORK(ds1374_work, ds1374_set_work); +static DECLARE_WORK(ds1374_work, ds1374_set_work, &new_time); int ds1374_set_rtc_time(ulong nowtime) { @@ -180,7 +180,7 @@ int ds1374_set_rtc_time(ulong nowtime) if (in_interrupt()) queue_work(ds1374_workqueue, &ds1374_work); else - ds1374_set_work(NULL); + ds1374_set_work(&new_time); return 0; } diff --git a/trunk/drivers/ide/legacy/ide-cs.c b/trunk/drivers/ide/legacy/ide-cs.c index 7efd28ac21ed..bef4759f70e5 100644 --- a/trunk/drivers/ide/legacy/ide-cs.c +++ b/trunk/drivers/ide/legacy/ide-cs.c @@ -192,10 +192,20 @@ static int ide_config(struct pcmcia_device *link) tuple.TupleOffset = 0; tuple.TupleDataMax = 255; tuple.Attributes = 0; - - is_kme = ((link->manf_id == MANFID_KME) && - ((link->card_id == PRODID_KME_KXLC005_A) || - (link->card_id == PRODID_KME_KXLC005_B))); + tuple.DesiredTuple = CISTPL_CONFIG; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &stk->parse)); + link->conf.ConfigBase = stk->parse.config.base; + link->conf.Present = stk->parse.config.rmask[0]; + + tuple.DesiredTuple = CISTPL_MANFID; + if (!pcmcia_get_first_tuple(link, &tuple) && + !pcmcia_get_tuple_data(link, &tuple) && + !pcmcia_parse_tuple(link, &tuple, &stk->parse)) + is_kme = ((stk->parse.manfid.manf == MANFID_KME) && + ((stk->parse.manfid.card == PRODID_KME_KXLC005_A) || + (stk->parse.manfid.card == PRODID_KME_KXLC005_B))); /* Not sure if this is right... look up the current Vcc */ CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &stk->conf)); @@ -398,10 +408,8 @@ static struct pcmcia_device_id ide_ids[] = { PCMCIA_DEVICE_PROD_ID12("SMI VENDOR", "SMI PRODUCT", 0x30896c92, 0x703cc5f6), PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003), PCMCIA_DEVICE_PROD_ID1("TRANSCEND 512M ", 0xd0909443), - PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS1GCF80", 0x709b1bf1, 0x2a54d4b1), PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF120", 0x709b1bf1, 0xf54a91c8), PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852), - PCMCIA_DEVICE_PROD_ID12("WEIDA", "TWTTI", 0xcc7cf69c, 0x212bb918), PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209), PCMCIA_DEVICE_PROD_ID12("STI", "Flash 5.0", 0xbf2df18d, 0x8cb57a0e), PCMCIA_MFC_DEVICE_PROD_ID12(1, "SanDisk", "ConnectPlus", 0x7a954bd9, 0x74be00c6), diff --git a/trunk/drivers/ieee1394/hosts.c b/trunk/drivers/ieee1394/hosts.c index 8f4378a1631c..d90a3a1898c0 100644 --- a/trunk/drivers/ieee1394/hosts.c +++ b/trunk/drivers/ieee1394/hosts.c @@ -31,10 +31,9 @@ #include "config_roms.h" -static void delayed_reset_bus(struct work_struct *work) +static void delayed_reset_bus(void * __reset_info) { - struct hpsb_host *host = - container_of(work, struct hpsb_host, delayed_reset.work); + struct hpsb_host *host = (struct hpsb_host*)__reset_info; int generation = host->csr.generation + 1; /* The generation field rolls over to 2 rather than 0 per IEEE @@ -146,7 +145,7 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra, atomic_set(&h->generation, 0); - INIT_DELAYED_WORK(&h->delayed_reset, delayed_reset_bus); + INIT_WORK(&h->delayed_reset, delayed_reset_bus, h); init_timer(&h->timeout); h->timeout.data = (unsigned long) h; @@ -235,7 +234,7 @@ int hpsb_update_config_rom_image(struct hpsb_host *host) * Config ROM in the near future. */ reset_delay = HZ; - PREPARE_DELAYED_WORK(&host->delayed_reset, delayed_reset_bus); + PREPARE_WORK(&host->delayed_reset, delayed_reset_bus, host); schedule_delayed_work(&host->delayed_reset, reset_delay); return 0; diff --git a/trunk/drivers/ieee1394/hosts.h b/trunk/drivers/ieee1394/hosts.h index d553e38c9543..bc6dbfadb891 100644 --- a/trunk/drivers/ieee1394/hosts.h +++ b/trunk/drivers/ieee1394/hosts.h @@ -62,7 +62,7 @@ struct hpsb_host { struct class_device class_dev; int update_config_rom; - struct delayed_work delayed_reset; + struct work_struct delayed_reset; unsigned int config_roms; struct list_head addr_space; diff --git a/trunk/drivers/ieee1394/sbp2.c b/trunk/drivers/ieee1394/sbp2.c index cd156d4e779e..6986ac188281 100644 --- a/trunk/drivers/ieee1394/sbp2.c +++ b/trunk/drivers/ieee1394/sbp2.c @@ -493,25 +493,20 @@ static void sbp2util_notify_fetch_agent(struct scsi_id_instance_data *scsi_id, scsi_unblock_requests(scsi_id->scsi_host); } -static void sbp2util_write_orb_pointer(struct work_struct *work) +static void sbp2util_write_orb_pointer(void *p) { - struct scsi_id_instance_data *scsi_id = - container_of(work, struct scsi_id_instance_data, - protocol_work.work); quadlet_t data[2]; - data[0] = ORB_SET_NODE_ID(scsi_id->hi->host->node_id); - data[1] = scsi_id->last_orb_dma; + data[0] = ORB_SET_NODE_ID( + ((struct scsi_id_instance_data *)p)->hi->host->node_id); + data[1] = ((struct scsi_id_instance_data *)p)->last_orb_dma; sbp2util_cpu_to_be32_buffer(data, 8); - sbp2util_notify_fetch_agent(scsi_id, SBP2_ORB_POINTER_OFFSET, data, 8); + sbp2util_notify_fetch_agent(p, SBP2_ORB_POINTER_OFFSET, data, 8); } -static void sbp2util_write_doorbell(struct work_struct *work) +static void sbp2util_write_doorbell(void *p) { - struct scsi_id_instance_data *scsi_id = - container_of(work, struct scsi_id_instance_data, - protocol_work.work); - sbp2util_notify_fetch_agent(scsi_id, SBP2_DOORBELL_OFFSET, NULL, 4); + sbp2util_notify_fetch_agent(p, SBP2_DOORBELL_OFFSET, NULL, 4); } /* @@ -848,7 +843,7 @@ static struct scsi_id_instance_data *sbp2_alloc_device(struct unit_directory *ud INIT_LIST_HEAD(&scsi_id->scsi_list); spin_lock_init(&scsi_id->sbp2_command_orb_lock); atomic_set(&scsi_id->state, SBP2LU_STATE_RUNNING); - INIT_DELAYED_WORK(&scsi_id->protocol_work, NULL); + INIT_WORK(&scsi_id->protocol_work, NULL, NULL); ud->device.driver_data = scsi_id; @@ -2052,10 +2047,11 @@ static void sbp2_link_orb_command(struct scsi_id_instance_data *scsi_id, * We do not accept new commands until the job is over. */ scsi_block_requests(scsi_id->scsi_host); - PREPARE_DELAYED_WORK(&scsi_id->protocol_work, + PREPARE_WORK(&scsi_id->protocol_work, last_orb ? sbp2util_write_doorbell: - sbp2util_write_orb_pointer); - schedule_delayed_work(&scsi_id->protocol_work, 0); + sbp2util_write_orb_pointer, + scsi_id); + schedule_work(&scsi_id->protocol_work); } } diff --git a/trunk/drivers/ieee1394/sbp2.h b/trunk/drivers/ieee1394/sbp2.h index 1b16d6b9cf11..abbe48e646c3 100644 --- a/trunk/drivers/ieee1394/sbp2.h +++ b/trunk/drivers/ieee1394/sbp2.h @@ -348,7 +348,7 @@ struct scsi_id_instance_data { unsigned workarounds; atomic_t state; - struct delayed_work protocol_work; + struct work_struct protocol_work; }; /* For use in scsi_id_instance_data.state */ diff --git a/trunk/drivers/infiniband/core/addr.c b/trunk/drivers/infiniband/core/addr.c index af939796750d..7767a11b6890 100644 --- a/trunk/drivers/infiniband/core/addr.c +++ b/trunk/drivers/infiniband/core/addr.c @@ -55,11 +55,11 @@ struct addr_req { int status; }; -static void process_req(struct work_struct *work); +static void process_req(void *data); static DEFINE_MUTEX(lock); static LIST_HEAD(req_list); -static DECLARE_DELAYED_WORK(work, process_req); +static DECLARE_WORK(work, process_req, NULL); static struct workqueue_struct *addr_wq; void rdma_addr_register_client(struct rdma_addr_client *client) @@ -215,7 +215,7 @@ static int addr_resolve_remote(struct sockaddr_in *src_in, return ret; } -static void process_req(struct work_struct *work) +static void process_req(void *data) { struct addr_req *req, *temp_req; struct sockaddr_in *src_in, *dst_in; diff --git a/trunk/drivers/infiniband/core/cache.c b/trunk/drivers/infiniband/core/cache.c index 98272fbbfb31..20e9f64e67a6 100644 --- a/trunk/drivers/infiniband/core/cache.c +++ b/trunk/drivers/infiniband/core/cache.c @@ -285,10 +285,9 @@ static void ib_cache_update(struct ib_device *device, kfree(tprops); } -static void ib_cache_task(struct work_struct *_work) +static void ib_cache_task(void *work_ptr) { - struct ib_update_work *work = - container_of(_work, struct ib_update_work, work); + struct ib_update_work *work = work_ptr; ib_cache_update(work->device, work->port_num); kfree(work); @@ -307,7 +306,7 @@ static void ib_cache_event(struct ib_event_handler *handler, event->event == IB_EVENT_CLIENT_REREGISTER) { work = kmalloc(sizeof *work, GFP_ATOMIC); if (work) { - INIT_WORK(&work->work, ib_cache_task); + INIT_WORK(&work->work, ib_cache_task, work); work->device = event->device; work->port_num = event->element.port_num; schedule_work(&work->work); diff --git a/trunk/drivers/infiniband/core/cm.c b/trunk/drivers/infiniband/core/cm.c index 79c937bf6962..e5dc4530808a 100644 --- a/trunk/drivers/infiniband/core/cm.c +++ b/trunk/drivers/infiniband/core/cm.c @@ -101,7 +101,7 @@ struct cm_av { }; struct cm_work { - struct delayed_work work; + struct work_struct work; struct list_head list; struct cm_port *port; struct ib_mad_recv_wc *mad_recv_wc; /* Received MADs */ @@ -161,7 +161,7 @@ struct cm_id_private { atomic_t work_count; }; -static void cm_work_handler(struct work_struct *work); +static void cm_work_handler(void *data); static inline void cm_deref_id(struct cm_id_private *cm_id_priv) { @@ -668,7 +668,8 @@ static struct cm_timewait_info * cm_create_timewait_info(__be32 local_id) return ERR_PTR(-ENOMEM); timewait_info->work.local_id = local_id; - INIT_DELAYED_WORK(&timewait_info->work.work, cm_work_handler); + INIT_WORK(&timewait_info->work.work, cm_work_handler, + &timewait_info->work); timewait_info->work.cm_event.event = IB_CM_TIMEWAIT_EXIT; return timewait_info; } @@ -2994,9 +2995,9 @@ static void cm_send_handler(struct ib_mad_agent *mad_agent, } } -static void cm_work_handler(struct work_struct *_work) +static void cm_work_handler(void *data) { - struct cm_work *work = container_of(_work, struct cm_work, work.work); + struct cm_work *work = data; int ret; switch (work->cm_event.event) { @@ -3086,12 +3087,12 @@ static int cm_establish(struct ib_cm_id *cm_id) * we need to find the cm_id once we're in the context of the * worker thread, rather than holding a reference on it. */ - INIT_DELAYED_WORK(&work->work, cm_work_handler); + INIT_WORK(&work->work, cm_work_handler, work); work->local_id = cm_id->local_id; work->remote_id = cm_id->remote_id; work->mad_recv_wc = NULL; work->cm_event.event = IB_CM_USER_ESTABLISHED; - queue_delayed_work(cm.wq, &work->work, 0); + queue_work(cm.wq, &work->work); out: return ret; } @@ -3190,11 +3191,11 @@ static void cm_recv_handler(struct ib_mad_agent *mad_agent, return; } - INIT_DELAYED_WORK(&work->work, cm_work_handler); + INIT_WORK(&work->work, cm_work_handler, work); work->cm_event.event = event; work->mad_recv_wc = mad_recv_wc; work->port = (struct cm_port *)mad_agent->context; - queue_delayed_work(cm.wq, &work->work, 0); + queue_work(cm.wq, &work->work); } static int cm_init_qp_init_attr(struct cm_id_private *cm_id_priv, diff --git a/trunk/drivers/infiniband/core/cma.c b/trunk/drivers/infiniband/core/cma.c index 985a6b564d8f..cf48f2697434 100644 --- a/trunk/drivers/infiniband/core/cma.c +++ b/trunk/drivers/infiniband/core/cma.c @@ -1340,9 +1340,9 @@ static int cma_query_ib_route(struct rdma_id_private *id_priv, int timeout_ms, return (id_priv->query_id < 0) ? id_priv->query_id : 0; } -static void cma_work_handler(struct work_struct *_work) +static void cma_work_handler(void *data) { - struct cma_work *work = container_of(_work, struct cma_work, work); + struct cma_work *work = data; struct rdma_id_private *id_priv = work->id; int destroy = 0; @@ -1373,7 +1373,7 @@ static int cma_resolve_ib_route(struct rdma_id_private *id_priv, int timeout_ms) return -ENOMEM; work->id = id_priv; - INIT_WORK(&work->work, cma_work_handler); + INIT_WORK(&work->work, cma_work_handler, work); work->old_state = CMA_ROUTE_QUERY; work->new_state = CMA_ROUTE_RESOLVED; work->event.event = RDMA_CM_EVENT_ROUTE_RESOLVED; @@ -1430,7 +1430,7 @@ static int cma_resolve_iw_route(struct rdma_id_private *id_priv, int timeout_ms) return -ENOMEM; work->id = id_priv; - INIT_WORK(&work->work, cma_work_handler); + INIT_WORK(&work->work, cma_work_handler, work); work->old_state = CMA_ROUTE_QUERY; work->new_state = CMA_ROUTE_RESOLVED; work->event.event = RDMA_CM_EVENT_ROUTE_RESOLVED; @@ -1583,7 +1583,7 @@ static int cma_resolve_loopback(struct rdma_id_private *id_priv) } work->id = id_priv; - INIT_WORK(&work->work, cma_work_handler); + INIT_WORK(&work->work, cma_work_handler, work); work->old_state = CMA_ADDR_QUERY; work->new_state = CMA_ADDR_RESOLVED; work->event.event = RDMA_CM_EVENT_ADDR_RESOLVED; diff --git a/trunk/drivers/infiniband/core/iwcm.c b/trunk/drivers/infiniband/core/iwcm.c index 1039ad57d53b..cf797d7aea09 100644 --- a/trunk/drivers/infiniband/core/iwcm.c +++ b/trunk/drivers/infiniband/core/iwcm.c @@ -828,9 +828,9 @@ static int process_event(struct iwcm_id_private *cm_id_priv, * thread asleep on the destroy_comp list vs. an object destroyed * here synchronously when the last reference is removed. */ -static void cm_work_handler(struct work_struct *_work) +static void cm_work_handler(void *arg) { - struct iwcm_work *work = container_of(_work, struct iwcm_work, work); + struct iwcm_work *work = arg; struct iw_cm_event levent; struct iwcm_id_private *cm_id_priv = work->cm_id; unsigned long flags; @@ -900,7 +900,7 @@ static int cm_event_handler(struct iw_cm_id *cm_id, goto out; } - INIT_WORK(&work->work, cm_work_handler); + INIT_WORK(&work->work, cm_work_handler, work); work->cm_id = cm_id_priv; work->event = *iw_event; diff --git a/trunk/drivers/infiniband/core/mad.c b/trunk/drivers/infiniband/core/mad.c index 15f38d94b3a8..3f9c16232c4d 100644 --- a/trunk/drivers/infiniband/core/mad.c +++ b/trunk/drivers/infiniband/core/mad.c @@ -65,8 +65,8 @@ static struct ib_mad_agent_private *find_mad_agent( static int ib_mad_post_receive_mads(struct ib_mad_qp_info *qp_info, struct ib_mad_private *mad); static void cancel_mads(struct ib_mad_agent_private *mad_agent_priv); -static void timeout_sends(struct work_struct *work); -static void local_completions(struct work_struct *work); +static void timeout_sends(void *data); +static void local_completions(void *data); static int add_nonoui_reg_req(struct ib_mad_reg_req *mad_reg_req, struct ib_mad_agent_private *agent_priv, u8 mgmt_class); @@ -356,9 +356,10 @@ struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device, INIT_LIST_HEAD(&mad_agent_priv->wait_list); INIT_LIST_HEAD(&mad_agent_priv->done_list); INIT_LIST_HEAD(&mad_agent_priv->rmpp_list); - INIT_DELAYED_WORK(&mad_agent_priv->timed_work, timeout_sends); + INIT_WORK(&mad_agent_priv->timed_work, timeout_sends, mad_agent_priv); INIT_LIST_HEAD(&mad_agent_priv->local_list); - INIT_WORK(&mad_agent_priv->local_work, local_completions); + INIT_WORK(&mad_agent_priv->local_work, local_completions, + mad_agent_priv); atomic_set(&mad_agent_priv->refcount, 1); init_completion(&mad_agent_priv->comp); @@ -2197,12 +2198,12 @@ static void mad_error_handler(struct ib_mad_port_private *port_priv, /* * IB MAD completion callback */ -static void ib_mad_completion_handler(struct work_struct *work) +static void ib_mad_completion_handler(void *data) { struct ib_mad_port_private *port_priv; struct ib_wc wc; - port_priv = container_of(work, struct ib_mad_port_private, work); + port_priv = (struct ib_mad_port_private *)data; ib_req_notify_cq(port_priv->cq, IB_CQ_NEXT_COMP); while (ib_poll_cq(port_priv->cq, 1, &wc) == 1) { @@ -2323,7 +2324,7 @@ void ib_cancel_mad(struct ib_mad_agent *mad_agent, } EXPORT_SYMBOL(ib_cancel_mad); -static void local_completions(struct work_struct *work) +static void local_completions(void *data) { struct ib_mad_agent_private *mad_agent_priv; struct ib_mad_local_private *local; @@ -2333,8 +2334,7 @@ static void local_completions(struct work_struct *work) struct ib_wc wc; struct ib_mad_send_wc mad_send_wc; - mad_agent_priv = - container_of(work, struct ib_mad_agent_private, local_work); + mad_agent_priv = (struct ib_mad_agent_private *)data; spin_lock_irqsave(&mad_agent_priv->lock, flags); while (!list_empty(&mad_agent_priv->local_list)) { @@ -2434,15 +2434,14 @@ static int retry_send(struct ib_mad_send_wr_private *mad_send_wr) return ret; } -static void timeout_sends(struct work_struct *work) +static void timeout_sends(void *data) { struct ib_mad_agent_private *mad_agent_priv; struct ib_mad_send_wr_private *mad_send_wr; struct ib_mad_send_wc mad_send_wc; unsigned long flags, delay; - mad_agent_priv = container_of(work, struct ib_mad_agent_private, - timed_work.work); + mad_agent_priv = (struct ib_mad_agent_private *)data; mad_send_wc.vendor_err = 0; spin_lock_irqsave(&mad_agent_priv->lock, flags); @@ -2800,7 +2799,7 @@ static int ib_mad_port_open(struct ib_device *device, ret = -ENOMEM; goto error8; } - INIT_WORK(&port_priv->work, ib_mad_completion_handler); + INIT_WORK(&port_priv->work, ib_mad_completion_handler, port_priv); spin_lock_irqsave(&ib_mad_port_list_lock, flags); list_add_tail(&port_priv->port_list, &ib_mad_port_list); diff --git a/trunk/drivers/infiniband/core/mad_priv.h b/trunk/drivers/infiniband/core/mad_priv.h index d5548e73e068..d06b59083f6e 100644 --- a/trunk/drivers/infiniband/core/mad_priv.h +++ b/trunk/drivers/infiniband/core/mad_priv.h @@ -102,7 +102,7 @@ struct ib_mad_agent_private { struct list_head send_list; struct list_head wait_list; struct list_head done_list; - struct delayed_work timed_work; + struct work_struct timed_work; unsigned long timeout; struct list_head local_list; struct work_struct local_work; diff --git a/trunk/drivers/infiniband/core/mad_rmpp.c b/trunk/drivers/infiniband/core/mad_rmpp.c index 3663fd7022be..1ef79d015a1e 100644 --- a/trunk/drivers/infiniband/core/mad_rmpp.c +++ b/trunk/drivers/infiniband/core/mad_rmpp.c @@ -45,8 +45,8 @@ enum rmpp_state { struct mad_rmpp_recv { struct ib_mad_agent_private *agent; struct list_head list; - struct delayed_work timeout_work; - struct delayed_work cleanup_work; + struct work_struct timeout_work; + struct work_struct cleanup_work; struct completion comp; enum rmpp_state state; spinlock_t lock; @@ -233,10 +233,9 @@ static void nack_recv(struct ib_mad_agent_private *agent, } } -static void recv_timeout_handler(struct work_struct *work) +static void recv_timeout_handler(void *data) { - struct mad_rmpp_recv *rmpp_recv = - container_of(work, struct mad_rmpp_recv, timeout_work.work); + struct mad_rmpp_recv *rmpp_recv = data; struct ib_mad_recv_wc *rmpp_wc; unsigned long flags; @@ -255,10 +254,9 @@ static void recv_timeout_handler(struct work_struct *work) ib_free_recv_mad(rmpp_wc); } -static void recv_cleanup_handler(struct work_struct *work) +static void recv_cleanup_handler(void *data) { - struct mad_rmpp_recv *rmpp_recv = - container_of(work, struct mad_rmpp_recv, cleanup_work.work); + struct mad_rmpp_recv *rmpp_recv = data; unsigned long flags; spin_lock_irqsave(&rmpp_recv->agent->lock, flags); @@ -287,8 +285,8 @@ create_rmpp_recv(struct ib_mad_agent_private *agent, rmpp_recv->agent = agent; init_completion(&rmpp_recv->comp); - INIT_DELAYED_WORK(&rmpp_recv->timeout_work, recv_timeout_handler); - INIT_DELAYED_WORK(&rmpp_recv->cleanup_work, recv_cleanup_handler); + INIT_WORK(&rmpp_recv->timeout_work, recv_timeout_handler, rmpp_recv); + INIT_WORK(&rmpp_recv->cleanup_work, recv_cleanup_handler, rmpp_recv); spin_lock_init(&rmpp_recv->lock); rmpp_recv->state = RMPP_STATE_ACTIVE; atomic_set(&rmpp_recv->refcount, 1); diff --git a/trunk/drivers/infiniband/core/sa_query.c b/trunk/drivers/infiniband/core/sa_query.c index e45afba75341..1706d3c7e95e 100644 --- a/trunk/drivers/infiniband/core/sa_query.c +++ b/trunk/drivers/infiniband/core/sa_query.c @@ -360,10 +360,9 @@ static void free_sm_ah(struct kref *kref) kfree(sm_ah); } -static void update_sm_ah(struct work_struct *work) +static void update_sm_ah(void *port_ptr) { - struct ib_sa_port *port = - container_of(work, struct ib_sa_port, update_task); + struct ib_sa_port *port = port_ptr; struct ib_sa_sm_ah *new_ah, *old_ah; struct ib_port_attr port_attr; struct ib_ah_attr ah_attr; @@ -993,7 +992,8 @@ static void ib_sa_add_one(struct ib_device *device) if (IS_ERR(sa_dev->port[i].agent)) goto err; - INIT_WORK(&sa_dev->port[i].update_task, update_sm_ah); + INIT_WORK(&sa_dev->port[i].update_task, + update_sm_ah, &sa_dev->port[i]); } ib_set_client_data(device, &sa_client, sa_dev); @@ -1010,7 +1010,7 @@ static void ib_sa_add_one(struct ib_device *device) goto err; for (i = 0; i <= e - s; ++i) - update_sm_ah(&sa_dev->port[i].update_task); + update_sm_ah(&sa_dev->port[i]); return; diff --git a/trunk/drivers/infiniband/core/uverbs_mem.c b/trunk/drivers/infiniband/core/uverbs_mem.c index db12cc0841df..efe147dbeb42 100644 --- a/trunk/drivers/infiniband/core/uverbs_mem.c +++ b/trunk/drivers/infiniband/core/uverbs_mem.c @@ -179,10 +179,9 @@ void ib_umem_release(struct ib_device *dev, struct ib_umem *umem) up_write(¤t->mm->mmap_sem); } -static void ib_umem_account(struct work_struct *_work) +static void ib_umem_account(void *work_ptr) { - struct ib_umem_account_work *work = - container_of(_work, struct ib_umem_account_work, work); + struct ib_umem_account_work *work = work_ptr; down_write(&work->mm->mmap_sem); work->mm->locked_vm -= work->diff; @@ -217,7 +216,7 @@ void ib_umem_release_on_close(struct ib_device *dev, struct ib_umem *umem) return; } - INIT_WORK(&work->work, ib_umem_account); + INIT_WORK(&work->work, ib_umem_account, work); work->mm = mm; work->diff = PAGE_ALIGN(umem->length + umem->offset) >> PAGE_SHIFT; diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_user_pages.c b/trunk/drivers/infiniband/hw/ipath/ipath_user_pages.c index 8536aeb96af8..413754b1d8a2 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_user_pages.c +++ b/trunk/drivers/infiniband/hw/ipath/ipath_user_pages.c @@ -214,10 +214,9 @@ struct ipath_user_pages_work { unsigned long num_pages; }; -static void user_pages_account(struct work_struct *_work) +static void user_pages_account(void *ptr) { - struct ipath_user_pages_work *work = - container_of(_work, struct ipath_user_pages_work, work); + struct ipath_user_pages_work *work = ptr; down_write(&work->mm->mmap_sem); work->mm->locked_vm -= work->num_pages; @@ -243,7 +242,7 @@ void ipath_release_user_pages_on_close(struct page **p, size_t num_pages) goto bail; - INIT_WORK(&work->work, user_pages_account); + INIT_WORK(&work->work, user_pages_account, work); work->mm = mm; work->num_pages = num_pages; diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_catas.c b/trunk/drivers/infiniband/hw/mthca/mthca_catas.c index e948158a28d9..cd044ea2dfa4 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_catas.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_catas.c @@ -57,7 +57,7 @@ static int catas_reset_disable; module_param_named(catas_reset_disable, catas_reset_disable, int, 0644); MODULE_PARM_DESC(catas_reset_disable, "disable reset on catastrophic event if nonzero"); -static void catas_reset(struct work_struct *work) +static void catas_reset(void *work_ptr) { struct mthca_dev *dev, *tmpdev; LIST_HEAD(tlist); @@ -203,7 +203,7 @@ void mthca_stop_catas_poll(struct mthca_dev *dev) int __init mthca_catas_init(void) { - INIT_WORK(&catas_work, catas_reset); + INIT_WORK(&catas_work, catas_reset, NULL); catas_wq = create_singlethread_workqueue("mthca_catas"); if (!catas_wq) diff --git a/trunk/drivers/infiniband/ulp/ipoib/ipoib.h b/trunk/drivers/infiniband/ulp/ipoib/ipoib.h index 99547996aba2..f2b61851a49c 100644 --- a/trunk/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/trunk/drivers/infiniband/ulp/ipoib/ipoib.h @@ -136,11 +136,11 @@ struct ipoib_dev_priv { struct list_head multicast_list; struct rb_root multicast_tree; - struct delayed_work pkey_task; - struct delayed_work mcast_task; + struct work_struct pkey_task; + struct work_struct mcast_task; struct work_struct flush_task; struct work_struct restart_task; - struct delayed_work ah_reap_task; + struct work_struct ah_reap_task; struct ib_device *ca; u8 port; @@ -254,13 +254,13 @@ int ipoib_add_pkey_attr(struct net_device *dev); void ipoib_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_ah *address, u32 qpn); -void ipoib_reap_ah(struct work_struct *work); +void ipoib_reap_ah(void *dev_ptr); void ipoib_flush_paths(struct net_device *dev); struct ipoib_dev_priv *ipoib_intf_alloc(const char *format); int ipoib_ib_dev_init(struct net_device *dev, struct ib_device *ca, int port); -void ipoib_ib_dev_flush(struct work_struct *work); +void ipoib_ib_dev_flush(void *dev); void ipoib_ib_dev_cleanup(struct net_device *dev); int ipoib_ib_dev_open(struct net_device *dev); @@ -271,10 +271,10 @@ int ipoib_ib_dev_stop(struct net_device *dev); int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port); void ipoib_dev_cleanup(struct net_device *dev); -void ipoib_mcast_join_task(struct work_struct *work); +void ipoib_mcast_join_task(void *dev_ptr); void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb); -void ipoib_mcast_restart_task(struct work_struct *work); +void ipoib_mcast_restart_task(void *dev_ptr); int ipoib_mcast_start_thread(struct net_device *dev); int ipoib_mcast_stop_thread(struct net_device *dev, int flush); @@ -312,7 +312,7 @@ void ipoib_event(struct ib_event_handler *handler, int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey); int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey); -void ipoib_pkey_poll(struct work_struct *work); +void ipoib_pkey_poll(void *dev); int ipoib_pkey_dev_delay_open(struct net_device *dev); #ifdef CONFIG_INFINIBAND_IPOIB_DEBUG diff --git a/trunk/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/trunk/drivers/infiniband/ulp/ipoib/ipoib_ib.c index f10fba5d3265..8bf5e9ec7c95 100644 --- a/trunk/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/trunk/drivers/infiniband/ulp/ipoib/ipoib_ib.c @@ -400,11 +400,10 @@ static void __ipoib_reap_ah(struct net_device *dev) spin_unlock_irq(&priv->tx_lock); } -void ipoib_reap_ah(struct work_struct *work) +void ipoib_reap_ah(void *dev_ptr) { - struct ipoib_dev_priv *priv = - container_of(work, struct ipoib_dev_priv, ah_reap_task.work); - struct net_device *dev = priv->dev; + struct net_device *dev = dev_ptr; + struct ipoib_dev_priv *priv = netdev_priv(dev); __ipoib_reap_ah(dev); @@ -614,11 +613,10 @@ int ipoib_ib_dev_init(struct net_device *dev, struct ib_device *ca, int port) return 0; } -void ipoib_ib_dev_flush(struct work_struct *work) +void ipoib_ib_dev_flush(void *_dev) { - struct ipoib_dev_priv *cpriv, *priv = - container_of(work, struct ipoib_dev_priv, flush_task); - struct net_device *dev = priv->dev; + struct net_device *dev = (struct net_device *)_dev; + struct ipoib_dev_priv *priv = netdev_priv(dev), *cpriv; if (!test_bit(IPOIB_FLAG_INITIALIZED, &priv->flags) ) { ipoib_dbg(priv, "Not flushing - IPOIB_FLAG_INITIALIZED not set.\n"); @@ -640,14 +638,14 @@ void ipoib_ib_dev_flush(struct work_struct *work) */ if (test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags)) { ipoib_ib_dev_up(dev); - ipoib_mcast_restart_task(&priv->restart_task); + ipoib_mcast_restart_task(dev); } mutex_lock(&priv->vlan_mutex); /* Flush any child interfaces too */ list_for_each_entry(cpriv, &priv->child_intfs, list) - ipoib_ib_dev_flush(&cpriv->flush_task); + ipoib_ib_dev_flush(cpriv->dev); mutex_unlock(&priv->vlan_mutex); } @@ -674,11 +672,10 @@ void ipoib_ib_dev_cleanup(struct net_device *dev) * change async notification is available. */ -void ipoib_pkey_poll(struct work_struct *work) +void ipoib_pkey_poll(void *dev_ptr) { - struct ipoib_dev_priv *priv = - container_of(work, struct ipoib_dev_priv, pkey_task.work); - struct net_device *dev = priv->dev; + struct net_device *dev = dev_ptr; + struct ipoib_dev_priv *priv = netdev_priv(dev); ipoib_pkey_dev_check_presence(dev); diff --git a/trunk/drivers/infiniband/ulp/ipoib/ipoib_main.c b/trunk/drivers/infiniband/ulp/ipoib/ipoib_main.c index c09280243726..5ba3154320b4 100644 --- a/trunk/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/trunk/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -940,11 +940,11 @@ static void ipoib_setup(struct net_device *dev) INIT_LIST_HEAD(&priv->dead_ahs); INIT_LIST_HEAD(&priv->multicast_list); - INIT_DELAYED_WORK(&priv->pkey_task, ipoib_pkey_poll); - INIT_DELAYED_WORK(&priv->mcast_task, ipoib_mcast_join_task); - INIT_WORK(&priv->flush_task, ipoib_ib_dev_flush); - INIT_WORK(&priv->restart_task, ipoib_mcast_restart_task); - INIT_DELAYED_WORK(&priv->ah_reap_task, ipoib_reap_ah); + INIT_WORK(&priv->pkey_task, ipoib_pkey_poll, priv->dev); + INIT_WORK(&priv->mcast_task, ipoib_mcast_join_task, priv->dev); + INIT_WORK(&priv->flush_task, ipoib_ib_dev_flush, priv->dev); + INIT_WORK(&priv->restart_task, ipoib_mcast_restart_task, priv->dev); + INIT_WORK(&priv->ah_reap_task, ipoib_reap_ah, priv->dev); } struct ipoib_dev_priv *ipoib_intf_alloc(const char *name) diff --git a/trunk/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/trunk/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index b04b72ca32ed..d282d65e3ee0 100644 --- a/trunk/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/trunk/drivers/infiniband/ulp/ipoib/ipoib_multicast.c @@ -399,8 +399,7 @@ static void ipoib_mcast_join_complete(int status, mcast->backoff = 1; mutex_lock(&mcast_mutex); if (test_bit(IPOIB_MCAST_RUN, &priv->flags)) - queue_delayed_work(ipoib_workqueue, - &priv->mcast_task, 0); + queue_work(ipoib_workqueue, &priv->mcast_task); mutex_unlock(&mcast_mutex); complete(&mcast->done); return; @@ -436,8 +435,7 @@ static void ipoib_mcast_join_complete(int status, if (test_bit(IPOIB_MCAST_RUN, &priv->flags)) { if (status == -ETIMEDOUT) - queue_delayed_work(ipoib_workqueue, &priv->mcast_task, - 0); + queue_work(ipoib_workqueue, &priv->mcast_task); else queue_delayed_work(ipoib_workqueue, &priv->mcast_task, mcast->backoff * HZ); @@ -519,11 +517,10 @@ static void ipoib_mcast_join(struct net_device *dev, struct ipoib_mcast *mcast, mcast->query_id = ret; } -void ipoib_mcast_join_task(struct work_struct *work) +void ipoib_mcast_join_task(void *dev_ptr) { - struct ipoib_dev_priv *priv = - container_of(work, struct ipoib_dev_priv, mcast_task.work); - struct net_device *dev = priv->dev; + struct net_device *dev = dev_ptr; + struct ipoib_dev_priv *priv = netdev_priv(dev); if (!test_bit(IPOIB_MCAST_RUN, &priv->flags)) return; @@ -613,7 +610,7 @@ int ipoib_mcast_start_thread(struct net_device *dev) mutex_lock(&mcast_mutex); if (!test_and_set_bit(IPOIB_MCAST_RUN, &priv->flags)) - queue_delayed_work(ipoib_workqueue, &priv->mcast_task, 0); + queue_work(ipoib_workqueue, &priv->mcast_task); mutex_unlock(&mcast_mutex); spin_lock_irq(&priv->lock); @@ -821,11 +818,10 @@ void ipoib_mcast_dev_flush(struct net_device *dev) } } -void ipoib_mcast_restart_task(struct work_struct *work) +void ipoib_mcast_restart_task(void *dev_ptr) { - struct ipoib_dev_priv *priv = - container_of(work, struct ipoib_dev_priv, restart_task); - struct net_device *dev = priv->dev; + struct net_device *dev = dev_ptr; + struct ipoib_dev_priv *priv = netdev_priv(dev); struct dev_mc_list *mclist; struct ipoib_mcast *mcast, *tmcast; LIST_HEAD(remove_list); diff --git a/trunk/drivers/infiniband/ulp/iser/iser_verbs.c b/trunk/drivers/infiniband/ulp/iser/iser_verbs.c index 693b77002897..18a000034996 100644 --- a/trunk/drivers/infiniband/ulp/iser/iser_verbs.c +++ b/trunk/drivers/infiniband/ulp/iser/iser_verbs.c @@ -48,7 +48,7 @@ static void iser_cq_tasklet_fn(unsigned long data); static void iser_cq_callback(struct ib_cq *cq, void *cq_context); -static void iser_comp_error_worker(struct work_struct *work); +static void iser_comp_error_worker(void *data); static void iser_cq_event_callback(struct ib_event *cause, void *context) { @@ -480,7 +480,8 @@ int iser_conn_init(struct iser_conn **ibconn) init_waitqueue_head(&ib_conn->wait); atomic_set(&ib_conn->post_recv_buf_count, 0); atomic_set(&ib_conn->post_send_buf_count, 0); - INIT_WORK(&ib_conn->comperror_work, iser_comp_error_worker); + INIT_WORK(&ib_conn->comperror_work, iser_comp_error_worker, + ib_conn); INIT_LIST_HEAD(&ib_conn->conn_list); spin_lock_init(&ib_conn->lock); @@ -753,10 +754,9 @@ int iser_post_send(struct iser_desc *tx_desc) return ret_val; } -static void iser_comp_error_worker(struct work_struct *work) +static void iser_comp_error_worker(void *data) { - struct iser_conn *ib_conn = - container_of(work, struct iser_conn, comperror_work); + struct iser_conn *ib_conn = data; /* getting here when the state is UP means that the conn is being * * terminated asynchronously from the iSCSI layer's perspective. */ diff --git a/trunk/drivers/infiniband/ulp/srp/ib_srp.c b/trunk/drivers/infiniband/ulp/srp/ib_srp.c index a6289595557b..64ab5fc7cca3 100644 --- a/trunk/drivers/infiniband/ulp/srp/ib_srp.c +++ b/trunk/drivers/infiniband/ulp/srp/ib_srp.c @@ -390,10 +390,9 @@ static void srp_disconnect_target(struct srp_target_port *target) wait_for_completion(&target->done); } -static void srp_remove_work(struct work_struct *work) +static void srp_remove_work(void *target_ptr) { - struct srp_target_port *target = - container_of(work, struct srp_target_port, work); + struct srp_target_port *target = target_ptr; spin_lock_irq(target->scsi_host->host_lock); if (target->state != SRP_TARGET_DEAD) { @@ -576,7 +575,7 @@ static int srp_reconnect_target(struct srp_target_port *target) spin_lock_irq(target->scsi_host->host_lock); if (target->state == SRP_TARGET_CONNECTING) { target->state = SRP_TARGET_DEAD; - INIT_WORK(&target->work, srp_remove_work); + INIT_WORK(&target->work, srp_remove_work, target); schedule_work(&target->work); } spin_unlock_irq(target->scsi_host->host_lock); diff --git a/trunk/drivers/input/keyboard/atkbd.c b/trunk/drivers/input/keyboard/atkbd.c index 8451b29a3db5..cbb93669d1ce 100644 --- a/trunk/drivers/input/keyboard/atkbd.c +++ b/trunk/drivers/input/keyboard/atkbd.c @@ -567,9 +567,9 @@ static int atkbd_set_leds(struct atkbd *atkbd) * interrupt context. */ -static void atkbd_event_work(struct work_struct *work) +static void atkbd_event_work(void *data) { - struct atkbd *atkbd = container_of(work, struct atkbd, event_work); + struct atkbd *atkbd = data; mutex_lock(&atkbd->event_mutex); @@ -943,7 +943,7 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv) atkbd->dev = dev; ps2_init(&atkbd->ps2dev, serio); - INIT_WORK(&atkbd->event_work, atkbd_event_work); + INIT_WORK(&atkbd->event_work, atkbd_event_work, atkbd); mutex_init(&atkbd->event_mutex); switch (serio->id.type) { diff --git a/trunk/drivers/input/keyboard/lkkbd.c b/trunk/drivers/input/keyboard/lkkbd.c index b7f049b45b6b..979b93e33da7 100644 --- a/trunk/drivers/input/keyboard/lkkbd.c +++ b/trunk/drivers/input/keyboard/lkkbd.c @@ -572,9 +572,9 @@ lkkbd_event (struct input_dev *dev, unsigned int type, unsigned int code, * were in. */ static void -lkkbd_reinit (struct work_struct *work) +lkkbd_reinit (void *data) { - struct lkkbd *lk = container_of(work, struct lkkbd, tq); + struct lkkbd *lk = data; int division; unsigned char leds_on = 0; unsigned char leds_off = 0; @@ -651,7 +651,7 @@ lkkbd_connect (struct serio *serio, struct serio_driver *drv) lk->serio = serio; lk->dev = input_dev; - INIT_WORK (&lk->tq, lkkbd_reinit); + INIT_WORK (&lk->tq, lkkbd_reinit, lk); lk->bell_volume = bell_volume; lk->keyclick_volume = keyclick_volume; lk->ctrlclick_volume = ctrlclick_volume; diff --git a/trunk/drivers/input/keyboard/sunkbd.c b/trunk/drivers/input/keyboard/sunkbd.c index 6cd887c5eb0a..cac4781103c3 100644 --- a/trunk/drivers/input/keyboard/sunkbd.c +++ b/trunk/drivers/input/keyboard/sunkbd.c @@ -208,9 +208,9 @@ static int sunkbd_initialize(struct sunkbd *sunkbd) * were in. */ -static void sunkbd_reinit(struct work_struct *work) +static void sunkbd_reinit(void *data) { - struct sunkbd *sunkbd = container_of(work, struct sunkbd, tq); + struct sunkbd *sunkbd = data; wait_event_interruptible_timeout(sunkbd->wait, sunkbd->reset >= 0, HZ); @@ -248,7 +248,7 @@ static int sunkbd_connect(struct serio *serio, struct serio_driver *drv) sunkbd->serio = serio; sunkbd->dev = input_dev; init_waitqueue_head(&sunkbd->wait); - INIT_WORK(&sunkbd->tq, sunkbd_reinit); + INIT_WORK(&sunkbd->tq, sunkbd_reinit, sunkbd); snprintf(sunkbd->phys, sizeof(sunkbd->phys), "%s/input0", serio->phys); serio_set_drvdata(serio, sunkbd); diff --git a/trunk/drivers/input/mouse/psmouse-base.c b/trunk/drivers/input/mouse/psmouse-base.c index 52bb2226ce2f..6f9b2c7cc9c2 100644 --- a/trunk/drivers/input/mouse/psmouse-base.c +++ b/trunk/drivers/input/mouse/psmouse-base.c @@ -888,10 +888,9 @@ static int psmouse_poll(struct psmouse *psmouse) * psmouse_resync() attempts to re-validate current protocol. */ -static void psmouse_resync(struct work_struct *work) +static void psmouse_resync(void *p) { - struct psmouse *parent = NULL, *psmouse = - container_of(work, struct psmouse, resync_work); + struct psmouse *psmouse = p, *parent = NULL; struct serio *serio = psmouse->ps2dev.serio; psmouse_ret_t rc = PSMOUSE_GOOD_DATA; int failed = 0, enabled = 0; @@ -1122,7 +1121,7 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv) goto out; ps2_init(&psmouse->ps2dev, serio); - INIT_WORK(&psmouse->resync_work, psmouse_resync); + INIT_WORK(&psmouse->resync_work, psmouse_resync, psmouse); psmouse->dev = input_dev; snprintf(psmouse->phys, sizeof(psmouse->phys), "%s/input0", serio->phys); diff --git a/trunk/drivers/input/serio/libps2.c b/trunk/drivers/input/serio/libps2.c index b3e84d3bb7f7..e5b1b60757bb 100644 --- a/trunk/drivers/input/serio/libps2.c +++ b/trunk/drivers/input/serio/libps2.c @@ -251,9 +251,9 @@ EXPORT_SYMBOL(ps2_command); * ps2_schedule_command(), to a PS/2 device (keyboard, mouse, etc.) */ -static void ps2_execute_scheduled_command(struct work_struct *work) +static void ps2_execute_scheduled_command(void *data) { - struct ps2work *ps2work = container_of(work, struct ps2work, work); + struct ps2work *ps2work = data; ps2_command(ps2work->ps2dev, ps2work->param, ps2work->command); kfree(ps2work); @@ -278,7 +278,7 @@ int ps2_schedule_command(struct ps2dev *ps2dev, unsigned char *param, int comman ps2work->ps2dev = ps2dev; ps2work->command = command; memcpy(ps2work->param, param, send); - INIT_WORK(&ps2work->work, ps2_execute_scheduled_command); + INIT_WORK(&ps2work->work, ps2_execute_scheduled_command, ps2work); if (!schedule_work(&ps2work->work)) { kfree(ps2work); diff --git a/trunk/drivers/isdn/act2000/capi.c b/trunk/drivers/isdn/act2000/capi.c index 946c38cf6f8a..6ae6eb322111 100644 --- a/trunk/drivers/isdn/act2000/capi.c +++ b/trunk/drivers/isdn/act2000/capi.c @@ -627,10 +627,8 @@ handle_ack(act2000_card *card, act2000_chan *chan, __u8 blocknr) { } void -actcapi_dispatch(struct work_struct *work) +actcapi_dispatch(act2000_card *card) { - struct act2000_card *card = - container_of(work, struct act2000_card, rcv_tq); struct sk_buff *skb; actcapi_msg *msg; __u16 ccmd; diff --git a/trunk/drivers/isdn/act2000/capi.h b/trunk/drivers/isdn/act2000/capi.h index e55f6a931f66..49f453c53c64 100644 --- a/trunk/drivers/isdn/act2000/capi.h +++ b/trunk/drivers/isdn/act2000/capi.h @@ -356,7 +356,7 @@ extern int actcapi_connect_req(act2000_card *, act2000_chan *, char *, char, int extern void actcapi_select_b2_protocol_req(act2000_card *, act2000_chan *); extern void actcapi_disconnect_b3_req(act2000_card *, act2000_chan *); extern void actcapi_connect_resp(act2000_card *, act2000_chan *, __u8); -extern void actcapi_dispatch(struct work_struct *); +extern void actcapi_dispatch(act2000_card *); #ifdef DEBUG_MSG extern void actcapi_debug_msg(struct sk_buff *skb, int); #else diff --git a/trunk/drivers/isdn/act2000/module.c b/trunk/drivers/isdn/act2000/module.c index 90593e2ef872..d89dcde4eade 100644 --- a/trunk/drivers/isdn/act2000/module.c +++ b/trunk/drivers/isdn/act2000/module.c @@ -192,11 +192,8 @@ act2000_set_msn(act2000_card *card, char *eazmsn) } static void -act2000_transmit(struct work_struct *work) +act2000_transmit(struct act2000_card *card) { - struct act2000_card *card = - container_of(work, struct act2000_card, snd_tq); - switch (card->bus) { case ACT2000_BUS_ISA: act2000_isa_send(card); @@ -210,11 +207,8 @@ act2000_transmit(struct work_struct *work) } static void -act2000_receive(struct work_struct *work) +act2000_receive(struct act2000_card *card) { - struct act2000_card *card = - container_of(work, struct act2000_card, poll_tq); - switch (card->bus) { case ACT2000_BUS_ISA: act2000_isa_receive(card); @@ -233,7 +227,7 @@ act2000_poll(unsigned long data) act2000_card * card = (act2000_card *)data; unsigned long flags; - act2000_receive(&card->poll_tq); + act2000_receive(card); spin_lock_irqsave(&card->lock, flags); mod_timer(&card->ptimer, jiffies+3); spin_unlock_irqrestore(&card->lock, flags); @@ -584,9 +578,9 @@ act2000_alloccard(int bus, int port, int irq, char *id) skb_queue_head_init(&card->sndq); skb_queue_head_init(&card->rcvq); skb_queue_head_init(&card->ackq); - INIT_WORK(&card->snd_tq, act2000_transmit); - INIT_WORK(&card->rcv_tq, actcapi_dispatch); - INIT_WORK(&card->poll_tq, act2000_receive); + INIT_WORK(&card->snd_tq, (void *) (void *) act2000_transmit, card); + INIT_WORK(&card->rcv_tq, (void *) (void *) actcapi_dispatch, card); + INIT_WORK(&card->poll_tq, (void *) (void *) act2000_receive, card); init_timer(&card->ptimer); card->interface.owner = THIS_MODULE; card->interface.channels = ACT2000_BCH; diff --git a/trunk/drivers/isdn/capi/kcapi.c b/trunk/drivers/isdn/capi/kcapi.c index 783a25526315..8c4fcb9027b3 100644 --- a/trunk/drivers/isdn/capi/kcapi.c +++ b/trunk/drivers/isdn/capi/kcapi.c @@ -208,10 +208,9 @@ static void notify_down(u32 contr) } } -static void notify_handler(struct work_struct *work) +static void notify_handler(void *data) { - struct capi_notifier *np = - container_of(work, struct capi_notifier, work); + struct capi_notifier *np = data; switch (np->cmd) { case KCI_CONTRUP: @@ -236,7 +235,7 @@ static int notify_push(unsigned int cmd, u32 controller, u16 applid, u32 ncci) if (!np) return -ENOMEM; - INIT_WORK(&np->work, notify_handler); + INIT_WORK(&np->work, notify_handler, np); np->cmd = cmd; np->controller = controller; np->applid = applid; @@ -249,11 +248,10 @@ static int notify_push(unsigned int cmd, u32 controller, u16 applid, u32 ncci) /* -------- Receiver ------------------------------------------ */ -static void recv_handler(struct work_struct *work) +static void recv_handler(void *_ap) { struct sk_buff *skb; - struct capi20_appl *ap = - container_of(work, struct capi20_appl, recv_work); + struct capi20_appl *ap = (struct capi20_appl *) _ap; if ((!ap) || (ap->release_in_progress)) return; @@ -529,7 +527,7 @@ u16 capi20_register(struct capi20_appl *ap) ap->callback = NULL; init_MUTEX(&ap->recv_sem); skb_queue_head_init(&ap->recv_queue); - INIT_WORK(&ap->recv_work, recv_handler); + INIT_WORK(&ap->recv_work, recv_handler, (void *)ap); ap->release_in_progress = 0; write_unlock_irqrestore(&application_lock, flags); diff --git a/trunk/drivers/isdn/hardware/avm/avm_cs.c b/trunk/drivers/isdn/hardware/avm/avm_cs.c index fd5d7364a487..7bbfd85ab793 100644 --- a/trunk/drivers/isdn/hardware/avm/avm_cs.c +++ b/trunk/drivers/isdn/hardware/avm/avm_cs.c @@ -194,11 +194,41 @@ static int avmcs_config(struct pcmcia_device *link) dev = link->priv; + /* + This reads the card's CONFIG tuple to find its configuration + registers. + */ do { - devname[0] = 0; - if (link->prod_id[1]) - strlcpy(devname, link->prod_id[1], sizeof(devname)); + tuple.DesiredTuple = CISTPL_CONFIG; + i = pcmcia_get_first_tuple(link, &tuple); + if (i != CS_SUCCESS) break; + tuple.TupleData = buf; + tuple.TupleDataMax = 64; + tuple.TupleOffset = 0; + i = pcmcia_get_tuple_data(link, &tuple); + if (i != CS_SUCCESS) break; + i = pcmcia_parse_tuple(link, &tuple, &parse); + if (i != CS_SUCCESS) break; + link->conf.ConfigBase = parse.config.base; + } while (0); + if (i != CS_SUCCESS) { + cs_error(link, ParseTuple, i); + return -ENODEV; + } + + do { + + tuple.Attributes = 0; + tuple.TupleData = buf; + tuple.TupleDataMax = 254; + tuple.TupleOffset = 0; + tuple.DesiredTuple = CISTPL_VERS_1; + devname[0] = 0; + if( !first_tuple(link, &tuple, &parse) && parse.version_1.ns > 1 ) { + strlcpy(devname,parse.version_1.str + parse.version_1.ofs[1], + sizeof(devname)); + } /* * find IO port */ diff --git a/trunk/drivers/isdn/hisax/amd7930_fn.c b/trunk/drivers/isdn/hisax/amd7930_fn.c index 3b19caeba258..bec59010bc66 100644 --- a/trunk/drivers/isdn/hisax/amd7930_fn.c +++ b/trunk/drivers/isdn/hisax/amd7930_fn.c @@ -232,10 +232,9 @@ Amd7930_new_ph(struct IsdnCardState *cs) static void -Amd7930_bh(struct work_struct *work) +Amd7930_bh(struct IsdnCardState *cs) { - struct IsdnCardState *cs = - container_of(work, struct IsdnCardState, tqueue); + struct PStack *stptr; if (!cs) @@ -790,7 +789,7 @@ Amd7930_init(struct IsdnCardState *cs) void __devinit setup_Amd7930(struct IsdnCardState *cs) { - INIT_WORK(&cs->tqueue, Amd7930_bh); + INIT_WORK(&cs->tqueue, (void *)(void *) Amd7930_bh, cs); cs->dbusytimer.function = (void *) dbusy_timer_handler; cs->dbusytimer.data = (long) cs; init_timer(&cs->dbusytimer); diff --git a/trunk/drivers/isdn/hisax/avma1_cs.c b/trunk/drivers/isdn/hisax/avma1_cs.c index 876fec6c6be8..ac28e3278ad9 100644 --- a/trunk/drivers/isdn/hisax/avma1_cs.c +++ b/trunk/drivers/isdn/hisax/avma1_cs.c @@ -216,11 +216,41 @@ static int avma1cs_config(struct pcmcia_device *link) DEBUG(0, "avma1cs_config(0x%p)\n", link); + /* + This reads the card's CONFIG tuple to find its configuration + registers. + */ do { - devname[0] = 0; - if (link->prod_id[1]) - strlcpy(devname, link->prod_id[1], sizeof(devname)); + tuple.DesiredTuple = CISTPL_CONFIG; + i = pcmcia_get_first_tuple(link, &tuple); + if (i != CS_SUCCESS) break; + tuple.TupleData = buf; + tuple.TupleDataMax = 64; + tuple.TupleOffset = 0; + i = pcmcia_get_tuple_data(link, &tuple); + if (i != CS_SUCCESS) break; + i = pcmcia_parse_tuple(link, &tuple, &parse); + if (i != CS_SUCCESS) break; + link->conf.ConfigBase = parse.config.base; + } while (0); + if (i != CS_SUCCESS) { + cs_error(link, ParseTuple, i); + return -ENODEV; + } + + do { + + tuple.Attributes = 0; + tuple.TupleData = buf; + tuple.TupleDataMax = 254; + tuple.TupleOffset = 0; + tuple.DesiredTuple = CISTPL_VERS_1; + devname[0] = 0; + if( !first_tuple(link, &tuple, &parse) && parse.version_1.ns > 1 ) { + strlcpy(devname,parse.version_1.str + parse.version_1.ofs[1], + sizeof(devname)); + } /* * find IO port */ diff --git a/trunk/drivers/isdn/hisax/config.c b/trunk/drivers/isdn/hisax/config.c index cede72cdbb31..785b08554fca 100644 --- a/trunk/drivers/isdn/hisax/config.c +++ b/trunk/drivers/isdn/hisax/config.c @@ -1137,6 +1137,7 @@ static int checkcard(int cardnr, char *id, int *busy_flag, struct module *lockow cs->tx_skb = NULL; cs->tx_cnt = 0; cs->event = 0; + cs->tqueue.data = cs; skb_queue_head_init(&cs->rq); skb_queue_head_init(&cs->sq); @@ -1553,7 +1554,7 @@ static void hisax_b_l2l1(struct PStack *st, int pr, void *arg); static int hisax_cardmsg(struct IsdnCardState *cs, int mt, void *arg); static int hisax_bc_setstack(struct PStack *st, struct BCState *bcs); static void hisax_bc_close(struct BCState *bcs); -static void hisax_bh(struct work_struct *work); +static void hisax_bh(struct IsdnCardState *cs); static void EChannel_proc_rcv(struct hisax_d_if *d_if); int hisax_register(struct hisax_d_if *hisax_d_if, struct hisax_b_if *b_if[], @@ -1585,7 +1586,7 @@ int hisax_register(struct hisax_d_if *hisax_d_if, struct hisax_b_if *b_if[], hisax_d_if->cs = cs; cs->hw.hisax_d_if = hisax_d_if; cs->cardmsg = hisax_cardmsg; - INIT_WORK(&cs->tqueue, hisax_bh); + INIT_WORK(&cs->tqueue, (void *)(void *)hisax_bh, cs); cs->channel[0].d_st->l2.l2l1 = hisax_d_l2l1; for (i = 0; i < 2; i++) { cs->bcs[i].BC_SetStack = hisax_bc_setstack; @@ -1617,10 +1618,8 @@ static void hisax_sched_event(struct IsdnCardState *cs, int event) schedule_work(&cs->tqueue); } -static void hisax_bh(struct work_struct *work) +static void hisax_bh(struct IsdnCardState *cs) { - struct IsdnCardState *cs = - container_of(work, struct IsdnCardState, tqueue); struct PStack *st; int pr; diff --git a/trunk/drivers/isdn/hisax/elsa_cs.c b/trunk/drivers/isdn/hisax/elsa_cs.c index 4e180d210faa..e18e75be8ed3 100644 --- a/trunk/drivers/isdn/hisax/elsa_cs.c +++ b/trunk/drivers/isdn/hisax/elsa_cs.c @@ -242,6 +242,23 @@ static int elsa_cs_config(struct pcmcia_device *link) DEBUG(0, "elsa_config(0x%p)\n", link); dev = link->priv; + /* + This reads the card's CONFIG tuple to find its configuration + registers. + */ + tuple.DesiredTuple = CISTPL_CONFIG; + tuple.TupleData = (cisdata_t *)buf; + tuple.TupleDataMax = 255; + tuple.TupleOffset = 0; + tuple.Attributes = 0; + i = first_tuple(link, &tuple, &parse); + if (i != CS_SUCCESS) { + last_fn = ParseTuple; + goto cs_failed; + } + link->conf.ConfigBase = parse.config.base; + link->conf.Present = parse.config.rmask[0]; + tuple.TupleData = (cisdata_t *)buf; tuple.TupleOffset = 0; tuple.TupleDataMax = 255; tuple.Attributes = 0; diff --git a/trunk/drivers/isdn/hisax/hfc4s8s_l1.c b/trunk/drivers/isdn/hisax/hfc4s8s_l1.c index de9b1a4d6bac..d852c9d998b2 100644 --- a/trunk/drivers/isdn/hisax/hfc4s8s_l1.c +++ b/trunk/drivers/isdn/hisax/hfc4s8s_l1.c @@ -1083,9 +1083,8 @@ tx_b_frame(struct hfc4s8s_btype *bch) /* bottom half handler for interrupt */ /*************************************/ static void -hfc4s8s_bh(struct work_struct *work) +hfc4s8s_bh(hfc4s8s_hw * hw) { - hfc4s8s_hw *hw = container_of(work, hfc4s8s_hw, tqueue); u_char b; struct hfc4s8s_l1 *l1p; volatile u_char *fifo_stat; @@ -1551,7 +1550,7 @@ setup_instance(hfc4s8s_hw * hw) goto out; } - INIT_WORK(&hw->tqueue, hfc4s8s_bh); + INIT_WORK(&hw->tqueue, (void *) (void *) hfc4s8s_bh, hw); if (request_irq (hw->irq, hfc4s8s_interrupt, IRQF_SHARED, hw->card_name, hw)) { diff --git a/trunk/drivers/isdn/hisax/hfc_2bds0.c b/trunk/drivers/isdn/hisax/hfc_2bds0.c index 8d9864453a23..6360e8214720 100644 --- a/trunk/drivers/isdn/hisax/hfc_2bds0.c +++ b/trunk/drivers/isdn/hisax/hfc_2bds0.c @@ -549,11 +549,10 @@ setstack_2b(struct PStack *st, struct BCState *bcs) } static void -hfcd_bh(struct work_struct *work) +hfcd_bh(struct IsdnCardState *cs) { - struct IsdnCardState *cs = - container_of(work, struct IsdnCardState, tqueue); - + if (!cs) + return; if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) { switch (cs->dc.hfcd.ph_state) { case (0): @@ -1073,5 +1072,5 @@ set_cs_func(struct IsdnCardState *cs) cs->dbusytimer.function = (void *) hfc_dbusy_timer; cs->dbusytimer.data = (long) cs; init_timer(&cs->dbusytimer); - INIT_WORK(&cs->tqueue, hfcd_bh); + INIT_WORK(&cs->tqueue, (void *)(void *) hfcd_bh, cs); } diff --git a/trunk/drivers/isdn/hisax/hfc_pci.c b/trunk/drivers/isdn/hisax/hfc_pci.c index 5db0a85b827f..93f60b563515 100644 --- a/trunk/drivers/isdn/hisax/hfc_pci.c +++ b/trunk/drivers/isdn/hisax/hfc_pci.c @@ -1506,10 +1506,8 @@ setstack_2b(struct PStack *st, struct BCState *bcs) /* handle L1 state changes */ /***************************/ static void -hfcpci_bh(struct work_struct *work) +hfcpci_bh(struct IsdnCardState *cs) { - struct IsdnCardState *cs = - container_of(work, struct IsdnCardState, tqueue); u_long flags; // struct PStack *stptr; @@ -1724,7 +1722,7 @@ setup_hfcpci(struct IsdnCard *card) Write_hfc(cs, HFCPCI_INT_M2, cs->hw.hfcpci.int_m2); /* At this point the needed PCI config is done */ /* fifos are still not enabled */ - INIT_WORK(&cs->tqueue, hfcpci_bh); + INIT_WORK(&cs->tqueue, (void *)(void *) hfcpci_bh, cs); cs->setstack_d = setstack_hfcpci; cs->BC_Send_Data = &hfcpci_send_data; cs->readisac = NULL; diff --git a/trunk/drivers/isdn/hisax/hfc_sx.c b/trunk/drivers/isdn/hisax/hfc_sx.c index 4fd09d21a27f..954d1536db1f 100644 --- a/trunk/drivers/isdn/hisax/hfc_sx.c +++ b/trunk/drivers/isdn/hisax/hfc_sx.c @@ -1251,10 +1251,8 @@ setstack_2b(struct PStack *st, struct BCState *bcs) /* handle L1 state changes */ /***************************/ static void -hfcsx_bh(struct work_struct *work) +hfcsx_bh(struct IsdnCardState *cs) { - struct IsdnCardState *cs = - container_of(work, struct IsdnCardState, tqueue); u_long flags; if (!cs) @@ -1501,7 +1499,7 @@ setup_hfcsx(struct IsdnCard *card) cs->dbusytimer.function = (void *) hfcsx_dbusy_timer; cs->dbusytimer.data = (long) cs; init_timer(&cs->dbusytimer); - INIT_WORK(&cs->tqueue, hfcsx_bh); + INIT_WORK(&cs->tqueue, (void *)(void *) hfcsx_bh, cs); cs->readisac = NULL; cs->writeisac = NULL; cs->readisacfifo = NULL; diff --git a/trunk/drivers/isdn/hisax/icc.c b/trunk/drivers/isdn/hisax/icc.c index 682cac32f259..da706925d54d 100644 --- a/trunk/drivers/isdn/hisax/icc.c +++ b/trunk/drivers/isdn/hisax/icc.c @@ -77,10 +77,8 @@ icc_new_ph(struct IsdnCardState *cs) } static void -icc_bh(struct work_struct *work) +icc_bh(struct IsdnCardState *cs) { - struct IsdnCardState *cs = - container_of(work, struct IsdnCardState, tqueue); struct PStack *stptr; if (!cs) @@ -676,7 +674,7 @@ clear_pending_icc_ints(struct IsdnCardState *cs) void __devinit setup_icc(struct IsdnCardState *cs) { - INIT_WORK(&cs->tqueue, icc_bh); + INIT_WORK(&cs->tqueue, (void *)(void *) icc_bh, cs); cs->dbusytimer.function = (void *) dbusy_timer_handler; cs->dbusytimer.data = (long) cs; init_timer(&cs->dbusytimer); diff --git a/trunk/drivers/isdn/hisax/isac.c b/trunk/drivers/isdn/hisax/isac.c index 4e9f23803dae..282f349408bc 100644 --- a/trunk/drivers/isdn/hisax/isac.c +++ b/trunk/drivers/isdn/hisax/isac.c @@ -81,10 +81,8 @@ isac_new_ph(struct IsdnCardState *cs) } static void -isac_bh(struct work_struct *work) +isac_bh(struct IsdnCardState *cs) { - struct IsdnCardState *cs = - container_of(work, struct IsdnCardState, tqueue); struct PStack *stptr; if (!cs) @@ -676,7 +674,7 @@ clear_pending_isac_ints(struct IsdnCardState *cs) void __devinit setup_isac(struct IsdnCardState *cs) { - INIT_WORK(&cs->tqueue, isac_bh); + INIT_WORK(&cs->tqueue, (void *)(void *) isac_bh, cs); cs->dbusytimer.function = (void *) dbusy_timer_handler; cs->dbusytimer.data = (long) cs; init_timer(&cs->dbusytimer); diff --git a/trunk/drivers/isdn/hisax/isar.c b/trunk/drivers/isdn/hisax/isar.c index 6f1a6583b17d..674af673ff96 100644 --- a/trunk/drivers/isdn/hisax/isar.c +++ b/trunk/drivers/isdn/hisax/isar.c @@ -437,10 +437,8 @@ extern void BChannel_bh(struct BCState *); #define B_LL_OK 10 static void -isar_bh(struct work_struct *work) +isar_bh(struct BCState *bcs) { - struct BCState *bcs = container_of(work, struct BCState, tqueue); - BChannel_bh(bcs); if (test_and_clear_bit(B_LL_NOCARRIER, &bcs->event)) ll_deliver_faxstat(bcs, ISDN_FAX_CLASS1_NOCARR); @@ -1582,7 +1580,7 @@ isar_setup(struct IsdnCardState *cs) cs->bcs[i].mode = 0; cs->bcs[i].hw.isar.dpath = i + 1; modeisar(&cs->bcs[i], 0, 0); - INIT_WORK(&cs->bcs[i].tqueue, isar_bh); + INIT_WORK(&cs->bcs[i].tqueue, (void *)(void *) isar_bh, &cs->bcs[i]); } } diff --git a/trunk/drivers/isdn/hisax/isdnl1.c b/trunk/drivers/isdn/hisax/isdnl1.c index a14204ec88ee..bab356886483 100644 --- a/trunk/drivers/isdn/hisax/isdnl1.c +++ b/trunk/drivers/isdn/hisax/isdnl1.c @@ -315,10 +315,8 @@ BChannel_proc_ack(struct BCState *bcs) } void -BChannel_bh(struct work_struct *work) +BChannel_bh(struct BCState *bcs) { - struct BCState *bcs = container_of(work, struct BCState, tqueue); - if (!bcs) return; if (test_and_clear_bit(B_RCVBUFREADY, &bcs->event)) @@ -364,7 +362,7 @@ init_bcstate(struct IsdnCardState *cs, int bc) bcs->cs = cs; bcs->channel = bc; - INIT_WORK(&bcs->tqueue, BChannel_bh); + INIT_WORK(&bcs->tqueue, (void *)(void *) BChannel_bh, bcs); spin_lock_init(&bcs->aclock); bcs->BC_SetStack = NULL; bcs->BC_Close = NULL; diff --git a/trunk/drivers/isdn/hisax/sedlbauer_cs.c b/trunk/drivers/isdn/hisax/sedlbauer_cs.c index 46ed65334c51..f9c14a2970bc 100644 --- a/trunk/drivers/isdn/hisax/sedlbauer_cs.c +++ b/trunk/drivers/isdn/hisax/sedlbauer_cs.c @@ -233,10 +233,20 @@ static int sedlbauer_config(struct pcmcia_device *link) DEBUG(0, "sedlbauer_config(0x%p)\n", link); + /* + This reads the card's CONFIG tuple to find its configuration + registers. + */ + tuple.DesiredTuple = CISTPL_CONFIG; tuple.Attributes = 0; tuple.TupleData = buf; tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + link->conf.ConfigBase = parse.config.base; + link->conf.Present = parse.config.rmask[0]; CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &conf)); diff --git a/trunk/drivers/isdn/hisax/teles_cs.c b/trunk/drivers/isdn/hisax/teles_cs.c index 6b754f183796..afcc2aeadb34 100644 --- a/trunk/drivers/isdn/hisax/teles_cs.c +++ b/trunk/drivers/isdn/hisax/teles_cs.c @@ -232,6 +232,23 @@ static int teles_cs_config(struct pcmcia_device *link) DEBUG(0, "teles_config(0x%p)\n", link); dev = link->priv; + /* + This reads the card's CONFIG tuple to find its configuration + registers. + */ + tuple.DesiredTuple = CISTPL_CONFIG; + tuple.TupleData = (cisdata_t *)buf; + tuple.TupleDataMax = 255; + tuple.TupleOffset = 0; + tuple.Attributes = 0; + i = first_tuple(link, &tuple, &parse); + if (i != CS_SUCCESS) { + last_fn = ParseTuple; + goto cs_failed; + } + link->conf.ConfigBase = parse.config.base; + link->conf.Present = parse.config.rmask[0]; + tuple.TupleData = (cisdata_t *)buf; tuple.TupleOffset = 0; tuple.TupleDataMax = 255; tuple.Attributes = 0; diff --git a/trunk/drivers/isdn/hisax/w6692.c b/trunk/drivers/isdn/hisax/w6692.c index 3aeceaf9769e..1655341797a9 100644 --- a/trunk/drivers/isdn/hisax/w6692.c +++ b/trunk/drivers/isdn/hisax/w6692.c @@ -101,10 +101,8 @@ W6692_new_ph(struct IsdnCardState *cs) } static void -W6692_bh(struct work_struct *work) +W6692_bh(struct IsdnCardState *cs) { - struct IsdnCardState *cs = - container_of(work, struct IsdnCardState, tqueue); struct PStack *stptr; if (!cs) @@ -1072,7 +1070,7 @@ setup_w6692(struct IsdnCard *card) id_list[cs->subtyp].card_name, cs->irq, cs->hw.w6692.iobase); - INIT_WORK(&cs->tqueue, W6692_bh); + INIT_WORK(&cs->tqueue, (void *)(void *) W6692_bh, cs); cs->readW6692 = &ReadW6692; cs->writeW6692 = &WriteW6692; cs->readisacfifo = &ReadISACfifo; diff --git a/trunk/drivers/isdn/i4l/isdn_net.c b/trunk/drivers/isdn/i4l/isdn_net.c index 2e4daebfb7e0..1f8d6ae66b41 100644 --- a/trunk/drivers/isdn/i4l/isdn_net.c +++ b/trunk/drivers/isdn/i4l/isdn_net.c @@ -984,9 +984,9 @@ void isdn_net_write_super(isdn_net_local *lp, struct sk_buff *skb) /* * called from tq_immediate */ -static void isdn_net_softint(struct work_struct *work) +static void isdn_net_softint(void *private) { - isdn_net_local *lp = container_of(work, isdn_net_local, tqueue); + isdn_net_local *lp = private; struct sk_buff *skb; spin_lock_bh(&lp->xmit_lock); @@ -2596,7 +2596,7 @@ isdn_net_new(char *name, struct net_device *master) netdev->local->netdev = netdev; netdev->local->next = netdev->local; - INIT_WORK(&netdev->local->tqueue, isdn_net_softint); + INIT_WORK(&netdev->local->tqueue, (void *)(void *) isdn_net_softint, netdev->local); spin_lock_init(&netdev->local->xmit_lock); netdev->local->isdn_device = -1; diff --git a/trunk/drivers/isdn/pcbit/drv.c b/trunk/drivers/isdn/pcbit/drv.c index 1966f3410a13..6ead5e1508b7 100644 --- a/trunk/drivers/isdn/pcbit/drv.c +++ b/trunk/drivers/isdn/pcbit/drv.c @@ -68,6 +68,8 @@ static void pcbit_set_msn(struct pcbit_dev *dev, char *list); static int pcbit_check_msn(struct pcbit_dev *dev, char *msn); +extern void pcbit_deliver(void * data); + int pcbit_init_dev(int board, int mem_base, int irq) { struct pcbit_dev *dev; @@ -127,7 +129,7 @@ int pcbit_init_dev(int board, int mem_base, int irq) memset(dev->b2, 0, sizeof(struct pcbit_chan)); dev->b2->id = 1; - INIT_WORK(&dev->qdelivery, pcbit_deliver); + INIT_WORK(&dev->qdelivery, pcbit_deliver, dev); /* * interrupts diff --git a/trunk/drivers/isdn/pcbit/layer2.c b/trunk/drivers/isdn/pcbit/layer2.c index 0c9f6df873fc..937fd2120381 100644 --- a/trunk/drivers/isdn/pcbit/layer2.c +++ b/trunk/drivers/isdn/pcbit/layer2.c @@ -67,6 +67,7 @@ extern void pcbit_l3_receive(struct pcbit_dev *dev, ulong msg, * Prototypes */ +void pcbit_deliver(void *data); static void pcbit_transmit(struct pcbit_dev *dev); static void pcbit_recv_ack(struct pcbit_dev *dev, unsigned char ack); @@ -298,12 +299,11 @@ pcbit_transmit(struct pcbit_dev *dev) */ void -pcbit_deliver(struct work_struct *work) +pcbit_deliver(void *data) { struct frame_buf *frame; unsigned long flags, msg; - struct pcbit_dev *dev = - container_of(work, struct pcbit_dev, qdelivery); + struct pcbit_dev *dev = (struct pcbit_dev *) data; spin_lock_irqsave(&dev->lock, flags); diff --git a/trunk/drivers/isdn/pcbit/pcbit.h b/trunk/drivers/isdn/pcbit/pcbit.h index 19c18e88ff16..388bacefd23a 100644 --- a/trunk/drivers/isdn/pcbit/pcbit.h +++ b/trunk/drivers/isdn/pcbit/pcbit.h @@ -166,6 +166,4 @@ struct pcbit_ioctl { #define L2_RUNNING 5 #define L2_ERROR 6 -extern void pcbit_deliver(struct work_struct *work); - #endif diff --git a/trunk/drivers/macintosh/rack-meter.c b/trunk/drivers/macintosh/rack-meter.c index 5ed41fe84e57..f1b6f563673a 100644 --- a/trunk/drivers/macintosh/rack-meter.c +++ b/trunk/drivers/macintosh/rack-meter.c @@ -48,8 +48,7 @@ struct rackmeter_dma { } ____cacheline_aligned; struct rackmeter_cpu { - struct delayed_work sniffer; - struct rackmeter *rm; + struct work_struct sniffer; cputime64_t prev_wall; cputime64_t prev_idle; int zero; @@ -209,12 +208,11 @@ static void rackmeter_setup_dbdma(struct rackmeter *rm) rackmeter_do_pause(rm, 0); } -static void rackmeter_do_timer(struct work_struct *work) +static void rackmeter_do_timer(void *data) { - struct rackmeter_cpu *rcpu = - container_of(work, struct rackmeter_cpu, sniffer.work); - struct rackmeter *rm = rcpu->rm; + struct rackmeter *rm = data; unsigned int cpu = smp_processor_id(); + struct rackmeter_cpu *rcpu = &rm->cpu[cpu]; cputime64_t cur_jiffies, total_idle_ticks; unsigned int total_ticks, idle_ticks; int i, offset, load, cumm, pause; @@ -265,10 +263,8 @@ static void __devinit rackmeter_init_cpu_sniffer(struct rackmeter *rm) * on those machines yet */ - rm->cpu[0].rm = rm; - INIT_DELAYED_WORK(&rm->cpu[0].sniffer, rackmeter_do_timer); - rm->cpu[1].rm = rm; - INIT_DELAYED_WORK(&rm->cpu[1].sniffer, rackmeter_do_timer); + INIT_WORK(&rm->cpu[0].sniffer, rackmeter_do_timer, rm); + INIT_WORK(&rm->cpu[1].sniffer, rackmeter_do_timer, rm); for_each_online_cpu(cpu) { struct rackmeter_cpu *rcpu; diff --git a/trunk/drivers/macintosh/smu.c b/trunk/drivers/macintosh/smu.c index 6dde27ab79a8..4f724cdd2efa 100644 --- a/trunk/drivers/macintosh/smu.c +++ b/trunk/drivers/macintosh/smu.c @@ -601,7 +601,7 @@ core_initcall(smu_late_init); * sysfs visibility */ -static void smu_expose_childs(struct work_struct *unused) +static void smu_expose_childs(void *unused) { struct device_node *np; @@ -611,7 +611,7 @@ static void smu_expose_childs(struct work_struct *unused) &smu->of_dev->dev); } -static DECLARE_WORK(smu_expose_childs_work, smu_expose_childs); +static DECLARE_WORK(smu_expose_childs_work, smu_expose_childs, NULL); static int smu_platform_probe(struct of_device* dev, const struct of_device_id *match) diff --git a/trunk/drivers/md/dm-crypt.c b/trunk/drivers/md/dm-crypt.c index ed2d4ef27fd8..08a40f4e4f60 100644 --- a/trunk/drivers/md/dm-crypt.c +++ b/trunk/drivers/md/dm-crypt.c @@ -458,11 +458,11 @@ static void dec_pending(struct crypt_io *io, int error) * interrupt context. */ static struct workqueue_struct *_kcryptd_workqueue; -static void kcryptd_do_work(struct work_struct *work); +static void kcryptd_do_work(void *data); static void kcryptd_queue_io(struct crypt_io *io) { - INIT_WORK(&io->work, kcryptd_do_work); + INIT_WORK(&io->work, kcryptd_do_work, io); queue_work(_kcryptd_workqueue, &io->work); } @@ -618,9 +618,9 @@ static void process_read_endio(struct crypt_io *io) dec_pending(io, crypt_convert(cc, &ctx)); } -static void kcryptd_do_work(struct work_struct *work) +static void kcryptd_do_work(void *data) { - struct crypt_io *io = container_of(work, struct crypt_io, work); + struct crypt_io *io = data; if (io->post_process) process_read_endio(io); diff --git a/trunk/drivers/md/dm-mpath.c b/trunk/drivers/md/dm-mpath.c index e77ee6fd1044..d754e0bc6e90 100644 --- a/trunk/drivers/md/dm-mpath.c +++ b/trunk/drivers/md/dm-mpath.c @@ -104,8 +104,8 @@ typedef int (*action_fn) (struct pgpath *pgpath); static kmem_cache_t *_mpio_cache; struct workqueue_struct *kmultipathd; -static void process_queued_ios(struct work_struct *work); -static void trigger_event(struct work_struct *work); +static void process_queued_ios(void *data); +static void trigger_event(void *data); /*----------------------------------------------- @@ -173,8 +173,8 @@ static struct multipath *alloc_multipath(struct dm_target *ti) INIT_LIST_HEAD(&m->priority_groups); spin_lock_init(&m->lock); m->queue_io = 1; - INIT_WORK(&m->process_queued_ios, process_queued_ios); - INIT_WORK(&m->trigger_event, trigger_event); + INIT_WORK(&m->process_queued_ios, process_queued_ios, m); + INIT_WORK(&m->trigger_event, trigger_event, m); m->mpio_pool = mempool_create_slab_pool(MIN_IOS, _mpio_cache); if (!m->mpio_pool) { kfree(m); @@ -379,10 +379,9 @@ static void dispatch_queued_ios(struct multipath *m) } } -static void process_queued_ios(struct work_struct *work) +static void process_queued_ios(void *data) { - struct multipath *m = - container_of(work, struct multipath, process_queued_ios); + struct multipath *m = (struct multipath *) data; struct hw_handler *hwh = &m->hw_handler; struct pgpath *pgpath = NULL; unsigned init_required = 0, must_queue = 1; @@ -422,10 +421,9 @@ static void process_queued_ios(struct work_struct *work) * An event is triggered whenever a path is taken out of use. * Includes path failure and PG bypass. */ -static void trigger_event(struct work_struct *work) +static void trigger_event(void *data) { - struct multipath *m = - container_of(work, struct multipath, trigger_event); + struct multipath *m = (struct multipath *) data; dm_table_event(m->ti->table); } diff --git a/trunk/drivers/md/dm-raid1.c b/trunk/drivers/md/dm-raid1.c index fc8cbb168e3e..48a653b3f518 100644 --- a/trunk/drivers/md/dm-raid1.c +++ b/trunk/drivers/md/dm-raid1.c @@ -883,7 +883,7 @@ static void do_mirror(struct mirror_set *ms) do_writes(ms, &writes); } -static void do_work(struct work_struct *ignored) +static void do_work(void *ignored) { struct mirror_set *ms; @@ -1269,7 +1269,7 @@ static int __init dm_mirror_init(void) dm_dirty_log_exit(); return r; } - INIT_WORK(&_kmirrord_work, do_work); + INIT_WORK(&_kmirrord_work, do_work, NULL); r = dm_register_target(&mirror_target); if (r < 0) { diff --git a/trunk/drivers/md/dm-snap.c b/trunk/drivers/md/dm-snap.c index 91c7aa1fed0e..5281e0094072 100644 --- a/trunk/drivers/md/dm-snap.c +++ b/trunk/drivers/md/dm-snap.c @@ -40,7 +40,7 @@ #define SNAPSHOT_PAGES 256 struct workqueue_struct *ksnapd; -static void flush_queued_bios(struct work_struct *work); +static void flush_queued_bios(void *data); struct pending_exception { struct exception e; @@ -528,7 +528,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) } bio_list_init(&s->queued_bios); - INIT_WORK(&s->queued_bios_work, flush_queued_bios); + INIT_WORK(&s->queued_bios_work, flush_queued_bios, s); /* Add snapshot to the list of snapshots for this origin */ /* Exceptions aren't triggered till snapshot_resume() is called */ @@ -603,10 +603,9 @@ static void flush_bios(struct bio *bio) } } -static void flush_queued_bios(struct work_struct *work) +static void flush_queued_bios(void *data) { - struct dm_snapshot *s = - container_of(work, struct dm_snapshot, queued_bios_work); + struct dm_snapshot *s = (struct dm_snapshot *) data; struct bio *queued_bios; unsigned long flags; diff --git a/trunk/drivers/md/kcopyd.c b/trunk/drivers/md/kcopyd.c index b3c01496c737..f1db6eff4857 100644 --- a/trunk/drivers/md/kcopyd.c +++ b/trunk/drivers/md/kcopyd.c @@ -417,7 +417,7 @@ static int process_jobs(struct list_head *jobs, int (*fn) (struct kcopyd_job *)) /* * kcopyd does this every time it's woken up. */ -static void do_work(struct work_struct *ignored) +static void do_work(void *ignored) { /* * The order that these are called is *very* important. @@ -628,7 +628,7 @@ static int kcopyd_init(void) } kcopyd_clients++; - INIT_WORK(&_kcopyd_work, do_work); + INIT_WORK(&_kcopyd_work, do_work, NULL); mutex_unlock(&kcopyd_init_lock); return 0; } diff --git a/trunk/drivers/media/dvb/b2c2/flexcop-pci.c b/trunk/drivers/media/dvb/b2c2/flexcop-pci.c index 6e166801505d..06893243f3d4 100644 --- a/trunk/drivers/media/dvb/b2c2/flexcop-pci.c +++ b/trunk/drivers/media/dvb/b2c2/flexcop-pci.c @@ -63,7 +63,7 @@ struct flexcop_pci { unsigned long last_irq; - struct delayed_work irq_check_work; + struct work_struct irq_check_work; struct flexcop_device *fc_dev; }; @@ -97,10 +97,9 @@ static int flexcop_pci_write_ibi_reg(struct flexcop_device *fc, flexcop_ibi_regi return 0; } -static void flexcop_pci_irq_check_work(struct work_struct *work) +static void flexcop_pci_irq_check_work(void *data) { - struct flexcop_pci *fc_pci = - container_of(work, struct flexcop_pci, irq_check_work.work); + struct flexcop_pci *fc_pci = data; struct flexcop_device *fc = fc_pci->fc_dev; flexcop_ibi_value v = fc->read_ibi_reg(fc,sram_dest_reg_714); @@ -372,7 +371,7 @@ static int flexcop_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e if ((ret = flexcop_pci_dma_init(fc_pci)) != 0) goto err_fc_exit; - INIT_DELAYED_WORK(&fc_pci->irq_check_work, flexcop_pci_irq_check_work); + INIT_WORK(&fc_pci->irq_check_work, flexcop_pci_irq_check_work, fc_pci); return ret; diff --git a/trunk/drivers/media/dvb/cinergyT2/cinergyT2.c b/trunk/drivers/media/dvb/cinergyT2/cinergyT2.c index 206c13e47a06..8a7dd507cf6e 100644 --- a/trunk/drivers/media/dvb/cinergyT2/cinergyT2.c +++ b/trunk/drivers/media/dvb/cinergyT2/cinergyT2.c @@ -128,7 +128,7 @@ struct cinergyt2 { struct dvbt_set_parameters_msg param; struct dvbt_get_status_msg status; - struct delayed_work query_work; + struct work_struct query_work; wait_queue_head_t poll_wq; int pending_fe_events; @@ -142,7 +142,7 @@ struct cinergyt2 { #ifdef ENABLE_RC struct input_dev *rc_input_dev; char phys[64]; - struct delayed_work rc_query_work; + struct work_struct rc_query_work; int rc_input_event; u32 rc_last_code; unsigned long last_event_jiffies; @@ -723,10 +723,9 @@ static struct dvb_device cinergyt2_fe_template = { #ifdef ENABLE_RC -static void cinergyt2_query_rc (struct work_struct *work) +static void cinergyt2_query_rc (void *data) { - struct cinergyt2 *cinergyt2 = - container_of(work, struct cinergyt2, rc_query_work.work); + struct cinergyt2 *cinergyt2 = data; char buf[1] = { CINERGYT2_EP1_GET_RC_EVENTS }; struct cinergyt2_rc_event rc_events[12]; int n, len, i; @@ -807,7 +806,7 @@ static int cinergyt2_register_rc(struct cinergyt2 *cinergyt2) strlcat(cinergyt2->phys, "/input0", sizeof(cinergyt2->phys)); cinergyt2->rc_input_event = KEY_MAX; cinergyt2->rc_last_code = ~0; - INIT_DELAYED_WORK(&cinergyt2->rc_query_work, cinergyt2_query_rc); + INIT_WORK(&cinergyt2->rc_query_work, cinergyt2_query_rc, cinergyt2); input_dev->name = DRIVER_NAME " remote control"; input_dev->phys = cinergyt2->phys; @@ -848,10 +847,9 @@ static inline void cinergyt2_resume_rc(struct cinergyt2 *cinergyt2) { } #endif /* ENABLE_RC */ -static void cinergyt2_query (struct work_struct *work) +static void cinergyt2_query (void *data) { - struct cinergyt2 *cinergyt2 = - container_of(work, struct cinergyt2, query_work.work); + struct cinergyt2 *cinergyt2 = (struct cinergyt2 *) data; char cmd [] = { CINERGYT2_EP1_GET_TUNER_STATUS }; struct dvbt_get_status_msg *s = &cinergyt2->status; uint8_t lock_bits; @@ -895,7 +893,7 @@ static int cinergyt2_probe (struct usb_interface *intf, mutex_init(&cinergyt2->sem); init_waitqueue_head (&cinergyt2->poll_wq); - INIT_DELAYED_WORK(&cinergyt2->query_work, cinergyt2_query); + INIT_WORK(&cinergyt2->query_work, cinergyt2_query, cinergyt2); cinergyt2->udev = interface_to_usbdev(intf); cinergyt2->param.cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS; diff --git a/trunk/drivers/media/dvb/dvb-core/dvb_net.c b/trunk/drivers/media/dvb/dvb-core/dvb_net.c index ebf4dc5190f6..8859ab74f0fe 100644 --- a/trunk/drivers/media/dvb/dvb-core/dvb_net.c +++ b/trunk/drivers/media/dvb/dvb-core/dvb_net.c @@ -127,7 +127,6 @@ struct dvb_net_priv { int in_use; struct net_device_stats stats; u16 pid; - struct net_device *net; struct dvb_net *host; struct dmx_demux *demux; struct dmx_section_feed *secfeed; @@ -1124,11 +1123,10 @@ static int dvb_set_mc_filter (struct net_device *dev, struct dev_mc_list *mc) } -static void wq_set_multicast_list (struct work_struct *work) +static void wq_set_multicast_list (void *data) { - struct dvb_net_priv *priv = - container_of(work, struct dvb_net_priv, set_multicast_list_wq); - struct net_device *dev = priv->net; + struct net_device *dev = data; + struct dvb_net_priv *priv = dev->priv; dvb_net_feed_stop(dev); priv->rx_mode = RX_MODE_UNI; @@ -1169,11 +1167,9 @@ static void dvb_net_set_multicast_list (struct net_device *dev) } -static void wq_restart_net_feed (struct work_struct *work) +static void wq_restart_net_feed (void *data) { - struct dvb_net_priv *priv = - container_of(work, struct dvb_net_priv, restart_net_feed_wq); - struct net_device *dev = priv->net; + struct net_device *dev = data; if (netif_running(dev)) { dvb_net_feed_stop(dev); @@ -1280,7 +1276,6 @@ static int dvb_net_add_if(struct dvb_net *dvbnet, u16 pid, u8 feedtype) dvbnet->device[if_num] = net; priv = net->priv; - priv->net = net; priv->demux = dvbnet->demux; priv->pid = pid; priv->rx_mode = RX_MODE_UNI; @@ -1289,8 +1284,8 @@ static int dvb_net_add_if(struct dvb_net *dvbnet, u16 pid, u8 feedtype) priv->feedtype = feedtype; reset_ule(priv); - INIT_WORK(&priv->set_multicast_list_wq, wq_set_multicast_list); - INIT_WORK(&priv->restart_net_feed_wq, wq_restart_net_feed); + INIT_WORK(&priv->set_multicast_list_wq, wq_set_multicast_list, net); + INIT_WORK(&priv->restart_net_feed_wq, wq_restart_net_feed, net); mutex_init(&priv->mutex); net->base_addr = pid; diff --git a/trunk/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/trunk/drivers/media/dvb/dvb-usb/dvb-usb-remote.c index 794e4471561c..0a3a0b6c2350 100644 --- a/trunk/drivers/media/dvb/dvb-usb/dvb-usb-remote.c +++ b/trunk/drivers/media/dvb/dvb-usb/dvb-usb-remote.c @@ -13,10 +13,9 @@ * * TODO: Fix the repeat rate of the input device. */ -static void dvb_usb_read_remote_control(struct work_struct *work) +static void dvb_usb_read_remote_control(void *data) { - struct dvb_usb_device *d = - container_of(work, struct dvb_usb_device, rc_query_work.work); + struct dvb_usb_device *d = data; u32 event; int state; @@ -129,7 +128,7 @@ int dvb_usb_remote_init(struct dvb_usb_device *d) input_register_device(d->rc_input_dev); - INIT_DELAYED_WORK(&d->rc_query_work, dvb_usb_read_remote_control); + INIT_WORK(&d->rc_query_work, dvb_usb_read_remote_control, d); info("schedule remote query interval to %d msecs.", d->props.rc_interval); schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc_interval)); diff --git a/trunk/drivers/media/dvb/dvb-usb/dvb-usb.h b/trunk/drivers/media/dvb/dvb-usb/dvb-usb.h index 0d721731a524..376c45a8e779 100644 --- a/trunk/drivers/media/dvb/dvb-usb/dvb-usb.h +++ b/trunk/drivers/media/dvb/dvb-usb/dvb-usb.h @@ -369,7 +369,7 @@ struct dvb_usb_device { /* remote control */ struct input_dev *rc_input_dev; char rc_phys[64]; - struct delayed_work rc_query_work; + struct work_struct rc_query_work; u32 last_event; int last_state; diff --git a/trunk/drivers/media/video/cpia_pp.c b/trunk/drivers/media/video/cpia_pp.c index b12cec94f4cc..41f4b8d17559 100644 --- a/trunk/drivers/media/video/cpia_pp.c +++ b/trunk/drivers/media/video/cpia_pp.c @@ -82,8 +82,6 @@ struct pp_cam_entry { struct pardevice *pdev; struct parport *port; struct work_struct cb_task; - void (*cb_func)(void *cbdata); - void *cb_data; int open_count; wait_queue_head_t wq_stream; /* image state flags */ @@ -132,20 +130,6 @@ static void cpia_parport_disable_irq( struct parport *port ) { #define PARPORT_CHUNK_SIZE PAGE_SIZE -static void cpia_pp_run_callback(struct work_struct *work) -{ - void (*cb_func)(void *cbdata); - void *cb_data; - struct pp_cam_entry *cam; - - cam = container_of(work, struct pp_cam_entry, cb_task); - cb_func = cam->cb_func; - cb_data = cam->cb_data; - work_release(work); - - cb_func(cb_data); -} - /**************************************************************************** * * CPiA-specific low-level parport functions for nibble uploads @@ -680,9 +664,7 @@ static int cpia_pp_registerCallback(void *privdata, void (*cb)(void *cbdata), vo int retval = 0; if(cam->port->irq != PARPORT_IRQ_NONE) { - cam->cb_func = cb; - cam->cb_data = cbdata; - INIT_WORK_NAR(&cam->cb_task, cpia_pp_run_callback); + INIT_WORK(&cam->cb_task, cb, cbdata); } else { retval = -1; } diff --git a/trunk/drivers/media/video/cx88/cx88-input.c b/trunk/drivers/media/video/cx88/cx88-input.c index e60a0a52e4b2..57e1c024a547 100644 --- a/trunk/drivers/media/video/cx88/cx88-input.c +++ b/trunk/drivers/media/video/cx88/cx88-input.c @@ -145,9 +145,9 @@ static void ir_timer(unsigned long data) schedule_work(&ir->work); } -static void cx88_ir_work(struct work_struct *work) +static void cx88_ir_work(void *data) { - struct cx88_IR *ir = container_of(work, struct cx88_IR, work); + struct cx88_IR *ir = data; unsigned long timeout; cx88_ir_handle_key(ir); @@ -308,7 +308,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) core->ir = ir; if (ir->polling) { - INIT_WORK(&ir->work, cx88_ir_work); + INIT_WORK(&ir->work, cx88_ir_work, ir); init_timer(&ir->timer); ir->timer.function = ir_timer; ir->timer.data = (unsigned long)ir; diff --git a/trunk/drivers/media/video/ir-kbd-i2c.c b/trunk/drivers/media/video/ir-kbd-i2c.c index ab87e7bfe84f..1457b1602221 100644 --- a/trunk/drivers/media/video/ir-kbd-i2c.c +++ b/trunk/drivers/media/video/ir-kbd-i2c.c @@ -268,9 +268,9 @@ static void ir_timer(unsigned long data) schedule_work(&ir->work); } -static void ir_work(struct work_struct *work) +static void ir_work(void *data) { - struct IR_i2c *ir = container_of(work, struct IR_i2c, work); + struct IR_i2c *ir = data; ir_key_poll(ir); mod_timer(&ir->timer, jiffies+HZ/10); } @@ -400,7 +400,7 @@ static int ir_attach(struct i2c_adapter *adap, int addr, ir->input->name,ir->input->phys,adap->name); /* start polling via eventd */ - INIT_WORK(&ir->work, ir_work); + INIT_WORK(&ir->work, ir_work, ir); init_timer(&ir->timer); ir->timer.function = ir_timer; ir->timer.data = (unsigned long)ir; diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-context.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-context.c index cf129746205d..f129f316d20e 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-context.c +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-context.c @@ -45,21 +45,16 @@ static void pvr2_context_trigger_poll(struct pvr2_context *mp) } -static void pvr2_context_poll(struct work_struct *work) +static void pvr2_context_poll(struct pvr2_context *mp) { - struct pvr2_context *mp = - container_of(work, struct pvr2_context, workpoll); pvr2_context_enter(mp); do { pvr2_hdw_poll(mp->hdw); } while (0); pvr2_context_exit(mp); } -static void pvr2_context_setup(struct work_struct *work) +static void pvr2_context_setup(struct pvr2_context *mp) { - struct pvr2_context *mp = - container_of(work, struct pvr2_context, workinit); - pvr2_context_enter(mp); do { if (!pvr2_hdw_dev_ok(mp->hdw)) break; pvr2_hdw_setup(mp->hdw); @@ -97,8 +92,8 @@ struct pvr2_context *pvr2_context_create( } mp->workqueue = create_singlethread_workqueue("pvrusb2"); - INIT_WORK(&mp->workinit, pvr2_context_setup); - INIT_WORK(&mp->workpoll, pvr2_context_poll); + INIT_WORK(&mp->workinit,(void (*)(void*))pvr2_context_setup,mp); + INIT_WORK(&mp->workpoll,(void (*)(void*))pvr2_context_poll,mp); queue_work(mp->workqueue,&mp->workinit); done: return mp; diff --git a/trunk/drivers/media/video/saa6588.c b/trunk/drivers/media/video/saa6588.c index 92eabf88a09b..7b9859c33018 100644 --- a/trunk/drivers/media/video/saa6588.c +++ b/trunk/drivers/media/video/saa6588.c @@ -324,9 +324,9 @@ static void saa6588_timer(unsigned long data) schedule_work(&s->work); } -static void saa6588_work(struct work_struct *work) +static void saa6588_work(void *data) { - struct saa6588 *s = container_of(work, struct saa6588, work); + struct saa6588 *s = (struct saa6588 *)data; saa6588_i2c_poll(s); mod_timer(&s->timer, jiffies + msecs_to_jiffies(20)); @@ -419,7 +419,7 @@ static int saa6588_attach(struct i2c_adapter *adap, int addr, int kind) saa6588_configure(s); /* start polling via eventd */ - INIT_WORK(&s->work, saa6588_work); + INIT_WORK(&s->work, saa6588_work, s); init_timer(&s->timer); s->timer.function = saa6588_timer; s->timer.data = (unsigned long)s; diff --git a/trunk/drivers/media/video/saa7134/saa7134-empress.c b/trunk/drivers/media/video/saa7134/saa7134-empress.c index daaae870a2c4..65d044086ce9 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-empress.c +++ b/trunk/drivers/media/video/saa7134/saa7134-empress.c @@ -343,10 +343,9 @@ static struct video_device saa7134_empress_template = .minor = -1, }; -static void empress_signal_update(struct work_struct *work) +static void empress_signal_update(void* data) { - struct saa7134_dev* dev = - container_of(work, struct saa7134_dev, empress_workqueue); + struct saa7134_dev* dev = (struct saa7134_dev*) data; if (dev->nosignal) { dprintk("no video signal\n"); @@ -379,7 +378,7 @@ static int empress_init(struct saa7134_dev *dev) "%s empress (%s)", dev->name, saa7134_boards[dev->board].name); - INIT_WORK(&dev->empress_workqueue, empress_signal_update); + INIT_WORK(&dev->empress_workqueue, empress_signal_update, (void*) dev); err = video_register_device(dev->empress_dev,VFL_TYPE_GRABBER, empress_nr[dev->nr]); @@ -400,7 +399,7 @@ static int empress_init(struct saa7134_dev *dev) sizeof(struct saa7134_buf), dev); - empress_signal_update(&dev->empress_workqueue); + empress_signal_update(dev); return 0; } diff --git a/trunk/drivers/message/fusion/mptfc.c b/trunk/drivers/message/fusion/mptfc.c index ef2b55e19910..1dd491773150 100644 --- a/trunk/drivers/message/fusion/mptfc.c +++ b/trunk/drivers/message/fusion/mptfc.c @@ -1018,10 +1018,9 @@ mptfc_init_host_attr(MPT_ADAPTER *ioc,int portnum) } static void -mptfc_setup_reset(struct work_struct *work) +mptfc_setup_reset(void *arg) { - MPT_ADAPTER *ioc = - container_of(work, MPT_ADAPTER, fc_setup_reset_work); + MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg; u64 pn; struct mptfc_rport_info *ri; @@ -1044,10 +1043,9 @@ mptfc_setup_reset(struct work_struct *work) } static void -mptfc_rescan_devices(struct work_struct *work) +mptfc_rescan_devices(void *arg) { - MPT_ADAPTER *ioc = - container_of(work, MPT_ADAPTER, fc_rescan_work); + MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg; int ii; u64 pn; struct mptfc_rport_info *ri; @@ -1156,8 +1154,8 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id) } spin_lock_init(&ioc->fc_rescan_work_lock); - INIT_WORK(&ioc->fc_rescan_work, mptfc_rescan_devices); - INIT_WORK(&ioc->fc_setup_reset_work, mptfc_setup_reset); + INIT_WORK(&ioc->fc_rescan_work, mptfc_rescan_devices,(void *)ioc); + INIT_WORK(&ioc->fc_setup_reset_work, mptfc_setup_reset, (void *)ioc); spin_lock_irqsave(&ioc->FreeQlock, flags); diff --git a/trunk/drivers/message/fusion/mptlan.c b/trunk/drivers/message/fusion/mptlan.c index b7c4407c5e3f..314c3a27585d 100644 --- a/trunk/drivers/message/fusion/mptlan.c +++ b/trunk/drivers/message/fusion/mptlan.c @@ -111,8 +111,7 @@ struct mpt_lan_priv { u32 total_received; struct net_device_stats stats; /* Per device statistics */ - struct delayed_work post_buckets_task; - struct net_device *dev; + struct work_struct post_buckets_task; unsigned long post_buckets_active; }; @@ -133,7 +132,7 @@ static int lan_reply (MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, static int mpt_lan_open(struct net_device *dev); static int mpt_lan_reset(struct net_device *dev); static int mpt_lan_close(struct net_device *dev); -static void mpt_lan_post_receive_buckets(struct mpt_lan_priv *priv); +static void mpt_lan_post_receive_buckets(void *dev_id); static void mpt_lan_wake_post_buckets_task(struct net_device *dev, int priority); static int mpt_lan_receive_post_turbo(struct net_device *dev, u32 tmsg); @@ -346,7 +345,7 @@ mpt_lan_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = i; spin_unlock_irqrestore(&priv->rxfidx_lock, flags); } else { - mpt_lan_post_receive_buckets(priv); + mpt_lan_post_receive_buckets(dev); netif_wake_queue(dev); } @@ -442,7 +441,7 @@ mpt_lan_open(struct net_device *dev) dlprintk((KERN_INFO MYNAM "/lo: Finished initializing RcvCtl\n")); - mpt_lan_post_receive_buckets(priv); + mpt_lan_post_receive_buckets(dev); printk(KERN_INFO MYNAM ": %s/%s: interface up & active\n", IOC_AND_NETDEV_NAMES_s_s(dev)); @@ -855,7 +854,7 @@ mpt_lan_wake_post_buckets_task(struct net_device *dev, int priority) if (test_and_set_bit(0, &priv->post_buckets_active) == 0) { if (priority) { - schedule_delayed_work(&priv->post_buckets_task, 0); + schedule_work(&priv->post_buckets_task); } else { schedule_delayed_work(&priv->post_buckets_task, 1); dioprintk((KERN_INFO MYNAM ": post_buckets queued on " @@ -1189,9 +1188,10 @@ mpt_lan_receive_post_reply(struct net_device *dev, /* Simple SGE's only at the moment */ static void -mpt_lan_post_receive_buckets(struct mpt_lan_priv *priv) +mpt_lan_post_receive_buckets(void *dev_id) { - struct net_device *dev = priv->dev; + struct net_device *dev = dev_id; + struct mpt_lan_priv *priv = dev->priv; MPT_ADAPTER *mpt_dev = priv->mpt_dev; MPT_FRAME_HDR *mf; LANReceivePostRequest_t *pRecvReq; @@ -1335,13 +1335,6 @@ mpt_lan_post_receive_buckets(struct mpt_lan_priv *priv) clear_bit(0, &priv->post_buckets_active); } -static void -mpt_lan_post_receive_buckets_work(struct work_struct *work) -{ - mpt_lan_post_receive_buckets(container_of(work, struct mpt_lan_priv, - post_buckets_task.work)); -} - /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ static struct net_device * mpt_register_lan_device (MPT_ADAPTER *mpt_dev, int pnum) @@ -1357,13 +1350,11 @@ mpt_register_lan_device (MPT_ADAPTER *mpt_dev, int pnum) priv = netdev_priv(dev); - priv->dev = dev; priv->mpt_dev = mpt_dev; priv->pnum = pnum; - memset(&priv->post_buckets_task, 0, sizeof(priv->post_buckets_task)); - INIT_DELAYED_WORK(&priv->post_buckets_task, - mpt_lan_post_receive_buckets_work); + memset(&priv->post_buckets_task, 0, sizeof(struct work_struct)); + INIT_WORK(&priv->post_buckets_task, mpt_lan_post_receive_buckets, dev); priv->post_buckets_active = 0; dlprintk((KERN_INFO MYNAM "@%d: bucketlen = %d\n", diff --git a/trunk/drivers/message/fusion/mptsas.c b/trunk/drivers/message/fusion/mptsas.c index 4f0c530e47b0..b752a479f6db 100644 --- a/trunk/drivers/message/fusion/mptsas.c +++ b/trunk/drivers/message/fusion/mptsas.c @@ -2006,10 +2006,9 @@ __mptsas_discovery_work(MPT_ADAPTER *ioc) *(Mutex LOCKED) */ static void -mptsas_discovery_work(struct work_struct *work) +mptsas_discovery_work(void * arg) { - struct mptsas_discovery_event *ev = - container_of(work, struct mptsas_discovery_event, work); + struct mptsas_discovery_event *ev = arg; MPT_ADAPTER *ioc = ev->ioc; mutex_lock(&ioc->sas_discovery_mutex); @@ -2069,9 +2068,9 @@ mptsas_find_phyinfo_by_target(MPT_ADAPTER *ioc, u32 id) * Work queue thread to clear the persitency table */ static void -mptsas_persist_clear_table(struct work_struct *work) +mptsas_persist_clear_table(void * arg) { - MPT_ADAPTER *ioc = container_of(work, MPT_ADAPTER, sas_persist_task); + MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg; mptbase_sas_persist_operation(ioc, MPI_SAS_OP_CLEAR_NOT_PRESENT); } @@ -2094,10 +2093,9 @@ mptsas_reprobe_target(struct scsi_target *starget, int uld_attach) * Work queue thread to handle SAS hotplug events */ static void -mptsas_hotplug_work(struct work_struct *work) +mptsas_hotplug_work(void *arg) { - struct mptsas_hotplug_event *ev = - container_of(work, struct mptsas_hotplug_event, work); + struct mptsas_hotplug_event *ev = arg; MPT_ADAPTER *ioc = ev->ioc; struct mptsas_phyinfo *phy_info; struct sas_rphy *rphy; @@ -2343,7 +2341,7 @@ mptsas_send_sas_event(MPT_ADAPTER *ioc, break; } - INIT_WORK(&ev->work, mptsas_hotplug_work); + INIT_WORK(&ev->work, mptsas_hotplug_work, ev); ev->ioc = ioc; ev->handle = le16_to_cpu(sas_event_data->DevHandle); ev->parent_handle = @@ -2368,7 +2366,7 @@ mptsas_send_sas_event(MPT_ADAPTER *ioc, * Persistent table is full. */ INIT_WORK(&ioc->sas_persist_task, - mptsas_persist_clear_table); + mptsas_persist_clear_table, (void *)ioc); schedule_work(&ioc->sas_persist_task); break; case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA: @@ -2397,7 +2395,7 @@ mptsas_send_raid_event(MPT_ADAPTER *ioc, return; } - INIT_WORK(&ev->work, mptsas_hotplug_work); + INIT_WORK(&ev->work, mptsas_hotplug_work, ev); ev->ioc = ioc; ev->id = raid_event_data->VolumeID; ev->event_type = MPTSAS_IGNORE_EVENT; @@ -2476,7 +2474,7 @@ mptsas_send_discovery_event(MPT_ADAPTER *ioc, ev = kzalloc(sizeof(*ev), GFP_ATOMIC); if (!ev) return; - INIT_WORK(&ev->work, mptsas_discovery_work); + INIT_WORK(&ev->work, mptsas_discovery_work, ev); ev->ioc = ioc; schedule_work(&ev->work); }; @@ -2513,7 +2511,8 @@ mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply) break; case MPI_EVENT_PERSISTENT_TABLE_FULL: INIT_WORK(&ioc->sas_persist_task, - mptsas_persist_clear_table); + mptsas_persist_clear_table, + (void *)ioc); schedule_work(&ioc->sas_persist_task); break; case MPI_EVENT_SAS_DISCOVERY: diff --git a/trunk/drivers/message/fusion/mptspi.c b/trunk/drivers/message/fusion/mptspi.c index f422c0d0621c..e4cc3dd5fc9f 100644 --- a/trunk/drivers/message/fusion/mptspi.c +++ b/trunk/drivers/message/fusion/mptspi.c @@ -646,10 +646,9 @@ struct work_queue_wrapper { int disk; }; -static void mpt_work_wrapper(struct work_struct *work) +static void mpt_work_wrapper(void *data) { - struct work_queue_wrapper *wqw = - container_of(work, struct work_queue_wrapper, work); + struct work_queue_wrapper *wqw = (struct work_queue_wrapper *)data; struct _MPT_SCSI_HOST *hd = wqw->hd; struct Scsi_Host *shost = hd->ioc->sh; struct scsi_device *sdev; @@ -696,7 +695,7 @@ static void mpt_dv_raid(struct _MPT_SCSI_HOST *hd, int disk) disk); return; } - INIT_WORK(&wqw->work, mpt_work_wrapper); + INIT_WORK(&wqw->work, mpt_work_wrapper, wqw); wqw->hd = hd; wqw->disk = disk; @@ -785,10 +784,9 @@ MODULE_DEVICE_TABLE(pci, mptspi_pci_table); * renegotiate for a given target */ static void -mptspi_dv_renegotiate_work(struct work_struct *work) +mptspi_dv_renegotiate_work(void *data) { - struct work_queue_wrapper *wqw = - container_of(work, struct work_queue_wrapper, work); + struct work_queue_wrapper *wqw = (struct work_queue_wrapper *)data; struct _MPT_SCSI_HOST *hd = wqw->hd; struct scsi_device *sdev; @@ -806,7 +804,7 @@ mptspi_dv_renegotiate(struct _MPT_SCSI_HOST *hd) if (!wqw) return; - INIT_WORK(&wqw->work, mptspi_dv_renegotiate_work); + INIT_WORK(&wqw->work, mptspi_dv_renegotiate_work, wqw); wqw->hd = hd; schedule_work(&wqw->work); diff --git a/trunk/drivers/message/i2o/driver.c b/trunk/drivers/message/i2o/driver.c index 7fc7399bd2ec..64130227574f 100644 --- a/trunk/drivers/message/i2o/driver.c +++ b/trunk/drivers/message/i2o/driver.c @@ -232,7 +232,7 @@ int i2o_driver_dispatch(struct i2o_controller *c, u32 m) break; } - INIT_WORK(&evt->work, drv->event); + INIT_WORK(&evt->work, (void (*)(void *))drv->event, evt); queue_work(drv->event_queue, &evt->work); return 1; } diff --git a/trunk/drivers/message/i2o/exec-osm.c b/trunk/drivers/message/i2o/exec-osm.c index 9e529d8dd5cb..a2350640384b 100644 --- a/trunk/drivers/message/i2o/exec-osm.c +++ b/trunk/drivers/message/i2o/exec-osm.c @@ -371,10 +371,8 @@ static int i2o_exec_remove(struct device *dev) * new LCT and if the buffer for the LCT was to small sends a LCT NOTIFY * again, otherwise send LCT NOTIFY to get informed on next LCT change. */ -static void i2o_exec_lct_modified(struct work_struct *_work) +static void i2o_exec_lct_modified(struct i2o_exec_lct_notify_work *work) { - struct i2o_exec_lct_notify_work *work = - container_of(_work, struct i2o_exec_lct_notify_work, work); u32 change_ind = 0; struct i2o_controller *c = work->c; @@ -441,7 +439,8 @@ static int i2o_exec_reply(struct i2o_controller *c, u32 m, work->c = c; - INIT_WORK(&work->work, i2o_exec_lct_modified); + INIT_WORK(&work->work, (void (*)(void *))i2o_exec_lct_modified, + work); queue_work(i2o_exec_driver.event_queue, &work->work); return 1; } @@ -461,15 +460,13 @@ static int i2o_exec_reply(struct i2o_controller *c, u32 m, /** * i2o_exec_event - Event handling function - * @work: Work item in occurring event + * @evt: Event which occurs * * Handles events send by the Executive device. At the moment does not do * anything useful. */ -static void i2o_exec_event(struct work_struct *work) +static void i2o_exec_event(struct i2o_event *evt) { - struct i2o_event *evt = container_of(work, struct i2o_event, work); - if (likely(evt->i2o_dev)) osm_debug("Event received from device: %d\n", evt->i2o_dev->lct_data.tid); diff --git a/trunk/drivers/message/i2o/i2o_block.c b/trunk/drivers/message/i2o/i2o_block.c index 70ae00253321..eaba81bf2eca 100644 --- a/trunk/drivers/message/i2o/i2o_block.c +++ b/trunk/drivers/message/i2o/i2o_block.c @@ -419,18 +419,16 @@ static int i2o_block_prep_req_fn(struct request_queue *q, struct request *req) /** * i2o_block_delayed_request_fn - delayed request queue function - * @work: the delayed request with the queue to start + * delayed_request: the delayed request with the queue to start * * If the request queue is stopped for a disk, and there is no open * request, a new event is created, which calls this function to start * the queue after I2O_BLOCK_REQUEST_TIME. Otherwise the queue will never * be started again. */ -static void i2o_block_delayed_request_fn(struct work_struct *work) +static void i2o_block_delayed_request_fn(void *delayed_request) { - struct i2o_block_delayed_request *dreq = - container_of(work, struct i2o_block_delayed_request, - work.work); + struct i2o_block_delayed_request *dreq = delayed_request; struct request_queue *q = dreq->queue; unsigned long flags; @@ -540,9 +538,8 @@ static int i2o_block_reply(struct i2o_controller *c, u32 m, return 1; }; -static void i2o_block_event(struct work_struct *work) +static void i2o_block_event(struct i2o_event *evt) { - struct i2o_event *evt = container_of(work, struct i2o_event, work); osm_debug("event received\n"); kfree(evt); }; @@ -941,8 +938,8 @@ static void i2o_block_request_fn(struct request_queue *q) continue; dreq->queue = q; - INIT_DELAYED_WORK(&dreq->work, - i2o_block_delayed_request_fn); + INIT_WORK(&dreq->work, i2o_block_delayed_request_fn, + dreq); if (!queue_delayed_work(i2o_block_driver.event_queue, &dreq->work, diff --git a/trunk/drivers/message/i2o/i2o_block.h b/trunk/drivers/message/i2o/i2o_block.h index d9fdc95b440d..4fdaa5bda412 100644 --- a/trunk/drivers/message/i2o/i2o_block.h +++ b/trunk/drivers/message/i2o/i2o_block.h @@ -96,7 +96,7 @@ struct i2o_block_request { /* I2O Block device delayed request */ struct i2o_block_delayed_request { - struct delayed_work work; + struct work_struct work; struct request_queue *queue; }; diff --git a/trunk/drivers/misc/tifm_7xx1.c b/trunk/drivers/misc/tifm_7xx1.c index 2ab7add78f94..1ba8754e9383 100644 --- a/trunk/drivers/misc/tifm_7xx1.c +++ b/trunk/drivers/misc/tifm_7xx1.c @@ -33,10 +33,9 @@ static void tifm_7xx1_eject(struct tifm_adapter *fm, struct tifm_dev *sock) spin_unlock_irqrestore(&fm->lock, flags); } -static void tifm_7xx1_remove_media(struct work_struct *work) +static void tifm_7xx1_remove_media(void *adapter) { - struct tifm_adapter *fm = - container_of(work, struct tifm_adapter, media_remover); + struct tifm_adapter *fm = adapter; unsigned long flags; int cnt; struct tifm_dev *sock; @@ -170,10 +169,9 @@ tifm_7xx1_sock_addr(char __iomem *base_addr, unsigned int sock_num) return base_addr + ((sock_num + 1) << 10); } -static void tifm_7xx1_insert_media(struct work_struct *work) +static void tifm_7xx1_insert_media(void *adapter) { - struct tifm_adapter *fm = - container_of(work, struct tifm_adapter, media_inserter); + struct tifm_adapter *fm = adapter; unsigned long flags; tifm_media_id media_id; char *card_name = "xx"; @@ -263,7 +261,7 @@ static int tifm_7xx1_suspend(struct pci_dev *dev, pm_message_t state) spin_unlock_irqrestore(&fm->lock, flags); flush_workqueue(fm->wq); - tifm_7xx1_remove_media(&fm->media_remover); + tifm_7xx1_remove_media(fm); pci_set_power_state(dev, PCI_D3hot); pci_disable_device(dev); @@ -330,8 +328,8 @@ static int tifm_7xx1_probe(struct pci_dev *dev, if (!fm->sockets) goto err_out_free; - INIT_WORK(&fm->media_inserter, tifm_7xx1_insert_media); - INIT_WORK(&fm->media_remover, tifm_7xx1_remove_media); + INIT_WORK(&fm->media_inserter, tifm_7xx1_insert_media, fm); + INIT_WORK(&fm->media_remover, tifm_7xx1_remove_media, fm); fm->eject = tifm_7xx1_eject; pci_set_drvdata(dev, fm); @@ -386,7 +384,7 @@ static void tifm_7xx1_remove(struct pci_dev *dev) flush_workqueue(fm->wq); - tifm_7xx1_remove_media(&fm->media_remover); + tifm_7xx1_remove_media(fm); writel(TIFM_IRQ_SETALL, fm->addr + FM_CLEAR_INTERRUPT_ENABLE); free_irq(dev->irq, fm); diff --git a/trunk/drivers/mmc/mmc.c b/trunk/drivers/mmc/mmc.c index 6f2a282e2b97..9d190022a490 100644 --- a/trunk/drivers/mmc/mmc.c +++ b/trunk/drivers/mmc/mmc.c @@ -1419,16 +1419,18 @@ static void mmc_setup(struct mmc_host *host) */ void mmc_detect_change(struct mmc_host *host, unsigned long delay) { - mmc_schedule_delayed_work(&host->detect, delay); + if (delay) + mmc_schedule_delayed_work(&host->detect, delay); + else + mmc_schedule_work(&host->detect); } EXPORT_SYMBOL(mmc_detect_change); -static void mmc_rescan(struct work_struct *work) +static void mmc_rescan(void *data) { - struct mmc_host *host = - container_of(work, struct mmc_host, detect.work); + struct mmc_host *host = data; struct list_head *l, *n; unsigned char power_mode; @@ -1511,7 +1513,7 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev) spin_lock_init(&host->lock); init_waitqueue_head(&host->wq); INIT_LIST_HEAD(&host->cards); - INIT_DELAYED_WORK(&host->detect, mmc_rescan); + INIT_WORK(&host->detect, mmc_rescan, host); /* * By default, hosts do not support SGIO or large requests. @@ -1609,7 +1611,7 @@ EXPORT_SYMBOL(mmc_suspend_host); */ int mmc_resume_host(struct mmc_host *host) { - mmc_rescan(&host->detect.work); + mmc_rescan(host); return 0; } diff --git a/trunk/drivers/mmc/mmc.h b/trunk/drivers/mmc/mmc.h index 149affe0b686..cd5e0ab3d84b 100644 --- a/trunk/drivers/mmc/mmc.h +++ b/trunk/drivers/mmc/mmc.h @@ -20,6 +20,6 @@ void mmc_remove_host_sysfs(struct mmc_host *host); void mmc_free_host_sysfs(struct mmc_host *host); int mmc_schedule_work(struct work_struct *work); -int mmc_schedule_delayed_work(struct delayed_work *work, unsigned long delay); +int mmc_schedule_delayed_work(struct work_struct *work, unsigned long delay); void mmc_flush_scheduled_work(void); #endif diff --git a/trunk/drivers/mmc/mmc_sysfs.c b/trunk/drivers/mmc/mmc_sysfs.c index e334acd045bc..ac5329636045 100644 --- a/trunk/drivers/mmc/mmc_sysfs.c +++ b/trunk/drivers/mmc/mmc_sysfs.c @@ -320,10 +320,18 @@ void mmc_free_host_sysfs(struct mmc_host *host) static struct workqueue_struct *workqueue; +/* + * Internal function. Schedule work in the MMC work queue. + */ +int mmc_schedule_work(struct work_struct *work) +{ + return queue_work(workqueue, work); +} + /* * Internal function. Schedule delayed work in the MMC work queue. */ -int mmc_schedule_delayed_work(struct delayed_work *work, unsigned long delay) +int mmc_schedule_delayed_work(struct work_struct *work, unsigned long delay) { return queue_delayed_work(workqueue, work, delay); } diff --git a/trunk/drivers/mmc/tifm_sd.c b/trunk/drivers/mmc/tifm_sd.c index e846499a004c..0fdc55b08a6d 100644 --- a/trunk/drivers/mmc/tifm_sd.c +++ b/trunk/drivers/mmc/tifm_sd.c @@ -99,7 +99,7 @@ struct tifm_sd { struct mmc_request *req; struct work_struct cmd_handler; - struct delayed_work abort_handler; + struct work_struct abort_handler; wait_queue_head_t can_eject; size_t written_blocks; @@ -496,9 +496,9 @@ static void tifm_sd_request(struct mmc_host *mmc, struct mmc_request *mrq) mmc_request_done(mmc, mrq); } -static void tifm_sd_end_cmd(struct work_struct *work) +static void tifm_sd_end_cmd(void *data) { - struct tifm_sd *host = container_of(work, struct tifm_sd, cmd_handler); + struct tifm_sd *host = data; struct tifm_dev *sock = host->dev; struct mmc_host *mmc = tifm_get_drvdata(sock); struct mmc_request *mrq; @@ -608,9 +608,9 @@ static void tifm_sd_request_nodma(struct mmc_host *mmc, struct mmc_request *mrq) mmc_request_done(mmc, mrq); } -static void tifm_sd_end_cmd_nodma(struct work_struct *work) +static void tifm_sd_end_cmd_nodma(void *data) { - struct tifm_sd *host = container_of(work, struct tifm_sd, cmd_handler); + struct tifm_sd *host = (struct tifm_sd*)data; struct tifm_dev *sock = host->dev; struct mmc_host *mmc = tifm_get_drvdata(sock); struct mmc_request *mrq; @@ -661,14 +661,11 @@ static void tifm_sd_end_cmd_nodma(struct work_struct *work) mmc_request_done(mmc, mrq); } -static void tifm_sd_abort(struct work_struct *work) +static void tifm_sd_abort(void *data) { - struct tifm_sd *host = - container_of(work, struct tifm_sd, abort_handler.work); - printk(KERN_ERR DRIVER_NAME ": card failed to respond for a long period of time"); - tifm_eject(host->dev); + tifm_eject(((struct tifm_sd*)data)->dev); } static void tifm_sd_ios(struct mmc_host *mmc, struct mmc_ios *ios) @@ -765,9 +762,9 @@ static struct mmc_host_ops tifm_sd_ops = { .get_ro = tifm_sd_ro }; -static void tifm_sd_register_host(struct work_struct *work) +static void tifm_sd_register_host(void *data) { - struct tifm_sd *host = container_of(work, struct tifm_sd, cmd_handler); + struct tifm_sd *host = (struct tifm_sd*)data; struct tifm_dev *sock = host->dev; struct mmc_host *mmc = tifm_get_drvdata(sock); unsigned long flags; @@ -775,7 +772,8 @@ static void tifm_sd_register_host(struct work_struct *work) spin_lock_irqsave(&sock->lock, flags); host->flags |= HOST_REG; PREPARE_WORK(&host->cmd_handler, - no_dma ? tifm_sd_end_cmd_nodma : tifm_sd_end_cmd); + no_dma ? tifm_sd_end_cmd_nodma : tifm_sd_end_cmd, + data); spin_unlock_irqrestore(&sock->lock, flags); dev_dbg(&sock->dev, "adding host\n"); mmc_add_host(mmc); @@ -801,8 +799,8 @@ static int tifm_sd_probe(struct tifm_dev *sock) host->dev = sock; host->clk_div = 61; init_waitqueue_head(&host->can_eject); - INIT_WORK(&host->cmd_handler, tifm_sd_register_host); - INIT_DELAYED_WORK(&host->abort_handler, tifm_sd_abort); + INIT_WORK(&host->cmd_handler, tifm_sd_register_host, host); + INIT_WORK(&host->abort_handler, tifm_sd_abort, host); tifm_set_drvdata(sock, mmc); sock->signal_irq = tifm_sd_signal_irq; diff --git a/trunk/drivers/net/8139too.c b/trunk/drivers/net/8139too.c index 931028f672de..d02ed51abfcc 100644 --- a/trunk/drivers/net/8139too.c +++ b/trunk/drivers/net/8139too.c @@ -594,7 +594,7 @@ struct rtl8139_private { u32 rx_config; struct rtl_extra_stats xstats; - struct delayed_work thread; + struct work_struct thread; struct mii_if_info mii; unsigned int regs_len; @@ -636,8 +636,8 @@ static struct net_device_stats *rtl8139_get_stats (struct net_device *dev); static void rtl8139_set_rx_mode (struct net_device *dev); static void __set_rx_mode (struct net_device *dev); static void rtl8139_hw_start (struct net_device *dev); -static void rtl8139_thread (struct work_struct *work); -static void rtl8139_tx_timeout_task(struct work_struct *work); +static void rtl8139_thread (void *_data); +static void rtl8139_tx_timeout_task(void *_data); static const struct ethtool_ops rtl8139_ethtool_ops; /* write MMIO register, with flush */ @@ -1010,7 +1010,7 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev, (debug < 0 ? RTL8139_DEF_MSG_ENABLE : ((1 << debug) - 1)); spin_lock_init (&tp->lock); spin_lock_init (&tp->rx_lock); - INIT_DELAYED_WORK(&tp->thread, rtl8139_thread); + INIT_WORK(&tp->thread, rtl8139_thread, dev); tp->mii.dev = dev; tp->mii.mdio_read = mdio_read; tp->mii.mdio_write = mdio_write; @@ -1596,16 +1596,15 @@ static inline void rtl8139_thread_iter (struct net_device *dev, RTL_R8 (Config1)); } -static void rtl8139_thread (struct work_struct *work) +static void rtl8139_thread (void *_data) { - struct rtl8139_private *tp = - container_of(work, struct rtl8139_private, thread.work); - struct net_device *dev = tp->mii.dev; + struct net_device *dev = _data; + struct rtl8139_private *tp = netdev_priv(dev); unsigned long thr_delay = next_tick; if (tp->watchdog_fired) { tp->watchdog_fired = 0; - rtl8139_tx_timeout_task(work); + rtl8139_tx_timeout_task(_data); } else if (rtnl_trylock()) { rtl8139_thread_iter (dev, tp, tp->mmio_addr); rtnl_unlock (); @@ -1647,11 +1646,10 @@ static inline void rtl8139_tx_clear (struct rtl8139_private *tp) /* XXX account for unsent Tx packets in tp->stats.tx_dropped */ } -static void rtl8139_tx_timeout_task (struct work_struct *work) +static void rtl8139_tx_timeout_task (void *_data) { - struct rtl8139_private *tp = - container_of(work, struct rtl8139_private, thread.work); - struct net_device *dev = tp->mii.dev; + struct net_device *dev = _data; + struct rtl8139_private *tp = netdev_priv(dev); void __iomem *ioaddr = tp->mmio_addr; int i; u8 tmp8; @@ -1697,7 +1695,7 @@ static void rtl8139_tx_timeout (struct net_device *dev) struct rtl8139_private *tp = netdev_priv(dev); if (!tp->have_thread) { - INIT_DELAYED_WORK(&tp->thread, rtl8139_tx_timeout_task); + INIT_WORK(&tp->thread, rtl8139_tx_timeout_task, dev); schedule_delayed_work(&tp->thread, next_tick); } else tp->watchdog_fired = 1; diff --git a/trunk/drivers/net/bnx2.c b/trunk/drivers/net/bnx2.c index 5bacb7587df4..fc2f1d1c7ead 100644 --- a/trunk/drivers/net/bnx2.c +++ b/trunk/drivers/net/bnx2.c @@ -4411,9 +4411,9 @@ bnx2_open(struct net_device *dev) } static void -bnx2_reset_task(struct work_struct *work) +bnx2_reset_task(void *data) { - struct bnx2 *bp = container_of(work, struct bnx2, reset_task); + struct bnx2 *bp = data; if (!netif_running(bp->dev)) return; @@ -5702,7 +5702,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) bp->pdev = pdev; spin_lock_init(&bp->phy_lock); - INIT_WORK(&bp->reset_task, bnx2_reset_task); + INIT_WORK(&bp->reset_task, bnx2_reset_task, bp); dev->base_addr = dev->mem_start = pci_resource_start(pdev, 0); mem_len = MB_GET_CID_ADDR(TX_TSS_CID + 1); diff --git a/trunk/drivers/net/cassini.c b/trunk/drivers/net/cassini.c index c8126484c2be..fd2cc13f7d97 100644 --- a/trunk/drivers/net/cassini.c +++ b/trunk/drivers/net/cassini.c @@ -4066,9 +4066,9 @@ static int cas_alloc_rxds(struct cas *cp) return 0; } -static void cas_reset_task(struct work_struct *work) +static void cas_reset_task(void *data) { - struct cas *cp = container_of(work, struct cas, reset_task); + struct cas *cp = (struct cas *) data; #if 0 int pending = atomic_read(&cp->reset_task_pending); #else @@ -5006,7 +5006,7 @@ static int __devinit cas_init_one(struct pci_dev *pdev, atomic_set(&cp->reset_task_pending_spare, 0); atomic_set(&cp->reset_task_pending_mtu, 0); #endif - INIT_WORK(&cp->reset_task, cas_reset_task); + INIT_WORK(&cp->reset_task, cas_reset_task, cp); /* Default link parameters */ if (link_mode >= 0 && link_mode <= 6) diff --git a/trunk/drivers/net/chelsio/common.h b/trunk/drivers/net/chelsio/common.h index 74758d2c7af8..b265941e1372 100644 --- a/trunk/drivers/net/chelsio/common.h +++ b/trunk/drivers/net/chelsio/common.h @@ -279,7 +279,7 @@ struct adapter { struct petp *tp; struct port_info port[MAX_NPORTS]; - struct delayed_work stats_update_task; + struct work_struct stats_update_task; struct timer_list stats_update_timer; spinlock_t tpi_lock; diff --git a/trunk/drivers/net/chelsio/cphy.h b/trunk/drivers/net/chelsio/cphy.h index cf9143499882..60901f25014e 100644 --- a/trunk/drivers/net/chelsio/cphy.h +++ b/trunk/drivers/net/chelsio/cphy.h @@ -91,7 +91,7 @@ struct cphy { int state; /* Link status state machine */ adapter_t *adapter; /* associated adapter */ - struct delayed_work phy_update; + struct work_struct phy_update; u16 bmsr; int count; diff --git a/trunk/drivers/net/chelsio/cxgb2.c b/trunk/drivers/net/chelsio/cxgb2.c index de48eadddbc4..53bec6739812 100644 --- a/trunk/drivers/net/chelsio/cxgb2.c +++ b/trunk/drivers/net/chelsio/cxgb2.c @@ -953,11 +953,10 @@ static void t1_netpoll(struct net_device *dev) * Periodic accumulation of MAC statistics. This is used only if the MAC * does not have any other way to prevent stats counter overflow. */ -static void mac_stats_task(struct work_struct *work) +static void mac_stats_task(void *data) { int i; - struct adapter *adapter = - container_of(work, struct adapter, stats_update_task.work); + struct adapter *adapter = data; for_each_port(adapter, i) { struct port_info *p = &adapter->port[i]; @@ -978,10 +977,9 @@ static void mac_stats_task(struct work_struct *work) /* * Processes elmer0 external interrupts in process context. */ -static void ext_intr_task(struct work_struct *work) +static void ext_intr_task(void *data) { - struct adapter *adapter = - container_of(work, struct adapter, ext_intr_handler_task); + struct adapter *adapter = data; t1_elmer0_ext_intr_handler(adapter); @@ -1115,9 +1113,9 @@ static int __devinit init_one(struct pci_dev *pdev, spin_lock_init(&adapter->mac_lock); INIT_WORK(&adapter->ext_intr_handler_task, - ext_intr_task); - INIT_DELAYED_WORK(&adapter->stats_update_task, - mac_stats_task); + ext_intr_task, adapter); + INIT_WORK(&adapter->stats_update_task, mac_stats_task, + adapter); pci_set_drvdata(pdev, netdev); } diff --git a/trunk/drivers/net/chelsio/my3126.c b/trunk/drivers/net/chelsio/my3126.c index c7731b6f9de3..0b90014d5b3e 100644 --- a/trunk/drivers/net/chelsio/my3126.c +++ b/trunk/drivers/net/chelsio/my3126.c @@ -93,11 +93,9 @@ static int my3126_interrupt_handler(struct cphy *cphy) return cphy_cause_link_change; } -static void my3216_poll(struct work_struct *work) +static void my3216_poll(void *arg) { - struct cphy *cphy = container_of(work, struct cphy, phy_update.work); - - my3126_interrupt_handler(cphy); + my3126_interrupt_handler(arg); } static int my3126_set_loopback(struct cphy *cphy, int on) @@ -173,7 +171,7 @@ static struct cphy *my3126_phy_create(adapter_t *adapter, if (cphy) cphy_init(cphy, adapter, phy_addr, &my3126_ops, mdio_ops); - INIT_DELAYED_WORK(&cphy->phy_update, my3216_poll); + INIT_WORK(&cphy->phy_update, my3216_poll, cphy); cphy->bmsr = 0; return (cphy); diff --git a/trunk/drivers/net/e100.c b/trunk/drivers/net/e100.c index 03bf164f9e8d..3a8df479cbda 100644 --- a/trunk/drivers/net/e100.c +++ b/trunk/drivers/net/e100.c @@ -2102,10 +2102,9 @@ static void e100_tx_timeout(struct net_device *netdev) schedule_work(&nic->tx_timeout_task); } -static void e100_tx_timeout_task(struct work_struct *work) +static void e100_tx_timeout_task(struct net_device *netdev) { - struct nic *nic = container_of(work, struct nic, tx_timeout_task); - struct net_device *netdev = nic->netdev; + struct nic *nic = netdev_priv(netdev); DPRINTK(TX_ERR, DEBUG, "scb.status=0x%02X\n", readb(&nic->csr->scb.status)); @@ -2638,7 +2637,8 @@ static int __devinit e100_probe(struct pci_dev *pdev, nic->blink_timer.function = e100_blink_led; nic->blink_timer.data = (unsigned long)nic; - INIT_WORK(&nic->tx_timeout_task, e100_tx_timeout_task); + INIT_WORK(&nic->tx_timeout_task, + (void (*)(void *))e100_tx_timeout_task, netdev); if((err = e100_alloc(nic))) { DPRINTK(PROBE, ERR, "Cannot alloc driver memory, aborting.\n"); diff --git a/trunk/drivers/net/e1000/e1000_main.c b/trunk/drivers/net/e1000/e1000_main.c index 73f3a85fd238..32dde0adb683 100644 --- a/trunk/drivers/net/e1000/e1000_main.c +++ b/trunk/drivers/net/e1000/e1000_main.c @@ -190,7 +190,7 @@ void e1000_set_ethtool_ops(struct net_device *netdev); static void e1000_enter_82542_rst(struct e1000_adapter *adapter); static void e1000_leave_82542_rst(struct e1000_adapter *adapter); static void e1000_tx_timeout(struct net_device *dev); -static void e1000_reset_task(struct work_struct *work); +static void e1000_reset_task(struct net_device *dev); static void e1000_smartspeed(struct e1000_adapter *adapter); static int e1000_82547_fifo_workaround(struct e1000_adapter *adapter, struct sk_buff *skb); @@ -914,7 +914,8 @@ e1000_probe(struct pci_dev *pdev, adapter->phy_info_timer.function = &e1000_update_phy_info; adapter->phy_info_timer.data = (unsigned long) adapter; - INIT_WORK(&adapter->reset_task, e1000_reset_task); + INIT_WORK(&adapter->reset_task, + (void (*)(void *))e1000_reset_task, netdev); e1000_check_options(adapter); @@ -3305,10 +3306,9 @@ e1000_tx_timeout(struct net_device *netdev) } static void -e1000_reset_task(struct work_struct *work) +e1000_reset_task(struct net_device *netdev) { - struct e1000_adapter *adapter = - container_of(work, struct e1000_adapter, reset_task); + struct e1000_adapter *adapter = netdev_priv(netdev); e1000_reinit_locked(adapter); } diff --git a/trunk/drivers/net/ehea/ehea_main.c b/trunk/drivers/net/ehea/ehea_main.c index 83fa32f72398..6ad696101418 100644 --- a/trunk/drivers/net/ehea/ehea_main.c +++ b/trunk/drivers/net/ehea/ehea_main.c @@ -2224,12 +2224,11 @@ static int ehea_stop(struct net_device *dev) return ret; } -static void ehea_reset_port(struct work_struct *work) +static void ehea_reset_port(void *data) { int ret; - struct ehea_port *port = - container_of(work, struct ehea_port, reset_task); - struct net_device *dev = port->netdev; + struct net_device *dev = data; + struct ehea_port *port = netdev_priv(dev); port->resets++; down(&port->port_lock); @@ -2380,7 +2379,7 @@ static int ehea_setup_single_port(struct ehea_port *port, dev->tx_timeout = &ehea_tx_watchdog; dev->watchdog_timeo = EHEA_WATCH_DOG_TIMEOUT; - INIT_WORK(&port->reset_task, ehea_reset_port); + INIT_WORK(&port->reset_task, ehea_reset_port, dev); ehea_set_ethtool_ops(dev); diff --git a/trunk/drivers/net/hamradio/baycom_epp.c b/trunk/drivers/net/hamradio/baycom_epp.c index 3c33d6f6a6a6..1ed9cccd3c11 100644 --- a/trunk/drivers/net/hamradio/baycom_epp.c +++ b/trunk/drivers/net/hamradio/baycom_epp.c @@ -168,9 +168,8 @@ struct baycom_state { int magic; struct pardevice *pdev; - struct net_device *dev; unsigned int work_running; - struct delayed_work run_work; + struct work_struct run_work; unsigned int modem; unsigned int bitrate; unsigned char stat; @@ -660,18 +659,16 @@ static int receive(struct net_device *dev, int cnt) #define GETTICK(x) #endif /* __i386__ */ -static void epp_bh(struct work_struct *work) +static void epp_bh(struct net_device *dev) { - struct net_device *dev; struct baycom_state *bc; struct parport *pp; unsigned char stat; unsigned char tmp[2]; unsigned int time1 = 0, time2 = 0, time3 = 0; int cnt, cnt2; - - bc = container_of(work, struct baycom_state, run_work.work); - dev = bc->dev; + + bc = netdev_priv(dev); if (!bc->work_running) return; baycom_int_freq(bc); @@ -892,7 +889,7 @@ static int epp_open(struct net_device *dev) return -EBUSY; } dev->irq = /*pp->irq*/ 0; - INIT_DELAYED_WORK(&bc->run_work, epp_bh); + INIT_WORK(&bc->run_work, (void *)(void *)epp_bh, dev); bc->work_running = 1; bc->modem = EPP_CONVENTIONAL; if (eppconfig(bc)) @@ -1216,7 +1213,6 @@ static void __init baycom_epp_dev_setup(struct net_device *dev) /* * initialize part of the baycom_state struct */ - bc->dev = dev; bc->magic = BAYCOM_MAGIC; bc->cfg.fclk = 19666600; bc->cfg.bps = 9600; diff --git a/trunk/drivers/net/irda/mcs7780.c b/trunk/drivers/net/irda/mcs7780.c index f0c61f3b2a82..b32c52ed19d7 100644 --- a/trunk/drivers/net/irda/mcs7780.c +++ b/trunk/drivers/net/irda/mcs7780.c @@ -560,9 +560,9 @@ static inline int mcs_find_endpoints(struct mcs_cb *mcs, return ret; } -static void mcs_speed_work(struct work_struct *work) +static void mcs_speed_work(void *arg) { - struct mcs_cb *mcs = container_of(work, struct mcs_cb, work); + struct mcs_cb *mcs = arg; struct net_device *netdev = mcs->netdev; mcs_speed_change(mcs); @@ -927,7 +927,7 @@ static int mcs_probe(struct usb_interface *intf, irda_qos_bits_to_value(&mcs->qos); /* Speed change work initialisation*/ - INIT_WORK(&mcs->work, mcs_speed_work); + INIT_WORK(&mcs->work, mcs_speed_work, mcs); /* Override the network functions we need to use */ ndev->hard_start_xmit = mcs_hard_xmit; diff --git a/trunk/drivers/net/irda/sir-dev.h b/trunk/drivers/net/irda/sir-dev.h index 2a57bc67ce35..9fa294a546d6 100644 --- a/trunk/drivers/net/irda/sir-dev.h +++ b/trunk/drivers/net/irda/sir-dev.h @@ -22,7 +22,7 @@ struct sir_fsm { struct semaphore sem; - struct delayed_work work; + struct work_struct work; unsigned state, substate; int param; int result; diff --git a/trunk/drivers/net/irda/sir_dev.c b/trunk/drivers/net/irda/sir_dev.c index 17b0c3ab6201..3b5854d10c17 100644 --- a/trunk/drivers/net/irda/sir_dev.c +++ b/trunk/drivers/net/irda/sir_dev.c @@ -100,9 +100,9 @@ static int sirdev_tx_complete_fsm(struct sir_dev *dev) * Both must be unlocked/restarted on completion - but only on final exit. */ -static void sirdev_config_fsm(struct work_struct *work) +static void sirdev_config_fsm(void *data) { - struct sir_dev *dev = container_of(work, struct sir_dev, fsm.work.work); + struct sir_dev *dev = data; struct sir_fsm *fsm = &dev->fsm; int next_state; int ret = -1; @@ -309,8 +309,8 @@ int sirdev_schedule_request(struct sir_dev *dev, int initial_state, unsigned par fsm->param = param; fsm->result = 0; - INIT_DELAYED_WORK(&fsm->work, sirdev_config_fsm); - queue_delayed_work(irda_sir_wq, &fsm->work, 0); + INIT_WORK(&fsm->work, sirdev_config_fsm, dev); + queue_work(irda_sir_wq, &fsm->work); return 0; } diff --git a/trunk/drivers/net/iseries_veth.c b/trunk/drivers/net/iseries_veth.c index d6f4f185bf37..2284e2ce1692 100644 --- a/trunk/drivers/net/iseries_veth.c +++ b/trunk/drivers/net/iseries_veth.c @@ -166,7 +166,7 @@ struct veth_msg { struct veth_lpar_connection { HvLpIndex remote_lp; - struct delayed_work statemachine_wq; + struct work_struct statemachine_wq; struct veth_msg *msgs; int num_events; struct veth_cap_data local_caps; @@ -456,7 +456,7 @@ static struct kobj_type veth_port_ktype = { static inline void veth_kick_statemachine(struct veth_lpar_connection *cnx) { - schedule_delayed_work(&cnx->statemachine_wq, 0); + schedule_work(&cnx->statemachine_wq); } static void veth_take_cap(struct veth_lpar_connection *cnx, @@ -638,11 +638,9 @@ static int veth_process_caps(struct veth_lpar_connection *cnx) } /* FIXME: The gotos here are a bit dubious */ -static void veth_statemachine(struct work_struct *work) +static void veth_statemachine(void *p) { - struct veth_lpar_connection *cnx = - container_of(work, struct veth_lpar_connection, - statemachine_wq.work); + struct veth_lpar_connection *cnx = (struct veth_lpar_connection *)p; int rlp = cnx->remote_lp; int rc; @@ -829,7 +827,7 @@ static int veth_init_connection(u8 rlp) cnx->remote_lp = rlp; spin_lock_init(&cnx->lock); - INIT_DELAYED_WORK(&cnx->statemachine_wq, veth_statemachine); + INIT_WORK(&cnx->statemachine_wq, veth_statemachine, cnx); init_timer(&cnx->ack_timer); cnx->ack_timer.function = veth_timed_ack; diff --git a/trunk/drivers/net/ixgb/ixgb_main.c b/trunk/drivers/net/ixgb/ixgb_main.c index e628126c9c49..7b127212e62b 100644 --- a/trunk/drivers/net/ixgb/ixgb_main.c +++ b/trunk/drivers/net/ixgb/ixgb_main.c @@ -106,7 +106,7 @@ static boolean_t ixgb_clean_rx_irq(struct ixgb_adapter *adapter); static void ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter); void ixgb_set_ethtool_ops(struct net_device *netdev); static void ixgb_tx_timeout(struct net_device *dev); -static void ixgb_tx_timeout_task(struct work_struct *work); +static void ixgb_tx_timeout_task(struct net_device *dev); static void ixgb_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp); static void ixgb_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid); @@ -489,7 +489,8 @@ ixgb_probe(struct pci_dev *pdev, adapter->watchdog_timer.function = &ixgb_watchdog; adapter->watchdog_timer.data = (unsigned long)adapter; - INIT_WORK(&adapter->tx_timeout_task, ixgb_tx_timeout_task); + INIT_WORK(&adapter->tx_timeout_task, + (void (*)(void *))ixgb_tx_timeout_task, netdev); strcpy(netdev->name, "eth%d"); if((err = register_netdev(netdev))) @@ -1492,10 +1493,9 @@ ixgb_tx_timeout(struct net_device *netdev) } static void -ixgb_tx_timeout_task(struct work_struct *work) +ixgb_tx_timeout_task(struct net_device *netdev) { - struct ixgb_adapter *adapter = - container_of(work, struct ixgb_adapter, tx_timeout_task); + struct ixgb_adapter *adapter = netdev_priv(netdev); adapter->tx_timeout_count++; ixgb_down(adapter, TRUE); diff --git a/trunk/drivers/net/myri10ge/myri10ge.c b/trunk/drivers/net/myri10ge/myri10ge.c index 38df42802386..36350e6db1c1 100644 --- a/trunk/drivers/net/myri10ge/myri10ge.c +++ b/trunk/drivers/net/myri10ge/myri10ge.c @@ -2615,10 +2615,9 @@ static u32 myri10ge_read_reboot(struct myri10ge_priv *mgp) * This watchdog is used to check whether the board has suffered * from a parity error and needs to be recovered. */ -static void myri10ge_watchdog(struct work_struct *work) +static void myri10ge_watchdog(void *arg) { - struct myri10ge_priv *mgp = - container_of(work, struct myri10ge_priv, watchdog_work); + struct myri10ge_priv *mgp = arg; u32 reboot; int status; u16 cmd, vendor; @@ -2888,7 +2887,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) (unsigned long)mgp); SET_ETHTOOL_OPS(netdev, &myri10ge_ethtool_ops); - INIT_WORK(&mgp->watchdog_work, myri10ge_watchdog); + INIT_WORK(&mgp->watchdog_work, myri10ge_watchdog, mgp); status = register_netdev(netdev); if (status != 0) { dev_err(&pdev->dev, "register_netdev failed: %d\n", status); diff --git a/trunk/drivers/net/netxen/netxen_nic.h b/trunk/drivers/net/netxen/netxen_nic.h index 9c588af8ab74..d925053fe597 100644 --- a/trunk/drivers/net/netxen/netxen_nic.h +++ b/trunk/drivers/net/netxen/netxen_nic.h @@ -714,7 +714,6 @@ struct netxen_adapter { spinlock_t lock; struct work_struct watchdog_task; struct work_struct tx_timeout_task; - struct net_device *netdev; struct timer_list watchdog_timer; u32 curr_window; @@ -922,7 +921,7 @@ netxen_nic_do_ioctl(struct netxen_adapter *adapter, void *u_data, struct netxen_port *port); int netxen_nic_rx_has_work(struct netxen_adapter *adapter); int netxen_nic_tx_has_work(struct netxen_adapter *adapter); -void netxen_watchdog_task(struct work_struct *work); +void netxen_watchdog_task(unsigned long v); void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid); void netxen_process_cmd_ring(unsigned long data); diff --git a/trunk/drivers/net/netxen/netxen_nic_init.c b/trunk/drivers/net/netxen/netxen_nic_init.c index eae18236aefa..0dca029bc3e5 100644 --- a/trunk/drivers/net/netxen/netxen_nic_init.c +++ b/trunk/drivers/net/netxen/netxen_nic_init.c @@ -710,13 +710,12 @@ static inline int netxen_nic_check_temp(struct netxen_adapter *adapter) return rv; } -void netxen_watchdog_task(struct work_struct *work) +void netxen_watchdog_task(unsigned long v) { int port_num; struct netxen_port *port; struct net_device *netdev; - struct netxen_adapter *adapter = - container_of(work, struct netxen_adapter, watchdog_task); + struct netxen_adapter *adapter = (struct netxen_adapter *)v; if (netxen_nic_check_temp(adapter)) return; diff --git a/trunk/drivers/net/netxen/netxen_nic_main.c b/trunk/drivers/net/netxen/netxen_nic_main.c index df0bb36a1cfb..1cb662d5bd76 100644 --- a/trunk/drivers/net/netxen/netxen_nic_main.c +++ b/trunk/drivers/net/netxen/netxen_nic_main.c @@ -64,7 +64,7 @@ static int netxen_nic_open(struct net_device *netdev); static int netxen_nic_close(struct net_device *netdev); static int netxen_nic_xmit_frame(struct sk_buff *, struct net_device *); static void netxen_tx_timeout(struct net_device *netdev); -static void netxen_tx_timeout_task(struct work_struct *work); +static void netxen_tx_timeout_task(struct net_device *netdev); static void netxen_watchdog(unsigned long); static int netxen_handle_int(struct netxen_adapter *, struct net_device *); static int netxen_nic_ioctl(struct net_device *netdev, @@ -274,7 +274,8 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) adapter->ahw.xg_linkup = 0; adapter->watchdog_timer.function = &netxen_watchdog; adapter->watchdog_timer.data = (unsigned long)adapter; - INIT_WORK(&adapter->watchdog_task, netxen_watchdog_task); + INIT_WORK(&adapter->watchdog_task, + (void (*)(void *))netxen_watchdog_task, adapter); adapter->ahw.pdev = pdev; adapter->proc_cmd_buf_counter = 0; pci_read_config_byte(pdev, PCI_REVISION_ID, &adapter->ahw.revision_id); @@ -378,8 +379,8 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) dev_addr); } } - adapter->netdev = netdev; - INIT_WORK(&adapter->tx_timeout_task, netxen_tx_timeout_task); + INIT_WORK(&adapter->tx_timeout_task, + (void (*)(void *))netxen_tx_timeout_task, netdev); netif_carrier_off(netdev); netif_stop_queue(netdev); @@ -937,20 +938,18 @@ static void netxen_tx_timeout(struct net_device *netdev) schedule_work(&adapter->tx_timeout_task); } -static void netxen_tx_timeout_task(struct work_struct *work) +static void netxen_tx_timeout_task(struct net_device *netdev) { - struct netxen_adapter *adapter = - container_of(work, struct netxen_adapter, tx_timeout_task); - struct net_device *netdev = adapter->netdev; + struct netxen_port *port = (struct netxen_port *)netdev_priv(netdev); unsigned long flags; printk(KERN_ERR "%s %s: transmit timeout, resetting.\n", netxen_nic_driver_name, netdev->name); - spin_lock_irqsave(&adapter->lock, flags); + spin_lock_irqsave(&port->adapter->lock, flags); netxen_nic_close(netdev); netxen_nic_open(netdev); - spin_unlock_irqrestore(&adapter->lock, flags); + spin_unlock_irqrestore(&port->adapter->lock, flags); netdev->trans_start = jiffies; netif_wake_queue(netdev); } diff --git a/trunk/drivers/net/ns83820.c b/trunk/drivers/net/ns83820.c index 312e0e331712..b0127c71a5b6 100644 --- a/trunk/drivers/net/ns83820.c +++ b/trunk/drivers/net/ns83820.c @@ -427,7 +427,6 @@ struct ns83820 { u8 __iomem *base; struct pci_dev *pci_dev; - struct net_device *ndev; #ifdef NS83820_VLAN_ACCEL_SUPPORT struct vlan_group *vlgrp; @@ -632,10 +631,10 @@ static void fastcall rx_refill_atomic(struct net_device *ndev) } /* REFILL */ -static inline void queue_refill(struct work_struct *work) +static inline void queue_refill(void *_dev) { - struct ns83820 *dev = container_of(work, struct ns83820, tq_refill); - struct net_device *ndev = dev->ndev; + struct net_device *ndev = _dev; + struct ns83820 *dev = PRIV(ndev); rx_refill(ndev, GFP_KERNEL); if (dev->rx_info.up) @@ -1842,7 +1841,6 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_ ndev = alloc_etherdev(sizeof(struct ns83820)); dev = PRIV(ndev); - dev->ndev = ndev; err = -ENOMEM; if (!dev) goto out; @@ -1855,7 +1853,7 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_ SET_MODULE_OWNER(ndev); SET_NETDEV_DEV(ndev, &pci_dev->dev); - INIT_WORK(&dev->tq_refill, queue_refill); + INIT_WORK(&dev->tq_refill, queue_refill, ndev); tasklet_init(&dev->rx_tasklet, rx_action, (unsigned long)ndev); err = pci_enable_device(pci_dev); diff --git a/trunk/drivers/net/pcmcia/3c574_cs.c b/trunk/drivers/net/pcmcia/3c574_cs.c index 794cc61819dd..046009928526 100644 --- a/trunk/drivers/net/pcmcia/3c574_cs.c +++ b/trunk/drivers/net/pcmcia/3c574_cs.c @@ -338,6 +338,7 @@ static int tc574_config(struct pcmcia_device *link) struct net_device *dev = link->priv; struct el3_private *lp = netdev_priv(dev); tuple_t tuple; + cisparse_t parse; unsigned short buf[32]; int last_fn, last_ret, i, j; kio_addr_t ioaddr; @@ -349,6 +350,17 @@ static int tc574_config(struct pcmcia_device *link) DEBUG(0, "3c574_config(0x%p)\n", link); + tuple.Attributes = 0; + tuple.DesiredTuple = CISTPL_CONFIG; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + tuple.TupleData = (cisdata_t *)buf; + tuple.TupleDataMax = 64; + tuple.TupleOffset = 0; + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + link->conf.ConfigBase = parse.config.base; + link->conf.Present = parse.config.rmask[0]; + link->io.IOAddrLines = 16; for (i = j = 0; j < 0x400; j += 0x20) { link->io.BasePort1 = j ^ 0x300; @@ -370,10 +382,6 @@ static int tc574_config(struct pcmcia_device *link) /* The 3c574 normally uses an EEPROM for configuration info, including the hardware address. The future products may include a modem chip and put the address in the CIS. */ - tuple.Attributes = 0; - tuple.TupleData = (cisdata_t *)buf; - tuple.TupleDataMax = 64; - tuple.TupleOffset = 0; tuple.DesiredTuple = 0x88; if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) { pcmcia_get_tuple_data(link, &tuple); @@ -389,9 +397,12 @@ static int tc574_config(struct pcmcia_device *link) goto failed; } } - if (link->prod_id[1]) - cardname = link->prod_id[1]; - else + tuple.DesiredTuple = CISTPL_VERS_1; + if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS && + pcmcia_get_tuple_data(link, &tuple) == CS_SUCCESS && + pcmcia_parse_tuple(link, &tuple, &parse) == CS_SUCCESS) { + cardname = parse.version_1.str + parse.version_1.ofs[1]; + } else cardname = "3Com 3c574"; { diff --git a/trunk/drivers/net/pcmcia/3c589_cs.c b/trunk/drivers/net/pcmcia/3c589_cs.c index 1e73ff7d5d8e..231fa2c9ec6c 100644 --- a/trunk/drivers/net/pcmcia/3c589_cs.c +++ b/trunk/drivers/net/pcmcia/3c589_cs.c @@ -253,6 +253,7 @@ static int tc589_config(struct pcmcia_device *link) struct net_device *dev = link->priv; struct el3_private *lp = netdev_priv(dev); tuple_t tuple; + cisparse_t parse; u16 buf[32], *phys_addr; int last_fn, last_ret, i, j, multi = 0, fifo; kio_addr_t ioaddr; @@ -262,16 +263,26 @@ static int tc589_config(struct pcmcia_device *link) phys_addr = (u16 *)dev->dev_addr; tuple.Attributes = 0; + tuple.DesiredTuple = CISTPL_CONFIG; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); tuple.TupleData = (cisdata_t *)buf; tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; - tuple.Attributes = TUPLE_RETURN_COMMON; - + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + link->conf.ConfigBase = parse.config.base; + link->conf.Present = parse.config.rmask[0]; + /* Is this a 3c562? */ - if (link->manf_id != MANFID_3COM) + tuple.DesiredTuple = CISTPL_MANFID; + tuple.Attributes = TUPLE_RETURN_COMMON; + if ((pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) && + (pcmcia_get_tuple_data(link, &tuple) == CS_SUCCESS)) { + if (le16_to_cpu(buf[0]) != MANFID_3COM) printk(KERN_INFO "3c589_cs: hmmm, is this really a " "3Com card??\n"); - multi = (link->card_id == PRODID_3COM_3C562); + multi = (le16_to_cpu(buf[1]) == PRODID_3COM_3C562); + } /* For the 3c562, the base address must be xx00-xx7f */ link->io.IOAddrLines = 16; diff --git a/trunk/drivers/net/pcmcia/axnet_cs.c b/trunk/drivers/net/pcmcia/axnet_cs.c index 6139048f8117..5ddd5742f779 100644 --- a/trunk/drivers/net/pcmcia/axnet_cs.c +++ b/trunk/drivers/net/pcmcia/axnet_cs.c @@ -299,7 +299,11 @@ static int axnet_config(struct pcmcia_device *link) tuple.TupleData = (cisdata_t *)buf; tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; - + tuple.DesiredTuple = CISTPL_CONFIG; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + link->conf.ConfigBase = parse.config.base; /* don't trust the CIS on this; Linksys got it wrong */ link->conf.Present = 0x63; diff --git a/trunk/drivers/net/pcmcia/com20020_cs.c b/trunk/drivers/net/pcmcia/com20020_cs.c index 91f65e91cd5f..48434d7924eb 100644 --- a/trunk/drivers/net/pcmcia/com20020_cs.c +++ b/trunk/drivers/net/pcmcia/com20020_cs.c @@ -249,9 +249,12 @@ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) static int com20020_config(struct pcmcia_device *link) { struct arcnet_local *lp; + tuple_t tuple; + cisparse_t parse; com20020_dev_t *info; struct net_device *dev; int i, last_ret, last_fn; + u_char buf[64]; int ioaddr; info = link->priv; @@ -261,6 +264,16 @@ static int com20020_config(struct pcmcia_device *link) DEBUG(0, "com20020_config(0x%p)\n", link); + tuple.Attributes = 0; + tuple.TupleData = buf; + tuple.TupleDataMax = 64; + tuple.TupleOffset = 0; + tuple.DesiredTuple = CISTPL_CONFIG; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + link->conf.ConfigBase = parse.config.base; + DEBUG(1,"arcnet: baseport1 is %Xh\n", link->io.BasePort1); i = !CS_SUCCESS; if (!link->io.BasePort1) diff --git a/trunk/drivers/net/pcmcia/fmvj18x_cs.c b/trunk/drivers/net/pcmcia/fmvj18x_cs.c index 0d7de617e535..65f6fdf43725 100644 --- a/trunk/drivers/net/pcmcia/fmvj18x_cs.c +++ b/trunk/drivers/net/pcmcia/fmvj18x_cs.c @@ -342,7 +342,7 @@ static int fmvj18x_config(struct pcmcia_device *link) tuple_t tuple; cisparse_t parse; u_short buf[32]; - int i, last_fn = 0, last_ret = 0, ret; + int i, last_fn, last_ret, ret; kio_addr_t ioaddr; cardtype_t cardtype; char *card_name = "unknown"; @@ -350,9 +350,21 @@ static int fmvj18x_config(struct pcmcia_device *link) DEBUG(0, "fmvj18x_config(0x%p)\n", link); + /* + This reads the card's CONFIG tuple to find its configuration + registers. + */ + tuple.DesiredTuple = CISTPL_CONFIG; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); tuple.TupleData = (u_char *)buf; tuple.TupleDataMax = 64; tuple.TupleOffset = 0; + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + + link->conf.ConfigBase = parse.config.base; + link->conf.Present = parse.config.rmask[0]; + tuple.DesiredTuple = CISTPL_FUNCE; tuple.TupleOffset = 0; if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) { @@ -362,12 +374,17 @@ static int fmvj18x_config(struct pcmcia_device *link) CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); link->conf.ConfigIndex = parse.cftable_entry.index; - switch (link->manf_id) { + tuple.DesiredTuple = CISTPL_MANFID; + if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + else + buf[0] = 0xffff; + switch (le16_to_cpu(buf[0])) { case MANFID_TDK: cardtype = TDK; - if (link->card_id == PRODID_TDK_GN3410 - || link->card_id == PRODID_TDK_NP9610 - || link->card_id == PRODID_TDK_MN3200) { + if (le16_to_cpu(buf[1]) == PRODID_TDK_GN3410 + || le16_to_cpu(buf[1]) == PRODID_TDK_NP9610 + || le16_to_cpu(buf[1]) == PRODID_TDK_MN3200) { /* MultiFunction Card */ link->conf.ConfigBase = 0x800; link->conf.ConfigIndex = 0x47; @@ -378,11 +395,11 @@ static int fmvj18x_config(struct pcmcia_device *link) cardtype = CONTEC; break; case MANFID_FUJITSU: - if (link->card_id == PRODID_FUJITSU_MBH10302) + if (le16_to_cpu(buf[1]) == PRODID_FUJITSU_MBH10302) /* RATOC REX-5588/9822/4886's PRODID are 0004(=MBH10302), but these are MBH10304 based card. */ cardtype = MBH10304; - else if (link->card_id == PRODID_FUJITSU_MBH10304) + else if (le16_to_cpu(buf[1]) == PRODID_FUJITSU_MBH10304) cardtype = MBH10304; else cardtype = LA501; @@ -392,9 +409,14 @@ static int fmvj18x_config(struct pcmcia_device *link) } } else { /* old type card */ - switch (link->manf_id) { + tuple.DesiredTuple = CISTPL_MANFID; + if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + else + buf[0] = 0xffff; + switch (le16_to_cpu(buf[0])) { case MANFID_FUJITSU: - if (link->card_id == PRODID_FUJITSU_MBH10304) { + if (le16_to_cpu(buf[1]) == PRODID_FUJITSU_MBH10304) { cardtype = XXX10304; /* MBH10304 with buggy CIS */ link->conf.ConfigIndex = 0x20; } else { diff --git a/trunk/drivers/net/pcmcia/ibmtr_cs.c b/trunk/drivers/net/pcmcia/ibmtr_cs.c index a956a51d284f..bc0ca41a0542 100644 --- a/trunk/drivers/net/pcmcia/ibmtr_cs.c +++ b/trunk/drivers/net/pcmcia/ibmtr_cs.c @@ -222,12 +222,24 @@ static int ibmtr_config(struct pcmcia_device *link) ibmtr_dev_t *info = link->priv; struct net_device *dev = info->dev; struct tok_info *ti = netdev_priv(dev); + tuple_t tuple; + cisparse_t parse; win_req_t req; memreq_t mem; int i, last_ret, last_fn; + u_char buf[64]; DEBUG(0, "ibmtr_config(0x%p)\n", link); + tuple.Attributes = 0; + tuple.TupleData = buf; + tuple.TupleDataMax = 64; + tuple.TupleOffset = 0; + tuple.DesiredTuple = CISTPL_CONFIG; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + link->conf.ConfigBase = parse.config.base; link->conf.ConfigIndex = 0x61; /* Determine if this is PRIMARY or ALTERNATE. */ diff --git a/trunk/drivers/net/pcmcia/nmclan_cs.c b/trunk/drivers/net/pcmcia/nmclan_cs.c index 3b707747a811..e77110e4c288 100644 --- a/trunk/drivers/net/pcmcia/nmclan_cs.c +++ b/trunk/drivers/net/pcmcia/nmclan_cs.c @@ -656,12 +656,23 @@ static int nmclan_config(struct pcmcia_device *link) struct net_device *dev = link->priv; mace_private *lp = netdev_priv(dev); tuple_t tuple; + cisparse_t parse; u_char buf[64]; int i, last_ret, last_fn; kio_addr_t ioaddr; DEBUG(0, "nmclan_config(0x%p)\n", link); + tuple.Attributes = 0; + tuple.TupleData = buf; + tuple.TupleDataMax = 64; + tuple.TupleOffset = 0; + tuple.DesiredTuple = CISTPL_CONFIG; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + link->conf.ConfigBase = parse.config.base; + CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io)); CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); @@ -675,7 +686,6 @@ static int nmclan_config(struct pcmcia_device *link) tuple.TupleData = buf; tuple.TupleDataMax = 64; tuple.TupleOffset = 0; - tuple.Attributes = 0; CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); memcpy(dev->dev_addr, tuple.TupleData, ETHER_ADDR_LEN); diff --git a/trunk/drivers/net/pcmcia/pcnet_cs.c b/trunk/drivers/net/pcmcia/pcnet_cs.c index 2b1238e2dbdb..c51cc5d8789a 100644 --- a/trunk/drivers/net/pcmcia/pcnet_cs.c +++ b/trunk/drivers/net/pcmcia/pcnet_cs.c @@ -519,15 +519,31 @@ static int pcnet_config(struct pcmcia_device *link) tuple_t tuple; cisparse_t parse; int i, last_ret, last_fn, start_pg, stop_pg, cm_offset; - int has_shmem = 0; + int manfid = 0, prodid = 0, has_shmem = 0; u_short buf[64]; hw_info_t *hw_info; DEBUG(0, "pcnet_config(0x%p)\n", link); + tuple.Attributes = 0; tuple.TupleData = (cisdata_t *)buf; tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; + tuple.DesiredTuple = CISTPL_CONFIG; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + link->conf.ConfigBase = parse.config.base; + link->conf.Present = parse.config.rmask[0]; + + tuple.DesiredTuple = CISTPL_MANFID; + tuple.Attributes = TUPLE_RETURN_COMMON; + if ((pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) && + (pcmcia_get_tuple_data(link, &tuple) == CS_SUCCESS)) { + manfid = le16_to_cpu(buf[0]); + prodid = le16_to_cpu(buf[1]); + } + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; tuple.Attributes = 0; CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); @@ -573,8 +589,8 @@ static int pcnet_config(struct pcmcia_device *link) link->conf.Attributes |= CONF_ENABLE_SPKR; link->conf.Status = CCSR_AUDIO_ENA; } - if ((link->manf_id == MANFID_IBM) && - (link->card_id == PRODID_IBM_HOME_AND_AWAY)) + if ((manfid == MANFID_IBM) && + (prodid == PRODID_IBM_HOME_AND_AWAY)) link->conf.ConfigIndex |= 0x10; CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); @@ -608,10 +624,10 @@ static int pcnet_config(struct pcmcia_device *link) info->flags = hw_info->flags; /* Check for user overrides */ info->flags |= (delay_output) ? DELAY_OUTPUT : 0; - if ((link->manf_id == MANFID_SOCKET) && - ((link->card_id == PRODID_SOCKET_LPE) || - (link->card_id == PRODID_SOCKET_LPE_CF) || - (link->card_id == PRODID_SOCKET_EIO))) + if ((manfid == MANFID_SOCKET) && + ((prodid == PRODID_SOCKET_LPE) || + (prodid == PRODID_SOCKET_LPE_CF) || + (prodid == PRODID_SOCKET_EIO))) info->flags &= ~USE_BIG_BUF; if (!use_big_buf) info->flags &= ~USE_BIG_BUF; diff --git a/trunk/drivers/net/pcmcia/smc91c92_cs.c b/trunk/drivers/net/pcmcia/smc91c92_cs.c index 530df8883fe5..20fcc3576202 100644 --- a/trunk/drivers/net/pcmcia/smc91c92_cs.c +++ b/trunk/drivers/net/pcmcia/smc91c92_cs.c @@ -560,8 +560,16 @@ static int mhz_setup(struct pcmcia_device *link) /* Read the station address from the CIS. It is stored as the last (fourth) string in the Version 1 Version/ID tuple. */ - if (link->prod_id[3]) { - station_addr = link->prod_id[3]; + tuple->DesiredTuple = CISTPL_VERS_1; + if (first_tuple(link, tuple, parse) != CS_SUCCESS) { + rc = -1; + goto free_cfg_mem; + } + /* Ugh -- the EM1144 card has two VERS_1 tuples!?! */ + if (next_tuple(link, tuple, parse) != CS_SUCCESS) + first_tuple(link, tuple, parse); + if (parse->version_1.ns > 3) { + station_addr = parse->version_1.str + parse->version_1.ofs[3]; if (cvt_ascii_address(dev, station_addr) == 0) { rc = 0; goto free_cfg_mem; @@ -736,12 +744,15 @@ static int smc_setup(struct pcmcia_device *link) } } /* Try the third string in the Version 1 Version/ID tuple. */ - if (link->prod_id[2]) { - station_addr = link->prod_id[2]; - if (cvt_ascii_address(dev, station_addr) == 0) { - rc = 0; - goto free_cfg_mem; - } + tuple->DesiredTuple = CISTPL_VERS_1; + if (first_tuple(link, tuple, parse) != CS_SUCCESS) { + rc = -1; + goto free_cfg_mem; + } + station_addr = parse->version_1.str + parse->version_1.ofs[2]; + if (cvt_ascii_address(dev, station_addr) == 0) { + rc = 0; + goto free_cfg_mem; } rc = -1; @@ -959,6 +970,10 @@ static int smc91c92_config(struct pcmcia_device *link) { struct net_device *dev = link->priv; struct smc_private *smc = netdev_priv(dev); + struct smc_cfg_mem *cfg_mem; + tuple_t *tuple; + cisparse_t *parse; + u_char *buf; char *name; int i, j, rev; kio_addr_t ioaddr; @@ -966,8 +981,30 @@ static int smc91c92_config(struct pcmcia_device *link) DEBUG(0, "smc91c92_config(0x%p)\n", link); - smc->manfid = link->manf_id; - smc->cardid = link->card_id; + cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL); + if (!cfg_mem) + goto config_failed; + + tuple = &cfg_mem->tuple; + parse = &cfg_mem->parse; + buf = cfg_mem->buf; + + tuple->Attributes = tuple->TupleOffset = 0; + tuple->TupleData = (cisdata_t *)buf; + tuple->TupleDataMax = 64; + + tuple->DesiredTuple = CISTPL_CONFIG; + i = first_tuple(link, tuple, parse); + CS_EXIT_TEST(i, ParseTuple, config_failed); + link->conf.ConfigBase = parse->config.base; + link->conf.Present = parse->config.rmask[0]; + + tuple->DesiredTuple = CISTPL_MANFID; + tuple->Attributes = TUPLE_RETURN_COMMON; + if (first_tuple(link, tuple, parse) == CS_SUCCESS) { + smc->manfid = parse->manfid.manf; + smc->cardid = parse->manfid.card; + } if ((smc->manfid == MANFID_OSITECH) && (smc->cardid != PRODID_OSITECH_SEVEN)) { @@ -1097,12 +1134,14 @@ static int smc91c92_config(struct pcmcia_device *link) printk(KERN_NOTICE " No MII transceivers found!\n"); } } + kfree(cfg_mem); return 0; config_undo: unregister_netdev(dev); config_failed: /* CS_EXIT_TEST() calls jump to here... */ smc91c92_release(link); + kfree(cfg_mem); return -ENODEV; } /* smc91c92_config */ diff --git a/trunk/drivers/net/pcmcia/xirc2ps_cs.c b/trunk/drivers/net/pcmcia/xirc2ps_cs.c index 8478dca3d8d1..f3914f58d67f 100644 --- a/trunk/drivers/net/pcmcia/xirc2ps_cs.c +++ b/trunk/drivers/net/pcmcia/xirc2ps_cs.c @@ -332,7 +332,6 @@ static irqreturn_t xirc2ps_interrupt(int irq, void *dev_id); */ typedef struct local_info_t { - struct net_device *dev; struct pcmcia_device *p_dev; dev_node_t node; struct net_device_stats stats; @@ -354,7 +353,7 @@ typedef struct local_info_t { */ static int do_start_xmit(struct sk_buff *skb, struct net_device *dev); static void do_tx_timeout(struct net_device *dev); -static void xirc2ps_tx_timeout_task(struct work_struct *work); +static void xirc2ps_tx_timeout_task(void *data); static struct net_device_stats *do_get_stats(struct net_device *dev); static void set_addresses(struct net_device *dev); static void set_multicast_list(struct net_device *dev); @@ -568,7 +567,6 @@ xirc2ps_probe(struct pcmcia_device *link) if (!dev) return -ENOMEM; local = netdev_priv(dev); - local->dev = dev; local->p_dev = link; link->priv = dev; @@ -593,7 +591,7 @@ xirc2ps_probe(struct pcmcia_device *link) #ifdef HAVE_TX_TIMEOUT dev->tx_timeout = do_tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; - INIT_WORK(&local->tx_timeout_task, xirc2ps_tx_timeout_task); + INIT_WORK(&local->tx_timeout_task, xirc2ps_tx_timeout_task, dev); #endif return xirc2ps_config(link); @@ -709,11 +707,22 @@ set_card_type(struct pcmcia_device *link, const void *s) * Returns: true if this is a CE2 */ static int -has_ce2_string(struct pcmcia_device * p_dev) +has_ce2_string(struct pcmcia_device * link) { - if (p_dev->prod_id[2] && strstr(p_dev->prod_id[2], "CE2")) - return 1; - return 0; + tuple_t tuple; + cisparse_t parse; + u_char buf[256]; + + tuple.Attributes = 0; + tuple.TupleData = buf; + tuple.TupleDataMax = 254; + tuple.TupleOffset = 0; + tuple.DesiredTuple = CISTPL_VERS_1; + if (!first_tuple(link, &tuple, &parse) && parse.version_1.ns > 2) { + if (strstr(parse.version_1.str + parse.version_1.ofs[2], "CE2")) + return 1; + } + return 0; } /**************** @@ -783,6 +792,13 @@ xirc2ps_config(struct pcmcia_device * link) goto failure; } + /* get configuration stuff */ + tuple.DesiredTuple = CISTPL_CONFIG; + if ((err=first_tuple(link, &tuple, &parse))) + goto cis_error; + link->conf.ConfigBase = parse.config.base; + link->conf.Present = parse.config.rmask[0]; + /* get the ethernet address from the CIS */ tuple.DesiredTuple = CISTPL_FUNCE; for (err = first_tuple(link, &tuple, &parse); !err; @@ -1046,6 +1062,8 @@ xirc2ps_config(struct pcmcia_device * link) xirc2ps_release(link); return -ENODEV; + cis_error: + printk(KNOT_XIRC "unable to parse CIS\n"); failure: return -ENODEV; } /* xirc2ps_config */ @@ -1326,11 +1344,9 @@ xirc2ps_interrupt(int irq, void *dev_id) /*====================================================================*/ static void -xirc2ps_tx_timeout_task(struct work_struct *work) +xirc2ps_tx_timeout_task(void *data) { - local_info_t *local = - container_of(work, local_info_t, tx_timeout_task); - struct net_device *dev = local->dev; + struct net_device *dev = data; /* reset the card */ do_reset(dev,1); dev->trans_start = jiffies; diff --git a/trunk/drivers/net/phy/phy.c b/trunk/drivers/net/phy/phy.c index 4044bb1ada86..88237bdb5255 100644 --- a/trunk/drivers/net/phy/phy.c +++ b/trunk/drivers/net/phy/phy.c @@ -397,7 +397,7 @@ int phy_start_aneg(struct phy_device *phydev) EXPORT_SYMBOL(phy_start_aneg); -static void phy_change(struct work_struct *work); +static void phy_change(void *data); static void phy_timer(unsigned long data); /* phy_start_machine: @@ -555,7 +555,7 @@ int phy_start_interrupts(struct phy_device *phydev) { int err = 0; - INIT_WORK(&phydev->phy_queue, phy_change); + INIT_WORK(&phydev->phy_queue, phy_change, phydev); if (request_irq(phydev->irq, phy_interrupt, IRQF_SHARED, @@ -598,11 +598,10 @@ EXPORT_SYMBOL(phy_stop_interrupts); /* Scheduled by the phy_interrupt/timer to handle PHY changes */ -static void phy_change(struct work_struct *work) +static void phy_change(void *data) { int err; - struct phy_device *phydev = - container_of(work, struct phy_device, phy_queue); + struct phy_device *phydev = data; err = phy_disable_interrupts(phydev); diff --git a/trunk/drivers/net/plip.c b/trunk/drivers/net/plip.c index 6bb085f54437..71afb274498f 100644 --- a/trunk/drivers/net/plip.c +++ b/trunk/drivers/net/plip.c @@ -138,9 +138,9 @@ static const unsigned int net_debug = NET_DEBUG; #define PLIP_NIBBLE_WAIT 3000 /* Bottom halves */ -static void plip_kick_bh(struct work_struct *work); -static void plip_bh(struct work_struct *work); -static void plip_timer_bh(struct work_struct *work); +static void plip_kick_bh(struct net_device *dev); +static void plip_bh(struct net_device *dev); +static void plip_timer_bh(struct net_device *dev); /* Interrupt handler */ static void plip_interrupt(int irq, void *dev_id); @@ -207,10 +207,9 @@ struct plip_local { struct net_local { struct net_device_stats enet_stats; - struct net_device *dev; struct work_struct immediate; - struct delayed_work deferred; - struct delayed_work timer; + struct work_struct deferred; + struct work_struct timer; struct plip_local snd_data; struct plip_local rcv_data; struct pardevice *pardev; @@ -307,11 +306,11 @@ plip_init_netdev(struct net_device *dev) nl->nibble = PLIP_NIBBLE_WAIT; /* Initialize task queue structures */ - INIT_WORK(&nl->immediate, plip_bh); - INIT_DELAYED_WORK(&nl->deferred, plip_kick_bh); + INIT_WORK(&nl->immediate, (void (*)(void *))plip_bh, dev); + INIT_WORK(&nl->deferred, (void (*)(void *))plip_kick_bh, dev); if (dev->irq == -1) - INIT_DELAYED_WORK(&nl->timer, plip_timer_bh); + INIT_WORK(&nl->timer, (void (*)(void *))plip_timer_bh, dev); spin_lock_init(&nl->lock); } @@ -320,10 +319,9 @@ plip_init_netdev(struct net_device *dev) This routine is kicked by do_timer(). Request `plip_bh' to be invoked. */ static void -plip_kick_bh(struct work_struct *work) +plip_kick_bh(struct net_device *dev) { - struct net_local *nl = - container_of(work, struct net_local, deferred.work); + struct net_local *nl = netdev_priv(dev); if (nl->is_deferred) schedule_work(&nl->immediate); @@ -364,9 +362,9 @@ static const plip_func connection_state_table[] = /* Bottom half handler of PLIP. */ static void -plip_bh(struct work_struct *work) +plip_bh(struct net_device *dev) { - struct net_local *nl = container_of(work, struct net_local, immediate); + struct net_local *nl = netdev_priv(dev); struct plip_local *snd = &nl->snd_data; struct plip_local *rcv = &nl->rcv_data; plip_func f; @@ -374,21 +372,20 @@ plip_bh(struct work_struct *work) nl->is_deferred = 0; f = connection_state_table[nl->connection]; - if ((r = (*f)(nl->dev, nl, snd, rcv)) != OK - && (r = plip_bh_timeout_error(nl->dev, nl, snd, rcv, r)) != OK) { + if ((r = (*f)(dev, nl, snd, rcv)) != OK + && (r = plip_bh_timeout_error(dev, nl, snd, rcv, r)) != OK) { nl->is_deferred = 1; schedule_delayed_work(&nl->deferred, 1); } } static void -plip_timer_bh(struct work_struct *work) +plip_timer_bh(struct net_device *dev) { - struct net_local *nl = - container_of(work, struct net_local, timer.work); + struct net_local *nl = netdev_priv(dev); if (!(atomic_read (&nl->kill_timer))) { - plip_interrupt (-1, nl->dev); + plip_interrupt (-1, dev); schedule_delayed_work(&nl->timer, 1); } @@ -1287,7 +1284,6 @@ static void plip_attach (struct parport *port) } nl = netdev_priv(dev); - nl->dev = dev; nl->pardev = parport_register_device(port, name, plip_preempt, plip_wakeup, plip_interrupt, 0, dev); diff --git a/trunk/drivers/net/qla3xxx.c b/trunk/drivers/net/qla3xxx.c index d79d141a601d..ec640f6229ae 100644 --- a/trunk/drivers/net/qla3xxx.c +++ b/trunk/drivers/net/qla3xxx.c @@ -2008,7 +2008,7 @@ static irqreturn_t ql3xxx_isr(int irq, void *dev_id) "%s: Another function issued a reset to the " "chip. ISR value = %x.\n", ndev->name, value); } - queue_delayed_work(qdev->workqueue, &qdev->reset_work, 0); + queue_work(qdev->workqueue, &qdev->reset_work); spin_unlock(&qdev->adapter_lock); } else if (value & ISP_IMR_DISABLE_CMPL_INT) { ql_disable_interrupts(qdev); @@ -3182,13 +3182,11 @@ static void ql3xxx_tx_timeout(struct net_device *ndev) /* * Wake up the worker to process this event. */ - queue_delayed_work(qdev->workqueue, &qdev->tx_timeout_work, 0); + queue_work(qdev->workqueue, &qdev->tx_timeout_work); } -static void ql_reset_work(struct work_struct *work) +static void ql_reset_work(struct ql3_adapter *qdev) { - struct ql3_adapter *qdev = - container_of(work, struct ql3_adapter, reset_work.work); struct net_device *ndev = qdev->ndev; u32 value; struct ql_tx_buf_cb *tx_cb; @@ -3280,12 +3278,9 @@ static void ql_reset_work(struct work_struct *work) } } -static void ql_tx_timeout_work(struct work_struct *work) +static void ql_tx_timeout_work(struct ql3_adapter *qdev) { - struct ql3_adapter *qdev = - container_of(work, struct ql3_adapter, tx_timeout_work.work); - - ql_cycle_adapter(qdev, QL_DO_RESET); + ql_cycle_adapter(qdev,QL_DO_RESET); } static void ql_get_board_info(struct ql3_adapter *qdev) @@ -3464,8 +3459,9 @@ static int __devinit ql3xxx_probe(struct pci_dev *pdev, netif_stop_queue(ndev); qdev->workqueue = create_singlethread_workqueue(ndev->name); - INIT_DELAYED_WORK(&qdev->reset_work, ql_reset_work); - INIT_DELAYED_WORK(&qdev->tx_timeout_work, ql_tx_timeout_work); + INIT_WORK(&qdev->reset_work, (void (*)(void *))ql_reset_work, qdev); + INIT_WORK(&qdev->tx_timeout_work, + (void (*)(void *))ql_tx_timeout_work, qdev); init_timer(&qdev->adapter_timer); qdev->adapter_timer.function = ql3xxx_timer; diff --git a/trunk/drivers/net/qla3xxx.h b/trunk/drivers/net/qla3xxx.h index ea94de7fd071..65da2c0bfda6 100644 --- a/trunk/drivers/net/qla3xxx.h +++ b/trunk/drivers/net/qla3xxx.h @@ -1186,8 +1186,8 @@ struct ql3_adapter { u32 numPorts; struct net_device_stats stats; struct workqueue_struct *workqueue; - struct delayed_work reset_work; - struct delayed_work tx_timeout_work; + struct work_struct reset_work; + struct work_struct tx_timeout_work; u32 max_frame_size; }; diff --git a/trunk/drivers/net/r8169.c b/trunk/drivers/net/r8169.c index 85a392fab5cc..45d3ca431957 100644 --- a/trunk/drivers/net/r8169.c +++ b/trunk/drivers/net/r8169.c @@ -424,7 +424,6 @@ struct ring_info { struct rtl8169_private { void __iomem *mmio_addr; /* memory map physical address */ struct pci_dev *pci_dev; /* Index of PCI device */ - struct net_device *dev; struct net_device_stats stats; /* statistics of net device */ spinlock_t lock; /* spin lock flag */ u32 msg_enable; @@ -456,7 +455,7 @@ struct rtl8169_private { void (*phy_reset_enable)(void __iomem *); unsigned int (*phy_reset_pending)(void __iomem *); unsigned int (*link_ok)(void __iomem *); - struct delayed_work task; + struct work_struct task; unsigned wol_enabled : 1; }; @@ -1511,7 +1510,6 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); tp = netdev_priv(dev); - tp->dev = dev; tp->msg_enable = netif_msg_init(debug.msg_enable, R8169_MSG_DEFAULT); /* enable device (incl. PCI PM wakeup and hotplug setup) */ @@ -1784,7 +1782,7 @@ static int rtl8169_open(struct net_device *dev) if (retval < 0) goto err_free_rx; - INIT_DELAYED_WORK(&tp->task, NULL); + INIT_WORK(&tp->task, NULL, dev); rtl8169_hw_start(dev); @@ -2107,11 +2105,11 @@ static void rtl8169_tx_clear(struct rtl8169_private *tp) tp->cur_tx = tp->dirty_tx = 0; } -static void rtl8169_schedule_work(struct net_device *dev, work_func_t task) +static void rtl8169_schedule_work(struct net_device *dev, void (*task)(void *)) { struct rtl8169_private *tp = netdev_priv(dev); - PREPARE_DELAYED_WORK(&tp->task, task); + PREPARE_WORK(&tp->task, task, dev); schedule_delayed_work(&tp->task, 4); } @@ -2130,11 +2128,9 @@ static void rtl8169_wait_for_quiescence(struct net_device *dev) netif_poll_enable(dev); } -static void rtl8169_reinit_task(struct work_struct *work) +static void rtl8169_reinit_task(void *_data) { - struct rtl8169_private *tp = - container_of(work, struct rtl8169_private, task.work); - struct net_device *dev = tp->dev; + struct net_device *dev = _data; int ret; if (netif_running(dev)) { @@ -2157,11 +2153,10 @@ static void rtl8169_reinit_task(struct work_struct *work) } } -static void rtl8169_reset_task(struct work_struct *work) +static void rtl8169_reset_task(void *_data) { - struct rtl8169_private *tp = - container_of(work, struct rtl8169_private, task.work); - struct net_device *dev = tp->dev; + struct net_device *dev = _data; + struct rtl8169_private *tp = netdev_priv(dev); if (!netif_running(dev)) return; diff --git a/trunk/drivers/net/s2io.c b/trunk/drivers/net/s2io.c index 250cdbeefdfd..33569ec9dbfc 100644 --- a/trunk/drivers/net/s2io.c +++ b/trunk/drivers/net/s2io.c @@ -5872,9 +5872,9 @@ static void s2io_tasklet(unsigned long dev_addr) * Description: Sets the link status for the adapter */ -static void s2io_set_link(struct work_struct *work) +static void s2io_set_link(unsigned long data) { - nic_t *nic = container_of(work, nic_t, set_link_task); + nic_t *nic = (nic_t *) data; struct net_device *dev = nic->dev; XENA_dev_config_t __iomem *bar0 = nic->bar0; register u64 val64; @@ -6379,10 +6379,10 @@ static int s2io_card_up(nic_t * sp) * spin lock. */ -static void s2io_restart_nic(struct work_struct *work) +static void s2io_restart_nic(unsigned long data) { - nic_t *sp = container_of(work, nic_t, rst_timer_task); - struct net_device *dev = sp->dev; + struct net_device *dev = (struct net_device *) data; + nic_t *sp = dev->priv; s2io_card_down(sp); if (s2io_card_up(sp)) { @@ -6992,8 +6992,10 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) dev->tx_timeout = &s2io_tx_watchdog; dev->watchdog_timeo = WATCH_DOG_TIMEOUT; - INIT_WORK(&sp->rst_timer_task, s2io_restart_nic); - INIT_WORK(&sp->set_link_task, s2io_set_link); + INIT_WORK(&sp->rst_timer_task, + (void (*)(void *)) s2io_restart_nic, dev); + INIT_WORK(&sp->set_link_task, + (void (*)(void *)) s2io_set_link, sp); pci_save_state(sp->pdev); diff --git a/trunk/drivers/net/s2io.h b/trunk/drivers/net/s2io.h index 3b0bafd273c8..12b719f4d00f 100644 --- a/trunk/drivers/net/s2io.h +++ b/trunk/drivers/net/s2io.h @@ -1000,7 +1000,7 @@ s2io_msix_fifo_handle(int irq, void *dev_id); static irqreturn_t s2io_isr(int irq, void *dev_id); static int verify_xena_quiescence(nic_t *sp, u64 val64, int flag); static const struct ethtool_ops netdev_ethtool_ops; -static void s2io_set_link(struct work_struct *work); +static void s2io_set_link(unsigned long data); static int s2io_set_swapper(nic_t * sp); static void s2io_card_down(nic_t *nic); static int s2io_card_up(nic_t *nic); diff --git a/trunk/drivers/net/sis190.c b/trunk/drivers/net/sis190.c index b70ed79d4121..aaba458584fb 100644 --- a/trunk/drivers/net/sis190.c +++ b/trunk/drivers/net/sis190.c @@ -280,7 +280,6 @@ enum sis190_feature { struct sis190_private { void __iomem *mmio_addr; struct pci_dev *pci_dev; - struct net_device *dev; struct net_device_stats stats; spinlock_t lock; u32 rx_buf_sz; @@ -898,11 +897,10 @@ static void sis190_hw_start(struct net_device *dev) netif_start_queue(dev); } -static void sis190_phy_task(struct work_struct *work) +static void sis190_phy_task(void * data) { - struct sis190_private *tp = - container_of(work, struct sis190_private, phy_task); - struct net_device *dev = tp->dev; + struct net_device *dev = data; + struct sis190_private *tp = netdev_priv(dev); void __iomem *ioaddr = tp->mmio_addr; int phy_id = tp->mii_if.phy_id; u16 val; @@ -1049,7 +1047,7 @@ static int sis190_open(struct net_device *dev) if (rc < 0) goto err_free_rx_1; - INIT_WORK(&tp->phy_task, sis190_phy_task); + INIT_WORK(&tp->phy_task, sis190_phy_task, dev); sis190_request_timer(dev); @@ -1438,7 +1436,6 @@ static struct net_device * __devinit sis190_init_board(struct pci_dev *pdev) SET_NETDEV_DEV(dev, &pdev->dev); tp = netdev_priv(dev); - tp->dev = dev; tp->msg_enable = netif_msg_init(debug.msg_enable, SIS190_MSG_DEFAULT); rc = pci_enable_device(pdev); @@ -1801,7 +1798,7 @@ static int __devinit sis190_init_one(struct pci_dev *pdev, sis190_init_rxfilter(dev); - INIT_WORK(&tp->phy_task, sis190_phy_task); + INIT_WORK(&tp->phy_task, sis190_phy_task, dev); dev->open = sis190_open; dev->stop = sis190_close; diff --git a/trunk/drivers/net/skge.c b/trunk/drivers/net/skge.c index b60f0451f6cd..5513907e8393 100644 --- a/trunk/drivers/net/skge.c +++ b/trunk/drivers/net/skge.c @@ -1327,11 +1327,10 @@ static void xm_check_link(struct net_device *dev) * Since internal PHY is wired to a level triggered pin, can't * get an interrupt when carrier is detected. */ -static void xm_link_timer(struct work_struct *work) +static void xm_link_timer(void *arg) { - struct skge_port *skge = - container_of(work, struct skge_port, link_thread.work); - struct net_device *dev = skge->netdev; + struct net_device *dev = arg; + struct skge_port *skge = netdev_priv(arg); struct skge_hw *hw = skge->hw; int port = skge->port; @@ -3073,9 +3072,9 @@ static void skge_error_irq(struct skge_hw *hw) * because accessing phy registers requires spin wait which might * cause excess interrupt latency. */ -static void skge_extirq(struct work_struct *work) +static void skge_extirq(void *arg) { - struct skge_hw *hw = container_of(work, struct skge_hw, phy_work); + struct skge_hw *hw = arg; int port; mutex_lock(&hw->phy_mutex); @@ -3457,7 +3456,7 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port, skge->port = port; /* Only used for Genesis XMAC */ - INIT_DELAYED_WORK(&skge->link_thread, xm_link_timer); + INIT_WORK(&skge->link_thread, xm_link_timer, dev); if (hw->chip_id != CHIP_ID_GENESIS) { dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG; @@ -3544,7 +3543,7 @@ static int __devinit skge_probe(struct pci_dev *pdev, hw->pdev = pdev; mutex_init(&hw->phy_mutex); - INIT_WORK(&hw->phy_work, skge_extirq); + INIT_WORK(&hw->phy_work, skge_extirq, hw); spin_lock_init(&hw->hw_lock); hw->regs = ioremap_nocache(pci_resource_start(pdev, 0), 0x4000); diff --git a/trunk/drivers/net/skge.h b/trunk/drivers/net/skge.h index 23e5275d920c..537c0aaa1db8 100644 --- a/trunk/drivers/net/skge.h +++ b/trunk/drivers/net/skge.h @@ -2456,7 +2456,7 @@ struct skge_port { struct net_device_stats net_stats; - struct delayed_work link_thread; + struct work_struct link_thread; enum pause_control flow_control; enum pause_status flow_status; u8 rx_csum; diff --git a/trunk/drivers/net/smc91x.c b/trunk/drivers/net/smc91x.c index e62a9586fb95..95b6478f55c6 100644 --- a/trunk/drivers/net/smc91x.c +++ b/trunk/drivers/net/smc91x.c @@ -210,7 +210,6 @@ struct smc_local { /* work queue */ struct work_struct phy_configure; - struct net_device *dev; int work_pending; spinlock_t lock; @@ -1115,11 +1114,10 @@ static void smc_phy_check_media(struct net_device *dev, int init) * of autonegotiation.) If the RPC ANEG bit is cleared, the selection * is controlled by the RPC SPEED and RPC DPLX bits. */ -static void smc_phy_configure(struct work_struct *work) +static void smc_phy_configure(void *data) { - struct smc_local *lp = - container_of(work, struct smc_local, phy_configure); - struct net_device *dev = lp->dev; + struct net_device *dev = data; + struct smc_local *lp = netdev_priv(dev); void __iomem *ioaddr = lp->base; int phyaddr = lp->mii.phy_id; int my_phy_caps; /* My PHY capabilities */ @@ -1594,7 +1592,7 @@ smc_open(struct net_device *dev) /* Configure the PHY, initialize the link state */ if (lp->phy_type != 0) - smc_phy_configure(&lp->phy_configure); + smc_phy_configure(dev); else { spin_lock_irq(&lp->lock); smc_10bt_check_media(dev, 1); @@ -1974,8 +1972,7 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr) #endif tasklet_init(&lp->tx_task, smc_hardware_send_pkt, (unsigned long)dev); - INIT_WORK(&lp->phy_configure, smc_phy_configure); - lp->dev = dev; + INIT_WORK(&lp->phy_configure, smc_phy_configure, dev); lp->mii.phy_id_mask = 0x1f; lp->mii.reg_num_mask = 0x1f; lp->mii.force_media = 0; @@ -2325,7 +2322,7 @@ static int smc_drv_resume(struct platform_device *dev) smc_reset(ndev); smc_enable(ndev); if (lp->phy_type != 0) - smc_phy_configure(&lp->phy_configure); + smc_phy_configure(ndev); netif_device_attach(ndev); } } diff --git a/trunk/drivers/net/spider_net.c b/trunk/drivers/net/spider_net.c index ebb6aa39f9c7..13e0a43e423b 100644 --- a/trunk/drivers/net/spider_net.c +++ b/trunk/drivers/net/spider_net.c @@ -1939,11 +1939,10 @@ spider_net_stop(struct net_device *netdev) * called as task when tx hangs, resets interface (if interface is up) */ static void -spider_net_tx_timeout_task(struct work_struct *work) +spider_net_tx_timeout_task(void *data) { - struct spider_net_card *card = - container_of(work, struct spider_net_card, tx_timeout_task); - struct net_device *netdev = card->netdev; + struct net_device *netdev = data; + struct spider_net_card *card = netdev_priv(netdev); if (!(netdev->flags & IFF_UP)) goto out; @@ -2117,7 +2116,7 @@ spider_net_alloc_card(void) card = netdev_priv(netdev); card->netdev = netdev; card->msg_enable = SPIDER_NET_DEFAULT_MSG; - INIT_WORK(&card->tx_timeout_task, spider_net_tx_timeout_task); + INIT_WORK(&card->tx_timeout_task, spider_net_tx_timeout_task, netdev); init_waitqueue_head(&card->waitq); atomic_set(&card->tx_timeout_task_counter, 0); diff --git a/trunk/drivers/net/sungem.c b/trunk/drivers/net/sungem.c index 785e4a535f9e..cf44e72399b9 100644 --- a/trunk/drivers/net/sungem.c +++ b/trunk/drivers/net/sungem.c @@ -2282,9 +2282,9 @@ static void gem_do_stop(struct net_device *dev, int wol) } } -static void gem_reset_task(struct work_struct *work) +static void gem_reset_task(void *data) { - struct gem *gp = container_of(work, struct gem, reset_task); + struct gem *gp = (struct gem *) data; mutex_lock(&gp->pm_mutex); @@ -3044,7 +3044,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev, gp->link_timer.function = gem_link_timer; gp->link_timer.data = (unsigned long) gp; - INIT_WORK(&gp->reset_task, gem_reset_task); + INIT_WORK(&gp->reset_task, gem_reset_task, gp); gp->lstate = link_down; gp->timer_ticks = 0; diff --git a/trunk/drivers/net/tg3.c b/trunk/drivers/net/tg3.c index d9123c9adc1e..c20bb998e0e5 100644 --- a/trunk/drivers/net/tg3.c +++ b/trunk/drivers/net/tg3.c @@ -3654,9 +3654,9 @@ static void tg3_poll_controller(struct net_device *dev) } #endif -static void tg3_reset_task(struct work_struct *work) +static void tg3_reset_task(void *_data) { - struct tg3 *tp = container_of(work, struct tg3, reset_task); + struct tg3 *tp = _data; unsigned int restart_timer; tg3_full_lock(tp, 0); @@ -11734,7 +11734,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, #endif spin_lock_init(&tp->lock); spin_lock_init(&tp->indirect_lock); - INIT_WORK(&tp->reset_task, tg3_reset_task); + INIT_WORK(&tp->reset_task, tg3_reset_task, tp); tp->regs = ioremap_nocache(tg3reg_base, tg3reg_len); if (tp->regs == 0UL) { diff --git a/trunk/drivers/net/tlan.c b/trunk/drivers/net/tlan.c index f85f00251123..e14f5a00f65a 100644 --- a/trunk/drivers/net/tlan.c +++ b/trunk/drivers/net/tlan.c @@ -296,7 +296,6 @@ static void TLan_SetMulticastList( struct net_device *); static int TLan_ioctl( struct net_device *dev, struct ifreq *rq, int cmd); static int TLan_probe1( struct pci_dev *pdev, long ioaddr, int irq, int rev, const struct pci_device_id *ent); static void TLan_tx_timeout( struct net_device *dev); -static void TLan_tx_timeout_work(struct work_struct *work); static int tlan_init_one( struct pci_dev *pdev, const struct pci_device_id *ent); static u32 TLan_HandleInvalid( struct net_device *, u16 ); @@ -563,7 +562,6 @@ static int __devinit TLan_probe1(struct pci_dev *pdev, priv = netdev_priv(dev); priv->pciDev = pdev; - priv->dev = dev; /* Is this a PCI device? */ if (pdev) { @@ -636,7 +634,7 @@ static int __devinit TLan_probe1(struct pci_dev *pdev, /* This will be used when we get an adapter error from * within our irq handler */ - INIT_WORK(&priv->tlan_tqueue, TLan_tx_timeout_work); + INIT_WORK(&priv->tlan_tqueue, (void *)(void*)TLan_tx_timeout, dev); spin_lock_init(&priv->lock); @@ -1042,25 +1040,6 @@ static void TLan_tx_timeout(struct net_device *dev) } - /*************************************************************** - * TLan_tx_timeout_work - * - * Returns: nothing - * - * Params: - * work work item of device which timed out - * - **************************************************************/ - -static void TLan_tx_timeout_work(struct work_struct *work) -{ - TLanPrivateInfo *priv = - container_of(work, TLanPrivateInfo, tlan_tqueue); - - TLan_tx_timeout(priv->dev); -} - - /*************************************************************** * TLan_StartTx diff --git a/trunk/drivers/net/tlan.h b/trunk/drivers/net/tlan.h index 41ce0b665937..a44e2f2ef62a 100644 --- a/trunk/drivers/net/tlan.h +++ b/trunk/drivers/net/tlan.h @@ -170,7 +170,6 @@ typedef u8 TLanBuffer[TLAN_MAX_FRAME_SIZE]; typedef struct tlan_private_tag { struct net_device *nextDevice; struct pci_dev *pciDev; - struct net_device *dev; void *dmaStorage; dma_addr_t dmaStorageDMA; unsigned int dmaSize; diff --git a/trunk/drivers/net/tulip/21142.c b/trunk/drivers/net/tulip/21142.c index 942b839ccc5b..fa3a2bb105ad 100644 --- a/trunk/drivers/net/tulip/21142.c +++ b/trunk/drivers/net/tulip/21142.c @@ -26,11 +26,10 @@ static u16 t21142_csr15[] = { 0x0008, 0x0006, 0x000E, 0x0008, 0x0008, }; /* Handle the 21143 uniquely: do autoselect with NWay, not the EEPROM list of available transceivers. */ -void t21142_media_task(struct work_struct *work) +void t21142_media_task(void *data) { - struct tulip_private *tp = - container_of(work, struct tulip_private, media_work); - struct net_device *dev = tp->dev; + struct net_device *dev = data; + struct tulip_private *tp = netdev_priv(dev); void __iomem *ioaddr = tp->base_addr; int csr12 = ioread32(ioaddr + CSR12); int next_tick = 60*HZ; diff --git a/trunk/drivers/net/tulip/timer.c b/trunk/drivers/net/tulip/timer.c index df326fe1cc8f..066e5d6bcbd8 100644 --- a/trunk/drivers/net/tulip/timer.c +++ b/trunk/drivers/net/tulip/timer.c @@ -18,11 +18,10 @@ #include "tulip.h" -void tulip_media_task(struct work_struct *work) +void tulip_media_task(void *data) { - struct tulip_private *tp = - container_of(work, struct tulip_private, media_work); - struct net_device *dev = tp->dev; + struct net_device *dev = data; + struct tulip_private *tp = netdev_priv(dev); void __iomem *ioaddr = tp->base_addr; u32 csr12 = ioread32(ioaddr + CSR12); int next_tick = 2*HZ; diff --git a/trunk/drivers/net/tulip/tulip.h b/trunk/drivers/net/tulip/tulip.h index 25f25da76917..ad107f45c7b1 100644 --- a/trunk/drivers/net/tulip/tulip.h +++ b/trunk/drivers/net/tulip/tulip.h @@ -44,7 +44,7 @@ struct tulip_chip_table { int valid_intrs; /* CSR7 interrupt enable settings */ int flags; void (*media_timer) (unsigned long); - work_func_t media_task; + void (*media_task) (void *); }; @@ -392,7 +392,6 @@ struct tulip_private { int csr12_shadow; int pad0; /* Used for 8-byte alignment */ struct work_struct media_work; - struct net_device *dev; }; @@ -407,7 +406,7 @@ struct eeprom_fixup { /* 21142.c */ extern u16 t21142_csr14[]; -void t21142_media_task(struct work_struct *work); +void t21142_media_task(void *data); void t21142_start_nway(struct net_device *dev); void t21142_lnk_change(struct net_device *dev, int csr5); @@ -445,7 +444,7 @@ void pnic_lnk_change(struct net_device *dev, int csr5); void pnic_timer(unsigned long data); /* timer.c */ -void tulip_media_task(struct work_struct *work); +void tulip_media_task(void *data); void mxic_timer(unsigned long data); void comet_timer(unsigned long data); diff --git a/trunk/drivers/net/tulip/tulip_core.c b/trunk/drivers/net/tulip/tulip_core.c index 5a35354aa523..0aee618f883c 100644 --- a/trunk/drivers/net/tulip/tulip_core.c +++ b/trunk/drivers/net/tulip/tulip_core.c @@ -1367,7 +1367,6 @@ static int __devinit tulip_init_one (struct pci_dev *pdev, * it is zeroed and aligned in alloc_etherdev */ tp = netdev_priv(dev); - tp->dev = dev; tp->rx_ring = pci_alloc_consistent(pdev, sizeof(struct tulip_rx_desc) * RX_RING_SIZE + @@ -1390,7 +1389,7 @@ static int __devinit tulip_init_one (struct pci_dev *pdev, tp->timer.data = (unsigned long)dev; tp->timer.function = tulip_tbl[tp->chip_id].media_timer; - INIT_WORK(&tp->media_work, tulip_tbl[tp->chip_id].media_task); + INIT_WORK(&tp->media_work, tulip_tbl[tp->chip_id].media_task, dev); dev->base_addr = (unsigned long)ioaddr; diff --git a/trunk/drivers/net/wan/pc300_tty.c b/trunk/drivers/net/wan/pc300_tty.c index b2a23aed4428..931cbdf6d791 100644 --- a/trunk/drivers/net/wan/pc300_tty.c +++ b/trunk/drivers/net/wan/pc300_tty.c @@ -125,8 +125,8 @@ static int cpc_tty_write_room(struct tty_struct *tty); static int cpc_tty_chars_in_buffer(struct tty_struct *tty); static void cpc_tty_flush_buffer(struct tty_struct *tty); static void cpc_tty_hangup(struct tty_struct *tty); -static void cpc_tty_rx_work(struct work_struct *work); -static void cpc_tty_tx_work(struct work_struct *work); +static void cpc_tty_rx_work(void *data); +static void cpc_tty_tx_work(void *data); static int cpc_tty_send_to_card(pc300dev_t *dev,void *buf, int len); static void cpc_tty_trace(pc300dev_t *dev, char* buf, int len, char rxtx); static void cpc_tty_signal_off(pc300dev_t *pc300dev, unsigned char); @@ -261,8 +261,8 @@ void cpc_tty_init(pc300dev_t *pc300dev) cpc_tty->tty_minor = port + CPC_TTY_MINOR_START; cpc_tty->pc300dev = pc300dev; - INIT_WORK(&cpc_tty->tty_tx_work, cpc_tty_tx_work); - INIT_WORK(&cpc_tty->tty_rx_work, cpc_tty_rx_work); + INIT_WORK(&cpc_tty->tty_tx_work, cpc_tty_tx_work, (void *)cpc_tty); + INIT_WORK(&cpc_tty->tty_rx_work, cpc_tty_rx_work, (void *)port); cpc_tty->buf_rx.first = cpc_tty->buf_rx.last = NULL; @@ -659,23 +659,21 @@ static void cpc_tty_hangup(struct tty_struct *tty) * o call the line disc. read * o free memory */ -static void cpc_tty_rx_work(struct work_struct *work) +static void cpc_tty_rx_work(void * data) { - st_cpc_tty_area *cpc_tty; unsigned long port; int i, j; + st_cpc_tty_area *cpc_tty; volatile st_cpc_rx_buf *buf; char flags=0,flg_rx=1; struct tty_ldisc *ld; if (cpc_tty_cnt == 0) return; + for (i=0; (i < 4) && flg_rx ; i++) { flg_rx = 0; - - cpc_tty = container_of(work, st_cpc_tty_area, tty_rx_work); - port = cpc_tty - cpc_tty_area; - + port = (unsigned long)data; for (j=0; j < CPC_TTY_NPORTS; j++) { cpc_tty = &cpc_tty_area[port]; @@ -884,10 +882,9 @@ void cpc_tty_receive(pc300dev_t *pc300dev) * o if need call line discipline wakeup * o call wake_up_interruptible */ -static void cpc_tty_tx_work(struct work_struct *work) +static void cpc_tty_tx_work(void *data) { - st_cpc_tty_area *cpc_tty = - container_of(work, st_cpc_tty_area, tty_tx_work); + st_cpc_tty_area *cpc_tty = (st_cpc_tty_area *) data; struct tty_struct *tty; CPC_TTY_DBG("%s: cpc_tty_tx_work init\n",cpc_tty->name); diff --git a/trunk/drivers/net/wireless/airo_cs.c b/trunk/drivers/net/wireless/airo_cs.c index f12355398fe7..ac9437d497f0 100644 --- a/trunk/drivers/net/wireless/airo_cs.c +++ b/trunk/drivers/net/wireless/airo_cs.c @@ -219,6 +219,21 @@ static int airo_config(struct pcmcia_device *link) dev = link->priv; DEBUG(0, "airo_config(0x%p)\n", link); + + /* + This reads the card's CONFIG tuple to find its configuration + registers. + */ + tuple.DesiredTuple = CISTPL_CONFIG; + tuple.Attributes = 0; + tuple.TupleData = buf; + tuple.TupleDataMax = sizeof(buf); + tuple.TupleOffset = 0; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + link->conf.ConfigBase = parse.config.base; + link->conf.Present = parse.config.rmask[0]; /* In this loop, we scan the CIS for configuration table entries, @@ -232,10 +247,6 @@ static int airo_config(struct pcmcia_device *link) these things without consulting the CIS, and most client drivers will only use the CIS to fill in implementation-defined details. */ - tuple.Attributes = 0; - tuple.TupleData = buf; - tuple.TupleDataMax = sizeof(buf); - tuple.TupleOffset = 0; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); while (1) { diff --git a/trunk/drivers/net/wireless/atmel_cs.c b/trunk/drivers/net/wireless/atmel_cs.c index 12617cd0b78e..5c410989c4d7 100644 --- a/trunk/drivers/net/wireless/atmel_cs.c +++ b/trunk/drivers/net/wireless/atmel_cs.c @@ -243,6 +243,17 @@ static int atmel_config(struct pcmcia_device *link) tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; + /* + This reads the card's CONFIG tuple to find its configuration + registers. + */ + tuple.DesiredTuple = CISTPL_CONFIG; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + link->conf.ConfigBase = parse.config.base; + link->conf.Present = parse.config.rmask[0]; + /* In this loop, we scan the CIS for configuration table entries, each of which describes a valid card configuration, including diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx.h b/trunk/drivers/net/wireless/bcm43xx/bcm43xx.h index 8286678513b9..94dfb92fab5c 100644 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx.h +++ b/trunk/drivers/net/wireless/bcm43xx/bcm43xx.h @@ -819,7 +819,7 @@ struct bcm43xx_private { struct tasklet_struct isr_tasklet; /* Periodic tasks */ - struct delayed_work periodic_work; + struct work_struct periodic_work; unsigned int periodic_state; struct work_struct restart_work; diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_main.c index 2ec2e5afce67..5b3c27359a18 100644 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_main.c +++ b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_main.c @@ -3215,10 +3215,9 @@ static void do_periodic_work(struct bcm43xx_private *bcm) schedule_delayed_work(&bcm->periodic_work, HZ * 15); } -static void bcm43xx_periodic_work_handler(struct work_struct *work) +static void bcm43xx_periodic_work_handler(void *d) { - struct bcm43xx_private *bcm = - container_of(work, struct bcm43xx_private, periodic_work.work); + struct bcm43xx_private *bcm = d; struct net_device *net_dev = bcm->net_dev; unsigned long flags; u32 savedirqs = 0; @@ -3280,11 +3279,11 @@ void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm) void bcm43xx_periodic_tasks_setup(struct bcm43xx_private *bcm) { - struct delayed_work *work = &bcm->periodic_work; + struct work_struct *work = &(bcm->periodic_work); assert(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED); - INIT_DELAYED_WORK(work, bcm43xx_periodic_work_handler); - schedule_delayed_work(work, 0); + INIT_WORK(work, bcm43xx_periodic_work_handler, bcm); + schedule_work(work); } static void bcm43xx_security_init(struct bcm43xx_private *bcm) @@ -3636,7 +3635,7 @@ static int bcm43xx_init_board(struct bcm43xx_private *bcm) bcm43xx_periodic_tasks_setup(bcm); /*FIXME: This should be handled by softmac instead. */ - schedule_delayed_work(&bcm->softmac->associnfo.work, 0); + schedule_work(&bcm->softmac->associnfo.work); out: mutex_unlock(&(bcm)->mutex); @@ -4183,10 +4182,9 @@ static void __devexit bcm43xx_remove_one(struct pci_dev *pdev) /* Hard-reset the chip. Do not call this directly. * Use bcm43xx_controller_restart() */ -static void bcm43xx_chip_reset(struct work_struct *work) +static void bcm43xx_chip_reset(void *_bcm) { - struct bcm43xx_private *bcm = - container_of(work, struct bcm43xx_private, restart_work); + struct bcm43xx_private *bcm = _bcm; struct bcm43xx_phyinfo *phy; int err = -ENODEV; @@ -4213,7 +4211,7 @@ void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char *reason) if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) return; printk(KERN_ERR PFX "Controller RESET (%s) ...\n", reason); - INIT_WORK(&bcm->restart_work, bcm43xx_chip_reset); + INIT_WORK(&bcm->restart_work, bcm43xx_chip_reset, bcm); schedule_work(&bcm->restart_work); } diff --git a/trunk/drivers/net/wireless/hostap/hostap.h b/trunk/drivers/net/wireless/hostap/hostap.h index e89c890d16fd..e663518bd570 100644 --- a/trunk/drivers/net/wireless/hostap/hostap.h +++ b/trunk/drivers/net/wireless/hostap/hostap.h @@ -35,7 +35,7 @@ int hostap_80211_get_hdrlen(u16 fc); struct net_device_stats *hostap_get_stats(struct net_device *dev); void hostap_setup_dev(struct net_device *dev, local_info_t *local, int main_dev); -void hostap_set_multicast_list_queue(struct work_struct *work); +void hostap_set_multicast_list_queue(void *data); int hostap_set_hostapd(local_info_t *local, int val, int rtnl_locked); int hostap_set_hostapd_sta(local_info_t *local, int val, int rtnl_locked); void hostap_cleanup(local_info_t *local); diff --git a/trunk/drivers/net/wireless/hostap/hostap_ap.c b/trunk/drivers/net/wireless/hostap/hostap_ap.c index 08bc57a4b895..ba13125024cb 100644 --- a/trunk/drivers/net/wireless/hostap/hostap_ap.c +++ b/trunk/drivers/net/wireless/hostap/hostap_ap.c @@ -49,10 +49,10 @@ MODULE_PARM_DESC(autom_ap_wds, "Add WDS connections to other APs " static struct sta_info* ap_get_sta(struct ap_data *ap, u8 *sta); static void hostap_event_expired_sta(struct net_device *dev, struct sta_info *sta); -static void handle_add_proc_queue(struct work_struct *work); +static void handle_add_proc_queue(void *data); #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT -static void handle_wds_oper_queue(struct work_struct *work); +static void handle_wds_oper_queue(void *data); static void prism2_send_mgmt(struct net_device *dev, u16 type_subtype, char *body, int body_len, u8 *addr, u16 tx_cb_idx); @@ -807,7 +807,7 @@ void hostap_init_data(local_info_t *local) INIT_LIST_HEAD(&ap->sta_list); /* Initialize task queue structure for AP management */ - INIT_WORK(&local->ap->add_sta_proc_queue, handle_add_proc_queue); + INIT_WORK(&local->ap->add_sta_proc_queue, handle_add_proc_queue, ap); ap->tx_callback_idx = hostap_tx_callback_register(local, hostap_ap_tx_cb, ap); @@ -815,7 +815,7 @@ void hostap_init_data(local_info_t *local) printk(KERN_WARNING "%s: failed to register TX callback for " "AP\n", local->dev->name); #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT - INIT_WORK(&local->ap->wds_oper_queue, handle_wds_oper_queue); + INIT_WORK(&local->ap->wds_oper_queue, handle_wds_oper_queue, local); ap->tx_callback_auth = hostap_tx_callback_register(local, hostap_ap_tx_cb_auth, ap); @@ -1062,10 +1062,9 @@ static int prism2_sta_proc_read(char *page, char **start, off_t off, } -static void handle_add_proc_queue(struct work_struct *work) +static void handle_add_proc_queue(void *data) { - struct ap_data *ap = container_of(work, struct ap_data, - add_sta_proc_queue); + struct ap_data *ap = (struct ap_data *) data; struct sta_info *sta; char name[20]; struct add_sta_proc_data *entry, *prev; @@ -1953,11 +1952,9 @@ static void handle_pspoll(local_info_t *local, #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT -static void handle_wds_oper_queue(struct work_struct *work) +static void handle_wds_oper_queue(void *data) { - struct ap_data *ap = container_of(work, struct ap_data, - wds_oper_queue); - local_info_t *local = ap->local; + local_info_t *local = data; struct wds_oper_data *entry, *prev; spin_lock_bh(&local->lock); diff --git a/trunk/drivers/net/wireless/hostap/hostap_cs.c b/trunk/drivers/net/wireless/hostap/hostap_cs.c index ee542ec6d6a8..f63909e4bc32 100644 --- a/trunk/drivers/net/wireless/hostap/hostap_cs.c +++ b/trunk/drivers/net/wireless/hostap/hostap_cs.c @@ -293,12 +293,15 @@ static int sandisk_enable_wireless(struct net_device *dev) goto done; } + tuple.DesiredTuple = CISTPL_MANFID; tuple.Attributes = TUPLE_RETURN_COMMON; tuple.TupleData = buf; tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; - - if (hw_priv->link->manf_id != 0xd601 || hw_priv->link->card_id != 0x0101) { + if (pcmcia_get_first_tuple(hw_priv->link, &tuple) || + pcmcia_get_tuple_data(hw_priv->link, &tuple) || + pcmcia_parse_tuple(hw_priv->link, &tuple, parse) || + parse->manfid.manf != 0xd601 || parse->manfid.card != 0x0101) { /* No SanDisk manfid found */ ret = -ENODEV; goto done; @@ -570,10 +573,16 @@ static int prism2_config(struct pcmcia_device *link) } memset(hw_priv, 0, sizeof(*hw_priv)); + tuple.DesiredTuple = CISTPL_CONFIG; tuple.Attributes = 0; tuple.TupleData = buf; tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, parse)); + link->conf.ConfigBase = parse->config.base; + link->conf.Present = parse->config.rmask[0]; CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &conf)); diff --git a/trunk/drivers/net/wireless/hostap/hostap_hw.c b/trunk/drivers/net/wireless/hostap/hostap_hw.c index c19e68636a1c..ed00ebb6e7f4 100644 --- a/trunk/drivers/net/wireless/hostap/hostap_hw.c +++ b/trunk/drivers/net/wireless/hostap/hostap_hw.c @@ -1645,9 +1645,9 @@ static void prism2_schedule_reset(local_info_t *local) /* Called only as scheduled task after noticing card timeout in interrupt * context */ -static void handle_reset_queue(struct work_struct *work) +static void handle_reset_queue(void *data) { - local_info_t *local = container_of(work, local_info_t, reset_queue); + local_info_t *local = (local_info_t *) data; printk(KERN_DEBUG "%s: scheduled card reset\n", local->dev->name); prism2_hw_reset(local->dev); @@ -2896,10 +2896,9 @@ static void hostap_passive_scan(unsigned long data) /* Called only as a scheduled task when communications quality values should * be updated. */ -static void handle_comms_qual_update(struct work_struct *work) +static void handle_comms_qual_update(void *data) { - local_info_t *local = - container_of(work, local_info_t, comms_qual_update); + local_info_t *local = data; prism2_update_comms_qual(local->dev); } @@ -3051,9 +3050,9 @@ static int prism2_set_tim(struct net_device *dev, int aid, int set) } -static void handle_set_tim_queue(struct work_struct *work) +static void handle_set_tim_queue(void *data) { - local_info_t *local = container_of(work, local_info_t, set_tim_queue); + local_info_t *local = (local_info_t *) data; struct set_tim_data *entry; u16 val; @@ -3210,15 +3209,15 @@ prism2_init_local_data(struct prism2_helper_functions *funcs, int card_idx, local->scan_channel_mask = 0xffff; /* Initialize task queue structures */ - INIT_WORK(&local->reset_queue, handle_reset_queue); + INIT_WORK(&local->reset_queue, handle_reset_queue, local); INIT_WORK(&local->set_multicast_list_queue, - hostap_set_multicast_list_queue); + hostap_set_multicast_list_queue, local->dev); - INIT_WORK(&local->set_tim_queue, handle_set_tim_queue); + INIT_WORK(&local->set_tim_queue, handle_set_tim_queue, local); INIT_LIST_HEAD(&local->set_tim_list); spin_lock_init(&local->set_tim_lock); - INIT_WORK(&local->comms_qual_update, handle_comms_qual_update); + INIT_WORK(&local->comms_qual_update, handle_comms_qual_update, local); /* Initialize tasklets for handling hardware IRQ related operations * outside hw IRQ handler */ diff --git a/trunk/drivers/net/wireless/hostap/hostap_info.c b/trunk/drivers/net/wireless/hostap/hostap_info.c index 5fd2b1ad7f5e..50f72d831cf4 100644 --- a/trunk/drivers/net/wireless/hostap/hostap_info.c +++ b/trunk/drivers/net/wireless/hostap/hostap_info.c @@ -474,9 +474,9 @@ static void handle_info_queue_scanresults(local_info_t *local) /* Called only as scheduled task after receiving info frames (used to avoid * pending too much time in HW IRQ handler). */ -static void handle_info_queue(struct work_struct *work) +static void handle_info_queue(void *data) { - local_info_t *local = container_of(work, local_info_t, info_queue); + local_info_t *local = (local_info_t *) data; if (test_and_clear_bit(PRISM2_INFO_PENDING_LINKSTATUS, &local->pending_info)) @@ -493,7 +493,7 @@ void hostap_info_init(local_info_t *local) { skb_queue_head_init(&local->info_list); #ifndef PRISM2_NO_STATION_MODES - INIT_WORK(&local->info_queue, handle_info_queue); + INIT_WORK(&local->info_queue, handle_info_queue, local); #endif /* PRISM2_NO_STATION_MODES */ } diff --git a/trunk/drivers/net/wireless/hostap/hostap_main.c b/trunk/drivers/net/wireless/hostap/hostap_main.c index 0796be9d9e77..53374fcba77e 100644 --- a/trunk/drivers/net/wireless/hostap/hostap_main.c +++ b/trunk/drivers/net/wireless/hostap/hostap_main.c @@ -767,14 +767,14 @@ static int prism2_set_mac_address(struct net_device *dev, void *p) /* TODO: to be further implemented as soon as Prism2 fully supports * GroupAddresses and correct documentation is available */ -void hostap_set_multicast_list_queue(struct work_struct *work) +void hostap_set_multicast_list_queue(void *data) { - local_info_t *local = - container_of(work, local_info_t, set_multicast_list_queue); - struct net_device *dev = local->dev; + struct net_device *dev = (struct net_device *) data; struct hostap_interface *iface; + local_info_t *local; iface = netdev_priv(dev); + local = iface->local; if (hostap_set_word(dev, HFA384X_RID_PROMISCUOUSMODE, local->is_promisc)) { printk(KERN_INFO "%s: %sabling promiscuous mode failed\n", diff --git a/trunk/drivers/net/wireless/ipw2100.c b/trunk/drivers/net/wireless/ipw2100.c index 1bcd352a813b..79607b8b877c 100644 --- a/trunk/drivers/net/wireless/ipw2100.c +++ b/trunk/drivers/net/wireless/ipw2100.c @@ -316,7 +316,7 @@ static void ipw2100_release_firmware(struct ipw2100_priv *priv, struct ipw2100_fw *fw); static int ipw2100_ucode_download(struct ipw2100_priv *priv, struct ipw2100_fw *fw); -static void ipw2100_wx_event_work(struct work_struct *work); +static void ipw2100_wx_event_work(struct ipw2100_priv *priv); static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device *dev); static struct iw_handler_def ipw2100_wx_handler_def; @@ -679,8 +679,7 @@ static void schedule_reset(struct ipw2100_priv *priv) queue_delayed_work(priv->workqueue, &priv->reset_work, priv->reset_backoff * HZ); else - queue_delayed_work(priv->workqueue, &priv->reset_work, - 0); + queue_work(priv->workqueue, &priv->reset_work); if (priv->reset_backoff < MAX_RESET_BACKOFF) priv->reset_backoff++; @@ -1874,10 +1873,8 @@ static void ipw2100_down(struct ipw2100_priv *priv) netif_stop_queue(priv->net_dev); } -static void ipw2100_reset_adapter(struct work_struct *work) +static void ipw2100_reset_adapter(struct ipw2100_priv *priv) { - struct ipw2100_priv *priv = - container_of(work, struct ipw2100_priv, reset_work.work); unsigned long flags; union iwreq_data wrqu = { .ap_addr = { @@ -2074,9 +2071,9 @@ static void isr_indicate_association_lost(struct ipw2100_priv *priv, u32 status) return; if (priv->status & STATUS_SECURITY_UPDATED) - queue_delayed_work(priv->workqueue, &priv->security_work, 0); + queue_work(priv->workqueue, &priv->security_work); - queue_delayed_work(priv->workqueue, &priv->wx_event_work, 0); + queue_work(priv->workqueue, &priv->wx_event_work); } static void isr_indicate_rf_kill(struct ipw2100_priv *priv, u32 status) @@ -5527,11 +5524,8 @@ static int ipw2100_configure_security(struct ipw2100_priv *priv, int batch_mode) return err; } -static void ipw2100_security_work(struct work_struct *work) +static void ipw2100_security_work(struct ipw2100_priv *priv) { - struct ipw2100_priv *priv = - container_of(work, struct ipw2100_priv, security_work.work); - /* If we happen to have reconnected before we get a chance to * process this, then update the security settings--which causes * a disassociation to occur */ @@ -5754,7 +5748,7 @@ static int ipw2100_set_address(struct net_device *dev, void *p) priv->reset_backoff = 0; mutex_unlock(&priv->action_mutex); - ipw2100_reset_adapter(&priv->reset_work.work); + ipw2100_reset_adapter(priv); return 0; done: @@ -5916,10 +5910,9 @@ static const struct ethtool_ops ipw2100_ethtool_ops = { .get_drvinfo = ipw_ethtool_get_drvinfo, }; -static void ipw2100_hang_check(struct work_struct *work) +static void ipw2100_hang_check(void *adapter) { - struct ipw2100_priv *priv = - container_of(work, struct ipw2100_priv, hang_check.work); + struct ipw2100_priv *priv = adapter; unsigned long flags; u32 rtc = 0xa5a5a5a5; u32 len = sizeof(rtc); @@ -5959,10 +5952,9 @@ static void ipw2100_hang_check(struct work_struct *work) spin_unlock_irqrestore(&priv->low_lock, flags); } -static void ipw2100_rf_kill(struct work_struct *work) +static void ipw2100_rf_kill(void *adapter) { - struct ipw2100_priv *priv = - container_of(work, struct ipw2100_priv, rf_kill.work); + struct ipw2100_priv *priv = adapter; unsigned long flags; spin_lock_irqsave(&priv->low_lock, flags); @@ -6111,11 +6103,14 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev, priv->workqueue = create_workqueue(DRV_NAME); - INIT_DELAYED_WORK(&priv->reset_work, ipw2100_reset_adapter); - INIT_DELAYED_WORK(&priv->security_work, ipw2100_security_work); - INIT_DELAYED_WORK(&priv->wx_event_work, ipw2100_wx_event_work); - INIT_DELAYED_WORK(&priv->hang_check, ipw2100_hang_check); - INIT_DELAYED_WORK(&priv->rf_kill, ipw2100_rf_kill); + INIT_WORK(&priv->reset_work, + (void (*)(void *))ipw2100_reset_adapter, priv); + INIT_WORK(&priv->security_work, + (void (*)(void *))ipw2100_security_work, priv); + INIT_WORK(&priv->wx_event_work, + (void (*)(void *))ipw2100_wx_event_work, priv); + INIT_WORK(&priv->hang_check, ipw2100_hang_check, priv); + INIT_WORK(&priv->rf_kill, ipw2100_rf_kill, priv); tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) ipw2100_irq_tasklet, (unsigned long)priv); @@ -8286,10 +8281,8 @@ static struct iw_handler_def ipw2100_wx_handler_def = { .get_wireless_stats = ipw2100_wx_wireless_stats, }; -static void ipw2100_wx_event_work(struct work_struct *work) +static void ipw2100_wx_event_work(struct ipw2100_priv *priv) { - struct ipw2100_priv *priv = - container_of(work, struct ipw2100_priv, wx_event_work.work); union iwreq_data wrqu; int len = ETH_ALEN; diff --git a/trunk/drivers/net/wireless/ipw2100.h b/trunk/drivers/net/wireless/ipw2100.h index de7d384d38af..55b7227198df 100644 --- a/trunk/drivers/net/wireless/ipw2100.h +++ b/trunk/drivers/net/wireless/ipw2100.h @@ -583,11 +583,11 @@ struct ipw2100_priv { struct tasklet_struct irq_tasklet; struct workqueue_struct *workqueue; - struct delayed_work reset_work; - struct delayed_work security_work; - struct delayed_work wx_event_work; - struct delayed_work hang_check; - struct delayed_work rf_kill; + struct work_struct reset_work; + struct work_struct security_work; + struct work_struct wx_event_work; + struct work_struct hang_check; + struct work_struct rf_kill; u32 interrupts; int tx_interrupts; diff --git a/trunk/drivers/net/wireless/ipw2200.c b/trunk/drivers/net/wireless/ipw2200.c index e82e56bb85e1..c692d01a76ca 100644 --- a/trunk/drivers/net/wireless/ipw2200.c +++ b/trunk/drivers/net/wireless/ipw2200.c @@ -187,9 +187,9 @@ static struct ipw_rx_queue *ipw_rx_queue_alloc(struct ipw_priv *); static void ipw_rx_queue_free(struct ipw_priv *, struct ipw_rx_queue *); static void ipw_rx_queue_replenish(void *); static int ipw_up(struct ipw_priv *); -static void ipw_bg_up(struct work_struct *work); +static void ipw_bg_up(void *); static void ipw_down(struct ipw_priv *); -static void ipw_bg_down(struct work_struct *work); +static void ipw_bg_down(void *); static int ipw_config(struct ipw_priv *); static int init_supported_rates(struct ipw_priv *priv, struct ipw_supported_rates *prates); @@ -862,12 +862,11 @@ static void ipw_led_link_on(struct ipw_priv *priv) spin_unlock_irqrestore(&priv->lock, flags); } -static void ipw_bg_led_link_on(struct work_struct *work) +static void ipw_bg_led_link_on(void *data) { - struct ipw_priv *priv = - container_of(work, struct ipw_priv, led_link_on.work); + struct ipw_priv *priv = data; mutex_lock(&priv->mutex); - ipw_led_link_on(priv); + ipw_led_link_on(data); mutex_unlock(&priv->mutex); } @@ -907,12 +906,11 @@ static void ipw_led_link_off(struct ipw_priv *priv) spin_unlock_irqrestore(&priv->lock, flags); } -static void ipw_bg_led_link_off(struct work_struct *work) +static void ipw_bg_led_link_off(void *data) { - struct ipw_priv *priv = - container_of(work, struct ipw_priv, led_link_off.work); + struct ipw_priv *priv = data; mutex_lock(&priv->mutex); - ipw_led_link_off(priv); + ipw_led_link_off(data); mutex_unlock(&priv->mutex); } @@ -987,12 +985,11 @@ static void ipw_led_activity_off(struct ipw_priv *priv) spin_unlock_irqrestore(&priv->lock, flags); } -static void ipw_bg_led_activity_off(struct work_struct *work) +static void ipw_bg_led_activity_off(void *data) { - struct ipw_priv *priv = - container_of(work, struct ipw_priv, led_act_off.work); + struct ipw_priv *priv = data; mutex_lock(&priv->mutex); - ipw_led_activity_off(priv); + ipw_led_activity_off(data); mutex_unlock(&priv->mutex); } @@ -2231,12 +2228,11 @@ static void ipw_adapter_restart(void *adapter) } } -static void ipw_bg_adapter_restart(struct work_struct *work) +static void ipw_bg_adapter_restart(void *data) { - struct ipw_priv *priv = - container_of(work, struct ipw_priv, adapter_restart); + struct ipw_priv *priv = data; mutex_lock(&priv->mutex); - ipw_adapter_restart(priv); + ipw_adapter_restart(data); mutex_unlock(&priv->mutex); } @@ -2253,12 +2249,11 @@ static void ipw_scan_check(void *data) } } -static void ipw_bg_scan_check(struct work_struct *work) +static void ipw_bg_scan_check(void *data) { - struct ipw_priv *priv = - container_of(work, struct ipw_priv, scan_check.work); + struct ipw_priv *priv = data; mutex_lock(&priv->mutex); - ipw_scan_check(priv); + ipw_scan_check(data); mutex_unlock(&priv->mutex); } @@ -3836,19 +3831,17 @@ static int ipw_disassociate(void *data) return 1; } -static void ipw_bg_disassociate(struct work_struct *work) +static void ipw_bg_disassociate(void *data) { - struct ipw_priv *priv = - container_of(work, struct ipw_priv, disassociate); + struct ipw_priv *priv = data; mutex_lock(&priv->mutex); - ipw_disassociate(priv); + ipw_disassociate(data); mutex_unlock(&priv->mutex); } -static void ipw_system_config(struct work_struct *work) +static void ipw_system_config(void *data) { - struct ipw_priv *priv = - container_of(work, struct ipw_priv, system_config); + struct ipw_priv *priv = data; #ifdef CONFIG_IPW2200_PROMISCUOUS if (priv->prom_net_dev && netif_running(priv->prom_net_dev)) { @@ -4215,12 +4208,11 @@ static void ipw_gather_stats(struct ipw_priv *priv) IPW_STATS_INTERVAL); } -static void ipw_bg_gather_stats(struct work_struct *work) +static void ipw_bg_gather_stats(void *data) { - struct ipw_priv *priv = - container_of(work, struct ipw_priv, gather_stats.work); + struct ipw_priv *priv = data; mutex_lock(&priv->mutex); - ipw_gather_stats(priv); + ipw_gather_stats(data); mutex_unlock(&priv->mutex); } @@ -4276,8 +4268,8 @@ static void ipw_handle_missed_beacon(struct ipw_priv *priv, if (!(priv->status & STATUS_ROAMING)) { priv->status |= STATUS_ROAMING; if (!(priv->status & STATUS_SCANNING)) - queue_delayed_work(priv->workqueue, - &priv->request_scan, 0); + queue_work(priv->workqueue, + &priv->request_scan); } return; } @@ -4615,8 +4607,8 @@ static void ipw_rx_notification(struct ipw_priv *priv, #ifdef CONFIG_IPW2200_MONITOR if (priv->ieee->iw_mode == IW_MODE_MONITOR) { priv->status |= STATUS_SCAN_FORCED; - queue_delayed_work(priv->workqueue, - &priv->request_scan, 0); + queue_work(priv->workqueue, + &priv->request_scan); break; } priv->status &= ~STATUS_SCAN_FORCED; @@ -4639,8 +4631,8 @@ static void ipw_rx_notification(struct ipw_priv *priv, /* Don't schedule if we aborted the scan */ priv->status &= ~STATUS_ROAMING; } else if (priv->status & STATUS_SCAN_PENDING) - queue_delayed_work(priv->workqueue, - &priv->request_scan, 0); + queue_work(priv->workqueue, + &priv->request_scan); else if (priv->config & CFG_BACKGROUND_SCAN && priv->status & STATUS_ASSOCIATED) queue_delayed_work(priv->workqueue, @@ -5063,12 +5055,11 @@ static void ipw_rx_queue_replenish(void *data) ipw_rx_queue_restock(priv); } -static void ipw_bg_rx_queue_replenish(struct work_struct *work) +static void ipw_bg_rx_queue_replenish(void *data) { - struct ipw_priv *priv = - container_of(work, struct ipw_priv, rx_replenish); + struct ipw_priv *priv = data; mutex_lock(&priv->mutex); - ipw_rx_queue_replenish(priv); + ipw_rx_queue_replenish(data); mutex_unlock(&priv->mutex); } @@ -5498,10 +5489,9 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv, return 1; } -static void ipw_merge_adhoc_network(struct work_struct *work) +static void ipw_merge_adhoc_network(void *data) { - struct ipw_priv *priv = - container_of(work, struct ipw_priv, merge_networks); + struct ipw_priv *priv = data; struct ieee80211_network *network = NULL; struct ipw_network_match match = { .network = priv->assoc_network @@ -5958,12 +5948,11 @@ static void ipw_adhoc_check(void *data) priv->assoc_request.beacon_interval); } -static void ipw_bg_adhoc_check(struct work_struct *work) +static void ipw_bg_adhoc_check(void *data) { - struct ipw_priv *priv = - container_of(work, struct ipw_priv, adhoc_check.work); + struct ipw_priv *priv = data; mutex_lock(&priv->mutex); - ipw_adhoc_check(priv); + ipw_adhoc_check(data); mutex_unlock(&priv->mutex); } @@ -6310,26 +6299,19 @@ static int ipw_request_scan_helper(struct ipw_priv *priv, int type) return err; } -static void ipw_request_passive_scan(struct work_struct *work) -{ - struct ipw_priv *priv = - container_of(work, struct ipw_priv, request_passive_scan); - ipw_request_scan_helper(priv, IW_SCAN_TYPE_PASSIVE); +static int ipw_request_passive_scan(struct ipw_priv *priv) { + return ipw_request_scan_helper(priv, IW_SCAN_TYPE_PASSIVE); } -static void ipw_request_scan(struct work_struct *work) -{ - struct ipw_priv *priv = - container_of(work, struct ipw_priv, request_scan.work); - ipw_request_scan_helper(priv, IW_SCAN_TYPE_ACTIVE); +static int ipw_request_scan(struct ipw_priv *priv) { + return ipw_request_scan_helper(priv, IW_SCAN_TYPE_ACTIVE); } -static void ipw_bg_abort_scan(struct work_struct *work) +static void ipw_bg_abort_scan(void *data) { - struct ipw_priv *priv = - container_of(work, struct ipw_priv, abort_scan); + struct ipw_priv *priv = data; mutex_lock(&priv->mutex); - ipw_abort_scan(priv); + ipw_abort_scan(data); mutex_unlock(&priv->mutex); } @@ -7102,10 +7084,9 @@ static int ipw_qos_set_tx_queue_command(struct ipw_priv *priv, /* * background support to run QoS activate functionality */ -static void ipw_bg_qos_activate(struct work_struct *work) +static void ipw_bg_qos_activate(void *data) { - struct ipw_priv *priv = - container_of(work, struct ipw_priv, qos_activate); + struct ipw_priv *priv = data; if (priv == NULL) return; @@ -7413,12 +7394,11 @@ static void ipw_roam(void *data) priv->status &= ~STATUS_ROAMING; } -static void ipw_bg_roam(struct work_struct *work) +static void ipw_bg_roam(void *data) { - struct ipw_priv *priv = - container_of(work, struct ipw_priv, roam); + struct ipw_priv *priv = data; mutex_lock(&priv->mutex); - ipw_roam(priv); + ipw_roam(data); mutex_unlock(&priv->mutex); } @@ -7499,8 +7479,8 @@ static int ipw_associate(void *data) &priv->request_scan, SCAN_INTERVAL); else - queue_delayed_work(priv->workqueue, - &priv->request_scan, 0); + queue_work(priv->workqueue, + &priv->request_scan); } return 0; @@ -7511,12 +7491,11 @@ static int ipw_associate(void *data) return 1; } -static void ipw_bg_associate(struct work_struct *work) +static void ipw_bg_associate(void *data) { - struct ipw_priv *priv = - container_of(work, struct ipw_priv, associate); + struct ipw_priv *priv = data; mutex_lock(&priv->mutex); - ipw_associate(priv); + ipw_associate(data); mutex_unlock(&priv->mutex); } @@ -9431,7 +9410,7 @@ static int ipw_wx_set_scan(struct net_device *dev, IPW_DEBUG_WX("Start scan\n"); - queue_delayed_work(priv->workqueue, &priv->request_scan, 0); + queue_work(priv->workqueue, &priv->request_scan); return 0; } @@ -10568,12 +10547,11 @@ static void ipw_rf_kill(void *adapter) spin_unlock_irqrestore(&priv->lock, flags); } -static void ipw_bg_rf_kill(struct work_struct *work) +static void ipw_bg_rf_kill(void *data) { - struct ipw_priv *priv = - container_of(work, struct ipw_priv, rf_kill.work); + struct ipw_priv *priv = data; mutex_lock(&priv->mutex); - ipw_rf_kill(priv); + ipw_rf_kill(data); mutex_unlock(&priv->mutex); } @@ -10604,12 +10582,11 @@ static void ipw_link_up(struct ipw_priv *priv) queue_delayed_work(priv->workqueue, &priv->request_scan, HZ); } -static void ipw_bg_link_up(struct work_struct *work) +static void ipw_bg_link_up(void *data) { - struct ipw_priv *priv = - container_of(work, struct ipw_priv, link_up); + struct ipw_priv *priv = data; mutex_lock(&priv->mutex); - ipw_link_up(priv); + ipw_link_up(data); mutex_unlock(&priv->mutex); } @@ -10629,16 +10606,15 @@ static void ipw_link_down(struct ipw_priv *priv) if (!(priv->status & STATUS_EXIT_PENDING)) { /* Queue up another scan... */ - queue_delayed_work(priv->workqueue, &priv->request_scan, 0); + queue_work(priv->workqueue, &priv->request_scan); } } -static void ipw_bg_link_down(struct work_struct *work) +static void ipw_bg_link_down(void *data) { - struct ipw_priv *priv = - container_of(work, struct ipw_priv, link_down); + struct ipw_priv *priv = data; mutex_lock(&priv->mutex); - ipw_link_down(priv); + ipw_link_down(data); mutex_unlock(&priv->mutex); } @@ -10650,30 +10626,38 @@ static int ipw_setup_deferred_work(struct ipw_priv *priv) init_waitqueue_head(&priv->wait_command_queue); init_waitqueue_head(&priv->wait_state); - INIT_DELAYED_WORK(&priv->adhoc_check, ipw_bg_adhoc_check); - INIT_WORK(&priv->associate, ipw_bg_associate); - INIT_WORK(&priv->disassociate, ipw_bg_disassociate); - INIT_WORK(&priv->system_config, ipw_system_config); - INIT_WORK(&priv->rx_replenish, ipw_bg_rx_queue_replenish); - INIT_WORK(&priv->adapter_restart, ipw_bg_adapter_restart); - INIT_DELAYED_WORK(&priv->rf_kill, ipw_bg_rf_kill); - INIT_WORK(&priv->up, ipw_bg_up); - INIT_WORK(&priv->down, ipw_bg_down); - INIT_DELAYED_WORK(&priv->request_scan, ipw_request_scan); - INIT_WORK(&priv->request_passive_scan, ipw_request_passive_scan); - INIT_DELAYED_WORK(&priv->gather_stats, ipw_bg_gather_stats); - INIT_WORK(&priv->abort_scan, ipw_bg_abort_scan); - INIT_WORK(&priv->roam, ipw_bg_roam); - INIT_DELAYED_WORK(&priv->scan_check, ipw_bg_scan_check); - INIT_WORK(&priv->link_up, ipw_bg_link_up); - INIT_WORK(&priv->link_down, ipw_bg_link_down); - INIT_DELAYED_WORK(&priv->led_link_on, ipw_bg_led_link_on); - INIT_DELAYED_WORK(&priv->led_link_off, ipw_bg_led_link_off); - INIT_DELAYED_WORK(&priv->led_act_off, ipw_bg_led_activity_off); - INIT_WORK(&priv->merge_networks, ipw_merge_adhoc_network); + INIT_WORK(&priv->adhoc_check, ipw_bg_adhoc_check, priv); + INIT_WORK(&priv->associate, ipw_bg_associate, priv); + INIT_WORK(&priv->disassociate, ipw_bg_disassociate, priv); + INIT_WORK(&priv->system_config, ipw_system_config, priv); + INIT_WORK(&priv->rx_replenish, ipw_bg_rx_queue_replenish, priv); + INIT_WORK(&priv->adapter_restart, ipw_bg_adapter_restart, priv); + INIT_WORK(&priv->rf_kill, ipw_bg_rf_kill, priv); + INIT_WORK(&priv->up, (void (*)(void *))ipw_bg_up, priv); + INIT_WORK(&priv->down, (void (*)(void *))ipw_bg_down, priv); + INIT_WORK(&priv->request_scan, + (void (*)(void *))ipw_request_scan, priv); + INIT_WORK(&priv->request_passive_scan, + (void (*)(void *))ipw_request_passive_scan, priv); + INIT_WORK(&priv->gather_stats, + (void (*)(void *))ipw_bg_gather_stats, priv); + INIT_WORK(&priv->abort_scan, (void (*)(void *))ipw_bg_abort_scan, priv); + INIT_WORK(&priv->roam, ipw_bg_roam, priv); + INIT_WORK(&priv->scan_check, ipw_bg_scan_check, priv); + INIT_WORK(&priv->link_up, (void (*)(void *))ipw_bg_link_up, priv); + INIT_WORK(&priv->link_down, (void (*)(void *))ipw_bg_link_down, priv); + INIT_WORK(&priv->led_link_on, (void (*)(void *))ipw_bg_led_link_on, + priv); + INIT_WORK(&priv->led_link_off, (void (*)(void *))ipw_bg_led_link_off, + priv); + INIT_WORK(&priv->led_act_off, (void (*)(void *))ipw_bg_led_activity_off, + priv); + INIT_WORK(&priv->merge_networks, + (void (*)(void *))ipw_merge_adhoc_network, priv); #ifdef CONFIG_IPW2200_QOS - INIT_WORK(&priv->qos_activate, ipw_bg_qos_activate); + INIT_WORK(&priv->qos_activate, (void (*)(void *))ipw_bg_qos_activate, + priv); #endif /* CONFIG_IPW2200_QOS */ tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) @@ -11206,8 +11190,7 @@ static int ipw_up(struct ipw_priv *priv) /* If configure to try and auto-associate, kick * off a scan. */ - queue_delayed_work(priv->workqueue, - &priv->request_scan, 0); + queue_work(priv->workqueue, &priv->request_scan); return 0; } @@ -11228,12 +11211,11 @@ static int ipw_up(struct ipw_priv *priv) return -EIO; } -static void ipw_bg_up(struct work_struct *work) +static void ipw_bg_up(void *data) { - struct ipw_priv *priv = - container_of(work, struct ipw_priv, up); + struct ipw_priv *priv = data; mutex_lock(&priv->mutex); - ipw_up(priv); + ipw_up(data); mutex_unlock(&priv->mutex); } @@ -11300,12 +11282,11 @@ static void ipw_down(struct ipw_priv *priv) ipw_led_radio_off(priv); } -static void ipw_bg_down(struct work_struct *work) +static void ipw_bg_down(void *data) { - struct ipw_priv *priv = - container_of(work, struct ipw_priv, down); + struct ipw_priv *priv = data; mutex_lock(&priv->mutex); - ipw_down(priv); + ipw_down(data); mutex_unlock(&priv->mutex); } diff --git a/trunk/drivers/net/wireless/ipw2200.h b/trunk/drivers/net/wireless/ipw2200.h index 626a240a87d8..dad5eedefbf1 100644 --- a/trunk/drivers/net/wireless/ipw2200.h +++ b/trunk/drivers/net/wireless/ipw2200.h @@ -1290,21 +1290,21 @@ struct ipw_priv { struct workqueue_struct *workqueue; - struct delayed_work adhoc_check; + struct work_struct adhoc_check; struct work_struct associate; struct work_struct disassociate; struct work_struct system_config; struct work_struct rx_replenish; - struct delayed_work request_scan; + struct work_struct request_scan; struct work_struct request_passive_scan; struct work_struct adapter_restart; - struct delayed_work rf_kill; + struct work_struct rf_kill; struct work_struct up; struct work_struct down; - struct delayed_work gather_stats; + struct work_struct gather_stats; struct work_struct abort_scan; struct work_struct roam; - struct delayed_work scan_check; + struct work_struct scan_check; struct work_struct link_up; struct work_struct link_down; @@ -1319,9 +1319,9 @@ struct ipw_priv { u32 led_ofdm_on; u32 led_ofdm_off; - struct delayed_work led_link_on; - struct delayed_work led_link_off; - struct delayed_work led_act_off; + struct work_struct led_link_on; + struct work_struct led_link_off; + struct work_struct led_act_off; struct work_struct merge_networks; struct ipw_cmd_log *cmdlog; diff --git a/trunk/drivers/net/wireless/netwave_cs.c b/trunk/drivers/net/wireless/netwave_cs.c index 644b4741ef74..6714e0dfa8d6 100644 --- a/trunk/drivers/net/wireless/netwave_cs.c +++ b/trunk/drivers/net/wireless/netwave_cs.c @@ -735,13 +735,31 @@ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) static int netwave_pcmcia_config(struct pcmcia_device *link) { struct net_device *dev = link->priv; netwave_private *priv = netdev_priv(dev); + tuple_t tuple; + cisparse_t parse; int i, j, last_ret, last_fn; + u_char buf[64]; win_req_t req; memreq_t mem; u_char __iomem *ramBase = NULL; DEBUG(0, "netwave_pcmcia_config(0x%p)\n", link); + /* + This reads the card's CONFIG tuple to find its configuration + registers. + */ + tuple.Attributes = 0; + tuple.TupleData = (cisdata_t *) buf; + tuple.TupleDataMax = 64; + tuple.TupleOffset = 0; + tuple.DesiredTuple = CISTPL_CONFIG; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + link->conf.ConfigBase = parse.config.base; + link->conf.Present = parse.config.rmask[0]; + /* * Try allocating IO ports. This tries a few fixed addresses. * If you want, you can also read the card's config table to diff --git a/trunk/drivers/net/wireless/orinoco.c b/trunk/drivers/net/wireless/orinoco.c index 936c888e03e1..336cabac13b3 100644 --- a/trunk/drivers/net/wireless/orinoco.c +++ b/trunk/drivers/net/wireless/orinoco.c @@ -980,11 +980,9 @@ static void print_linkstatus(struct net_device *dev, u16 status) } /* Search scan results for requested BSSID, join it if found */ -static void orinoco_join_ap(struct work_struct *work) +static void orinoco_join_ap(struct net_device *dev) { - struct orinoco_private *priv = - container_of(work, struct orinoco_private, join_work); - struct net_device *dev = priv->ndev; + struct orinoco_private *priv = netdev_priv(dev); struct hermes *hw = &priv->hw; int err; unsigned long flags; @@ -1057,11 +1055,9 @@ static void orinoco_join_ap(struct work_struct *work) } /* Send new BSSID to userspace */ -static void orinoco_send_wevents(struct work_struct *work) +static void orinoco_send_wevents(struct net_device *dev) { - struct orinoco_private *priv = - container_of(work, struct orinoco_private, wevent_work); - struct net_device *dev = priv->ndev; + struct orinoco_private *priv = netdev_priv(dev); struct hermes *hw = &priv->hw; union iwreq_data wrqu; int err; @@ -1868,11 +1864,9 @@ __orinoco_set_multicast_list(struct net_device *dev) /* This must be called from user context, without locks held - use * schedule_work() */ -static void orinoco_reset(struct work_struct *work) +static void orinoco_reset(struct net_device *dev) { - struct orinoco_private *priv = - container_of(work, struct orinoco_private, reset_work); - struct net_device *dev = priv->ndev; + struct orinoco_private *priv = netdev_priv(dev); struct hermes *hw = &priv->hw; int err; unsigned long flags; @@ -2440,9 +2434,9 @@ struct net_device *alloc_orinocodev(int sizeof_card, priv->hw_unavailable = 1; /* orinoco_init() must clear this * before anything else touches the * hardware */ - INIT_WORK(&priv->reset_work, orinoco_reset); - INIT_WORK(&priv->join_work, orinoco_join_ap); - INIT_WORK(&priv->wevent_work, orinoco_send_wevents); + INIT_WORK(&priv->reset_work, (void (*)(void *))orinoco_reset, dev); + INIT_WORK(&priv->join_work, (void (*)(void *))orinoco_join_ap, dev); + INIT_WORK(&priv->wevent_work, (void (*)(void *))orinoco_send_wevents, dev); netif_carrier_off(dev); priv->last_linkstatus = 0xffff; @@ -3614,7 +3608,7 @@ static int orinoco_ioctl_reset(struct net_device *dev, printk(KERN_DEBUG "%s: Forcing reset!\n", dev->name); /* Firmware reset */ - orinoco_reset(&priv->reset_work); + orinoco_reset(dev); } else { printk(KERN_DEBUG "%s: Force scheduling reset!\n", dev->name); @@ -4160,7 +4154,7 @@ static int orinoco_ioctl_commit(struct net_device *dev, return 0; if (priv->broken_disableport) { - orinoco_reset(&priv->reset_work); + orinoco_reset(dev); return 0; } diff --git a/trunk/drivers/net/wireless/orinoco_cs.c b/trunk/drivers/net/wireless/orinoco_cs.c index d08ae8d2726c..bc14689cbf24 100644 --- a/trunk/drivers/net/wireless/orinoco_cs.c +++ b/trunk/drivers/net/wireless/orinoco_cs.c @@ -178,6 +178,21 @@ orinoco_cs_config(struct pcmcia_device *link) cisparse_t parse; void __iomem *mem; + /* + * This reads the card's CONFIG tuple to find its + * configuration registers. + */ + tuple.DesiredTuple = CISTPL_CONFIG; + tuple.Attributes = 0; + tuple.TupleData = buf; + tuple.TupleDataMax = sizeof(buf); + tuple.TupleOffset = 0; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + link->conf.ConfigBase = parse.config.base; + link->conf.Present = parse.config.rmask[0]; + /* Look up the current Vcc */ CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &conf)); @@ -196,10 +211,6 @@ orinoco_cs_config(struct pcmcia_device *link) * and most client drivers will only use the CIS to fill in * implementation-defined details. */ - tuple.Attributes = 0; - tuple.TupleData = buf; - tuple.TupleDataMax = sizeof(buf); - tuple.TupleOffset = 0; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); while (1) { diff --git a/trunk/drivers/net/wireless/prism54/isl_ioctl.c b/trunk/drivers/net/wireless/prism54/isl_ioctl.c index a87eb51886c8..4a20e45de3ca 100644 --- a/trunk/drivers/net/wireless/prism54/isl_ioctl.c +++ b/trunk/drivers/net/wireless/prism54/isl_ioctl.c @@ -157,9 +157,8 @@ prism54_mib_init(islpci_private *priv) * schedule_work(), thus we can as well use sleeping semaphore * locking */ void -prism54_update_stats(struct work_struct *work) +prism54_update_stats(islpci_private *priv) { - islpci_private *priv = container_of(work, islpci_private, stats_work); char *data; int j; struct obj_bss bss, *bss2; @@ -2494,10 +2493,9 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid, * interrupt context, no locks held. */ void -prism54_process_trap(struct work_struct *work) +prism54_process_trap(void *data) { - struct islpci_mgmtframe *frame = - container_of(work, struct islpci_mgmtframe, ws); + struct islpci_mgmtframe *frame = data; struct net_device *ndev = frame->ndev; enum oid_num_t n = mgt_oidtonum(frame->header->oid); diff --git a/trunk/drivers/net/wireless/prism54/isl_ioctl.h b/trunk/drivers/net/wireless/prism54/isl_ioctl.h index bcfbfb9281d2..e8183d30c52e 100644 --- a/trunk/drivers/net/wireless/prism54/isl_ioctl.h +++ b/trunk/drivers/net/wireless/prism54/isl_ioctl.h @@ -31,12 +31,12 @@ void prism54_mib_init(islpci_private *); struct iw_statistics *prism54_get_wireless_stats(struct net_device *); -void prism54_update_stats(struct work_struct *); +void prism54_update_stats(islpci_private *); void prism54_acl_init(struct islpci_acl *); void prism54_acl_clean(struct islpci_acl *); -void prism54_process_trap(struct work_struct *); +void prism54_process_trap(void *); void prism54_wpa_bss_ie_init(islpci_private *priv); void prism54_wpa_bss_ie_clean(islpci_private *priv); diff --git a/trunk/drivers/net/wireless/prism54/islpci_dev.c b/trunk/drivers/net/wireless/prism54/islpci_dev.c index f057fd9fcd79..1e0603ca436c 100644 --- a/trunk/drivers/net/wireless/prism54/islpci_dev.c +++ b/trunk/drivers/net/wireless/prism54/islpci_dev.c @@ -860,10 +860,11 @@ islpci_setup(struct pci_dev *pdev) priv->state_off = 1; /* initialize workqueue's */ - INIT_WORK(&priv->stats_work, prism54_update_stats); + INIT_WORK(&priv->stats_work, + (void (*)(void *)) prism54_update_stats, priv); priv->stats_timestamp = 0; - INIT_WORK(&priv->reset_task, islpci_do_reset_and_wake); + INIT_WORK(&priv->reset_task, islpci_do_reset_and_wake, priv); priv->reset_task_pending = 0; /* allocate various memory areas */ diff --git a/trunk/drivers/net/wireless/prism54/islpci_eth.c b/trunk/drivers/net/wireless/prism54/islpci_eth.c index b1122912ee2d..676d83813dc8 100644 --- a/trunk/drivers/net/wireless/prism54/islpci_eth.c +++ b/trunk/drivers/net/wireless/prism54/islpci_eth.c @@ -480,9 +480,9 @@ islpci_eth_receive(islpci_private *priv) } void -islpci_do_reset_and_wake(struct work_struct *work) +islpci_do_reset_and_wake(void *data) { - islpci_private *priv = container_of(work, islpci_private, reset_task); + islpci_private *priv = data; islpci_reset(priv, 1); priv->reset_task_pending = 0; diff --git a/trunk/drivers/net/wireless/prism54/islpci_eth.h b/trunk/drivers/net/wireless/prism54/islpci_eth.h index 5bf820defbd0..26789454067c 100644 --- a/trunk/drivers/net/wireless/prism54/islpci_eth.h +++ b/trunk/drivers/net/wireless/prism54/islpci_eth.h @@ -67,6 +67,6 @@ void islpci_eth_cleanup_transmit(islpci_private *, isl38xx_control_block *); int islpci_eth_transmit(struct sk_buff *, struct net_device *); int islpci_eth_receive(islpci_private *); void islpci_eth_tx_timeout(struct net_device *); -void islpci_do_reset_and_wake(struct work_struct *); +void islpci_do_reset_and_wake(void *data); #endif /* _ISL_GEN_H */ diff --git a/trunk/drivers/net/wireless/prism54/islpci_mgt.c b/trunk/drivers/net/wireless/prism54/islpci_mgt.c index 2246f7930b4e..036a875054c9 100644 --- a/trunk/drivers/net/wireless/prism54/islpci_mgt.c +++ b/trunk/drivers/net/wireless/prism54/islpci_mgt.c @@ -386,7 +386,7 @@ islpci_mgt_receive(struct net_device *ndev) /* Create work to handle trap out of interrupt * context. */ - INIT_WORK(&frame->ws, prism54_process_trap); + INIT_WORK(&frame->ws, prism54_process_trap, frame); schedule_work(&frame->ws); } else { diff --git a/trunk/drivers/net/wireless/ray_cs.c b/trunk/drivers/net/wireless/ray_cs.c index 88e10c9bc4ac..7fbfc9e41d07 100644 --- a/trunk/drivers/net/wireless/ray_cs.c +++ b/trunk/drivers/net/wireless/ray_cs.c @@ -408,8 +408,11 @@ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) #define MAX_TUPLE_SIZE 128 static int ray_config(struct pcmcia_device *link) { + tuple_t tuple; + cisparse_t parse; int last_fn = 0, last_ret = 0; int i; + u_char buf[MAX_TUPLE_SIZE]; win_req_t req; memreq_t mem; struct net_device *dev = (struct net_device *)link->priv; @@ -417,12 +420,29 @@ static int ray_config(struct pcmcia_device *link) DEBUG(1, "ray_config(0x%p)\n", link); + /* This reads the card's CONFIG tuple to find its configuration regs */ + tuple.DesiredTuple = CISTPL_CONFIG; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + tuple.TupleData = buf; + tuple.TupleDataMax = MAX_TUPLE_SIZE; + tuple.TupleOffset = 0; + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + link->conf.ConfigBase = parse.config.base; + link->conf.Present = parse.config.rmask[0]; + /* Determine card type and firmware version */ - printk(KERN_INFO "ray_cs Detected: %s%s%s%s\n", - link->prod_id[0] ? link->prod_id[0] : " ", - link->prod_id[1] ? link->prod_id[1] : " ", - link->prod_id[2] ? link->prod_id[2] : " ", - link->prod_id[3] ? link->prod_id[3] : " "); + buf[0] = buf[MAX_TUPLE_SIZE - 1] = 0; + tuple.DesiredTuple = CISTPL_VERS_1; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + tuple.TupleData = buf; + tuple.TupleDataMax = MAX_TUPLE_SIZE; + tuple.TupleOffset = 2; + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + + for (i=0; iconf.ConfigBase = parse.config.base; + link->conf.Present = parse.config.rmask[0]; + /* Look up the current Vcc */ CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &conf)); @@ -666,10 +681,6 @@ spectrum_cs_config(struct pcmcia_device *link) * implementation-defined details. */ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - tuple.Attributes = 0; - tuple.TupleData = buf; - tuple.TupleDataMax = sizeof(buf); - tuple.TupleOffset = 0; CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); while (1) { cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); diff --git a/trunk/drivers/net/wireless/wavelan_cs.c b/trunk/drivers/net/wireless/wavelan_cs.c index 233d906c08f0..aafb301041b1 100644 --- a/trunk/drivers/net/wireless/wavelan_cs.c +++ b/trunk/drivers/net/wireless/wavelan_cs.c @@ -3939,8 +3939,11 @@ wv_hw_reset(struct net_device * dev) static inline int wv_pcmcia_config(struct pcmcia_device * link) { + tuple_t tuple; + cisparse_t parse; struct net_device * dev = (struct net_device *) link->priv; int i; + u_char buf[64]; win_req_t req; memreq_t mem; net_local * lp = netdev_priv(dev); @@ -3950,6 +3953,36 @@ wv_pcmcia_config(struct pcmcia_device * link) printk(KERN_DEBUG "->wv_pcmcia_config(0x%p)\n", link); #endif + /* + * This reads the card's CONFIG tuple to find its configuration + * registers. + */ + do + { + tuple.Attributes = 0; + tuple.DesiredTuple = CISTPL_CONFIG; + i = pcmcia_get_first_tuple(link, &tuple); + if(i != CS_SUCCESS) + break; + tuple.TupleData = (cisdata_t *)buf; + tuple.TupleDataMax = 64; + tuple.TupleOffset = 0; + i = pcmcia_get_tuple_data(link, &tuple); + if(i != CS_SUCCESS) + break; + i = pcmcia_parse_tuple(link, &tuple, &parse); + if(i != CS_SUCCESS) + break; + link->conf.ConfigBase = parse.config.base; + link->conf.Present = parse.config.rmask[0]; + } + while(0); + if(i != CS_SUCCESS) + { + cs_error(link, ParseTuple, i); + return FALSE; + } + do { i = pcmcia_request_io(link, &link->io); diff --git a/trunk/drivers/net/wireless/wl3501_cs.c b/trunk/drivers/net/wireless/wl3501_cs.c index 583e0d655a98..5b98a7876982 100644 --- a/trunk/drivers/net/wireless/wl3501_cs.c +++ b/trunk/drivers/net/wireless/wl3501_cs.c @@ -1966,10 +1966,25 @@ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) */ static int wl3501_config(struct pcmcia_device *link) { + tuple_t tuple; + cisparse_t parse; struct net_device *dev = link->priv; int i = 0, j, last_fn, last_ret; + unsigned char bf[64]; struct wl3501_card *this; + /* This reads the card's CONFIG tuple to find its config registers. */ + tuple.Attributes = 0; + tuple.DesiredTuple = CISTPL_CONFIG; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + tuple.TupleData = bf; + tuple.TupleDataMax = sizeof(bf); + tuple.TupleOffset = 0; + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + link->conf.ConfigBase = parse.config.base; + link->conf.Present = parse.config.rmask[0]; + /* Try allocating IO ports. This tries a few fixed addresses. If you * want, you can also read the card's config table to pick addresses -- * see the serial driver for an example. */ diff --git a/trunk/drivers/net/wireless/zd1211rw/zd_mac.c b/trunk/drivers/net/wireless/zd1211rw/zd_mac.c index f1573a9c2336..2696f95b9278 100644 --- a/trunk/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/trunk/drivers/net/wireless/zd1211rw/zd_mac.c @@ -32,8 +32,8 @@ static void ieee_init(struct ieee80211_device *ieee); static void softmac_init(struct ieee80211softmac_device *sm); -static void set_rts_cts_work(struct work_struct *work); -static void set_basic_rates_work(struct work_struct *work); +static void set_rts_cts_work(void *d); +static void set_basic_rates_work(void *d); static void housekeeping_init(struct zd_mac *mac); static void housekeeping_enable(struct zd_mac *mac); @@ -48,8 +48,8 @@ int zd_mac_init(struct zd_mac *mac, memset(mac, 0, sizeof(*mac)); spin_lock_init(&mac->lock); mac->netdev = netdev; - INIT_DELAYED_WORK(&mac->set_rts_cts_work, set_rts_cts_work); - INIT_DELAYED_WORK(&mac->set_basic_rates_work, set_basic_rates_work); + INIT_WORK(&mac->set_rts_cts_work, set_rts_cts_work, mac); + INIT_WORK(&mac->set_basic_rates_work, set_basic_rates_work, mac); ieee_init(ieee); softmac_init(ieee80211_priv(netdev)); @@ -366,10 +366,9 @@ static void try_enable_tx(struct zd_mac *mac) spin_unlock_irqrestore(&mac->lock, flags); } -static void set_rts_cts_work(struct work_struct *work) +static void set_rts_cts_work(void *d) { - struct zd_mac *mac = - container_of(work, struct zd_mac, set_rts_cts_work.work); + struct zd_mac *mac = d; unsigned long flags; u8 rts_rate; unsigned int short_preamble; @@ -388,10 +387,9 @@ static void set_rts_cts_work(struct work_struct *work) try_enable_tx(mac); } -static void set_basic_rates_work(struct work_struct *work) +static void set_basic_rates_work(void *d) { - struct zd_mac *mac = - container_of(work, struct zd_mac, set_basic_rates_work.work); + struct zd_mac *mac = d; unsigned long flags; u16 basic_rates; @@ -469,13 +467,12 @@ static void bssinfo_change(struct net_device *netdev, u32 changes) if (need_set_rts_cts && !mac->updating_rts_rate) { mac->updating_rts_rate = 1; netif_stop_queue(mac->netdev); - queue_delayed_work(zd_workqueue, &mac->set_rts_cts_work, 0); + queue_work(zd_workqueue, &mac->set_rts_cts_work); } if (need_set_rates && !mac->updating_basic_rates) { mac->updating_basic_rates = 1; netif_stop_queue(mac->netdev); - queue_delayed_work(zd_workqueue, &mac->set_basic_rates_work, - 0); + queue_work(zd_workqueue, &mac->set_basic_rates_work); } spin_unlock_irqrestore(&mac->lock, flags); } @@ -1185,10 +1182,9 @@ struct iw_statistics *zd_mac_get_wireless_stats(struct net_device *ndev) #define LINK_LED_WORK_DELAY HZ -static void link_led_handler(struct work_struct *work) +static void link_led_handler(void *p) { - struct zd_mac *mac = - container_of(work, struct zd_mac, housekeeping.link_led_work.work); + struct zd_mac *mac = p; struct zd_chip *chip = &mac->chip; struct ieee80211softmac_device *sm = ieee80211_priv(mac->netdev); int is_associated; @@ -1209,7 +1205,7 @@ static void link_led_handler(struct work_struct *work) static void housekeeping_init(struct zd_mac *mac) { - INIT_DELAYED_WORK(&mac->housekeeping.link_led_work, link_led_handler); + INIT_WORK(&mac->housekeeping.link_led_work, link_led_handler, mac); } static void housekeeping_enable(struct zd_mac *mac) diff --git a/trunk/drivers/net/wireless/zd1211rw/zd_mac.h b/trunk/drivers/net/wireless/zd1211rw/zd_mac.h index d4e8b870409d..5dcfb251f02e 100644 --- a/trunk/drivers/net/wireless/zd1211rw/zd_mac.h +++ b/trunk/drivers/net/wireless/zd1211rw/zd_mac.h @@ -119,7 +119,7 @@ struct rx_status { #define ZD_RX_ERROR 0x80 struct housekeeping { - struct delayed_work link_led_work; + struct work_struct link_led_work; }; #define ZD_MAC_STATS_BUFFER_SIZE 16 @@ -133,8 +133,8 @@ struct zd_mac { struct iw_statistics iw_stats; struct housekeeping housekeeping; - struct delayed_work set_rts_cts_work; - struct delayed_work set_basic_rates_work; + struct work_struct set_rts_cts_work; + struct work_struct set_basic_rates_work; unsigned int stats_count; u8 qual_buffer[ZD_MAC_STATS_BUFFER_SIZE]; diff --git a/trunk/drivers/oprofile/cpu_buffer.c b/trunk/drivers/oprofile/cpu_buffer.c index a83c3db7d18f..fc4bc9b94c74 100644 --- a/trunk/drivers/oprofile/cpu_buffer.c +++ b/trunk/drivers/oprofile/cpu_buffer.c @@ -29,7 +29,7 @@ struct oprofile_cpu_buffer cpu_buffer[NR_CPUS] __cacheline_aligned; -static void wq_sync_buffer(struct work_struct *work); +static void wq_sync_buffer(void *); #define DEFAULT_TIMER_EXPIRE (HZ / 10) static int work_enabled; @@ -65,7 +65,7 @@ int alloc_cpu_buffers(void) b->sample_received = 0; b->sample_lost_overflow = 0; b->cpu = i; - INIT_DELAYED_WORK(&b->work, wq_sync_buffer); + INIT_WORK(&b->work, wq_sync_buffer, b); } return 0; @@ -282,10 +282,9 @@ void oprofile_add_trace(unsigned long pc) * By using schedule_delayed_work_on and then schedule_delayed_work * we guarantee this will stay on the correct cpu */ -static void wq_sync_buffer(struct work_struct *work) +static void wq_sync_buffer(void * data) { - struct oprofile_cpu_buffer * b = - container_of(work, struct oprofile_cpu_buffer, work.work); + struct oprofile_cpu_buffer * b = data; if (b->cpu != smp_processor_id()) { printk("WQ on CPU%d, prefer CPU%d\n", smp_processor_id(), b->cpu); diff --git a/trunk/drivers/oprofile/cpu_buffer.h b/trunk/drivers/oprofile/cpu_buffer.h index 49900d9e3235..09abb80e0570 100644 --- a/trunk/drivers/oprofile/cpu_buffer.h +++ b/trunk/drivers/oprofile/cpu_buffer.h @@ -43,7 +43,7 @@ struct oprofile_cpu_buffer { unsigned long sample_lost_overflow; unsigned long backtrace_aborted; int cpu; - struct delayed_work work; + struct work_struct work; } ____cacheline_aligned; extern struct oprofile_cpu_buffer cpu_buffer[]; diff --git a/trunk/drivers/parport/parport_cs.c b/trunk/drivers/parport/parport_cs.c index e60b4bf6bae8..b953d5907c05 100644 --- a/trunk/drivers/parport/parport_cs.c +++ b/trunk/drivers/parport/parport_cs.c @@ -166,6 +166,14 @@ static int parport_config(struct pcmcia_device *link) tuple.TupleData = (cisdata_t *)buf; tuple.TupleOffset = 0; tuple.TupleDataMax = 255; + tuple.Attributes = 0; + tuple.DesiredTuple = CISTPL_CONFIG; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + link->conf.ConfigBase = parse.config.base; + link->conf.Present = parse.config.rmask[0]; + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; tuple.Attributes = 0; CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); @@ -255,7 +263,6 @@ void parport_cs_release(struct pcmcia_device *link) static struct pcmcia_device_id parport_ids[] = { PCMCIA_DEVICE_FUNC_ID(3), - PCMCIA_MFC_DEVICE_PROD_ID12(1,"Elan","Serial+Parallel Port: SP230",0x3beb8cf2,0xdb9e58bc), PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0003), PCMCIA_DEVICE_NULL }; diff --git a/trunk/drivers/pci/hotplug/shpchp.h b/trunk/drivers/pci/hotplug/shpchp.h index 50757695844f..ea2087c34149 100644 --- a/trunk/drivers/pci/hotplug/shpchp.h +++ b/trunk/drivers/pci/hotplug/shpchp.h @@ -70,7 +70,7 @@ struct slot { struct hotplug_slot *hotplug_slot; struct list_head slot_list; char name[SLOT_NAME_SIZE]; - struct delayed_work work; /* work for button event */ + struct work_struct work; /* work for button event */ struct mutex lock; }; @@ -187,7 +187,7 @@ extern int shpchp_configure_device(struct slot *p_slot); extern int shpchp_unconfigure_device(struct slot *p_slot); extern void shpchp_remove_ctrl_files(struct controller *ctrl); extern void cleanup_slots(struct controller *ctrl); -extern void queue_pushbutton_work(struct work_struct *work); +extern void queue_pushbutton_work(void *data); #ifdef CONFIG_ACPI diff --git a/trunk/drivers/pci/hotplug/shpchp_core.c b/trunk/drivers/pci/hotplug/shpchp_core.c index 4eac85b3d90e..235c18a22393 100644 --- a/trunk/drivers/pci/hotplug/shpchp_core.c +++ b/trunk/drivers/pci/hotplug/shpchp_core.c @@ -159,7 +159,7 @@ static int init_slots(struct controller *ctrl) goto error_info; slot->number = sun; - INIT_DELAYED_WORK(&slot->work, queue_pushbutton_work); + INIT_WORK(&slot->work, queue_pushbutton_work, slot); /* register this slot with the hotplug pci core */ hotplug_slot->private = slot; diff --git a/trunk/drivers/pci/hotplug/shpchp_ctrl.c b/trunk/drivers/pci/hotplug/shpchp_ctrl.c index 158ac7836096..c39901dbff20 100644 --- a/trunk/drivers/pci/hotplug/shpchp_ctrl.c +++ b/trunk/drivers/pci/hotplug/shpchp_ctrl.c @@ -36,7 +36,7 @@ #include "../pci.h" #include "shpchp.h" -static void interrupt_event_handler(struct work_struct *work); +static void interrupt_event_handler(void *data); static int shpchp_enable_slot(struct slot *p_slot); static int shpchp_disable_slot(struct slot *p_slot); @@ -50,7 +50,7 @@ static int queue_interrupt_event(struct slot *p_slot, u32 event_type) info->event_type = event_type; info->p_slot = p_slot; - INIT_WORK(&info->work, interrupt_event_handler); + INIT_WORK(&info->work, interrupt_event_handler, info); schedule_work(&info->work); @@ -408,10 +408,9 @@ struct pushbutton_work_info { * Handles all pending events and exits. * */ -static void shpchp_pushbutton_thread(struct work_struct *work) +static void shpchp_pushbutton_thread(void *data) { - struct pushbutton_work_info *info = - container_of(work, struct pushbutton_work_info, work); + struct pushbutton_work_info *info = data; struct slot *p_slot = info->p_slot; mutex_lock(&p_slot->lock); @@ -437,9 +436,9 @@ static void shpchp_pushbutton_thread(struct work_struct *work) kfree(info); } -void queue_pushbutton_work(struct work_struct *work) +void queue_pushbutton_work(void *data) { - struct slot *p_slot = container_of(work, struct slot, work.work); + struct slot *p_slot = data; struct pushbutton_work_info *info; info = kmalloc(sizeof(*info), GFP_KERNEL); @@ -448,7 +447,7 @@ void queue_pushbutton_work(struct work_struct *work) return; } info->p_slot = p_slot; - INIT_WORK(&info->work, shpchp_pushbutton_thread); + INIT_WORK(&info->work, shpchp_pushbutton_thread, info); mutex_lock(&p_slot->lock); switch (p_slot->state) { @@ -542,9 +541,9 @@ static void handle_button_press_event(struct slot *p_slot) } } -static void interrupt_event_handler(struct work_struct *work) +static void interrupt_event_handler(void *data) { - struct event_info *info = container_of(work, struct event_info, work); + struct event_info *info = data; struct slot *p_slot = info->p_slot; mutex_lock(&p_slot->lock); diff --git a/trunk/drivers/pci/pcie/aer/aerdrv.c b/trunk/drivers/pci/pcie/aer/aerdrv.c index 55866b6b26fa..04c43ef529ac 100644 --- a/trunk/drivers/pci/pcie/aer/aerdrv.c +++ b/trunk/drivers/pci/pcie/aer/aerdrv.c @@ -160,7 +160,7 @@ static struct aer_rpc* aer_alloc_rpc(struct pcie_device *dev) rpc->e_lock = SPIN_LOCK_UNLOCKED; rpc->rpd = dev; - INIT_WORK(&rpc->dpc_handler, aer_isr); + INIT_WORK(&rpc->dpc_handler, aer_isr, (void *)dev); rpc->prod_idx = rpc->cons_idx = 0; mutex_init(&rpc->rpc_mutex); init_waitqueue_head(&rpc->wait_release); diff --git a/trunk/drivers/pci/pcie/aer/aerdrv.h b/trunk/drivers/pci/pcie/aer/aerdrv.h index 3c0a58f64dd8..daf0cad88fc8 100644 --- a/trunk/drivers/pci/pcie/aer/aerdrv.h +++ b/trunk/drivers/pci/pcie/aer/aerdrv.h @@ -118,7 +118,7 @@ extern struct bus_type pcie_port_bus_type; extern void aer_enable_rootport(struct aer_rpc *rpc); extern void aer_delete_rootport(struct aer_rpc *rpc); extern int aer_init(struct pcie_device *dev); -extern void aer_isr(struct work_struct *work); +extern void aer_isr(void *context); extern void aer_print_error(struct pci_dev *dev, struct aer_err_info *info); extern int aer_osc_setup(struct pci_dev *dev); diff --git a/trunk/drivers/pci/pcie/aer/aerdrv_core.c b/trunk/drivers/pci/pcie/aer/aerdrv_core.c index 08e13033ced8..1c7e660d6535 100644 --- a/trunk/drivers/pci/pcie/aer/aerdrv_core.c +++ b/trunk/drivers/pci/pcie/aer/aerdrv_core.c @@ -690,14 +690,14 @@ static void aer_isr_one_error(struct pcie_device *p_device, /** * aer_isr - consume errors detected by root port - * @work: definition of this work item + * @context: pointer to a private data of pcie device * * Invoked, as DPC, when root port records new detected error **/ -void aer_isr(struct work_struct *work) +void aer_isr(void *context) { - struct aer_rpc *rpc = container_of(work, struct aer_rpc, dpc_handler); - struct pcie_device *p_device = rpc->rpd; + struct pcie_device *p_device = (struct pcie_device *) context; + struct aer_rpc *rpc = get_service_data(p_device); struct aer_err_source *e_src; mutex_lock(&rpc->rpc_mutex); diff --git a/trunk/drivers/pcmcia/at91_cf.c b/trunk/drivers/pcmcia/at91_cf.c index b6746301d9a9..3bcb7dc32995 100644 --- a/trunk/drivers/pcmcia/at91_cf.c +++ b/trunk/drivers/pcmcia/at91_cf.c @@ -32,11 +32,10 @@ * A0..A10 work in each range; A23 indicates I/O space; A25 is CFRNW; * some other bit in {A24,A22..A11} is nREG to flag memory access * (vs attributes). So more than 2KB/region would just be waste. - * Note: These are offsets from the physical base address. */ -#define CF_ATTR_PHYS (0) -#define CF_IO_PHYS (1 << 23) -#define CF_MEM_PHYS (0x017ff800) +#define CF_ATTR_PHYS (AT91_CF_BASE) +#define CF_IO_PHYS (AT91_CF_BASE + (1 << 23)) +#define CF_MEM_PHYS (AT91_CF_BASE + 0x017ff800) /*--------------------------------------------------------------------------*/ @@ -49,8 +48,6 @@ struct at91_cf_socket { struct platform_device *pdev; struct at91_cf_data *board; - - unsigned long phys_baseaddr; }; #define SZ_2K (2 * SZ_1K) @@ -157,8 +154,9 @@ static int at91_cf_set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io) /* * Use 16 bit accesses unless/until we need 8-bit i/o space. + * Always set CSR4 ... PCMCIA won't always unmap things. */ - csr = at91_sys_read(AT91_SMC_CSR(cf->board->chipselect)) & ~AT91_SMC_DBW; + csr = at91_sys_read(AT91_SMC_CSR(4)) & ~AT91_SMC_DBW; /* * NOTE: this CF controller ignores IOIS16, so we can't really do @@ -170,14 +168,14 @@ static int at91_cf_set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io) * some cards only like that way to get at the odd byte, despite * CF 3.0 spec table 35 also giving the D8-D15 option. */ - if (!(io->flags & (MAP_16BIT | MAP_AUTOSZ))) { + if (!(io->flags & (MAP_16BIT|MAP_AUTOSZ))) { csr |= AT91_SMC_DBW_8; pr_debug("%s: 8bit i/o bus\n", driver_name); } else { csr |= AT91_SMC_DBW_16; pr_debug("%s: 16bit i/o bus\n", driver_name); } - at91_sys_write(AT91_SMC_CSR(cf->board->chipselect), csr); + at91_sys_write(AT91_SMC_CSR(4), csr); io->start = cf->socket.io_offset; io->stop = io->start + SZ_2K - 1; @@ -196,11 +194,11 @@ at91_cf_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *map) cf = container_of(s, struct at91_cf_socket, socket); - map->flags &= (MAP_ACTIVE | MAP_ATTRIB | MAP_16BIT); + map->flags &= MAP_ACTIVE|MAP_ATTRIB|MAP_16BIT; if (map->flags & MAP_ATTRIB) - map->static_start = cf->phys_baseaddr + CF_ATTR_PHYS; + map->static_start = CF_ATTR_PHYS; else - map->static_start = cf->phys_baseaddr + CF_MEM_PHYS; + map->static_start = CF_MEM_PHYS; return 0; } @@ -221,6 +219,7 @@ static int __init at91_cf_probe(struct platform_device *pdev) struct at91_cf_socket *cf; struct at91_cf_data *board = pdev->dev.platform_data; struct resource *io; + unsigned int csa; int status; if (!board || !board->det_pin || !board->rst_pin) @@ -236,11 +235,33 @@ static int __init at91_cf_probe(struct platform_device *pdev) cf->board = board; cf->pdev = pdev; - cf->phys_baseaddr = io->start; platform_set_drvdata(pdev, cf); + /* CF takes over CS4, CS5, CS6 */ + csa = at91_sys_read(AT91_EBI_CSA); + at91_sys_write(AT91_EBI_CSA, csa | AT91_EBI_CS4A_SMC_COMPACTFLASH); + + /* nWAIT is _not_ a default setting */ + (void) at91_set_A_periph(AT91_PIN_PC6, 1); /* nWAIT */ + + /* + * Static memory controller timing adjustments. + * REVISIT: these timings are in terms of MCK cycles, so + * when MCK changes (cpufreq etc) so must these values... + */ + at91_sys_write(AT91_SMC_CSR(4), + AT91_SMC_ACSS_STD + | AT91_SMC_DBW_16 + | AT91_SMC_BAT + | AT91_SMC_WSEN + | AT91_SMC_NWS_(32) /* wait states */ + | AT91_SMC_RWSETUP_(6) /* setup time */ + | AT91_SMC_RWHOLD_(4) /* hold time */ + ); + /* must be a GPIO; ergo must trigger on both edges */ - status = request_irq(board->det_pin, at91_cf_irq, 0, driver_name, cf); + status = request_irq(board->det_pin, at91_cf_irq, + IRQF_SAMPLE_RANDOM, driver_name, cf); if (status < 0) goto fail0; device_init_wakeup(&pdev->dev, 1); @@ -261,18 +282,14 @@ static int __init at91_cf_probe(struct platform_device *pdev) cf->socket.pci_irq = NR_IRQS + 1; /* pcmcia layer only remaps "real" memory not iospace */ - cf->socket.io_offset = (unsigned long) ioremap(cf->phys_baseaddr + CF_IO_PHYS, SZ_2K); - if (!cf->socket.io_offset) { - status = -ENXIO; + cf->socket.io_offset = (unsigned long) ioremap(CF_IO_PHYS, SZ_2K); + if (!cf->socket.io_offset) goto fail1; - } - /* reserve chip-select regions */ + /* reserve CS4, CS5, and CS6 regions; but use just CS4 */ if (!request_mem_region(io->start, io->end + 1 - io->start, - driver_name)) { - status = -ENXIO; + driver_name)) goto fail1; - } pr_info("%s: irqs det #%d, io #%d\n", driver_name, board->det_pin, board->irq_pin); @@ -302,7 +319,9 @@ static int __init at91_cf_probe(struct platform_device *pdev) fail0a: device_init_wakeup(&pdev->dev, 0); free_irq(board->det_pin, cf); + device_init_wakeup(&pdev->dev, 0); fail0: + at91_sys_write(AT91_EBI_CSA, csa); kfree(cf); return status; } @@ -312,15 +331,19 @@ static int __exit at91_cf_remove(struct platform_device *pdev) struct at91_cf_socket *cf = platform_get_drvdata(pdev); struct at91_cf_data *board = cf->board; struct resource *io = cf->socket.io[0].res; + unsigned int csa; pcmcia_unregister_socket(&cf->socket); if (board->irq_pin) free_irq(board->irq_pin, cf); - device_init_wakeup(&pdev->dev, 0); free_irq(board->det_pin, cf); + device_init_wakeup(&pdev->dev, 0); iounmap((void __iomem *) cf->socket.io_offset); release_mem_region(io->start, io->end + 1 - io->start); + csa = at91_sys_read(AT91_EBI_CSA); + at91_sys_write(AT91_EBI_CSA, csa & ~AT91_EBI_CS4A); + kfree(cf); return 0; } diff --git a/trunk/drivers/pcmcia/cs_internal.h b/trunk/drivers/pcmcia/cs_internal.h index f573ea04db6f..d6164cd583fd 100644 --- a/trunk/drivers/pcmcia/cs_internal.h +++ b/trunk/drivers/pcmcia/cs_internal.h @@ -135,7 +135,7 @@ int pccard_get_status(struct pcmcia_socket *s, struct pcmcia_device *p_dev, cs_s struct pcmcia_callback{ struct module *owner; int (*event) (struct pcmcia_socket *s, event_t event, int priority); - void (*requery) (struct pcmcia_socket *s, int new_cis); + void (*requery) (struct pcmcia_socket *s); int (*suspend) (struct pcmcia_socket *s); int (*resume) (struct pcmcia_socket *s); }; diff --git a/trunk/drivers/pcmcia/ds.c b/trunk/drivers/pcmcia/ds.c index 7355eb455a88..21d83a895b21 100644 --- a/trunk/drivers/pcmcia/ds.c +++ b/trunk/drivers/pcmcia/ds.c @@ -231,6 +231,65 @@ static void pcmcia_check_driver(struct pcmcia_driver *p_drv) } +#ifdef CONFIG_PCMCIA_LOAD_CIS + +/** + * pcmcia_load_firmware - load CIS from userspace if device-provided is broken + * @dev - the pcmcia device which needs a CIS override + * @filename - requested filename in /lib/firmware/ + * + * This uses the in-kernel firmware loading mechanism to use a "fake CIS" if + * the one provided by the card is broken. The firmware files reside in + * /lib/firmware/ in userspace. + */ +static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename) +{ + struct pcmcia_socket *s = dev->socket; + const struct firmware *fw; + char path[20]; + int ret=-ENOMEM; + cisdump_t *cis; + + if (!filename) + return -EINVAL; + + ds_dbg(1, "trying to load firmware %s\n", filename); + + if (strlen(filename) > 14) + return -EINVAL; + + snprintf(path, 20, "%s", filename); + + if (request_firmware(&fw, path, &dev->dev) == 0) { + if (fw->size >= CISTPL_MAX_CIS_SIZE) + goto release; + + cis = kzalloc(sizeof(cisdump_t), GFP_KERNEL); + if (!cis) + goto release; + + cis->Length = fw->size + 1; + memcpy(cis->Data, fw->data, fw->size); + + if (!pcmcia_replace_cis(s, cis)) + ret = 0; + } + release: + release_firmware(fw); + + return (ret); +} + +#else /* !CONFIG_PCMCIA_LOAD_CIS */ + +static inline int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename) +{ + return -ENODEV; +} + +#endif + + /*======================================================================*/ @@ -250,8 +309,6 @@ int pcmcia_register_driver(struct pcmcia_driver *driver) driver->drv.bus = &pcmcia_bus_type; driver->drv.owner = driver->owner; - ds_dbg(3, "registering driver %s\n", driver->drv.name); - return driver_register(&driver->drv); } EXPORT_SYMBOL(pcmcia_register_driver); @@ -261,7 +318,6 @@ EXPORT_SYMBOL(pcmcia_register_driver); */ void pcmcia_unregister_driver(struct pcmcia_driver *driver) { - ds_dbg(3, "unregistering driver %s\n", driver->drv.name); driver_unregister(&driver->drv); } EXPORT_SYMBOL(pcmcia_unregister_driver); @@ -287,27 +343,23 @@ void pcmcia_put_dev(struct pcmcia_device *p_dev) static void pcmcia_release_function(struct kref *ref) { struct config_t *c = container_of(ref, struct config_t, ref); - ds_dbg(1, "releasing config_t\n"); kfree(c); } static void pcmcia_release_dev(struct device *dev) { struct pcmcia_device *p_dev = to_pcmcia_dev(dev); - ds_dbg(1, "releasing device %s\n", p_dev->dev.bus_id); + ds_dbg(1, "releasing dev %p\n", p_dev); pcmcia_put_socket(p_dev->socket); kfree(p_dev->devname); kref_put(&p_dev->function_config->ref, pcmcia_release_function); kfree(p_dev); } -static void pcmcia_add_device_later(struct pcmcia_socket *s, int mfc) +static void pcmcia_add_pseudo_device(struct pcmcia_socket *s) { if (!s->pcmcia_state.device_add_pending) { - ds_dbg(1, "scheduling to add %s secondary" - " device to %d\n", mfc ? "mfc" : "pfc", s->sock); s->pcmcia_state.device_add_pending = 1; - s->pcmcia_state.mfc_pfc = mfc; schedule_work(&s->device_add); } return; @@ -319,7 +371,6 @@ static int pcmcia_device_probe(struct device * dev) struct pcmcia_driver *p_drv; struct pcmcia_device_id *did; struct pcmcia_socket *s; - cistpl_config_t cis_config; int ret = 0; dev = get_device(dev); @@ -330,33 +381,15 @@ static int pcmcia_device_probe(struct device * dev) p_drv = to_pcmcia_drv(dev->driver); s = p_dev->socket; - ds_dbg(1, "trying to bind %s to %s\n", p_dev->dev.bus_id, - p_drv->drv.name); - if ((!p_drv->probe) || (!p_dev->function_config) || (!try_module_get(p_drv->owner))) { ret = -EINVAL; goto put_dev; } - /* set up some more device information */ - ret = pccard_read_tuple(p_dev->socket, p_dev->func, CISTPL_CONFIG, - &cis_config); - if (!ret) { - p_dev->conf.ConfigBase = cis_config.base; - p_dev->conf.Present = cis_config.rmask[0]; - } else { - printk(KERN_INFO "pcmcia: could not parse base and rmask0 of CIS\n"); - p_dev->conf.ConfigBase = 0; - p_dev->conf.Present = 0; - } - ret = p_drv->probe(p_dev); - if (ret) { - ds_dbg(1, "binding %s to %s failed with %d\n", - p_dev->dev.bus_id, p_drv->drv.name, ret); + if (ret) goto put_module; - } /* handle pseudo multifunction devices: * there are at most two pseudo multifunction devices. @@ -367,7 +400,7 @@ static int pcmcia_device_probe(struct device * dev) did = p_dev->dev.driver_data; if (did && (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) && (p_dev->socket->device_count == 1) && (p_dev->device_no == 0)) - pcmcia_add_device_later(p_dev->socket, 0); + pcmcia_add_pseudo_device(p_dev->socket); put_module: if (ret) @@ -388,8 +421,8 @@ static void pcmcia_card_remove(struct pcmcia_socket *s, struct pcmcia_device *le struct pcmcia_device *tmp; unsigned long flags; - ds_dbg(2, "pcmcia_card_remove(%d) %s\n", s->sock, - leftover ? leftover->devname : ""); + ds_dbg(2, "unbind_request(%d)\n", s->sock); + if (!leftover) s->device_count = 0; @@ -406,7 +439,6 @@ static void pcmcia_card_remove(struct pcmcia_socket *s, struct pcmcia_device *le p_dev->_removed=1; spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); - ds_dbg(2, "unregistering device %s\n", p_dev->dev.bus_id); device_unregister(&p_dev->dev); } @@ -423,8 +455,6 @@ static int pcmcia_device_remove(struct device * dev) p_dev = to_pcmcia_dev(dev); p_drv = to_pcmcia_drv(dev->driver); - ds_dbg(1, "removing device %s\n", p_dev->dev.bus_id); - /* If we're removing the primary module driving a * pseudo multi-function card, we need to unbind * all devices @@ -557,10 +587,8 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f mutex_lock(&device_add_lock); - ds_dbg(3, "adding device to %d, function %d\n", s->sock, function); - - /* max of 4 devices per card */ - if (s->device_count == 4) + /* max of 2 devices per card */ + if (s->device_count == 2) goto err_put; p_dev = kzalloc(sizeof(struct pcmcia_device), GFP_KERNEL); @@ -570,6 +598,8 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f p_dev->socket = s; p_dev->device_no = (s->device_count++); p_dev->func = function; + if (s->functions <= function) + s->functions = function + 1; p_dev->dev.bus = &pcmcia_bus_type; p_dev->dev.parent = s->dev.dev; @@ -580,8 +610,8 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f if (!p_dev->devname) goto err_free; sprintf (p_dev->devname, "pcmcia%s", p_dev->dev.bus_id); - ds_dbg(3, "devname is %s\n", p_dev->devname); + /* compat */ spin_lock_irqsave(&pcmcia_dev_list_lock, flags); /* @@ -601,7 +631,6 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); if (!p_dev->function_config) { - ds_dbg(3, "creating config_t for %s\n", p_dev->dev.bus_id); p_dev->function_config = kzalloc(sizeof(struct config_t), GFP_KERNEL); if (!p_dev->function_config) @@ -645,16 +674,11 @@ static int pcmcia_card_add(struct pcmcia_socket *s) unsigned int no_funcs, i; int ret = 0; - if (!(s->resource_setup_done)) { - ds_dbg(3, "no resources available, delaying card_add\n"); + if (!(s->resource_setup_done)) return -EAGAIN; /* try again, but later... */ - } - if (pcmcia_validate_mem(s)) { - ds_dbg(3, "validating mem resources failed, " - "delaying card_add\n"); + if (pcmcia_validate_mem(s)) return -EAGAIN; /* try again, but later... */ - } ret = pccard_validate_cis(s, BIND_FN_ALL, &cisinfo); if (ret || !cisinfo.Chains) { @@ -666,7 +690,6 @@ static int pcmcia_card_add(struct pcmcia_socket *s) no_funcs = mfc.nfn; else no_funcs = 1; - s->functions = no_funcs; for (i=0; i < no_funcs; i++) pcmcia_device_add(s, i); @@ -675,50 +698,38 @@ static int pcmcia_card_add(struct pcmcia_socket *s) } -static void pcmcia_delayed_add_device(struct work_struct *work) +static void pcmcia_delayed_add_pseudo_device(void *data) { - struct pcmcia_socket *s = - container_of(work, struct pcmcia_socket, device_add); - ds_dbg(1, "adding additional device to %d\n", s->sock); - pcmcia_device_add(s, s->pcmcia_state.mfc_pfc); + struct pcmcia_socket *s = data; + pcmcia_device_add(s, 0); s->pcmcia_state.device_add_pending = 0; - s->pcmcia_state.mfc_pfc = 0; } static int pcmcia_requery(struct device *dev, void * _data) { struct pcmcia_device *p_dev = to_pcmcia_dev(dev); - if (!p_dev->dev.driver) { - ds_dbg(1, "update device information for %s\n", - p_dev->dev.bus_id); + if (!p_dev->dev.driver) pcmcia_device_query(p_dev); - } return 0; } -static void pcmcia_bus_rescan(struct pcmcia_socket *skt, int new_cis) +static void pcmcia_bus_rescan(struct pcmcia_socket *skt) { - int no_devices = 0; + int no_devices=0; int ret = 0; unsigned long flags; /* must be called with skt_mutex held */ - ds_dbg(0, "re-scanning socket %d\n", skt->sock); - spin_lock_irqsave(&pcmcia_dev_list_lock, flags); if (list_empty(&skt->devices_list)) - no_devices = 1; + no_devices=1; spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); - /* If this is because of a CIS override, start over */ - if (new_cis && !no_devices) - pcmcia_card_remove(skt, NULL); - /* if no devices were added for this socket yet because of * missing resource information or other trouble, we need to * do this now. */ - if (no_devices || new_cis) { + if (no_devices) { ret = pcmcia_card_add(skt); if (ret) return; @@ -736,97 +747,6 @@ static void pcmcia_bus_rescan(struct pcmcia_socket *skt, int new_cis) printk(KERN_INFO "pcmcia: bus_rescan_devices failed\n"); } -#ifdef CONFIG_PCMCIA_LOAD_CIS - -/** - * pcmcia_load_firmware - load CIS from userspace if device-provided is broken - * @dev - the pcmcia device which needs a CIS override - * @filename - requested filename in /lib/firmware/ - * - * This uses the in-kernel firmware loading mechanism to use a "fake CIS" if - * the one provided by the card is broken. The firmware files reside in - * /lib/firmware/ in userspace. - */ -static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename) -{ - struct pcmcia_socket *s = dev->socket; - const struct firmware *fw; - char path[20]; - int ret = -ENOMEM; - int no_funcs; - int old_funcs; - cisdump_t *cis; - cistpl_longlink_mfc_t mfc; - - if (!filename) - return -EINVAL; - - ds_dbg(1, "trying to load CIS file %s\n", filename); - - if (strlen(filename) > 14) { - printk(KERN_WARNING "pcmcia: CIS filename is too long\n"); - return -EINVAL; - } - - snprintf(path, 20, "%s", filename); - - if (request_firmware(&fw, path, &dev->dev) == 0) { - if (fw->size >= CISTPL_MAX_CIS_SIZE) { - ret = -EINVAL; - printk(KERN_ERR "pcmcia: CIS override is too big\n"); - goto release; - } - - cis = kzalloc(sizeof(cisdump_t), GFP_KERNEL); - if (!cis) { - ret = -ENOMEM; - goto release; - } - - cis->Length = fw->size + 1; - memcpy(cis->Data, fw->data, fw->size); - - if (!pcmcia_replace_cis(s, cis)) - ret = 0; - else { - printk(KERN_ERR "pcmcia: CIS override failed\n"); - goto release; - } - - - /* update information */ - pcmcia_device_query(dev); - - /* does this cis override add or remove functions? */ - old_funcs = s->functions; - - if (!pccard_read_tuple(s, BIND_FN_ALL, CISTPL_LONGLINK_MFC, &mfc)) - no_funcs = mfc.nfn; - else - no_funcs = 1; - s->functions = no_funcs; - - if (old_funcs > no_funcs) - pcmcia_card_remove(s, dev); - else if (no_funcs > old_funcs) - pcmcia_add_device_later(s, 1); - } - release: - release_firmware(fw); - - return (ret); -} - -#else /* !CONFIG_PCMCIA_LOAD_CIS */ - -static inline int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename) -{ - return -ENODEV; -} - -#endif - - static inline int pcmcia_devmatch(struct pcmcia_device *dev, struct pcmcia_device_id *did) { @@ -893,14 +813,11 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev, * after it has re-checked that there is no possible module * with a prod_id/manf_id/card_id match. */ - ds_dbg(0, "skipping FUNC_ID match for %s until userspace " - "interaction\n", dev->dev.bus_id); if (!dev->allow_func_id_match) return 0; } if (did->match_flags & PCMCIA_DEV_ID_MATCH_FAKE_CIS) { - ds_dbg(0, "device %s needs a fake CIS\n", dev->dev.bus_id); if (!dev->socket->fake_cis) pcmcia_load_firmware(dev, did->cisfile); @@ -930,21 +847,13 @@ static int pcmcia_bus_match(struct device * dev, struct device_driver * drv) { #ifdef CONFIG_PCMCIA_IOCTL /* matching by cardmgr */ - if (p_dev->cardmgr == p_drv) { - ds_dbg(0, "cardmgr matched %s to %s\n", dev->bus_id, - drv->name); + if (p_dev->cardmgr == p_drv) return 1; - } #endif while (did && did->match_flags) { - ds_dbg(3, "trying to match %s to %s\n", dev->bus_id, - drv->name); - if (pcmcia_devmatch(p_dev, did)) { - ds_dbg(0, "matched %s to %s\n", dev->bus_id, - drv->name); + if (pcmcia_devmatch(p_dev, did)) return 1; - } did++; } @@ -1135,8 +1044,6 @@ static int pcmcia_dev_suspend(struct device * dev, pm_message_t state) struct pcmcia_driver *p_drv = NULL; int ret = 0; - ds_dbg(2, "suspending %s\n", dev->bus_id); - if (dev->driver) p_drv = to_pcmcia_drv(dev->driver); @@ -1145,18 +1052,12 @@ static int pcmcia_dev_suspend(struct device * dev, pm_message_t state) if (p_drv->suspend) { ret = p_drv->suspend(p_dev); - if (ret) { - printk(KERN_ERR "pcmcia: device %s (driver %s) did " - "not want to go to sleep (%d)\n", - p_dev->devname, p_drv->drv.name, ret); + if (ret) goto out; - } } - if (p_dev->device_no == p_dev->func) { - ds_dbg(2, "releasing configuration for %s\n", dev->bus_id); + if (p_dev->device_no == p_dev->func) pcmcia_release_configuration(p_dev); - } out: if (!ret) @@ -1171,8 +1072,6 @@ static int pcmcia_dev_resume(struct device * dev) struct pcmcia_driver *p_drv = NULL; int ret = 0; - ds_dbg(2, "resuming %s\n", dev->bus_id); - if (dev->driver) p_drv = to_pcmcia_drv(dev->driver); @@ -1180,7 +1079,6 @@ static int pcmcia_dev_resume(struct device * dev) goto out; if (p_dev->device_no == p_dev->func) { - ds_dbg(2, "requesting configuration for %s\n", dev->bus_id); ret = pcmcia_request_configuration(p_dev, &p_dev->conf); if (ret) goto out; @@ -1222,14 +1120,12 @@ static int pcmcia_bus_resume_callback(struct device *dev, void * _data) static int pcmcia_bus_resume(struct pcmcia_socket *skt) { - ds_dbg(2, "resuming socket %d\n", skt->sock); bus_for_each_dev(&pcmcia_bus_type, NULL, skt, pcmcia_bus_resume_callback); return 0; } static int pcmcia_bus_suspend(struct pcmcia_socket *skt) { - ds_dbg(2, "suspending socket %d\n", skt->sock); if (bus_for_each_dev(&pcmcia_bus_type, NULL, skt, pcmcia_bus_suspend_callback)) { pcmcia_bus_resume(skt); @@ -1350,7 +1246,7 @@ static int __devinit pcmcia_bus_add_socket(struct class_device *class_dev, init_waitqueue_head(&socket->queue); #endif INIT_LIST_HEAD(&socket->devices_list); - INIT_WORK(&socket->device_add, pcmcia_delayed_add_device); + INIT_WORK(&socket->device_add, pcmcia_delayed_add_pseudo_device, socket); memset(&socket->pcmcia_state, 0, sizeof(u8)); socket->device_count = 0; diff --git a/trunk/drivers/pcmcia/m32r_cfc.c b/trunk/drivers/pcmcia/m32r_cfc.c index 3c22ac4625c2..36fdaa58458c 100644 --- a/trunk/drivers/pcmcia/m32r_cfc.c +++ b/trunk/drivers/pcmcia/m32r_cfc.c @@ -398,7 +398,7 @@ static irqreturn_t pcc_interrupt(int irq, void *dev) static void pcc_interrupt_wrapper(u_long data) { debug(3, "m32r_cfc: pcc_interrupt_wrapper:\n"); - pcc_interrupt(0, NULL); + pcc_interrupt(0, NULL, NULL); init_timer(&poll_timer); poll_timer.expires = jiffies + poll_interval; add_timer(&poll_timer); diff --git a/trunk/drivers/pcmcia/pcmcia_ioctl.c b/trunk/drivers/pcmcia/pcmcia_ioctl.c index d077870c6731..310ede575caa 100644 --- a/trunk/drivers/pcmcia/pcmcia_ioctl.c +++ b/trunk/drivers/pcmcia/pcmcia_ioctl.c @@ -594,12 +594,7 @@ static int ds_ioctl(struct inode * inode, struct file * file, err = ret = 0; - if (cmd & IOC_IN) { - if (__copy_from_user((char *)buf, uarg, size)) { - err = -EFAULT; - goto free_out; - } - } + if (cmd & IOC_IN) __copy_from_user((char *)buf, uarg, size); switch (cmd) { case DS_ADJUST_RESOURCE_INFO: diff --git a/trunk/drivers/pcmcia/pd6729.c b/trunk/drivers/pcmcia/pd6729.c index 360c24896548..a70f97fdbbdd 100644 --- a/trunk/drivers/pcmcia/pd6729.c +++ b/trunk/drivers/pcmcia/pd6729.c @@ -581,10 +581,10 @@ static irqreturn_t pd6729_test(int irq, void *dev) return IRQ_HANDLED; } -static int pd6729_check_irq(int irq) +static int pd6729_check_irq(int irq, int flags) { - if (request_irq(irq, pd6729_test, IRQF_PROBE_SHARED, "x", pd6729_test) - != 0) return -1; + if (request_irq(irq, pd6729_test, flags, "x", pd6729_test) != 0) + return -1; free_irq(irq, pd6729_test); return 0; } @@ -610,7 +610,7 @@ static u_int __devinit pd6729_isa_scan(void) /* just find interrupts that aren't in use */ for (i = 0; i < 16; i++) - if ((mask0 & (1 << i)) && (pd6729_check_irq(i) == 0)) + if ((mask0 & (1 << i)) && (pd6729_check_irq(i, 0) == 0)) mask |= (1 << i); printk(KERN_INFO "pd6729: ISA irqs = "); diff --git a/trunk/drivers/pcmcia/socket_sysfs.c b/trunk/drivers/pcmcia/socket_sysfs.c index b005602d6b53..933cd864a5c9 100644 --- a/trunk/drivers/pcmcia/socket_sysfs.c +++ b/trunk/drivers/pcmcia/socket_sysfs.c @@ -188,7 +188,7 @@ static ssize_t pccard_store_resource(struct class_device *dev, const char *buf, (s->state & SOCKET_PRESENT) && !(s->state & SOCKET_CARDBUS)) { if (try_module_get(s->callback->owner)) { - s->callback->requery(s, 0); + s->callback->requery(s); module_put(s->callback->owner); } } @@ -325,7 +325,7 @@ static ssize_t pccard_store_cis(struct kobject *kobj, char *buf, loff_t off, siz if ((s->callback) && (s->state & SOCKET_PRESENT) && !(s->state & SOCKET_CARDBUS)) { if (try_module_get(s->callback->owner)) { - s->callback->requery(s, 1); + s->callback->requery(s); module_put(s->callback->owner); } } diff --git a/trunk/drivers/rtc/rtc-dev.c b/trunk/drivers/rtc/rtc-dev.c index 828b329e08e0..814b9e1873f5 100644 --- a/trunk/drivers/rtc/rtc-dev.c +++ b/trunk/drivers/rtc/rtc-dev.c @@ -53,10 +53,9 @@ static int rtc_dev_open(struct inode *inode, struct file *file) * Routine to poll RTC seconds field for change as often as possible, * after first RTC_UIE use timer to reduce polling */ -static void rtc_uie_task(struct work_struct *work) +static void rtc_uie_task(void *data) { - struct rtc_device *rtc = - container_of(work, struct rtc_device, uie_task); + struct rtc_device *rtc = data; struct rtc_time tm; int num = 0; int err; @@ -412,7 +411,7 @@ static int rtc_dev_add_device(struct class_device *class_dev, spin_lock_init(&rtc->irq_lock); init_waitqueue_head(&rtc->irq_queue); #ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL - INIT_WORK(&rtc->uie_task, rtc_uie_task); + INIT_WORK(&rtc->uie_task, rtc_uie_task, rtc); setup_timer(&rtc->uie_timer, rtc_uie_timer, (unsigned long)rtc); #endif diff --git a/trunk/drivers/scsi/53c700.c b/trunk/drivers/scsi/53c700.c index 335a25540c08..562432d017b0 100644 --- a/trunk/drivers/scsi/53c700.c +++ b/trunk/drivers/scsi/53c700.c @@ -622,10 +622,8 @@ NCR_700_scsi_done(struct NCR_700_Host_Parameters *hostdata, dma_unmap_single(hostdata->dev, slot->dma_handle, sizeof(SCp->sense_buffer), DMA_FROM_DEVICE); /* restore the old result if the request sense was * successful */ - if (result == 0) + if(result == 0) result = cmnd[7]; - /* restore the original length */ - SCp->cmd_len = cmnd[8]; } else NCR_700_unmap(hostdata, SCp, slot); @@ -1009,9 +1007,6 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp, * of the command */ cmnd[6] = NCR_700_INTERNAL_SENSE_MAGIC; cmnd[7] = hostdata->status[0]; - cmnd[8] = SCp->cmd_len; - SCp->cmd_len = 6; /* command length for - * REQUEST_SENSE */ slot->pCmd = dma_map_single(hostdata->dev, cmnd, MAX_COMMAND_SIZE, DMA_TO_DEVICE); slot->dma_handle = dma_map_single(hostdata->dev, SCp->sense_buffer, sizeof(SCp->sense_buffer), DMA_FROM_DEVICE); slot->SG[0].ins = bS_to_host(SCRIPT_MOVE_DATA_IN | sizeof(SCp->sense_buffer)); diff --git a/trunk/drivers/scsi/BusLogic.c b/trunk/drivers/scsi/BusLogic.c index 3075204915c8..cdd033724786 100644 --- a/trunk/drivers/scsi/BusLogic.c +++ b/trunk/drivers/scsi/BusLogic.c @@ -2186,21 +2186,21 @@ static int __init BusLogic_init(void) if (BusLogic_ProbeOptions.NoProbe) return -ENODEV; - BusLogic_ProbeInfoList = - kzalloc(BusLogic_MaxHostAdapters * sizeof(struct BusLogic_ProbeInfo), GFP_KERNEL); + BusLogic_ProbeInfoList = (struct BusLogic_ProbeInfo *) + kmalloc(BusLogic_MaxHostAdapters * sizeof(struct BusLogic_ProbeInfo), GFP_ATOMIC); if (BusLogic_ProbeInfoList == NULL) { BusLogic_Error("BusLogic: Unable to allocate Probe Info List\n", NULL); return -ENOMEM; } - - PrototypeHostAdapter = - kzalloc(sizeof(struct BusLogic_HostAdapter), GFP_KERNEL); + memset(BusLogic_ProbeInfoList, 0, BusLogic_MaxHostAdapters * sizeof(struct BusLogic_ProbeInfo)); + PrototypeHostAdapter = (struct BusLogic_HostAdapter *) + kmalloc(sizeof(struct BusLogic_HostAdapter), GFP_ATOMIC); if (PrototypeHostAdapter == NULL) { kfree(BusLogic_ProbeInfoList); BusLogic_Error("BusLogic: Unable to allocate Prototype " "Host Adapter\n", NULL); return -ENOMEM; } - + memset(PrototypeHostAdapter, 0, sizeof(struct BusLogic_HostAdapter)); #ifdef MODULE if (BusLogic != NULL) BusLogic_Setup(BusLogic); diff --git a/trunk/drivers/scsi/Kconfig b/trunk/drivers/scsi/Kconfig index 69569096dae5..9540eb8efdcb 100644 --- a/trunk/drivers/scsi/Kconfig +++ b/trunk/drivers/scsi/Kconfig @@ -29,13 +29,6 @@ config SCSI However, do not compile this as a module if your root file system (the one containing the directory /) is located on a SCSI device. -config SCSI_TGT - tristate "SCSI target support" - depends on SCSI && EXPERIMENTAL - ---help--- - If you want to use SCSI target mode drivers enable this option. - If you choose M, the module will be called scsi_tgt. - config SCSI_NETLINK bool default n @@ -223,23 +216,6 @@ config SCSI_LOGGING there should be no noticeable performance impact as long as you have logging turned off. -config SCSI_SCAN_ASYNC - bool "Asynchronous SCSI scanning" - depends on SCSI - help - The SCSI subsystem can probe for devices while the rest of the - system continues booting, and even probe devices on different - busses in parallel, leading to a significant speed-up. - If you have built SCSI as modules, enabling this option can - be a problem as the devices may not have been found by the - time your system expects them to have been. You can load the - scsi_wait_scan module to ensure that all scans have completed. - If you build your SCSI drivers into the kernel, then everything - will work fine if you say Y here. - - You can override this choice by specifying scsi_mod.scan="sync" - or "async" on the kernel's command line. - menu "SCSI Transports" depends on SCSI @@ -821,20 +797,6 @@ config SCSI_IBMVSCSI To compile this driver as a module, choose M here: the module will be called ibmvscsic. -config SCSI_IBMVSCSIS - tristate "IBM Virtual SCSI Server support" - depends on PPC_PSERIES && SCSI_TGT && SCSI_SRP - help - This is the SRP target driver for IBM pSeries virtual environments. - - The userspace component needed to initialize the driver and - documentation can be found: - - http://stgt.berlios.de/ - - To compile this driver as a module, choose M here: the - module will be called ibmvstgt. - config SCSI_INITIO tristate "Initio 9100U(W) support" depends on PCI && SCSI @@ -982,13 +944,8 @@ config SCSI_STEX tristate "Promise SuperTrak EX Series support" depends on PCI && SCSI ---help--- - This driver supports Promise SuperTrak EX series storage controllers. - - Promise provides Linux RAID configuration utility for these - controllers. Please visit to download. - - To compile this driver as a module, choose M here: the - module will be called stex. + This driver supports Promise SuperTrak EX8350/8300/16350/16300 + Storage controllers. config SCSI_SYM53C8XX_2 tristate "SYM53C8XX Version 2 SCSI support" @@ -1069,7 +1026,6 @@ config SCSI_IPR config SCSI_IPR_TRACE bool "enable driver internal trace" depends on SCSI_IPR - default y help If you say Y here, the driver will trace all commands issued to the adapter. Performance impact is minimal. Trace can be @@ -1078,7 +1034,6 @@ config SCSI_IPR_TRACE config SCSI_IPR_DUMP bool "enable adapter dump support" depends on SCSI_IPR - default y help If you say Y here, the driver will support adapter crash dump. If you enable this support, the iprdump daemon can be used @@ -1779,16 +1734,6 @@ config ZFCP called zfcp. If you want to compile it as a module, say M here and read . -config SCSI_SRP - tristate "SCSI RDMA Protocol helper library" - depends on SCSI && PCI - select SCSI_TGT - help - If you wish to use SRP target drivers, say Y. - - To compile this driver as a module, choose M here: the - module will be called libsrp. - endmenu source "drivers/scsi/pcmcia/Kconfig" diff --git a/trunk/drivers/scsi/Makefile b/trunk/drivers/scsi/Makefile index bd7c9888f7f4..bcca39c3bcbf 100644 --- a/trunk/drivers/scsi/Makefile +++ b/trunk/drivers/scsi/Makefile @@ -21,7 +21,6 @@ CFLAGS_seagate.o = -DARBITRATE -DPARITY -DSEAGATE_USE_ASM subdir-$(CONFIG_PCMCIA) += pcmcia obj-$(CONFIG_SCSI) += scsi_mod.o -obj-$(CONFIG_SCSI_TGT) += scsi_tgt.o obj-$(CONFIG_RAID_ATTRS) += raid_class.o @@ -126,9 +125,7 @@ obj-$(CONFIG_SCSI_FCAL) += fcal.o obj-$(CONFIG_SCSI_LASI700) += 53c700.o lasi700.o obj-$(CONFIG_SCSI_NSP32) += nsp32.o obj-$(CONFIG_SCSI_IPR) += ipr.o -obj-$(CONFIG_SCSI_SRP) += libsrp.o obj-$(CONFIG_SCSI_IBMVSCSI) += ibmvscsi/ -obj-$(CONFIG_SCSI_IBMVSCSIS) += ibmvscsi/ obj-$(CONFIG_SCSI_HPTIOP) += hptiop.o obj-$(CONFIG_SCSI_STEX) += stex.o @@ -144,8 +141,6 @@ obj-$(CONFIG_CHR_DEV_SCH) += ch.o # This goes last, so that "real" scsi devices probe earlier obj-$(CONFIG_SCSI_DEBUG) += scsi_debug.o -obj-$(CONFIG_SCSI) += scsi_wait_scan.o - scsi_mod-y += scsi.o hosts.o scsi_ioctl.o constants.o \ scsicam.o scsi_error.o scsi_lib.o \ scsi_scan.o scsi_sysfs.o \ @@ -154,8 +149,6 @@ scsi_mod-$(CONFIG_SCSI_NETLINK) += scsi_netlink.o scsi_mod-$(CONFIG_SYSCTL) += scsi_sysctl.o scsi_mod-$(CONFIG_SCSI_PROC_FS) += scsi_proc.o -scsi_tgt-y += scsi_tgt_lib.o scsi_tgt_if.o - sd_mod-objs := sd.o sr_mod-objs := sr.o sr_ioctl.o sr_vendor.o ncr53c8xx-flags-$(CONFIG_SCSI_ZALON) \ diff --git a/trunk/drivers/scsi/NCR5380.c b/trunk/drivers/scsi/NCR5380.c index bb3cb3360541..a6aa91072880 100644 --- a/trunk/drivers/scsi/NCR5380.c +++ b/trunk/drivers/scsi/NCR5380.c @@ -849,7 +849,7 @@ static int __devinit NCR5380_init(struct Scsi_Host *instance, int flags) hostdata->issue_queue = NULL; hostdata->disconnected_queue = NULL; - INIT_DELAYED_WORK(&hostdata->coroutine, NCR5380_main); + INIT_WORK(&hostdata->coroutine, NCR5380_main, hostdata); #ifdef NCR5380_STATS for (i = 0; i < 8; ++i) { @@ -1016,7 +1016,7 @@ static int NCR5380_queue_command(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)) /* Run the coroutine if it isn't already running. */ /* Kick off command processing */ - schedule_delayed_work(&hostdata->coroutine, 0); + schedule_work(&hostdata->coroutine); return 0; } @@ -1033,10 +1033,9 @@ static int NCR5380_queue_command(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)) * host lock and called routines may take the isa dma lock. */ -static void NCR5380_main(struct work_struct *work) +static void NCR5380_main(void *p) { - struct NCR5380_hostdata *hostdata = - container_of(work, struct NCR5380_hostdata, coroutine.work); + struct NCR5380_hostdata *hostdata = p; struct Scsi_Host *instance = hostdata->host; Scsi_Cmnd *tmp, *prev; int done; @@ -1222,7 +1221,7 @@ static irqreturn_t NCR5380_intr(int irq, void *dev_id) } /* if BASR_IRQ */ spin_unlock_irqrestore(instance->host_lock, flags); if(!done) - schedule_delayed_work(&hostdata->coroutine, 0); + schedule_work(&hostdata->coroutine); } while (!done); return IRQ_HANDLED; } diff --git a/trunk/drivers/scsi/NCR5380.h b/trunk/drivers/scsi/NCR5380.h index 713a108c02ef..1bc73de496b0 100644 --- a/trunk/drivers/scsi/NCR5380.h +++ b/trunk/drivers/scsi/NCR5380.h @@ -271,7 +271,7 @@ struct NCR5380_hostdata { unsigned long time_expires; /* in jiffies, set prior to sleeping */ int select_time; /* timer in select for target response */ volatile Scsi_Cmnd *selecting; - struct delayed_work coroutine; /* our co-routine */ + struct work_struct coroutine; /* our co-routine */ #ifdef NCR5380_STATS unsigned timebase; /* Base for time calcs */ long time_read[8]; /* time to do reads */ @@ -298,7 +298,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance); #ifndef DONT_USE_INTR static irqreturn_t NCR5380_intr(int irq, void *dev_id); #endif -static void NCR5380_main(struct work_struct *work); +static void NCR5380_main(void *ptr); static void NCR5380_print_options(struct Scsi_Host *instance); #ifdef NDEBUG static void NCR5380_print_phase(struct Scsi_Host *instance); diff --git a/trunk/drivers/scsi/NCR53c406a.c b/trunk/drivers/scsi/NCR53c406a.c index 8578555d58fd..d4613815f685 100644 --- a/trunk/drivers/scsi/NCR53c406a.c +++ b/trunk/drivers/scsi/NCR53c406a.c @@ -220,11 +220,9 @@ static void *addresses[] = { static unsigned short ports[] = { 0x230, 0x330, 0x280, 0x290, 0x330, 0x340, 0x300, 0x310, 0x348, 0x350 }; #define PORT_COUNT ARRAY_SIZE(ports) -#ifndef MODULE /* possible interrupt channels */ static unsigned short intrs[] = { 10, 11, 12, 15 }; #define INTR_COUNT ARRAY_SIZE(intrs) -#endif /* !MODULE */ /* signatures for NCR 53c406a based controllers */ #if USE_BIOS @@ -607,7 +605,6 @@ static int NCR53c406a_release(struct Scsi_Host *shost) return 0; } -#ifndef MODULE /* called from init/main.c */ static int __init NCR53c406a_setup(char *str) { @@ -664,8 +661,6 @@ static int __init NCR53c406a_setup(char *str) __setup("ncr53c406a=", NCR53c406a_setup); -#endif /* !MODULE */ - static const char *NCR53c406a_info(struct Scsi_Host *SChost) { DEB(printk("NCR53c406a_info called\n")); diff --git a/trunk/drivers/scsi/aacraid/aacraid.h b/trunk/drivers/scsi/aacraid/aacraid.h index 4f8b4c53d435..eb3ed91bac79 100644 --- a/trunk/drivers/scsi/aacraid/aacraid.h +++ b/trunk/drivers/scsi/aacraid/aacraid.h @@ -11,8 +11,8 @@ *----------------------------------------------------------------------------*/ #ifndef AAC_DRIVER_BUILD -# define AAC_DRIVER_BUILD 2423 -# define AAC_DRIVER_BRANCH "-mh3" +# define AAC_DRIVER_BUILD 2409 +# define AAC_DRIVER_BRANCH "-mh2" #endif #define MAXIMUM_NUM_CONTAINERS 32 diff --git a/trunk/drivers/scsi/aacraid/commsup.c b/trunk/drivers/scsi/aacraid/commsup.c index 4893a6d06a33..19e42ac07cb2 100644 --- a/trunk/drivers/scsi/aacraid/commsup.c +++ b/trunk/drivers/scsi/aacraid/commsup.c @@ -518,7 +518,6 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, */ unsigned long count = 36000000L; /* 3 minutes */ while (down_trylock(&fibptr->event_wait)) { - int blink; if (--count == 0) { spin_lock_irqsave(q->lock, qflags); q->numpending--; @@ -531,14 +530,6 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, } return -ETIMEDOUT; } - if ((blink = aac_adapter_check_health(dev)) > 0) { - if (wait == -1) { - printk(KERN_ERR "aacraid: aac_fib_send: adapter blinkLED 0x%x.\n" - "Usually a result of a serious unrecoverable hardware problem\n", - blink); - } - return -EFAULT; - } udelay(5); } } else if (down_interruptible(&fibptr->event_wait)) { @@ -1102,20 +1093,6 @@ static int _aac_reset_adapter(struct aac_dev *aac) goto out; } - /* - * Loop through the fibs, close the synchronous FIBS - */ - for (index = 0; index < (aac->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB); index++) { - struct fib *fib = &aac->fibs[index]; - if (!(fib->hw_fib->header.XferState & cpu_to_le32(NoResponseExpected | Async)) && - (fib->hw_fib->header.XferState & cpu_to_le32(ResponseExpected))) { - unsigned long flagv; - spin_lock_irqsave(&fib->event_lock, flagv); - up(&fib->event_wait); - spin_unlock_irqrestore(&fib->event_lock, flagv); - schedule(); - } - } index = aac->cardtype; /* diff --git a/trunk/drivers/scsi/aha152x.c b/trunk/drivers/scsi/aha152x.c index 0cec742d12e9..306f46b85a55 100644 --- a/trunk/drivers/scsi/aha152x.c +++ b/trunk/drivers/scsi/aha152x.c @@ -1443,7 +1443,7 @@ static struct work_struct aha152x_tq; * Run service completions on the card with interrupts enabled. * */ -static void run(struct work_struct *work) +static void run(void) { struct aha152x_hostdata *hd; @@ -1499,7 +1499,7 @@ static irqreturn_t intr(int irqno, void *dev_id) HOSTDATA(shpnt)->service=1; /* Poke the BH handler */ - INIT_WORK(&aha152x_tq, run); + INIT_WORK(&aha152x_tq, (void *) run, NULL); schedule_work(&aha152x_tq); } DO_UNLOCK(flags); diff --git a/trunk/drivers/scsi/aha1740.c b/trunk/drivers/scsi/aha1740.c index d7af9c63a04d..c3c38a7e8d32 100644 --- a/trunk/drivers/scsi/aha1740.c +++ b/trunk/drivers/scsi/aha1740.c @@ -586,7 +586,7 @@ static struct scsi_host_template aha1740_template = { static int aha1740_probe (struct device *dev) { - int slotbase, rc; + int slotbase; unsigned int irq_level, irq_type, translation; struct Scsi_Host *shpnt; struct aha1740_hostdata *host; @@ -641,16 +641,10 @@ static int aha1740_probe (struct device *dev) } eisa_set_drvdata (edev, shpnt); - - rc = scsi_add_host (shpnt, dev); - if (rc) - goto err_irq; - + scsi_add_host (shpnt, dev); /* XXX handle failure */ scsi_scan_host (shpnt); return 0; - err_irq: - free_irq(irq_level, shpnt); err_unmap: dma_unmap_single (&edev->dev, host->ecb_dma_addr, sizeof (host->ecb), DMA_BIDIRECTIONAL); diff --git a/trunk/drivers/scsi/aic7xxx/aic79xx_osm_pci.c b/trunk/drivers/scsi/aic7xxx/aic79xx_osm_pci.c index 1a3ab6aa856b..2001fe890e71 100644 --- a/trunk/drivers/scsi/aic7xxx/aic79xx_osm_pci.c +++ b/trunk/drivers/scsi/aic7xxx/aic79xx_osm_pci.c @@ -62,7 +62,6 @@ static struct pci_device_id ahd_linux_pci_id_table[] = { /* aic7901 based controllers */ ID(ID_AHA_29320A), ID(ID_AHA_29320ALP), - ID(ID_AHA_29320LPE), /* aic7902 based controllers */ ID(ID_AHA_29320), ID(ID_AHA_29320B), diff --git a/trunk/drivers/scsi/aic7xxx/aic79xx_pci.c b/trunk/drivers/scsi/aic7xxx/aic79xx_pci.c index 2cf7bb3123f0..c07735819cd1 100644 --- a/trunk/drivers/scsi/aic7xxx/aic79xx_pci.c +++ b/trunk/drivers/scsi/aic7xxx/aic79xx_pci.c @@ -109,13 +109,7 @@ static struct ahd_pci_identity ahd_pci_ident_table [] = { ID_AHA_29320ALP, ID_ALL_MASK, - "Adaptec 29320ALP PCIx Ultra320 SCSI adapter", - ahd_aic7901_setup - }, - { - ID_AHA_29320LPE, - ID_ALL_MASK, - "Adaptec 29320LPE PCIe Ultra320 SCSI adapter", + "Adaptec 29320ALP Ultra320 SCSI adapter", ahd_aic7901_setup }, /* aic7901A based controllers */ diff --git a/trunk/drivers/scsi/aic7xxx/aic79xx_pci.h b/trunk/drivers/scsi/aic7xxx/aic79xx_pci.h index 16b7c70a673c..da45153668c7 100644 --- a/trunk/drivers/scsi/aic7xxx/aic79xx_pci.h +++ b/trunk/drivers/scsi/aic7xxx/aic79xx_pci.h @@ -51,7 +51,6 @@ #define ID_AIC7901 0x800F9005FFFF9005ull #define ID_AHA_29320A 0x8000900500609005ull #define ID_AHA_29320ALP 0x8017900500449005ull -#define ID_AHA_29320LPE 0x8017900500459005ull #define ID_AIC7901A 0x801E9005FFFF9005ull #define ID_AHA_29320LP 0x8014900500449005ull diff --git a/trunk/drivers/scsi/aic94xx/aic94xx_init.c b/trunk/drivers/scsi/aic94xx/aic94xx_init.c index 42302ef05ee5..57c5ba4043f2 100644 --- a/trunk/drivers/scsi/aic94xx/aic94xx_init.c +++ b/trunk/drivers/scsi/aic94xx/aic94xx_init.c @@ -724,15 +724,6 @@ static void asd_free_queues(struct asd_ha_struct *asd_ha) list_for_each_safe(pos, n, &pending) { struct asd_ascb *ascb = list_entry(pos, struct asd_ascb, list); - /* - * Delete unexpired ascb timers. This may happen if we issue - * a CONTROL PHY scb to an adapter and rmmod before the scb - * times out. Apparently we don't wait for the CONTROL PHY - * to complete, so it doesn't matter if we kill the timer. - */ - del_timer_sync(&ascb->timer); - WARN_ON(ascb->scb->header.opcode != CONTROL_PHY); - list_del_init(pos); ASD_DPRINTK("freeing from pending\n"); asd_ascb_free(ascb); diff --git a/trunk/drivers/scsi/aic94xx/aic94xx_scb.c b/trunk/drivers/scsi/aic94xx/aic94xx_scb.c index 75ed6b0569d1..b15caf1c8fa2 100644 --- a/trunk/drivers/scsi/aic94xx/aic94xx_scb.c +++ b/trunk/drivers/scsi/aic94xx/aic94xx_scb.c @@ -25,7 +25,6 @@ */ #include -#include #include "aic94xx.h" #include "aic94xx_reg.h" @@ -413,40 +412,6 @@ void asd_invalidate_edb(struct asd_ascb *ascb, int edb_id) } } -/* hard reset a phy later */ -static void do_phy_reset_later(struct work_struct *work) -{ - struct sas_phy *sas_phy = - container_of(work, struct sas_phy, reset_work); - int error; - - ASD_DPRINTK("%s: About to hard reset phy %d\n", __FUNCTION__, - sas_phy->identify.phy_identifier); - /* Reset device port */ - error = sas_phy_reset(sas_phy, 1); - if (error) - ASD_DPRINTK("%s: Hard reset of phy %d failed (%d).\n", - __FUNCTION__, sas_phy->identify.phy_identifier, error); -} - -static void phy_reset_later(struct sas_phy *sas_phy, struct Scsi_Host *shost) -{ - INIT_WORK(&sas_phy->reset_work, do_phy_reset_later); - queue_work(shost->work_q, &sas_phy->reset_work); -} - -/* start up the ABORT TASK tmf... */ -static void task_kill_later(struct asd_ascb *ascb) -{ - struct asd_ha_struct *asd_ha = ascb->ha; - struct sas_ha_struct *sas_ha = &asd_ha->sas_ha; - struct Scsi_Host *shost = sas_ha->core.shost; - struct sas_task *task = ascb->uldd_task; - - INIT_WORK(&task->abort_work, sas_task_abort); - queue_work(shost->work_q, &task->abort_work); -} - static void escb_tasklet_complete(struct asd_ascb *ascb, struct done_list_struct *dl) { @@ -474,74 +439,6 @@ static void escb_tasklet_complete(struct asd_ascb *ascb, ascb->scb->header.opcode); } - /* Catch these before we mask off the sb_opcode bits */ - switch (sb_opcode) { - case REQ_TASK_ABORT: { - struct asd_ascb *a, *b; - u16 tc_abort; - - tc_abort = *((u16*)(&dl->status_block[1])); - tc_abort = le16_to_cpu(tc_abort); - - ASD_DPRINTK("%s: REQ_TASK_ABORT, reason=0x%X\n", - __FUNCTION__, dl->status_block[3]); - - /* Find the pending task and abort it. */ - list_for_each_entry_safe(a, b, &asd_ha->seq.pend_q, list) - if (a->tc_index == tc_abort) { - task_kill_later(a); - break; - } - goto out; - } - case REQ_DEVICE_RESET: { - struct Scsi_Host *shost = sas_ha->core.shost; - struct sas_phy *dev_phy; - struct asd_ascb *a; - u16 conn_handle; - - conn_handle = *((u16*)(&dl->status_block[1])); - conn_handle = le16_to_cpu(conn_handle); - - ASD_DPRINTK("%s: REQ_DEVICE_RESET, reason=0x%X\n", __FUNCTION__, - dl->status_block[3]); - - /* Kill all pending tasks and reset the device */ - dev_phy = NULL; - list_for_each_entry(a, &asd_ha->seq.pend_q, list) { - struct sas_task *task; - struct domain_device *dev; - u16 x; - - task = a->uldd_task; - if (!task) - continue; - dev = task->dev; - - x = (unsigned long)dev->lldd_dev; - if (x == conn_handle) { - dev_phy = dev->port->phy; - task_kill_later(a); - } - } - - /* Reset device port */ - if (!dev_phy) { - ASD_DPRINTK("%s: No pending commands; can't reset.\n", - __FUNCTION__); - goto out; - } - phy_reset_later(dev_phy, shost); - goto out; - } - case SIGNAL_NCQ_ERROR: - ASD_DPRINTK("%s: SIGNAL_NCQ_ERROR\n", __FUNCTION__); - goto out; - case CLEAR_NCQ_ERROR: - ASD_DPRINTK("%s: CLEAR_NCQ_ERROR\n", __FUNCTION__); - goto out; - } - sb_opcode &= ~DL_PHY_MASK; switch (sb_opcode) { @@ -572,6 +469,22 @@ static void escb_tasklet_complete(struct asd_ascb *ascb, asd_deform_port(asd_ha, phy); sas_ha->notify_port_event(sas_phy, PORTE_TIMER_EVENT); break; + case REQ_TASK_ABORT: + ASD_DPRINTK("%s: phy%d: REQ_TASK_ABORT\n", __FUNCTION__, + phy_id); + break; + case REQ_DEVICE_RESET: + ASD_DPRINTK("%s: phy%d: REQ_DEVICE_RESET\n", __FUNCTION__, + phy_id); + break; + case SIGNAL_NCQ_ERROR: + ASD_DPRINTK("%s: phy%d: SIGNAL_NCQ_ERROR\n", __FUNCTION__, + phy_id); + break; + case CLEAR_NCQ_ERROR: + ASD_DPRINTK("%s: phy%d: CLEAR_NCQ_ERROR\n", __FUNCTION__, + phy_id); + break; default: ASD_DPRINTK("%s: phy%d: unknown event:0x%x\n", __FUNCTION__, phy_id, sb_opcode); @@ -591,7 +504,7 @@ static void escb_tasklet_complete(struct asd_ascb *ascb, break; } -out: + asd_invalidate_edb(ascb, edb); } diff --git a/trunk/drivers/scsi/fd_mcs.c b/trunk/drivers/scsi/fd_mcs.c index 668569e8856b..ef8285c326e4 100644 --- a/trunk/drivers/scsi/fd_mcs.c +++ b/trunk/drivers/scsi/fd_mcs.c @@ -294,7 +294,6 @@ static struct Scsi_Host *hosts[FD_MAX_HOSTS + 1] = { NULL }; static int user_fifo_count = 0; static int user_fifo_size = 0; -#ifndef MODULE static int __init fd_mcs_setup(char *str) { static int done_setup = 0; @@ -312,7 +311,6 @@ static int __init fd_mcs_setup(char *str) } __setup("fd_mcs=", fd_mcs_setup); -#endif /* !MODULE */ static void print_banner(struct Scsi_Host *shpnt) { diff --git a/trunk/drivers/scsi/hosts.c b/trunk/drivers/scsi/hosts.c index 38c3a291efac..68ef1636678d 100644 --- a/trunk/drivers/scsi/hosts.c +++ b/trunk/drivers/scsi/hosts.c @@ -263,10 +263,6 @@ static void scsi_host_dev_release(struct device *dev) kthread_stop(shost->ehandler); if (shost->work_q) destroy_workqueue(shost->work_q); - if (shost->uspace_req_q) { - kfree(shost->uspace_req_q->queuedata); - scsi_free_queue(shost->uspace_req_q); - } scsi_destroy_command_freelist(shost); if (shost->bqt) @@ -305,8 +301,8 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) if (!shost) return NULL; - shost->host_lock = &shost->default_lock; - spin_lock_init(shost->host_lock); + spin_lock_init(&shost->default_lock); + scsi_assign_lock(shost, &shost->default_lock); shost->shost_state = SHOST_CREATED; INIT_LIST_HEAD(&shost->__devices); INIT_LIST_HEAD(&shost->__targets); diff --git a/trunk/drivers/scsi/ibmvscsi/Makefile b/trunk/drivers/scsi/ibmvscsi/Makefile index 6ac0633d5452..4e247b6b8700 100644 --- a/trunk/drivers/scsi/ibmvscsi/Makefile +++ b/trunk/drivers/scsi/ibmvscsi/Makefile @@ -3,5 +3,3 @@ obj-$(CONFIG_SCSI_IBMVSCSI) += ibmvscsic.o ibmvscsic-y += ibmvscsi.o ibmvscsic-$(CONFIG_PPC_ISERIES) += iseries_vscsi.o ibmvscsic-$(CONFIG_PPC_PSERIES) += rpa_vscsi.o - -obj-$(CONFIG_SCSI_IBMVSCSIS) += ibmvstgt.o diff --git a/trunk/drivers/scsi/ibmvscsi/ibmvstgt.c b/trunk/drivers/scsi/ibmvscsi/ibmvstgt.c deleted file mode 100644 index 0e74174a1b37..000000000000 --- a/trunk/drivers/scsi/ibmvscsi/ibmvstgt.c +++ /dev/null @@ -1,958 +0,0 @@ -/* - * IBM eServer i/pSeries Virtual SCSI Target Driver - * Copyright (C) 2003-2005 Dave Boutcher (boutcher@us.ibm.com) IBM Corp. - * Santiago Leon (santil@us.ibm.com) IBM Corp. - * Linda Xie (lxie@us.ibm.com) IBM Corp. - * - * Copyright (C) 2005-2006 FUJITA Tomonori - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ibmvscsi.h" - -#define INITIAL_SRP_LIMIT 16 -#define DEFAULT_MAX_SECTORS 512 - -#define TGT_NAME "ibmvstgt" - -/* - * Hypervisor calls. - */ -#define h_copy_rdma(l, sa, sb, da, db) \ - plpar_hcall_norets(H_COPY_RDMA, l, sa, sb, da, db) -#define h_send_crq(ua, l, h) \ - plpar_hcall_norets(H_SEND_CRQ, ua, l, h) -#define h_reg_crq(ua, tok, sz)\ - plpar_hcall_norets(H_REG_CRQ, ua, tok, sz); -#define h_free_crq(ua) \ - plpar_hcall_norets(H_FREE_CRQ, ua); - -/* tmp - will replace with SCSI logging stuff */ -#define eprintk(fmt, args...) \ -do { \ - printk("%s(%d) " fmt, __FUNCTION__, __LINE__, ##args); \ -} while (0) -/* #define dprintk eprintk */ -#define dprintk(fmt, args...) - -struct vio_port { - struct vio_dev *dma_dev; - - struct crq_queue crq_queue; - struct work_struct crq_work; - - unsigned long liobn; - unsigned long riobn; -}; - -static struct workqueue_struct *vtgtd; - -/* - * These are fixed for the system and come from the Open Firmware device tree. - * We just store them here to save getting them every time. - */ -static char system_id[64] = ""; -static char partition_name[97] = "UNKNOWN"; -static unsigned int partition_number = -1; - -static struct vio_port *target_to_port(struct srp_target *target) -{ - return (struct vio_port *) target->ldata; -} - -static inline union viosrp_iu *vio_iu(struct iu_entry *iue) -{ - return (union viosrp_iu *) (iue->sbuf->buf); -} - -static int send_iu(struct iu_entry *iue, uint64_t length, uint8_t format) -{ - struct srp_target *target = iue->target; - struct vio_port *vport = target_to_port(target); - long rc, rc1; - union { - struct viosrp_crq cooked; - uint64_t raw[2]; - } crq; - - /* First copy the SRP */ - rc = h_copy_rdma(length, vport->liobn, iue->sbuf->dma, - vport->riobn, iue->remote_token); - - if (rc) - eprintk("Error %ld transferring data\n", rc); - - crq.cooked.valid = 0x80; - crq.cooked.format = format; - crq.cooked.reserved = 0x00; - crq.cooked.timeout = 0x00; - crq.cooked.IU_length = length; - crq.cooked.IU_data_ptr = vio_iu(iue)->srp.rsp.tag; - - if (rc == 0) - crq.cooked.status = 0x99; /* Just needs to be non-zero */ - else - crq.cooked.status = 0x00; - - rc1 = h_send_crq(vport->dma_dev->unit_address, crq.raw[0], crq.raw[1]); - - if (rc1) { - eprintk("%ld sending response\n", rc1); - return rc1; - } - - return rc; -} - -#define SRP_RSP_SENSE_DATA_LEN 18 - -static int send_rsp(struct iu_entry *iue, struct scsi_cmnd *sc, - unsigned char status, unsigned char asc) -{ - union viosrp_iu *iu = vio_iu(iue); - uint64_t tag = iu->srp.rsp.tag; - - /* If the linked bit is on and status is good */ - if (test_bit(V_LINKED, &iue->flags) && (status == NO_SENSE)) - status = 0x10; - - memset(iu, 0, sizeof(struct srp_rsp)); - iu->srp.rsp.opcode = SRP_RSP; - iu->srp.rsp.req_lim_delta = 1; - iu->srp.rsp.tag = tag; - - if (test_bit(V_DIOVER, &iue->flags)) - iu->srp.rsp.flags |= SRP_RSP_FLAG_DIOVER; - - iu->srp.rsp.data_in_res_cnt = 0; - iu->srp.rsp.data_out_res_cnt = 0; - - iu->srp.rsp.flags &= ~SRP_RSP_FLAG_RSPVALID; - - iu->srp.rsp.resp_data_len = 0; - iu->srp.rsp.status = status; - if (status) { - uint8_t *sense = iu->srp.rsp.data; - - if (sc) { - iu->srp.rsp.flags |= SRP_RSP_FLAG_SNSVALID; - iu->srp.rsp.sense_data_len = SCSI_SENSE_BUFFERSIZE; - memcpy(sense, sc->sense_buffer, SCSI_SENSE_BUFFERSIZE); - } else { - iu->srp.rsp.status = SAM_STAT_CHECK_CONDITION; - iu->srp.rsp.flags |= SRP_RSP_FLAG_SNSVALID; - iu->srp.rsp.sense_data_len = SRP_RSP_SENSE_DATA_LEN; - - /* Valid bit and 'current errors' */ - sense[0] = (0x1 << 7 | 0x70); - /* Sense key */ - sense[2] = status; - /* Additional sense length */ - sense[7] = 0xa; /* 10 bytes */ - /* Additional sense code */ - sense[12] = asc; - } - } - - send_iu(iue, sizeof(iu->srp.rsp) + SRP_RSP_SENSE_DATA_LEN, - VIOSRP_SRP_FORMAT); - - return 0; -} - -static void handle_cmd_queue(struct srp_target *target) -{ - struct Scsi_Host *shost = target->shost; - struct iu_entry *iue; - struct srp_cmd *cmd; - unsigned long flags; - int err; - -retry: - spin_lock_irqsave(&target->lock, flags); - - list_for_each_entry(iue, &target->cmd_queue, ilist) { - if (!test_and_set_bit(V_FLYING, &iue->flags)) { - spin_unlock_irqrestore(&target->lock, flags); - cmd = iue->sbuf->buf; - err = srp_cmd_queue(shost, cmd, iue, 0); - if (err) { - eprintk("cannot queue cmd %p %d\n", cmd, err); - srp_iu_put(iue); - } - goto retry; - } - } - - spin_unlock_irqrestore(&target->lock, flags); -} - -static int ibmvstgt_rdma(struct scsi_cmnd *sc, struct scatterlist *sg, int nsg, - struct srp_direct_buf *md, int nmd, - enum dma_data_direction dir, unsigned int rest) -{ - struct iu_entry *iue = (struct iu_entry *) sc->SCp.ptr; - struct srp_target *target = iue->target; - struct vio_port *vport = target_to_port(target); - dma_addr_t token; - long err; - unsigned int done = 0; - int i, sidx, soff; - - sidx = soff = 0; - token = sg_dma_address(sg + sidx); - - for (i = 0; i < nmd && rest; i++) { - unsigned int mdone, mlen; - - mlen = min(rest, md[i].len); - for (mdone = 0; mlen;) { - int slen = min(sg_dma_len(sg + sidx) - soff, mlen); - - if (dir == DMA_TO_DEVICE) - err = h_copy_rdma(slen, - vport->riobn, - md[i].va + mdone, - vport->liobn, - token + soff); - else - err = h_copy_rdma(slen, - vport->liobn, - token + soff, - vport->riobn, - md[i].va + mdone); - - if (err != H_SUCCESS) { - eprintk("rdma error %d %d\n", dir, slen); - goto out; - } - - mlen -= slen; - mdone += slen; - soff += slen; - done += slen; - - if (soff == sg_dma_len(sg + sidx)) { - sidx++; - soff = 0; - token = sg_dma_address(sg + sidx); - - if (sidx > nsg) { - eprintk("out of sg %p %d %d\n", - iue, sidx, nsg); - goto out; - } - } - }; - - rest -= mlen; - } -out: - - return 0; -} - -static int ibmvstgt_transfer_data(struct scsi_cmnd *sc, - void (*done)(struct scsi_cmnd *)) -{ - struct iu_entry *iue = (struct iu_entry *) sc->SCp.ptr; - int err; - - err = srp_transfer_data(sc, &vio_iu(iue)->srp.cmd, ibmvstgt_rdma, 1, 1); - - done(sc); - - return err; -} - -static int ibmvstgt_cmd_done(struct scsi_cmnd *sc, - void (*done)(struct scsi_cmnd *)) -{ - unsigned long flags; - struct iu_entry *iue = (struct iu_entry *) sc->SCp.ptr; - struct srp_target *target = iue->target; - - dprintk("%p %p %x\n", iue, target, vio_iu(iue)->srp.cmd.cdb[0]); - - spin_lock_irqsave(&target->lock, flags); - list_del(&iue->ilist); - spin_unlock_irqrestore(&target->lock, flags); - - if (sc->result != SAM_STAT_GOOD) { - eprintk("operation failed %p %d %x\n", - iue, sc->result, vio_iu(iue)->srp.cmd.cdb[0]); - send_rsp(iue, sc, HARDWARE_ERROR, 0x00); - } else - send_rsp(iue, sc, NO_SENSE, 0x00); - - done(sc); - srp_iu_put(iue); - return 0; -} - -int send_adapter_info(struct iu_entry *iue, - dma_addr_t remote_buffer, uint16_t length) -{ - struct srp_target *target = iue->target; - struct vio_port *vport = target_to_port(target); - struct Scsi_Host *shost = target->shost; - dma_addr_t data_token; - struct mad_adapter_info_data *info; - int err; - - info = dma_alloc_coherent(target->dev, sizeof(*info), &data_token, - GFP_KERNEL); - if (!info) { - eprintk("bad dma_alloc_coherent %p\n", target); - return 1; - } - - /* Get remote info */ - err = h_copy_rdma(sizeof(*info), vport->riobn, remote_buffer, - vport->liobn, data_token); - if (err == H_SUCCESS) { - dprintk("Client connect: %s (%d)\n", - info->partition_name, info->partition_number); - } - - memset(info, 0, sizeof(*info)); - - strcpy(info->srp_version, "16.a"); - strncpy(info->partition_name, partition_name, - sizeof(info->partition_name)); - info->partition_number = partition_number; - info->mad_version = 1; - info->os_type = 2; - info->port_max_txu[0] = shost->hostt->max_sectors << 9; - - /* Send our info to remote */ - err = h_copy_rdma(sizeof(*info), vport->liobn, data_token, - vport->riobn, remote_buffer); - - dma_free_coherent(target->dev, sizeof(*info), info, data_token); - - if (err != H_SUCCESS) { - eprintk("Error sending adapter info %d\n", err); - return 1; - } - - return 0; -} - -static void process_login(struct iu_entry *iue) -{ - union viosrp_iu *iu = vio_iu(iue); - struct srp_login_rsp *rsp = &iu->srp.login_rsp; - uint64_t tag = iu->srp.rsp.tag; - - /* TODO handle case that requested size is wrong and - * buffer format is wrong - */ - memset(iu, 0, sizeof(struct srp_login_rsp)); - rsp->opcode = SRP_LOGIN_RSP; - rsp->req_lim_delta = INITIAL_SRP_LIMIT; - rsp->tag = tag; - rsp->max_it_iu_len = sizeof(union srp_iu); - rsp->max_ti_iu_len = sizeof(union srp_iu); - /* direct and indirect */ - rsp->buf_fmt = SRP_BUF_FORMAT_DIRECT | SRP_BUF_FORMAT_INDIRECT; - - send_iu(iue, sizeof(*rsp), VIOSRP_SRP_FORMAT); -} - -static inline void queue_cmd(struct iu_entry *iue) -{ - struct srp_target *target = iue->target; - unsigned long flags; - - spin_lock_irqsave(&target->lock, flags); - list_add_tail(&iue->ilist, &target->cmd_queue); - spin_unlock_irqrestore(&target->lock, flags); -} - -static int process_tsk_mgmt(struct iu_entry *iue) -{ - union viosrp_iu *iu = vio_iu(iue); - int fn; - - dprintk("%p %u\n", iue, iu->srp.tsk_mgmt.tsk_mgmt_func); - - switch (iu->srp.tsk_mgmt.tsk_mgmt_func) { - case SRP_TSK_ABORT_TASK: - fn = ABORT_TASK; - break; - case SRP_TSK_ABORT_TASK_SET: - fn = ABORT_TASK_SET; - break; - case SRP_TSK_CLEAR_TASK_SET: - fn = CLEAR_TASK_SET; - break; - case SRP_TSK_LUN_RESET: - fn = LOGICAL_UNIT_RESET; - break; - case SRP_TSK_CLEAR_ACA: - fn = CLEAR_ACA; - break; - default: - fn = 0; - } - if (fn) - scsi_tgt_tsk_mgmt_request(iue->target->shost, fn, - iu->srp.tsk_mgmt.task_tag, - (struct scsi_lun *) &iu->srp.tsk_mgmt.lun, - iue); - else - send_rsp(iue, NULL, ILLEGAL_REQUEST, 0x20); - - return !fn; -} - -static int process_mad_iu(struct iu_entry *iue) -{ - union viosrp_iu *iu = vio_iu(iue); - struct viosrp_adapter_info *info; - struct viosrp_host_config *conf; - - switch (iu->mad.empty_iu.common.type) { - case VIOSRP_EMPTY_IU_TYPE: - eprintk("%s\n", "Unsupported EMPTY MAD IU"); - break; - case VIOSRP_ERROR_LOG_TYPE: - eprintk("%s\n", "Unsupported ERROR LOG MAD IU"); - iu->mad.error_log.common.status = 1; - send_iu(iue, sizeof(iu->mad.error_log), VIOSRP_MAD_FORMAT); - break; - case VIOSRP_ADAPTER_INFO_TYPE: - info = &iu->mad.adapter_info; - info->common.status = send_adapter_info(iue, info->buffer, - info->common.length); - send_iu(iue, sizeof(*info), VIOSRP_MAD_FORMAT); - break; - case VIOSRP_HOST_CONFIG_TYPE: - conf = &iu->mad.host_config; - conf->common.status = 1; - send_iu(iue, sizeof(*conf), VIOSRP_MAD_FORMAT); - break; - default: - eprintk("Unknown type %u\n", iu->srp.rsp.opcode); - } - - return 1; -} - -static int process_srp_iu(struct iu_entry *iue) -{ - union viosrp_iu *iu = vio_iu(iue); - int done = 1; - u8 opcode = iu->srp.rsp.opcode; - - switch (opcode) { - case SRP_LOGIN_REQ: - process_login(iue); - break; - case SRP_TSK_MGMT: - done = process_tsk_mgmt(iue); - break; - case SRP_CMD: - queue_cmd(iue); - done = 0; - break; - case SRP_LOGIN_RSP: - case SRP_I_LOGOUT: - case SRP_T_LOGOUT: - case SRP_RSP: - case SRP_CRED_REQ: - case SRP_CRED_RSP: - case SRP_AER_REQ: - case SRP_AER_RSP: - eprintk("Unsupported type %u\n", opcode); - break; - default: - eprintk("Unknown type %u\n", opcode); - } - - return done; -} - -static void process_iu(struct viosrp_crq *crq, struct srp_target *target) -{ - struct vio_port *vport = target_to_port(target); - struct iu_entry *iue; - long err, done; - - iue = srp_iu_get(target); - if (!iue) { - eprintk("Error getting IU from pool, %p\n", target); - return; - } - - iue->remote_token = crq->IU_data_ptr; - - err = h_copy_rdma(crq->IU_length, vport->riobn, - iue->remote_token, vport->liobn, iue->sbuf->dma); - - if (err != H_SUCCESS) { - eprintk("%ld transferring data error %p\n", err, iue); - done = 1; - goto out; - } - - if (crq->format == VIOSRP_MAD_FORMAT) - done = process_mad_iu(iue); - else - done = process_srp_iu(iue); -out: - if (done) - srp_iu_put(iue); -} - -static irqreturn_t ibmvstgt_interrupt(int irq, void *data) -{ - struct srp_target *target = (struct srp_target *) data; - struct vio_port *vport = target_to_port(target); - - vio_disable_interrupts(vport->dma_dev); - queue_work(vtgtd, &vport->crq_work); - - return IRQ_HANDLED; -} - -static int crq_queue_create(struct crq_queue *queue, struct srp_target *target) -{ - int err; - struct vio_port *vport = target_to_port(target); - - queue->msgs = (struct viosrp_crq *) get_zeroed_page(GFP_KERNEL); - if (!queue->msgs) - goto malloc_failed; - queue->size = PAGE_SIZE / sizeof(*queue->msgs); - - queue->msg_token = dma_map_single(target->dev, queue->msgs, - queue->size * sizeof(*queue->msgs), - DMA_BIDIRECTIONAL); - - if (dma_mapping_error(queue->msg_token)) - goto map_failed; - - err = h_reg_crq(vport->dma_dev->unit_address, queue->msg_token, - PAGE_SIZE); - - /* If the adapter was left active for some reason (like kexec) - * try freeing and re-registering - */ - if (err == H_RESOURCE) { - do { - err = h_free_crq(vport->dma_dev->unit_address); - } while (err == H_BUSY || H_IS_LONG_BUSY(err)); - - err = h_reg_crq(vport->dma_dev->unit_address, queue->msg_token, - PAGE_SIZE); - } - - if (err != H_SUCCESS && err != 2) { - eprintk("Error 0x%x opening virtual adapter\n", err); - goto reg_crq_failed; - } - - err = request_irq(vport->dma_dev->irq, &ibmvstgt_interrupt, - SA_INTERRUPT, "ibmvstgt", target); - if (err) - goto req_irq_failed; - - vio_enable_interrupts(vport->dma_dev); - - h_send_crq(vport->dma_dev->unit_address, 0xC001000000000000, 0); - - queue->cur = 0; - spin_lock_init(&queue->lock); - - return 0; - -req_irq_failed: - do { - err = h_free_crq(vport->dma_dev->unit_address); - } while (err == H_BUSY || H_IS_LONG_BUSY(err)); - -reg_crq_failed: - dma_unmap_single(target->dev, queue->msg_token, - queue->size * sizeof(*queue->msgs), DMA_BIDIRECTIONAL); -map_failed: - free_page((unsigned long) queue->msgs); - -malloc_failed: - return -ENOMEM; -} - -static void crq_queue_destroy(struct srp_target *target) -{ - struct vio_port *vport = target_to_port(target); - struct crq_queue *queue = &vport->crq_queue; - int err; - - free_irq(vport->dma_dev->irq, target); - do { - err = h_free_crq(vport->dma_dev->unit_address); - } while (err == H_BUSY || H_IS_LONG_BUSY(err)); - - dma_unmap_single(target->dev, queue->msg_token, - queue->size * sizeof(*queue->msgs), DMA_BIDIRECTIONAL); - - free_page((unsigned long) queue->msgs); -} - -static void process_crq(struct viosrp_crq *crq, struct srp_target *target) -{ - struct vio_port *vport = target_to_port(target); - dprintk("%x %x\n", crq->valid, crq->format); - - switch (crq->valid) { - case 0xC0: - /* initialization */ - switch (crq->format) { - case 0x01: - h_send_crq(vport->dma_dev->unit_address, - 0xC002000000000000, 0); - break; - case 0x02: - break; - default: - eprintk("Unknown format %u\n", crq->format); - } - break; - case 0xFF: - /* transport event */ - break; - case 0x80: - /* real payload */ - switch (crq->format) { - case VIOSRP_SRP_FORMAT: - case VIOSRP_MAD_FORMAT: - process_iu(crq, target); - break; - case VIOSRP_OS400_FORMAT: - case VIOSRP_AIX_FORMAT: - case VIOSRP_LINUX_FORMAT: - case VIOSRP_INLINE_FORMAT: - eprintk("Unsupported format %u\n", crq->format); - break; - default: - eprintk("Unknown format %u\n", crq->format); - } - break; - default: - eprintk("unknown message type 0x%02x!?\n", crq->valid); - } -} - -static inline struct viosrp_crq *next_crq(struct crq_queue *queue) -{ - struct viosrp_crq *crq; - unsigned long flags; - - spin_lock_irqsave(&queue->lock, flags); - crq = &queue->msgs[queue->cur]; - if (crq->valid & 0x80) { - if (++queue->cur == queue->size) - queue->cur = 0; - } else - crq = NULL; - spin_unlock_irqrestore(&queue->lock, flags); - - return crq; -} - -static void handle_crq(void *data) -{ - struct srp_target *target = (struct srp_target *) data; - struct vio_port *vport = target_to_port(target); - struct viosrp_crq *crq; - int done = 0; - - while (!done) { - while ((crq = next_crq(&vport->crq_queue)) != NULL) { - process_crq(crq, target); - crq->valid = 0x00; - } - - vio_enable_interrupts(vport->dma_dev); - - crq = next_crq(&vport->crq_queue); - if (crq) { - vio_disable_interrupts(vport->dma_dev); - process_crq(crq, target); - crq->valid = 0x00; - } else - done = 1; - } - - handle_cmd_queue(target); -} - - -static int ibmvstgt_eh_abort_handler(struct scsi_cmnd *sc) -{ - unsigned long flags; - struct iu_entry *iue = (struct iu_entry *) sc->SCp.ptr; - struct srp_target *target = iue->target; - - dprintk("%p %p %x\n", iue, target, vio_iu(iue)->srp.cmd.cdb[0]); - - spin_lock_irqsave(&target->lock, flags); - list_del(&iue->ilist); - spin_unlock_irqrestore(&target->lock, flags); - - srp_iu_put(iue); - - return 0; -} - -static int ibmvstgt_tsk_mgmt_response(u64 mid, int result) -{ - struct iu_entry *iue = (struct iu_entry *) ((void *) mid); - union viosrp_iu *iu = vio_iu(iue); - unsigned char status, asc; - - eprintk("%p %d\n", iue, result); - status = NO_SENSE; - asc = 0; - - switch (iu->srp.tsk_mgmt.tsk_mgmt_func) { - case SRP_TSK_ABORT_TASK: - asc = 0x14; - if (result) - status = ABORTED_COMMAND; - break; - default: - break; - } - - send_rsp(iue, NULL, status, asc); - srp_iu_put(iue); - - return 0; -} - -static ssize_t system_id_show(struct class_device *cdev, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%s\n", system_id); -} - -static ssize_t partition_number_show(struct class_device *cdev, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%x\n", partition_number); -} - -static ssize_t unit_address_show(struct class_device *cdev, char *buf) -{ - struct Scsi_Host *shost = class_to_shost(cdev); - struct srp_target *target = host_to_srp_target(shost); - struct vio_port *vport = target_to_port(target); - return snprintf(buf, PAGE_SIZE, "%x\n", vport->dma_dev->unit_address); -} - -static CLASS_DEVICE_ATTR(system_id, S_IRUGO, system_id_show, NULL); -static CLASS_DEVICE_ATTR(partition_number, S_IRUGO, partition_number_show, NULL); -static CLASS_DEVICE_ATTR(unit_address, S_IRUGO, unit_address_show, NULL); - -static struct class_device_attribute *ibmvstgt_attrs[] = { - &class_device_attr_system_id, - &class_device_attr_partition_number, - &class_device_attr_unit_address, - NULL, -}; - -static struct scsi_host_template ibmvstgt_sht = { - .name = TGT_NAME, - .module = THIS_MODULE, - .can_queue = INITIAL_SRP_LIMIT, - .sg_tablesize = SG_ALL, - .use_clustering = DISABLE_CLUSTERING, - .max_sectors = DEFAULT_MAX_SECTORS, - .transfer_response = ibmvstgt_cmd_done, - .transfer_data = ibmvstgt_transfer_data, - .eh_abort_handler = ibmvstgt_eh_abort_handler, - .tsk_mgmt_response = ibmvstgt_tsk_mgmt_response, - .shost_attrs = ibmvstgt_attrs, - .proc_name = TGT_NAME, -}; - -static int ibmvstgt_probe(struct vio_dev *dev, const struct vio_device_id *id) -{ - struct Scsi_Host *shost; - struct srp_target *target; - struct vio_port *vport; - unsigned int *dma, dma_size; - int err = -ENOMEM; - - vport = kzalloc(sizeof(struct vio_port), GFP_KERNEL); - if (!vport) - return err; - shost = scsi_host_alloc(&ibmvstgt_sht, sizeof(struct srp_target)); - if (!shost) - goto free_vport; - err = scsi_tgt_alloc_queue(shost); - if (err) - goto put_host; - - target = host_to_srp_target(shost); - target->shost = shost; - vport->dma_dev = dev; - target->ldata = vport; - err = srp_target_alloc(target, &dev->dev, INITIAL_SRP_LIMIT, - SRP_MAX_IU_LEN); - if (err) - goto put_host; - - dma = (unsigned int *) vio_get_attribute(dev, "ibm,my-dma-window", - &dma_size); - if (!dma || dma_size != 40) { - eprintk("Couldn't get window property %d\n", dma_size); - err = -EIO; - goto free_srp_target; - } - vport->liobn = dma[0]; - vport->riobn = dma[5]; - - INIT_WORK(&vport->crq_work, handle_crq, target); - - err = crq_queue_create(&vport->crq_queue, target); - if (err) - goto free_srp_target; - - err = scsi_add_host(shost, target->dev); - if (err) - goto destroy_queue; - return 0; - -destroy_queue: - crq_queue_destroy(target); -free_srp_target: - srp_target_free(target); -put_host: - scsi_host_put(shost); -free_vport: - kfree(vport); - return err; -} - -static int ibmvstgt_remove(struct vio_dev *dev) -{ - struct srp_target *target = (struct srp_target *) dev->dev.driver_data; - struct Scsi_Host *shost = target->shost; - struct vio_port *vport = target->ldata; - - crq_queue_destroy(target); - scsi_remove_host(shost); - scsi_tgt_free_queue(shost); - srp_target_free(target); - kfree(vport); - scsi_host_put(shost); - return 0; -} - -static struct vio_device_id ibmvstgt_device_table[] __devinitdata = { - {"v-scsi-host", "IBM,v-scsi-host"}, - {"",""} -}; - -MODULE_DEVICE_TABLE(vio, ibmvstgt_device_table); - -static struct vio_driver ibmvstgt_driver = { - .id_table = ibmvstgt_device_table, - .probe = ibmvstgt_probe, - .remove = ibmvstgt_remove, - .driver = { - .name = "ibmvscsis", - .owner = THIS_MODULE, - } -}; - -static int get_system_info(void) -{ - struct device_node *rootdn; - const char *id, *model, *name; - unsigned int *num; - - rootdn = find_path_device("/"); - if (!rootdn) - return -ENOENT; - - model = get_property(rootdn, "model", NULL); - id = get_property(rootdn, "system-id", NULL); - if (model && id) - snprintf(system_id, sizeof(system_id), "%s-%s", model, id); - - name = get_property(rootdn, "ibm,partition-name", NULL); - if (name) - strncpy(partition_name, name, sizeof(partition_name)); - - num = (unsigned int *) get_property(rootdn, "ibm,partition-no", NULL); - if (num) - partition_number = *num; - - return 0; -} - -static int ibmvstgt_init(void) -{ - int err = -ENOMEM; - - printk("IBM eServer i/pSeries Virtual SCSI Target Driver\n"); - - vtgtd = create_workqueue("ibmvtgtd"); - if (!vtgtd) - return err; - - err = get_system_info(); - if (err) - goto destroy_wq; - - err = vio_register_driver(&ibmvstgt_driver); - if (err) - goto destroy_wq; - - return 0; - -destroy_wq: - destroy_workqueue(vtgtd); - return err; -} - -static void ibmvstgt_exit(void) -{ - printk("Unregister IBM virtual SCSI driver\n"); - - destroy_workqueue(vtgtd); - vio_unregister_driver(&ibmvstgt_driver); -} - -MODULE_DESCRIPTION("IBM Virtual SCSI Target"); -MODULE_AUTHOR("Santiago Leon"); -MODULE_LICENSE("GPL"); - -module_init(ibmvstgt_init); -module_exit(ibmvstgt_exit); diff --git a/trunk/drivers/scsi/imm.c b/trunk/drivers/scsi/imm.c index 0464c182c577..e31f6122106f 100644 --- a/trunk/drivers/scsi/imm.c +++ b/trunk/drivers/scsi/imm.c @@ -36,7 +36,7 @@ typedef struct { int base_hi; /* Hi Base address for ECP-ISA chipset */ int mode; /* Transfer mode */ struct scsi_cmnd *cur_cmd; /* Current queued command */ - struct delayed_work imm_tq; /* Polling interrupt stuff */ + struct work_struct imm_tq; /* Polling interrupt stuff */ unsigned long jstart; /* Jiffies at start */ unsigned failed:1; /* Failure flag */ unsigned dp:1; /* Data phase present */ @@ -733,9 +733,9 @@ static int imm_completion(struct scsi_cmnd *cmd) * the scheduler's task queue to generate a stream of call-backs and * complete the request when the drive is ready. */ -static void imm_interrupt(struct work_struct *work) +static void imm_interrupt(void *data) { - imm_struct *dev = container_of(work, imm_struct, imm_tq.work); + imm_struct *dev = (imm_struct *) data; struct scsi_cmnd *cmd = dev->cur_cmd; struct Scsi_Host *host = cmd->device->host; unsigned long flags; @@ -745,6 +745,7 @@ static void imm_interrupt(struct work_struct *work) return; } if (imm_engine(dev, cmd)) { + INIT_WORK(&dev->imm_tq, imm_interrupt, (void *) dev); schedule_delayed_work(&dev->imm_tq, 1); return; } @@ -952,7 +953,8 @@ static int imm_queuecommand(struct scsi_cmnd *cmd, cmd->result = DID_ERROR << 16; /* default return code */ cmd->SCp.phase = 0; /* bus free */ - schedule_delayed_work(&dev->imm_tq, 0); + INIT_WORK(&dev->imm_tq, imm_interrupt, dev); + schedule_work(&dev->imm_tq); imm_pb_claim(dev); @@ -1223,7 +1225,7 @@ static int __imm_attach(struct parport *pb) else ports = 8; - INIT_DELAYED_WORK(&dev->imm_tq, imm_interrupt); + INIT_WORK(&dev->imm_tq, imm_interrupt, dev); err = -ENOMEM; host = scsi_host_alloc(&imm_template, sizeof(imm_struct *)); diff --git a/trunk/drivers/scsi/initio.c b/trunk/drivers/scsi/initio.c index f160357e37a6..afed293dd7b9 100644 --- a/trunk/drivers/scsi/initio.c +++ b/trunk/drivers/scsi/initio.c @@ -170,7 +170,7 @@ static int setup_debug = 0; static void i91uSCBPost(BYTE * pHcb, BYTE * pScb); /* PCI Devices supported by this driver */ -static struct pci_device_id i91u_pci_devices[] = { +static struct pci_device_id i91u_pci_devices[] __devinitdata = { { PCI_VENDOR_ID_INIT, I950_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { PCI_VENDOR_ID_INIT, I940_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { PCI_VENDOR_ID_INIT, I935_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, diff --git a/trunk/drivers/scsi/ipr.c b/trunk/drivers/scsi/ipr.c index ccd4dafce8e2..2dde821025f3 100644 --- a/trunk/drivers/scsi/ipr.c +++ b/trunk/drivers/scsi/ipr.c @@ -79,6 +79,7 @@ #include #include #include +#include #include "ipr.h" /* @@ -97,7 +98,7 @@ static DEFINE_SPINLOCK(ipr_driver_lock); /* This table describes the differences between DMA controller chips */ static const struct ipr_chip_cfg_t ipr_chip_cfg[] = { - { /* Gemstone, Citrine, Obsidian, and Obsidian-E */ + { /* Gemstone, Citrine, and Obsidian */ .mailbox = 0x0042C, .cache_line_size = 0x20, { @@ -134,7 +135,6 @@ static const struct ipr_chip_t ipr_chip[] = { { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, &ipr_chip_cfg[0] }, { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN, &ipr_chip_cfg[0] }, { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, &ipr_chip_cfg[0] }, - { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, &ipr_chip_cfg[0] }, { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_SNIPE, &ipr_chip_cfg[1] }, { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, &ipr_chip_cfg[1] } }; @@ -1249,23 +1249,19 @@ static void ipr_log_array_error(struct ipr_ioa_cfg *ioa_cfg, /** * ipr_log_hex_data - Log additional hex IOA error data. - * @ioa_cfg: ioa config struct * @data: IOA error data * @len: data length * * Return value: * none **/ -static void ipr_log_hex_data(struct ipr_ioa_cfg *ioa_cfg, u32 *data, int len) +static void ipr_log_hex_data(u32 *data, int len) { int i; if (len == 0) return; - if (ioa_cfg->log_level <= IPR_DEFAULT_LOG_LEVEL) - len = min_t(int, len, IPR_DEFAULT_MAX_ERROR_DUMP); - for (i = 0; i < len / 4; i += 4) { ipr_err("%08X: %08X %08X %08X %08X\n", i*4, be32_to_cpu(data[i]), @@ -1294,7 +1290,7 @@ static void ipr_log_enhanced_dual_ioa_error(struct ipr_ioa_cfg *ioa_cfg, ipr_err("%s\n", error->failure_reason); ipr_err("Remote Adapter VPD:\n"); ipr_log_ext_vpd(&error->vpd); - ipr_log_hex_data(ioa_cfg, error->data, + ipr_log_hex_data(error->data, be32_to_cpu(hostrcb->hcam.length) - (offsetof(struct ipr_hostrcb_error, u) + offsetof(struct ipr_hostrcb_type_17_error, data))); @@ -1319,225 +1315,12 @@ static void ipr_log_dual_ioa_error(struct ipr_ioa_cfg *ioa_cfg, ipr_err("%s\n", error->failure_reason); ipr_err("Remote Adapter VPD:\n"); ipr_log_vpd(&error->vpd); - ipr_log_hex_data(ioa_cfg, error->data, + ipr_log_hex_data(error->data, be32_to_cpu(hostrcb->hcam.length) - (offsetof(struct ipr_hostrcb_error, u) + offsetof(struct ipr_hostrcb_type_07_error, data))); } -static const struct { - u8 active; - char *desc; -} path_active_desc[] = { - { IPR_PATH_NO_INFO, "Path" }, - { IPR_PATH_ACTIVE, "Active path" }, - { IPR_PATH_NOT_ACTIVE, "Inactive path" } -}; - -static const struct { - u8 state; - char *desc; -} path_state_desc[] = { - { IPR_PATH_STATE_NO_INFO, "has no path state information available" }, - { IPR_PATH_HEALTHY, "is healthy" }, - { IPR_PATH_DEGRADED, "is degraded" }, - { IPR_PATH_FAILED, "is failed" } -}; - -/** - * ipr_log_fabric_path - Log a fabric path error - * @hostrcb: hostrcb struct - * @fabric: fabric descriptor - * - * Return value: - * none - **/ -static void ipr_log_fabric_path(struct ipr_hostrcb *hostrcb, - struct ipr_hostrcb_fabric_desc *fabric) -{ - int i, j; - u8 path_state = fabric->path_state; - u8 active = path_state & IPR_PATH_ACTIVE_MASK; - u8 state = path_state & IPR_PATH_STATE_MASK; - - for (i = 0; i < ARRAY_SIZE(path_active_desc); i++) { - if (path_active_desc[i].active != active) - continue; - - for (j = 0; j < ARRAY_SIZE(path_state_desc); j++) { - if (path_state_desc[j].state != state) - continue; - - if (fabric->cascaded_expander == 0xff && fabric->phy == 0xff) { - ipr_hcam_err(hostrcb, "%s %s: IOA Port=%d\n", - path_active_desc[i].desc, path_state_desc[j].desc, - fabric->ioa_port); - } else if (fabric->cascaded_expander == 0xff) { - ipr_hcam_err(hostrcb, "%s %s: IOA Port=%d, Phy=%d\n", - path_active_desc[i].desc, path_state_desc[j].desc, - fabric->ioa_port, fabric->phy); - } else if (fabric->phy == 0xff) { - ipr_hcam_err(hostrcb, "%s %s: IOA Port=%d, Cascade=%d\n", - path_active_desc[i].desc, path_state_desc[j].desc, - fabric->ioa_port, fabric->cascaded_expander); - } else { - ipr_hcam_err(hostrcb, "%s %s: IOA Port=%d, Cascade=%d, Phy=%d\n", - path_active_desc[i].desc, path_state_desc[j].desc, - fabric->ioa_port, fabric->cascaded_expander, fabric->phy); - } - return; - } - } - - ipr_err("Path state=%02X IOA Port=%d Cascade=%d Phy=%d\n", path_state, - fabric->ioa_port, fabric->cascaded_expander, fabric->phy); -} - -static const struct { - u8 type; - char *desc; -} path_type_desc[] = { - { IPR_PATH_CFG_IOA_PORT, "IOA port" }, - { IPR_PATH_CFG_EXP_PORT, "Expander port" }, - { IPR_PATH_CFG_DEVICE_PORT, "Device port" }, - { IPR_PATH_CFG_DEVICE_LUN, "Device LUN" } -}; - -static const struct { - u8 status; - char *desc; -} path_status_desc[] = { - { IPR_PATH_CFG_NO_PROB, "Functional" }, - { IPR_PATH_CFG_DEGRADED, "Degraded" }, - { IPR_PATH_CFG_FAILED, "Failed" }, - { IPR_PATH_CFG_SUSPECT, "Suspect" }, - { IPR_PATH_NOT_DETECTED, "Missing" }, - { IPR_PATH_INCORRECT_CONN, "Incorrectly connected" } -}; - -static const char *link_rate[] = { - "unknown", - "disabled", - "phy reset problem", - "spinup hold", - "port selector", - "unknown", - "unknown", - "unknown", - "1.5Gbps", - "3.0Gbps", - "unknown", - "unknown", - "unknown", - "unknown", - "unknown", - "unknown" -}; - -/** - * ipr_log_path_elem - Log a fabric path element. - * @hostrcb: hostrcb struct - * @cfg: fabric path element struct - * - * Return value: - * none - **/ -static void ipr_log_path_elem(struct ipr_hostrcb *hostrcb, - struct ipr_hostrcb_config_element *cfg) -{ - int i, j; - u8 type = cfg->type_status & IPR_PATH_CFG_TYPE_MASK; - u8 status = cfg->type_status & IPR_PATH_CFG_STATUS_MASK; - - if (type == IPR_PATH_CFG_NOT_EXIST) - return; - - for (i = 0; i < ARRAY_SIZE(path_type_desc); i++) { - if (path_type_desc[i].type != type) - continue; - - for (j = 0; j < ARRAY_SIZE(path_status_desc); j++) { - if (path_status_desc[j].status != status) - continue; - - if (type == IPR_PATH_CFG_IOA_PORT) { - ipr_hcam_err(hostrcb, "%s %s: Phy=%d, Link rate=%s, WWN=%08X%08X\n", - path_status_desc[j].desc, path_type_desc[i].desc, - cfg->phy, link_rate[cfg->link_rate & IPR_PHY_LINK_RATE_MASK], - be32_to_cpu(cfg->wwid[0]), be32_to_cpu(cfg->wwid[1])); - } else { - if (cfg->cascaded_expander == 0xff && cfg->phy == 0xff) { - ipr_hcam_err(hostrcb, "%s %s: Link rate=%s, WWN=%08X%08X\n", - path_status_desc[j].desc, path_type_desc[i].desc, - link_rate[cfg->link_rate & IPR_PHY_LINK_RATE_MASK], - be32_to_cpu(cfg->wwid[0]), be32_to_cpu(cfg->wwid[1])); - } else if (cfg->cascaded_expander == 0xff) { - ipr_hcam_err(hostrcb, "%s %s: Phy=%d, Link rate=%s, " - "WWN=%08X%08X\n", path_status_desc[j].desc, - path_type_desc[i].desc, cfg->phy, - link_rate[cfg->link_rate & IPR_PHY_LINK_RATE_MASK], - be32_to_cpu(cfg->wwid[0]), be32_to_cpu(cfg->wwid[1])); - } else if (cfg->phy == 0xff) { - ipr_hcam_err(hostrcb, "%s %s: Cascade=%d, Link rate=%s, " - "WWN=%08X%08X\n", path_status_desc[j].desc, - path_type_desc[i].desc, cfg->cascaded_expander, - link_rate[cfg->link_rate & IPR_PHY_LINK_RATE_MASK], - be32_to_cpu(cfg->wwid[0]), be32_to_cpu(cfg->wwid[1])); - } else { - ipr_hcam_err(hostrcb, "%s %s: Cascade=%d, Phy=%d, Link rate=%s " - "WWN=%08X%08X\n", path_status_desc[j].desc, - path_type_desc[i].desc, cfg->cascaded_expander, cfg->phy, - link_rate[cfg->link_rate & IPR_PHY_LINK_RATE_MASK], - be32_to_cpu(cfg->wwid[0]), be32_to_cpu(cfg->wwid[1])); - } - } - return; - } - } - - ipr_hcam_err(hostrcb, "Path element=%02X: Cascade=%d Phy=%d Link rate=%s " - "WWN=%08X%08X\n", cfg->type_status, cfg->cascaded_expander, cfg->phy, - link_rate[cfg->link_rate & IPR_PHY_LINK_RATE_MASK], - be32_to_cpu(cfg->wwid[0]), be32_to_cpu(cfg->wwid[1])); -} - -/** - * ipr_log_fabric_error - Log a fabric error. - * @ioa_cfg: ioa config struct - * @hostrcb: hostrcb struct - * - * Return value: - * none - **/ -static void ipr_log_fabric_error(struct ipr_ioa_cfg *ioa_cfg, - struct ipr_hostrcb *hostrcb) -{ - struct ipr_hostrcb_type_20_error *error; - struct ipr_hostrcb_fabric_desc *fabric; - struct ipr_hostrcb_config_element *cfg; - int i, add_len; - - error = &hostrcb->hcam.u.error.u.type_20_error; - error->failure_reason[sizeof(error->failure_reason) - 1] = '\0'; - ipr_hcam_err(hostrcb, "%s\n", error->failure_reason); - - add_len = be32_to_cpu(hostrcb->hcam.length) - - (offsetof(struct ipr_hostrcb_error, u) + - offsetof(struct ipr_hostrcb_type_20_error, desc)); - - for (i = 0, fabric = error->desc; i < error->num_entries; i++) { - ipr_log_fabric_path(hostrcb, fabric); - for_each_fabric_cfg(fabric, cfg) - ipr_log_path_elem(hostrcb, cfg); - - add_len -= be16_to_cpu(fabric->length); - fabric = (struct ipr_hostrcb_fabric_desc *) - ((unsigned long)fabric + be16_to_cpu(fabric->length)); - } - - ipr_log_hex_data(ioa_cfg, (u32 *)fabric, add_len); -} - /** * ipr_log_generic_error - Log an adapter error. * @ioa_cfg: ioa config struct @@ -1549,7 +1332,7 @@ static void ipr_log_fabric_error(struct ipr_ioa_cfg *ioa_cfg, static void ipr_log_generic_error(struct ipr_ioa_cfg *ioa_cfg, struct ipr_hostrcb *hostrcb) { - ipr_log_hex_data(ioa_cfg, hostrcb->hcam.u.raw.data, + ipr_log_hex_data(hostrcb->hcam.u.raw.data, be32_to_cpu(hostrcb->hcam.length)); } @@ -1611,7 +1394,13 @@ static void ipr_handle_log_data(struct ipr_ioa_cfg *ioa_cfg, if (!ipr_error_table[error_index].log_hcam) return; - ipr_hcam_err(hostrcb, "%s\n", ipr_error_table[error_index].error); + if (ipr_is_device(&hostrcb->hcam.u.error.failing_dev_res_addr)) { + ipr_ra_err(ioa_cfg, hostrcb->hcam.u.error.failing_dev_res_addr, + "%s\n", ipr_error_table[error_index].error); + } else { + dev_err(&ioa_cfg->pdev->dev, "%s\n", + ipr_error_table[error_index].error); + } /* Set indication we have logged an error */ ioa_cfg->errors_logged++; @@ -1648,9 +1437,6 @@ static void ipr_handle_log_data(struct ipr_ioa_cfg *ioa_cfg, case IPR_HOST_RCB_OVERLAY_ID_17: ipr_log_enhanced_dual_ioa_error(ioa_cfg, hostrcb); break; - case IPR_HOST_RCB_OVERLAY_ID_20: - ipr_log_fabric_error(ioa_cfg, hostrcb); - break; case IPR_HOST_RCB_OVERLAY_ID_1: case IPR_HOST_RCB_OVERLAY_ID_DEFAULT: default: @@ -2307,7 +2093,7 @@ static void ipr_release_dump(struct kref *kref) /** * ipr_worker_thread - Worker thread - * @work: ioa config struct + * @data: ioa config struct * * Called at task level from a work thread. This function takes care * of adding and removing device from the mid-layer as configuration @@ -2316,14 +2102,13 @@ static void ipr_release_dump(struct kref *kref) * Return value: * nothing **/ -static void ipr_worker_thread(struct work_struct *work) +static void ipr_worker_thread(void *data) { unsigned long lock_flags; struct ipr_resource_entry *res; struct scsi_device *sdev; struct ipr_dump *dump; - struct ipr_ioa_cfg *ioa_cfg = - container_of(work, struct ipr_ioa_cfg, work_q); + struct ipr_ioa_cfg *ioa_cfg = data; u8 bus, target, lun; int did_work; @@ -3184,6 +2969,7 @@ static int ipr_alloc_dump(struct ipr_ioa_cfg *ioa_cfg) struct ipr_dump *dump; unsigned long lock_flags = 0; + ENTER; dump = kzalloc(sizeof(struct ipr_dump), GFP_KERNEL); if (!dump) { @@ -3210,6 +2996,7 @@ static int ipr_alloc_dump(struct ipr_ioa_cfg *ioa_cfg) } spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + LEAVE; return 0; } @@ -3786,12 +3573,6 @@ static int ipr_sata_reset(struct ata_port *ap, unsigned int *classes) ENTER; spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); - while(ioa_cfg->in_reset_reload) { - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); - wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload); - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); - } - res = sata_port->res; if (res) { rc = ipr_device_reset(ioa_cfg, res); @@ -3855,10 +3636,6 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd * scsi_cmd) if (ipr_cmd->ioarcb.res_handle == res->cfgte.res_handle) { if (ipr_cmd->scsi_cmd) ipr_cmd->done = ipr_scsi_eh_done; - if (ipr_cmd->qc && !(ipr_cmd->qc->flags & ATA_QCFLAG_FAILED)) { - ipr_cmd->qc->err_mask |= AC_ERR_TIMEOUT; - ipr_cmd->qc->flags |= ATA_QCFLAG_FAILED; - } } } @@ -3993,7 +3770,7 @@ static int ipr_cancel_op(struct scsi_cmnd * scsi_cmd) */ if (ioa_cfg->in_reset_reload || ioa_cfg->ioa_is_dead) return FAILED; - if (!res || !ipr_is_gscsi(res)) + if (!res || (!ipr_is_gscsi(res) && !ipr_is_vset_device(res))) return FAILED; list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) { @@ -4838,7 +4615,7 @@ static int ipr_queuecommand(struct scsi_cmnd *scsi_cmd, * Return value: * 0 on success / other on failure **/ -static int ipr_ioctl(struct scsi_device *sdev, int cmd, void __user *arg) +int ipr_ioctl(struct scsi_device *sdev, int cmd, void __user *arg) { struct ipr_resource_entry *res; @@ -4871,6 +4648,40 @@ static const char * ipr_ioa_info(struct Scsi_Host *host) return buffer; } +/** + * ipr_scsi_timed_out - Handle scsi command timeout + * @scsi_cmd: scsi command struct + * + * Return value: + * EH_NOT_HANDLED + **/ +enum scsi_eh_timer_return ipr_scsi_timed_out(struct scsi_cmnd *scsi_cmd) +{ + struct ipr_ioa_cfg *ioa_cfg; + struct ipr_cmnd *ipr_cmd; + unsigned long flags; + + ENTER; + spin_lock_irqsave(scsi_cmd->device->host->host_lock, flags); + ioa_cfg = (struct ipr_ioa_cfg *)scsi_cmd->device->host->hostdata; + + list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) { + if (ipr_cmd->qc && ipr_cmd->qc->scsicmd == scsi_cmd) { + ipr_cmd->qc->err_mask |= AC_ERR_TIMEOUT; + ipr_cmd->qc->flags |= ATA_QCFLAG_FAILED; + break; + } + } + + spin_unlock_irqrestore(scsi_cmd->device->host->host_lock, flags); + LEAVE; + return EH_NOT_HANDLED; +} + +static struct scsi_transport_template ipr_transport_template = { + .eh_timed_out = ipr_scsi_timed_out +}; + static struct scsi_host_template driver_template = { .module = THIS_MODULE, .name = "IPR", @@ -4965,12 +4776,6 @@ static void ipr_ata_post_internal(struct ata_queued_cmd *qc) unsigned long flags; spin_lock_irqsave(ioa_cfg->host->host_lock, flags); - while(ioa_cfg->in_reset_reload) { - spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags); - wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload); - spin_lock_irqsave(ioa_cfg->host->host_lock, flags); - } - list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) { if (ipr_cmd->qc == qc) { ipr_device_reset(ioa_cfg, sata_port->res); @@ -7027,7 +6832,6 @@ static int __devinit ipr_alloc_mem(struct ipr_ioa_cfg *ioa_cfg) ioa_cfg->hostrcb[i]->hostrcb_dma = ioa_cfg->hostrcb_dma[i] + offsetof(struct ipr_hostrcb, hcam); - ioa_cfg->hostrcb[i]->ioa_cfg = ioa_cfg; list_add_tail(&ioa_cfg->hostrcb[i]->queue, &ioa_cfg->hostrcb_free_q); } @@ -7122,7 +6926,7 @@ static void __devinit ipr_init_ioa_cfg(struct ipr_ioa_cfg *ioa_cfg, INIT_LIST_HEAD(&ioa_cfg->hostrcb_pending_q); INIT_LIST_HEAD(&ioa_cfg->free_res_q); INIT_LIST_HEAD(&ioa_cfg->used_res_q); - INIT_WORK(&ioa_cfg->work_q, ipr_worker_thread); + INIT_WORK(&ioa_cfg->work_q, ipr_worker_thread, ioa_cfg); init_waitqueue_head(&ioa_cfg->reset_wait_q); ioa_cfg->sdt_state = INACTIVE; if (ipr_enable_cache) @@ -7213,6 +7017,7 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev, ioa_cfg = (struct ipr_ioa_cfg *)host->hostdata; memset(ioa_cfg, 0, sizeof(struct ipr_ioa_cfg)); + host->transportt = &ipr_transport_template; ata_host_init(&ioa_cfg->ata_host, &pdev->dev, sata_port_info.flags, &ipr_sata_ops); @@ -7546,24 +7351,12 @@ static struct pci_device_id ipr_pci_table[] __devinitdata = { { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN, PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572B, 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] }, - { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN, - PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575C, - 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] }, { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572A, 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] }, { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572B, 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] }, - { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, - PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575C, - 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] }, - { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, - PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B8, - 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] }, - { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, - PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B7, - 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] }, { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_SNIPE, PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_2780, 0, 0, (kernel_ulong_t)&ipr_chip_cfg[1] }, @@ -7573,9 +7366,6 @@ static struct pci_device_id ipr_pci_table[] __devinitdata = { { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_571F, 0, 0, (kernel_ulong_t)&ipr_chip_cfg[1] }, - { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, - PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572F, - 0, 0, (kernel_ulong_t)&ipr_chip_cfg[1] }, { } }; MODULE_DEVICE_TABLE(pci, ipr_pci_table); diff --git a/trunk/drivers/scsi/ipr.h b/trunk/drivers/scsi/ipr.h index 9f62a1d4d511..6d035283af08 100644 --- a/trunk/drivers/scsi/ipr.h +++ b/trunk/drivers/scsi/ipr.h @@ -37,8 +37,8 @@ /* * Literals */ -#define IPR_DRIVER_VERSION "2.3.0" -#define IPR_DRIVER_DATE "(November 8, 2006)" +#define IPR_DRIVER_VERSION "2.2.0" +#define IPR_DRIVER_DATE "(September 25, 2006)" /* * IPR_MAX_CMD_PER_LUN: This defines the maximum number of outstanding @@ -54,8 +54,6 @@ */ #define IPR_NUM_BASE_CMD_BLKS 100 -#define PCI_DEVICE_ID_IBM_OBSIDIAN_E 0x0339 - #define IPR_SUBS_DEV_ID_2780 0x0264 #define IPR_SUBS_DEV_ID_5702 0x0266 #define IPR_SUBS_DEV_ID_5703 0x0278 @@ -68,11 +66,7 @@ #define IPR_SUBS_DEV_ID_571F 0x02D5 #define IPR_SUBS_DEV_ID_572A 0x02C1 #define IPR_SUBS_DEV_ID_572B 0x02C2 -#define IPR_SUBS_DEV_ID_572F 0x02C3 #define IPR_SUBS_DEV_ID_575B 0x030D -#define IPR_SUBS_DEV_ID_575C 0x0338 -#define IPR_SUBS_DEV_ID_57B7 0x0360 -#define IPR_SUBS_DEV_ID_57B8 0x02C2 #define IPR_NAME "ipr" @@ -104,7 +98,6 @@ #define IPR_IOASC_IOA_WAS_RESET 0x10000001 #define IPR_IOASC_PCI_ACCESS_ERROR 0x10000002 -#define IPR_DEFAULT_MAX_ERROR_DUMP 984 #define IPR_NUM_LOG_HCAMS 2 #define IPR_NUM_CFG_CHG_HCAMS 2 #define IPR_NUM_HCAMS (IPR_NUM_LOG_HCAMS + IPR_NUM_CFG_CHG_HCAMS) @@ -738,64 +731,6 @@ struct ipr_hostrcb_type_17_error { u32 data[476]; }__attribute__((packed, aligned (4))); -struct ipr_hostrcb_config_element { - u8 type_status; -#define IPR_PATH_CFG_TYPE_MASK 0xF0 -#define IPR_PATH_CFG_NOT_EXIST 0x00 -#define IPR_PATH_CFG_IOA_PORT 0x10 -#define IPR_PATH_CFG_EXP_PORT 0x20 -#define IPR_PATH_CFG_DEVICE_PORT 0x30 -#define IPR_PATH_CFG_DEVICE_LUN 0x40 - -#define IPR_PATH_CFG_STATUS_MASK 0x0F -#define IPR_PATH_CFG_NO_PROB 0x00 -#define IPR_PATH_CFG_DEGRADED 0x01 -#define IPR_PATH_CFG_FAILED 0x02 -#define IPR_PATH_CFG_SUSPECT 0x03 -#define IPR_PATH_NOT_DETECTED 0x04 -#define IPR_PATH_INCORRECT_CONN 0x05 - - u8 cascaded_expander; - u8 phy; - u8 link_rate; -#define IPR_PHY_LINK_RATE_MASK 0x0F - - __be32 wwid[2]; -}__attribute__((packed, aligned (4))); - -struct ipr_hostrcb_fabric_desc { - __be16 length; - u8 ioa_port; - u8 cascaded_expander; - u8 phy; - u8 path_state; -#define IPR_PATH_ACTIVE_MASK 0xC0 -#define IPR_PATH_NO_INFO 0x00 -#define IPR_PATH_ACTIVE 0x40 -#define IPR_PATH_NOT_ACTIVE 0x80 - -#define IPR_PATH_STATE_MASK 0x0F -#define IPR_PATH_STATE_NO_INFO 0x00 -#define IPR_PATH_HEALTHY 0x01 -#define IPR_PATH_DEGRADED 0x02 -#define IPR_PATH_FAILED 0x03 - - __be16 num_entries; - struct ipr_hostrcb_config_element elem[1]; -}__attribute__((packed, aligned (4))); - -#define for_each_fabric_cfg(fabric, cfg) \ - for (cfg = (fabric)->elem; \ - cfg < ((fabric)->elem + be16_to_cpu((fabric)->num_entries)); \ - cfg++) - -struct ipr_hostrcb_type_20_error { - u8 failure_reason[64]; - u8 reserved[3]; - u8 num_entries; - struct ipr_hostrcb_fabric_desc desc[1]; -}__attribute__((packed, aligned (4))); - struct ipr_hostrcb_error { __be32 failing_dev_ioasc; struct ipr_res_addr failing_dev_res_addr; @@ -812,7 +747,6 @@ struct ipr_hostrcb_error { struct ipr_hostrcb_type_13_error type_13_error; struct ipr_hostrcb_type_14_error type_14_error; struct ipr_hostrcb_type_17_error type_17_error; - struct ipr_hostrcb_type_20_error type_20_error; } u; }__attribute__((packed, aligned (4))); @@ -852,7 +786,6 @@ struct ipr_hcam { #define IPR_HOST_RCB_OVERLAY_ID_14 0x14 #define IPR_HOST_RCB_OVERLAY_ID_16 0x16 #define IPR_HOST_RCB_OVERLAY_ID_17 0x17 -#define IPR_HOST_RCB_OVERLAY_ID_20 0x20 #define IPR_HOST_RCB_OVERLAY_ID_DEFAULT 0xFF u8 reserved1[3]; @@ -872,7 +805,6 @@ struct ipr_hostrcb { struct ipr_hcam hcam; dma_addr_t hostrcb_dma; struct list_head queue; - struct ipr_ioa_cfg *ioa_cfg; }; /* IPR smart dump table structures */ @@ -1351,17 +1283,6 @@ struct ipr_ucode_image_header { } \ } -#define ipr_hcam_err(hostrcb, fmt, ...) \ -{ \ - if (ipr_is_device(&(hostrcb)->hcam.u.error.failing_dev_res_addr)) { \ - ipr_ra_err((hostrcb)->ioa_cfg, \ - (hostrcb)->hcam.u.error.failing_dev_res_addr, \ - fmt, ##__VA_ARGS__); \ - } else { \ - dev_err(&(hostrcb)->ioa_cfg->pdev->dev, fmt, ##__VA_ARGS__); \ - } \ -} - #define ipr_trace ipr_dbg("%s: %s: Line: %d\n",\ __FILE__, __FUNCTION__, __LINE__) diff --git a/trunk/drivers/scsi/ips.c b/trunk/drivers/scsi/ips.c index 8b704f73055a..f06a06ae6092 100644 --- a/trunk/drivers/scsi/ips.c +++ b/trunk/drivers/scsi/ips.c @@ -5001,7 +5001,7 @@ ips_init_copperhead(ips_ha_t * ha) break; /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); + msleep(IPS_ONE_SEC); } if (j >= 45) @@ -5027,7 +5027,7 @@ ips_init_copperhead(ips_ha_t * ha) break; /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); + msleep(IPS_ONE_SEC); } if (j >= 240) @@ -5045,7 +5045,7 @@ ips_init_copperhead(ips_ha_t * ha) break; /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); + msleep(IPS_ONE_SEC); } if (i >= 240) @@ -5095,7 +5095,7 @@ ips_init_copperhead_memio(ips_ha_t * ha) break; /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); + msleep(IPS_ONE_SEC); } if (j >= 45) @@ -5121,7 +5121,7 @@ ips_init_copperhead_memio(ips_ha_t * ha) break; /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); + msleep(IPS_ONE_SEC); } if (j >= 240) @@ -5139,7 +5139,7 @@ ips_init_copperhead_memio(ips_ha_t * ha) break; /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); + msleep(IPS_ONE_SEC); } if (i >= 240) @@ -5191,7 +5191,7 @@ ips_init_morpheus(ips_ha_t * ha) break; /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); + msleep(IPS_ONE_SEC); } if (i >= 45) { @@ -5217,7 +5217,7 @@ ips_init_morpheus(ips_ha_t * ha) if (Post != 0x4F00) break; /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); + msleep(IPS_ONE_SEC); } if (i >= 120) { @@ -5247,7 +5247,7 @@ ips_init_morpheus(ips_ha_t * ha) break; /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); + msleep(IPS_ONE_SEC); } if (i >= 240) { @@ -5307,12 +5307,12 @@ ips_reset_copperhead(ips_ha_t * ha) outb(IPS_BIT_RST, ha->io_addr + IPS_REG_SCPR); /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); + msleep(IPS_ONE_SEC); outb(0, ha->io_addr + IPS_REG_SCPR); /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); + msleep(IPS_ONE_SEC); if ((*ha->func.init) (ha)) break; @@ -5352,12 +5352,12 @@ ips_reset_copperhead_memio(ips_ha_t * ha) writeb(IPS_BIT_RST, ha->mem_ptr + IPS_REG_SCPR); /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); + msleep(IPS_ONE_SEC); writeb(0, ha->mem_ptr + IPS_REG_SCPR); /* Delay for 1 Second */ - MDELAY(IPS_ONE_SEC); + msleep(IPS_ONE_SEC); if ((*ha->func.init) (ha)) break; @@ -5398,7 +5398,7 @@ ips_reset_morpheus(ips_ha_t * ha) writel(0x80000000, ha->mem_ptr + IPS_REG_I960_IDR); /* Delay for 5 Seconds */ - MDELAY(5 * IPS_ONE_SEC); + msleep(5 * IPS_ONE_SEC); /* Do a PCI config read to wait for adapter */ pci_read_config_byte(ha->pcidev, 4, &junk); diff --git a/trunk/drivers/scsi/ips.h b/trunk/drivers/scsi/ips.h index b726dcc424b1..34680f3dd452 100644 --- a/trunk/drivers/scsi/ips.h +++ b/trunk/drivers/scsi/ips.h @@ -51,7 +51,6 @@ #define _IPS_H_ #include -#include #include #include @@ -117,11 +116,9 @@ dev_printk(level , &((pcidev)->dev) , format , ## arg) #endif - #define MDELAY(n) \ - do { \ - mdelay(n); \ - touch_nmi_watchdog(); \ - } while (0) + #ifndef MDELAY + #define MDELAY mdelay + #endif #ifndef min #define min(x,y) ((x) < (y) ? x : y) diff --git a/trunk/drivers/scsi/libiscsi.c b/trunk/drivers/scsi/libiscsi.c index e11b23c641e2..5d8862189485 100644 --- a/trunk/drivers/scsi/libiscsi.c +++ b/trunk/drivers/scsi/libiscsi.c @@ -719,10 +719,9 @@ static int iscsi_data_xmit(struct iscsi_conn *conn) return rc; } -static void iscsi_xmitworker(struct work_struct *work) +static void iscsi_xmitworker(void *data) { - struct iscsi_conn *conn = - container_of(work, struct iscsi_conn, xmitwork); + struct iscsi_conn *conn = data; int rc; /* * serialize Xmit worker on a per-connection basis. @@ -1513,7 +1512,7 @@ iscsi_conn_setup(struct iscsi_cls_session *cls_session, uint32_t conn_idx) if (conn->mgmtqueue == ERR_PTR(-ENOMEM)) goto mgmtqueue_alloc_fail; - INIT_WORK(&conn->xmitwork, iscsi_xmitworker); + INIT_WORK(&conn->xmitwork, iscsi_xmitworker, conn); /* allocate login_mtask used for the login/text sequences */ spin_lock_bh(&session->lock); diff --git a/trunk/drivers/scsi/libsas/sas_discover.c b/trunk/drivers/scsi/libsas/sas_discover.c index fb7df7b75811..d977bd492d8d 100644 --- a/trunk/drivers/scsi/libsas/sas_discover.c +++ b/trunk/drivers/scsi/libsas/sas_discover.c @@ -647,12 +647,10 @@ void sas_unregister_domain_devices(struct asd_sas_port *port) * Discover process only interrogates devices in order to discover the * domain. */ -static void sas_discover_domain(struct work_struct *work) +static void sas_discover_domain(void *data) { int error = 0; - struct sas_discovery_event *ev = - container_of(work, struct sas_discovery_event, work); - struct asd_sas_port *port = ev->port; + struct asd_sas_port *port = data; sas_begin_event(DISCE_DISCOVER_DOMAIN, &port->disc.disc_event_lock, &port->disc.pending); @@ -694,12 +692,10 @@ static void sas_discover_domain(struct work_struct *work) current->pid, error); } -static void sas_revalidate_domain(struct work_struct *work) +static void sas_revalidate_domain(void *data) { int res = 0; - struct sas_discovery_event *ev = - container_of(work, struct sas_discovery_event, work); - struct asd_sas_port *port = ev->port; + struct asd_sas_port *port = data; sas_begin_event(DISCE_REVALIDATE_DOMAIN, &port->disc.disc_event_lock, &port->disc.pending); @@ -726,7 +722,7 @@ int sas_discover_event(struct asd_sas_port *port, enum discover_event ev) BUG_ON(ev >= DISC_NUM_EVENTS); sas_queue_event(ev, &disc->disc_event_lock, &disc->pending, - &disc->disc_work[ev].work, port->ha->core.shost); + &disc->disc_work[ev], port->ha->core.shost); return 0; } @@ -741,15 +737,13 @@ void sas_init_disc(struct sas_discovery *disc, struct asd_sas_port *port) { int i; - static const work_func_t sas_event_fns[DISC_NUM_EVENTS] = { + static void (*sas_event_fns[DISC_NUM_EVENTS])(void *) = { [DISCE_DISCOVER_DOMAIN] = sas_discover_domain, [DISCE_REVALIDATE_DOMAIN] = sas_revalidate_domain, }; spin_lock_init(&disc->disc_event_lock); disc->pending = 0; - for (i = 0; i < DISC_NUM_EVENTS; i++) { - INIT_WORK(&disc->disc_work[i].work, sas_event_fns[i]); - disc->disc_work[i].port = port; - } + for (i = 0; i < DISC_NUM_EVENTS; i++) + INIT_WORK(&disc->disc_work[i], sas_event_fns[i], port); } diff --git a/trunk/drivers/scsi/libsas/sas_event.c b/trunk/drivers/scsi/libsas/sas_event.c index d83392ee6823..19110ed1c89c 100644 --- a/trunk/drivers/scsi/libsas/sas_event.c +++ b/trunk/drivers/scsi/libsas/sas_event.c @@ -31,7 +31,7 @@ static void notify_ha_event(struct sas_ha_struct *sas_ha, enum ha_event event) BUG_ON(event >= HA_NUM_EVENTS); sas_queue_event(event, &sas_ha->event_lock, &sas_ha->pending, - &sas_ha->ha_events[event].work, sas_ha->core.shost); + &sas_ha->ha_events[event], sas_ha->core.shost); } static void notify_port_event(struct asd_sas_phy *phy, enum port_event event) @@ -41,7 +41,7 @@ static void notify_port_event(struct asd_sas_phy *phy, enum port_event event) BUG_ON(event >= PORT_NUM_EVENTS); sas_queue_event(event, &ha->event_lock, &phy->port_events_pending, - &phy->port_events[event].work, ha->core.shost); + &phy->port_events[event], ha->core.shost); } static void notify_phy_event(struct asd_sas_phy *phy, enum phy_event event) @@ -51,12 +51,12 @@ static void notify_phy_event(struct asd_sas_phy *phy, enum phy_event event) BUG_ON(event >= PHY_NUM_EVENTS); sas_queue_event(event, &ha->event_lock, &phy->phy_events_pending, - &phy->phy_events[event].work, ha->core.shost); + &phy->phy_events[event], ha->core.shost); } int sas_init_events(struct sas_ha_struct *sas_ha) { - static const work_func_t sas_ha_event_fns[HA_NUM_EVENTS] = { + static void (*sas_ha_event_fns[HA_NUM_EVENTS])(void *) = { [HAE_RESET] = sas_hae_reset, }; @@ -64,10 +64,8 @@ int sas_init_events(struct sas_ha_struct *sas_ha) spin_lock_init(&sas_ha->event_lock); - for (i = 0; i < HA_NUM_EVENTS; i++) { - INIT_WORK(&sas_ha->ha_events[i].work, sas_ha_event_fns[i]); - sas_ha->ha_events[i].ha = sas_ha; - } + for (i = 0; i < HA_NUM_EVENTS; i++) + INIT_WORK(&sas_ha->ha_events[i], sas_ha_event_fns[i], sas_ha); sas_ha->notify_ha_event = notify_ha_event; sas_ha->notify_port_event = notify_port_event; diff --git a/trunk/drivers/scsi/libsas/sas_expander.c b/trunk/drivers/scsi/libsas/sas_expander.c index d31e6fa466f7..e34a93435497 100644 --- a/trunk/drivers/scsi/libsas/sas_expander.c +++ b/trunk/drivers/scsi/libsas/sas_expander.c @@ -597,15 +597,10 @@ static struct domain_device *sas_ex_discover_end_dev( child->iproto = phy->attached_iproto; memcpy(child->sas_addr, phy->attached_sas_addr, SAS_ADDR_SIZE); sas_hash_addr(child->hashed_sas_addr, child->sas_addr); - if (!phy->port) { - phy->port = sas_port_alloc(&parent->rphy->dev, phy_id); - if (unlikely(!phy->port)) - goto out_err; - if (unlikely(sas_port_add(phy->port) != 0)) { - sas_port_free(phy->port); - goto out_err; - } - } + phy->port = sas_port_alloc(&parent->rphy->dev, phy_id); + BUG_ON(!phy->port); + /* FIXME: better error handling*/ + BUG_ON(sas_port_add(phy->port) != 0); sas_ex_get_linkrate(parent, child, phy); if ((phy->attached_tproto & SAS_PROTO_STP) || phy->attached_sata_dev) { @@ -620,7 +615,8 @@ static struct domain_device *sas_ex_discover_end_dev( SAS_DPRINTK("report phy sata to %016llx:0x%x returned " "0x%x\n", SAS_ADDR(parent->sas_addr), phy_id, res); - goto out_free; + kfree(child); + return NULL; } memcpy(child->frame_rcvd, &child->sata_dev.rps_resp.rps.fis, sizeof(struct dev_to_host_fis)); @@ -631,14 +627,14 @@ static struct domain_device *sas_ex_discover_end_dev( "%016llx:0x%x returned 0x%x\n", SAS_ADDR(child->sas_addr), SAS_ADDR(parent->sas_addr), phy_id, res); - goto out_free; + kfree(child); + return NULL; } } else if (phy->attached_tproto & SAS_PROTO_SSP) { child->dev_type = SAS_END_DEV; rphy = sas_end_device_alloc(phy->port); /* FIXME: error handling */ - if (unlikely(!rphy)) - goto out_free; + BUG_ON(!rphy); child->tproto = phy->attached_tproto; sas_init_dev(child); @@ -655,7 +651,9 @@ static struct domain_device *sas_ex_discover_end_dev( "at %016llx:0x%x returned 0x%x\n", SAS_ADDR(child->sas_addr), SAS_ADDR(parent->sas_addr), phy_id, res); - goto out_list_del; + /* FIXME: this kfrees list elements without removing them */ + //kfree(child); + return NULL; } } else { SAS_DPRINTK("target proto 0x%x at %016llx:0x%x not handled\n", @@ -665,16 +663,6 @@ static struct domain_device *sas_ex_discover_end_dev( list_add_tail(&child->siblings, &parent_ex->children); return child; - - out_list_del: - list_del(&child->dev_list_node); - sas_rphy_free(rphy); - out_free: - sas_port_delete(phy->port); - out_err: - phy->port = NULL; - kfree(child); - return NULL; } static struct domain_device *sas_ex_discover_expander( diff --git a/trunk/drivers/scsi/libsas/sas_init.c b/trunk/drivers/scsi/libsas/sas_init.c index d65bc4e0f214..c836a237fb79 100644 --- a/trunk/drivers/scsi/libsas/sas_init.c +++ b/trunk/drivers/scsi/libsas/sas_init.c @@ -65,11 +65,9 @@ void sas_hash_addr(u8 *hashed, const u8 *sas_addr) /* ---------- HA events ---------- */ -void sas_hae_reset(struct work_struct *work) +void sas_hae_reset(void *data) { - struct sas_ha_event *ev = - container_of(work, struct sas_ha_event, work); - struct sas_ha_struct *ha = ev->ha; + struct sas_ha_struct *ha = data; sas_begin_event(HAE_RESET, &ha->event_lock, &ha->pending); @@ -114,8 +112,6 @@ int sas_register_ha(struct sas_ha_struct *sas_ha) } } - INIT_LIST_HEAD(&sas_ha->eh_done_q); - return 0; Undo_ports: @@ -146,7 +142,7 @@ static int sas_get_linkerrors(struct sas_phy *phy) return sas_smp_get_phy_events(phy); } -int sas_phy_reset(struct sas_phy *phy, int hard_reset) +static int sas_phy_reset(struct sas_phy *phy, int hard_reset) { int ret; enum phy_func reset_type; diff --git a/trunk/drivers/scsi/libsas/sas_internal.h b/trunk/drivers/scsi/libsas/sas_internal.h index 137d7e496b6d..bffcee474921 100644 --- a/trunk/drivers/scsi/libsas/sas_internal.h +++ b/trunk/drivers/scsi/libsas/sas_internal.h @@ -60,11 +60,11 @@ void sas_shutdown_queue(struct sas_ha_struct *sas_ha); void sas_deform_port(struct asd_sas_phy *phy); -void sas_porte_bytes_dmaed(struct work_struct *work); -void sas_porte_broadcast_rcvd(struct work_struct *work); -void sas_porte_link_reset_err(struct work_struct *work); -void sas_porte_timer_event(struct work_struct *work); -void sas_porte_hard_reset(struct work_struct *work); +void sas_porte_bytes_dmaed(void *); +void sas_porte_broadcast_rcvd(void *); +void sas_porte_link_reset_err(void *); +void sas_porte_timer_event(void *); +void sas_porte_hard_reset(void *); int sas_notify_lldd_dev_found(struct domain_device *); void sas_notify_lldd_dev_gone(struct domain_device *); @@ -75,7 +75,7 @@ int sas_smp_get_phy_events(struct sas_phy *phy); struct domain_device *sas_find_dev_by_rphy(struct sas_rphy *rphy); -void sas_hae_reset(struct work_struct *work); +void sas_hae_reset(void *); static inline void sas_queue_event(int event, spinlock_t *lock, unsigned long *pending, diff --git a/trunk/drivers/scsi/libsas/sas_phy.c b/trunk/drivers/scsi/libsas/sas_phy.c index b459c4b635b1..9340cdbae4a3 100644 --- a/trunk/drivers/scsi/libsas/sas_phy.c +++ b/trunk/drivers/scsi/libsas/sas_phy.c @@ -30,11 +30,9 @@ /* ---------- Phy events ---------- */ -static void sas_phye_loss_of_signal(struct work_struct *work) +static void sas_phye_loss_of_signal(void *data) { - struct asd_sas_event *ev = - container_of(work, struct asd_sas_event, work); - struct asd_sas_phy *phy = ev->phy; + struct asd_sas_phy *phy = data; sas_begin_event(PHYE_LOSS_OF_SIGNAL, &phy->ha->event_lock, &phy->phy_events_pending); @@ -42,22 +40,18 @@ static void sas_phye_loss_of_signal(struct work_struct *work) sas_deform_port(phy); } -static void sas_phye_oob_done(struct work_struct *work) +static void sas_phye_oob_done(void *data) { - struct asd_sas_event *ev = - container_of(work, struct asd_sas_event, work); - struct asd_sas_phy *phy = ev->phy; + struct asd_sas_phy *phy = data; sas_begin_event(PHYE_OOB_DONE, &phy->ha->event_lock, &phy->phy_events_pending); phy->error = 0; } -static void sas_phye_oob_error(struct work_struct *work) +static void sas_phye_oob_error(void *data) { - struct asd_sas_event *ev = - container_of(work, struct asd_sas_event, work); - struct asd_sas_phy *phy = ev->phy; + struct asd_sas_phy *phy = data; struct sas_ha_struct *sas_ha = phy->ha; struct asd_sas_port *port = phy->port; struct sas_internal *i = @@ -86,11 +80,9 @@ static void sas_phye_oob_error(struct work_struct *work) } } -static void sas_phye_spinup_hold(struct work_struct *work) +static void sas_phye_spinup_hold(void *data) { - struct asd_sas_event *ev = - container_of(work, struct asd_sas_event, work); - struct asd_sas_phy *phy = ev->phy; + struct asd_sas_phy *phy = data; struct sas_ha_struct *sas_ha = phy->ha; struct sas_internal *i = to_sas_internal(sas_ha->core.shost->transportt); @@ -108,14 +100,14 @@ int sas_register_phys(struct sas_ha_struct *sas_ha) { int i; - static const work_func_t sas_phy_event_fns[PHY_NUM_EVENTS] = { + static void (*sas_phy_event_fns[PHY_NUM_EVENTS])(void *) = { [PHYE_LOSS_OF_SIGNAL] = sas_phye_loss_of_signal, [PHYE_OOB_DONE] = sas_phye_oob_done, [PHYE_OOB_ERROR] = sas_phye_oob_error, [PHYE_SPINUP_HOLD] = sas_phye_spinup_hold, }; - static const work_func_t sas_port_event_fns[PORT_NUM_EVENTS] = { + static void (*sas_port_event_fns[PORT_NUM_EVENTS])(void *) = { [PORTE_BYTES_DMAED] = sas_porte_bytes_dmaed, [PORTE_BROADCAST_RCVD] = sas_porte_broadcast_rcvd, [PORTE_LINK_RESET_ERR] = sas_porte_link_reset_err, @@ -130,18 +122,13 @@ int sas_register_phys(struct sas_ha_struct *sas_ha) phy->error = 0; INIT_LIST_HEAD(&phy->port_phy_el); - for (k = 0; k < PORT_NUM_EVENTS; k++) { - INIT_WORK(&phy->port_events[k].work, - sas_port_event_fns[k]); - phy->port_events[k].phy = phy; - } - - for (k = 0; k < PHY_NUM_EVENTS; k++) { - INIT_WORK(&phy->phy_events[k].work, - sas_phy_event_fns[k]); - phy->phy_events[k].phy = phy; - } + for (k = 0; k < PORT_NUM_EVENTS; k++) + INIT_WORK(&phy->port_events[k], sas_port_event_fns[k], + phy); + for (k = 0; k < PHY_NUM_EVENTS; k++) + INIT_WORK(&phy->phy_events[k], sas_phy_event_fns[k], + phy); phy->port = NULL; phy->ha = sas_ha; spin_lock_init(&phy->frame_rcvd_lock); diff --git a/trunk/drivers/scsi/libsas/sas_port.c b/trunk/drivers/scsi/libsas/sas_port.c index 971c37ceecb4..253cdcf306a2 100644 --- a/trunk/drivers/scsi/libsas/sas_port.c +++ b/trunk/drivers/scsi/libsas/sas_port.c @@ -181,11 +181,9 @@ void sas_deform_port(struct asd_sas_phy *phy) /* ---------- SAS port events ---------- */ -void sas_porte_bytes_dmaed(struct work_struct *work) +void sas_porte_bytes_dmaed(void *data) { - struct asd_sas_event *ev = - container_of(work, struct asd_sas_event, work); - struct asd_sas_phy *phy = ev->phy; + struct asd_sas_phy *phy = data; sas_begin_event(PORTE_BYTES_DMAED, &phy->ha->event_lock, &phy->port_events_pending); @@ -193,13 +191,11 @@ void sas_porte_bytes_dmaed(struct work_struct *work) sas_form_port(phy); } -void sas_porte_broadcast_rcvd(struct work_struct *work) +void sas_porte_broadcast_rcvd(void *data) { - struct asd_sas_event *ev = - container_of(work, struct asd_sas_event, work); - struct asd_sas_phy *phy = ev->phy; unsigned long flags; u32 prim; + struct asd_sas_phy *phy = data; sas_begin_event(PORTE_BROADCAST_RCVD, &phy->ha->event_lock, &phy->port_events_pending); @@ -212,11 +208,9 @@ void sas_porte_broadcast_rcvd(struct work_struct *work) sas_discover_event(phy->port, DISCE_REVALIDATE_DOMAIN); } -void sas_porte_link_reset_err(struct work_struct *work) +void sas_porte_link_reset_err(void *data) { - struct asd_sas_event *ev = - container_of(work, struct asd_sas_event, work); - struct asd_sas_phy *phy = ev->phy; + struct asd_sas_phy *phy = data; sas_begin_event(PORTE_LINK_RESET_ERR, &phy->ha->event_lock, &phy->port_events_pending); @@ -224,11 +218,9 @@ void sas_porte_link_reset_err(struct work_struct *work) sas_deform_port(phy); } -void sas_porte_timer_event(struct work_struct *work) +void sas_porte_timer_event(void *data) { - struct asd_sas_event *ev = - container_of(work, struct asd_sas_event, work); - struct asd_sas_phy *phy = ev->phy; + struct asd_sas_phy *phy = data; sas_begin_event(PORTE_TIMER_EVENT, &phy->ha->event_lock, &phy->port_events_pending); @@ -236,11 +228,9 @@ void sas_porte_timer_event(struct work_struct *work) sas_deform_port(phy); } -void sas_porte_hard_reset(struct work_struct *work) +void sas_porte_hard_reset(void *data) { - struct asd_sas_event *ev = - container_of(work, struct asd_sas_event, work); - struct asd_sas_phy *phy = ev->phy; + struct asd_sas_phy *phy = data; sas_begin_event(PORTE_HARD_RESET, &phy->ha->event_lock, &phy->port_events_pending); diff --git a/trunk/drivers/scsi/libsas/sas_scsi_host.c b/trunk/drivers/scsi/libsas/sas_scsi_host.c index 22672d54aa27..e46e79355b77 100644 --- a/trunk/drivers/scsi/libsas/sas_scsi_host.c +++ b/trunk/drivers/scsi/libsas/sas_scsi_host.c @@ -29,11 +29,9 @@ #include #include #include -#include #include #include #include "../scsi_sas_internal.h" -#include "../scsi_transport_api.h" #include #include @@ -48,7 +46,6 @@ static void sas_scsi_task_done(struct sas_task *task) { struct task_status_struct *ts = &task->task_status; struct scsi_cmnd *sc = task->uldd_task; - struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(sc->device->host); unsigned ts_flags = task->task_state_flags; int hs = 0, stat = 0; @@ -119,7 +116,7 @@ static void sas_scsi_task_done(struct sas_task *task) sas_free_task(task); /* This is very ugly but this is how SCSI Core works. */ if (ts_flags & SAS_TASK_STATE_ABORTED) - scsi_eh_finish_cmd(sc, &sas_ha->eh_done_q); + scsi_finish_command(sc); else sc->scsi_done(sc); } @@ -310,15 +307,6 @@ static enum task_disposition sas_scsi_find_task(struct sas_task *task) spin_unlock_irqrestore(&core->task_queue_lock, flags); } - spin_lock_irqsave(&task->task_state_lock, flags); - if (task->task_state_flags & SAS_TASK_INITIATOR_ABORTED) { - spin_unlock_irqrestore(&task->task_state_lock, flags); - SAS_DPRINTK("%s: task 0x%p already aborted\n", - __FUNCTION__, task); - return TASK_IS_ABORTED; - } - spin_unlock_irqrestore(&task->task_state_lock, flags); - for (i = 0; i < 5; i++) { SAS_DPRINTK("%s: aborting task 0x%p\n", __FUNCTION__, task); res = si->dft->lldd_abort_task(task); @@ -421,16 +409,13 @@ void sas_scsi_recover_host(struct Scsi_Host *shost) SAS_DPRINTK("going over list...\n"); list_for_each_entry_safe(cmd, n, &error_q, eh_entry) { struct sas_task *task = TO_SAS_TASK(cmd); - list_del_init(&cmd->eh_entry); - if (!task) { - SAS_DPRINTK("%s: taskless cmd?!\n", __FUNCTION__); - continue; - } SAS_DPRINTK("trying to find task 0x%p\n", task); + list_del_init(&cmd->eh_entry); res = sas_scsi_find_task(task); cmd->eh_eflags = 0; + shost->host_failed--; switch (res) { case TASK_IS_DONE: @@ -506,7 +491,6 @@ void sas_scsi_recover_host(struct Scsi_Host *shost) } } out: - scsi_eh_flush_done_q(&ha->eh_done_q); SAS_DPRINTK("--- Exit %s\n", __FUNCTION__); return; clear_q: @@ -524,18 +508,12 @@ enum scsi_eh_timer_return sas_scsi_timed_out(struct scsi_cmnd *cmd) unsigned long flags; if (!task) { - SAS_DPRINTK("command 0x%p, task 0x%p, gone: EH_HANDLED\n", + SAS_DPRINTK("command 0x%p, task 0x%p, timed out: EH_HANDLED\n", cmd, task); return EH_HANDLED; } spin_lock_irqsave(&task->task_state_lock, flags); - if (task->task_state_flags & SAS_TASK_INITIATOR_ABORTED) { - spin_unlock_irqrestore(&task->task_state_lock, flags); - SAS_DPRINTK("command 0x%p, task 0x%p, aborted by initiator: " - "EH_NOT_HANDLED\n", cmd, task); - return EH_NOT_HANDLED; - } if (task->task_state_flags & SAS_TASK_STATE_DONE) { spin_unlock_irqrestore(&task->task_state_lock, flags); SAS_DPRINTK("command 0x%p, task 0x%p, timed out: EH_HANDLED\n", @@ -799,66 +777,6 @@ void sas_shutdown_queue(struct sas_ha_struct *sas_ha) spin_unlock_irqrestore(&core->task_queue_lock, flags); } -static int do_sas_task_abort(struct sas_task *task) -{ - struct scsi_cmnd *sc = task->uldd_task; - struct sas_internal *si = - to_sas_internal(task->dev->port->ha->core.shost->transportt); - unsigned long flags; - int res; - - spin_lock_irqsave(&task->task_state_lock, flags); - if (task->task_state_flags & SAS_TASK_STATE_ABORTED) { - spin_unlock_irqrestore(&task->task_state_lock, flags); - SAS_DPRINTK("%s: Task %p already aborted.\n", __FUNCTION__, - task); - return 0; - } - - task->task_state_flags |= SAS_TASK_INITIATOR_ABORTED; - if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) - task->task_state_flags |= SAS_TASK_STATE_ABORTED; - spin_unlock_irqrestore(&task->task_state_lock, flags); - - if (!si->dft->lldd_abort_task) - return -ENODEV; - - res = si->dft->lldd_abort_task(task); - if ((task->task_state_flags & SAS_TASK_STATE_DONE) || - (res == TMF_RESP_FUNC_COMPLETE)) - { - /* SMP commands don't have scsi_cmds(?) */ - if (!sc) { - task->task_done(task); - return 0; - } - scsi_req_abort_cmd(sc); - scsi_schedule_eh(sc->device->host); - return 0; - } - - spin_lock_irqsave(&task->task_state_lock, flags); - task->task_state_flags &= ~SAS_TASK_INITIATOR_ABORTED; - if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) - task->task_state_flags &= ~SAS_TASK_STATE_ABORTED; - spin_unlock_irqrestore(&task->task_state_lock, flags); - - return -EAGAIN; -} - -void sas_task_abort(struct work_struct *work) -{ - struct sas_task *task = - container_of(work, struct sas_task, abort_work); - int i; - - for (i = 0; i < 5; i++) - if (!do_sas_task_abort(task)) - return; - - SAS_DPRINTK("%s: Could not kill task!\n", __FUNCTION__); -} - EXPORT_SYMBOL_GPL(sas_queuecommand); EXPORT_SYMBOL_GPL(sas_target_alloc); EXPORT_SYMBOL_GPL(sas_slave_configure); @@ -866,5 +784,3 @@ EXPORT_SYMBOL_GPL(sas_slave_destroy); EXPORT_SYMBOL_GPL(sas_change_queue_depth); EXPORT_SYMBOL_GPL(sas_change_queue_type); EXPORT_SYMBOL_GPL(sas_bios_param); -EXPORT_SYMBOL_GPL(sas_task_abort); -EXPORT_SYMBOL_GPL(sas_phy_reset); diff --git a/trunk/drivers/scsi/libsrp.c b/trunk/drivers/scsi/libsrp.c deleted file mode 100644 index 89403b00e042..000000000000 --- a/trunk/drivers/scsi/libsrp.c +++ /dev/null @@ -1,441 +0,0 @@ -/* - * SCSI RDAM Protocol lib functions - * - * Copyright (C) 2006 FUJITA Tomonori - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -enum srp_task_attributes { - SRP_SIMPLE_TASK = 0, - SRP_HEAD_TASK = 1, - SRP_ORDERED_TASK = 2, - SRP_ACA_TASK = 4 -}; - -/* tmp - will replace with SCSI logging stuff */ -#define eprintk(fmt, args...) \ -do { \ - printk("%s(%d) " fmt, __FUNCTION__, __LINE__, ##args); \ -} while (0) -/* #define dprintk eprintk */ -#define dprintk(fmt, args...) - -static int srp_iu_pool_alloc(struct srp_queue *q, size_t max, - struct srp_buf **ring) -{ - int i; - struct iu_entry *iue; - - q->pool = kcalloc(max, sizeof(struct iu_entry *), GFP_KERNEL); - if (!q->pool) - return -ENOMEM; - q->items = kcalloc(max, sizeof(struct iu_entry), GFP_KERNEL); - if (!q->items) - goto free_pool; - - spin_lock_init(&q->lock); - q->queue = kfifo_init((void *) q->pool, max * sizeof(void *), - GFP_KERNEL, &q->lock); - if (IS_ERR(q->queue)) - goto free_item; - - for (i = 0, iue = q->items; i < max; i++) { - __kfifo_put(q->queue, (void *) &iue, sizeof(void *)); - iue->sbuf = ring[i]; - iue++; - } - return 0; - -free_item: - kfree(q->items); -free_pool: - kfree(q->pool); - return -ENOMEM; -} - -static void srp_iu_pool_free(struct srp_queue *q) -{ - kfree(q->items); - kfree(q->pool); -} - -static struct srp_buf **srp_ring_alloc(struct device *dev, - size_t max, size_t size) -{ - int i; - struct srp_buf **ring; - - ring = kcalloc(max, sizeof(struct srp_buf *), GFP_KERNEL); - if (!ring) - return NULL; - - for (i = 0; i < max; i++) { - ring[i] = kzalloc(sizeof(struct srp_buf), GFP_KERNEL); - if (!ring[i]) - goto out; - ring[i]->buf = dma_alloc_coherent(dev, size, &ring[i]->dma, - GFP_KERNEL); - if (!ring[i]->buf) - goto out; - } - return ring; - -out: - for (i = 0; i < max && ring[i]; i++) { - if (ring[i]->buf) - dma_free_coherent(dev, size, ring[i]->buf, ring[i]->dma); - kfree(ring[i]); - } - kfree(ring); - - return NULL; -} - -static void srp_ring_free(struct device *dev, struct srp_buf **ring, size_t max, - size_t size) -{ - int i; - - for (i = 0; i < max; i++) { - dma_free_coherent(dev, size, ring[i]->buf, ring[i]->dma); - kfree(ring[i]); - } -} - -int srp_target_alloc(struct srp_target *target, struct device *dev, - size_t nr, size_t iu_size) -{ - int err; - - spin_lock_init(&target->lock); - INIT_LIST_HEAD(&target->cmd_queue); - - target->dev = dev; - target->dev->driver_data = target; - - target->srp_iu_size = iu_size; - target->rx_ring_size = nr; - target->rx_ring = srp_ring_alloc(target->dev, nr, iu_size); - if (!target->rx_ring) - return -ENOMEM; - err = srp_iu_pool_alloc(&target->iu_queue, nr, target->rx_ring); - if (err) - goto free_ring; - - return 0; - -free_ring: - srp_ring_free(target->dev, target->rx_ring, nr, iu_size); - return -ENOMEM; -} -EXPORT_SYMBOL_GPL(srp_target_alloc); - -void srp_target_free(struct srp_target *target) -{ - srp_ring_free(target->dev, target->rx_ring, target->rx_ring_size, - target->srp_iu_size); - srp_iu_pool_free(&target->iu_queue); -} -EXPORT_SYMBOL_GPL(srp_target_free); - -struct iu_entry *srp_iu_get(struct srp_target *target) -{ - struct iu_entry *iue = NULL; - - kfifo_get(target->iu_queue.queue, (void *) &iue, sizeof(void *)); - if (!iue) - return iue; - iue->target = target; - INIT_LIST_HEAD(&iue->ilist); - iue->flags = 0; - return iue; -} -EXPORT_SYMBOL_GPL(srp_iu_get); - -void srp_iu_put(struct iu_entry *iue) -{ - kfifo_put(iue->target->iu_queue.queue, (void *) &iue, sizeof(void *)); -} -EXPORT_SYMBOL_GPL(srp_iu_put); - -static int srp_direct_data(struct scsi_cmnd *sc, struct srp_direct_buf *md, - enum dma_data_direction dir, srp_rdma_t rdma_io, - int dma_map, int ext_desc) -{ - struct iu_entry *iue = NULL; - struct scatterlist *sg = NULL; - int err, nsg = 0, len; - - if (dma_map) { - iue = (struct iu_entry *) sc->SCp.ptr; - sg = sc->request_buffer; - - dprintk("%p %u %u %d\n", iue, sc->request_bufflen, - md->len, sc->use_sg); - - nsg = dma_map_sg(iue->target->dev, sg, sc->use_sg, - DMA_BIDIRECTIONAL); - if (!nsg) { - printk("fail to map %p %d\n", iue, sc->use_sg); - return 0; - } - len = min(sc->request_bufflen, md->len); - } else - len = md->len; - - err = rdma_io(sc, sg, nsg, md, 1, dir, len); - - if (dma_map) - dma_unmap_sg(iue->target->dev, sg, nsg, DMA_BIDIRECTIONAL); - - return err; -} - -static int srp_indirect_data(struct scsi_cmnd *sc, struct srp_cmd *cmd, - struct srp_indirect_buf *id, - enum dma_data_direction dir, srp_rdma_t rdma_io, - int dma_map, int ext_desc) -{ - struct iu_entry *iue = NULL; - struct srp_direct_buf *md = NULL; - struct scatterlist dummy, *sg = NULL; - dma_addr_t token = 0; - long err; - unsigned int done = 0; - int nmd, nsg = 0, len; - - if (dma_map || ext_desc) { - iue = (struct iu_entry *) sc->SCp.ptr; - sg = sc->request_buffer; - - dprintk("%p %u %u %d %d\n", - iue, sc->request_bufflen, id->len, - cmd->data_in_desc_cnt, cmd->data_out_desc_cnt); - } - - nmd = id->table_desc.len / sizeof(struct srp_direct_buf); - - if ((dir == DMA_FROM_DEVICE && nmd == cmd->data_in_desc_cnt) || - (dir == DMA_TO_DEVICE && nmd == cmd->data_out_desc_cnt)) { - md = &id->desc_list[0]; - goto rdma; - } - - if (ext_desc && dma_map) { - md = dma_alloc_coherent(iue->target->dev, id->table_desc.len, - &token, GFP_KERNEL); - if (!md) { - eprintk("Can't get dma memory %u\n", id->table_desc.len); - return -ENOMEM; - } - - sg_init_one(&dummy, md, id->table_desc.len); - sg_dma_address(&dummy) = token; - err = rdma_io(sc, &dummy, 1, &id->table_desc, 1, DMA_TO_DEVICE, - id->table_desc.len); - if (err < 0) { - eprintk("Error copying indirect table %ld\n", err); - goto free_mem; - } - } else { - eprintk("This command uses external indirect buffer\n"); - return -EINVAL; - } - -rdma: - if (dma_map) { - nsg = dma_map_sg(iue->target->dev, sg, sc->use_sg, DMA_BIDIRECTIONAL); - if (!nsg) { - eprintk("fail to map %p %d\n", iue, sc->use_sg); - goto free_mem; - } - len = min(sc->request_bufflen, id->len); - } else - len = id->len; - - err = rdma_io(sc, sg, nsg, md, nmd, dir, len); - - if (dma_map) - dma_unmap_sg(iue->target->dev, sg, nsg, DMA_BIDIRECTIONAL); - -free_mem: - if (token && dma_map) - dma_free_coherent(iue->target->dev, id->table_desc.len, md, token); - - return done; -} - -static int data_out_desc_size(struct srp_cmd *cmd) -{ - int size = 0; - u8 fmt = cmd->buf_fmt >> 4; - - switch (fmt) { - case SRP_NO_DATA_DESC: - break; - case SRP_DATA_DESC_DIRECT: - size = sizeof(struct srp_direct_buf); - break; - case SRP_DATA_DESC_INDIRECT: - size = sizeof(struct srp_indirect_buf) + - sizeof(struct srp_direct_buf) * cmd->data_out_desc_cnt; - break; - default: - eprintk("client error. Invalid data_out_format %x\n", fmt); - break; - } - return size; -} - -/* - * TODO: this can be called multiple times for a single command if it - * has very long data. - */ -int srp_transfer_data(struct scsi_cmnd *sc, struct srp_cmd *cmd, - srp_rdma_t rdma_io, int dma_map, int ext_desc) -{ - struct srp_direct_buf *md; - struct srp_indirect_buf *id; - enum dma_data_direction dir; - int offset, err = 0; - u8 format; - - offset = cmd->add_cdb_len * 4; - - dir = srp_cmd_direction(cmd); - if (dir == DMA_FROM_DEVICE) - offset += data_out_desc_size(cmd); - - if (dir == DMA_TO_DEVICE) - format = cmd->buf_fmt >> 4; - else - format = cmd->buf_fmt & ((1U << 4) - 1); - - switch (format) { - case SRP_NO_DATA_DESC: - break; - case SRP_DATA_DESC_DIRECT: - md = (struct srp_direct_buf *) - (cmd->add_data + offset); - err = srp_direct_data(sc, md, dir, rdma_io, dma_map, ext_desc); - break; - case SRP_DATA_DESC_INDIRECT: - id = (struct srp_indirect_buf *) - (cmd->add_data + offset); - err = srp_indirect_data(sc, cmd, id, dir, rdma_io, dma_map, - ext_desc); - break; - default: - eprintk("Unknown format %d %x\n", dir, format); - break; - } - - return err; -} -EXPORT_SYMBOL_GPL(srp_transfer_data); - -static int vscsis_data_length(struct srp_cmd *cmd, enum dma_data_direction dir) -{ - struct srp_direct_buf *md; - struct srp_indirect_buf *id; - int len = 0, offset = cmd->add_cdb_len * 4; - u8 fmt; - - if (dir == DMA_TO_DEVICE) - fmt = cmd->buf_fmt >> 4; - else { - fmt = cmd->buf_fmt & ((1U << 4) - 1); - offset += data_out_desc_size(cmd); - } - - switch (fmt) { - case SRP_NO_DATA_DESC: - break; - case SRP_DATA_DESC_DIRECT: - md = (struct srp_direct_buf *) (cmd->add_data + offset); - len = md->len; - break; - case SRP_DATA_DESC_INDIRECT: - id = (struct srp_indirect_buf *) (cmd->add_data + offset); - len = id->len; - break; - default: - eprintk("invalid data format %x\n", fmt); - break; - } - return len; -} - -int srp_cmd_queue(struct Scsi_Host *shost, struct srp_cmd *cmd, void *info, - u64 addr) -{ - enum dma_data_direction dir; - struct scsi_cmnd *sc; - int tag, len, err; - - switch (cmd->task_attr) { - case SRP_SIMPLE_TASK: - tag = MSG_SIMPLE_TAG; - break; - case SRP_ORDERED_TASK: - tag = MSG_ORDERED_TAG; - break; - case SRP_HEAD_TASK: - tag = MSG_HEAD_TAG; - break; - default: - eprintk("Task attribute %d not supported\n", cmd->task_attr); - tag = MSG_ORDERED_TAG; - } - - dir = srp_cmd_direction(cmd); - len = vscsis_data_length(cmd, dir); - - dprintk("%p %x %lx %d %d %d %llx\n", info, cmd->cdb[0], - cmd->lun, dir, len, tag, (unsigned long long) cmd->tag); - - sc = scsi_host_get_command(shost, dir, GFP_KERNEL); - if (!sc) - return -ENOMEM; - - sc->SCp.ptr = info; - memcpy(sc->cmnd, cmd->cdb, MAX_COMMAND_SIZE); - sc->request_bufflen = len; - sc->request_buffer = (void *) (unsigned long) addr; - sc->tag = tag; - err = scsi_tgt_queue_command(sc, (struct scsi_lun *) &cmd->lun, cmd->tag); - if (err) - scsi_host_put_command(shost, sc); - - return err; -} -EXPORT_SYMBOL_GPL(srp_cmd_queue); - -MODULE_DESCRIPTION("SCSI RDAM Protocol lib functions"); -MODULE_AUTHOR("FUJITA Tomonori"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/scsi/lpfc/lpfc.h b/trunk/drivers/scsi/lpfc/lpfc.h index a7de0bca5bdd..3f7f5f8abd75 100644 --- a/trunk/drivers/scsi/lpfc/lpfc.h +++ b/trunk/drivers/scsi/lpfc/lpfc.h @@ -296,17 +296,13 @@ struct lpfc_hba { uint32_t cfg_cr_delay; uint32_t cfg_cr_count; uint32_t cfg_multi_ring_support; - uint32_t cfg_multi_ring_rctl; - uint32_t cfg_multi_ring_type; uint32_t cfg_fdmi_on; uint32_t cfg_discovery_threads; uint32_t cfg_max_luns; uint32_t cfg_poll; uint32_t cfg_poll_tmo; - uint32_t cfg_use_msi; uint32_t cfg_sg_seg_cnt; uint32_t cfg_sg_dma_buf_size; - uint64_t cfg_soft_wwnn; uint64_t cfg_soft_wwpn; uint32_t dev_loss_tmo_changed; @@ -359,7 +355,7 @@ struct lpfc_hba { #define VPD_PORT 0x8 /* valid vpd port data */ #define VPD_MASK 0xf /* mask for any vpd data */ - uint8_t soft_wwn_enable; + uint8_t soft_wwpn_enable; struct timer_list fcp_poll_timer; struct timer_list els_tmofunc; diff --git a/trunk/drivers/scsi/lpfc/lpfc_attr.c b/trunk/drivers/scsi/lpfc/lpfc_attr.c index f247e786af99..2a4e02e7a392 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_attr.c +++ b/trunk/drivers/scsi/lpfc/lpfc_attr.c @@ -552,10 +552,10 @@ static CLASS_DEVICE_ATTR(board_mode, S_IRUGO | S_IWUSR, static CLASS_DEVICE_ATTR(issue_reset, S_IWUSR, NULL, lpfc_issue_reset); -static char *lpfc_soft_wwn_key = "C99G71SL8032A"; +static char *lpfc_soft_wwpn_key = "C99G71SL8032A"; static ssize_t -lpfc_soft_wwn_enable_store(struct class_device *cdev, const char *buf, +lpfc_soft_wwpn_enable_store(struct class_device *cdev, const char *buf, size_t count) { struct Scsi_Host *host = class_to_shost(cdev); @@ -579,15 +579,15 @@ lpfc_soft_wwn_enable_store(struct class_device *cdev, const char *buf, if (buf[cnt-1] == '\n') cnt--; - if ((cnt != strlen(lpfc_soft_wwn_key)) || - (strncmp(buf, lpfc_soft_wwn_key, strlen(lpfc_soft_wwn_key)) != 0)) + if ((cnt != strlen(lpfc_soft_wwpn_key)) || + (strncmp(buf, lpfc_soft_wwpn_key, strlen(lpfc_soft_wwpn_key)) != 0)) return -EINVAL; - phba->soft_wwn_enable = 1; + phba->soft_wwpn_enable = 1; return count; } -static CLASS_DEVICE_ATTR(lpfc_soft_wwn_enable, S_IWUSR, NULL, - lpfc_soft_wwn_enable_store); +static CLASS_DEVICE_ATTR(lpfc_soft_wwpn_enable, S_IWUSR, NULL, + lpfc_soft_wwpn_enable_store); static ssize_t lpfc_soft_wwpn_show(struct class_device *cdev, char *buf) @@ -613,12 +613,12 @@ lpfc_soft_wwpn_store(struct class_device *cdev, const char *buf, size_t count) if (buf[cnt-1] == '\n') cnt--; - if (!phba->soft_wwn_enable || (cnt < 16) || (cnt > 18) || + if (!phba->soft_wwpn_enable || (cnt < 16) || (cnt > 18) || ((cnt == 17) && (*buf++ != 'x')) || ((cnt == 18) && ((*buf++ != '0') || (*buf++ != 'x')))) return -EINVAL; - phba->soft_wwn_enable = 0; + phba->soft_wwpn_enable = 0; memset(wwpn, 0, sizeof(wwpn)); @@ -639,8 +639,6 @@ lpfc_soft_wwpn_store(struct class_device *cdev, const char *buf, size_t count) } phba->cfg_soft_wwpn = wwn_to_u64(wwpn); fc_host_port_name(host) = phba->cfg_soft_wwpn; - if (phba->cfg_soft_wwnn) - fc_host_node_name(host) = phba->cfg_soft_wwnn; dev_printk(KERN_NOTICE, &phba->pcidev->dev, "lpfc%d: Reinitializing to use soft_wwpn\n", phba->brd_no); @@ -666,66 +664,6 @@ lpfc_soft_wwpn_store(struct class_device *cdev, const char *buf, size_t count) static CLASS_DEVICE_ATTR(lpfc_soft_wwpn, S_IRUGO | S_IWUSR,\ lpfc_soft_wwpn_show, lpfc_soft_wwpn_store); -static ssize_t -lpfc_soft_wwnn_show(struct class_device *cdev, char *buf) -{ - struct Scsi_Host *host = class_to_shost(cdev); - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; - return snprintf(buf, PAGE_SIZE, "0x%llx\n", - (unsigned long long)phba->cfg_soft_wwnn); -} - - -static ssize_t -lpfc_soft_wwnn_store(struct class_device *cdev, const char *buf, size_t count) -{ - struct Scsi_Host *host = class_to_shost(cdev); - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; - unsigned int i, j, cnt=count; - u8 wwnn[8]; - - /* count may include a LF at end of string */ - if (buf[cnt-1] == '\n') - cnt--; - - if (!phba->soft_wwn_enable || (cnt < 16) || (cnt > 18) || - ((cnt == 17) && (*buf++ != 'x')) || - ((cnt == 18) && ((*buf++ != '0') || (*buf++ != 'x')))) - return -EINVAL; - - /* - * Allow wwnn to be set many times, as long as the enable is set. - * However, once the wwpn is set, everything locks. - */ - - memset(wwnn, 0, sizeof(wwnn)); - - /* Validate and store the new name */ - for (i=0, j=0; i < 16; i++) { - if ((*buf >= 'a') && (*buf <= 'f')) - j = ((j << 4) | ((*buf++ -'a') + 10)); - else if ((*buf >= 'A') && (*buf <= 'F')) - j = ((j << 4) | ((*buf++ -'A') + 10)); - else if ((*buf >= '0') && (*buf <= '9')) - j = ((j << 4) | (*buf++ -'0')); - else - return -EINVAL; - if (i % 2) { - wwnn[i/2] = j & 0xff; - j = 0; - } - } - phba->cfg_soft_wwnn = wwn_to_u64(wwnn); - - dev_printk(KERN_NOTICE, &phba->pcidev->dev, - "lpfc%d: soft_wwnn set. Value will take effect upon " - "setting of the soft_wwpn\n", phba->brd_no); - - return count; -} -static CLASS_DEVICE_ATTR(lpfc_soft_wwnn, S_IRUGO | S_IWUSR,\ - lpfc_soft_wwnn_show, lpfc_soft_wwnn_store); - static int lpfc_poll = 0; module_param(lpfc_poll, int, 0); @@ -864,11 +802,12 @@ static CLASS_DEVICE_ATTR(lpfc_devloss_tmo, S_IRUGO | S_IWUSR, # LOG_MBOX 0x4 Mailbox events # LOG_INIT 0x8 Initialization events # LOG_LINK_EVENT 0x10 Link events +# LOG_IP 0x20 IP traffic history # LOG_FCP 0x40 FCP traffic history # LOG_NODE 0x80 Node table events # LOG_MISC 0x400 Miscellaneous events # LOG_SLI 0x800 SLI events -# LOG_FCP_ERROR 0x1000 Only log FCP errors +# LOG_CHK_COND 0x1000 FCP Check condition flag # LOG_LIBDFC 0x2000 LIBDFC events # LOG_ALL_MSG 0xffff LOG all messages */ @@ -976,22 +915,6 @@ LPFC_ATTR_RW(cr_count, 1, 1, 255, "A count of I/O completions after which an " LPFC_ATTR_R(multi_ring_support, 1, 1, 2, "Determines number of primary " "SLI rings to spread IOCB entries across"); -/* -# lpfc_multi_ring_rctl: If lpfc_multi_ring_support is enabled, this -# identifies what rctl value to configure the additional ring for. -# Value range is [1,0xff]. Default value is 4 (Unsolicated Data). -*/ -LPFC_ATTR_R(multi_ring_rctl, FC_UNSOL_DATA, 1, - 255, "Identifies RCTL for additional ring configuration"); - -/* -# lpfc_multi_ring_type: If lpfc_multi_ring_support is enabled, this -# identifies what type value to configure the additional ring for. -# Value range is [1,0xff]. Default value is 5 (LLC/SNAP). -*/ -LPFC_ATTR_R(multi_ring_type, FC_LLC_SNAP, 1, - 255, "Identifies TYPE for additional ring configuration"); - /* # lpfc_fdmi_on: controls FDMI support. # 0 = no FDMI support @@ -1023,15 +946,6 @@ LPFC_ATTR_R(max_luns, 255, 0, 65535, LPFC_ATTR_RW(poll_tmo, 10, 1, 255, "Milliseconds driver will wait between polling FCP ring"); -/* -# lpfc_use_msi: Use MSI (Message Signaled Interrupts) in systems that -# support this feature -# 0 = MSI disabled (default) -# 1 = MSI enabled -# Value range is [0,1]. Default value is 0. -*/ -LPFC_ATTR_R(use_msi, 0, 0, 1, "Use Message Signaled Interrupts, if possible"); - struct class_device_attribute *lpfc_host_attrs[] = { &class_device_attr_info, @@ -1060,8 +974,6 @@ struct class_device_attribute *lpfc_host_attrs[] = { &class_device_attr_lpfc_cr_delay, &class_device_attr_lpfc_cr_count, &class_device_attr_lpfc_multi_ring_support, - &class_device_attr_lpfc_multi_ring_rctl, - &class_device_attr_lpfc_multi_ring_type, &class_device_attr_lpfc_fdmi_on, &class_device_attr_lpfc_max_luns, &class_device_attr_nport_evt_cnt, @@ -1070,10 +982,8 @@ struct class_device_attribute *lpfc_host_attrs[] = { &class_device_attr_issue_reset, &class_device_attr_lpfc_poll, &class_device_attr_lpfc_poll_tmo, - &class_device_attr_lpfc_use_msi, - &class_device_attr_lpfc_soft_wwnn, &class_device_attr_lpfc_soft_wwpn, - &class_device_attr_lpfc_soft_wwn_enable, + &class_device_attr_lpfc_soft_wwpn_enable, NULL, }; @@ -1861,8 +1771,6 @@ lpfc_get_cfgparam(struct lpfc_hba *phba) lpfc_cr_delay_init(phba, lpfc_cr_delay); lpfc_cr_count_init(phba, lpfc_cr_count); lpfc_multi_ring_support_init(phba, lpfc_multi_ring_support); - lpfc_multi_ring_rctl_init(phba, lpfc_multi_ring_rctl); - lpfc_multi_ring_type_init(phba, lpfc_multi_ring_type); lpfc_lun_queue_depth_init(phba, lpfc_lun_queue_depth); lpfc_fcp_class_init(phba, lpfc_fcp_class); lpfc_use_adisc_init(phba, lpfc_use_adisc); @@ -1874,11 +1782,9 @@ lpfc_get_cfgparam(struct lpfc_hba *phba) lpfc_discovery_threads_init(phba, lpfc_discovery_threads); lpfc_max_luns_init(phba, lpfc_max_luns); lpfc_poll_tmo_init(phba, lpfc_poll_tmo); - lpfc_use_msi_init(phba, lpfc_use_msi); lpfc_devloss_tmo_init(phba, lpfc_devloss_tmo); lpfc_nodev_tmo_init(phba, lpfc_nodev_tmo); phba->cfg_poll = lpfc_poll; - phba->cfg_soft_wwnn = 0L; phba->cfg_soft_wwpn = 0L; /* diff --git a/trunk/drivers/scsi/lpfc/lpfc_ct.c b/trunk/drivers/scsi/lpfc/lpfc_ct.c index a51a41b7f15d..3add7c237859 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_ct.c +++ b/trunk/drivers/scsi/lpfc/lpfc_ct.c @@ -558,14 +558,6 @@ lpfc_cmpl_ct_cmd_rsnn_nn(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, return; } -static void -lpfc_cmpl_ct_cmd_rff_id(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, - struct lpfc_iocbq * rspiocb) -{ - lpfc_cmpl_ct_cmd_rft_id(phba, cmdiocb, rspiocb); - return; -} - void lpfc_get_hba_sym_node_name(struct lpfc_hba * phba, uint8_t * symbp) { @@ -637,8 +629,6 @@ lpfc_ns_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode) bpl->tus.f.bdeSize = RNN_REQUEST_SZ; else if (cmdcode == SLI_CTNS_RSNN_NN) bpl->tus.f.bdeSize = RSNN_REQUEST_SZ; - else if (cmdcode == SLI_CTNS_RFF_ID) - bpl->tus.f.bdeSize = RFF_REQUEST_SZ; else bpl->tus.f.bdeSize = 0; bpl->tus.w = le32_to_cpu(bpl->tus.w); @@ -670,17 +660,6 @@ lpfc_ns_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode) cmpl = lpfc_cmpl_ct_cmd_rft_id; break; - case SLI_CTNS_RFF_ID: - CtReq->CommandResponse.bits.CmdRsp = - be16_to_cpu(SLI_CTNS_RFF_ID); - CtReq->un.rff.PortId = be32_to_cpu(phba->fc_myDID); - CtReq->un.rff.feature_res = 0; - CtReq->un.rff.feature_tgt = 0; - CtReq->un.rff.type_code = FC_FCP_DATA; - CtReq->un.rff.feature_init = 1; - cmpl = lpfc_cmpl_ct_cmd_rff_id; - break; - case SLI_CTNS_RNN_ID: CtReq->CommandResponse.bits.CmdRsp = be16_to_cpu(SLI_CTNS_RNN_ID); @@ -955,8 +934,7 @@ lpfc_fdmi_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode) ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) rh + size); ae->ad.bits.AttrType = be16_to_cpu(OS_NAME_VERSION); sprintf(ae->un.OsNameVersion, "%s %s %s", - init_utsname()->sysname, - init_utsname()->release, + init_utsname()->sysname, init_utsname()->release, init_utsname()->version); len = strlen(ae->un.OsNameVersion); len += (len & 3) ? (4 - (len & 3)) : 4; diff --git a/trunk/drivers/scsi/lpfc/lpfc_els.c b/trunk/drivers/scsi/lpfc/lpfc_els.c index a5f33a0dd4e7..71864cdc6c71 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_els.c +++ b/trunk/drivers/scsi/lpfc/lpfc_els.c @@ -243,7 +243,6 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, struct serv_parm *sp, IOCB_t *irsp) { LPFC_MBOXQ_t *mbox; - struct lpfc_dmabuf *mp; int rc; spin_lock_irq(phba->host->host_lock); @@ -308,14 +307,10 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT | MBX_STOP_IOCB); if (rc == MBX_NOT_FINISHED) - goto fail_issue_reg_login; + goto fail_free_mbox; return 0; - fail_issue_reg_login: - mp = (struct lpfc_dmabuf *) mbox->context1; - lpfc_mbuf_free(phba, mp->virt, mp->phys); - kfree(mp); fail_free_mbox: mempool_free(mbox, phba->mbox_mem_pool); fail: @@ -662,12 +657,6 @@ lpfc_plogi_confirm_nport(struct lpfc_hba * phba, struct lpfc_dmabuf *prsp, uint8_t name[sizeof (struct lpfc_name)]; uint32_t rc; - /* Fabric nodes can have the same WWPN so we don't bother searching - * by WWPN. Just return the ndlp that was given to us. - */ - if (ndlp->nlp_type & NLP_FABRIC) - return ndlp; - lp = (uint32_t *) prsp->virt; sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t)); memset(name, 0, sizeof (struct lpfc_name)); @@ -1133,7 +1122,7 @@ lpfc_cmpl_els_adisc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, mempool_free(mbox, phba->mbox_mem_pool); lpfc_disc_flush_list(phba); - psli->ring[(psli->extra_ring)]. + psli->ring[(psli->ip_ring)]. flag &= ~LPFC_STOP_IOCB_EVENT; psli->ring[(psli->fcp_ring)]. @@ -1862,7 +1851,6 @@ lpfc_cmpl_els_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, IOCB_t *irsp; struct lpfc_nodelist *ndlp; LPFC_MBOXQ_t *mbox = NULL; - struct lpfc_dmabuf *mp; irsp = &rspiocb->iocb; @@ -1874,11 +1862,6 @@ lpfc_cmpl_els_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, /* Check to see if link went down during discovery */ if ((lpfc_els_chk_latt(phba)) || !ndlp) { if (mbox) { - mp = (struct lpfc_dmabuf *) mbox->context1; - if (mp) { - lpfc_mbuf_free(phba, mp->virt, mp->phys); - kfree(mp); - } mempool_free( mbox, phba->mbox_mem_pool); } goto out; @@ -1910,7 +1893,9 @@ lpfc_cmpl_els_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, } /* NOTE: we should have messages for unsuccessful reglogin */ + mempool_free( mbox, phba->mbox_mem_pool); } else { + mempool_free( mbox, phba->mbox_mem_pool); /* Do not call NO_LIST for lpfc_els_abort'ed ELS cmds */ if (!((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) && ((irsp->un.ulpWord[4] == IOERR_SLI_ABORTED) || @@ -1922,12 +1907,6 @@ lpfc_cmpl_els_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, } } } - mp = (struct lpfc_dmabuf *) mbox->context1; - if (mp) { - lpfc_mbuf_free(phba, mp->virt, mp->phys); - kfree(mp); - } - mempool_free(mbox, phba->mbox_mem_pool); } out: if (ndlp) { @@ -2665,7 +2644,6 @@ lpfc_els_handle_rscn(struct lpfc_hba * phba) ndlp->nlp_type |= NLP_FABRIC; ndlp->nlp_prev_state = ndlp->nlp_state; ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; - lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); lpfc_issue_els_plogi(phba, NameServer_DID, 0); /* Wait for NameServer login cmpl before we can continue */ @@ -3061,7 +3039,7 @@ lpfc_els_rcv_farp(struct lpfc_hba * phba, /* FARP-REQ received from DID */ lpfc_printf_log(phba, KERN_INFO, - LOG_ELS, + LOG_IP, "%d:0601 FARP-REQ received from DID x%x\n", phba->brd_no, did); @@ -3123,7 +3101,7 @@ lpfc_els_rcv_farpr(struct lpfc_hba * phba, /* FARP-RSP received from DID */ lpfc_printf_log(phba, KERN_INFO, - LOG_ELS, + LOG_IP, "%d:0600 FARP-RSP received from DID x%x\n", phba->brd_no, did); diff --git a/trunk/drivers/scsi/lpfc/lpfc_hbadisc.c b/trunk/drivers/scsi/lpfc/lpfc_hbadisc.c index c39564e85e94..19c79a0549a7 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/trunk/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -525,7 +525,7 @@ lpfc_mbx_cmpl_clear_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) psli = &phba->sli; mb = &pmb->mb; /* Since we don't do discovery right now, turn these off here */ - psli->ring[psli->extra_ring].flag &= ~LPFC_STOP_IOCB_EVENT; + psli->ring[psli->ip_ring].flag &= ~LPFC_STOP_IOCB_EVENT; psli->ring[psli->fcp_ring].flag &= ~LPFC_STOP_IOCB_EVENT; psli->ring[psli->next_ring].flag &= ~LPFC_STOP_IOCB_EVENT; @@ -641,7 +641,7 @@ lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) if (rc == MBX_NOT_FINISHED) { mempool_free(pmb, phba->mbox_mem_pool); lpfc_disc_flush_list(phba); - psli->ring[(psli->extra_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; + psli->ring[(psli->ip_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; psli->ring[(psli->fcp_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; psli->ring[(psli->next_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; phba->hba_state = LPFC_HBA_READY; @@ -672,8 +672,6 @@ lpfc_mbx_cmpl_read_sparam(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) memcpy((uint8_t *) & phba->fc_sparam, (uint8_t *) mp->virt, sizeof (struct serv_parm)); - if (phba->cfg_soft_wwnn) - u64_to_wwn(phba->cfg_soft_wwnn, phba->fc_sparam.nodeName.u.wwn); if (phba->cfg_soft_wwpn) u64_to_wwn(phba->cfg_soft_wwpn, phba->fc_sparam.portName.u.wwn); memcpy((uint8_t *) & phba->fc_nodename, @@ -698,7 +696,7 @@ lpfc_mbx_cmpl_read_sparam(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) == MBX_NOT_FINISHED) { mempool_free( pmb, phba->mbox_mem_pool); lpfc_disc_flush_list(phba); - psli->ring[(psli->extra_ring)].flag &= + psli->ring[(psli->ip_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; psli->ring[(psli->fcp_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; @@ -717,9 +715,6 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) { int i; LPFC_MBOXQ_t *sparam_mbox, *cfglink_mbox; - struct lpfc_dmabuf *mp; - int rc; - sparam_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); cfglink_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); @@ -798,27 +793,16 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) if (sparam_mbox) { lpfc_read_sparam(phba, sparam_mbox); sparam_mbox->mbox_cmpl = lpfc_mbx_cmpl_read_sparam; - rc = lpfc_sli_issue_mbox(phba, sparam_mbox, + lpfc_sli_issue_mbox(phba, sparam_mbox, (MBX_NOWAIT | MBX_STOP_IOCB)); - if (rc == MBX_NOT_FINISHED) { - mp = (struct lpfc_dmabuf *) sparam_mbox->context1; - lpfc_mbuf_free(phba, mp->virt, mp->phys); - kfree(mp); - mempool_free(sparam_mbox, phba->mbox_mem_pool); - if (cfglink_mbox) - mempool_free(cfglink_mbox, phba->mbox_mem_pool); - return; - } } if (cfglink_mbox) { phba->hba_state = LPFC_LOCAL_CFG_LINK; lpfc_config_link(phba, cfglink_mbox); cfglink_mbox->mbox_cmpl = lpfc_mbx_cmpl_local_config_link; - rc = lpfc_sli_issue_mbox(phba, cfglink_mbox, + lpfc_sli_issue_mbox(phba, cfglink_mbox, (MBX_NOWAIT | MBX_STOP_IOCB)); - if (rc == MBX_NOT_FINISHED) - mempool_free(cfglink_mbox, phba->mbox_mem_pool); } } @@ -1083,7 +1067,6 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) lpfc_ns_cmd(phba, ndlp, SLI_CTNS_RNN_ID); lpfc_ns_cmd(phba, ndlp, SLI_CTNS_RSNN_NN); lpfc_ns_cmd(phba, ndlp, SLI_CTNS_RFT_ID); - lpfc_ns_cmd(phba, ndlp, SLI_CTNS_RFF_ID); } phba->fc_ns_retry = 0; @@ -1440,7 +1423,7 @@ lpfc_check_sli_ndlp(struct lpfc_hba * phba, if (iocb->context1 == (uint8_t *) ndlp) return 1; } - } else if (pring->ringno == psli->extra_ring) { + } else if (pring->ringno == psli->ip_ring) { } else if (pring->ringno == psli->fcp_ring) { /* Skip match check if waiting to relogin to FCP target */ @@ -1697,38 +1680,21 @@ lpfc_matchdid(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, uint32_t did) struct lpfc_nodelist * lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order, uint32_t did) { - struct lpfc_nodelist *ndlp; - struct list_head *lists[]={&phba->fc_nlpunmap_list, - &phba->fc_nlpmap_list, - &phba->fc_plogi_list, - &phba->fc_adisc_list, - &phba->fc_reglogin_list, - &phba->fc_prli_list, - &phba->fc_npr_list, - &phba->fc_unused_list}; - uint32_t search[]={NLP_SEARCH_UNMAPPED, - NLP_SEARCH_MAPPED, - NLP_SEARCH_PLOGI, - NLP_SEARCH_ADISC, - NLP_SEARCH_REGLOGIN, - NLP_SEARCH_PRLI, - NLP_SEARCH_NPR, - NLP_SEARCH_UNUSED}; - int i; + struct lpfc_nodelist *ndlp, *next_ndlp; uint32_t data1; spin_lock_irq(phba->host->host_lock); - for (i = 0; i < ARRAY_SIZE(lists); i++ ) { - if (!(order & search[i])) - continue; - list_for_each_entry(ndlp, lists[i], nlp_listp) { + if (order & NLP_SEARCH_UNMAPPED) { + list_for_each_entry_safe(ndlp, next_ndlp, + &phba->fc_nlpunmap_list, nlp_listp) { if (lpfc_matchdid(phba, ndlp, did)) { data1 = (((uint32_t) ndlp->nlp_state << 24) | ((uint32_t) ndlp->nlp_xri << 16) | ((uint32_t) ndlp->nlp_type << 8) | ((uint32_t) ndlp->nlp_rpi & 0xff)); + /* FIND node DID unmapped */ lpfc_printf_log(phba, KERN_INFO, LOG_NODE, - "%d:0929 FIND node DID " + "%d:0929 FIND node DID unmapped" " Data: x%p x%x x%x x%x\n", phba->brd_no, ndlp, ndlp->nlp_DID, @@ -1738,12 +1704,177 @@ lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order, uint32_t did) } } } + + if (order & NLP_SEARCH_MAPPED) { + list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nlpmap_list, + nlp_listp) { + if (lpfc_matchdid(phba, ndlp, did)) { + + data1 = (((uint32_t) ndlp->nlp_state << 24) | + ((uint32_t) ndlp->nlp_xri << 16) | + ((uint32_t) ndlp->nlp_type << 8) | + ((uint32_t) ndlp->nlp_rpi & 0xff)); + /* FIND node DID mapped */ + lpfc_printf_log(phba, KERN_INFO, LOG_NODE, + "%d:0930 FIND node DID mapped " + "Data: x%p x%x x%x x%x\n", + phba->brd_no, + ndlp, ndlp->nlp_DID, + ndlp->nlp_flag, data1); + spin_unlock_irq(phba->host->host_lock); + return ndlp; + } + } + } + + if (order & NLP_SEARCH_PLOGI) { + list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_plogi_list, + nlp_listp) { + if (lpfc_matchdid(phba, ndlp, did)) { + + data1 = (((uint32_t) ndlp->nlp_state << 24) | + ((uint32_t) ndlp->nlp_xri << 16) | + ((uint32_t) ndlp->nlp_type << 8) | + ((uint32_t) ndlp->nlp_rpi & 0xff)); + /* LOG change to PLOGI */ + /* FIND node DID plogi */ + lpfc_printf_log(phba, KERN_INFO, LOG_NODE, + "%d:0908 FIND node DID plogi " + "Data: x%p x%x x%x x%x\n", + phba->brd_no, + ndlp, ndlp->nlp_DID, + ndlp->nlp_flag, data1); + spin_unlock_irq(phba->host->host_lock); + return ndlp; + } + } + } + + if (order & NLP_SEARCH_ADISC) { + list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_adisc_list, + nlp_listp) { + if (lpfc_matchdid(phba, ndlp, did)) { + + data1 = (((uint32_t) ndlp->nlp_state << 24) | + ((uint32_t) ndlp->nlp_xri << 16) | + ((uint32_t) ndlp->nlp_type << 8) | + ((uint32_t) ndlp->nlp_rpi & 0xff)); + /* LOG change to ADISC */ + /* FIND node DID adisc */ + lpfc_printf_log(phba, KERN_INFO, LOG_NODE, + "%d:0931 FIND node DID adisc " + "Data: x%p x%x x%x x%x\n", + phba->brd_no, + ndlp, ndlp->nlp_DID, + ndlp->nlp_flag, data1); + spin_unlock_irq(phba->host->host_lock); + return ndlp; + } + } + } + + if (order & NLP_SEARCH_REGLOGIN) { + list_for_each_entry_safe(ndlp, next_ndlp, + &phba->fc_reglogin_list, nlp_listp) { + if (lpfc_matchdid(phba, ndlp, did)) { + + data1 = (((uint32_t) ndlp->nlp_state << 24) | + ((uint32_t) ndlp->nlp_xri << 16) | + ((uint32_t) ndlp->nlp_type << 8) | + ((uint32_t) ndlp->nlp_rpi & 0xff)); + /* LOG change to REGLOGIN */ + /* FIND node DID reglogin */ + lpfc_printf_log(phba, KERN_INFO, LOG_NODE, + "%d:0901 FIND node DID reglogin" + " Data: x%p x%x x%x x%x\n", + phba->brd_no, + ndlp, ndlp->nlp_DID, + ndlp->nlp_flag, data1); + spin_unlock_irq(phba->host->host_lock); + return ndlp; + } + } + } + + if (order & NLP_SEARCH_PRLI) { + list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_prli_list, + nlp_listp) { + if (lpfc_matchdid(phba, ndlp, did)) { + + data1 = (((uint32_t) ndlp->nlp_state << 24) | + ((uint32_t) ndlp->nlp_xri << 16) | + ((uint32_t) ndlp->nlp_type << 8) | + ((uint32_t) ndlp->nlp_rpi & 0xff)); + /* LOG change to PRLI */ + /* FIND node DID prli */ + lpfc_printf_log(phba, KERN_INFO, LOG_NODE, + "%d:0902 FIND node DID prli " + "Data: x%p x%x x%x x%x\n", + phba->brd_no, + ndlp, ndlp->nlp_DID, + ndlp->nlp_flag, data1); + spin_unlock_irq(phba->host->host_lock); + return ndlp; + } + } + } + + if (order & NLP_SEARCH_NPR) { + list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_npr_list, + nlp_listp) { + if (lpfc_matchdid(phba, ndlp, did)) { + + data1 = (((uint32_t) ndlp->nlp_state << 24) | + ((uint32_t) ndlp->nlp_xri << 16) | + ((uint32_t) ndlp->nlp_type << 8) | + ((uint32_t) ndlp->nlp_rpi & 0xff)); + /* LOG change to NPR */ + /* FIND node DID npr */ + lpfc_printf_log(phba, KERN_INFO, LOG_NODE, + "%d:0903 FIND node DID npr " + "Data: x%p x%x x%x x%x\n", + phba->brd_no, + ndlp, ndlp->nlp_DID, + ndlp->nlp_flag, data1); + spin_unlock_irq(phba->host->host_lock); + return ndlp; + } + } + } + + if (order & NLP_SEARCH_UNUSED) { + list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_adisc_list, + nlp_listp) { + if (lpfc_matchdid(phba, ndlp, did)) { + + data1 = (((uint32_t) ndlp->nlp_state << 24) | + ((uint32_t) ndlp->nlp_xri << 16) | + ((uint32_t) ndlp->nlp_type << 8) | + ((uint32_t) ndlp->nlp_rpi & 0xff)); + /* LOG change to UNUSED */ + /* FIND node DID unused */ + lpfc_printf_log(phba, KERN_INFO, LOG_NODE, + "%d:0905 FIND node DID unused " + "Data: x%p x%x x%x x%x\n", + phba->brd_no, + ndlp, ndlp->nlp_DID, + ndlp->nlp_flag, data1); + spin_unlock_irq(phba->host->host_lock); + return ndlp; + } + } + } + spin_unlock_irq(phba->host->host_lock); /* FIND node did NOT FOUND */ - lpfc_printf_log(phba, KERN_INFO, LOG_NODE, + lpfc_printf_log(phba, + KERN_INFO, + LOG_NODE, "%d:0932 FIND node did x%x NOT FOUND Data: x%x\n", phba->brd_no, did, order); + + /* no match found */ return NULL; } @@ -1905,7 +2036,7 @@ lpfc_disc_start(struct lpfc_hba * phba) if (rc == MBX_NOT_FINISHED) { mempool_free( mbox, phba->mbox_mem_pool); lpfc_disc_flush_list(phba); - psli->ring[(psli->extra_ring)].flag &= + psli->ring[(psli->ip_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; psli->ring[(psli->fcp_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; @@ -2284,7 +2415,7 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba) if (clrlaerr) { lpfc_disc_flush_list(phba); - psli->ring[(psli->extra_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; + psli->ring[(psli->ip_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; psli->ring[(psli->fcp_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; psli->ring[(psli->next_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; phba->hba_state = LPFC_HBA_READY; diff --git a/trunk/drivers/scsi/lpfc/lpfc_hw.h b/trunk/drivers/scsi/lpfc/lpfc_hw.h index f79cb6136906..eedf98801366 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_hw.h +++ b/trunk/drivers/scsi/lpfc/lpfc_hw.h @@ -42,14 +42,14 @@ #define FCELSSIZE 1024 /* maximum ELS transfer size */ #define LPFC_FCP_RING 0 /* ring 0 for FCP initiator commands */ -#define LPFC_EXTRA_RING 1 /* ring 1 for other protocols */ +#define LPFC_IP_RING 1 /* ring 1 for IP commands */ #define LPFC_ELS_RING 2 /* ring 2 for ELS commands */ #define LPFC_FCP_NEXT_RING 3 #define SLI2_IOCB_CMD_R0_ENTRIES 172 /* SLI-2 FCP command ring entries */ #define SLI2_IOCB_RSP_R0_ENTRIES 134 /* SLI-2 FCP response ring entries */ -#define SLI2_IOCB_CMD_R1_ENTRIES 4 /* SLI-2 extra command ring entries */ -#define SLI2_IOCB_RSP_R1_ENTRIES 4 /* SLI-2 extra response ring entries */ +#define SLI2_IOCB_CMD_R1_ENTRIES 4 /* SLI-2 IP command ring entries */ +#define SLI2_IOCB_RSP_R1_ENTRIES 4 /* SLI-2 IP response ring entries */ #define SLI2_IOCB_CMD_R1XTRA_ENTRIES 36 /* SLI-2 extra FCP cmd ring entries */ #define SLI2_IOCB_RSP_R1XTRA_ENTRIES 52 /* SLI-2 extra FCP rsp ring entries */ #define SLI2_IOCB_CMD_R2_ENTRIES 20 /* SLI-2 ELS command ring entries */ @@ -121,20 +121,6 @@ struct lpfc_sli_ct_request { uint32_t rsvd[7]; } rft; - struct rff { - uint32_t PortId; - uint8_t reserved[2]; -#ifdef __BIG_ENDIAN_BITFIELD - uint8_t feature_res:6; - uint8_t feature_init:1; - uint8_t feature_tgt:1; -#else /* __LITTLE_ENDIAN_BITFIELD */ - uint8_t feature_tgt:1; - uint8_t feature_init:1; - uint8_t feature_res:6; -#endif - uint8_t type_code; /* type=8 for FCP */ - } rff; struct rnn { uint32_t PortId; /* For RNN_ID requests */ uint8_t wwnn[8]; @@ -150,7 +136,6 @@ struct lpfc_sli_ct_request { #define SLI_CT_REVISION 1 #define GID_REQUEST_SZ (sizeof(struct lpfc_sli_ct_request) - 260) #define RFT_REQUEST_SZ (sizeof(struct lpfc_sli_ct_request) - 228) -#define RFF_REQUEST_SZ (sizeof(struct lpfc_sli_ct_request) - 235) #define RNN_REQUEST_SZ (sizeof(struct lpfc_sli_ct_request) - 252) #define RSNN_REQUEST_SZ (sizeof(struct lpfc_sli_ct_request)) @@ -240,7 +225,6 @@ struct lpfc_sli_ct_request { #define SLI_CTNS_RNN_ID 0x0213 #define SLI_CTNS_RCS_ID 0x0214 #define SLI_CTNS_RFT_ID 0x0217 -#define SLI_CTNS_RFF_ID 0x021F #define SLI_CTNS_RSPN_ID 0x0218 #define SLI_CTNS_RPT_ID 0x021A #define SLI_CTNS_RIP_NN 0x0235 @@ -1105,6 +1089,12 @@ typedef struct { #define PCI_DEVICE_ID_ZEPHYR_SCSP 0xfe11 #define PCI_DEVICE_ID_ZEPHYR_DCSP 0xfe12 +#define PCI_SUBSYSTEM_ID_LP11000S 0xfc11 +#define PCI_SUBSYSTEM_ID_LP11002S 0xfc12 +#define PCI_SUBSYSTEM_ID_LPE11000S 0xfc21 +#define PCI_SUBSYSTEM_ID_LPE11002S 0xfc22 +#define PCI_SUBSYSTEM_ID_LPE11010S 0xfc2A + #define JEDEC_ID_ADDRESS 0x0080001c #define FIREFLY_JEDEC_ID 0x1ACC #define SUPERFLY_JEDEC_ID 0x0020 @@ -1294,10 +1284,6 @@ typedef struct { /* FireFly BIU registers */ #define CMD_FCP_IREAD_CX 0x1B #define CMD_FCP_ICMND_CR 0x1C #define CMD_FCP_ICMND_CX 0x1D -#define CMD_FCP_TSEND_CX 0x1F -#define CMD_FCP_TRECEIVE_CX 0x21 -#define CMD_FCP_TRSP_CX 0x23 -#define CMD_FCP_AUTO_TRSP_CX 0x29 #define CMD_ADAPTER_MSG 0x20 #define CMD_ADAPTER_DUMP 0x22 @@ -1324,9 +1310,6 @@ typedef struct { /* FireFly BIU registers */ #define CMD_FCP_IREAD64_CX 0x9B #define CMD_FCP_ICMND64_CR 0x9C #define CMD_FCP_ICMND64_CX 0x9D -#define CMD_FCP_TSEND64_CX 0x9F -#define CMD_FCP_TRECEIVE64_CX 0xA1 -#define CMD_FCP_TRSP64_CX 0xA3 #define CMD_GEN_REQUEST64_CR 0xC2 #define CMD_GEN_REQUEST64_CX 0xC3 diff --git a/trunk/drivers/scsi/lpfc/lpfc_init.c b/trunk/drivers/scsi/lpfc/lpfc_init.c index afca45cdbcef..a5723ad0a099 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_init.c +++ b/trunk/drivers/scsi/lpfc/lpfc_init.c @@ -268,8 +268,6 @@ lpfc_config_port_post(struct lpfc_hba * phba) kfree(mp); pmb->context1 = NULL; - if (phba->cfg_soft_wwnn) - u64_to_wwn(phba->cfg_soft_wwnn, phba->fc_sparam.nodeName.u.wwn); if (phba->cfg_soft_wwpn) u64_to_wwn(phba->cfg_soft_wwpn, phba->fc_sparam.portName.u.wwn); memcpy(&phba->fc_nodename, &phba->fc_sparam.nodeName, @@ -351,8 +349,8 @@ lpfc_config_port_post(struct lpfc_hba * phba) phba->hba_state = LPFC_LINK_DOWN; /* Only process IOCBs on ring 0 till hba_state is READY */ - if (psli->ring[psli->extra_ring].cmdringaddr) - psli->ring[psli->extra_ring].flag |= LPFC_STOP_IOCB_EVENT; + if (psli->ring[psli->ip_ring].cmdringaddr) + psli->ring[psli->ip_ring].flag |= LPFC_STOP_IOCB_EVENT; if (psli->ring[psli->fcp_ring].cmdringaddr) psli->ring[psli->fcp_ring].flag |= LPFC_STOP_IOCB_EVENT; if (psli->ring[psli->next_ring].cmdringaddr) @@ -519,8 +517,7 @@ lpfc_handle_eratt(struct lpfc_hba * phba) struct lpfc_sli_ring *pring; uint32_t event_data; - if (phba->work_hs & HS_FFER6 || - phba->work_hs & HS_FFER5) { + if (phba->work_hs & HS_FFER6) { /* Re-establishing Link */ lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT, "%d:1301 Re-establishing Link " @@ -614,7 +611,7 @@ lpfc_handle_latt(struct lpfc_hba * phba) pmb->mbox_cmpl = lpfc_mbx_cmpl_read_la; rc = lpfc_sli_issue_mbox (phba, pmb, (MBX_NOWAIT | MBX_STOP_IOCB)); if (rc == MBX_NOT_FINISHED) - goto lpfc_handle_latt_free_mbuf; + goto lpfc_handle_latt_free_mp; /* Clear Link Attention in HA REG */ spin_lock_irq(phba->host->host_lock); @@ -624,8 +621,6 @@ lpfc_handle_latt(struct lpfc_hba * phba) return; -lpfc_handle_latt_free_mbuf: - lpfc_mbuf_free(phba, mp->virt, mp->phys); lpfc_handle_latt_free_mp: kfree(mp); lpfc_handle_latt_free_pmb: @@ -807,13 +802,19 @@ lpfc_get_hba_model_desc(struct lpfc_hba * phba, uint8_t * mdp, uint8_t * descp) { lpfc_vpd_t *vp; uint16_t dev_id = phba->pcidev->device; + uint16_t dev_subid = phba->pcidev->subsystem_device; + uint8_t hdrtype; int max_speed; + char * ports; struct { char * name; int max_speed; + char * ports; char * bus; - } m = {"", 0, ""}; + } m = {"", 0, "", ""}; + pci_read_config_byte(phba->pcidev, PCI_HEADER_TYPE, &hdrtype); + ports = (hdrtype == 0x80) ? "2-port " : ""; if (mdp && mdp[0] != '\0' && descp && descp[0] != '\0') return; @@ -833,93 +834,130 @@ lpfc_get_hba_model_desc(struct lpfc_hba * phba, uint8_t * mdp, uint8_t * descp) switch (dev_id) { case PCI_DEVICE_ID_FIREFLY: - m = (typeof(m)){"LP6000", max_speed, "PCI"}; + m = (typeof(m)){"LP6000", max_speed, "", "PCI"}; break; case PCI_DEVICE_ID_SUPERFLY: if (vp->rev.biuRev >= 1 && vp->rev.biuRev <= 3) - m = (typeof(m)){"LP7000", max_speed, "PCI"}; + m = (typeof(m)){"LP7000", max_speed, "", "PCI"}; else - m = (typeof(m)){"LP7000E", max_speed, "PCI"}; + m = (typeof(m)){"LP7000E", max_speed, "", "PCI"}; break; case PCI_DEVICE_ID_DRAGONFLY: - m = (typeof(m)){"LP8000", max_speed, "PCI"}; + m = (typeof(m)){"LP8000", max_speed, "", "PCI"}; break; case PCI_DEVICE_ID_CENTAUR: if (FC_JEDEC_ID(vp->rev.biuRev) == CENTAUR_2G_JEDEC_ID) - m = (typeof(m)){"LP9002", max_speed, "PCI"}; + m = (typeof(m)){"LP9002", max_speed, "", "PCI"}; else - m = (typeof(m)){"LP9000", max_speed, "PCI"}; + m = (typeof(m)){"LP9000", max_speed, "", "PCI"}; break; case PCI_DEVICE_ID_RFLY: - m = (typeof(m)){"LP952", max_speed, "PCI"}; + m = (typeof(m)){"LP952", max_speed, "", "PCI"}; break; case PCI_DEVICE_ID_PEGASUS: - m = (typeof(m)){"LP9802", max_speed, "PCI-X"}; + m = (typeof(m)){"LP9802", max_speed, "", "PCI-X"}; break; case PCI_DEVICE_ID_THOR: - m = (typeof(m)){"LP10000", max_speed, "PCI-X"}; + if (hdrtype == 0x80) + m = (typeof(m)){"LP10000DC", + max_speed, ports, "PCI-X"}; + else + m = (typeof(m)){"LP10000", + max_speed, ports, "PCI-X"}; break; case PCI_DEVICE_ID_VIPER: - m = (typeof(m)){"LPX1000", max_speed, "PCI-X"}; + m = (typeof(m)){"LPX1000", max_speed, "", "PCI-X"}; break; case PCI_DEVICE_ID_PFLY: - m = (typeof(m)){"LP982", max_speed, "PCI-X"}; + m = (typeof(m)){"LP982", max_speed, "", "PCI-X"}; break; case PCI_DEVICE_ID_TFLY: - m = (typeof(m)){"LP1050", max_speed, "PCI-X"}; + if (hdrtype == 0x80) + m = (typeof(m)){"LP1050DC", max_speed, ports, "PCI-X"}; + else + m = (typeof(m)){"LP1050", max_speed, ports, "PCI-X"}; break; case PCI_DEVICE_ID_HELIOS: - m = (typeof(m)){"LP11000", max_speed, "PCI-X2"}; + if (hdrtype == 0x80) + m = (typeof(m)){"LP11002", max_speed, ports, "PCI-X2"}; + else + m = (typeof(m)){"LP11000", max_speed, ports, "PCI-X2"}; break; case PCI_DEVICE_ID_HELIOS_SCSP: - m = (typeof(m)){"LP11000-SP", max_speed, "PCI-X2"}; + m = (typeof(m)){"LP11000-SP", max_speed, ports, "PCI-X2"}; break; case PCI_DEVICE_ID_HELIOS_DCSP: - m = (typeof(m)){"LP11002-SP", max_speed, "PCI-X2"}; + m = (typeof(m)){"LP11002-SP", max_speed, ports, "PCI-X2"}; break; case PCI_DEVICE_ID_NEPTUNE: - m = (typeof(m)){"LPe1000", max_speed, "PCIe"}; + if (hdrtype == 0x80) + m = (typeof(m)){"LPe1002", max_speed, ports, "PCIe"}; + else + m = (typeof(m)){"LPe1000", max_speed, ports, "PCIe"}; break; case PCI_DEVICE_ID_NEPTUNE_SCSP: - m = (typeof(m)){"LPe1000-SP", max_speed, "PCIe"}; + m = (typeof(m)){"LPe1000-SP", max_speed, ports, "PCIe"}; break; case PCI_DEVICE_ID_NEPTUNE_DCSP: - m = (typeof(m)){"LPe1002-SP", max_speed, "PCIe"}; + m = (typeof(m)){"LPe1002-SP", max_speed, ports, "PCIe"}; break; case PCI_DEVICE_ID_BMID: - m = (typeof(m)){"LP1150", max_speed, "PCI-X2"}; + m = (typeof(m)){"LP1150", max_speed, ports, "PCI-X2"}; break; case PCI_DEVICE_ID_BSMB: - m = (typeof(m)){"LP111", max_speed, "PCI-X2"}; + m = (typeof(m)){"LP111", max_speed, ports, "PCI-X2"}; break; case PCI_DEVICE_ID_ZEPHYR: - m = (typeof(m)){"LPe11000", max_speed, "PCIe"}; + if (hdrtype == 0x80) + m = (typeof(m)){"LPe11002", max_speed, ports, "PCIe"}; + else + m = (typeof(m)){"LPe11000", max_speed, ports, "PCIe"}; break; case PCI_DEVICE_ID_ZEPHYR_SCSP: - m = (typeof(m)){"LPe11000", max_speed, "PCIe"}; + m = (typeof(m)){"LPe11000", max_speed, ports, "PCIe"}; break; case PCI_DEVICE_ID_ZEPHYR_DCSP: - m = (typeof(m)){"LPe11002-SP", max_speed, "PCIe"}; + m = (typeof(m)){"LPe11002-SP", max_speed, ports, "PCIe"}; break; case PCI_DEVICE_ID_ZMID: - m = (typeof(m)){"LPe1150", max_speed, "PCIe"}; + m = (typeof(m)){"LPe1150", max_speed, ports, "PCIe"}; break; case PCI_DEVICE_ID_ZSMB: - m = (typeof(m)){"LPe111", max_speed, "PCIe"}; + m = (typeof(m)){"LPe111", max_speed, ports, "PCIe"}; break; case PCI_DEVICE_ID_LP101: - m = (typeof(m)){"LP101", max_speed, "PCI-X"}; + m = (typeof(m)){"LP101", max_speed, ports, "PCI-X"}; break; case PCI_DEVICE_ID_LP10000S: - m = (typeof(m)){"LP10000-S", max_speed, "PCI"}; + m = (typeof(m)){"LP10000-S", max_speed, ports, "PCI"}; break; case PCI_DEVICE_ID_LP11000S: - m = (typeof(m)){"LP11000-S", max_speed, - "PCI-X2"}; - break; case PCI_DEVICE_ID_LPE11000S: - m = (typeof(m)){"LPe11000-S", max_speed, - "PCIe"}; + switch (dev_subid) { + case PCI_SUBSYSTEM_ID_LP11000S: + m = (typeof(m)){"LP11000-S", max_speed, + ports, "PCI-X2"}; + break; + case PCI_SUBSYSTEM_ID_LP11002S: + m = (typeof(m)){"LP11002-S", max_speed, + ports, "PCI-X2"}; + break; + case PCI_SUBSYSTEM_ID_LPE11000S: + m = (typeof(m)){"LPe11000-S", max_speed, + ports, "PCIe"}; + break; + case PCI_SUBSYSTEM_ID_LPE11002S: + m = (typeof(m)){"LPe11002-S", max_speed, + ports, "PCIe"}; + break; + case PCI_SUBSYSTEM_ID_LPE11010S: + m = (typeof(m)){"LPe11010-S", max_speed, + "10-port ", "PCIe"}; + break; + default: + m = (typeof(m)){ NULL }; + break; + } break; default: m = (typeof(m)){ NULL }; @@ -930,8 +968,8 @@ lpfc_get_hba_model_desc(struct lpfc_hba * phba, uint8_t * mdp, uint8_t * descp) snprintf(mdp, 79,"%s", m.name); if (descp && descp[0] == '\0') snprintf(descp, 255, - "Emulex %s %dGb %s Fibre Channel Adapter", - m.name, m.max_speed, m.bus); + "Emulex %s %dGb %s%s Fibre Channel Adapter", + m.name, m.max_speed, m.ports, m.bus); } /**************************************************/ @@ -1613,14 +1651,6 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) if (error) goto out_remove_host; - if (phba->cfg_use_msi) { - error = pci_enable_msi(phba->pcidev); - if (error) - lpfc_printf_log(phba, KERN_INFO, LOG_INIT, "%d:0452 " - "Enable MSI failed, continuing with " - "IRQ\n", phba->brd_no); - } - error = request_irq(phba->pcidev->irq, lpfc_intr_handler, IRQF_SHARED, LPFC_DRIVER_NAME, phba); if (error) { @@ -1700,7 +1730,6 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) lpfc_stop_timer(phba); phba->work_hba_events = 0; free_irq(phba->pcidev->irq, phba); - pci_disable_msi(phba->pcidev); out_free_sysfs_attr: lpfc_free_sysfs_attr(phba); out_remove_host: @@ -1767,7 +1796,6 @@ lpfc_pci_remove_one(struct pci_dev *pdev) /* Release the irq reservation */ free_irq(phba->pcidev->irq, phba); - pci_disable_msi(phba->pcidev); lpfc_cleanup(phba, 0); lpfc_stop_timer(phba); diff --git a/trunk/drivers/scsi/lpfc/lpfc_logmsg.h b/trunk/drivers/scsi/lpfc/lpfc_logmsg.h index 438cbcd9eb13..62c8ca862e9e 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_logmsg.h +++ b/trunk/drivers/scsi/lpfc/lpfc_logmsg.h @@ -28,7 +28,7 @@ #define LOG_NODE 0x80 /* Node table events */ #define LOG_MISC 0x400 /* Miscellaneous events */ #define LOG_SLI 0x800 /* SLI events */ -#define LOG_FCP_ERROR 0x1000 /* log errors, not underruns */ +#define LOG_CHK_COND 0x1000 /* FCP Check condition flag */ #define LOG_LIBDFC 0x2000 /* Libdfc events */ #define LOG_ALL_MSG 0xffff /* LOG all messages */ diff --git a/trunk/drivers/scsi/lpfc/lpfc_nportdisc.c b/trunk/drivers/scsi/lpfc/lpfc_nportdisc.c index 0c7e731dc45a..d5f415007db2 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/trunk/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -739,7 +739,7 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba, uint32_t evt) { struct lpfc_iocbq *cmdiocb, *rspiocb; - struct lpfc_dmabuf *pcmd, *prsp, *mp; + struct lpfc_dmabuf *pcmd, *prsp; uint32_t *lp; IOCB_t *irsp; struct serv_parm *sp; @@ -829,9 +829,6 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba, NLP_REGLOGIN_LIST); return ndlp->nlp_state; } - mp = (struct lpfc_dmabuf *)mbox->context1; - lpfc_mbuf_free(phba, mp->virt, mp->phys); - kfree(mp); mempool_free(mbox, phba->mbox_mem_pool); } else { mempool_free(mbox, phba->mbox_mem_pool); @@ -1623,8 +1620,8 @@ lpfc_rcv_padisc_npr_node(struct lpfc_hba * phba, * or discovery in progress for this node. Starting discovery * here will affect the counting of discovery threads. */ - if (!(ndlp->nlp_flag & NLP_DELAY_TMO) && - !(ndlp->nlp_flag & NLP_NPR_2B_DISC)){ + if ((!(ndlp->nlp_flag & NLP_DELAY_TMO)) && + (ndlp->nlp_flag & NLP_NPR_2B_DISC)){ if (ndlp->nlp_flag & NLP_NPR_ADISC) { ndlp->nlp_prev_state = NLP_STE_NPR_NODE; ndlp->nlp_state = NLP_STE_ADISC_ISSUE; diff --git a/trunk/drivers/scsi/lpfc/lpfc_scsi.c b/trunk/drivers/scsi/lpfc/lpfc_scsi.c index c3e68e0d8f74..97ae98dc95d0 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_scsi.c +++ b/trunk/drivers/scsi/lpfc/lpfc_scsi.c @@ -297,10 +297,8 @@ lpfc_handle_fcp_err(struct lpfc_scsi_buf *lpfc_cmd) uint32_t fcpi_parm = lpfc_cmd->cur_iocbq.iocb.un.fcpi.fcpi_parm; uint32_t resp_info = fcprsp->rspStatus2; uint32_t scsi_status = fcprsp->rspStatus3; - uint32_t *lp; uint32_t host_status = DID_OK; uint32_t rsplen = 0; - uint32_t logit = LOG_FCP | LOG_FCP_ERROR; /* * If this is a task management command, there is no @@ -312,25 +310,10 @@ lpfc_handle_fcp_err(struct lpfc_scsi_buf *lpfc_cmd) goto out; } - if ((resp_info & SNS_LEN_VALID) && fcprsp->rspSnsLen) { - uint32_t snslen = be32_to_cpu(fcprsp->rspSnsLen); - if (snslen > SCSI_SENSE_BUFFERSIZE) - snslen = SCSI_SENSE_BUFFERSIZE; - - if (resp_info & RSP_LEN_VALID) - rsplen = be32_to_cpu(fcprsp->rspRspLen); - memcpy(cmnd->sense_buffer, &fcprsp->rspInfo0 + rsplen, snslen); - } - lp = (uint32_t *)cmnd->sense_buffer; - - if (!scsi_status && (resp_info & RESID_UNDER)) - logit = LOG_FCP; - - lpfc_printf_log(phba, KERN_WARNING, logit, - "%d:0730 FCP command x%x failed: x%x SNS x%x x%x " - "Data: x%x x%x x%x x%x x%x\n", - phba->brd_no, cmnd->cmnd[0], scsi_status, - be32_to_cpu(*lp), be32_to_cpu(*(lp + 3)), resp_info, + lpfc_printf_log(phba, KERN_WARNING, LOG_FCP, + "%d:0730 FCP command failed: RSP " + "Data: x%x x%x x%x x%x x%x x%x\n", + phba->brd_no, resp_info, scsi_status, be32_to_cpu(fcprsp->rspResId), be32_to_cpu(fcprsp->rspSnsLen), be32_to_cpu(fcprsp->rspRspLen), @@ -345,6 +328,14 @@ lpfc_handle_fcp_err(struct lpfc_scsi_buf *lpfc_cmd) } } + if ((resp_info & SNS_LEN_VALID) && fcprsp->rspSnsLen) { + uint32_t snslen = be32_to_cpu(fcprsp->rspSnsLen); + if (snslen > SCSI_SENSE_BUFFERSIZE) + snslen = SCSI_SENSE_BUFFERSIZE; + + memcpy(cmnd->sense_buffer, &fcprsp->rspInfo0 + rsplen, snslen); + } + cmnd->resid = 0; if (resp_info & RESID_UNDER) { cmnd->resid = be32_to_cpu(fcprsp->rspResId); @@ -387,7 +378,7 @@ lpfc_handle_fcp_err(struct lpfc_scsi_buf *lpfc_cmd) */ } else if ((scsi_status == SAM_STAT_GOOD) && fcpi_parm && (cmnd->sc_data_direction == DMA_FROM_DEVICE)) { - lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_FCP_ERROR, + lpfc_printf_log(phba, KERN_WARNING, LOG_FCP, "%d:0734 FCP Read Check Error Data: " "x%x x%x x%x x%x\n", phba->brd_no, be32_to_cpu(fcpcmd->fcpDl), @@ -679,9 +670,6 @@ lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba, struct lpfc_iocbq *iocbqrsp; int ret; - if (!rdata->pnode) - return FAILED; - lpfc_cmd->rdata = rdata; ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, lun, FCP_TARGET_RESET); @@ -988,34 +976,20 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) lpfc_block_error_handler(cmnd); spin_lock_irq(shost->host_lock); - loopcnt = 0; /* * If target is not in a MAPPED state, delay the reset until * target is rediscovered or devloss timeout expires. */ while ( 1 ) { if (!pnode) - return FAILED; + break; if (pnode->nlp_state != NLP_STE_MAPPED_NODE) { spin_unlock_irq(phba->host->host_lock); schedule_timeout_uninterruptible(msecs_to_jiffies(500)); spin_lock_irq(phba->host->host_lock); - loopcnt++; - rdata = cmnd->device->hostdata; - if (!rdata || - (loopcnt > ((phba->cfg_devloss_tmo * 2) + 1))) { - lpfc_printf_log(phba, KERN_ERR, LOG_FCP, - "%d:0721 LUN Reset rport failure:" - " cnt x%x rdata x%p\n", - phba->brd_no, loopcnt, rdata); - goto out; - } - pnode = rdata->pnode; - if (!pnode) - return FAILED; } - if (pnode->nlp_state == NLP_STE_MAPPED_NODE) + if ((pnode) && (pnode->nlp_state == NLP_STE_MAPPED_NODE)) break; } diff --git a/trunk/drivers/scsi/lpfc/lpfc_sli.c b/trunk/drivers/scsi/lpfc/lpfc_sli.c index a4128e19338a..582f5ea4e84e 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_sli.c +++ b/trunk/drivers/scsi/lpfc/lpfc_sli.c @@ -117,10 +117,6 @@ lpfc_sli_iocb_cmd_type(uint8_t iocb_cmnd) case CMD_FCP_IREAD_CX: case CMD_FCP_ICMND_CR: case CMD_FCP_ICMND_CX: - case CMD_FCP_TSEND_CX: - case CMD_FCP_TRSP_CX: - case CMD_FCP_TRECEIVE_CX: - case CMD_FCP_AUTO_TRSP_CX: case CMD_ADAPTER_MSG: case CMD_ADAPTER_DUMP: case CMD_XMIT_SEQUENCE64_CR: @@ -135,9 +131,6 @@ lpfc_sli_iocb_cmd_type(uint8_t iocb_cmnd) case CMD_FCP_IREAD64_CX: case CMD_FCP_ICMND64_CR: case CMD_FCP_ICMND64_CX: - case CMD_FCP_TSEND64_CX: - case CMD_FCP_TRSP64_CX: - case CMD_FCP_TRECEIVE64_CX: case CMD_GEN_REQUEST64_CR: case CMD_GEN_REQUEST64_CX: case CMD_XMIT_ELS_RSP64_CX: @@ -1105,7 +1098,6 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba * phba, lpfc_sli_pcimem_bcopy((uint32_t *) entry, (uint32_t *) &rspiocbq.iocb, sizeof (IOCB_t)); - INIT_LIST_HEAD(&(rspiocbq.list)); irsp = &rspiocbq.iocb; type = lpfc_sli_iocb_cmd_type(irsp->ulpCommand & CMD_IOCB_MASK); @@ -1157,11 +1149,6 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba * phba, } } break; - case LPFC_UNSOL_IOCB: - spin_unlock_irqrestore(phba->host->host_lock, iflag); - lpfc_sli_process_unsol_iocb(phba, pring, &rspiocbq); - spin_lock_irqsave(phba->host->host_lock, iflag); - break; default: if (irsp->ulpCommand == CMD_ADAPTER_MSG) { char adaptermsg[LPFC_MAX_ADPTMSG]; @@ -2485,17 +2472,13 @@ lpfc_extra_ring_setup( struct lpfc_hba *phba) psli = &phba->sli; /* Adjust cmd/rsp ring iocb entries more evenly */ - - /* Take some away from the FCP ring */ pring = &psli->ring[psli->fcp_ring]; pring->numCiocb -= SLI2_IOCB_CMD_R1XTRA_ENTRIES; pring->numRiocb -= SLI2_IOCB_RSP_R1XTRA_ENTRIES; pring->numCiocb -= SLI2_IOCB_CMD_R3XTRA_ENTRIES; pring->numRiocb -= SLI2_IOCB_RSP_R3XTRA_ENTRIES; - /* and give them to the extra ring */ - pring = &psli->ring[psli->extra_ring]; - + pring = &psli->ring[1]; pring->numCiocb += SLI2_IOCB_CMD_R1XTRA_ENTRIES; pring->numRiocb += SLI2_IOCB_RSP_R1XTRA_ENTRIES; pring->numCiocb += SLI2_IOCB_CMD_R3XTRA_ENTRIES; @@ -2505,8 +2488,8 @@ lpfc_extra_ring_setup( struct lpfc_hba *phba) pring->iotag_max = 4096; pring->num_mask = 1; pring->prt[0].profile = 0; /* Mask 0 */ - pring->prt[0].rctl = phba->cfg_multi_ring_rctl; - pring->prt[0].type = phba->cfg_multi_ring_type; + pring->prt[0].rctl = FC_UNSOL_DATA; + pring->prt[0].type = 5; pring->prt[0].lpfc_sli_rcv_unsol_event = NULL; return 0; } @@ -2522,7 +2505,7 @@ lpfc_sli_setup(struct lpfc_hba *phba) psli->sli_flag = 0; psli->fcp_ring = LPFC_FCP_RING; psli->next_ring = LPFC_FCP_NEXT_RING; - psli->extra_ring = LPFC_EXTRA_RING; + psli->ip_ring = LPFC_IP_RING; psli->iocbq_lookup = NULL; psli->iocbq_lookup_len = 0; @@ -2545,7 +2528,7 @@ lpfc_sli_setup(struct lpfc_hba *phba) pring->fast_iotag = pring->iotag_max; pring->num_mask = 0; break; - case LPFC_EXTRA_RING: /* ring 1 - EXTRA */ + case LPFC_IP_RING: /* ring 1 - IP */ /* numCiocb and numRiocb are used in config_port */ pring->numCiocb = SLI2_IOCB_CMD_R1_ENTRIES; pring->numRiocb = SLI2_IOCB_RSP_R1_ENTRIES; @@ -3255,21 +3238,6 @@ lpfc_intr_handler(int irq, void *dev_id) lpfc_sli_handle_fast_ring_event(phba, &phba->sli.ring[LPFC_FCP_RING], status); - - if (phba->cfg_multi_ring_support == 2) { - /* - * Process all events on extra ring. Take the optimized path - * for extra ring IO. Any other IO is slow path and is handled - * by the worker thread. - */ - status = (ha_copy & (HA_RXMASK << (4*LPFC_EXTRA_RING))); - status >>= (4*LPFC_EXTRA_RING); - if (status & HA_RXATT) { - lpfc_sli_handle_fast_ring_event(phba, - &phba->sli.ring[LPFC_EXTRA_RING], - status); - } - } return IRQ_HANDLED; } /* lpfc_intr_handler */ diff --git a/trunk/drivers/scsi/lpfc/lpfc_sli.h b/trunk/drivers/scsi/lpfc/lpfc_sli.h index a43549959dc7..e26de6809358 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_sli.h +++ b/trunk/drivers/scsi/lpfc/lpfc_sli.h @@ -198,7 +198,7 @@ struct lpfc_sli { int fcp_ring; /* ring used for FCP initiator commands */ int next_ring; - int extra_ring; /* extra ring used for other protocols */ + int ip_ring; /* ring used for IP network drv cmds */ struct lpfc_sli_stat slistat; /* SLI statistical info */ struct list_head mboxq; diff --git a/trunk/drivers/scsi/lpfc/lpfc_version.h b/trunk/drivers/scsi/lpfc/lpfc_version.h index a61ef3d1e7f1..ac417908b407 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_version.h +++ b/trunk/drivers/scsi/lpfc/lpfc_version.h @@ -18,7 +18,7 @@ * included with this package. * *******************************************************************/ -#define LPFC_DRIVER_VERSION "8.1.11" +#define LPFC_DRIVER_VERSION "8.1.10" #define LPFC_DRIVER_NAME "lpfc" diff --git a/trunk/drivers/scsi/megaraid.c b/trunk/drivers/scsi/megaraid.c index 77d9d3804ccf..86099fde1b2a 100644 --- a/trunk/drivers/scsi/megaraid.c +++ b/trunk/drivers/scsi/megaraid.c @@ -73,10 +73,10 @@ static unsigned short int max_mbox_busy_wait = MBOX_BUSY_WAIT; module_param(max_mbox_busy_wait, ushort, 0); MODULE_PARM_DESC(max_mbox_busy_wait, "Maximum wait for mailbox in microseconds if busy (default=MBOX_BUSY_WAIT=10)"); -#define RDINDOOR(adapter) readl((adapter)->mmio_base + 0x20) -#define RDOUTDOOR(adapter) readl((adapter)->mmio_base + 0x2C) -#define WRINDOOR(adapter,value) writel(value, (adapter)->mmio_base + 0x20) -#define WROUTDOOR(adapter,value) writel(value, (adapter)->mmio_base + 0x2C) +#define RDINDOOR(adapter) readl((adapter)->base + 0x20) +#define RDOUTDOOR(adapter) readl((adapter)->base + 0x2C) +#define WRINDOOR(adapter,value) writel(value, (adapter)->base + 0x20) +#define WROUTDOOR(adapter,value) writel(value, (adapter)->base + 0x2C) /* * Global variables @@ -1386,8 +1386,7 @@ megaraid_isr_memmapped(int irq, void *devp) handled = 1; - while( RDINDOOR(adapter) & 0x02 ) - cpu_relax(); + while( RDINDOOR(adapter) & 0x02 ) cpu_relax(); mega_cmd_done(adapter, completed, nstatus, status); @@ -4669,8 +4668,6 @@ megaraid_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) host->host_no, mega_baseport, irq); adapter->base = mega_baseport; - if (flag & BOARD_MEMMAP) - adapter->mmio_base = (void __iomem *) mega_baseport; INIT_LIST_HEAD(&adapter->free_list); INIT_LIST_HEAD(&adapter->pending_list); diff --git a/trunk/drivers/scsi/megaraid.h b/trunk/drivers/scsi/megaraid.h index c6e74643abe2..66529f11d23c 100644 --- a/trunk/drivers/scsi/megaraid.h +++ b/trunk/drivers/scsi/megaraid.h @@ -801,8 +801,7 @@ typedef struct { clustering is available */ u32 flag; - unsigned long base; - void __iomem *mmio_base; + unsigned long base; /* mbox64 with mbox not aligned on 16-byte boundry */ mbox64_t *una_mbox64; diff --git a/trunk/drivers/scsi/megaraid/megaraid_sas.c b/trunk/drivers/scsi/megaraid/megaraid_sas.c index 046223b4ae57..7e4262f2af96 100644 --- a/trunk/drivers/scsi/megaraid/megaraid_sas.c +++ b/trunk/drivers/scsi/megaraid/megaraid_sas.c @@ -517,7 +517,7 @@ megasas_make_sgl64(struct megasas_instance *instance, struct scsi_cmnd *scp, * Returns the number of frames required for numnber of sge's (sge_count) */ -static u32 megasas_get_frame_count(u8 sge_count) +u32 megasas_get_frame_count(u8 sge_count) { int num_cnt; int sge_bytes; @@ -1733,7 +1733,7 @@ megasas_get_ctrl_info(struct megasas_instance *instance, * * Tasklet to complete cmds */ -static void megasas_complete_cmd_dpc(unsigned long instance_addr) +void megasas_complete_cmd_dpc(unsigned long instance_addr) { u32 producer; u32 consumer; diff --git a/trunk/drivers/scsi/ncr53c8xx.c b/trunk/drivers/scsi/ncr53c8xx.c index bbf521cbc55d..adb8eb4f5fd1 100644 --- a/trunk/drivers/scsi/ncr53c8xx.c +++ b/trunk/drivers/scsi/ncr53c8xx.c @@ -589,12 +589,10 @@ static int __map_scsi_sg_data(struct device *dev, struct scsi_cmnd *cmd) static struct ncr_driver_setup driver_setup = SCSI_NCR_DRIVER_SETUP; -#ifndef MODULE #ifdef SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT static struct ncr_driver_setup driver_safe_setup __initdata = SCSI_NCR_DRIVER_SAFE_SETUP; #endif -#endif /* !MODULE */ #define initverbose (driver_setup.verbose) #define bootverbose (np->verbose) @@ -643,13 +641,6 @@ static struct ncr_driver_setup #define OPT_IARB 26 #endif -#ifdef MODULE -#define ARG_SEP ' ' -#else -#define ARG_SEP ',' -#endif - -#ifndef MODULE static char setup_token[] __initdata = "tags:" "mpar:" "spar:" "disc:" @@ -669,6 +660,12 @@ static char setup_token[] __initdata = #endif ; /* DONNOT REMOVE THIS ';' */ +#ifdef MODULE +#define ARG_SEP ' ' +#else +#define ARG_SEP ',' +#endif + static int __init get_setup_token(char *p) { char *cur = setup_token; @@ -685,6 +682,7 @@ static int __init get_setup_token(char *p) return 0; } + static int __init sym53c8xx__setup(char *str) { #ifdef SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT @@ -806,7 +804,6 @@ static int __init sym53c8xx__setup(char *str) #endif /* SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT */ return 1; } -#endif /* !MODULE */ /*=================================================================== ** @@ -8324,12 +8321,12 @@ char *ncr53c8xx; /* command line passed by insmod */ module_param(ncr53c8xx, charp, 0); #endif -#ifndef MODULE static int __init ncr53c8xx_setup(char *str) { return sym53c8xx__setup(str); } +#ifndef MODULE __setup("ncr53c8xx=", ncr53c8xx_setup); #endif diff --git a/trunk/drivers/scsi/pcmcia/aha152x_stub.c b/trunk/drivers/scsi/pcmcia/aha152x_stub.c index aad362ba02e0..ee449b29fc82 100644 --- a/trunk/drivers/scsi/pcmcia/aha152x_stub.c +++ b/trunk/drivers/scsi/pcmcia/aha152x_stub.c @@ -154,11 +154,16 @@ static int aha152x_config_cs(struct pcmcia_device *link) DEBUG(0, "aha152x_config(0x%p)\n", link); + tuple.DesiredTuple = CISTPL_CONFIG; tuple.TupleData = tuple_data; tuple.TupleDataMax = 64; tuple.TupleOffset = 0; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + link->conf.ConfigBase = parse.config.base; + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - tuple.Attributes = 0; CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); while (1) { if (pcmcia_get_tuple_data(link, &tuple) != 0 || diff --git a/trunk/drivers/scsi/pcmcia/fdomain_stub.c b/trunk/drivers/scsi/pcmcia/fdomain_stub.c index a1c5f265069f..85f7ffac19a0 100644 --- a/trunk/drivers/scsi/pcmcia/fdomain_stub.c +++ b/trunk/drivers/scsi/pcmcia/fdomain_stub.c @@ -136,9 +136,14 @@ static int fdomain_config(struct pcmcia_device *link) DEBUG(0, "fdomain_config(0x%p)\n", link); + tuple.DesiredTuple = CISTPL_CONFIG; tuple.TupleData = tuple_data; tuple.TupleDataMax = 64; tuple.TupleOffset = 0; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + link->conf.ConfigBase = parse.config.base; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); diff --git a/trunk/drivers/scsi/pcmcia/nsp_cs.c b/trunk/drivers/scsi/pcmcia/nsp_cs.c index d72df5dae4ee..f2d79c3f0b8e 100644 --- a/trunk/drivers/scsi/pcmcia/nsp_cs.c +++ b/trunk/drivers/scsi/pcmcia/nsp_cs.c @@ -1685,10 +1685,16 @@ static int nsp_cs_config(struct pcmcia_device *link) nsp_dbg(NSP_DEBUG_INIT, "in"); + tuple.DesiredTuple = CISTPL_CONFIG; tuple.Attributes = 0; tuple.TupleData = tuple_data; tuple.TupleDataMax = sizeof(tuple_data); tuple.TupleOffset = 0; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + link->conf.ConfigBase = parse.config.base; + link->conf.Present = parse.config.rmask[0]; /* Look up the current Vcc */ CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &conf)); diff --git a/trunk/drivers/scsi/pcmcia/qlogic_stub.c b/trunk/drivers/scsi/pcmcia/qlogic_stub.c index 9d431fe7f47f..86c2ac6ae623 100644 --- a/trunk/drivers/scsi/pcmcia/qlogic_stub.c +++ b/trunk/drivers/scsi/pcmcia/qlogic_stub.c @@ -208,11 +208,18 @@ static int qlogic_config(struct pcmcia_device * link) DEBUG(0, "qlogic_config(0x%p)\n", link); - info->manf_id = link->manf_id; - tuple.TupleData = (cisdata_t *) tuple_data; tuple.TupleDataMax = 64; tuple.TupleOffset = 0; + tuple.DesiredTuple = CISTPL_CONFIG; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + link->conf.ConfigBase = parse.config.base; + + tuple.DesiredTuple = CISTPL_MANFID; + if ((pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) && (pcmcia_get_tuple_data(link, &tuple) == CS_SUCCESS)) + info->manf_id = le16_to_cpu(tuple.TupleData[0]); tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); diff --git a/trunk/drivers/scsi/pcmcia/sym53c500_cs.c b/trunk/drivers/scsi/pcmcia/sym53c500_cs.c index fb7acea60286..72fe5d055de1 100644 --- a/trunk/drivers/scsi/pcmcia/sym53c500_cs.c +++ b/trunk/drivers/scsi/pcmcia/sym53c500_cs.c @@ -722,11 +722,19 @@ SYM53C500_config(struct pcmcia_device *link) DEBUG(0, "SYM53C500_config(0x%p)\n", link); - info->manf_id = link->manf_id; - tuple.TupleData = (cisdata_t *)tuple_data; tuple.TupleDataMax = 64; tuple.TupleOffset = 0; + tuple.DesiredTuple = CISTPL_CONFIG; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + link->conf.ConfigBase = parse.config.base; + + tuple.DesiredTuple = CISTPL_MANFID; + if ((pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) && + (pcmcia_get_tuple_data(link, &tuple) == CS_SUCCESS)) + info->manf_id = le16_to_cpu(tuple.TupleData[0]); tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); diff --git a/trunk/drivers/scsi/ppa.c b/trunk/drivers/scsi/ppa.c index 584ba4d6e038..89a2a9f11e41 100644 --- a/trunk/drivers/scsi/ppa.c +++ b/trunk/drivers/scsi/ppa.c @@ -31,7 +31,7 @@ typedef struct { int base; /* Actual port address */ int mode; /* Transfer mode */ struct scsi_cmnd *cur_cmd; /* Current queued command */ - struct delayed_work ppa_tq; /* Polling interrupt stuff */ + struct work_struct ppa_tq; /* Polling interrupt stuff */ unsigned long jstart; /* Jiffies at start */ unsigned long recon_tmo; /* How many usecs to wait for reconnection (6th bit) */ unsigned int failed:1; /* Failure flag */ @@ -627,9 +627,9 @@ static int ppa_completion(struct scsi_cmnd *cmd) * the scheduler's task queue to generate a stream of call-backs and * complete the request when the drive is ready. */ -static void ppa_interrupt(struct work_struct *work) +static void ppa_interrupt(void *data) { - ppa_struct *dev = container_of(work, ppa_struct, ppa_tq.work); + ppa_struct *dev = (ppa_struct *) data; struct scsi_cmnd *cmd = dev->cur_cmd; if (!cmd) { @@ -637,6 +637,7 @@ static void ppa_interrupt(struct work_struct *work) return; } if (ppa_engine(dev, cmd)) { + dev->ppa_tq.data = (void *) dev; schedule_delayed_work(&dev->ppa_tq, 1); return; } @@ -821,7 +822,8 @@ static int ppa_queuecommand(struct scsi_cmnd *cmd, cmd->result = DID_ERROR << 16; /* default return code */ cmd->SCp.phase = 0; /* bus free */ - schedule_delayed_work(&dev->ppa_tq, 0); + dev->ppa_tq.data = dev; + schedule_work(&dev->ppa_tq); ppa_pb_claim(dev); @@ -1084,7 +1086,7 @@ static int __ppa_attach(struct parport *pb) else ports = 8; - INIT_DELAYED_WORK(&dev->ppa_tq, ppa_interrupt); + INIT_WORK(&dev->ppa_tq, ppa_interrupt, dev); err = -ENOMEM; host = scsi_host_alloc(&ppa_template, sizeof(ppa_struct *)); diff --git a/trunk/drivers/scsi/qla2xxx/qla_attr.c b/trunk/drivers/scsi/qla2xxx/qla_attr.c index 7b18a6c7b7eb..285c8e8ff1a0 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_attr.c +++ b/trunk/drivers/scsi/qla2xxx/qla_attr.c @@ -390,7 +390,7 @@ static struct sysfs_entry { { "optrom_ctl", &sysfs_optrom_ctl_attr, }, { "vpd", &sysfs_vpd_attr, 1 }, { "sfp", &sysfs_sfp_attr, 1 }, - { NULL }, + { 0 }, }; void diff --git a/trunk/drivers/scsi/qla2xxx/qla_init.c b/trunk/drivers/scsi/qla2xxx/qla_init.c index a823f0bc519d..08cb5e3fb553 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_init.c +++ b/trunk/drivers/scsi/qla2xxx/qla_init.c @@ -59,6 +59,9 @@ int qla2x00_initialize_adapter(scsi_qla_host_t *ha) { int rval; + uint8_t restart_risc = 0; + uint8_t retry; + uint32_t wait_time; /* Clear adapter flags. */ ha->flags.online = 0; @@ -101,15 +104,87 @@ qla2x00_initialize_adapter(scsi_qla_host_t *ha) qla_printk(KERN_INFO, ha, "Verifying loaded RISC code...\n"); - if (qla2x00_isp_firmware(ha) != QLA_SUCCESS) { - rval = ha->isp_ops.chip_diag(ha); - if (rval) - return (rval); - rval = qla2x00_setup_chip(ha); - if (rval) - return (rval); + retry = 10; + /* + * Try to configure the loop. + */ + do { + restart_risc = 0; + + /* If firmware needs to be loaded */ + if (qla2x00_isp_firmware(ha) != QLA_SUCCESS) { + if ((rval = ha->isp_ops.chip_diag(ha)) == QLA_SUCCESS) { + rval = qla2x00_setup_chip(ha); + } + } + + if (rval == QLA_SUCCESS && + (rval = qla2x00_init_rings(ha)) == QLA_SUCCESS) { +check_fw_ready_again: + /* + * Wait for a successful LIP up to a maximum + * of (in seconds): RISC login timeout value, + * RISC retry count value, and port down retry + * value OR a minimum of 4 seconds OR If no + * cable, only 5 seconds. + */ + rval = qla2x00_fw_ready(ha); + if (rval == QLA_SUCCESS) { + clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags); + + /* Issue a marker after FW becomes ready. */ + qla2x00_marker(ha, 0, 0, MK_SYNC_ALL); + + /* + * Wait at most MAX_TARGET RSCNs for a stable + * link. + */ + wait_time = 256; + do { + clear_bit(LOOP_RESYNC_NEEDED, + &ha->dpc_flags); + rval = qla2x00_configure_loop(ha); + + if (test_and_clear_bit(ISP_ABORT_NEEDED, + &ha->dpc_flags)) { + restart_risc = 1; + break; + } + + /* + * If loop state change while we were + * discoverying devices then wait for + * LIP to complete + */ + + if (atomic_read(&ha->loop_state) != + LOOP_READY && retry--) { + goto check_fw_ready_again; + } + wait_time--; + } while (!atomic_read(&ha->loop_down_timer) && + retry && + wait_time && + (test_bit(LOOP_RESYNC_NEEDED, + &ha->dpc_flags))); + + if (wait_time == 0) + rval = QLA_FUNCTION_FAILED; + } else if (ha->device_flags & DFLG_NO_CABLE) + /* If no cable, then all is good. */ + rval = QLA_SUCCESS; + } + } while (restart_risc && retry--); + + if (rval == QLA_SUCCESS) { + clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags); + qla2x00_marker(ha, 0, 0, MK_SYNC_ALL); + ha->marker_needed = 0; + + ha->flags.online = 1; + } else { + DEBUG2_3(printk("%s(): **** FAILED ****\n", __func__)); } - rval = qla2x00_init_rings(ha); return (rval); } @@ -2133,7 +2208,8 @@ qla2x00_update_fcport(scsi_qla_host_t *ha, fc_port_t *fcport) atomic_set(&fcport->state, FCS_ONLINE); - qla2x00_reg_remote_port(ha, fcport); + if (ha->flags.init_done) + qla2x00_reg_remote_port(ha, fcport); } void diff --git a/trunk/drivers/scsi/qla2xxx/qla_os.c b/trunk/drivers/scsi/qla2xxx/qla_os.c index cbe0cad83b68..208607be78c7 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_os.c +++ b/trunk/drivers/scsi/qla2xxx/qla_os.c @@ -95,8 +95,6 @@ MODULE_PARM_DESC(ql2xqfullrampup, */ static int qla2xxx_slave_configure(struct scsi_device * device); static int qla2xxx_slave_alloc(struct scsi_device *); -static int qla2xxx_scan_finished(struct Scsi_Host *, unsigned long time); -static void qla2xxx_scan_start(struct Scsi_Host *); static void qla2xxx_slave_destroy(struct scsi_device *); static int qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*fn)(struct scsi_cmnd *)); @@ -126,8 +124,6 @@ static struct scsi_host_template qla2x00_driver_template = { .slave_alloc = qla2xxx_slave_alloc, .slave_destroy = qla2xxx_slave_destroy, - .scan_finished = qla2xxx_scan_finished, - .scan_start = qla2xxx_scan_start, .change_queue_depth = qla2x00_change_queue_depth, .change_queue_type = qla2x00_change_queue_type, .this_id = -1, @@ -291,7 +287,7 @@ qla24xx_pci_info_str(struct scsi_qla_host *ha, char *str) return str; } -static char * +char * qla2x00_fw_version_str(struct scsi_qla_host *ha, char *str) { char un_str[10]; @@ -329,7 +325,7 @@ qla2x00_fw_version_str(struct scsi_qla_host *ha, char *str) return (str); } -static char * +char * qla24xx_fw_version_str(struct scsi_qla_host *ha, char *str) { sprintf(str, "%d.%02d.%02d ", ha->fw_major_version, @@ -638,7 +634,7 @@ qla2x00_block_error_handler(struct scsi_cmnd *cmnd) * Note: * Only return FAILED if command not returned by firmware. **************************************************************************/ -static int +int qla2xxx_eh_abort(struct scsi_cmnd *cmd) { scsi_qla_host_t *ha = to_qla_host(cmd->device->host); @@ -775,7 +771,7 @@ qla2x00_eh_wait_for_pending_target_commands(scsi_qla_host_t *ha, unsigned int t) * SUCCESS/FAILURE (defined as macro in scsi.h). * **************************************************************************/ -static int +int qla2xxx_eh_device_reset(struct scsi_cmnd *cmd) { scsi_qla_host_t *ha = to_qla_host(cmd->device->host); @@ -906,7 +902,7 @@ qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *ha) * SUCCESS/FAILURE (defined as macro in scsi.h). * **************************************************************************/ -static int +int qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd) { scsi_qla_host_t *ha = to_qla_host(cmd->device->host); @@ -967,7 +963,7 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd) * * Note: **************************************************************************/ -static int +int qla2xxx_eh_host_reset(struct scsi_cmnd *cmd) { scsi_qla_host_t *ha = to_qla_host(cmd->device->host); @@ -1370,29 +1366,6 @@ qla24xx_disable_intrs(scsi_qla_host_t *ha) spin_unlock_irqrestore(&ha->hardware_lock, flags); } -static void -qla2xxx_scan_start(struct Scsi_Host *shost) -{ - scsi_qla_host_t *ha = (scsi_qla_host_t *)shost->hostdata; - - set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags); - set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags); - set_bit(RSCN_UPDATE, &ha->dpc_flags); -} - -static int -qla2xxx_scan_finished(struct Scsi_Host *shost, unsigned long time) -{ - scsi_qla_host_t *ha = (scsi_qla_host_t *)shost->hostdata; - - if (!ha->host) - return 1; - if (time > ha->loop_reset_delay * HZ) - return 1; - - return atomic_read(&ha->loop_state) == LOOP_READY; -} - /* * PCI driver interface */ @@ -1404,8 +1377,10 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) struct Scsi_Host *host; scsi_qla_host_t *ha; unsigned long flags = 0; + unsigned long wait_switch = 0; char pci_info[20]; char fw_str[30]; + fc_port_t *fcport; struct scsi_host_template *sht; if (pci_enable_device(pdev)) @@ -1656,19 +1631,30 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) ha->isp_ops.enable_intrs(ha); - pci_set_drvdata(pdev, ha); + /* v2.19.5b6 */ + /* + * Wait around max loop_reset_delay secs for the devices to come + * on-line. We don't want Linux scanning before we are ready. + * + */ + for (wait_switch = jiffies + (ha->loop_reset_delay * HZ); + time_before(jiffies,wait_switch) && + !(ha->device_flags & (DFLG_NO_CABLE | DFLG_FABRIC_DEVICES)) + && (ha->device_flags & SWITCH_FOUND) ;) { - ha->flags.init_done = 1; - ha->flags.online = 1; + qla2x00_check_fabric_devices(ha); + + msleep(10); + } + pci_set_drvdata(pdev, ha); + ha->flags.init_done = 1; num_hosts++; ret = scsi_add_host(host, &pdev->dev); if (ret) goto probe_failed; - scsi_scan_host(host); - qla2x00_alloc_sysfs_attr(ha); qla2x00_init_host_attr(ha); @@ -1683,6 +1669,10 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) ha->flags.enable_64bit_addressing ? '+': '-', ha->host_no, ha->isp_ops.fw_version_str(ha, fw_str)); + /* Go with fc_rport registration. */ + list_for_each_entry(fcport, &ha->fcports, list) + qla2x00_reg_remote_port(ha, fcport); + return 0; probe_failed: diff --git a/trunk/drivers/scsi/qla2xxx/qla_sup.c b/trunk/drivers/scsi/qla2xxx/qla_sup.c index 15390ad87456..c71dbd5bd543 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_sup.c +++ b/trunk/drivers/scsi/qla2xxx/qla_sup.c @@ -449,7 +449,7 @@ nvram_data_to_access_addr(uint32_t naddr) return FARX_ACCESS_NVRAM_DATA | naddr; } -static uint32_t +uint32_t qla24xx_read_flash_dword(scsi_qla_host_t *ha, uint32_t addr) { int rval; @@ -490,7 +490,7 @@ qla24xx_read_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr, return dwptr; } -static int +int qla24xx_write_flash_dword(scsi_qla_host_t *ha, uint32_t addr, uint32_t data) { int rval; @@ -512,7 +512,7 @@ qla24xx_write_flash_dword(scsi_qla_host_t *ha, uint32_t addr, uint32_t data) return rval; } -static void +void qla24xx_get_flash_manufacturer(scsi_qla_host_t *ha, uint8_t *man_id, uint8_t *flash_id) { @@ -537,7 +537,7 @@ qla24xx_get_flash_manufacturer(scsi_qla_host_t *ha, uint8_t *man_id, } } -static int +int qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr, uint32_t dwords) { diff --git a/trunk/drivers/scsi/qla4xxx/ql4_dbg.c b/trunk/drivers/scsi/qla4xxx/ql4_dbg.c index 7b4e077a39c1..752031fadfef 100644 --- a/trunk/drivers/scsi/qla4xxx/ql4_dbg.c +++ b/trunk/drivers/scsi/qla4xxx/ql4_dbg.c @@ -71,7 +71,7 @@ void __dump_registers(struct scsi_qla_host *ha) readw(&ha->reg->u1.isp4010.nvram)); } - else if (is_qla4022(ha) | is_qla4032(ha)) { + else if (is_qla4022(ha)) { printk(KERN_INFO "0x%02X intr_mask = 0x%08X\n", (uint8_t) offsetof(struct isp_reg, u1.isp4022.intr_mask), @@ -119,7 +119,7 @@ void __dump_registers(struct scsi_qla_host *ha) readw(&ha->reg->u2.isp4010.port_err_status)); } - else if (is_qla4022(ha) | is_qla4032(ha)) { + else if (is_qla4022(ha)) { printk(KERN_INFO "Page 0 Registers:\n"); printk(KERN_INFO "0x%02X ext_hw_conf = 0x%08X\n", (uint8_t) offsetof(struct isp_reg, diff --git a/trunk/drivers/scsi/qla4xxx/ql4_def.h b/trunk/drivers/scsi/qla4xxx/ql4_def.h index 4249e52a5592..a7f6c7b1c590 100644 --- a/trunk/drivers/scsi/qla4xxx/ql4_def.h +++ b/trunk/drivers/scsi/qla4xxx/ql4_def.h @@ -40,11 +40,7 @@ #ifndef PCI_DEVICE_ID_QLOGIC_ISP4022 #define PCI_DEVICE_ID_QLOGIC_ISP4022 0x4022 -#endif - -#ifndef PCI_DEVICE_ID_QLOGIC_ISP4032 -#define PCI_DEVICE_ID_QLOGIC_ISP4032 0x4032 -#endif +#endif /* */ #define QLA_SUCCESS 0 #define QLA_ERROR 1 @@ -281,6 +277,7 @@ struct scsi_qla_host { #define AF_INTERRUPTS_ON 6 /* 0x00000040 Not Used */ #define AF_GET_CRASH_RECORD 7 /* 0x00000080 */ #define AF_LINK_UP 8 /* 0x00000100 */ +#define AF_TOPCAT_CHIP_PRESENT 9 /* 0x00000200 */ #define AF_IRQ_ATTACHED 10 /* 0x00000400 */ #define AF_ISNS_CMD_IN_PROCESS 12 /* 0x00001000 */ #define AF_ISNS_CMD_DONE 13 /* 0x00002000 */ @@ -320,17 +317,16 @@ struct scsi_qla_host { /* NVRAM registers */ struct eeprom_data *nvram; spinlock_t hardware_lock ____cacheline_aligned; + spinlock_t list_lock; uint32_t eeprom_cmd_data; /* Counters for general statistics */ - uint64_t isr_count; uint64_t adapter_error_count; uint64_t device_error_count; uint64_t total_io_count; uint64_t total_mbytes_xferred; uint64_t link_failure_count; uint64_t invalid_crc_count; - uint32_t bytes_xfered; uint32_t spurious_int_count; uint32_t aborted_io_count; uint32_t io_timeout_count; @@ -442,11 +438,6 @@ static inline int is_qla4022(struct scsi_qla_host *ha) return ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP4022; } -static inline int is_qla4032(struct scsi_qla_host *ha) -{ - return ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP4032; -} - static inline int adapter_up(struct scsi_qla_host *ha) { return (test_bit(AF_ONLINE, &ha->flags) != 0) && @@ -460,58 +451,58 @@ static inline struct scsi_qla_host* to_qla_host(struct Scsi_Host *shost) static inline void __iomem* isp_semaphore(struct scsi_qla_host *ha) { - return (is_qla4010(ha) ? - &ha->reg->u1.isp4010.nvram : - &ha->reg->u1.isp4022.semaphore); + return (is_qla4022(ha) ? + &ha->reg->u1.isp4022.semaphore : + &ha->reg->u1.isp4010.nvram); } static inline void __iomem* isp_nvram(struct scsi_qla_host *ha) { - return (is_qla4010(ha) ? - &ha->reg->u1.isp4010.nvram : - &ha->reg->u1.isp4022.nvram); + return (is_qla4022(ha) ? + &ha->reg->u1.isp4022.nvram : + &ha->reg->u1.isp4010.nvram); } static inline void __iomem* isp_ext_hw_conf(struct scsi_qla_host *ha) { - return (is_qla4010(ha) ? - &ha->reg->u2.isp4010.ext_hw_conf : - &ha->reg->u2.isp4022.p0.ext_hw_conf); + return (is_qla4022(ha) ? + &ha->reg->u2.isp4022.p0.ext_hw_conf : + &ha->reg->u2.isp4010.ext_hw_conf); } static inline void __iomem* isp_port_status(struct scsi_qla_host *ha) { - return (is_qla4010(ha) ? - &ha->reg->u2.isp4010.port_status : - &ha->reg->u2.isp4022.p0.port_status); + return (is_qla4022(ha) ? + &ha->reg->u2.isp4022.p0.port_status : + &ha->reg->u2.isp4010.port_status); } static inline void __iomem* isp_port_ctrl(struct scsi_qla_host *ha) { - return (is_qla4010(ha) ? - &ha->reg->u2.isp4010.port_ctrl : - &ha->reg->u2.isp4022.p0.port_ctrl); + return (is_qla4022(ha) ? + &ha->reg->u2.isp4022.p0.port_ctrl : + &ha->reg->u2.isp4010.port_ctrl); } static inline void __iomem* isp_port_error_status(struct scsi_qla_host *ha) { - return (is_qla4010(ha) ? - &ha->reg->u2.isp4010.port_err_status : - &ha->reg->u2.isp4022.p0.port_err_status); + return (is_qla4022(ha) ? + &ha->reg->u2.isp4022.p0.port_err_status : + &ha->reg->u2.isp4010.port_err_status); } static inline void __iomem * isp_gp_out(struct scsi_qla_host *ha) { - return (is_qla4010(ha) ? - &ha->reg->u2.isp4010.gp_out : - &ha->reg->u2.isp4022.p0.gp_out); + return (is_qla4022(ha) ? + &ha->reg->u2.isp4022.p0.gp_out : + &ha->reg->u2.isp4010.gp_out); } static inline int eeprom_ext_hw_conf_offset(struct scsi_qla_host *ha) { - return (is_qla4010(ha) ? - offsetof(struct eeprom_data, isp4010.ext_hw_conf) / 2 : - offsetof(struct eeprom_data, isp4022.ext_hw_conf) / 2); + return (is_qla4022(ha) ? + offsetof(struct eeprom_data, isp4022.ext_hw_conf) / 2 : + offsetof(struct eeprom_data, isp4010.ext_hw_conf) / 2); } int ql4xxx_sem_spinlock(struct scsi_qla_host * ha, u32 sem_mask, u32 sem_bits); @@ -520,59 +511,59 @@ int ql4xxx_sem_lock(struct scsi_qla_host * ha, u32 sem_mask, u32 sem_bits); static inline int ql4xxx_lock_flash(struct scsi_qla_host *a) { - if (is_qla4010(a)) - return ql4xxx_sem_spinlock(a, QL4010_FLASH_SEM_MASK, - QL4010_FLASH_SEM_BITS); - else + if (is_qla4022(a)) return ql4xxx_sem_spinlock(a, QL4022_FLASH_SEM_MASK, (QL4022_RESOURCE_BITS_BASE_CODE | (a->mac_index)) << 13); + else + return ql4xxx_sem_spinlock(a, QL4010_FLASH_SEM_MASK, + QL4010_FLASH_SEM_BITS); } static inline void ql4xxx_unlock_flash(struct scsi_qla_host *a) { - if (is_qla4010(a)) - ql4xxx_sem_unlock(a, QL4010_FLASH_SEM_MASK); - else + if (is_qla4022(a)) ql4xxx_sem_unlock(a, QL4022_FLASH_SEM_MASK); + else + ql4xxx_sem_unlock(a, QL4010_FLASH_SEM_MASK); } static inline int ql4xxx_lock_nvram(struct scsi_qla_host *a) { - if (is_qla4010(a)) - return ql4xxx_sem_spinlock(a, QL4010_NVRAM_SEM_MASK, - QL4010_NVRAM_SEM_BITS); - else + if (is_qla4022(a)) return ql4xxx_sem_spinlock(a, QL4022_NVRAM_SEM_MASK, (QL4022_RESOURCE_BITS_BASE_CODE | (a->mac_index)) << 10); + else + return ql4xxx_sem_spinlock(a, QL4010_NVRAM_SEM_MASK, + QL4010_NVRAM_SEM_BITS); } static inline void ql4xxx_unlock_nvram(struct scsi_qla_host *a) { - if (is_qla4010(a)) - ql4xxx_sem_unlock(a, QL4010_NVRAM_SEM_MASK); - else + if (is_qla4022(a)) ql4xxx_sem_unlock(a, QL4022_NVRAM_SEM_MASK); + else + ql4xxx_sem_unlock(a, QL4010_NVRAM_SEM_MASK); } static inline int ql4xxx_lock_drvr(struct scsi_qla_host *a) { - if (is_qla4010(a)) - return ql4xxx_sem_lock(a, QL4010_DRVR_SEM_MASK, - QL4010_DRVR_SEM_BITS); - else + if (is_qla4022(a)) return ql4xxx_sem_lock(a, QL4022_DRVR_SEM_MASK, (QL4022_RESOURCE_BITS_BASE_CODE | (a->mac_index)) << 1); + else + return ql4xxx_sem_lock(a, QL4010_DRVR_SEM_MASK, + QL4010_DRVR_SEM_BITS); } static inline void ql4xxx_unlock_drvr(struct scsi_qla_host *a) { - if (is_qla4010(a)) - ql4xxx_sem_unlock(a, QL4010_DRVR_SEM_MASK); - else + if (is_qla4022(a)) ql4xxx_sem_unlock(a, QL4022_DRVR_SEM_MASK); + else + ql4xxx_sem_unlock(a, QL4010_DRVR_SEM_MASK); } /*---------------------------------------------------------------------------*/ diff --git a/trunk/drivers/scsi/qla4xxx/ql4_fw.h b/trunk/drivers/scsi/qla4xxx/ql4_fw.h index 4eea8c571916..427489de64bc 100644 --- a/trunk/drivers/scsi/qla4xxx/ql4_fw.h +++ b/trunk/drivers/scsi/qla4xxx/ql4_fw.h @@ -296,6 +296,7 @@ static inline uint32_t clr_rmask(uint32_t val) /* ISP Semaphore definitions */ /* ISP General Purpose Output definitions */ +#define GPOR_TOPCAT_RESET 0x00000004 /* shadow registers (DMA'd from HA to system memory. read only) */ struct shadow_regs { @@ -338,13 +339,10 @@ union external_hw_config_reg { /* Mailbox command definitions */ #define MBOX_CMD_ABOUT_FW 0x0009 #define MBOX_CMD_LUN_RESET 0x0016 -#define MBOX_CMD_GET_MANAGEMENT_DATA 0x001E #define MBOX_CMD_GET_FW_STATUS 0x001F #define MBOX_CMD_SET_ISNS_SERVICE 0x0021 #define ISNS_DISABLE 0 #define ISNS_ENABLE 1 -#define MBOX_CMD_COPY_FLASH 0x0024 -#define MBOX_CMD_WRITE_FLASH 0x0025 #define MBOX_CMD_READ_FLASH 0x0026 #define MBOX_CMD_CLEAR_DATABASE_ENTRY 0x0031 #define MBOX_CMD_CONN_CLOSE_SESS_LOGOUT 0x0056 @@ -362,13 +360,10 @@ union external_hw_config_reg { #define DDB_DS_SESSION_FAILED 0x06 #define DDB_DS_LOGIN_IN_PROCESS 0x07 #define MBOX_CMD_GET_FW_STATE 0x0069 -#define MBOX_CMD_GET_INIT_FW_CTRL_BLOCK_DEFAULTS 0x006A -#define MBOX_CMD_RESTORE_FACTORY_DEFAULTS 0x0087 /* Mailbox 1 */ #define FW_STATE_READY 0x0000 #define FW_STATE_CONFIG_WAIT 0x0001 -#define FW_STATE_WAIT_LOGIN 0x0002 #define FW_STATE_ERROR 0x0004 #define FW_STATE_DHCP_IN_PROGRESS 0x0008 diff --git a/trunk/drivers/scsi/qla4xxx/ql4_glbl.h b/trunk/drivers/scsi/qla4xxx/ql4_glbl.h index 2122967bbf0b..1b221ff0f6f7 100644 --- a/trunk/drivers/scsi/qla4xxx/ql4_glbl.h +++ b/trunk/drivers/scsi/qla4xxx/ql4_glbl.h @@ -8,7 +8,6 @@ #ifndef __QLA4x_GBL_H #define __QLA4x_GBL_H -int ql4xxx_lock_drvr_wait(struct scsi_qla_host *a); int qla4xxx_send_tgts(struct scsi_qla_host *ha, char *ip, uint16_t port); int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb * srb); int qla4xxx_initialize_adapter(struct scsi_qla_host * ha, @@ -76,4 +75,4 @@ int qla4xxx_process_ddb_changed(struct scsi_qla_host * ha, extern int ql4xextended_error_logging; extern int ql4xdiscoverywait; extern int ql4xdontresethba; -#endif /* _QLA4x_GBL_H */ +#endif /* _QLA4x_GBL_H */ diff --git a/trunk/drivers/scsi/qla4xxx/ql4_init.c b/trunk/drivers/scsi/qla4xxx/ql4_init.c index cc210f297a78..bb3a1c11f44c 100644 --- a/trunk/drivers/scsi/qla4xxx/ql4_init.c +++ b/trunk/drivers/scsi/qla4xxx/ql4_init.c @@ -259,16 +259,10 @@ static int qla4xxx_fw_ready(struct scsi_qla_host *ha) "seconds expired= %d\n", ha->host_no, __func__, ha->firmware_state, ha->addl_fw_state, timeout_count)); - if (is_qla4032(ha) && - !(ha->addl_fw_state & FW_ADDSTATE_LINK_UP) && - (timeout_count < ADAPTER_INIT_TOV - 5)) { - break; - } - msleep(1000); } /* end of for */ - if (timeout_count == 0) + if (timeout_count <= 0) DEBUG2(printk("scsi%ld: %s: FW Initialization timed out!\n", ha->host_no, __func__)); @@ -812,6 +806,32 @@ int qla4xxx_relogin_device(struct scsi_qla_host *ha, return QLA_SUCCESS; } +/** + * qla4010_get_topcat_presence - check if it is QLA4040 TopCat Chip + * @ha: Pointer to host adapter structure. + * + **/ +static int qla4010_get_topcat_presence(struct scsi_qla_host *ha) +{ + unsigned long flags; + uint16_t topcat; + + if (ql4xxx_lock_nvram(ha) != QLA_SUCCESS) + return QLA_ERROR; + spin_lock_irqsave(&ha->hardware_lock, flags); + topcat = rd_nvram_word(ha, offsetof(struct eeprom_data, + isp4010.topcat)); + spin_unlock_irqrestore(&ha->hardware_lock, flags); + + if ((topcat & TOPCAT_MASK) == TOPCAT_PRESENT) + set_bit(AF_TOPCAT_CHIP_PRESENT, &ha->flags); + else + clear_bit(AF_TOPCAT_CHIP_PRESENT, &ha->flags); + ql4xxx_unlock_nvram(ha); + return QLA_SUCCESS; +} + + static int qla4xxx_config_nvram(struct scsi_qla_host *ha) { unsigned long flags; @@ -846,7 +866,7 @@ static int qla4xxx_config_nvram(struct scsi_qla_host *ha) /* set defaults */ if (is_qla4010(ha)) extHwConfig.Asuint32_t = 0x1912; - else if (is_qla4022(ha) | is_qla4032(ha)) + else if (is_qla4022(ha)) extHwConfig.Asuint32_t = 0x0023; } DEBUG(printk("scsi%ld: %s: Setting extHwConfig to 0xFFFF%04x\n", @@ -907,7 +927,7 @@ static int qla4xxx_start_firmware_from_flash(struct scsi_qla_host *ha) spin_lock_irqsave(&ha->hardware_lock, flags); writel(jiffies, &ha->reg->mailbox[7]); - if (is_qla4022(ha) | is_qla4032(ha)) + if (is_qla4022(ha)) writel(set_rmask(NVR_WRITE_ENABLE), &ha->reg->u1.isp4022.nvram); @@ -958,7 +978,7 @@ static int qla4xxx_start_firmware_from_flash(struct scsi_qla_host *ha) return status; } -int ql4xxx_lock_drvr_wait(struct scsi_qla_host *a) +static int ql4xxx_lock_drvr_wait(struct scsi_qla_host *a) { #define QL4_LOCK_DRVR_WAIT 300 #define QL4_LOCK_DRVR_SLEEP 100 @@ -998,7 +1018,12 @@ static int qla4xxx_start_firmware(struct scsi_qla_host *ha) int soft_reset = 1; int config_chip = 0; - if (is_qla4022(ha) | is_qla4032(ha)) + if (is_qla4010(ha)){ + if (qla4010_get_topcat_presence(ha) != QLA_SUCCESS) + return QLA_ERROR; + } + + if (is_qla4022(ha)) ql4xxx_set_mac_number(ha); if (ql4xxx_lock_drvr_wait(ha) != QLA_SUCCESS) diff --git a/trunk/drivers/scsi/qla4xxx/ql4_inline.h b/trunk/drivers/scsi/qla4xxx/ql4_inline.h index 6375eb017dd3..0d61797af7da 100644 --- a/trunk/drivers/scsi/qla4xxx/ql4_inline.h +++ b/trunk/drivers/scsi/qla4xxx/ql4_inline.h @@ -38,7 +38,7 @@ qla4xxx_lookup_ddb_by_fw_index(struct scsi_qla_host *ha, uint32_t fw_ddb_index) static inline void __qla4xxx_enable_intrs(struct scsi_qla_host *ha) { - if (is_qla4022(ha) | is_qla4032(ha)) { + if (is_qla4022(ha)) { writel(set_rmask(IMR_SCSI_INTR_ENABLE), &ha->reg->u1.isp4022.intr_mask); readl(&ha->reg->u1.isp4022.intr_mask); @@ -52,7 +52,7 @@ __qla4xxx_enable_intrs(struct scsi_qla_host *ha) static inline void __qla4xxx_disable_intrs(struct scsi_qla_host *ha) { - if (is_qla4022(ha) | is_qla4032(ha)) { + if (is_qla4022(ha)) { writel(clr_rmask(IMR_SCSI_INTR_ENABLE), &ha->reg->u1.isp4022.intr_mask); readl(&ha->reg->u1.isp4022.intr_mask); diff --git a/trunk/drivers/scsi/qla4xxx/ql4_iocb.c b/trunk/drivers/scsi/qla4xxx/ql4_iocb.c index d41ce380eedc..c0a254b89a30 100644 --- a/trunk/drivers/scsi/qla4xxx/ql4_iocb.c +++ b/trunk/drivers/scsi/qla4xxx/ql4_iocb.c @@ -294,12 +294,6 @@ int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb * srb) cmd_entry->control_flags = CF_WRITE; else if (cmd->sc_data_direction == DMA_FROM_DEVICE) cmd_entry->control_flags = CF_READ; - - ha->bytes_xfered += cmd->request_bufflen; - if (ha->bytes_xfered & ~0xFFFFF){ - ha->total_mbytes_xferred += ha->bytes_xfered >> 20; - ha->bytes_xfered &= 0xFFFFF; - } } /* Set tagged queueing control flags */ diff --git a/trunk/drivers/scsi/qla4xxx/ql4_isr.c b/trunk/drivers/scsi/qla4xxx/ql4_isr.c index ef975e0dc87f..1e283321a59d 100644 --- a/trunk/drivers/scsi/qla4xxx/ql4_isr.c +++ b/trunk/drivers/scsi/qla4xxx/ql4_isr.c @@ -627,7 +627,6 @@ irqreturn_t qla4xxx_intr_handler(int irq, void *dev_id) spin_lock_irqsave(&ha->hardware_lock, flags); - ha->isr_count++; /* * Repeatedly service interrupts up to a maximum of * MAX_REQS_SERVICED_PER_INTR diff --git a/trunk/drivers/scsi/qla4xxx/ql4_nvram.c b/trunk/drivers/scsi/qla4xxx/ql4_nvram.c index 58afd135aa1d..e3957ca5b645 100644 --- a/trunk/drivers/scsi/qla4xxx/ql4_nvram.c +++ b/trunk/drivers/scsi/qla4xxx/ql4_nvram.c @@ -7,22 +7,15 @@ #include "ql4_def.h" -static inline void eeprom_cmd(uint32_t cmd, struct scsi_qla_host *ha) -{ - writel(cmd, isp_nvram(ha)); - readl(isp_nvram(ha)); - udelay(1); -} - static inline int eeprom_size(struct scsi_qla_host *ha) { - return is_qla4010(ha) ? FM93C66A_SIZE_16 : FM93C86A_SIZE_16; + return is_qla4022(ha) ? FM93C86A_SIZE_16 : FM93C66A_SIZE_16; } static inline int eeprom_no_addr_bits(struct scsi_qla_host *ha) { - return is_qla4010(ha) ? FM93C56A_NO_ADDR_BITS_16 : - FM93C86A_NO_ADDR_BITS_16 ; + return is_qla4022(ha) ? FM93C86A_NO_ADDR_BITS_16 : + FM93C56A_NO_ADDR_BITS_16; } static inline int eeprom_no_data_bits(struct scsi_qla_host *ha) @@ -35,7 +28,8 @@ static int fm93c56a_select(struct scsi_qla_host * ha) DEBUG5(printk(KERN_ERR "fm93c56a_select:\n")); ha->eeprom_cmd_data = AUBURN_EEPROM_CS_1 | 0x000f0000; - eeprom_cmd(ha->eeprom_cmd_data, ha); + writel(ha->eeprom_cmd_data, isp_nvram(ha)); + readl(isp_nvram(ha)); return 1; } @@ -47,13 +41,12 @@ static int fm93c56a_cmd(struct scsi_qla_host * ha, int cmd, int addr) int previousBit; /* Clock in a zero, then do the start bit. */ - eeprom_cmd(ha->eeprom_cmd_data | AUBURN_EEPROM_DO_1, ha); - - eeprom_cmd(ha->eeprom_cmd_data | AUBURN_EEPROM_DO_1 | - AUBURN_EEPROM_CLK_RISE, ha); - eeprom_cmd(ha->eeprom_cmd_data | AUBURN_EEPROM_DO_1 | - AUBURN_EEPROM_CLK_FALL, ha); - + writel(ha->eeprom_cmd_data | AUBURN_EEPROM_DO_1, isp_nvram(ha)); + writel(ha->eeprom_cmd_data | AUBURN_EEPROM_DO_1 | + AUBURN_EEPROM_CLK_RISE, isp_nvram(ha)); + writel(ha->eeprom_cmd_data | AUBURN_EEPROM_DO_1 | + AUBURN_EEPROM_CLK_FALL, isp_nvram(ha)); + readl(isp_nvram(ha)); mask = 1 << (FM93C56A_CMD_BITS - 1); /* Force the previous data bit to be different. */ @@ -67,14 +60,14 @@ static int fm93c56a_cmd(struct scsi_qla_host * ha, int cmd, int addr) * If the bit changed, then change the DO state to * match. */ - eeprom_cmd(ha->eeprom_cmd_data | dataBit, ha); + writel(ha->eeprom_cmd_data | dataBit, isp_nvram(ha)); previousBit = dataBit; } - eeprom_cmd(ha->eeprom_cmd_data | dataBit | - AUBURN_EEPROM_CLK_RISE, ha); - eeprom_cmd(ha->eeprom_cmd_data | dataBit | - AUBURN_EEPROM_CLK_FALL, ha); - + writel(ha->eeprom_cmd_data | dataBit | + AUBURN_EEPROM_CLK_RISE, isp_nvram(ha)); + writel(ha->eeprom_cmd_data | dataBit | + AUBURN_EEPROM_CLK_FALL, isp_nvram(ha)); + readl(isp_nvram(ha)); cmd = cmd << 1; } mask = 1 << (eeprom_no_addr_bits(ha) - 1); @@ -89,15 +82,14 @@ static int fm93c56a_cmd(struct scsi_qla_host * ha, int cmd, int addr) * If the bit changed, then change the DO state to * match. */ - eeprom_cmd(ha->eeprom_cmd_data | dataBit, ha); - + writel(ha->eeprom_cmd_data | dataBit, isp_nvram(ha)); previousBit = dataBit; } - eeprom_cmd(ha->eeprom_cmd_data | dataBit | - AUBURN_EEPROM_CLK_RISE, ha); - eeprom_cmd(ha->eeprom_cmd_data | dataBit | - AUBURN_EEPROM_CLK_FALL, ha); - + writel(ha->eeprom_cmd_data | dataBit | + AUBURN_EEPROM_CLK_RISE, isp_nvram(ha)); + writel(ha->eeprom_cmd_data | dataBit | + AUBURN_EEPROM_CLK_FALL, isp_nvram(ha)); + readl(isp_nvram(ha)); addr = addr << 1; } return 1; @@ -106,7 +98,8 @@ static int fm93c56a_cmd(struct scsi_qla_host * ha, int cmd, int addr) static int fm93c56a_deselect(struct scsi_qla_host * ha) { ha->eeprom_cmd_data = AUBURN_EEPROM_CS_0 | 0x000f0000; - eeprom_cmd(ha->eeprom_cmd_data, ha); + writel(ha->eeprom_cmd_data, isp_nvram(ha)); + readl(isp_nvram(ha)); return 1; } @@ -119,13 +112,12 @@ static int fm93c56a_datain(struct scsi_qla_host * ha, unsigned short *value) /* Read the data bits * The first bit is a dummy. Clock right over it. */ for (i = 0; i < eeprom_no_data_bits(ha); i++) { - eeprom_cmd(ha->eeprom_cmd_data | - AUBURN_EEPROM_CLK_RISE, ha); - eeprom_cmd(ha->eeprom_cmd_data | - AUBURN_EEPROM_CLK_FALL, ha); - - dataBit = (readw(isp_nvram(ha)) & AUBURN_EEPROM_DI_1) ? 1 : 0; - + writel(ha->eeprom_cmd_data | + AUBURN_EEPROM_CLK_RISE, isp_nvram(ha)); + writel(ha->eeprom_cmd_data | + AUBURN_EEPROM_CLK_FALL, isp_nvram(ha)); + dataBit = + (readw(isp_nvram(ha)) & AUBURN_EEPROM_DI_1) ? 1 : 0; data = (data << 1) | dataBit; } diff --git a/trunk/drivers/scsi/qla4xxx/ql4_nvram.h b/trunk/drivers/scsi/qla4xxx/ql4_nvram.h index b47b4fc59d83..08e2aed8c6cc 100644 --- a/trunk/drivers/scsi/qla4xxx/ql4_nvram.h +++ b/trunk/drivers/scsi/qla4xxx/ql4_nvram.h @@ -134,7 +134,9 @@ struct eeprom_data { u16 phyConfig; /* x36 */ #define PHY_CONFIG_PHY_ADDR_MASK 0x1f #define PHY_CONFIG_ENABLE_FW_MANAGEMENT_MASK 0x20 - u16 reserved_56; /* x38 */ + u16 topcat; /* x38 */ +#define TOPCAT_PRESENT 0x0100 +#define TOPCAT_MASK 0xFF00 #define EEPROM_UNUSED_1_SIZE 2 u8 unused_1[EEPROM_UNUSED_1_SIZE]; /* x3A */ diff --git a/trunk/drivers/scsi/qla4xxx/ql4_os.c b/trunk/drivers/scsi/qla4xxx/ql4_os.c index 969c9e431028..5b8db6109536 100644 --- a/trunk/drivers/scsi/qla4xxx/ql4_os.c +++ b/trunk/drivers/scsi/qla4xxx/ql4_os.c @@ -708,10 +708,10 @@ static int qla4xxx_cmd_wait(struct scsi_qla_host *ha) } /** - * qla4xxx_soft_reset - performs soft reset. + * qla4010_soft_reset - performs soft reset. * @ha: Pointer to host adapter structure. **/ -int qla4xxx_soft_reset(struct scsi_qla_host *ha) +static int qla4010_soft_reset(struct scsi_qla_host *ha) { uint32_t max_wait_time; unsigned long flags = 0; @@ -816,6 +816,29 @@ int qla4xxx_soft_reset(struct scsi_qla_host *ha) return status; } +/** + * qla4xxx_topcat_reset - performs hard reset of TopCat Chip. + * @ha: Pointer to host adapter structure. + **/ +static int qla4xxx_topcat_reset(struct scsi_qla_host *ha) +{ + unsigned long flags; + + ql4xxx_lock_nvram(ha); + spin_lock_irqsave(&ha->hardware_lock, flags); + writel(set_rmask(GPOR_TOPCAT_RESET), isp_gp_out(ha)); + readl(isp_gp_out(ha)); + mdelay(1); + + writel(clr_rmask(GPOR_TOPCAT_RESET), isp_gp_out(ha)); + readl(isp_gp_out(ha)); + spin_unlock_irqrestore(&ha->hardware_lock, flags); + mdelay(2523); + + ql4xxx_unlock_nvram(ha); + return QLA_SUCCESS; +} + /** * qla4xxx_flush_active_srbs - returns all outstanding i/o requests to O.S. * @ha: Pointer to host adapter structure. @@ -843,6 +866,26 @@ static void qla4xxx_flush_active_srbs(struct scsi_qla_host *ha) } +/** + * qla4xxx_hard_reset - performs HBA Hard Reset + * @ha: Pointer to host adapter structure. + **/ +static int qla4xxx_hard_reset(struct scsi_qla_host *ha) +{ + /* The QLA4010 really doesn't have an equivalent to a hard reset */ + qla4xxx_flush_active_srbs(ha); + if (test_bit(AF_TOPCAT_CHIP_PRESENT, &ha->flags)) { + int status = QLA_ERROR; + + if ((qla4010_soft_reset(ha) == QLA_SUCCESS) && + (qla4xxx_topcat_reset(ha) == QLA_SUCCESS) && + (qla4010_soft_reset(ha) == QLA_SUCCESS)) + status = QLA_SUCCESS; + return status; + } else + return qla4010_soft_reset(ha); +} + /** * qla4xxx_recover_adapter - recovers adapter after a fatal error * @ha: Pointer to host adapter structure. @@ -876,11 +919,18 @@ static int qla4xxx_recover_adapter(struct scsi_qla_host *ha, if (status == QLA_SUCCESS) { DEBUG2(printk("scsi%ld: %s - Performing soft reset..\n", ha->host_no, __func__)); - qla4xxx_flush_active_srbs(ha); - if (ql4xxx_lock_drvr_wait(ha) == QLA_SUCCESS) - status = qla4xxx_soft_reset(ha); - else - status = QLA_ERROR; + status = qla4xxx_soft_reset(ha); + } + /* FIXMEkaren: Do we want to keep interrupts enabled and process + AENs after soft reset */ + + /* If firmware (SOFT) reset failed, or if all outstanding + * commands have not returned, then do a HARD reset. + */ + if (status == QLA_ERROR) { + DEBUG2(printk("scsi%ld: %s - Performing hard reset..\n", + ha->host_no, __func__)); + status = qla4xxx_hard_reset(ha); } /* Flush any pending ddb changed AENs */ @@ -961,15 +1011,18 @@ static int qla4xxx_recover_adapter(struct scsi_qla_host *ha, * the mid-level tries to sleep when it reaches the driver threshold * "host->can_queue". This can cause a panic if we were in our interrupt code. **/ -static void qla4xxx_do_dpc(struct work_struct *work) +static void qla4xxx_do_dpc(void *data) { - struct scsi_qla_host *ha = - container_of(work, struct scsi_qla_host, dpc_work); + struct scsi_qla_host *ha = (struct scsi_qla_host *) data; struct ddb_entry *ddb_entry, *dtemp; - DEBUG2(printk("scsi%ld: %s: DPC handler waking up." - "flags = 0x%08lx, dpc_flags = 0x%08lx\n", - ha->host_no, __func__, ha->flags, ha->dpc_flags)); + DEBUG2(printk("scsi%ld: %s: DPC handler waking up.\n", + ha->host_no, __func__)); + + DEBUG2(printk("scsi%ld: %s: ha->flags = 0x%08lx\n", + ha->host_no, __func__, ha->flags)); + DEBUG2(printk("scsi%ld: %s: ha->dpc_flags = 0x%08lx\n", + ha->host_no, __func__, ha->dpc_flags)); /* Initialization not yet finished. Don't do anything yet. */ if (!test_bit(AF_INIT_DONE, &ha->flags)) @@ -979,8 +1032,16 @@ static void qla4xxx_do_dpc(struct work_struct *work) test_bit(DPC_RESET_HA, &ha->dpc_flags) || test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags) || test_bit(DPC_RESET_HA_DESTROY_DDB_LIST, &ha->dpc_flags)) { - if (test_bit(DPC_RESET_HA_DESTROY_DDB_LIST, &ha->dpc_flags) || - test_bit(DPC_RESET_HA, &ha->dpc_flags)) + if (test_bit(DPC_RESET_HA_DESTROY_DDB_LIST, &ha->dpc_flags)) + /* + * dg 09/23 Never initialize ddb list + * once we up and running + * qla4xxx_recover_adapter(ha, + * REBUILD_DDB_LIST); + */ + qla4xxx_recover_adapter(ha, PRESERVE_DDB_LIST); + + if (test_bit(DPC_RESET_HA, &ha->dpc_flags)) qla4xxx_recover_adapter(ha, PRESERVE_DDB_LIST); if (test_and_clear_bit(DPC_RESET_HA_INTR, &ha->dpc_flags)) { @@ -1061,8 +1122,7 @@ static void qla4xxx_free_adapter(struct scsi_qla_host *ha) destroy_workqueue(ha->dpc_thread); /* Issue Soft Reset to put firmware in unknown state */ - if (ql4xxx_lock_drvr_wait(ha) == QLA_SUCCESS) - qla4xxx_soft_reset(ha); + qla4xxx_soft_reset(ha); /* Remove timer thread, if present */ if (ha->timer_active) @@ -1201,6 +1261,7 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev, init_waitqueue_head(&ha->mailbox_wait_queue); spin_lock_init(&ha->hardware_lock); + spin_lock_init(&ha->list_lock); /* Allocate dma buffers */ if (qla4xxx_mem_alloc(ha)) { @@ -1254,7 +1315,7 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev, ret = -ENODEV; goto probe_failed; } - INIT_WORK(&ha->dpc_work, qla4xxx_do_dpc); + INIT_WORK(&ha->dpc_work, qla4xxx_do_dpc, ha); ret = request_irq(pdev->irq, qla4xxx_intr_handler, SA_INTERRUPT|SA_SHIRQ, "qla4xxx", ha); @@ -1406,6 +1467,27 @@ struct srb * qla4xxx_del_from_active_array(struct scsi_qla_host *ha, uint32_t in return srb; } +/** + * qla4xxx_soft_reset - performs a SOFT RESET of hba. + * @ha: Pointer to host adapter structure. + **/ +int qla4xxx_soft_reset(struct scsi_qla_host *ha) +{ + + DEBUG2(printk(KERN_WARNING "scsi%ld: %s: chip reset!\n", ha->host_no, + __func__)); + if (test_bit(AF_TOPCAT_CHIP_PRESENT, &ha->flags)) { + int status = QLA_ERROR; + + if ((qla4010_soft_reset(ha) == QLA_SUCCESS) && + (qla4xxx_topcat_reset(ha) == QLA_SUCCESS) && + (qla4010_soft_reset(ha) == QLA_SUCCESS) ) + status = QLA_SUCCESS; + return status; + } else + return qla4010_soft_reset(ha); +} + /** * qla4xxx_eh_wait_on_command - waits for command to be returned by firmware * @ha: actual ha whose done queue will contain the comd returned by firmware. @@ -1604,12 +1686,6 @@ static struct pci_device_id qla4xxx_pci_tbl[] = { .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, }, - { - .vendor = PCI_VENDOR_ID_QLOGIC, - .device = PCI_DEVICE_ID_QLOGIC_ISP4032, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - }, {0, 0}, }; MODULE_DEVICE_TABLE(pci, qla4xxx_pci_tbl); diff --git a/trunk/drivers/scsi/qla4xxx/ql4_version.h b/trunk/drivers/scsi/qla4xxx/ql4_version.h index 454e19c8ad68..b3fe7e68988e 100644 --- a/trunk/drivers/scsi/qla4xxx/ql4_version.h +++ b/trunk/drivers/scsi/qla4xxx/ql4_version.h @@ -5,4 +5,9 @@ * See LICENSE.qla4xxx for copyright and licensing details. */ -#define QLA4XXX_DRIVER_VERSION "5.00.07-k" +#define QLA4XXX_DRIVER_VERSION "5.00.05b9-k" + +#define QL4_DRIVER_MAJOR_VER 5 +#define QL4_DRIVER_MINOR_VER 0 +#define QL4_DRIVER_PATCH_VER 5 +#define QL4_DRIVER_BETA_VER 9 diff --git a/trunk/drivers/scsi/scsi.c b/trunk/drivers/scsi/scsi.c index fafc00deaade..c59f31533ab4 100644 --- a/trunk/drivers/scsi/scsi.c +++ b/trunk/drivers/scsi/scsi.c @@ -156,7 +156,8 @@ static struct scsi_host_cmd_pool scsi_cmd_dma_pool = { static DEFINE_MUTEX(host_cmd_pool_mutex); -struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *shost, gfp_t gfp_mask) +static struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *shost, + gfp_t gfp_mask) { struct scsi_cmnd *cmd; @@ -177,7 +178,6 @@ struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *shost, gfp_t gfp_mask) return cmd; } -EXPORT_SYMBOL_GPL(__scsi_get_command); /* * Function: scsi_get_command() @@ -214,29 +214,9 @@ struct scsi_cmnd *scsi_get_command(struct scsi_device *dev, gfp_t gfp_mask) put_device(&dev->sdev_gendev); return cmd; -} +} EXPORT_SYMBOL(scsi_get_command); -void __scsi_put_command(struct Scsi_Host *shost, struct scsi_cmnd *cmd, - struct device *dev) -{ - unsigned long flags; - - /* changing locks here, don't need to restore the irq state */ - spin_lock_irqsave(&shost->free_list_lock, flags); - if (unlikely(list_empty(&shost->free_list))) { - list_add(&cmd->list, &shost->free_list); - cmd = NULL; - } - spin_unlock_irqrestore(&shost->free_list_lock, flags); - - if (likely(cmd != NULL)) - kmem_cache_free(shost->cmd_pool->slab, cmd); - - put_device(dev); -} -EXPORT_SYMBOL(__scsi_put_command); - /* * Function: scsi_put_command() * @@ -251,15 +231,26 @@ EXPORT_SYMBOL(__scsi_put_command); void scsi_put_command(struct scsi_cmnd *cmd) { struct scsi_device *sdev = cmd->device; + struct Scsi_Host *shost = sdev->host; unsigned long flags; - + /* serious error if the command hasn't come from a device list */ spin_lock_irqsave(&cmd->device->list_lock, flags); BUG_ON(list_empty(&cmd->list)); list_del_init(&cmd->list); - spin_unlock_irqrestore(&cmd->device->list_lock, flags); + spin_unlock(&cmd->device->list_lock); + /* changing locks here, don't need to restore the irq state */ + spin_lock(&shost->free_list_lock); + if (unlikely(list_empty(&shost->free_list))) { + list_add(&cmd->list, &shost->free_list); + cmd = NULL; + } + spin_unlock_irqrestore(&shost->free_list_lock, flags); + + if (likely(cmd != NULL)) + kmem_cache_free(shost->cmd_pool->slab, cmd); - __scsi_put_command(cmd->device->host, cmd, &sdev->sdev_gendev); + put_device(&sdev->sdev_gendev); } EXPORT_SYMBOL(scsi_put_command); @@ -880,9 +871,9 @@ EXPORT_SYMBOL(scsi_device_get); */ void scsi_device_put(struct scsi_device *sdev) { -#ifdef CONFIG_MODULE_UNLOAD struct module *module = sdev->host->hostt->module; +#ifdef CONFIG_MODULE_UNLOAD /* The module refcount will be zero if scsi_device_get() * was called from a module removal routine */ if (module && module_refcount(module) != 0) diff --git a/trunk/drivers/scsi/scsi_error.c b/trunk/drivers/scsi/scsi_error.c index 2ecb6ff42444..aff1b0cfd4b2 100644 --- a/trunk/drivers/scsi/scsi_error.c +++ b/trunk/drivers/scsi/scsi_error.c @@ -453,18 +453,9 @@ static void scsi_eh_done(struct scsi_cmnd *scmd) } /** - * scsi_send_eh_cmnd - submit a scsi command as part of error recory - * @scmd: SCSI command structure to hijack - * @cmnd: CDB to send - * @cmnd_size: size in bytes of @cmnd - * @timeout: timeout for this request - * @copy_sense: request sense data if set to 1 - * - * This function is used to send a scsi command down to a target device - * as part of the error recovery process. If @copy_sense is 0 the command - * sent must be one that does not transfer any data. If @copy_sense is 1 - * the command must be REQUEST_SENSE and this functions copies out the - * sense buffer it got into @scmd->sense_buffer. + * scsi_send_eh_cmnd - send a cmd to a device as part of error recovery. + * @scmd: SCSI Cmd to send. + * @timeout: Timeout for cmd. * * Return value: * SUCCESS or FAILED or NEEDS_RETRY @@ -478,7 +469,6 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd, DECLARE_COMPLETION_ONSTACK(done); unsigned long timeleft; unsigned long flags; - struct scatterlist sgl; unsigned char old_cmnd[MAX_COMMAND_SIZE]; enum dma_data_direction old_data_direction; unsigned short old_use_sg; @@ -510,24 +500,19 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd, if (shost->hostt->unchecked_isa_dma) gfp_mask |= __GFP_DMA; - sgl.page = alloc_page(gfp_mask); - if (!sgl.page) - return FAILED; - sgl.offset = 0; - sgl.length = 252; - scmd->sc_data_direction = DMA_FROM_DEVICE; - scmd->request_bufflen = sgl.length; - scmd->request_buffer = &sgl; - scmd->use_sg = 1; + scmd->request_bufflen = 252; + scmd->request_buffer = kzalloc(scmd->request_bufflen, gfp_mask); + if (!scmd->request_buffer) + return FAILED; } else { scmd->request_buffer = NULL; scmd->request_bufflen = 0; scmd->sc_data_direction = DMA_NONE; - scmd->use_sg = 0; } scmd->underflow = 0; + scmd->use_sg = 0; scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]); if (sdev->scsi_level <= SCSI_2) @@ -598,7 +583,7 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd, memcpy(scmd->sense_buffer, scmd->request_buffer, sizeof(scmd->sense_buffer)); } - __free_page(sgl.page); + kfree(scmd->request_buffer); } diff --git a/trunk/drivers/scsi/scsi_lib.c b/trunk/drivers/scsi/scsi_lib.c index fb616c69151f..3ac4890ce086 100644 --- a/trunk/drivers/scsi/scsi_lib.c +++ b/trunk/drivers/scsi/scsi_lib.c @@ -704,7 +704,7 @@ static struct scsi_cmnd *scsi_end_request(struct scsi_cmnd *cmd, int uptodate, return NULL; } -struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask) +static struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask) { struct scsi_host_sg_pool *sgp; struct scatterlist *sgl; @@ -745,9 +745,7 @@ struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask) return sgl; } -EXPORT_SYMBOL(scsi_alloc_sgtable); - -void scsi_free_sgtable(struct scatterlist *sgl, int index) +static void scsi_free_sgtable(struct scatterlist *sgl, int index) { struct scsi_host_sg_pool *sgp; @@ -757,8 +755,6 @@ void scsi_free_sgtable(struct scatterlist *sgl, int index) mempool_free(sgl, sgp->pool); } -EXPORT_SYMBOL(scsi_free_sgtable); - /* * Function: scsi_release_buffers() * @@ -1000,14 +996,25 @@ static int scsi_init_io(struct scsi_cmnd *cmd) int count; /* - * We used to not use scatter-gather for single segment request, + * if this is a rq->data based REQ_BLOCK_PC, setup for a non-sg xfer + */ + if (blk_pc_request(req) && !req->bio) { + cmd->request_bufflen = req->data_len; + cmd->request_buffer = req->data; + req->buffer = req->data; + cmd->use_sg = 0; + return 0; + } + + /* + * we used to not use scatter-gather for single segment request, * but now we do (it makes highmem I/O easier to support without * kmapping pages) */ cmd->use_sg = req->nr_phys_segments; /* - * If sg table allocation fails, requeue request later. + * if sg table allocation fails, requeue request later. */ sgpnt = scsi_alloc_sgtable(cmd, GFP_ATOMIC); if (unlikely(!sgpnt)) { @@ -1015,21 +1022,24 @@ static int scsi_init_io(struct scsi_cmnd *cmd) return BLKPREP_DEFER; } - req->buffer = NULL; cmd->request_buffer = (char *) sgpnt; + cmd->request_bufflen = req->nr_sectors << 9; if (blk_pc_request(req)) cmd->request_bufflen = req->data_len; - else - cmd->request_bufflen = req->nr_sectors << 9; + req->buffer = NULL; /* * Next, walk the list, and fill in the addresses and sizes of * each segment. */ count = blk_rq_map_sg(req->q, req, cmd->request_buffer); + + /* + * mapped well, send it off + */ if (likely(count <= cmd->use_sg)) { cmd->use_sg = count; - return BLKPREP_OK; + return 0; } printk(KERN_ERR "Incorrect number of segments after building list\n"); @@ -1059,27 +1069,6 @@ static int scsi_issue_flush_fn(request_queue_t *q, struct gendisk *disk, return -EOPNOTSUPP; } -static struct scsi_cmnd *scsi_get_cmd_from_req(struct scsi_device *sdev, - struct request *req) -{ - struct scsi_cmnd *cmd; - - if (!req->special) { - cmd = scsi_get_command(sdev, GFP_ATOMIC); - if (unlikely(!cmd)) - return NULL; - req->special = cmd; - } else { - cmd = req->special; - } - - /* pull a tag out of the request if we have one */ - cmd->tag = req->tag; - cmd->request = req; - - return cmd; -} - static void scsi_blk_pc_done(struct scsi_cmnd *cmd) { BUG_ON(!blk_pc_request(cmd->request)); @@ -1092,37 +1081,9 @@ static void scsi_blk_pc_done(struct scsi_cmnd *cmd) scsi_io_completion(cmd, cmd->request_bufflen); } -static int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req) +static void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd) { - struct scsi_cmnd *cmd; - - cmd = scsi_get_cmd_from_req(sdev, req); - if (unlikely(!cmd)) - return BLKPREP_DEFER; - - /* - * BLOCK_PC requests may transfer data, in which case they must - * a bio attached to them. Or they might contain a SCSI command - * that does not transfer data, in which case they may optionally - * submit a request without an attached bio. - */ - if (req->bio) { - int ret; - - BUG_ON(!req->nr_phys_segments); - - ret = scsi_init_io(cmd); - if (unlikely(ret)) - return ret; - } else { - BUG_ON(req->data_len); - BUG_ON(req->data); - - cmd->request_bufflen = 0; - cmd->request_buffer = NULL; - cmd->use_sg = 0; - req->buffer = NULL; - } + struct request *req = cmd->request; BUILD_BUG_ON(sizeof(req->cmd) > sizeof(cmd->cmnd)); memcpy(cmd->cmnd, req->cmd, sizeof(cmd->cmnd)); @@ -1138,138 +1099,154 @@ static int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req) cmd->allowed = req->retries; cmd->timeout_per_command = req->timeout; cmd->done = scsi_blk_pc_done; - return BLKPREP_OK; -} - -/* - * Setup a REQ_TYPE_FS command. These are simple read/write request - * from filesystems that still need to be translated to SCSI CDBs from - * the ULD. - */ -static int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req) -{ - struct scsi_cmnd *cmd; - struct scsi_driver *drv; - int ret; - - /* - * Filesystem requests must transfer data. - */ - BUG_ON(!req->nr_phys_segments); - - cmd = scsi_get_cmd_from_req(sdev, req); - if (unlikely(!cmd)) - return BLKPREP_DEFER; - - ret = scsi_init_io(cmd); - if (unlikely(ret)) - return ret; - - /* - * Initialize the actual SCSI command for this request. - */ - drv = *(struct scsi_driver **)req->rq_disk->private_data; - if (unlikely(!drv->init_command(cmd))) { - scsi_release_buffers(cmd); - scsi_put_command(cmd); - return BLKPREP_KILL; - } - - return BLKPREP_OK; } static int scsi_prep_fn(struct request_queue *q, struct request *req) { struct scsi_device *sdev = q->queuedata; - int ret = BLKPREP_OK; + struct scsi_cmnd *cmd; + int specials_only = 0; /* - * If the device is not in running state we will reject some - * or all commands. + * Just check to see if the device is online. If it isn't, we + * refuse to process any commands. The device must be brought + * online before trying any recovery commands */ + if (unlikely(!scsi_device_online(sdev))) { + sdev_printk(KERN_ERR, sdev, + "rejecting I/O to offline device\n"); + goto kill; + } if (unlikely(sdev->sdev_state != SDEV_RUNNING)) { - switch (sdev->sdev_state) { - case SDEV_OFFLINE: - /* - * If the device is offline we refuse to process any - * commands. The device must be brought online - * before trying any recovery commands. - */ - sdev_printk(KERN_ERR, sdev, - "rejecting I/O to offline device\n"); - ret = BLKPREP_KILL; - break; - case SDEV_DEL: - /* - * If the device is fully deleted, we refuse to - * process any commands as well. - */ + /* OK, we're not in a running state don't prep + * user commands */ + if (sdev->sdev_state == SDEV_DEL) { + /* Device is fully deleted, no commands + * at all allowed down */ sdev_printk(KERN_ERR, sdev, "rejecting I/O to dead device\n"); - ret = BLKPREP_KILL; - break; - case SDEV_QUIESCE: - case SDEV_BLOCK: - /* - * If the devices is blocked we defer normal commands. - */ - if (!(req->cmd_flags & REQ_PREEMPT)) - ret = BLKPREP_DEFER; - break; - default: - /* - * For any other not fully online state we only allow - * special commands. In particular any user initiated - * command is not allowed. - */ - if (!(req->cmd_flags & REQ_PREEMPT)) - ret = BLKPREP_KILL; - break; + goto kill; } - - if (ret != BLKPREP_OK) - goto out; + /* OK, we only allow special commands (i.e. not + * user initiated ones */ + specials_only = sdev->sdev_state; } - switch (req->cmd_type) { - case REQ_TYPE_BLOCK_PC: - ret = scsi_setup_blk_pc_cmnd(sdev, req); - break; - case REQ_TYPE_FS: - ret = scsi_setup_fs_cmnd(sdev, req); - break; - default: + /* + * Find the actual device driver associated with this command. + * The SPECIAL requests are things like character device or + * ioctls, which did not originate from ll_rw_blk. Note that + * the special field is also used to indicate the cmd for + * the remainder of a partially fulfilled request that can + * come up when there is a medium error. We have to treat + * these two cases differently. We differentiate by looking + * at request->cmd, as this tells us the real story. + */ + if (blk_special_request(req) && req->special) + cmd = req->special; + else if (blk_pc_request(req) || blk_fs_request(req)) { + if (unlikely(specials_only) && !(req->cmd_flags & REQ_PREEMPT)){ + if (specials_only == SDEV_QUIESCE || + specials_only == SDEV_BLOCK) + goto defer; + + sdev_printk(KERN_ERR, sdev, + "rejecting I/O to device being removed\n"); + goto kill; + } + /* - * All other command types are not supported. - * - * Note that these days the SCSI subsystem does not use - * REQ_TYPE_SPECIAL requests anymore. These are only used - * (directly or via blk_insert_request) by non-SCSI drivers. + * Now try and find a command block that we can use. */ + if (!req->special) { + cmd = scsi_get_command(sdev, GFP_ATOMIC); + if (unlikely(!cmd)) + goto defer; + } else + cmd = req->special; + + /* pull a tag out of the request if we have one */ + cmd->tag = req->tag; + } else { blk_dump_rq_flags(req, "SCSI bad req"); - ret = BLKPREP_KILL; - break; + goto kill; } + + /* note the overloading of req->special. When the tag + * is active it always means cmd. If the tag goes + * back for re-queueing, it may be reset */ + req->special = cmd; + cmd->request = req; + + /* + * FIXME: drop the lock here because the functions below + * expect to be called without the queue lock held. Also, + * previously, we dequeued the request before dropping the + * lock. We hope REQ_STARTED prevents anything untoward from + * happening now. + */ + if (blk_fs_request(req) || blk_pc_request(req)) { + int ret; - out: - switch (ret) { - case BLKPREP_KILL: - req->errors = DID_NO_CONNECT << 16; - break; - case BLKPREP_DEFER: /* - * If we defer, the elv_next_request() returns NULL, but the - * queue must be restarted, so we plug here if no returning - * command will automatically do that. + * This will do a couple of things: + * 1) Fill in the actual SCSI command. + * 2) Fill in any other upper-level specific fields + * (timeout). + * + * If this returns 0, it means that the request failed + * (reading past end of disk, reading offline device, + * etc). This won't actually talk to the device, but + * some kinds of consistency checking may cause the + * request to be rejected immediately. */ - if (sdev->device_busy == 0) - blk_plug_device(q); - break; - default: - req->cmd_flags |= REQ_DONTPREP; + + /* + * This sets up the scatter-gather table (allocating if + * required). + */ + ret = scsi_init_io(cmd); + switch(ret) { + /* For BLKPREP_KILL/DEFER the cmd was released */ + case BLKPREP_KILL: + goto kill; + case BLKPREP_DEFER: + goto defer; + } + + /* + * Initialize the actual SCSI command for this request. + */ + if (blk_pc_request(req)) { + scsi_setup_blk_pc_cmnd(cmd); + } else if (req->rq_disk) { + struct scsi_driver *drv; + + drv = *(struct scsi_driver **)req->rq_disk->private_data; + if (unlikely(!drv->init_command(cmd))) { + scsi_release_buffers(cmd); + scsi_put_command(cmd); + goto kill; + } + } } - return ret; + /* + * The request is now prepped, no need to come back here + */ + req->cmd_flags |= REQ_DONTPREP; + return BLKPREP_OK; + + defer: + /* If we defer, the elv_next_request() returns NULL, but the + * queue must be restarted, so we plug here if no returning + * command will automatically do that. */ + if (sdev->device_busy == 0) + blk_plug_device(q); + return BLKPREP_DEFER; + kill: + req->errors = DID_NO_CONNECT << 16; + return BLKPREP_KILL; } /* @@ -1571,40 +1548,29 @@ u64 scsi_calculate_bounce_limit(struct Scsi_Host *shost) } EXPORT_SYMBOL(scsi_calculate_bounce_limit); -struct request_queue *__scsi_alloc_queue(struct Scsi_Host *shost, - request_fn_proc *request_fn) +struct request_queue *scsi_alloc_queue(struct scsi_device *sdev) { + struct Scsi_Host *shost = sdev->host; struct request_queue *q; - q = blk_init_queue(request_fn, NULL); + q = blk_init_queue(scsi_request_fn, NULL); if (!q) return NULL; + blk_queue_prep_rq(q, scsi_prep_fn); + blk_queue_max_hw_segments(q, shost->sg_tablesize); blk_queue_max_phys_segments(q, SCSI_MAX_PHYS_SEGMENTS); blk_queue_max_sectors(q, shost->max_sectors); blk_queue_bounce_limit(q, scsi_calculate_bounce_limit(shost)); blk_queue_segment_boundary(q, shost->dma_boundary); + blk_queue_issue_flush_fn(q, scsi_issue_flush_fn); + blk_queue_softirq_done(q, scsi_softirq_done); if (!shost->use_clustering) clear_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags); return q; } -EXPORT_SYMBOL(__scsi_alloc_queue); - -struct request_queue *scsi_alloc_queue(struct scsi_device *sdev) -{ - struct request_queue *q; - - q = __scsi_alloc_queue(sdev->host, scsi_request_fn); - if (!q) - return NULL; - - blk_queue_prep_rq(q, scsi_prep_fn); - blk_queue_issue_flush_fn(q, scsi_issue_flush_fn); - blk_queue_softirq_done(q, scsi_softirq_done); - return q; -} void scsi_free_queue(struct request_queue *q) { diff --git a/trunk/drivers/scsi/scsi_priv.h b/trunk/drivers/scsi/scsi_priv.h index f458c2f686d2..5d023d44e5e7 100644 --- a/trunk/drivers/scsi/scsi_priv.h +++ b/trunk/drivers/scsi/scsi_priv.h @@ -39,9 +39,6 @@ static inline void scsi_log_completion(struct scsi_cmnd *cmd, int disposition) { }; #endif -/* scsi_scan.c */ -int scsi_complete_async_scans(void); - /* scsi_devinfo.c */ extern int scsi_get_device_flags(struct scsi_device *sdev, const unsigned char *vendor, diff --git a/trunk/drivers/scsi/scsi_scan.c b/trunk/drivers/scsi/scsi_scan.c index 14e635aa44ce..94a274645f6f 100644 --- a/trunk/drivers/scsi/scsi_scan.c +++ b/trunk/drivers/scsi/scsi_scan.c @@ -29,9 +29,7 @@ #include #include #include -#include -#include -#include +#include #include #include @@ -89,17 +87,6 @@ module_param_named(max_luns, max_scsi_luns, int, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(max_luns, "last scsi LUN (should be between 1 and 2^32-1)"); -#ifdef CONFIG_SCSI_SCAN_ASYNC -#define SCSI_SCAN_TYPE_DEFAULT "async" -#else -#define SCSI_SCAN_TYPE_DEFAULT "sync" -#endif - -static char scsi_scan_type[6] = SCSI_SCAN_TYPE_DEFAULT; - -module_param_string(scan, scsi_scan_type, sizeof(scsi_scan_type), S_IRUGO); -MODULE_PARM_DESC(scan, "sync, async or none"); - /* * max_scsi_report_luns: the maximum number of LUNS that will be * returned from the REPORT LUNS command. 8 times this value must @@ -121,68 +108,6 @@ MODULE_PARM_DESC(inq_timeout, "Timeout (in seconds) waiting for devices to answer INQUIRY." " Default is 5. Some non-compliant devices need more."); -static DEFINE_SPINLOCK(async_scan_lock); -static LIST_HEAD(scanning_hosts); - -struct async_scan_data { - struct list_head list; - struct Scsi_Host *shost; - struct completion prev_finished; -}; - -/** - * scsi_complete_async_scans - Wait for asynchronous scans to complete - * - * Asynchronous scans add themselves to the scanning_hosts list. Once - * that list is empty, we know that the scans are complete. Rather than - * waking up periodically to check the state of the list, we pretend to be - * a scanning task by adding ourselves at the end of the list and going to - * sleep. When the task before us wakes us up, we take ourselves off the - * list and return. - */ -int scsi_complete_async_scans(void) -{ - struct async_scan_data *data; - - do { - if (list_empty(&scanning_hosts)) - return 0; - /* If we can't get memory immediately, that's OK. Just - * sleep a little. Even if we never get memory, the async - * scans will finish eventually. - */ - data = kmalloc(sizeof(*data), GFP_KERNEL); - if (!data) - msleep(1); - } while (!data); - - data->shost = NULL; - init_completion(&data->prev_finished); - - spin_lock(&async_scan_lock); - /* Check that there's still somebody else on the list */ - if (list_empty(&scanning_hosts)) - goto done; - list_add_tail(&data->list, &scanning_hosts); - spin_unlock(&async_scan_lock); - - printk(KERN_INFO "scsi: waiting for bus probes to complete ...\n"); - wait_for_completion(&data->prev_finished); - - spin_lock(&async_scan_lock); - list_del(&data->list); - done: - spin_unlock(&async_scan_lock); - - kfree(data); - return 0; -} - -#ifdef MODULE -/* Only exported for the benefit of scsi_wait_scan */ -EXPORT_SYMBOL_GPL(scsi_complete_async_scans); -#endif - /** * scsi_unlock_floptical - unlock device via a special MODE SENSE command * @sdev: scsi device to send command to @@ -437,10 +362,9 @@ static struct scsi_target *scsi_alloc_target(struct device *parent, goto retry; } -static void scsi_target_reap_usercontext(struct work_struct *work) +static void scsi_target_reap_usercontext(void *data) { - struct scsi_target *starget = - container_of(work, struct scsi_target, ew.work); + struct scsi_target *starget = data; struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); unsigned long flags; @@ -476,7 +400,7 @@ void scsi_target_reap(struct scsi_target *starget) starget->state = STARGET_DEL; spin_unlock_irqrestore(shost->host_lock, flags); execute_in_process_context(scsi_target_reap_usercontext, - &starget->ew); + starget, &starget->ew); return; } @@ -695,7 +619,7 @@ static int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result, * SCSI_SCAN_LUN_PRESENT: a new scsi_device was allocated and initialized **/ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, - int *bflags, int async) + int *bflags) { /* * XXX do not save the inquiry, since it can change underneath us, @@ -881,7 +805,7 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, * register it and tell the rest of the kernel * about it. */ - if (!async && scsi_sysfs_add_sdev(sdev) != 0) + if (scsi_sysfs_add_sdev(sdev) != 0) return SCSI_SCAN_NO_RESPONSE; return SCSI_SCAN_LUN_PRESENT; @@ -1050,7 +974,7 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget, goto out_free_result; } - res = scsi_add_lun(sdev, result, &bflags, shost->async_scan); + res = scsi_add_lun(sdev, result, &bflags); if (res == SCSI_SCAN_LUN_PRESENT) { if (bflags & BLIST_KEY) { sdev->lockable = 0; @@ -1550,12 +1474,6 @@ void scsi_scan_target(struct device *parent, unsigned int channel, { struct Scsi_Host *shost = dev_to_shost(parent); - if (strncmp(scsi_scan_type, "none", 4) == 0) - return; - - if (!shost->async_scan) - scsi_complete_async_scans(); - mutex_lock(&shost->scan_mutex); if (scsi_host_scan_allowed(shost)) __scsi_scan_target(parent, channel, id, lun, rescan); @@ -1601,9 +1519,6 @@ int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel, "%s: <%u:%u:%u>\n", __FUNCTION__, channel, id, lun)); - if (!shost->async_scan) - scsi_complete_async_scans(); - if (((channel != SCAN_WILD_CARD) && (channel > shost->max_channel)) || ((id != SCAN_WILD_CARD) && (id >= shost->max_id)) || ((lun != SCAN_WILD_CARD) && (lun > shost->max_lun))) @@ -1624,143 +1539,14 @@ int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel, return 0; } -static void scsi_sysfs_add_devices(struct Scsi_Host *shost) -{ - struct scsi_device *sdev; - shost_for_each_device(sdev, shost) { - if (scsi_sysfs_add_sdev(sdev) != 0) - scsi_destroy_sdev(sdev); - } -} - -/** - * scsi_prep_async_scan - prepare for an async scan - * @shost: the host which will be scanned - * Returns: a cookie to be passed to scsi_finish_async_scan() - * - * Tells the midlayer this host is going to do an asynchronous scan. - * It reserves the host's position in the scanning list and ensures - * that other asynchronous scans started after this one won't affect the - * ordering of the discovered devices. - */ -static struct async_scan_data *scsi_prep_async_scan(struct Scsi_Host *shost) -{ - struct async_scan_data *data; - - if (strncmp(scsi_scan_type, "sync", 4) == 0) - return NULL; - - if (shost->async_scan) { - printk("%s called twice for host %d", __FUNCTION__, - shost->host_no); - dump_stack(); - return NULL; - } - - data = kmalloc(sizeof(*data), GFP_KERNEL); - if (!data) - goto err; - data->shost = scsi_host_get(shost); - if (!data->shost) - goto err; - init_completion(&data->prev_finished); - - spin_lock(&async_scan_lock); - shost->async_scan = 1; - if (list_empty(&scanning_hosts)) - complete(&data->prev_finished); - list_add_tail(&data->list, &scanning_hosts); - spin_unlock(&async_scan_lock); - - return data; - - err: - kfree(data); - return NULL; -} - -/** - * scsi_finish_async_scan - asynchronous scan has finished - * @data: cookie returned from earlier call to scsi_prep_async_scan() - * - * All the devices currently attached to this host have been found. - * This function announces all the devices it has found to the rest - * of the system. - */ -static void scsi_finish_async_scan(struct async_scan_data *data) -{ - struct Scsi_Host *shost; - - if (!data) - return; - - shost = data->shost; - if (!shost->async_scan) { - printk("%s called twice for host %d", __FUNCTION__, - shost->host_no); - dump_stack(); - return; - } - - wait_for_completion(&data->prev_finished); - - scsi_sysfs_add_devices(shost); - - spin_lock(&async_scan_lock); - shost->async_scan = 0; - list_del(&data->list); - if (!list_empty(&scanning_hosts)) { - struct async_scan_data *next = list_entry(scanning_hosts.next, - struct async_scan_data, list); - complete(&next->prev_finished); - } - spin_unlock(&async_scan_lock); - - scsi_host_put(shost); - kfree(data); -} - -static void do_scsi_scan_host(struct Scsi_Host *shost) -{ - if (shost->hostt->scan_finished) { - unsigned long start = jiffies; - if (shost->hostt->scan_start) - shost->hostt->scan_start(shost); - - while (!shost->hostt->scan_finished(shost, jiffies - start)) - msleep(10); - } else { - scsi_scan_host_selected(shost, SCAN_WILD_CARD, SCAN_WILD_CARD, - SCAN_WILD_CARD, 0); - } -} - -static int do_scan_async(void *_data) -{ - struct async_scan_data *data = _data; - do_scsi_scan_host(data->shost); - scsi_finish_async_scan(data); - return 0; -} - /** * scsi_scan_host - scan the given adapter * @shost: adapter to scan **/ void scsi_scan_host(struct Scsi_Host *shost) { - struct async_scan_data *data; - - if (strncmp(scsi_scan_type, "none", 4) == 0) - return; - - data = scsi_prep_async_scan(shost); - if (!data) { - do_scsi_scan_host(shost); - return; - } - - kthread_run(do_scan_async, data, "scsi_scan_%d", shost->host_no); + scsi_scan_host_selected(shost, SCAN_WILD_CARD, SCAN_WILD_CARD, + SCAN_WILD_CARD, 0); } EXPORT_SYMBOL(scsi_scan_host); diff --git a/trunk/drivers/scsi/scsi_sysfs.c b/trunk/drivers/scsi/scsi_sysfs.c index 259c90cfa367..e1a91665d1c2 100644 --- a/trunk/drivers/scsi/scsi_sysfs.c +++ b/trunk/drivers/scsi/scsi_sysfs.c @@ -218,16 +218,16 @@ static void scsi_device_cls_release(struct class_device *class_dev) put_device(&sdev->sdev_gendev); } -static void scsi_device_dev_release_usercontext(struct work_struct *work) +static void scsi_device_dev_release_usercontext(void *data) { + struct device *dev = data; struct scsi_device *sdev; struct device *parent; struct scsi_target *starget; unsigned long flags; - sdev = container_of(work, struct scsi_device, ew.work); - - parent = sdev->sdev_gendev.parent; + parent = dev->parent; + sdev = to_scsi_device(dev); starget = to_scsi_target(parent); spin_lock_irqsave(sdev->host->host_lock, flags); @@ -258,7 +258,7 @@ static void scsi_device_dev_release_usercontext(struct work_struct *work) static void scsi_device_dev_release(struct device *dev) { struct scsi_device *sdp = to_scsi_device(dev); - execute_in_process_context(scsi_device_dev_release_usercontext, + execute_in_process_context(scsi_device_dev_release_usercontext, dev, &sdp->ew); } diff --git a/trunk/drivers/scsi/scsi_tgt_if.c b/trunk/drivers/scsi/scsi_tgt_if.c deleted file mode 100644 index 37bbfbdb870f..000000000000 --- a/trunk/drivers/scsi/scsi_tgt_if.c +++ /dev/null @@ -1,352 +0,0 @@ -/* - * SCSI target kernel/user interface functions - * - * Copyright (C) 2005 FUJITA Tomonori - * Copyright (C) 2005 Mike Christie - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "scsi_tgt_priv.h" - -struct tgt_ring { - u32 tr_idx; - unsigned long tr_pages[TGT_RING_PAGES]; - spinlock_t tr_lock; -}; - -/* tx_ring : kernel->user, rx_ring : user->kernel */ -static struct tgt_ring tx_ring, rx_ring; -static DECLARE_WAIT_QUEUE_HEAD(tgt_poll_wait); - -static inline void tgt_ring_idx_inc(struct tgt_ring *ring) -{ - if (ring->tr_idx == TGT_MAX_EVENTS - 1) - ring->tr_idx = 0; - else - ring->tr_idx++; -} - -static struct tgt_event *tgt_head_event(struct tgt_ring *ring, u32 idx) -{ - u32 pidx, off; - - pidx = idx / TGT_EVENT_PER_PAGE; - off = idx % TGT_EVENT_PER_PAGE; - - return (struct tgt_event *) - (ring->tr_pages[pidx] + sizeof(struct tgt_event) * off); -} - -static int tgt_uspace_send_event(u32 type, struct tgt_event *p) -{ - struct tgt_event *ev; - struct tgt_ring *ring = &tx_ring; - unsigned long flags; - int err = 0; - - spin_lock_irqsave(&ring->tr_lock, flags); - - ev = tgt_head_event(ring, ring->tr_idx); - if (!ev->hdr.status) - tgt_ring_idx_inc(ring); - else - err = -BUSY; - - spin_unlock_irqrestore(&ring->tr_lock, flags); - - if (err) - return err; - - memcpy(ev, p, sizeof(*ev)); - ev->hdr.type = type; - mb(); - ev->hdr.status = 1; - - flush_dcache_page(virt_to_page(ev)); - - wake_up_interruptible(&tgt_poll_wait); - - return 0; -} - -int scsi_tgt_uspace_send_cmd(struct scsi_cmnd *cmd, struct scsi_lun *lun, u64 tag) -{ - struct Scsi_Host *shost = scsi_tgt_cmd_to_host(cmd); - struct tgt_event ev; - int err; - - memset(&ev, 0, sizeof(ev)); - ev.p.cmd_req.host_no = shost->host_no; - ev.p.cmd_req.data_len = cmd->request_bufflen; - memcpy(ev.p.cmd_req.scb, cmd->cmnd, sizeof(ev.p.cmd_req.scb)); - memcpy(ev.p.cmd_req.lun, lun, sizeof(ev.p.cmd_req.lun)); - ev.p.cmd_req.attribute = cmd->tag; - ev.p.cmd_req.tag = tag; - - dprintk("%p %d %u %x %llx\n", cmd, shost->host_no, - ev.p.cmd_req.data_len, cmd->tag, - (unsigned long long) ev.p.cmd_req.tag); - - err = tgt_uspace_send_event(TGT_KEVENT_CMD_REQ, &ev); - if (err) - eprintk("tx buf is full, could not send\n"); - - return err; -} - -int scsi_tgt_uspace_send_status(struct scsi_cmnd *cmd, u64 tag) -{ - struct Scsi_Host *shost = scsi_tgt_cmd_to_host(cmd); - struct tgt_event ev; - int err; - - memset(&ev, 0, sizeof(ev)); - ev.p.cmd_done.host_no = shost->host_no; - ev.p.cmd_done.tag = tag; - ev.p.cmd_done.result = cmd->result; - - dprintk("%p %d %llu %u %x\n", cmd, shost->host_no, - (unsigned long long) ev.p.cmd_req.tag, - ev.p.cmd_req.data_len, cmd->tag); - - err = tgt_uspace_send_event(TGT_KEVENT_CMD_DONE, &ev); - if (err) - eprintk("tx buf is full, could not send\n"); - - return err; -} - -int scsi_tgt_uspace_send_tsk_mgmt(int host_no, int function, u64 tag, - struct scsi_lun *scsilun, void *data) -{ - struct tgt_event ev; - int err; - - memset(&ev, 0, sizeof(ev)); - ev.p.tsk_mgmt_req.host_no = host_no; - ev.p.tsk_mgmt_req.function = function; - ev.p.tsk_mgmt_req.tag = tag; - memcpy(ev.p.tsk_mgmt_req.lun, scsilun, sizeof(ev.p.tsk_mgmt_req.lun)); - ev.p.tsk_mgmt_req.mid = (u64) (unsigned long) data; - - dprintk("%d %x %llx %llx\n", host_no, function, (unsigned long long) tag, - (unsigned long long) ev.p.tsk_mgmt_req.mid); - - err = tgt_uspace_send_event(TGT_KEVENT_TSK_MGMT_REQ, &ev); - if (err) - eprintk("tx buf is full, could not send\n"); - - return err; -} - -static int event_recv_msg(struct tgt_event *ev) -{ - int err = 0; - - switch (ev->hdr.type) { - case TGT_UEVENT_CMD_RSP: - err = scsi_tgt_kspace_exec(ev->p.cmd_rsp.host_no, - ev->p.cmd_rsp.tag, - ev->p.cmd_rsp.result, - ev->p.cmd_rsp.len, - ev->p.cmd_rsp.uaddr, - ev->p.cmd_rsp.rw); - break; - case TGT_UEVENT_TSK_MGMT_RSP: - err = scsi_tgt_kspace_tsk_mgmt(ev->p.tsk_mgmt_rsp.host_no, - ev->p.tsk_mgmt_rsp.mid, - ev->p.tsk_mgmt_rsp.result); - break; - default: - eprintk("unknown type %d\n", ev->hdr.type); - err = -EINVAL; - } - - return err; -} - -static ssize_t tgt_write(struct file *file, const char __user * buffer, - size_t count, loff_t * ppos) -{ - struct tgt_event *ev; - struct tgt_ring *ring = &rx_ring; - - while (1) { - ev = tgt_head_event(ring, ring->tr_idx); - /* do we need this? */ - flush_dcache_page(virt_to_page(ev)); - - if (!ev->hdr.status) - break; - - tgt_ring_idx_inc(ring); - event_recv_msg(ev); - ev->hdr.status = 0; - }; - - return count; -} - -static unsigned int tgt_poll(struct file * file, struct poll_table_struct *wait) -{ - struct tgt_event *ev; - struct tgt_ring *ring = &tx_ring; - unsigned long flags; - unsigned int mask = 0; - u32 idx; - - poll_wait(file, &tgt_poll_wait, wait); - - spin_lock_irqsave(&ring->tr_lock, flags); - - idx = ring->tr_idx ? ring->tr_idx - 1 : TGT_MAX_EVENTS - 1; - ev = tgt_head_event(ring, idx); - if (ev->hdr.status) - mask |= POLLIN | POLLRDNORM; - - spin_unlock_irqrestore(&ring->tr_lock, flags); - - return mask; -} - -static int uspace_ring_map(struct vm_area_struct *vma, unsigned long addr, - struct tgt_ring *ring) -{ - int i, err; - - for (i = 0; i < TGT_RING_PAGES; i++) { - struct page *page = virt_to_page(ring->tr_pages[i]); - err = vm_insert_page(vma, addr, page); - if (err) - return err; - addr += PAGE_SIZE; - } - - return 0; -} - -static int tgt_mmap(struct file *filp, struct vm_area_struct *vma) -{ - unsigned long addr; - int err; - - if (vma->vm_pgoff) - return -EINVAL; - - if (vma->vm_end - vma->vm_start != TGT_RING_SIZE * 2) { - eprintk("mmap size must be %lu, not %lu \n", - TGT_RING_SIZE * 2, vma->vm_end - vma->vm_start); - return -EINVAL; - } - - addr = vma->vm_start; - err = uspace_ring_map(vma, addr, &tx_ring); - if (err) - return err; - err = uspace_ring_map(vma, addr + TGT_RING_SIZE, &rx_ring); - - return err; -} - -static int tgt_open(struct inode *inode, struct file *file) -{ - tx_ring.tr_idx = rx_ring.tr_idx = 0; - - return 0; -} - -static struct file_operations tgt_fops = { - .owner = THIS_MODULE, - .open = tgt_open, - .poll = tgt_poll, - .write = tgt_write, - .mmap = tgt_mmap, -}; - -static struct miscdevice tgt_miscdev = { - .minor = MISC_DYNAMIC_MINOR, - .name = "tgt", - .fops = &tgt_fops, -}; - -static void tgt_ring_exit(struct tgt_ring *ring) -{ - int i; - - for (i = 0; i < TGT_RING_PAGES; i++) - free_page(ring->tr_pages[i]); -} - -static int tgt_ring_init(struct tgt_ring *ring) -{ - int i; - - spin_lock_init(&ring->tr_lock); - - for (i = 0; i < TGT_RING_PAGES; i++) { - ring->tr_pages[i] = get_zeroed_page(GFP_KERNEL); - if (!ring->tr_pages[i]) { - eprintk("out of memory\n"); - return -ENOMEM; - } - } - - return 0; -} - -void scsi_tgt_if_exit(void) -{ - tgt_ring_exit(&tx_ring); - tgt_ring_exit(&rx_ring); - misc_deregister(&tgt_miscdev); -} - -int scsi_tgt_if_init(void) -{ - int err; - - err = tgt_ring_init(&tx_ring); - if (err) - return err; - - err = tgt_ring_init(&rx_ring); - if (err) - goto free_tx_ring; - - err = misc_register(&tgt_miscdev); - if (err) - goto free_rx_ring; - - return 0; -free_rx_ring: - tgt_ring_exit(&rx_ring); -free_tx_ring: - tgt_ring_exit(&tx_ring); - - return err; -} diff --git a/trunk/drivers/scsi/scsi_tgt_lib.c b/trunk/drivers/scsi/scsi_tgt_lib.c deleted file mode 100644 index 386dbae17b44..000000000000 --- a/trunk/drivers/scsi/scsi_tgt_lib.c +++ /dev/null @@ -1,745 +0,0 @@ -/* - * SCSI target lib functions - * - * Copyright (C) 2005 Mike Christie - * Copyright (C) 2005 FUJITA Tomonori - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include <../drivers/md/dm-bio-list.h> - -#include "scsi_tgt_priv.h" - -static struct workqueue_struct *scsi_tgtd; -static kmem_cache_t *scsi_tgt_cmd_cache; - -/* - * TODO: this struct will be killed when the block layer supports large bios - * and James's work struct code is in - */ -struct scsi_tgt_cmd { - /* TODO replace work with James b's code */ - struct work_struct work; - /* TODO replace the lists with a large bio */ - struct bio_list xfer_done_list; - struct bio_list xfer_list; - - struct list_head hash_list; - struct request *rq; - u64 tag; - - void *buffer; - unsigned bufflen; -}; - -#define TGT_HASH_ORDER 4 -#define cmd_hashfn(tag) hash_long((unsigned long) (tag), TGT_HASH_ORDER) - -struct scsi_tgt_queuedata { - struct Scsi_Host *shost; - struct list_head cmd_hash[1 << TGT_HASH_ORDER]; - spinlock_t cmd_hash_lock; -}; - -/* - * Function: scsi_host_get_command() - * - * Purpose: Allocate and setup a scsi command block and blk request - * - * Arguments: shost - scsi host - * data_dir - dma data dir - * gfp_mask- allocator flags - * - * Returns: The allocated scsi command structure. - * - * This should be called by target LLDs to get a command. - */ -struct scsi_cmnd *scsi_host_get_command(struct Scsi_Host *shost, - enum dma_data_direction data_dir, - gfp_t gfp_mask) -{ - int write = (data_dir == DMA_TO_DEVICE); - struct request *rq; - struct scsi_cmnd *cmd; - struct scsi_tgt_cmd *tcmd; - - /* Bail if we can't get a reference to the device */ - if (!get_device(&shost->shost_gendev)) - return NULL; - - tcmd = kmem_cache_alloc(scsi_tgt_cmd_cache, GFP_ATOMIC); - if (!tcmd) - goto put_dev; - - rq = blk_get_request(shost->uspace_req_q, write, gfp_mask); - if (!rq) - goto free_tcmd; - - cmd = __scsi_get_command(shost, gfp_mask); - if (!cmd) - goto release_rq; - - memset(cmd, 0, sizeof(*cmd)); - cmd->sc_data_direction = data_dir; - cmd->jiffies_at_alloc = jiffies; - cmd->request = rq; - - rq->special = cmd; - rq->cmd_type = REQ_TYPE_SPECIAL; - rq->cmd_flags |= REQ_TYPE_BLOCK_PC; - rq->end_io_data = tcmd; - - bio_list_init(&tcmd->xfer_list); - bio_list_init(&tcmd->xfer_done_list); - tcmd->rq = rq; - - return cmd; - -release_rq: - blk_put_request(rq); -free_tcmd: - kmem_cache_free(scsi_tgt_cmd_cache, tcmd); -put_dev: - put_device(&shost->shost_gendev); - return NULL; - -} -EXPORT_SYMBOL_GPL(scsi_host_get_command); - -/* - * Function: scsi_host_put_command() - * - * Purpose: Free a scsi command block - * - * Arguments: shost - scsi host - * cmd - command block to free - * - * Returns: Nothing. - * - * Notes: The command must not belong to any lists. - */ -void scsi_host_put_command(struct Scsi_Host *shost, struct scsi_cmnd *cmd) -{ - struct request_queue *q = shost->uspace_req_q; - struct request *rq = cmd->request; - struct scsi_tgt_cmd *tcmd = rq->end_io_data; - unsigned long flags; - - kmem_cache_free(scsi_tgt_cmd_cache, tcmd); - - spin_lock_irqsave(q->queue_lock, flags); - __blk_put_request(q, rq); - spin_unlock_irqrestore(q->queue_lock, flags); - - __scsi_put_command(shost, cmd, &shost->shost_gendev); -} -EXPORT_SYMBOL_GPL(scsi_host_put_command); - -static void scsi_unmap_user_pages(struct scsi_tgt_cmd *tcmd) -{ - struct bio *bio; - - /* must call bio_endio in case bio was bounced */ - while ((bio = bio_list_pop(&tcmd->xfer_done_list))) { - bio_endio(bio, bio->bi_size, 0); - bio_unmap_user(bio); - } - - while ((bio = bio_list_pop(&tcmd->xfer_list))) { - bio_endio(bio, bio->bi_size, 0); - bio_unmap_user(bio); - } -} - -static void cmd_hashlist_del(struct scsi_cmnd *cmd) -{ - struct request_queue *q = cmd->request->q; - struct scsi_tgt_queuedata *qdata = q->queuedata; - unsigned long flags; - struct scsi_tgt_cmd *tcmd = cmd->request->end_io_data; - - spin_lock_irqsave(&qdata->cmd_hash_lock, flags); - list_del(&tcmd->hash_list); - spin_unlock_irqrestore(&qdata->cmd_hash_lock, flags); -} - -static void scsi_tgt_cmd_destroy(struct work_struct *work) -{ - struct scsi_tgt_cmd *tcmd = - container_of(work, struct scsi_tgt_cmd, work); - struct scsi_cmnd *cmd = tcmd->rq->special; - - dprintk("cmd %p %d %lu\n", cmd, cmd->sc_data_direction, - rq_data_dir(cmd->request)); - /* - * We fix rq->cmd_flags here since when we told bio_map_user - * to write vm for WRITE commands, blk_rq_bio_prep set - * rq_data_dir the flags to READ. - */ - if (cmd->sc_data_direction == DMA_TO_DEVICE) - cmd->request->cmd_flags |= REQ_RW; - else - cmd->request->cmd_flags &= ~REQ_RW; - - scsi_unmap_user_pages(tcmd); - scsi_host_put_command(scsi_tgt_cmd_to_host(cmd), cmd); -} - -static void init_scsi_tgt_cmd(struct request *rq, struct scsi_tgt_cmd *tcmd, - u64 tag) -{ - struct scsi_tgt_queuedata *qdata = rq->q->queuedata; - unsigned long flags; - struct list_head *head; - - tcmd->tag = tag; - INIT_WORK(&tcmd->work, scsi_tgt_cmd_destroy); - spin_lock_irqsave(&qdata->cmd_hash_lock, flags); - head = &qdata->cmd_hash[cmd_hashfn(tag)]; - list_add(&tcmd->hash_list, head); - spin_unlock_irqrestore(&qdata->cmd_hash_lock, flags); -} - -/* - * scsi_tgt_alloc_queue - setup queue used for message passing - * shost: scsi host - * - * This should be called by the LLD after host allocation. - * And will be released when the host is released. - */ -int scsi_tgt_alloc_queue(struct Scsi_Host *shost) -{ - struct scsi_tgt_queuedata *queuedata; - struct request_queue *q; - int err, i; - - /* - * Do we need to send a netlink event or should uspace - * just respond to the hotplug event? - */ - q = __scsi_alloc_queue(shost, NULL); - if (!q) - return -ENOMEM; - - queuedata = kzalloc(sizeof(*queuedata), GFP_KERNEL); - if (!queuedata) { - err = -ENOMEM; - goto cleanup_queue; - } - queuedata->shost = shost; - q->queuedata = queuedata; - - /* - * this is a silly hack. We should probably just queue as many - * command as is recvd to userspace. uspace can then make - * sure we do not overload the HBA - */ - q->nr_requests = shost->hostt->can_queue; - /* - * We currently only support software LLDs so this does - * not matter for now. Do we need this for the cards we support? - * If so we should make it a host template value. - */ - blk_queue_dma_alignment(q, 0); - shost->uspace_req_q = q; - - for (i = 0; i < ARRAY_SIZE(queuedata->cmd_hash); i++) - INIT_LIST_HEAD(&queuedata->cmd_hash[i]); - spin_lock_init(&queuedata->cmd_hash_lock); - - return 0; - -cleanup_queue: - blk_cleanup_queue(q); - return err; -} -EXPORT_SYMBOL_GPL(scsi_tgt_alloc_queue); - -void scsi_tgt_free_queue(struct Scsi_Host *shost) -{ - int i; - unsigned long flags; - struct request_queue *q = shost->uspace_req_q; - struct scsi_cmnd *cmd; - struct scsi_tgt_queuedata *qdata = q->queuedata; - struct scsi_tgt_cmd *tcmd, *n; - LIST_HEAD(cmds); - - spin_lock_irqsave(&qdata->cmd_hash_lock, flags); - - for (i = 0; i < ARRAY_SIZE(qdata->cmd_hash); i++) { - list_for_each_entry_safe(tcmd, n, &qdata->cmd_hash[i], - hash_list) { - list_del(&tcmd->hash_list); - list_add(&tcmd->hash_list, &cmds); - } - } - - spin_unlock_irqrestore(&qdata->cmd_hash_lock, flags); - - while (!list_empty(&cmds)) { - tcmd = list_entry(cmds.next, struct scsi_tgt_cmd, hash_list); - list_del(&tcmd->hash_list); - cmd = tcmd->rq->special; - - shost->hostt->eh_abort_handler(cmd); - scsi_tgt_cmd_destroy(&tcmd->work); - } -} -EXPORT_SYMBOL_GPL(scsi_tgt_free_queue); - -struct Scsi_Host *scsi_tgt_cmd_to_host(struct scsi_cmnd *cmd) -{ - struct scsi_tgt_queuedata *queue = cmd->request->q->queuedata; - return queue->shost; -} -EXPORT_SYMBOL_GPL(scsi_tgt_cmd_to_host); - -/* - * scsi_tgt_queue_command - queue command for userspace processing - * @cmd: scsi command - * @scsilun: scsi lun - * @tag: unique value to identify this command for tmf - */ -int scsi_tgt_queue_command(struct scsi_cmnd *cmd, struct scsi_lun *scsilun, - u64 tag) -{ - struct scsi_tgt_cmd *tcmd = cmd->request->end_io_data; - int err; - - init_scsi_tgt_cmd(cmd->request, tcmd, tag); - err = scsi_tgt_uspace_send_cmd(cmd, scsilun, tag); - if (err) - cmd_hashlist_del(cmd); - - return err; -} -EXPORT_SYMBOL_GPL(scsi_tgt_queue_command); - -/* - * This is run from a interrpt handler normally and the unmap - * needs process context so we must queue - */ -static void scsi_tgt_cmd_done(struct scsi_cmnd *cmd) -{ - struct scsi_tgt_cmd *tcmd = cmd->request->end_io_data; - - dprintk("cmd %p %lu\n", cmd, rq_data_dir(cmd->request)); - - scsi_tgt_uspace_send_status(cmd, tcmd->tag); - queue_work(scsi_tgtd, &tcmd->work); -} - -static int __scsi_tgt_transfer_response(struct scsi_cmnd *cmd) -{ - struct Scsi_Host *shost = scsi_tgt_cmd_to_host(cmd); - int err; - - dprintk("cmd %p %lu\n", cmd, rq_data_dir(cmd->request)); - - err = shost->hostt->transfer_response(cmd, scsi_tgt_cmd_done); - switch (err) { - case SCSI_MLQUEUE_HOST_BUSY: - case SCSI_MLQUEUE_DEVICE_BUSY: - return -EAGAIN; - } - - return 0; -} - -static void scsi_tgt_transfer_response(struct scsi_cmnd *cmd) -{ - struct scsi_tgt_cmd *tcmd = cmd->request->end_io_data; - int err; - - err = __scsi_tgt_transfer_response(cmd); - if (!err) - return; - - cmd->result = DID_BUS_BUSY << 16; - err = scsi_tgt_uspace_send_status(cmd, tcmd->tag); - if (err <= 0) - /* the eh will have to pick this up */ - printk(KERN_ERR "Could not send cmd %p status\n", cmd); -} - -static int scsi_tgt_init_cmd(struct scsi_cmnd *cmd, gfp_t gfp_mask) -{ - struct request *rq = cmd->request; - struct scsi_tgt_cmd *tcmd = rq->end_io_data; - int count; - - cmd->use_sg = rq->nr_phys_segments; - cmd->request_buffer = scsi_alloc_sgtable(cmd, gfp_mask); - if (!cmd->request_buffer) - return -ENOMEM; - - cmd->request_bufflen = rq->data_len; - - dprintk("cmd %p addr %p cnt %d %lu\n", cmd, tcmd->buffer, cmd->use_sg, - rq_data_dir(rq)); - count = blk_rq_map_sg(rq->q, rq, cmd->request_buffer); - if (likely(count <= cmd->use_sg)) { - cmd->use_sg = count; - return 0; - } - - eprintk("cmd %p addr %p cnt %d\n", cmd, tcmd->buffer, cmd->use_sg); - scsi_free_sgtable(cmd->request_buffer, cmd->sglist_len); - return -EINVAL; -} - -/* TODO: test this crap and replace bio_map_user with new interface maybe */ -static int scsi_map_user_pages(struct scsi_tgt_cmd *tcmd, struct scsi_cmnd *cmd, - int rw) -{ - struct request_queue *q = cmd->request->q; - struct request *rq = cmd->request; - void *uaddr = tcmd->buffer; - unsigned int len = tcmd->bufflen; - struct bio *bio; - int err; - - while (len > 0) { - dprintk("%lx %u\n", (unsigned long) uaddr, len); - bio = bio_map_user(q, NULL, (unsigned long) uaddr, len, rw); - if (IS_ERR(bio)) { - err = PTR_ERR(bio); - dprintk("fail to map %lx %u %d %x\n", - (unsigned long) uaddr, len, err, cmd->cmnd[0]); - goto unmap_bios; - } - - uaddr += bio->bi_size; - len -= bio->bi_size; - - /* - * The first bio is added and merged. We could probably - * try to add others using scsi_merge_bio() but for now - * we keep it simple. The first bio should be pretty large - * (either hitting the 1 MB bio pages limit or a queue limit) - * already but for really large IO we may want to try and - * merge these. - */ - if (!rq->bio) { - blk_rq_bio_prep(q, rq, bio); - rq->data_len = bio->bi_size; - } else - /* put list of bios to transfer in next go around */ - bio_list_add(&tcmd->xfer_list, bio); - } - - cmd->offset = 0; - err = scsi_tgt_init_cmd(cmd, GFP_KERNEL); - if (err) - goto unmap_bios; - - return 0; - -unmap_bios: - if (rq->bio) { - bio_unmap_user(rq->bio); - while ((bio = bio_list_pop(&tcmd->xfer_list))) - bio_unmap_user(bio); - } - - return err; -} - -static int scsi_tgt_transfer_data(struct scsi_cmnd *); - -static void scsi_tgt_data_transfer_done(struct scsi_cmnd *cmd) -{ - struct scsi_tgt_cmd *tcmd = cmd->request->end_io_data; - struct bio *bio; - int err; - - /* should we free resources here on error ? */ - if (cmd->result) { -send_uspace_err: - err = scsi_tgt_uspace_send_status(cmd, tcmd->tag); - if (err <= 0) - /* the tgt uspace eh will have to pick this up */ - printk(KERN_ERR "Could not send cmd %p status\n", cmd); - return; - } - - dprintk("cmd %p request_bufflen %u bufflen %u\n", - cmd, cmd->request_bufflen, tcmd->bufflen); - - scsi_free_sgtable(cmd->request_buffer, cmd->sglist_len); - bio_list_add(&tcmd->xfer_done_list, cmd->request->bio); - - tcmd->buffer += cmd->request_bufflen; - cmd->offset += cmd->request_bufflen; - - if (!tcmd->xfer_list.head) { - scsi_tgt_transfer_response(cmd); - return; - } - - dprintk("cmd2 %p request_bufflen %u bufflen %u\n", - cmd, cmd->request_bufflen, tcmd->bufflen); - - bio = bio_list_pop(&tcmd->xfer_list); - BUG_ON(!bio); - - blk_rq_bio_prep(cmd->request->q, cmd->request, bio); - cmd->request->data_len = bio->bi_size; - err = scsi_tgt_init_cmd(cmd, GFP_ATOMIC); - if (err) { - cmd->result = DID_ERROR << 16; - goto send_uspace_err; - } - - if (scsi_tgt_transfer_data(cmd)) { - cmd->result = DID_NO_CONNECT << 16; - goto send_uspace_err; - } -} - -static int scsi_tgt_transfer_data(struct scsi_cmnd *cmd) -{ - int err; - struct Scsi_Host *host = scsi_tgt_cmd_to_host(cmd); - - err = host->hostt->transfer_data(cmd, scsi_tgt_data_transfer_done); - switch (err) { - case SCSI_MLQUEUE_HOST_BUSY: - case SCSI_MLQUEUE_DEVICE_BUSY: - return -EAGAIN; - default: - return 0; - } -} - -static int scsi_tgt_copy_sense(struct scsi_cmnd *cmd, unsigned long uaddr, - unsigned len) -{ - char __user *p = (char __user *) uaddr; - - if (copy_from_user(cmd->sense_buffer, p, - min_t(unsigned, SCSI_SENSE_BUFFERSIZE, len))) { - printk(KERN_ERR "Could not copy the sense buffer\n"); - return -EIO; - } - return 0; -} - -static int scsi_tgt_abort_cmd(struct Scsi_Host *shost, struct scsi_cmnd *cmd) -{ - struct scsi_tgt_cmd *tcmd; - int err; - - err = shost->hostt->eh_abort_handler(cmd); - if (err) - eprintk("fail to abort %p\n", cmd); - - tcmd = cmd->request->end_io_data; - scsi_tgt_cmd_destroy(&tcmd->work); - return err; -} - -static struct request *tgt_cmd_hash_lookup(struct request_queue *q, u64 tag) -{ - struct scsi_tgt_queuedata *qdata = q->queuedata; - struct request *rq = NULL; - struct list_head *head; - struct scsi_tgt_cmd *tcmd; - unsigned long flags; - - head = &qdata->cmd_hash[cmd_hashfn(tag)]; - spin_lock_irqsave(&qdata->cmd_hash_lock, flags); - list_for_each_entry(tcmd, head, hash_list) { - if (tcmd->tag == tag) { - rq = tcmd->rq; - list_del(&tcmd->hash_list); - break; - } - } - spin_unlock_irqrestore(&qdata->cmd_hash_lock, flags); - - return rq; -} - -int scsi_tgt_kspace_exec(int host_no, u64 tag, int result, u32 len, - unsigned long uaddr, u8 rw) -{ - struct Scsi_Host *shost; - struct scsi_cmnd *cmd; - struct request *rq; - struct scsi_tgt_cmd *tcmd; - int err = 0; - - dprintk("%d %llu %d %u %lx %u\n", host_no, (unsigned long long) tag, - result, len, uaddr, rw); - - /* TODO: replace with a O(1) alg */ - shost = scsi_host_lookup(host_no); - if (IS_ERR(shost)) { - printk(KERN_ERR "Could not find host no %d\n", host_no); - return -EINVAL; - } - - if (!shost->uspace_req_q) { - printk(KERN_ERR "Not target scsi host %d\n", host_no); - goto done; - } - - rq = tgt_cmd_hash_lookup(shost->uspace_req_q, tag); - if (!rq) { - printk(KERN_ERR "Could not find tag %llu\n", - (unsigned long long) tag); - err = -EINVAL; - goto done; - } - cmd = rq->special; - - dprintk("cmd %p result %d len %d bufflen %u %lu %x\n", cmd, - result, len, cmd->request_bufflen, rq_data_dir(rq), cmd->cmnd[0]); - - if (result == TASK_ABORTED) { - scsi_tgt_abort_cmd(shost, cmd); - goto done; - } - /* - * store the userspace values here, the working values are - * in the request_* values - */ - tcmd = cmd->request->end_io_data; - tcmd->buffer = (void *)uaddr; - tcmd->bufflen = len; - cmd->result = result; - - if (!tcmd->bufflen || cmd->request_buffer) { - err = __scsi_tgt_transfer_response(cmd); - goto done; - } - - /* - * TODO: Do we need to handle case where request does not - * align with LLD. - */ - err = scsi_map_user_pages(rq->end_io_data, cmd, rw); - if (err) { - eprintk("%p %d\n", cmd, err); - err = -EAGAIN; - goto done; - } - - /* userspace failure */ - if (cmd->result) { - if (status_byte(cmd->result) == CHECK_CONDITION) - scsi_tgt_copy_sense(cmd, uaddr, len); - err = __scsi_tgt_transfer_response(cmd); - goto done; - } - /* ask the target LLD to transfer the data to the buffer */ - err = scsi_tgt_transfer_data(cmd); - -done: - scsi_host_put(shost); - return err; -} - -int scsi_tgt_tsk_mgmt_request(struct Scsi_Host *shost, int function, u64 tag, - struct scsi_lun *scsilun, void *data) -{ - int err; - - /* TODO: need to retry if this fails. */ - err = scsi_tgt_uspace_send_tsk_mgmt(shost->host_no, function, - tag, scsilun, data); - if (err < 0) - eprintk("The task management request lost!\n"); - return err; -} -EXPORT_SYMBOL_GPL(scsi_tgt_tsk_mgmt_request); - -int scsi_tgt_kspace_tsk_mgmt(int host_no, u64 mid, int result) -{ - struct Scsi_Host *shost; - int err = -EINVAL; - - dprintk("%d %d %llx\n", host_no, result, (unsigned long long) mid); - - shost = scsi_host_lookup(host_no); - if (IS_ERR(shost)) { - printk(KERN_ERR "Could not find host no %d\n", host_no); - return err; - } - - if (!shost->uspace_req_q) { - printk(KERN_ERR "Not target scsi host %d\n", host_no); - goto done; - } - - err = shost->hostt->tsk_mgmt_response(mid, result); -done: - scsi_host_put(shost); - return err; -} - -static int __init scsi_tgt_init(void) -{ - int err; - - scsi_tgt_cmd_cache = kmem_cache_create("scsi_tgt_cmd", - sizeof(struct scsi_tgt_cmd), - 0, 0, NULL, NULL); - if (!scsi_tgt_cmd_cache) - return -ENOMEM; - - scsi_tgtd = create_workqueue("scsi_tgtd"); - if (!scsi_tgtd) { - err = -ENOMEM; - goto free_kmemcache; - } - - err = scsi_tgt_if_init(); - if (err) - goto destroy_wq; - - return 0; - -destroy_wq: - destroy_workqueue(scsi_tgtd); -free_kmemcache: - kmem_cache_destroy(scsi_tgt_cmd_cache); - return err; -} - -static void __exit scsi_tgt_exit(void) -{ - destroy_workqueue(scsi_tgtd); - scsi_tgt_if_exit(); - kmem_cache_destroy(scsi_tgt_cmd_cache); -} - -module_init(scsi_tgt_init); -module_exit(scsi_tgt_exit); - -MODULE_DESCRIPTION("SCSI target core"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/scsi/scsi_tgt_priv.h b/trunk/drivers/scsi/scsi_tgt_priv.h deleted file mode 100644 index 84488c51ff62..000000000000 --- a/trunk/drivers/scsi/scsi_tgt_priv.h +++ /dev/null @@ -1,25 +0,0 @@ -struct scsi_cmnd; -struct scsi_lun; -struct Scsi_Host; -struct task_struct; - -/* tmp - will replace with SCSI logging stuff */ -#define eprintk(fmt, args...) \ -do { \ - printk("%s(%d) " fmt, __FUNCTION__, __LINE__, ##args); \ -} while (0) - -#define dprintk(fmt, args...) -/* #define dprintk eprintk */ - -extern void scsi_tgt_if_exit(void); -extern int scsi_tgt_if_init(void); - -extern int scsi_tgt_uspace_send_cmd(struct scsi_cmnd *cmd, struct scsi_lun *lun, - u64 tag); -extern int scsi_tgt_uspace_send_status(struct scsi_cmnd *cmd, u64 tag); -extern int scsi_tgt_kspace_exec(int host_no, u64 tag, int result, u32 len, - unsigned long uaddr, u8 rw); -extern int scsi_tgt_uspace_send_tsk_mgmt(int host_no, int function, u64 tag, - struct scsi_lun *scsilun, void *data); -extern int scsi_tgt_kspace_tsk_mgmt(int host_no, u64 mid, int result); diff --git a/trunk/drivers/scsi/scsi_transport_fc.c b/trunk/drivers/scsi/scsi_transport_fc.c index 3571ce8934e7..38c215a78f69 100644 --- a/trunk/drivers/scsi/scsi_transport_fc.c +++ b/trunk/drivers/scsi/scsi_transport_fc.c @@ -241,9 +241,9 @@ fc_bitfield_name_search(remote_port_roles, fc_remote_port_role_names) #define FC_MGMTSRVR_PORTID 0x00000a -static void fc_timeout_deleted_rport(struct work_struct *work); -static void fc_timeout_fail_rport_io(struct work_struct *work); -static void fc_scsi_scan_rport(struct work_struct *work); +static void fc_timeout_deleted_rport(void *data); +static void fc_timeout_fail_rport_io(void *data); +static void fc_scsi_scan_rport(void *data); /* * Attribute counts pre object type... @@ -1613,7 +1613,7 @@ fc_flush_work(struct Scsi_Host *shost) * 1 on success / 0 already queued / < 0 for error **/ static int -fc_queue_devloss_work(struct Scsi_Host *shost, struct delayed_work *work, +fc_queue_devloss_work(struct Scsi_Host *shost, struct work_struct *work, unsigned long delay) { if (unlikely(!fc_host_devloss_work_q(shost))) { @@ -1625,6 +1625,9 @@ fc_queue_devloss_work(struct Scsi_Host *shost, struct delayed_work *work, return -EINVAL; } + if (delay == 0) + return queue_work(fc_host_devloss_work_q(shost), work); + return queue_delayed_work(fc_host_devloss_work_q(shost), work, delay); } @@ -1709,13 +1712,12 @@ EXPORT_SYMBOL(fc_remove_host); * fc_starget_delete - called to delete the scsi decendents of an rport * (target and all sdevs) * - * @work: remote port to be operated on. + * @data: remote port to be operated on. **/ static void -fc_starget_delete(struct work_struct *work) +fc_starget_delete(void *data) { - struct fc_rport *rport = - container_of(work, struct fc_rport, stgt_delete_work); + struct fc_rport *rport = (struct fc_rport *)data; struct Scsi_Host *shost = rport_to_shost(rport); unsigned long flags; struct fc_internal *i = to_fc_internal(shost->transportt); @@ -1749,13 +1751,12 @@ fc_starget_delete(struct work_struct *work) /** * fc_rport_final_delete - finish rport termination and delete it. * - * @work: remote port to be deleted. + * @data: remote port to be deleted. **/ static void -fc_rport_final_delete(struct work_struct *work) +fc_rport_final_delete(void *data) { - struct fc_rport *rport = - container_of(work, struct fc_rport, rport_delete_work); + struct fc_rport *rport = (struct fc_rport *)data; struct device *dev = &rport->dev; struct Scsi_Host *shost = rport_to_shost(rport); struct fc_internal *i = to_fc_internal(shost->transportt); @@ -1769,7 +1770,7 @@ fc_rport_final_delete(struct work_struct *work) /* Delete SCSI target and sdevs */ if (rport->scsi_target_id != -1) - fc_starget_delete(&rport->stgt_delete_work); + fc_starget_delete(data); else if (i->f->dev_loss_tmo_callbk) i->f->dev_loss_tmo_callbk(rport); else if (i->f->terminate_rport_io) @@ -1828,11 +1829,11 @@ fc_rport_create(struct Scsi_Host *shost, int channel, rport->channel = channel; rport->fast_io_fail_tmo = -1; - INIT_DELAYED_WORK(&rport->dev_loss_work, fc_timeout_deleted_rport); - INIT_DELAYED_WORK(&rport->fail_io_work, fc_timeout_fail_rport_io); - INIT_WORK(&rport->scan_work, fc_scsi_scan_rport); - INIT_WORK(&rport->stgt_delete_work, fc_starget_delete); - INIT_WORK(&rport->rport_delete_work, fc_rport_final_delete); + INIT_WORK(&rport->dev_loss_work, fc_timeout_deleted_rport, rport); + INIT_WORK(&rport->fail_io_work, fc_timeout_fail_rport_io, rport); + INIT_WORK(&rport->scan_work, fc_scsi_scan_rport, rport); + INIT_WORK(&rport->stgt_delete_work, fc_starget_delete, rport); + INIT_WORK(&rport->rport_delete_work, fc_rport_final_delete, rport); spin_lock_irqsave(shost->host_lock, flags); @@ -1962,7 +1963,7 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel, } if (match) { - struct delayed_work *work = + struct work_struct *work = &rport->dev_loss_work; memcpy(&rport->node_name, &ids->node_name, @@ -2266,13 +2267,12 @@ EXPORT_SYMBOL(fc_remote_port_rolechg); * was a SCSI target (thus was blocked), and failed * to return in the alloted time. * - * @work: rport target that failed to reappear in the alloted time. + * @data: rport target that failed to reappear in the alloted time. **/ static void -fc_timeout_deleted_rport(struct work_struct *work) +fc_timeout_deleted_rport(void *data) { - struct fc_rport *rport = - container_of(work, struct fc_rport, dev_loss_work.work); + struct fc_rport *rport = (struct fc_rport *)data; struct Scsi_Host *shost = rport_to_shost(rport); struct fc_host_attrs *fc_host = shost_to_fc_host(shost); unsigned long flags; @@ -2366,16 +2366,15 @@ fc_timeout_deleted_rport(struct work_struct *work) * fc_timeout_fail_rport_io - Timeout handler for a fast io failing on a * disconnected SCSI target. * - * @work: rport to terminate io on. + * @data: rport to terminate io on. * * Notes: Only requests the failure of the io, not that all are flushed * prior to returning. **/ static void -fc_timeout_fail_rport_io(struct work_struct *work) +fc_timeout_fail_rport_io(void *data) { - struct fc_rport *rport = - container_of(work, struct fc_rport, fail_io_work.work); + struct fc_rport *rport = (struct fc_rport *)data; struct Scsi_Host *shost = rport_to_shost(rport); struct fc_internal *i = to_fc_internal(shost->transportt); @@ -2388,13 +2387,12 @@ fc_timeout_fail_rport_io(struct work_struct *work) /** * fc_scsi_scan_rport - called to perform a scsi scan on a remote port. * - * @work: remote port to be scanned. + * @data: remote port to be scanned. **/ static void -fc_scsi_scan_rport(struct work_struct *work) +fc_scsi_scan_rport(void *data) { - struct fc_rport *rport = - container_of(work, struct fc_rport, scan_work); + struct fc_rport *rport = (struct fc_rport *)data; struct Scsi_Host *shost = rport_to_shost(rport); unsigned long flags; diff --git a/trunk/drivers/scsi/scsi_transport_iscsi.c b/trunk/drivers/scsi/scsi_transport_iscsi.c index 9c22f1342715..9b25124a989e 100644 --- a/trunk/drivers/scsi/scsi_transport_iscsi.c +++ b/trunk/drivers/scsi/scsi_transport_iscsi.c @@ -234,11 +234,9 @@ static int iscsi_user_scan(struct Scsi_Host *shost, uint channel, return 0; } -static void session_recovery_timedout(struct work_struct *work) +static void session_recovery_timedout(void *data) { - struct iscsi_cls_session *session = - container_of(work, struct iscsi_cls_session, - recovery_work.work); + struct iscsi_cls_session *session = data; dev_printk(KERN_INFO, &session->dev, "iscsi: session recovery timed " "out after %d secs\n", session->recovery_tmo); @@ -278,7 +276,7 @@ iscsi_alloc_session(struct Scsi_Host *shost, session->transport = transport; session->recovery_tmo = 120; - INIT_DELAYED_WORK(&session->recovery_work, session_recovery_timedout); + INIT_WORK(&session->recovery_work, session_recovery_timedout, session); INIT_LIST_HEAD(&session->host_list); INIT_LIST_HEAD(&session->sess_list); diff --git a/trunk/drivers/scsi/scsi_transport_spi.c b/trunk/drivers/scsi/scsi_transport_spi.c index 3fded4831460..9f070f0d0f2b 100644 --- a/trunk/drivers/scsi/scsi_transport_spi.c +++ b/trunk/drivers/scsi/scsi_transport_spi.c @@ -964,10 +964,9 @@ struct work_queue_wrapper { }; static void -spi_dv_device_work_wrapper(struct work_struct *work) +spi_dv_device_work_wrapper(void *data) { - struct work_queue_wrapper *wqw = - container_of(work, struct work_queue_wrapper, work); + struct work_queue_wrapper *wqw = (struct work_queue_wrapper *)data; struct scsi_device *sdev = wqw->sdev; kfree(wqw); @@ -1007,7 +1006,7 @@ spi_schedule_dv_device(struct scsi_device *sdev) return; } - INIT_WORK(&wqw->work, spi_dv_device_work_wrapper); + INIT_WORK(&wqw->work, spi_dv_device_work_wrapper, wqw); wqw->sdev = sdev; schedule_work(&wqw->work); diff --git a/trunk/drivers/scsi/scsi_wait_scan.c b/trunk/drivers/scsi/scsi_wait_scan.c deleted file mode 100644 index 8a636103083d..000000000000 --- a/trunk/drivers/scsi/scsi_wait_scan.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - * scsi_wait_scan.c - * - * Copyright (C) 2006 James Bottomley - * - * This is a simple module to wait until all the async scans are - * complete. The idea is to use it in initrd/initramfs scripts. You - * modprobe it after all the modprobes of the root SCSI drivers and it - * will wait until they have all finished scanning their busses before - * allowing the boot to proceed - */ - -#include -#include "scsi_priv.h" - -static int __init wait_scan_init(void) -{ - scsi_complete_async_scans(); - return 0; -} - -static void __exit wait_scan_exit(void) -{ -} - -MODULE_DESCRIPTION("SCSI wait for scans"); -MODULE_AUTHOR("James Bottomley"); -MODULE_LICENSE("GPL"); - -late_initcall(wait_scan_init); -module_exit(wait_scan_exit); diff --git a/trunk/drivers/scsi/sd.c b/trunk/drivers/scsi/sd.c index f6a452846fab..84ff203ffedd 100644 --- a/trunk/drivers/scsi/sd.c +++ b/trunk/drivers/scsi/sd.c @@ -1051,14 +1051,6 @@ sd_spinup_disk(struct scsi_disk *sdkp, char *diskname) &sshdr, SD_TIMEOUT, SD_MAX_RETRIES); - /* - * If the drive has indicated to us that it - * doesn't have any media in it, don't bother - * with any more polling. - */ - if (media_not_present(sdkp, &sshdr)) - return; - if (the_result) sense_valid = scsi_sense_valid(&sshdr); retries++; @@ -1067,6 +1059,14 @@ sd_spinup_disk(struct scsi_disk *sdkp, char *diskname) ((driver_byte(the_result) & DRIVER_SENSE) && sense_valid && sshdr.sense_key == UNIT_ATTENTION))); + /* + * If the drive has indicated to us that it doesn't have + * any media in it, don't bother with any of the rest of + * this crap. + */ + if (media_not_present(sdkp, &sshdr)) + return; + if ((driver_byte(the_result) & DRIVER_SENSE) == 0) { /* no sense, TUR either succeeded or failed * with a status error */ @@ -1467,6 +1467,7 @@ sd_read_cache_type(struct scsi_disk *sdkp, char *diskname, res = sd_do_mode_sense(sdp, dbd, modepage, buffer, len, &data, &sshdr); if (scsi_status_is_good(res)) { + int ct = 0; int offset = data.header_length + data.block_descriptor_length; if (offset >= SD_BUF_SIZE - 2) { @@ -1495,13 +1496,11 @@ sd_read_cache_type(struct scsi_disk *sdkp, char *diskname, sdkp->DPOFUA = 0; } - printk(KERN_NOTICE "SCSI device %s: " - "write cache: %s, read cache: %s, %s\n", - diskname, - sdkp->WCE ? "enabled" : "disabled", - sdkp->RCD ? "disabled" : "enabled", - sdkp->DPOFUA ? "supports DPO and FUA" - : "doesn't support DPO or FUA"); + ct = sdkp->RCD + 2*sdkp->WCE; + + printk(KERN_NOTICE "SCSI device %s: drive cache: %s%s\n", + diskname, sd_cache_types[ct], + sdkp->DPOFUA ? " w/ FUA" : ""); return; } diff --git a/trunk/drivers/scsi/st.c b/trunk/drivers/scsi/st.c index 587274dd7059..e1a52c525ed4 100644 --- a/trunk/drivers/scsi/st.c +++ b/trunk/drivers/scsi/st.c @@ -9,7 +9,7 @@ Steve Hirsch, Andreas Koppenh"ofer, Michael Leodolter, Eyal Lebedinsky, Michael Schaefer, J"org Weule, and Eric Youngdale. - Copyright 1992 - 2006 Kai Makisara + Copyright 1992 - 2005 Kai Makisara email Kai.Makisara@kolumbus.fi Some small formal changes - aeb, 950809 @@ -17,7 +17,7 @@ Last modified: 18-JAN-1998 Richard Gooch Devfs support */ -static const char *verstr = "20061107"; +static const char *verstr = "20050830"; #include @@ -999,7 +999,7 @@ static int check_tape(struct scsi_tape *STp, struct file *filp) STp->min_block = ((STp->buffer)->b_data[4] << 8) | (STp->buffer)->b_data[5]; if ( DEB( debugging || ) !STp->inited) - printk(KERN_INFO + printk(KERN_WARNING "%s: Block limits %d - %d bytes.\n", name, STp->min_block, STp->max_block); } else { @@ -1224,7 +1224,7 @@ static int st_flush(struct file *filp, fl_owner_t id) } DEBC( if (STp->nbr_requests) - printk(KERN_DEBUG "%s: Number of r/w requests %d, dio used in %d, pages %d (%d).\n", + printk(KERN_WARNING "%s: Number of r/w requests %d, dio used in %d, pages %d (%d).\n", name, STp->nbr_requests, STp->nbr_dio, STp->nbr_pages, STp->nbr_combinable)); if (STps->rw == ST_WRITING && !STp->pos_unknown) { @@ -4056,11 +4056,11 @@ static int st_probe(struct device *dev) goto out_free_tape; } - sdev_printk(KERN_NOTICE, SDp, + sdev_printk(KERN_WARNING, SDp, "Attached scsi tape %s\n", tape_name(tpnt)); - sdev_printk(KERN_INFO, SDp, "%s: try direct i/o: %s (alignment %d B)\n", - tape_name(tpnt), tpnt->try_dio ? "yes" : "no", - queue_dma_alignment(SDp->request_queue) + 1); + printk(KERN_WARNING "%s: try direct i/o: %s (alignment %d B)\n", + tape_name(tpnt), tpnt->try_dio ? "yes" : "no", + queue_dma_alignment(SDp->request_queue) + 1); return 0; diff --git a/trunk/drivers/scsi/stex.c b/trunk/drivers/scsi/stex.c index ba6bcdaf2a6a..185c270bb043 100644 --- a/trunk/drivers/scsi/stex.c +++ b/trunk/drivers/scsi/stex.c @@ -11,6 +11,8 @@ * Written By: * Ed Lin * + * Version: 3.0.0.1 + * */ #include @@ -35,9 +37,9 @@ #include #define DRV_NAME "stex" -#define ST_DRIVER_VERSION "3.1.0.1" +#define ST_DRIVER_VERSION "3.0.0.1" #define ST_VER_MAJOR 3 -#define ST_VER_MINOR 1 +#define ST_VER_MINOR 0 #define ST_OEM 0 #define ST_BUILD_VER 1 @@ -74,10 +76,8 @@ enum { MU_STATE_STARTED = 4, MU_STATE_RESETTING = 5, - MU_MAX_DELAY = 120, + MU_MAX_DELAY_TIME = 240000, MU_HANDSHAKE_SIGNATURE = 0x55aaaa55, - MU_HANDSHAKE_SIGNATURE_HALF = 0x5a5a0000, - MU_HARD_RESET_WAIT = 30000, HMU_PARTNER_TYPE = 2, /* firmware returned values */ @@ -120,8 +120,7 @@ enum { st_shasta = 0, st_vsc = 1, - st_vsc1 = 2, - st_yosemite = 3, + st_yosemite = 2, PASSTHRU_REQ_TYPE = 0x00000001, PASSTHRU_REQ_NO_WAKEUP = 0x00000100, @@ -151,8 +150,6 @@ enum { MGT_CMD_SIGNATURE = 0xba, INQUIRY_EVPD = 0x01, - - ST_ADDITIONAL_MEM = 0x200000, }; /* SCSI inquiry data */ @@ -214,9 +211,7 @@ struct handshake_frame { __le32 partner_ver_minor; __le32 partner_ver_oem; __le32 partner_ver_build; - __le32 extra_offset; /* NEW */ - __le32 extra_size; /* NEW */ - u32 reserved1[2]; + u32 reserved1[4]; }; struct req_msg { @@ -307,7 +302,6 @@ struct st_hba { void __iomem *mmio_base; /* iomapped PCI memory space */ void *dma_mem; dma_addr_t dma_handle; - size_t dma_size; struct Scsi_Host *host; struct pci_dev *pdev; @@ -513,7 +507,6 @@ static void stex_controller_info(struct st_hba *hba, struct st_ccb *ccb) size_t count = sizeof(struct st_frame); p = hba->copy_buffer; - stex_internal_copy(ccb->cmd, p, &count, ccb->sg_count, ST_FROM_CMD); memset(p->base, 0, sizeof(u32)*6); *(unsigned long *)(p->base) = pci_resource_start(hba->pdev, 0); p->rom_addr = 0; @@ -908,34 +901,27 @@ static int stex_handshake(struct st_hba *hba) void __iomem *base = hba->mmio_base; struct handshake_frame *h; dma_addr_t status_phys; - u32 data; - unsigned long before; + int i; if (readl(base + OMR0) != MU_HANDSHAKE_SIGNATURE) { writel(MU_INBOUND_DOORBELL_HANDSHAKE, base + IDBL); readl(base + IDBL); - before = jiffies; - while (readl(base + OMR0) != MU_HANDSHAKE_SIGNATURE) { - if (time_after(jiffies, before + MU_MAX_DELAY * HZ)) { - printk(KERN_ERR DRV_NAME - "(%s): no handshake signature\n", - pci_name(hba->pdev)); - return -1; - } + for (i = 0; readl(base + OMR0) != MU_HANDSHAKE_SIGNATURE + && i < MU_MAX_DELAY_TIME; i++) { rmb(); msleep(1); } + + if (i == MU_MAX_DELAY_TIME) { + printk(KERN_ERR DRV_NAME + "(%s): no handshake signature\n", + pci_name(hba->pdev)); + return -1; + } } udelay(10); - data = readl(base + OMR1); - if ((data & 0xffff0000) == MU_HANDSHAKE_SIGNATURE_HALF) { - data &= 0x0000ffff; - if (hba->host->can_queue > data) - hba->host->can_queue = data; - } - h = (struct handshake_frame *)(hba->dma_mem + MU_REQ_BUFFER_SIZE); h->rb_phy = cpu_to_le32(hba->dma_handle); h->rb_phy_hi = cpu_to_le32((hba->dma_handle >> 16) >> 16); @@ -945,11 +931,6 @@ static int stex_handshake(struct st_hba *hba) h->status_cnt = cpu_to_le16(MU_STATUS_COUNT); stex_gettime(&h->hosttime); h->partner_type = HMU_PARTNER_TYPE; - if (hba->dma_size > STEX_BUFFER_SIZE) { - h->extra_offset = cpu_to_le32(STEX_BUFFER_SIZE); - h->extra_size = cpu_to_le32(ST_ADDITIONAL_MEM); - } else - h->extra_offset = h->extra_size = 0; status_phys = hba->dma_handle + MU_REQ_BUFFER_SIZE; writel(status_phys, base + IMR0); @@ -963,18 +944,19 @@ static int stex_handshake(struct st_hba *hba) readl(base + IDBL); /* flush */ udelay(10); - before = jiffies; - while (readl(base + OMR0) != MU_HANDSHAKE_SIGNATURE) { - if (time_after(jiffies, before + MU_MAX_DELAY * HZ)) { - printk(KERN_ERR DRV_NAME - "(%s): no signature after handshake frame\n", - pci_name(hba->pdev)); - return -1; - } + for (i = 0; readl(base + OMR0) != MU_HANDSHAKE_SIGNATURE + && i < MU_MAX_DELAY_TIME; i++) { rmb(); msleep(1); } + if (i == MU_MAX_DELAY_TIME) { + printk(KERN_ERR DRV_NAME + "(%s): no signature after handshake frame\n", + pci_name(hba->pdev)); + return -1; + } + writel(0, base + IMR0); readl(base + IMR0); writel(0, base + OMR0); @@ -1056,9 +1038,9 @@ static void stex_hard_reset(struct st_hba *hba) pci_bctl &= ~PCI_BRIDGE_CTL_BUS_RESET; pci_write_config_byte(bus->self, PCI_BRIDGE_CONTROL, pci_bctl); - for (i = 0; i < MU_HARD_RESET_WAIT; i++) { + for (i = 0; i < MU_MAX_DELAY_TIME; i++) { pci_read_config_word(hba->pdev, PCI_COMMAND, &pci_cmd); - if (pci_cmd != 0xffff && (pci_cmd & PCI_COMMAND_MASTER)) + if (pci_cmd & PCI_COMMAND_MASTER) break; msleep(1); } @@ -1118,18 +1100,18 @@ static int stex_reset(struct scsi_cmnd *cmd) static int stex_biosparam(struct scsi_device *sdev, struct block_device *bdev, sector_t capacity, int geom[]) { - int heads = 255, sectors = 63; + int heads = 255, sectors = 63, cylinders; if (capacity < 0x200000) { heads = 64; sectors = 32; } - sector_div(capacity, heads * sectors); + cylinders = sector_div(capacity, heads * sectors); geom[0] = heads; geom[1] = sectors; - geom[2] = capacity; + geom[2] = cylinders; return 0; } @@ -1211,13 +1193,8 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id) goto out_iounmap; } - hba->cardtype = (unsigned int) id->driver_data; - if (hba->cardtype == st_vsc && (pdev->subsystem_device & 0xf) == 0x1) - hba->cardtype = st_vsc1; - hba->dma_size = (hba->cardtype == st_vsc1) ? - (STEX_BUFFER_SIZE + ST_ADDITIONAL_MEM) : (STEX_BUFFER_SIZE); hba->dma_mem = dma_alloc_coherent(&pdev->dev, - hba->dma_size, &hba->dma_handle, GFP_KERNEL); + STEX_BUFFER_SIZE, &hba->dma_handle, GFP_KERNEL); if (!hba->dma_mem) { err = -ENOMEM; printk(KERN_ERR DRV_NAME "(%s): dma mem alloc failed\n", @@ -1230,6 +1207,8 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id) hba->copy_buffer = hba->dma_mem + MU_BUFFER_SIZE; hba->mu_status = MU_STATE_STARTING; + hba->cardtype = (unsigned int) id->driver_data; + /* firmware uses id/lun pair for a logical drive, but lun would be always 0 if CONFIG_SCSI_MULTI_LUN not configured, so we use channel to map lun here */ @@ -1254,7 +1233,7 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (err) goto out_free_irq; - err = scsi_init_shared_tag_map(host, host->can_queue); + err = scsi_init_shared_tag_map(host, ST_CAN_QUEUE); if (err) { printk(KERN_ERR DRV_NAME "(%s): init shared queue failed\n", pci_name(pdev)); @@ -1277,7 +1256,7 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id) out_free_irq: free_irq(pdev->irq, hba); out_pci_free: - dma_free_coherent(&pdev->dev, hba->dma_size, + dma_free_coherent(&pdev->dev, STEX_BUFFER_SIZE, hba->dma_mem, hba->dma_handle); out_iounmap: iounmap(hba->mmio_base); @@ -1338,7 +1317,7 @@ static void stex_hba_free(struct st_hba *hba) pci_release_regions(hba->pdev); - dma_free_coherent(&hba->pdev->dev, hba->dma_size, + dma_free_coherent(&hba->pdev->dev, STEX_BUFFER_SIZE, hba->dma_mem, hba->dma_handle); } @@ -1367,32 +1346,15 @@ static void stex_shutdown(struct pci_dev *pdev) } static struct pci_device_id stex_pci_tbl[] = { - /* st_shasta */ - { 0x105a, 0x8350, PCI_ANY_ID, PCI_ANY_ID, 0, 0, - st_shasta }, /* SuperTrak EX8350/8300/16350/16300 */ - { 0x105a, 0xc350, PCI_ANY_ID, PCI_ANY_ID, 0, 0, - st_shasta }, /* SuperTrak EX12350 */ - { 0x105a, 0x4302, PCI_ANY_ID, PCI_ANY_ID, 0, 0, - st_shasta }, /* SuperTrak EX4350 */ - { 0x105a, 0xe350, PCI_ANY_ID, PCI_ANY_ID, 0, 0, - st_shasta }, /* SuperTrak EX24350 */ - - /* st_vsc */ - { 0x105a, 0x7250, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_vsc }, - - /* st_yosemite */ - { 0x105a, 0x8650, PCI_ANY_ID, 0x4600, 0, 0, - st_yosemite }, /* SuperTrak EX4650 */ - { 0x105a, 0x8650, PCI_ANY_ID, 0x4610, 0, 0, - st_yosemite }, /* SuperTrak EX4650o */ - { 0x105a, 0x8650, PCI_ANY_ID, 0x8600, 0, 0, - st_yosemite }, /* SuperTrak EX8650EL */ - { 0x105a, 0x8650, PCI_ANY_ID, 0x8601, 0, 0, - st_yosemite }, /* SuperTrak EX8650 */ - { 0x105a, 0x8650, PCI_ANY_ID, 0x8602, 0, 0, - st_yosemite }, /* SuperTrak EX8654 */ - { 0x105a, 0x8650, PCI_ANY_ID, PCI_ANY_ID, 0, 0, - st_yosemite }, /* generic st_yosemite */ + { 0x105a, 0x8350, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_shasta }, + { 0x105a, 0xc350, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_shasta }, + { 0x105a, 0xf350, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_shasta }, + { 0x105a, 0x4301, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_shasta }, + { 0x105a, 0x4302, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_shasta }, + { 0x105a, 0x8301, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_shasta }, + { 0x105a, 0x8302, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_shasta }, + { 0x1725, 0x7250, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_vsc }, + { 0x105a, 0x8650, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_yosemite }, { } /* terminate list */ }; MODULE_DEVICE_TABLE(pci, stex_pci_tbl); diff --git a/trunk/drivers/scsi/t128.h b/trunk/drivers/scsi/t128.h index 76a069b7ac0b..646e840266e2 100644 --- a/trunk/drivers/scsi/t128.h +++ b/trunk/drivers/scsi/t128.h @@ -8,20 +8,20 @@ * drew@colorado.edu * +1 (303) 440-4894 * - * DISTRIBUTION RELEASE 3. + * DISTRIBUTION RELEASE 3. * - * For more information, please consult + * For more information, please consult * * Trantor Systems, Ltd. * T128/T128F/T228 SCSI Host Adapter * Hardware Specifications - * - * Trantor Systems, Ltd. + * + * Trantor Systems, Ltd. * 5415 Randall Place * Fremont, CA 94538 * 1+ (415) 770-1400, FAX 1+ (415) 770-9910 - * - * and + * + * and * * NCR 5380 Family * SCSI Protocol Controller @@ -48,15 +48,15 @@ #define TDEBUG_TRANSFER 0x2 /* - * The trantor boards are memory mapped. They use an NCR5380 or + * The trantor boards are memory mapped. They use an NCR5380 or * equivalent (my sample board had part second sourced from ZILOG). - * NCR's recommended "Pseudo-DMA" architecture is used, where + * NCR's recommended "Pseudo-DMA" architecture is used, where * a PAL drives the DMA signals on the 5380 allowing fast, blind - * transfers with proper handshaking. + * transfers with proper handshaking. */ /* - * Note : a boot switch is provided for the purpose of informing the + * Note : a boot switch is provided for the purpose of informing the * firmware to boot or not boot from attached SCSI devices. So, I imagine * there are fewer people who've yanked the ROM like they do on the Seagate * to make bootup faster, and I'll probably use this for autodetection. @@ -92,20 +92,19 @@ #define T_DATA_REG_OFFSET 0x1e00 /* rw 512 bytes long */ #ifndef ASM -static int t128_abort(struct scsi_cmnd *); +static int t128_abort(Scsi_Cmnd *); static int t128_biosparam(struct scsi_device *, struct block_device *, sector_t, int*); static int t128_detect(struct scsi_host_template *); -static int t128_queue_command(struct scsi_cmnd *, - void (*done)(struct scsi_cmnd *)); -static int t128_bus_reset(struct scsi_cmnd *); +static int t128_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); +static int t128_bus_reset(Scsi_Cmnd *); #ifndef CMD_PER_LUN #define CMD_PER_LUN 2 #endif #ifndef CAN_QUEUE -#define CAN_QUEUE 32 +#define CAN_QUEUE 32 #endif #ifndef HOSTS_C @@ -121,7 +120,7 @@ static int t128_bus_reset(struct scsi_cmnd *); #define T128_address(reg) (base + T_5380_OFFSET + ((reg) * 0x20)) -#if !(TDEBUG & TDEBUG_TRANSFER) +#if !(TDEBUG & TDEBUG_TRANSFER) #define NCR5380_read(reg) readb(T128_address(reg)) #define NCR5380_write(reg, value) writeb((value),(T128_address(reg))) #else @@ -130,7 +129,7 @@ static int t128_bus_reset(struct scsi_cmnd *); , instance->hostno, (reg), T128_address(reg))), readb(T128_address(reg))) #define NCR5380_write(reg, value) { \ - printk("scsi%d : write %02x to register %d at address %08x\n", \ + printk("scsi%d : write %02x to register %d at address %08x\n", \ instance->hostno, (value), (reg), T128_address(reg)); \ writeb((value), (T128_address(reg))); \ } @@ -143,10 +142,10 @@ static int t128_bus_reset(struct scsi_cmnd *); #define NCR5380_bus_reset t128_bus_reset #define NCR5380_proc_info t128_proc_info -/* 15 14 12 10 7 5 3 +/* 15 14 12 10 7 5 3 1101 0100 1010 1000 */ - -#define T128_IRQS 0xc4a8 + +#define T128_IRQS 0xc4a8 #endif /* else def HOSTS_C */ #endif /* ndef ASM */ diff --git a/trunk/drivers/serial/mcfserial.c b/trunk/drivers/serial/mcfserial.c index 3db206d29b33..aee1b31f1a1c 100644 --- a/trunk/drivers/serial/mcfserial.c +++ b/trunk/drivers/serial/mcfserial.c @@ -60,8 +60,7 @@ struct timer_list mcfrs_timer_struct; #if defined(CONFIG_HW_FEITH) #define CONSOLE_BAUD_RATE 38400 #define DEFAULT_CBAUD B38400 -#elif defined(CONFIG_MOD5272) || defined(CONFIG_M5208EVB) || \ - defined(CONFIG_M5329EVB) || defined(CONFIG_GILBARCO) +#elif defined(CONFIG_MOD5272) || defined(CONFIG_M5208EVB) || defined(CONFIG_M5329EVB) #define CONSOLE_BAUD_RATE 115200 #define DEFAULT_CBAUD B115200 #elif defined(CONFIG_ARNEWSH) || defined(CONFIG_FREESCALE) || \ @@ -110,30 +109,12 @@ static struct mcf_serial mcfrs_table[] = { .irq = IRQBASE, .flags = ASYNC_BOOT_AUTOCONF, }, -#ifdef MCFUART_BASE2 { /* ttyS1 */ .magic = 0, .addr = (volatile unsigned char *) (MCF_MBAR+MCFUART_BASE2), .irq = IRQBASE+1, .flags = ASYNC_BOOT_AUTOCONF, }, -#endif -#ifdef MCFUART_BASE3 - { /* ttyS2 */ - .magic = 0, - .addr = (volatile unsigned char *) (MCF_MBAR+MCFUART_BASE3), - .irq = IRQBASE+2, - .flags = ASYNC_BOOT_AUTOCONF, - }, -#endif -#ifdef MCFUART_BASE4 - { /* ttyS3 */ - .magic = 0, - .addr = (volatile unsigned char *) (MCF_MBAR+MCFUART_BASE4), - .irq = IRQBASE+3, - .flags = ASYNC_BOOT_AUTOCONF, - }, -#endif }; @@ -1535,22 +1516,6 @@ static void mcfrs_irqinit(struct mcf_serial *info) imrp = (volatile unsigned long *) (MCF_MBAR + MCFICM_INTC0 + MCFINTC_IMRL); *imrp &= ~((1 << (info->irq - MCFINT_VECBASE)) | 1); -#if defined(CONFIG_M527x) - { - /* - * External Pin Mask Setting & Enable External Pin for Interface - * mrcbis@aliceposta.it - */ - unsigned short *serpin_enable_mask; - serpin_enable_mask = (MCF_IPSBAR + MCF_GPIO_PAR_UART); - if (info->line == 0) - *serpin_enable_mask |= UART0_ENABLE_MASK; - else if (info->line == 1) - *serpin_enable_mask |= UART1_ENABLE_MASK; - else if (info->line == 2) - *serpin_enable_mask |= UART2_ENABLE_MASK; - } -#endif #elif defined(CONFIG_M520x) volatile unsigned char *icrp, *uartp; volatile unsigned long *imrp; @@ -1748,7 +1713,7 @@ mcfrs_init(void) /* Initialize the tty_driver structure */ mcfrs_serial_driver->owner = THIS_MODULE; mcfrs_serial_driver->name = "ttyS"; - mcfrs_serial_driver->driver_name = "mcfserial"; + mcfrs_serial_driver->driver_name = "serial"; mcfrs_serial_driver->major = TTY_MAJOR; mcfrs_serial_driver->minor_start = 64; mcfrs_serial_driver->type = TTY_DRIVER_TYPE_SERIAL; @@ -1832,23 +1797,10 @@ void mcfrs_init_console(void) uartp[MCFUART_UMR] = MCFUART_MR1_PARITYNONE | MCFUART_MR1_CS8; uartp[MCFUART_UMR] = MCFUART_MR2_STOP1; -#ifdef CONFIG_M5272 -{ - /* - * For the MCF5272, also compute the baudrate fraction. - */ - int fraction = MCF_BUSCLK - (clk * 32 * mcfrs_console_baud); - fraction *= 16; - fraction /= (32 * mcfrs_console_baud); - uartp[MCFUART_UFPD] = (fraction & 0xf); /* set fraction */ - clk = (MCF_BUSCLK / mcfrs_console_baud) / 32; -} -#else clk = ((MCF_BUSCLK / mcfrs_console_baud) + 16) / 32; /* set baud */ -#endif - uartp[MCFUART_UBG1] = (clk & 0xff00) >> 8; /* set msb baud */ uartp[MCFUART_UBG2] = (clk & 0xff); /* set lsb baud */ + uartp[MCFUART_UCSR] = MCFUART_UCSR_RXCLKTIMER | MCFUART_UCSR_TXCLKTIMER; uartp[MCFUART_UCR] = MCFUART_UCR_RXENABLE | MCFUART_UCR_TXENABLE; diff --git a/trunk/drivers/serial/serial_cs.c b/trunk/drivers/serial/serial_cs.c index 431433f4dd6d..00f9ffd69489 100644 --- a/trunk/drivers/serial/serial_cs.c +++ b/trunk/drivers/serial/serial_cs.c @@ -723,7 +723,7 @@ static int serial_config(struct pcmcia_device * link) u_char *buf; cisparse_t *parse; cistpl_cftable_entry_t *cf; - int i; + int i, last_ret, last_fn; DEBUG(0, "serial_config(0x%p)\n", link); @@ -740,6 +740,15 @@ static int serial_config(struct pcmcia_device * link) tuple->TupleOffset = 0; tuple->TupleDataMax = 255; tuple->Attributes = 0; + /* Get configuration register information */ + tuple->DesiredTuple = CISTPL_CONFIG; + last_ret = first_tuple(link, tuple, parse); + if (last_ret != CS_SUCCESS) { + last_fn = ParseTuple; + goto cs_failed; + } + link->conf.ConfigBase = parse->config.base; + link->conf.Present = parse->config.rmask[0]; /* Is this a compliant multifunction card? */ tuple->DesiredTuple = CISTPL_LONGLINK_MFC; @@ -748,25 +757,27 @@ static int serial_config(struct pcmcia_device * link) /* Is this a multiport card? */ tuple->DesiredTuple = CISTPL_MANFID; - info->manfid = link->manf_id; - info->prodid = link->card_id; - - for (i = 0; i < ARRAY_SIZE(quirks); i++) - if ((quirks[i].manfid == ~0 || - quirks[i].manfid == info->manfid) && - (quirks[i].prodid == ~0 || - quirks[i].prodid == info->prodid)) { - info->quirk = &quirks[i]; - break; - } + if (first_tuple(link, tuple, parse) == CS_SUCCESS) { + info->manfid = parse->manfid.manf; + info->prodid = parse->manfid.card; + + for (i = 0; i < ARRAY_SIZE(quirks); i++) + if ((quirks[i].manfid == ~0 || + quirks[i].manfid == info->manfid) && + (quirks[i].prodid == ~0 || + quirks[i].prodid == info->prodid)) { + info->quirk = &quirks[i]; + break; + } + } /* Another check for dual-serial cards: look for either serial or multifunction cards that ask for appropriate IO port ranges */ tuple->DesiredTuple = CISTPL_FUNCID; if ((info->multi == 0) && - (link->has_func_id) && - ((link->func_id == CISTPL_FUNCID_MULTI) || - (link->func_id == CISTPL_FUNCID_SERIAL))) { + ((first_tuple(link, tuple, parse) != CS_SUCCESS) || + (parse->funcid.func == CISTPL_FUNCID_MULTI) || + (parse->funcid.func == CISTPL_FUNCID_SERIAL))) { tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; if (first_tuple(link, tuple, parse) == CS_SUCCESS) { if ((cf->io.nwin == 1) && (cf->io.win[0].len % 8 == 0)) @@ -803,6 +814,8 @@ static int serial_config(struct pcmcia_device * link) kfree(cfg_mem); return 0; + cs_failed: + cs_error(link, last_fn, last_ret); failed: serial_remove(link); kfree(cfg_mem); @@ -912,30 +925,6 @@ static struct pcmcia_device_id serial_ids[] = { PCMCIA_DEVICE_CIS_PROD_ID123("ADVANTECH", "COMpad-32/85", "1.0", 0x96913a85, 0x8fbe92ae, 0x0877b627, "COMpad2.cis"), PCMCIA_DEVICE_CIS_PROD_ID2("RS-COM 2P", 0xad20b156, "RS-COM-2P.cis"), PCMCIA_DEVICE_CIS_MANF_CARD(0x0013, 0x0000, "GLOBETROTTER.cis"), - PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL100 1.00.",0x19ca78af,0xf964f42b), - PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL100",0x19ca78af,0x71d98e83), - PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL232 1.00.",0x19ca78af,0x69fb7490), - PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL232",0x19ca78af,0xb6bc0235), - PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c2000.","SERIAL CARD: CF232",0x63f2e0bd,0xb9e175d3), - PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c2000.","SERIAL CARD: CF232-5",0x63f2e0bd,0xfce33442), - PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: CF232",0x3beb8cf2,0x171e7190), - PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: CF232-5",0x3beb8cf2,0x20da4262), - PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: CF428",0x3beb8cf2,0xea5dd57d), - PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: CF500",0x3beb8cf2,0xd77255fa), - PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: IC232",0x3beb8cf2,0x6a709903), - PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: SL232",0x3beb8cf2,0x18430676), - PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: XL232",0x3beb8cf2,0x6f933767), - PCMCIA_MFC_DEVICE_PROD_ID12(0,"Elan","Serial Port: CF332",0x3beb8cf2,0x16dc1ba7), - PCMCIA_MFC_DEVICE_PROD_ID12(0,"Elan","Serial Port: SL332",0x3beb8cf2,0x19816c41), - PCMCIA_MFC_DEVICE_PROD_ID12(0,"Elan","Serial Port: SL385",0x3beb8cf2,0x64112029), - PCMCIA_MFC_DEVICE_PROD_ID12(0,"Elan","Serial Port: SL432",0x3beb8cf2,0x1cce7ac4), - PCMCIA_MFC_DEVICE_PROD_ID12(0,"Elan","Serial+Parallel Port: SP230",0x3beb8cf2,0xdb9e58bc), - PCMCIA_MFC_DEVICE_PROD_ID12(1,"Elan","Serial Port: CF332",0x3beb8cf2,0x16dc1ba7), - PCMCIA_MFC_DEVICE_PROD_ID12(1,"Elan","Serial Port: SL332",0x3beb8cf2,0x19816c41), - PCMCIA_MFC_DEVICE_PROD_ID12(1,"Elan","Serial Port: SL385",0x3beb8cf2,0x64112029), - PCMCIA_MFC_DEVICE_PROD_ID12(1,"Elan","Serial Port: SL432",0x3beb8cf2,0x1cce7ac4), - PCMCIA_MFC_DEVICE_PROD_ID12(2,"Elan","Serial Port: SL432",0x3beb8cf2,0x1cce7ac4), - PCMCIA_MFC_DEVICE_PROD_ID12(3,"Elan","Serial Port: SL432",0x3beb8cf2,0x1cce7ac4), /* too generic */ /* PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0160, 0x0002), */ /* PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0160, 0x0002), */ diff --git a/trunk/drivers/serial/sh-sci.h b/trunk/drivers/serial/sh-sci.h index 7ee992146ae9..b2bc0cfb4014 100644 --- a/trunk/drivers/serial/sh-sci.h +++ b/trunk/drivers/serial/sh-sci.h @@ -133,6 +133,20 @@ # define SCIF_ORER 0x0001 /* Overrun error bit */ # define SCSCR_INIT(port) 0x3a /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ # define SCIF_ONLY +#elif defined(CONFIG_CPU_SUBTYPE_SH7206) +# define SCSPTR0 0xfffe8020 /* 16 bit SCIF */ +# define SCSPTR1 0xfffe8820 /* 16 bit SCIF */ +# define SCSPTR2 0xfffe9020 /* 16 bit SCIF */ +# define SCSPTR3 0xfffe9820 /* 16 bit SCIF */ +# define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ +# define SCIF_ONLY +#elif defined(CONFIG_CPU_SUBTYPE_SH7619) +# define SCSPTR0 0xf8400020 /* 16 bit SCIF */ +# define SCSPTR1 0xf8410020 /* 16 bit SCIF */ +# define SCSPTR2 0xf8420020 /* 16 bit SCIF */ +# define SCIF_ORER 0x0001 /* overrun error bit */ +# define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ +# define SCIF_ONLY #else # error CPU subtype not defined #endif @@ -544,6 +558,28 @@ static inline int sci_rxd_in(struct uart_port *port) if (port->mapbase == 0xffe10000) return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ } +#elif defined(CONFIG_CPU_SUBTYPE_SH7206) +static inline int sci_rxd_in(struct uart_port *port) +{ + if (port->mapbase == 0xfffe8000) + return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ + if (port->mapbase == 0xfffe8800) + return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ + if (port->mapbase == 0xfffe9000) + return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ + if (port->mapbase == 0xfffe9800) + return ctrl_inw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */ +} +#elif defined(CONFIG_CPU_SUBTYPE_SH7619) +static inline int sci_rxd_in(struct uart_port *port) +{ + if (port->mapbase == 0xf8400000) + return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ + if (port->mapbase == 0xf8410000) + return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ + if (port->mapbase == 0xf8420000) + return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ +} #endif /* diff --git a/trunk/drivers/spi/pxa2xx_spi.c b/trunk/drivers/spi/pxa2xx_spi.c index 494d9b856488..72025df5561d 100644 --- a/trunk/drivers/spi/pxa2xx_spi.c +++ b/trunk/drivers/spi/pxa2xx_spi.c @@ -148,7 +148,7 @@ struct chip_data { void (*cs_control)(u32 command); }; -static void pump_messages(struct work_struct *work); +static void pump_messages(void *data); static int flush(struct driver_data *drv_data) { @@ -884,10 +884,9 @@ static void pump_transfers(unsigned long data) } } -static void pump_messages(struct work_struct *work) +static void pump_messages(void *data) { - struct driver_data *drv_data = - container_of(work, struct driver_data, pump_messages); + struct driver_data *drv_data = data; unsigned long flags; /* Lock queue and check for queue work */ @@ -1099,7 +1098,7 @@ static int init_queue(struct driver_data *drv_data) tasklet_init(&drv_data->pump_transfers, pump_transfers, (unsigned long)drv_data); - INIT_WORK(&drv_data->pump_messages, pump_messages); + INIT_WORK(&drv_data->pump_messages, pump_messages, drv_data); drv_data->workqueue = create_singlethread_workqueue( drv_data->master->cdev.dev->bus_id); if (drv_data->workqueue == NULL) diff --git a/trunk/drivers/spi/spi_bitbang.c b/trunk/drivers/spi/spi_bitbang.c index 08c1c57c6128..a23862ef72b2 100644 --- a/trunk/drivers/spi/spi_bitbang.c +++ b/trunk/drivers/spi/spi_bitbang.c @@ -265,10 +265,9 @@ static int spi_bitbang_bufs(struct spi_device *spi, struct spi_transfer *t) * Drivers can provide word-at-a-time i/o primitives, or provide * transfer-at-a-time ones to leverage dma or fifo hardware. */ -static void bitbang_work(struct work_struct *work) +static void bitbang_work(void *_bitbang) { - struct spi_bitbang *bitbang = - container_of(work, struct spi_bitbang, work); + struct spi_bitbang *bitbang = _bitbang; unsigned long flags; spin_lock_irqsave(&bitbang->lock, flags); @@ -457,7 +456,7 @@ int spi_bitbang_start(struct spi_bitbang *bitbang) if (!bitbang->master || !bitbang->chipselect) return -EINVAL; - INIT_WORK(&bitbang->work, bitbang_work); + INIT_WORK(&bitbang->work, bitbang_work, bitbang); spin_lock_init(&bitbang->lock); INIT_LIST_HEAD(&bitbang->queue); diff --git a/trunk/drivers/telephony/ixj_pcmcia.c b/trunk/drivers/telephony/ixj_pcmcia.c index 164a5dcf1f1e..dda0ca45d904 100644 --- a/trunk/drivers/telephony/ixj_pcmcia.c +++ b/trunk/drivers/telephony/ixj_pcmcia.c @@ -69,21 +69,25 @@ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) static void ixj_get_serial(struct pcmcia_device * link, IXJ * j) { + tuple_t tuple; + u_short buf[128]; char *str; - int i, place; + int last_ret, last_fn, i, place; DEBUG(0, "ixj_get_serial(0x%p)\n", link); - - str = link->prod_id[0]; - if (!str) - goto cs_failed; + tuple.TupleData = (cisdata_t *) buf; + tuple.TupleOffset = 0; + tuple.TupleDataMax = 80; + tuple.Attributes = 0; + tuple.DesiredTuple = CISTPL_VERS_1; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + str = (char *) buf; + printk("PCMCIA Version %d.%d\n", str[0], str[1]); + str += 2; printk("%s", str); - str = link->prod_id[1]; - if (!str) - goto cs_failed; + str = str + strlen(str) + 1; printk(" %s", str); - str = link->prod_id[2]; - if (!str) - goto cs_failed; + str = str + strlen(str) + 1; place = 1; for (i = strlen(str) - 1; i >= 0; i--) { switch (str[i]) { @@ -118,9 +122,7 @@ static void ixj_get_serial(struct pcmcia_device * link, IXJ * j) } place = place * 0x10; } - str = link->prod_id[3]; - if (!str) - goto cs_failed; + str = str + strlen(str) + 1; printk(" version %s\n", str); cs_failed: return; @@ -144,6 +146,13 @@ static int ixj_config(struct pcmcia_device * link) tuple.TupleData = (cisdata_t *) buf; tuple.TupleOffset = 0; tuple.TupleDataMax = 255; + tuple.Attributes = 0; + tuple.DesiredTuple = CISTPL_CONFIG; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + link->conf.ConfigBase = parse.config.base; + link->conf.Present = parse.config.rmask[0]; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; tuple.Attributes = 0; CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); diff --git a/trunk/drivers/usb/atm/cxacru.c b/trunk/drivers/usb/atm/cxacru.c index 3dfa3e40e148..e6565633ba0f 100644 --- a/trunk/drivers/usb/atm/cxacru.c +++ b/trunk/drivers/usb/atm/cxacru.c @@ -158,7 +158,7 @@ struct cxacru_data { const struct cxacru_modem_type *modem_type; int line_status; - struct delayed_work poll_work; + struct work_struct poll_work; /* contol handles */ struct mutex cm_serialize; @@ -347,7 +347,7 @@ static int cxacru_card_status(struct cxacru_data *instance) return 0; } -static void cxacru_poll_status(struct work_struct *work); +static void cxacru_poll_status(struct cxacru_data *instance); static int cxacru_atm_start(struct usbatm_data *usbatm_instance, struct atm_dev *atm_dev) @@ -376,14 +376,12 @@ static int cxacru_atm_start(struct usbatm_data *usbatm_instance, } /* Start status polling */ - cxacru_poll_status(&instance->poll_work.work); + cxacru_poll_status(instance); return 0; } -static void cxacru_poll_status(struct work_struct *work) +static void cxacru_poll_status(struct cxacru_data *instance) { - struct cxacru_data *instance = - container_of(work, struct cxacru_data, poll_work.work); u32 buf[CXINF_MAX] = {}; struct usbatm_data *usbatm = instance->usbatm; struct atm_dev *atm_dev = usbatm->atm_dev; @@ -722,7 +720,7 @@ static int cxacru_bind(struct usbatm_data *usbatm_instance, mutex_init(&instance->cm_serialize); - INIT_DELAYED_WORK(&instance->poll_work, cxacru_poll_status); + INIT_WORK(&instance->poll_work, (void *)cxacru_poll_status, instance); usbatm_instance->driver_data = instance; diff --git a/trunk/drivers/usb/atm/speedtch.c b/trunk/drivers/usb/atm/speedtch.c index 8ed6c75adf0f..a823486495c3 100644 --- a/trunk/drivers/usb/atm/speedtch.c +++ b/trunk/drivers/usb/atm/speedtch.c @@ -142,7 +142,7 @@ struct speedtch_instance_data { struct speedtch_params params; /* set in probe, constant afterwards */ - struct delayed_work status_checker; + struct work_struct status_checker; unsigned char last_status; @@ -498,11 +498,8 @@ static int speedtch_start_synchro(struct speedtch_instance_data *instance) return ret; } -static void speedtch_check_status(struct work_struct *work) +static void speedtch_check_status(struct speedtch_instance_data *instance) { - struct speedtch_instance_data *instance = - container_of(work, struct speedtch_instance_data, - status_checker.work); struct usbatm_data *usbatm = instance->usbatm; struct atm_dev *atm_dev = usbatm->atm_dev; unsigned char *buf = instance->scratch_buffer; @@ -579,7 +576,7 @@ static void speedtch_status_poll(unsigned long data) { struct speedtch_instance_data *instance = (void *)data; - schedule_delayed_work(&instance->status_checker, 0); + schedule_work(&instance->status_checker); /* The following check is racy, but the race is harmless */ if (instance->poll_delay < MAX_POLL_DELAY) @@ -599,7 +596,7 @@ static void speedtch_resubmit_int(unsigned long data) if (int_urb) { ret = usb_submit_urb(int_urb, GFP_ATOMIC); if (!ret) - schedule_delayed_work(&instance->status_checker, 0); + schedule_work(&instance->status_checker); else { atm_dbg(instance->usbatm, "%s: usb_submit_urb failed with result %d\n", __func__, ret); mod_timer(&instance->resubmit_timer, jiffies + msecs_to_jiffies(RESUBMIT_DELAY)); @@ -643,7 +640,7 @@ static void speedtch_handle_int(struct urb *int_urb) if ((int_urb = instance->int_urb)) { ret = usb_submit_urb(int_urb, GFP_ATOMIC); - schedule_delayed_work(&instance->status_checker, 0); + schedule_work(&instance->status_checker); if (ret < 0) { atm_dbg(usbatm, "%s: usb_submit_urb failed with result %d\n", __func__, ret); goto fail; @@ -858,7 +855,7 @@ static int speedtch_bind(struct usbatm_data *usbatm, usbatm->flags |= (use_isoc ? UDSL_USE_ISOC : 0); - INIT_DELAYED_WORK(&instance->status_checker, speedtch_check_status); + INIT_WORK(&instance->status_checker, (void *)speedtch_check_status, instance); instance->status_checker.timer.function = speedtch_status_poll; instance->status_checker.timer.data = (unsigned long)instance; diff --git a/trunk/drivers/usb/atm/ueagle-atm.c b/trunk/drivers/usb/atm/ueagle-atm.c index f2d196fa1e8b..c137c041f7a4 100644 --- a/trunk/drivers/usb/atm/ueagle-atm.c +++ b/trunk/drivers/usb/atm/ueagle-atm.c @@ -655,9 +655,9 @@ static int request_dsp(struct uea_softc *sc) /* * The uea_load_page() function must be called within a process context */ -static void uea_load_page(struct work_struct *work) +static void uea_load_page(void *xsc) { - struct uea_softc *sc = container_of(work, struct uea_softc, task); + struct uea_softc *sc = xsc; u16 pageno = sc->pageno; u16 ovl = sc->ovl; struct block_info bi; @@ -1348,7 +1348,7 @@ static int uea_boot(struct uea_softc *sc) uea_enters(INS_TO_USBDEV(sc)); - INIT_WORK(&sc->task, uea_load_page); + INIT_WORK(&sc->task, uea_load_page, sc); init_waitqueue_head(&sc->sync_q); init_waitqueue_head(&sc->cmv_ack_wait); diff --git a/trunk/drivers/usb/class/cdc-acm.c b/trunk/drivers/usb/class/cdc-acm.c index 7f1fa956dcdb..ec3438dc8ee5 100644 --- a/trunk/drivers/usb/class/cdc-acm.c +++ b/trunk/drivers/usb/class/cdc-acm.c @@ -421,9 +421,9 @@ static void acm_write_bulk(struct urb *urb) schedule_work(&acm->work); } -static void acm_softint(struct work_struct *work) +static void acm_softint(void *private) { - struct acm *acm = container_of(work, struct acm, work); + struct acm *acm = private; dbg("Entering acm_softint."); if (!ACM_READY(acm)) @@ -927,7 +927,7 @@ static int acm_probe (struct usb_interface *intf, acm->rx_buflimit = num_rx_buf; acm->urb_task.func = acm_rx_tasklet; acm->urb_task.data = (unsigned long) acm; - INIT_WORK(&acm->work, acm_softint); + INIT_WORK(&acm->work, acm_softint, acm); spin_lock_init(&acm->throttle_lock); spin_lock_init(&acm->write_lock); spin_lock_init(&acm->read_lock); diff --git a/trunk/drivers/usb/core/hub.c b/trunk/drivers/usb/core/hub.c index 9be41ed1f9a6..0ce393eb3c4b 100644 --- a/trunk/drivers/usb/core/hub.c +++ b/trunk/drivers/usb/core/hub.c @@ -68,7 +68,7 @@ struct usb_hub { unsigned has_indicators:1; u8 indicator[USB_MAXCHILDREN]; - struct delayed_work leds; + struct work_struct leds; }; @@ -218,10 +218,9 @@ static void set_port_led( #define LED_CYCLE_PERIOD ((2*HZ)/3) -static void led_work (struct work_struct *work) +static void led_work (void *__hub) { - struct usb_hub *hub = - container_of(work, struct usb_hub, leds.work); + struct usb_hub *hub = __hub; struct usb_device *hdev = hub->hdev; unsigned i; unsigned changed = 0; @@ -406,10 +405,9 @@ hub_clear_tt_buffer (struct usb_device *hdev, u16 devinfo, u16 tt) * talking to TTs must queue control transfers (not just bulk and iso), so * both can talk to the same hub concurrently. */ -static void hub_tt_kevent (struct work_struct *work) +static void hub_tt_kevent (void *arg) { - struct usb_hub *hub = - container_of(work, struct usb_hub, tt.kevent); + struct usb_hub *hub = arg; unsigned long flags; spin_lock_irqsave (&hub->tt.lock, flags); @@ -696,7 +694,7 @@ static int hub_configure(struct usb_hub *hub, spin_lock_init (&hub->tt.lock); INIT_LIST_HEAD (&hub->tt.clear_list); - INIT_WORK (&hub->tt.kevent, hub_tt_kevent); + INIT_WORK (&hub->tt.kevent, hub_tt_kevent, hub); switch (hdev->descriptor.bDeviceProtocol) { case 0: break; @@ -940,7 +938,7 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) INIT_LIST_HEAD(&hub->event_list); hub->intfdev = &intf->dev; hub->hdev = hdev; - INIT_DELAYED_WORK(&hub->leds, led_work); + INIT_WORK(&hub->leds, led_work, hub); usb_set_intfdata (intf, hub); intf->needs_remote_wakeup = 1; @@ -2383,7 +2381,7 @@ check_highspeed (struct usb_hub *hub, struct usb_device *udev, int port1) /* hub LEDs are probably harder to miss than syslog */ if (hub->has_indicators) { hub->indicator[port1-1] = INDICATOR_GREEN_BLINK; - schedule_delayed_work (&hub->leds, 0); + schedule_work (&hub->leds); } } kfree(qual); @@ -2557,7 +2555,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, if (hub->has_indicators) { hub->indicator[port1-1] = INDICATOR_AMBER_BLINK; - schedule_delayed_work (&hub->leds, 0); + schedule_work (&hub->leds); } status = -ENOTCONN; /* Don't retry */ goto loop_disable; diff --git a/trunk/drivers/usb/core/message.c b/trunk/drivers/usb/core/message.c index 7390b67c609d..29b0fa9ff9d0 100644 --- a/trunk/drivers/usb/core/message.c +++ b/trunk/drivers/usb/core/message.c @@ -1501,10 +1501,9 @@ struct set_config_request { }; /* Worker routine for usb_driver_set_configuration() */ -static void driver_set_config_work(struct work_struct *work) +static void driver_set_config_work(void *_req) { - struct set_config_request *req = - container_of(work, struct set_config_request, work); + struct set_config_request *req = _req; usb_lock_device(req->udev); usb_set_configuration(req->udev, req->config); @@ -1542,7 +1541,7 @@ int usb_driver_set_configuration(struct usb_device *udev, int config) return -ENOMEM; req->udev = udev; req->config = config; - INIT_WORK(&req->work, driver_set_config_work); + INIT_WORK(&req->work, driver_set_config_work, req); usb_get_dev(udev); if (!schedule_work(&req->work)) { diff --git a/trunk/drivers/usb/core/usb.c b/trunk/drivers/usb/core/usb.c index 02426d0b9a34..81cb52564e68 100644 --- a/trunk/drivers/usb/core/usb.c +++ b/trunk/drivers/usb/core/usb.c @@ -203,10 +203,9 @@ static void ksuspend_usb_cleanup(void) #ifdef CONFIG_USB_SUSPEND /* usb_autosuspend_work - callback routine to autosuspend a USB device */ -static void usb_autosuspend_work(struct work_struct *work) +static void usb_autosuspend_work(void *_udev) { - struct usb_device *udev = - container_of(work, struct usb_device, autosuspend.work); + struct usb_device *udev = _udev; usb_pm_lock(udev); udev->auto_pm = 1; @@ -216,7 +215,7 @@ static void usb_autosuspend_work(struct work_struct *work) #else -static void usb_autosuspend_work(struct work_struct *work) +static void usb_autosuspend_work(void *_udev) {} #endif /* CONFIG_USB_SUSPEND */ @@ -305,7 +304,7 @@ usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1) #ifdef CONFIG_PM mutex_init(&dev->pm_mutex); - INIT_DELAYED_WORK(&dev->autosuspend, usb_autosuspend_work); + INIT_WORK(&dev->autosuspend, usb_autosuspend_work, dev); #endif return dev; } diff --git a/trunk/drivers/usb/gadget/ether.c b/trunk/drivers/usb/gadget/ether.c index d15bf22b9a03..3bd1dfe565c1 100644 --- a/trunk/drivers/usb/gadget/ether.c +++ b/trunk/drivers/usb/gadget/ether.c @@ -1833,9 +1833,9 @@ static void rx_fill (struct eth_dev *dev, gfp_t gfp_flags) spin_unlock_irqrestore(&dev->req_lock, flags); } -static void eth_work (struct work_struct *work) +static void eth_work (void *_dev) { - struct eth_dev *dev = container_of(work, struct eth_dev, work); + struct eth_dev *dev = _dev; if (test_and_clear_bit (WORK_RX_MEMORY, &dev->todo)) { if (netif_running (dev->net)) @@ -2398,7 +2398,7 @@ eth_bind (struct usb_gadget *gadget) dev = netdev_priv(net); spin_lock_init (&dev->lock); spin_lock_init (&dev->req_lock); - INIT_WORK (&dev->work, eth_work); + INIT_WORK (&dev->work, eth_work, dev); INIT_LIST_HEAD (&dev->tx_reqs); INIT_LIST_HEAD (&dev->rx_reqs); diff --git a/trunk/drivers/usb/host/sl811_cs.c b/trunk/drivers/usb/host/sl811_cs.c index ac9f11d19817..54f554e0f0ad 100644 --- a/trunk/drivers/usb/host/sl811_cs.c +++ b/trunk/drivers/usb/host/sl811_cs.c @@ -169,14 +169,21 @@ static int sl811_cs_config(struct pcmcia_device *link) DBG(0, "sl811_cs_config(0x%p)\n", link); - /* Look up the current Vcc */ - CS_CHECK(GetConfigurationInfo, - pcmcia_get_configuration_info(link, &conf)); - + tuple.DesiredTuple = CISTPL_CONFIG; tuple.Attributes = 0; tuple.TupleData = buf; tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + link->conf.ConfigBase = parse.config.base; + link->conf.Present = parse.config.rmask[0]; + + /* Look up the current Vcc */ + CS_CHECK(GetConfigurationInfo, + pcmcia_get_configuration_info(link, &conf)); + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); while (1) { diff --git a/trunk/drivers/usb/host/u132-hcd.c b/trunk/drivers/usb/host/u132-hcd.c index a9d7119e3176..ef54e310bfc4 100644 --- a/trunk/drivers/usb/host/u132-hcd.c +++ b/trunk/drivers/usb/host/u132-hcd.c @@ -163,7 +163,7 @@ struct u132_endp { u16 queue_next; struct urb *urb_list[ENDP_QUEUE_SIZE]; struct list_head urb_more; - struct delayed_work scheduler; + struct work_struct scheduler; }; struct u132_ring { unsigned in_use:1; @@ -171,7 +171,7 @@ struct u132_ring { u8 number; struct u132 *u132; struct u132_endp *curr_endp; - struct delayed_work scheduler; + struct work_struct scheduler; }; #define OHCI_QUIRK_AMD756 0x01 #define OHCI_QUIRK_SUPERIO 0x02 @@ -198,7 +198,7 @@ struct u132 { u32 hc_roothub_portstatus[MAX_ROOT_PORTS]; int flags; unsigned long next_statechange; - struct delayed_work monitor; + struct work_struct monitor; int num_endpoints; struct u132_addr addr[MAX_U132_ADDRS]; struct u132_udev udev[MAX_U132_UDEVS]; @@ -310,7 +310,7 @@ static void u132_ring_requeue_work(struct u132 *u132, struct u132_ring *ring, if (delta > 0) { if (queue_delayed_work(workqueue, &ring->scheduler, delta)) return; - } else if (queue_delayed_work(workqueue, &ring->scheduler, 0)) + } else if (queue_work(workqueue, &ring->scheduler)) return; kref_put(&u132->kref, u132_hcd_delete); return; @@ -389,8 +389,12 @@ static inline void u132_endp_init_kref(struct u132 *u132, static void u132_endp_queue_work(struct u132 *u132, struct u132_endp *endp, unsigned int delta) { - if (queue_delayed_work(workqueue, &endp->scheduler, delta)) - kref_get(&endp->kref); + if (delta > 0) { + if (queue_delayed_work(workqueue, &endp->scheduler, delta)) + kref_get(&endp->kref); + } else if (queue_work(workqueue, &endp->scheduler)) + kref_get(&endp->kref); + return; } static void u132_endp_cancel_work(struct u132 *u132, struct u132_endp *endp) @@ -406,14 +410,24 @@ static inline void u132_monitor_put_kref(struct u132 *u132) static void u132_monitor_queue_work(struct u132 *u132, unsigned int delta) { - if (queue_delayed_work(workqueue, &u132->monitor, delta)) - kref_get(&u132->kref); + if (delta > 0) { + if (queue_delayed_work(workqueue, &u132->monitor, delta)) { + kref_get(&u132->kref); + } + } else if (queue_work(workqueue, &u132->monitor)) + kref_get(&u132->kref); + return; } static void u132_monitor_requeue_work(struct u132 *u132, unsigned int delta) { - if (!queue_delayed_work(workqueue, &u132->monitor, delta)) - kref_put(&u132->kref, u132_hcd_delete); + if (delta > 0) { + if (queue_delayed_work(workqueue, &u132->monitor, delta)) + return; + } else if (queue_work(workqueue, &u132->monitor)) + return; + kref_put(&u132->kref, u132_hcd_delete); + return; } static void u132_monitor_cancel_work(struct u132 *u132) @@ -475,9 +489,9 @@ static int read_roothub_info(struct u132 *u132) return 0; } -static void u132_hcd_monitor_work(struct work_struct *work) +static void u132_hcd_monitor_work(void *data) { - struct u132 *u132 = container_of(work, struct u132, monitor.work); + struct u132 *u132 = data; if (u132->going > 1) { dev_err(&u132->platform_dev->dev, "device has been removed %d\n" , u132->going); @@ -1301,14 +1315,15 @@ static void u132_hcd_initial_setup_sent(void *data, struct urb *urb, u8 *buf, } } +static void u132_hcd_ring_work_scheduler(void *data); +static void u132_hcd_endp_work_scheduler(void *data); /* * this work function is only executed from the work queue * */ -static void u132_hcd_ring_work_scheduler(struct work_struct *work) +static void u132_hcd_ring_work_scheduler(void *data) { - struct u132_ring *ring = - container_of(work, struct u132_ring, scheduler.work); + struct u132_ring *ring = data; struct u132 *u132 = ring->u132; down(&u132->scheduler_lock); if (ring->in_use) { @@ -1367,11 +1382,10 @@ static void u132_hcd_ring_work_scheduler(struct work_struct *work) } } -static void u132_hcd_endp_work_scheduler(struct work_struct *work) +static void u132_hcd_endp_work_scheduler(void *data) { struct u132_ring *ring; - struct u132_endp *endp = - container_of(work, struct u132_endp, scheduler.work); + struct u132_endp *endp = data; struct u132 *u132 = endp->u132; down(&u132->scheduler_lock); ring = endp->ring; @@ -1929,7 +1943,7 @@ static int create_endpoint_and_queue_int(struct u132 *u132, if (!endp) { return -ENOMEM; } - INIT_DELAYED_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler); + INIT_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler, (void *)endp); spin_lock_init(&endp->queue_lock.slock); INIT_LIST_HEAD(&endp->urb_more); ring = endp->ring = &u132->ring[0]; @@ -2018,7 +2032,7 @@ static int create_endpoint_and_queue_bulk(struct u132 *u132, if (!endp) { return -ENOMEM; } - INIT_DELAYED_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler); + INIT_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler, (void *)endp); spin_lock_init(&endp->queue_lock.slock); INIT_LIST_HEAD(&endp->urb_more); endp->dequeueing = 0; @@ -2103,7 +2117,7 @@ static int create_endpoint_and_queue_control(struct u132 *u132, if (!endp) { return -ENOMEM; } - INIT_DELAYED_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler); + INIT_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler, (void *)endp); spin_lock_init(&endp->queue_lock.slock); INIT_LIST_HEAD(&endp->urb_more); ring = endp->ring = &u132->ring[0]; @@ -3082,10 +3096,10 @@ static void u132_initialise(struct u132 *u132, struct platform_device *pdev) ring->number = rings + 1; ring->length = 0; ring->curr_endp = NULL; - INIT_DELAYED_WORK(&ring->scheduler, - u132_hcd_ring_work_scheduler); + INIT_WORK(&ring->scheduler, u132_hcd_ring_work_scheduler, + (void *)ring); } down(&u132->sw_lock); - INIT_DELAYED_WORK(&u132->monitor, u132_hcd_monitor_work); + INIT_WORK(&u132->monitor, u132_hcd_monitor_work, (void *)u132); while (ports-- > 0) { struct u132_port *port = &u132->port[ports]; port->u132 = u132; diff --git a/trunk/drivers/usb/input/hid-core.c b/trunk/drivers/usb/input/hid-core.c index 4295bab4f1e2..a49644b7c58e 100644 --- a/trunk/drivers/usb/input/hid-core.c +++ b/trunk/drivers/usb/input/hid-core.c @@ -969,10 +969,9 @@ static void hid_retry_timeout(unsigned long _hid) } /* Workqueue routine to reset the device or clear a halt */ -static void hid_reset(struct work_struct *work) +static void hid_reset(void *_hid) { - struct hid_device *hid = - container_of(work, struct hid_device, reset_work); + struct hid_device *hid = (struct hid_device *) _hid; int rc_lock, rc = 0; if (test_bit(HID_CLEAR_HALT, &hid->iofl)) { @@ -2044,7 +2043,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) init_waitqueue_head(&hid->wait); - INIT_WORK(&hid->reset_work, hid_reset); + INIT_WORK(&hid->reset_work, hid_reset, hid); setup_timer(&hid->io_retry, hid_retry_timeout, (unsigned long) hid); spin_lock_init(&hid->inlock); diff --git a/trunk/drivers/usb/misc/appledisplay.c b/trunk/drivers/usb/misc/appledisplay.c index 02cbb7fff24f..ba30ca6a14aa 100644 --- a/trunk/drivers/usb/misc/appledisplay.c +++ b/trunk/drivers/usb/misc/appledisplay.c @@ -76,7 +76,7 @@ struct appledisplay { char *urbdata; /* interrupt URB data buffer */ char *msgdata; /* control message data buffer */ - struct delayed_work work; + struct work_struct work; int button_pressed; spinlock_t lock; }; @@ -117,7 +117,7 @@ static void appledisplay_complete(struct urb *urb) case ACD_BTN_BRIGHT_UP: case ACD_BTN_BRIGHT_DOWN: pdata->button_pressed = 1; - queue_delayed_work(wq, &pdata->work, 0); + queue_work(wq, &pdata->work); break; case ACD_BTN_NONE: default: @@ -184,10 +184,9 @@ static struct backlight_properties appledisplay_bl_data = { .max_brightness = 0xFF }; -static void appledisplay_work(struct work_struct *work) +static void appledisplay_work(void *private) { - struct appledisplay *pdata = - container_of(work, struct appledisplay, work.work); + struct appledisplay *pdata = private; int retval; up(&pdata->bd->sem); @@ -239,7 +238,7 @@ static int appledisplay_probe(struct usb_interface *iface, pdata->udev = udev; spin_lock_init(&pdata->lock); - INIT_DELAYED_WORK(&pdata->work, appledisplay_work); + INIT_WORK(&pdata->work, appledisplay_work, pdata); /* Allocate buffer for control messages */ pdata->msgdata = kmalloc(ACD_MSG_BUFFER_LEN, GFP_KERNEL); diff --git a/trunk/drivers/usb/misc/ftdi-elan.c b/trunk/drivers/usb/misc/ftdi-elan.c index 18b1925032a8..cb0ba3107d7f 100644 --- a/trunk/drivers/usb/misc/ftdi-elan.c +++ b/trunk/drivers/usb/misc/ftdi-elan.c @@ -156,9 +156,9 @@ struct usb_ftdi { struct usb_device *udev; struct usb_interface *interface; struct usb_class_driver *class; - struct delayed_work status_work; - struct delayed_work command_work; - struct delayed_work respond_work; + struct work_struct status_work; + struct work_struct command_work; + struct work_struct respond_work; struct u132_platform_data platform_data; struct resource resources[0]; struct platform_device platform_dev; @@ -210,14 +210,23 @@ static void ftdi_elan_init_kref(struct usb_ftdi *ftdi) static void ftdi_status_requeue_work(struct usb_ftdi *ftdi, unsigned int delta) { - if (!queue_delayed_work(status_queue, &ftdi->status_work, delta)) - kref_put(&ftdi->kref, ftdi_elan_delete); + if (delta > 0) { + if (queue_delayed_work(status_queue, &ftdi->status_work, delta)) + return; + } else if (queue_work(status_queue, &ftdi->status_work)) + return; + kref_put(&ftdi->kref, ftdi_elan_delete); + return; } static void ftdi_status_queue_work(struct usb_ftdi *ftdi, unsigned int delta) { - if (queue_delayed_work(status_queue, &ftdi->status_work, delta)) - kref_get(&ftdi->kref); + if (delta > 0) { + if (queue_delayed_work(status_queue, &ftdi->status_work, delta)) + kref_get(&ftdi->kref); + } else if (queue_work(status_queue, &ftdi->status_work)) + kref_get(&ftdi->kref); + return; } static void ftdi_status_cancel_work(struct usb_ftdi *ftdi) @@ -228,14 +237,25 @@ static void ftdi_status_cancel_work(struct usb_ftdi *ftdi) static void ftdi_command_requeue_work(struct usb_ftdi *ftdi, unsigned int delta) { - if (!queue_delayed_work(command_queue, &ftdi->command_work, delta)) - kref_put(&ftdi->kref, ftdi_elan_delete); + if (delta > 0) { + if (queue_delayed_work(command_queue, &ftdi->command_work, + delta)) + return; + } else if (queue_work(command_queue, &ftdi->command_work)) + return; + kref_put(&ftdi->kref, ftdi_elan_delete); + return; } static void ftdi_command_queue_work(struct usb_ftdi *ftdi, unsigned int delta) { - if (queue_delayed_work(command_queue, &ftdi->command_work, delta)) - kref_get(&ftdi->kref); + if (delta > 0) { + if (queue_delayed_work(command_queue, &ftdi->command_work, + delta)) + kref_get(&ftdi->kref); + } else if (queue_work(command_queue, &ftdi->command_work)) + kref_get(&ftdi->kref); + return; } static void ftdi_command_cancel_work(struct usb_ftdi *ftdi) @@ -247,14 +267,25 @@ static void ftdi_command_cancel_work(struct usb_ftdi *ftdi) static void ftdi_response_requeue_work(struct usb_ftdi *ftdi, unsigned int delta) { - if (!queue_delayed_work(respond_queue, &ftdi->respond_work, delta)) - kref_put(&ftdi->kref, ftdi_elan_delete); + if (delta > 0) { + if (queue_delayed_work(respond_queue, &ftdi->respond_work, + delta)) + return; + } else if (queue_work(respond_queue, &ftdi->respond_work)) + return; + kref_put(&ftdi->kref, ftdi_elan_delete); + return; } static void ftdi_respond_queue_work(struct usb_ftdi *ftdi, unsigned int delta) { - if (queue_delayed_work(respond_queue, &ftdi->respond_work, delta)) - kref_get(&ftdi->kref); + if (delta > 0) { + if (queue_delayed_work(respond_queue, &ftdi->respond_work, + delta)) + kref_get(&ftdi->kref); + } else if (queue_work(respond_queue, &ftdi->respond_work)) + kref_get(&ftdi->kref); + return; } static void ftdi_response_cancel_work(struct usb_ftdi *ftdi) @@ -444,11 +475,9 @@ static void ftdi_elan_kick_command_queue(struct usb_ftdi *ftdi) return; } -static void ftdi_elan_command_work(struct work_struct *work) +static void ftdi_elan_command_work(void *data) { - struct usb_ftdi *ftdi = - container_of(work, struct usb_ftdi, command_work.work); - + struct usb_ftdi *ftdi = data; if (ftdi->disconnected > 0) { ftdi_elan_put_kref(ftdi); return; @@ -471,10 +500,9 @@ static void ftdi_elan_kick_respond_queue(struct usb_ftdi *ftdi) return; } -static void ftdi_elan_respond_work(struct work_struct *work) +static void ftdi_elan_respond_work(void *data) { - struct usb_ftdi *ftdi = - container_of(work, struct usb_ftdi, respond_work.work); + struct usb_ftdi *ftdi = data; if (ftdi->disconnected > 0) { ftdi_elan_put_kref(ftdi); return; @@ -506,10 +534,9 @@ static void ftdi_elan_respond_work(struct work_struct *work) * after the FTDI has been synchronized * */ -static void ftdi_elan_status_work(struct work_struct *work) +static void ftdi_elan_status_work(void *data) { - struct usb_ftdi *ftdi = - container_of(work, struct usb_ftdi, status_work.work); + struct usb_ftdi *ftdi = data; int work_delay_in_msec = 0; if (ftdi->disconnected > 0) { ftdi_elan_put_kref(ftdi); @@ -2650,9 +2677,12 @@ static int ftdi_elan_probe(struct usb_interface *interface, ftdi->class = NULL; dev_info(&ftdi->udev->dev, "USB FDTI=%p ELAN interface %d now a" "ctivated\n", ftdi, iface_desc->desc.bInterfaceNumber); - INIT_DELAYED_WORK(&ftdi->status_work, ftdi_elan_status_work); - INIT_DELAYED_WORK(&ftdi->command_work, ftdi_elan_command_work); - INIT_DELAYED_WORK(&ftdi->respond_work, ftdi_elan_respond_work); + INIT_WORK(&ftdi->status_work, ftdi_elan_status_work, + (void *)ftdi); + INIT_WORK(&ftdi->command_work, ftdi_elan_command_work, + (void *)ftdi); + INIT_WORK(&ftdi->respond_work, ftdi_elan_respond_work, + (void *)ftdi); ftdi_status_queue_work(ftdi, msecs_to_jiffies(3 *1000)); return 0; } else { diff --git a/trunk/drivers/usb/misc/phidgetkit.c b/trunk/drivers/usb/misc/phidgetkit.c index 9659c79e187e..9110793f81d3 100644 --- a/trunk/drivers/usb/misc/phidgetkit.c +++ b/trunk/drivers/usb/misc/phidgetkit.c @@ -81,8 +81,8 @@ struct interfacekit { unsigned char *data; dma_addr_t data_dma; - struct delayed_work do_notify; - struct delayed_work do_resubmit; + struct work_struct do_notify; + struct work_struct do_resubmit; unsigned long input_events; unsigned long sensor_events; }; @@ -374,7 +374,7 @@ static void interfacekit_irq(struct urb *urb) } if (kit->input_events || kit->sensor_events) - schedule_delayed_work(&kit->do_notify, 0); + schedule_work(&kit->do_notify); resubmit: status = usb_submit_urb(urb, SLAB_ATOMIC); @@ -384,10 +384,9 @@ static void interfacekit_irq(struct urb *urb) kit->udev->devpath, status); } -static void do_notify(struct work_struct *work) +static void do_notify(void *data) { - struct interfacekit *kit = - container_of(work, struct interfacekit, do_notify.work); + struct interfacekit *kit = data; int i; char sysfs_file[8]; @@ -406,11 +405,9 @@ static void do_notify(struct work_struct *work) } } -static void do_resubmit(struct work_struct *work) +static void do_resubmit(void *data) { - struct interfacekit *kit = - container_of(work, struct interfacekit, do_resubmit.work); - set_outputs(kit); + set_outputs(data); } #define show_set_output(value) \ @@ -578,8 +575,8 @@ static int interfacekit_probe(struct usb_interface *intf, const struct usb_devic kit->udev = usb_get_dev(dev); kit->intf = intf; - INIT_DELAYED_WORK(&kit->do_notify, do_notify); - INIT_DELAYED_WORK(&kit->do_resubmit, do_resubmit); + INIT_WORK(&kit->do_notify, do_notify, kit); + INIT_WORK(&kit->do_resubmit, do_resubmit, kit); usb_fill_int_urb(kit->irq, kit->udev, pipe, kit->data, maxp > URB_INT_SIZE ? URB_INT_SIZE : maxp, interfacekit_irq, kit, endpoint->bInterval); diff --git a/trunk/drivers/usb/misc/phidgetmotorcontrol.c b/trunk/drivers/usb/misc/phidgetmotorcontrol.c index 2bb4fa572bb7..c3469b0a67c2 100644 --- a/trunk/drivers/usb/misc/phidgetmotorcontrol.c +++ b/trunk/drivers/usb/misc/phidgetmotorcontrol.c @@ -41,7 +41,7 @@ struct motorcontrol { unsigned char *data; dma_addr_t data_dma; - struct delayed_work do_notify; + struct work_struct do_notify; unsigned long input_events; unsigned long speed_events; unsigned long exceed_events; @@ -148,7 +148,7 @@ static void motorcontrol_irq(struct urb *urb) set_bit(1, &mc->exceed_events); if (mc->input_events || mc->exceed_events || mc->speed_events) - schedule_delayed_work(&mc->do_notify, 0); + schedule_work(&mc->do_notify); resubmit: status = usb_submit_urb(urb, SLAB_ATOMIC); @@ -159,10 +159,9 @@ static void motorcontrol_irq(struct urb *urb) mc->udev->devpath, status); } -static void do_notify(struct work_struct *work) +static void do_notify(void *data) { - struct motorcontrol *mc = - container_of(work, struct motorcontrol, do_notify.work); + struct motorcontrol *mc = data; int i; char sysfs_file[8]; @@ -349,7 +348,7 @@ static int motorcontrol_probe(struct usb_interface *intf, const struct usb_devic mc->udev = usb_get_dev(dev); mc->intf = intf; mc->acceleration[0] = mc->acceleration[1] = 10; - INIT_DELAYED_WORK(&mc->do_notify, do_notify); + INIT_WORK(&mc->do_notify, do_notify, mc); usb_fill_int_urb(mc->irq, mc->udev, pipe, mc->data, maxp > URB_INT_SIZE ? URB_INT_SIZE : maxp, motorcontrol_irq, mc, endpoint->bInterval); diff --git a/trunk/drivers/usb/net/kaweth.c b/trunk/drivers/usb/net/kaweth.c index fa78326d0bf0..7c906a43e497 100644 --- a/trunk/drivers/usb/net/kaweth.c +++ b/trunk/drivers/usb/net/kaweth.c @@ -222,7 +222,7 @@ struct kaweth_device int suspend_lowmem_ctrl; int linkstate; int opened; - struct delayed_work lowmem_work; + struct work_struct lowmem_work; struct usb_device *dev; struct net_device *net; @@ -530,10 +530,9 @@ static void int_callback(struct urb *u) kaweth_resubmit_int_urb(kaweth, GFP_ATOMIC); } -static void kaweth_resubmit_tl(struct work_struct *work) +static void kaweth_resubmit_tl(void *d) { - struct kaweth_device *kaweth = - container_of(work, struct kaweth_device, lowmem_work.work); + struct kaweth_device *kaweth = (struct kaweth_device *)d; if (IS_BLOCKED(kaweth->status)) return; @@ -1127,7 +1126,7 @@ static int kaweth_probe( /* kaweth is zeroed as part of alloc_netdev */ - INIT_DELAYED_WORK(&kaweth->lowmem_work, kaweth_resubmit_tl); + INIT_WORK(&kaweth->lowmem_work, kaweth_resubmit_tl, (void *)kaweth); SET_MODULE_OWNER(netdev); diff --git a/trunk/drivers/usb/net/pegasus.c b/trunk/drivers/usb/net/pegasus.c index b5690b3834e3..69eb0db399df 100644 --- a/trunk/drivers/usb/net/pegasus.c +++ b/trunk/drivers/usb/net/pegasus.c @@ -1281,9 +1281,9 @@ static inline void setup_pegasus_II(pegasus_t * pegasus) static struct workqueue_struct *pegasus_workqueue = NULL; #define CARRIER_CHECK_DELAY (2 * HZ) -static void check_carrier(struct work_struct *work) +static void check_carrier(void *data) { - pegasus_t *pegasus = container_of(work, pegasus_t, carrier_check.work); + pegasus_t *pegasus = data; set_carrier(pegasus->net); if (!(pegasus->flags & PEGASUS_UNPLUG)) { queue_delayed_work(pegasus_workqueue, &pegasus->carrier_check, @@ -1319,7 +1319,7 @@ static int pegasus_probe(struct usb_interface *intf, tasklet_init(&pegasus->rx_tl, rx_fixup, (unsigned long) pegasus); - INIT_DELAYED_WORK(&pegasus->carrier_check, check_carrier); + INIT_WORK(&pegasus->carrier_check, check_carrier, pegasus); pegasus->intf = intf; pegasus->usb = dev; diff --git a/trunk/drivers/usb/net/pegasus.h b/trunk/drivers/usb/net/pegasus.h index 98f6898cae1f..006438069b66 100644 --- a/trunk/drivers/usb/net/pegasus.h +++ b/trunk/drivers/usb/net/pegasus.h @@ -95,7 +95,7 @@ typedef struct pegasus { int dev_index; int intr_interval; struct tasklet_struct rx_tl; - struct delayed_work carrier_check; + struct work_struct carrier_check; struct urb *ctrl_urb, *rx_urb, *tx_urb, *intr_urb; struct sk_buff *rx_pool[RX_SKBS]; struct sk_buff *rx_skb; diff --git a/trunk/drivers/usb/net/usbnet.c b/trunk/drivers/usb/net/usbnet.c index 327f97555679..7672e11c94c4 100644 --- a/trunk/drivers/usb/net/usbnet.c +++ b/trunk/drivers/usb/net/usbnet.c @@ -782,10 +782,9 @@ static struct ethtool_ops usbnet_ethtool_ops = { * especially now that control transfers can be queued. */ static void -kevent (struct work_struct *work) +kevent (void *data) { - struct usbnet *dev = - container_of(work, struct usbnet, kevent); + struct usbnet *dev = data; int status; /* usb_clear_halt() needs a thread context */ @@ -1147,7 +1146,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) skb_queue_head_init (&dev->done); dev->bh.func = usbnet_bh; dev->bh.data = (unsigned long) dev; - INIT_WORK (&dev->kevent, kevent); + INIT_WORK (&dev->kevent, kevent, dev); dev->delay.function = usbnet_bh; dev->delay.data = (unsigned long) dev; init_timer (&dev->delay); diff --git a/trunk/drivers/usb/serial/aircable.c b/trunk/drivers/usb/serial/aircable.c index 86bcf63b6ba5..b1b5707bc99a 100644 --- a/trunk/drivers/usb/serial/aircable.c +++ b/trunk/drivers/usb/serial/aircable.c @@ -92,7 +92,6 @@ struct aircable_private { struct circ_buf *rx_buf; /* read buffer */ int rx_flags; /* for throttilng */ struct work_struct rx_work; /* work cue for the receiving line */ - struct usb_serial_port *port; /* USB port with which associated */ }; /* Private methods */ @@ -252,11 +251,10 @@ static void aircable_send(struct usb_serial_port *port) schedule_work(&port->work); } -static void aircable_read(struct work_struct *work) +static void aircable_read(void *params) { - struct aircable_private *priv = - container_of(work, struct aircable_private, rx_work); - struct usb_serial_port *port = priv->port; + struct usb_serial_port *port = params; + struct aircable_private *priv = usb_get_serial_port_data(port); struct tty_struct *tty; unsigned char *data; int count; @@ -351,8 +349,7 @@ static int aircable_attach (struct usb_serial *serial) } priv->rx_flags &= ~(THROTTLED | ACTUALLY_THROTTLED); - priv->port = port; - INIT_WORK(&priv->rx_work, aircable_read); + INIT_WORK(&priv->rx_work, aircable_read, port); usb_set_serial_port_data(serial->port[0], priv); @@ -519,7 +516,7 @@ static void aircable_read_bulk_callback(struct urb *urb) package_length - shift); } } - aircable_read(&priv->rx_work); + aircable_read(port); } /* Schedule the next read _if_ we are still open */ diff --git a/trunk/drivers/usb/serial/digi_acceleport.c b/trunk/drivers/usb/serial/digi_acceleport.c index 83d0e21145b0..5e3ac281a2f8 100644 --- a/trunk/drivers/usb/serial/digi_acceleport.c +++ b/trunk/drivers/usb/serial/digi_acceleport.c @@ -430,14 +430,13 @@ struct digi_port { int dp_in_close; /* close in progress */ wait_queue_head_t dp_close_wait; /* wait queue for close */ struct work_struct dp_wakeup_work; - struct usb_serial_port *dp_port; }; /* Local Function Declarations */ static void digi_wakeup_write( struct usb_serial_port *port ); -static void digi_wakeup_write_lock(struct work_struct *work); +static void digi_wakeup_write_lock(void *); static int digi_write_oob_command( struct usb_serial_port *port, unsigned char *buf, int count, int interruptible ); static int digi_write_inb_command( struct usb_serial_port *port, @@ -599,12 +598,11 @@ static inline long cond_wait_interruptible_timeout_irqrestore( * on writes. */ -static void digi_wakeup_write_lock(struct work_struct *work) +static void digi_wakeup_write_lock(void *arg) { - struct digi_port *priv = - container_of(work, struct digi_port, dp_wakeup_work); - struct usb_serial_port *port = priv->dp_port; + struct usb_serial_port *port = arg; unsigned long flags; + struct digi_port *priv = usb_get_serial_port_data(port); spin_lock_irqsave( &priv->dp_port_lock, flags ); @@ -1704,8 +1702,8 @@ dbg( "digi_startup: TOP" ); init_waitqueue_head( &priv->dp_flush_wait ); priv->dp_in_close = 0; init_waitqueue_head( &priv->dp_close_wait ); - INIT_WORK(&priv->dp_wakeup_work, digi_wakeup_write_lock); - priv->dp_port = serial->port[i]; + INIT_WORK(&priv->dp_wakeup_work, + digi_wakeup_write_lock, serial->port[i]); /* initialize write wait queue for this port */ init_waitqueue_head( &serial->port[i]->write_wait ); diff --git a/trunk/drivers/usb/serial/ftdi_sio.c b/trunk/drivers/usb/serial/ftdi_sio.c index 72e4d48f51e9..89ce2775be15 100644 --- a/trunk/drivers/usb/serial/ftdi_sio.c +++ b/trunk/drivers/usb/serial/ftdi_sio.c @@ -559,8 +559,7 @@ struct ftdi_private { char prev_status, diff_status; /* Used for TIOCMIWAIT */ __u8 rx_flags; /* receive state flags (throttling) */ spinlock_t rx_lock; /* spinlock for receive state */ - struct delayed_work rx_work; - struct usb_serial_port *port; + struct work_struct rx_work; int rx_processed; unsigned long rx_bytes; @@ -594,7 +593,7 @@ static int ftdi_write_room (struct usb_serial_port *port); static int ftdi_chars_in_buffer (struct usb_serial_port *port); static void ftdi_write_bulk_callback (struct urb *urb); static void ftdi_read_bulk_callback (struct urb *urb); -static void ftdi_process_read (struct work_struct *work); +static void ftdi_process_read (void *param); static void ftdi_set_termios (struct usb_serial_port *port, struct termios * old); static int ftdi_tiocmget (struct usb_serial_port *port, struct file *file); static int ftdi_tiocmset (struct usb_serial_port *port, struct file * file, unsigned int set, unsigned int clear); @@ -1202,8 +1201,7 @@ static int ftdi_sio_attach (struct usb_serial *serial) port->read_urb->transfer_buffer_length = BUFSZ; } - INIT_DELAYED_WORK(&priv->rx_work, ftdi_process_read); - priv->port = port; + INIT_WORK(&priv->rx_work, ftdi_process_read, port); /* Free port's existing write urb and transfer buffer. */ if (port->write_urb) { @@ -1642,18 +1640,17 @@ static void ftdi_read_bulk_callback (struct urb *urb) priv->rx_bytes += countread; spin_unlock_irqrestore(&priv->rx_lock, flags); - ftdi_process_read(&priv->rx_work.work); + ftdi_process_read(port); } /* ftdi_read_bulk_callback */ -static void ftdi_process_read (struct work_struct *work) +static void ftdi_process_read (void *param) { /* ftdi_process_read */ - struct ftdi_private *priv = - container_of(work, struct ftdi_private, rx_work.work); - struct usb_serial_port *port = priv->port; + struct usb_serial_port *port = (struct usb_serial_port*)param; struct urb *urb; struct tty_struct *tty; + struct ftdi_private *priv; char error_flag; unsigned char *data; @@ -2182,7 +2179,7 @@ static void ftdi_unthrottle (struct usb_serial_port *port) spin_unlock_irqrestore(&priv->rx_lock, flags); if (actually_throttled) - schedule_delayed_work(&priv->rx_work, 0); + schedule_work(&priv->rx_work); } static int __init ftdi_init (void) diff --git a/trunk/drivers/usb/serial/keyspan_pda.c b/trunk/drivers/usb/serial/keyspan_pda.c index e09a0bfe6231..909005107ea2 100644 --- a/trunk/drivers/usb/serial/keyspan_pda.c +++ b/trunk/drivers/usb/serial/keyspan_pda.c @@ -120,8 +120,6 @@ struct keyspan_pda_private { int tx_throttled; struct work_struct wakeup_work; struct work_struct unthrottle_work; - struct usb_serial *serial; - struct usb_serial_port *port; }; @@ -177,11 +175,9 @@ static struct usb_device_id id_table_fake_xircom [] = { }; #endif -static void keyspan_pda_wakeup_write(struct work_struct *work) +static void keyspan_pda_wakeup_write( struct usb_serial_port *port ) { - struct keyspan_pda_private *priv = - container_of(work, struct keyspan_pda_private, wakeup_work); - struct usb_serial_port *port = priv->port; + struct tty_struct *tty = port->tty; /* wake up port processes */ @@ -191,11 +187,8 @@ static void keyspan_pda_wakeup_write(struct work_struct *work) tty_wakeup(tty); } -static void keyspan_pda_request_unthrottle(struct work_struct *work) +static void keyspan_pda_request_unthrottle( struct usb_serial *serial ) { - struct keyspan_pda_private *priv = - container_of(work, struct keyspan_pda_private, unthrottle_work); - struct usb_serial *serial = priv->serial; int result; dbg(" request_unthrottle"); @@ -772,10 +765,11 @@ static int keyspan_pda_startup (struct usb_serial *serial) return (1); /* error */ usb_set_serial_port_data(serial->port[0], priv); init_waitqueue_head(&serial->port[0]->write_wait); - INIT_WORK(&priv->wakeup_work, keyspan_pda_wakeup_write); - INIT_WORK(&priv->unthrottle_work, keyspan_pda_request_unthrottle); - priv->serial = serial; - priv->port = serial->port[0]; + INIT_WORK(&priv->wakeup_work, (void *)keyspan_pda_wakeup_write, + (void *)(serial->port[0])); + INIT_WORK(&priv->unthrottle_work, + (void *)keyspan_pda_request_unthrottle, + (void *)(serial)); return (0); } diff --git a/trunk/drivers/usb/serial/usb-serial.c b/trunk/drivers/usb/serial/usb-serial.c index 3d5072f14b8d..c1257d5292f5 100644 --- a/trunk/drivers/usb/serial/usb-serial.c +++ b/trunk/drivers/usb/serial/usb-serial.c @@ -533,10 +533,9 @@ void usb_serial_port_softint(struct usb_serial_port *port) schedule_work(&port->work); } -static void usb_serial_port_work(struct work_struct *work) +static void usb_serial_port_work(void *private) { - struct usb_serial_port *port = - container_of(work, struct usb_serial_port, work); + struct usb_serial_port *port = private; struct tty_struct *tty; dbg("%s - port %d", __FUNCTION__, port->number); @@ -800,7 +799,7 @@ int usb_serial_probe(struct usb_interface *interface, port->serial = serial; spin_lock_init(&port->lock); mutex_init(&port->mutex); - INIT_WORK(&port->work, usb_serial_port_work); + INIT_WORK(&port->work, usb_serial_port_work, port); serial->port[i] = port; } diff --git a/trunk/drivers/usb/serial/whiteheat.c b/trunk/drivers/usb/serial/whiteheat.c index 154c7d290597..4d1cd7aeccd3 100644 --- a/trunk/drivers/usb/serial/whiteheat.c +++ b/trunk/drivers/usb/serial/whiteheat.c @@ -227,7 +227,6 @@ struct whiteheat_private { struct list_head rx_urbs_submitted; struct list_head rx_urb_q; struct work_struct rx_work; - struct usb_serial_port *port; struct list_head tx_urbs_free; struct list_head tx_urbs_submitted; }; @@ -242,7 +241,7 @@ static void command_port_read_callback(struct urb *urb); static int start_port_read(struct usb_serial_port *port); static struct whiteheat_urb_wrap *urb_to_wrap(struct urb *urb, struct list_head *head); static struct list_head *list_first(struct list_head *head); -static void rx_data_softint(struct work_struct *work); +static void rx_data_softint(void *private); static int firm_send_command(struct usb_serial_port *port, __u8 command, __u8 *data, __u8 datasize); static int firm_open(struct usb_serial_port *port); @@ -425,8 +424,7 @@ static int whiteheat_attach (struct usb_serial *serial) spin_lock_init(&info->lock); info->flags = 0; info->mcr = 0; - INIT_WORK(&info->rx_work, rx_data_softint); - info->port = port; + INIT_WORK(&info->rx_work, rx_data_softint, port); INIT_LIST_HEAD(&info->rx_urbs_free); INIT_LIST_HEAD(&info->rx_urbs_submitted); @@ -951,7 +949,7 @@ static void whiteheat_unthrottle (struct usb_serial_port *port) spin_unlock_irqrestore(&info->lock, flags); if (actually_throttled) - rx_data_softint(&info->rx_work); + rx_data_softint(port); return; } @@ -1402,11 +1400,10 @@ static struct list_head *list_first(struct list_head *head) } -static void rx_data_softint(struct work_struct *work) +static void rx_data_softint(void *private) { - struct whiteheat_private *info = - container_of(work, struct whiteheat_private, rx_work); - struct usb_serial_port *port = info->port; + struct usb_serial_port *port = (struct usb_serial_port *)private; + struct whiteheat_private *info = usb_get_serial_port_data(port); struct tty_struct *tty = port->tty; struct whiteheat_urb_wrap *wrap; struct urb *urb; diff --git a/trunk/drivers/video/console/fbcon.c b/trunk/drivers/video/console/fbcon.c index 31f476a64790..302174b8e477 100644 --- a/trunk/drivers/video/console/fbcon.c +++ b/trunk/drivers/video/console/fbcon.c @@ -383,9 +383,9 @@ static void fbcon_update_softback(struct vc_data *vc) softback_top = 0; } -static void fb_flashcursor(struct work_struct *work) +static void fb_flashcursor(void *private) { - struct fb_info *info = container_of(work, struct fb_info, queue); + struct fb_info *info = private; struct fbcon_ops *ops = info->fbcon_par; struct display *p; struct vc_data *vc = NULL; @@ -442,7 +442,7 @@ static void fbcon_add_cursor_timer(struct fb_info *info) if ((!info->queue.func || info->queue.func == fb_flashcursor) && !(ops->flags & FBCON_FLAGS_CURSOR_TIMER)) { if (!info->queue.func) - INIT_WORK(&info->queue, fb_flashcursor); + INIT_WORK(&info->queue, fb_flashcursor, info); init_timer(&ops->cursor_timer); ops->cursor_timer.function = cursor_timer_handler; diff --git a/trunk/drivers/video/pxafb.c b/trunk/drivers/video/pxafb.c index 38eb0b69c2d7..8a8ae55a7403 100644 --- a/trunk/drivers/video/pxafb.c +++ b/trunk/drivers/video/pxafb.c @@ -964,10 +964,9 @@ static void set_ctrlr_state(struct pxafb_info *fbi, u_int state) * Our LCD controller task (which is called when we blank or unblank) * via keventd. */ -static void pxafb_task(struct work_struct *work) +static void pxafb_task(void *dummy) { - struct pxafb_info *fbi = - container_of(work, struct pxafb_info, task); + struct pxafb_info *fbi = dummy; u_int state = xchg(&fbi->task_state, -1); set_ctrlr_state(fbi, state); @@ -1160,7 +1159,7 @@ static struct pxafb_info * __init pxafb_init_fbinfo(struct device *dev) } init_waitqueue_head(&fbi->ctrlr_wait); - INIT_WORK(&fbi->task, pxafb_task); + INIT_WORK(&fbi->task, pxafb_task, fbi); init_MUTEX(&fbi->ctrlr_sem); return fbi; diff --git a/trunk/fs/9p/mux.c b/trunk/fs/9p/mux.c index 944273c3dbff..90a79c784549 100644 --- a/trunk/fs/9p/mux.c +++ b/trunk/fs/9p/mux.c @@ -110,8 +110,8 @@ struct v9fs_mux_rpc { }; static int v9fs_poll_proc(void *); -static void v9fs_read_work(struct work_struct *work); -static void v9fs_write_work(struct work_struct *work); +static void v9fs_read_work(void *); +static void v9fs_write_work(void *); static void v9fs_pollwait(struct file *filp, wait_queue_head_t * wait_address, poll_table * p); static u16 v9fs_mux_get_tag(struct v9fs_mux_data *); @@ -297,8 +297,8 @@ struct v9fs_mux_data *v9fs_mux_init(struct v9fs_transport *trans, int msize, m->rbuf = NULL; m->wpos = m->wsize = 0; m->wbuf = NULL; - INIT_WORK(&m->rq, v9fs_read_work); - INIT_WORK(&m->wq, v9fs_write_work); + INIT_WORK(&m->rq, v9fs_read_work, m); + INIT_WORK(&m->wq, v9fs_write_work, m); m->wsched = 0; memset(&m->poll_waddr, 0, sizeof(m->poll_waddr)); m->poll_task = NULL; @@ -458,13 +458,13 @@ static int v9fs_poll_proc(void *a) /** * v9fs_write_work - called when a transport can send some data */ -static void v9fs_write_work(struct work_struct *work) +static void v9fs_write_work(void *a) { int n, err; struct v9fs_mux_data *m; struct v9fs_req *req; - m = container_of(work, struct v9fs_mux_data, wq); + m = a; if (m->err < 0) { clear_bit(Wworksched, &m->wsched); @@ -564,7 +564,7 @@ static void process_request(struct v9fs_mux_data *m, struct v9fs_req *req) /** * v9fs_read_work - called when there is some data to be read from a transport */ -static void v9fs_read_work(struct work_struct *work) +static void v9fs_read_work(void *a) { int n, err; struct v9fs_mux_data *m; @@ -572,7 +572,7 @@ static void v9fs_read_work(struct work_struct *work) struct v9fs_fcall *rcall; char *rbuf; - m = container_of(work, struct v9fs_mux_data, rq); + m = a; if (m->err < 0) return; diff --git a/trunk/fs/aio.c b/trunk/fs/aio.c index 287a1bc7a182..277a5f2d18ad 100644 --- a/trunk/fs/aio.c +++ b/trunk/fs/aio.c @@ -53,13 +53,13 @@ static kmem_cache_t *kioctx_cachep; static struct workqueue_struct *aio_wq; /* Used for rare fput completion. */ -static void aio_fput_routine(struct work_struct *); -static DECLARE_WORK(fput_work, aio_fput_routine); +static void aio_fput_routine(void *); +static DECLARE_WORK(fput_work, aio_fput_routine, NULL); static DEFINE_SPINLOCK(fput_lock); static LIST_HEAD(fput_head); -static void aio_kick_handler(struct work_struct *); +static void aio_kick_handler(void *); static void aio_queue_work(struct kioctx *); /* aio_setup @@ -227,7 +227,7 @@ static struct kioctx *ioctx_alloc(unsigned nr_events) INIT_LIST_HEAD(&ctx->active_reqs); INIT_LIST_HEAD(&ctx->run_list); - INIT_DELAYED_WORK(&ctx->wq, aio_kick_handler); + INIT_WORK(&ctx->wq, aio_kick_handler, ctx); if (aio_setup_ring(ctx) < 0) goto out_freectx; @@ -469,7 +469,7 @@ static inline void really_put_req(struct kioctx *ctx, struct kiocb *req) wake_up(&ctx->wait); } -static void aio_fput_routine(struct work_struct *data) +static void aio_fput_routine(void *data) { spin_lock_irq(&fput_lock); while (likely(!list_empty(&fput_head))) { @@ -857,9 +857,9 @@ static inline void aio_run_all_iocbs(struct kioctx *ctx) * space. * Run on aiod's context. */ -static void aio_kick_handler(struct work_struct *work) +static void aio_kick_handler(void *data) { - struct kioctx *ctx = container_of(work, struct kioctx, wq.work); + struct kioctx *ctx = data; mm_segment_t oldfs = get_fs(); int requeue; @@ -874,7 +874,7 @@ static void aio_kick_handler(struct work_struct *work) * we're in a worker thread already, don't use queue_delayed_work, */ if (requeue) - queue_delayed_work(aio_wq, &ctx->wq, 0); + queue_work(aio_wq, &ctx->wq); } diff --git a/trunk/fs/bio.c b/trunk/fs/bio.c index 50c40ce2cead..aa4d09bd4e71 100644 --- a/trunk/fs/bio.c +++ b/trunk/fs/bio.c @@ -940,16 +940,16 @@ static void bio_release_pages(struct bio *bio) * run one bio_put() against the BIO. */ -static void bio_dirty_fn(struct work_struct *work); +static void bio_dirty_fn(void *data); -static DECLARE_WORK(bio_dirty_work, bio_dirty_fn); +static DECLARE_WORK(bio_dirty_work, bio_dirty_fn, NULL); static DEFINE_SPINLOCK(bio_dirty_lock); static struct bio *bio_dirty_list; /* * This runs in process context */ -static void bio_dirty_fn(struct work_struct *work) +static void bio_dirty_fn(void *data) { unsigned long flags; struct bio *bio; diff --git a/trunk/fs/file.c b/trunk/fs/file.c index 3787e82f54c1..8e81775c5dc8 100644 --- a/trunk/fs/file.c +++ b/trunk/fs/file.c @@ -91,10 +91,8 @@ static void fdtable_timer(unsigned long data) spin_unlock(&fddef->lock); } -static void free_fdtable_work(struct work_struct *work) +static void free_fdtable_work(struct fdtable_defer *f) { - struct fdtable_defer *f = - container_of(work, struct fdtable_defer, wq); struct fdtable *fdt; spin_lock_bh(&f->lock); @@ -353,7 +351,7 @@ static void __devinit fdtable_defer_list_init(int cpu) { struct fdtable_defer *fddef = &per_cpu(fdtable_defer_list, cpu); spin_lock_init(&fddef->lock); - INIT_WORK(&fddef->wq, free_fdtable_work); + INIT_WORK(&fddef->wq, (void (*)(void *))free_fdtable_work, fddef); init_timer(&fddef->timer); fddef->timer.data = (unsigned long)fddef; fddef->timer.function = fdtable_timer; diff --git a/trunk/fs/gfs2/glock.c b/trunk/fs/gfs2/glock.c index 55f5333dae99..78fe0fae23ff 100644 --- a/trunk/fs/gfs2/glock.c +++ b/trunk/fs/gfs2/glock.c @@ -35,7 +35,7 @@ struct greedy { struct gfs2_holder gr_gh; - struct delayed_work gr_work; + struct work_struct gr_work; }; struct gfs2_gl_hash_bucket { @@ -1368,9 +1368,9 @@ static void gfs2_glock_prefetch(struct gfs2_glock *gl, unsigned int state, glops->go_xmote_th(gl, state, flags); } -static void greedy_work(struct work_struct *work) +static void greedy_work(void *data) { - struct greedy *gr = container_of(work, struct greedy, gr_work.work); + struct greedy *gr = data; struct gfs2_holder *gh = &gr->gr_gh; struct gfs2_glock *gl = gh->gh_gl; const struct gfs2_glock_operations *glops = gl->gl_ops; @@ -1422,7 +1422,7 @@ int gfs2_glock_be_greedy(struct gfs2_glock *gl, unsigned int time) gfs2_holder_init(gl, 0, 0, gh); set_bit(HIF_GREEDY, &gh->gh_iflags); - INIT_DELAYED_WORK(&gr->gr_work, greedy_work); + INIT_WORK(&gr->gr_work, greedy_work, gr); set_bit(GLF_SKIP_WAITERS2, &gl->gl_flags); schedule_delayed_work(&gr->gr_work, time); diff --git a/trunk/fs/ncpfs/inode.c b/trunk/fs/ncpfs/inode.c index 72dad552aa00..42e3bef270c9 100644 --- a/trunk/fs/ncpfs/inode.c +++ b/trunk/fs/ncpfs/inode.c @@ -577,12 +577,12 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent) server->rcv.ptr = (unsigned char*)&server->rcv.buf; server->rcv.len = 10; server->rcv.state = 0; - INIT_WORK(&server->rcv.tq, ncp_tcp_rcv_proc); - INIT_WORK(&server->tx.tq, ncp_tcp_tx_proc); + INIT_WORK(&server->rcv.tq, ncp_tcp_rcv_proc, server); + INIT_WORK(&server->tx.tq, ncp_tcp_tx_proc, server); sock->sk->sk_write_space = ncp_tcp_write_space; } else { - INIT_WORK(&server->rcv.tq, ncpdgram_rcv_proc); - INIT_WORK(&server->timeout_tq, ncpdgram_timeout_proc); + INIT_WORK(&server->rcv.tq, ncpdgram_rcv_proc, server); + INIT_WORK(&server->timeout_tq, ncpdgram_timeout_proc, server); server->timeout_tm.data = (unsigned long)server; server->timeout_tm.function = ncpdgram_timeout_call; } diff --git a/trunk/fs/ncpfs/sock.c b/trunk/fs/ncpfs/sock.c index e496d8b65e92..11c2b252ebed 100644 --- a/trunk/fs/ncpfs/sock.c +++ b/trunk/fs/ncpfs/sock.c @@ -350,10 +350,9 @@ static void info_server(struct ncp_server *server, unsigned int id, const void * } } -void ncpdgram_rcv_proc(struct work_struct *work) +void ncpdgram_rcv_proc(void *s) { - struct ncp_server *server = - container_of(work, struct ncp_server, rcv.tq); + struct ncp_server *server = s; struct socket* sock; sock = server->ncp_sock; @@ -469,10 +468,9 @@ static void __ncpdgram_timeout_proc(struct ncp_server *server) } } -void ncpdgram_timeout_proc(struct work_struct *work) +void ncpdgram_timeout_proc(void *s) { - struct ncp_server *server = - container_of(work, struct ncp_server, timeout_tq); + struct ncp_server *server = s; mutex_lock(&server->rcv.creq_mutex); __ncpdgram_timeout_proc(server); mutex_unlock(&server->rcv.creq_mutex); @@ -654,20 +652,18 @@ skipdata:; } } -void ncp_tcp_rcv_proc(struct work_struct *work) +void ncp_tcp_rcv_proc(void *s) { - struct ncp_server *server = - container_of(work, struct ncp_server, rcv.tq); + struct ncp_server *server = s; mutex_lock(&server->rcv.creq_mutex); __ncptcp_rcv_proc(server); mutex_unlock(&server->rcv.creq_mutex); } -void ncp_tcp_tx_proc(struct work_struct *work) +void ncp_tcp_tx_proc(void *s) { - struct ncp_server *server = - container_of(work, struct ncp_server, tx.tq); + struct ncp_server *server = s; mutex_lock(&server->rcv.creq_mutex); __ncptcp_try_send(server); diff --git a/trunk/fs/nfs/client.c b/trunk/fs/nfs/client.c index 23ab145daa2d..5fea638743e4 100644 --- a/trunk/fs/nfs/client.c +++ b/trunk/fs/nfs/client.c @@ -143,7 +143,7 @@ static struct nfs_client *nfs_alloc_client(const char *hostname, INIT_LIST_HEAD(&clp->cl_state_owners); INIT_LIST_HEAD(&clp->cl_unused); spin_lock_init(&clp->cl_lock); - INIT_DELAYED_WORK(&clp->cl_renewd, nfs4_renew_state); + INIT_WORK(&clp->cl_renewd, nfs4_renew_state, clp); rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS client"); clp->cl_boot_time = CURRENT_TIME; clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED; diff --git a/trunk/fs/nfs/namespace.c b/trunk/fs/nfs/namespace.c index 371b804e7cc8..ec1114b33d89 100644 --- a/trunk/fs/nfs/namespace.c +++ b/trunk/fs/nfs/namespace.c @@ -18,10 +18,10 @@ #define NFSDBG_FACILITY NFSDBG_VFS -static void nfs_expire_automounts(struct work_struct *work); +static void nfs_expire_automounts(void *list); LIST_HEAD(nfs_automount_list); -static DECLARE_DELAYED_WORK(nfs_automount_task, nfs_expire_automounts); +static DECLARE_WORK(nfs_automount_task, nfs_expire_automounts, &nfs_automount_list); int nfs_mountpoint_expiry_timeout = 500 * HZ; static struct vfsmount *nfs_do_submount(const struct vfsmount *mnt_parent, @@ -164,9 +164,9 @@ struct inode_operations nfs_referral_inode_operations = { .follow_link = nfs_follow_mountpoint, }; -static void nfs_expire_automounts(struct work_struct *work) +static void nfs_expire_automounts(void *data) { - struct list_head *list = &nfs_automount_list; + struct list_head *list = (struct list_head *)data; mark_mounts_for_expiry(list); if (!list_empty(list)) diff --git a/trunk/fs/nfs/nfs4_fs.h b/trunk/fs/nfs/nfs4_fs.h index c26cd978c7cc..6f346677332d 100644 --- a/trunk/fs/nfs/nfs4_fs.h +++ b/trunk/fs/nfs/nfs4_fs.h @@ -185,7 +185,7 @@ extern const u32 nfs4_fs_locations_bitmap[2]; extern void nfs4_schedule_state_renewal(struct nfs_client *); extern void nfs4_renewd_prepare_shutdown(struct nfs_server *); extern void nfs4_kill_renewd(struct nfs_client *); -extern void nfs4_renew_state(struct work_struct *); +extern void nfs4_renew_state(void *); /* nfs4state.c */ struct rpc_cred *nfs4_get_renew_cred(struct nfs_client *clp); diff --git a/trunk/fs/nfs/nfs4renewd.c b/trunk/fs/nfs/nfs4renewd.c index 823298561c0a..7b6df1852e75 100644 --- a/trunk/fs/nfs/nfs4renewd.c +++ b/trunk/fs/nfs/nfs4renewd.c @@ -59,10 +59,9 @@ #define NFSDBG_FACILITY NFSDBG_PROC void -nfs4_renew_state(struct work_struct *work) +nfs4_renew_state(void *data) { - struct nfs_client *clp = - container_of(work, struct nfs_client, cl_renewd.work); + struct nfs_client *clp = (struct nfs_client *)data; struct rpc_cred *cred; long lease, timeout; unsigned long last, now; diff --git a/trunk/fs/nfsd/nfs4state.c b/trunk/fs/nfsd/nfs4state.c index e431e93ab503..293b6495829f 100644 --- a/trunk/fs/nfsd/nfs4state.c +++ b/trunk/fs/nfsd/nfs4state.c @@ -1829,8 +1829,9 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf } static struct workqueue_struct *laundry_wq; -static void laundromat_main(struct work_struct *); -static DECLARE_DELAYED_WORK(laundromat_work, laundromat_main); +static struct work_struct laundromat_work; +static void laundromat_main(void *); +static DECLARE_WORK(laundromat_work, laundromat_main, NULL); __be32 nfsd4_renew(clientid_t *clid) @@ -1939,7 +1940,7 @@ nfs4_laundromat(void) } void -laundromat_main(struct work_struct *not_used) +laundromat_main(void *not_used) { time_t t; diff --git a/trunk/fs/ocfs2/alloc.c b/trunk/fs/ocfs2/alloc.c index edc91ca3792a..85a048b7a67b 100644 --- a/trunk/fs/ocfs2/alloc.c +++ b/trunk/fs/ocfs2/alloc.c @@ -1197,12 +1197,10 @@ int ocfs2_flush_truncate_log(struct ocfs2_super *osb) return status; } -static void ocfs2_truncate_log_worker(struct work_struct *work) +static void ocfs2_truncate_log_worker(void *data) { int status; - struct ocfs2_super *osb = - container_of(work, struct ocfs2_super, - osb_truncate_log_wq.work); + struct ocfs2_super *osb = data; mlog_entry_void(); @@ -1434,8 +1432,7 @@ int ocfs2_truncate_log_init(struct ocfs2_super *osb) /* ocfs2_truncate_log_shutdown keys on the existence of * osb->osb_tl_inode so we don't set any of the osb variables * until we're sure all is well. */ - INIT_DELAYED_WORK(&osb->osb_truncate_log_wq, - ocfs2_truncate_log_worker); + INIT_WORK(&osb->osb_truncate_log_wq, ocfs2_truncate_log_worker, osb); osb->osb_tl_bh = tl_bh; osb->osb_tl_inode = tl_inode; diff --git a/trunk/fs/ocfs2/cluster/heartbeat.c b/trunk/fs/ocfs2/cluster/heartbeat.c index 4cd9a9580456..305cba3681fe 100644 --- a/trunk/fs/ocfs2/cluster/heartbeat.c +++ b/trunk/fs/ocfs2/cluster/heartbeat.c @@ -141,7 +141,7 @@ struct o2hb_region { * recognizes a node going up and down in one iteration */ u64 hr_generation; - struct delayed_work hr_write_timeout_work; + struct work_struct hr_write_timeout_work; unsigned long hr_last_timeout_start; /* Used during o2hb_check_slot to hold a copy of the block @@ -156,11 +156,9 @@ struct o2hb_bio_wait_ctxt { int wc_error; }; -static void o2hb_write_timeout(struct work_struct *work) +static void o2hb_write_timeout(void *arg) { - struct o2hb_region *reg = - container_of(work, struct o2hb_region, - hr_write_timeout_work.work); + struct o2hb_region *reg = arg; mlog(ML_ERROR, "Heartbeat write timeout to device %s after %u " "milliseconds\n", reg->hr_dev_name, @@ -1406,7 +1404,7 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg, goto out; } - INIT_DELAYED_WORK(®->hr_write_timeout_work, o2hb_write_timeout); + INIT_WORK(®->hr_write_timeout_work, o2hb_write_timeout, reg); /* * A node is considered live after it has beat LIVE_THRESHOLD diff --git a/trunk/fs/ocfs2/cluster/quorum.c b/trunk/fs/ocfs2/cluster/quorum.c index 4705d659fe57..7bba98fbfc15 100644 --- a/trunk/fs/ocfs2/cluster/quorum.c +++ b/trunk/fs/ocfs2/cluster/quorum.c @@ -88,7 +88,7 @@ void o2quo_disk_timeout(void) o2quo_fence_self(); } -static void o2quo_make_decision(struct work_struct *work) +static void o2quo_make_decision(void *arg) { int quorum; int lowest_hb, lowest_reachable = 0, fence = 0; @@ -306,7 +306,7 @@ void o2quo_init(void) struct o2quo_state *qs = &o2quo_state; spin_lock_init(&qs->qs_lock); - INIT_WORK(&qs->qs_work, o2quo_make_decision); + INIT_WORK(&qs->qs_work, o2quo_make_decision, NULL); } void o2quo_exit(void) diff --git a/trunk/fs/ocfs2/cluster/tcp.c b/trunk/fs/ocfs2/cluster/tcp.c index 9b3209dc0b16..b650efa8c8be 100644 --- a/trunk/fs/ocfs2/cluster/tcp.c +++ b/trunk/fs/ocfs2/cluster/tcp.c @@ -140,11 +140,11 @@ static int o2net_sys_err_translations[O2NET_ERR_MAX] = [O2NET_ERR_DIED] = -EHOSTDOWN,}; /* can't quite avoid *all* internal declarations :/ */ -static void o2net_sc_connect_completed(struct work_struct *work); -static void o2net_rx_until_empty(struct work_struct *work); -static void o2net_shutdown_sc(struct work_struct *work); +static void o2net_sc_connect_completed(void *arg); +static void o2net_rx_until_empty(void *arg); +static void o2net_shutdown_sc(void *arg); static void o2net_listen_data_ready(struct sock *sk, int bytes); -static void o2net_sc_send_keep_req(struct work_struct *work); +static void o2net_sc_send_keep_req(void *arg); static void o2net_idle_timer(unsigned long data); static void o2net_sc_postpone_idle(struct o2net_sock_container *sc); @@ -308,10 +308,10 @@ static struct o2net_sock_container *sc_alloc(struct o2nm_node *node) o2nm_node_get(node); sc->sc_node = node; - INIT_WORK(&sc->sc_connect_work, o2net_sc_connect_completed); - INIT_WORK(&sc->sc_rx_work, o2net_rx_until_empty); - INIT_WORK(&sc->sc_shutdown_work, o2net_shutdown_sc); - INIT_DELAYED_WORK(&sc->sc_keepalive_work, o2net_sc_send_keep_req); + INIT_WORK(&sc->sc_connect_work, o2net_sc_connect_completed, sc); + INIT_WORK(&sc->sc_rx_work, o2net_rx_until_empty, sc); + INIT_WORK(&sc->sc_shutdown_work, o2net_shutdown_sc, sc); + INIT_WORK(&sc->sc_keepalive_work, o2net_sc_send_keep_req, sc); init_timer(&sc->sc_idle_timeout); sc->sc_idle_timeout.function = o2net_idle_timer; @@ -342,7 +342,7 @@ static void o2net_sc_queue_work(struct o2net_sock_container *sc, sc_put(sc); } static void o2net_sc_queue_delayed_work(struct o2net_sock_container *sc, - struct delayed_work *work, + struct work_struct *work, int delay) { sc_get(sc); @@ -350,7 +350,7 @@ static void o2net_sc_queue_delayed_work(struct o2net_sock_container *sc, sc_put(sc); } static void o2net_sc_cancel_delayed_work(struct o2net_sock_container *sc, - struct delayed_work *work) + struct work_struct *work) { if (cancel_delayed_work(work)) sc_put(sc); @@ -564,11 +564,9 @@ static void o2net_ensure_shutdown(struct o2net_node *nn, * ourselves as state_change couldn't get the nn_lock and call set_nn_state * itself. */ -static void o2net_shutdown_sc(struct work_struct *work) +static void o2net_shutdown_sc(void *arg) { - struct o2net_sock_container *sc = - container_of(work, struct o2net_sock_container, - sc_shutdown_work); + struct o2net_sock_container *sc = arg; struct o2net_node *nn = o2net_nn_from_num(sc->sc_node->nd_num); sclog(sc, "shutting down\n"); @@ -1203,10 +1201,9 @@ static int o2net_advance_rx(struct o2net_sock_container *sc) /* this work func is triggerd by data ready. it reads until it can read no * more. it interprets 0, eof, as fatal. if data_ready hits while we're doing * our work the work struct will be marked and we'll be called again. */ -static void o2net_rx_until_empty(struct work_struct *work) +static void o2net_rx_until_empty(void *arg) { - struct o2net_sock_container *sc = - container_of(work, struct o2net_sock_container, sc_rx_work); + struct o2net_sock_container *sc = arg; int ret; do { @@ -1252,11 +1249,9 @@ static int o2net_set_nodelay(struct socket *sock) /* called when a connect completes and after a sock is accepted. the * rx path will see the response and mark the sc valid */ -static void o2net_sc_connect_completed(struct work_struct *work) +static void o2net_sc_connect_completed(void *arg) { - struct o2net_sock_container *sc = - container_of(work, struct o2net_sock_container, - sc_connect_work); + struct o2net_sock_container *sc = arg; mlog(ML_MSG, "sc sending handshake with ver %llu id %llx\n", (unsigned long long)O2NET_PROTOCOL_VERSION, @@ -1267,11 +1262,9 @@ static void o2net_sc_connect_completed(struct work_struct *work) } /* this is called as a work_struct func. */ -static void o2net_sc_send_keep_req(struct work_struct *work) +static void o2net_sc_send_keep_req(void *arg) { - struct o2net_sock_container *sc = - container_of(work, struct o2net_sock_container, - sc_keepalive_work.work); + struct o2net_sock_container *sc = arg; o2net_sendpage(sc, o2net_keep_req, sizeof(*o2net_keep_req)); sc_put(sc); @@ -1321,15 +1314,14 @@ static void o2net_sc_postpone_idle(struct o2net_sock_container *sc) * having a connect attempt fail, etc. This centralizes the logic which decides * if a connect attempt should be made or if we should give up and all future * transmit attempts should fail */ -static void o2net_start_connect(struct work_struct *work) +static void o2net_start_connect(void *arg) { - struct o2net_node *nn = - container_of(work, struct o2net_node, nn_connect_work.work); + struct o2net_node *nn = arg; struct o2net_sock_container *sc = NULL; struct o2nm_node *node = NULL, *mynode = NULL; struct socket *sock = NULL; struct sockaddr_in myaddr = {0, }, remoteaddr = {0, }; - int ret = 0, stop; + int ret = 0; /* if we're greater we initiate tx, otherwise we accept */ if (o2nm_this_node() <= o2net_num_from_nn(nn)) @@ -1350,9 +1342,10 @@ static void o2net_start_connect(struct work_struct *work) spin_lock(&nn->nn_lock); /* see if we already have one pending or have given up */ - stop = (nn->nn_sc || nn->nn_persistent_error); + if (nn->nn_sc || nn->nn_persistent_error) + arg = NULL; spin_unlock(&nn->nn_lock); - if (stop) + if (arg == NULL) /* *shrug*, needed some indicator */ goto out; nn->nn_last_connect_attempt = jiffies; @@ -1428,10 +1421,9 @@ static void o2net_start_connect(struct work_struct *work) return; } -static void o2net_connect_expired(struct work_struct *work) +static void o2net_connect_expired(void *arg) { - struct o2net_node *nn = - container_of(work, struct o2net_node, nn_connect_expired.work); + struct o2net_node *nn = arg; spin_lock(&nn->nn_lock); if (!nn->nn_sc_valid) { @@ -1444,10 +1436,9 @@ static void o2net_connect_expired(struct work_struct *work) spin_unlock(&nn->nn_lock); } -static void o2net_still_up(struct work_struct *work) +static void o2net_still_up(void *arg) { - struct o2net_node *nn = - container_of(work, struct o2net_node, nn_still_up.work); + struct o2net_node *nn = arg; o2quo_hb_still_up(o2net_num_from_nn(nn)); } @@ -1653,9 +1644,9 @@ static int o2net_accept_one(struct socket *sock) return ret; } -static void o2net_accept_many(struct work_struct *work) +static void o2net_accept_many(void *arg) { - struct socket *sock = o2net_listen_sock; + struct socket *sock = arg; while (o2net_accept_one(sock) == 0) cond_resched(); } @@ -1709,7 +1700,7 @@ static int o2net_open_listening_sock(__be16 port) write_unlock_bh(&sock->sk->sk_callback_lock); o2net_listen_sock = sock; - INIT_WORK(&o2net_listen_work, o2net_accept_many); + INIT_WORK(&o2net_listen_work, o2net_accept_many, sock); sock->sk->sk_reuse = 1; ret = sock->ops->bind(sock, (struct sockaddr *)&sin, sizeof(sin)); @@ -1828,10 +1819,9 @@ int o2net_init(void) struct o2net_node *nn = o2net_nn_from_num(i); spin_lock_init(&nn->nn_lock); - INIT_DELAYED_WORK(&nn->nn_connect_work, o2net_start_connect); - INIT_DELAYED_WORK(&nn->nn_connect_expired, - o2net_connect_expired); - INIT_DELAYED_WORK(&nn->nn_still_up, o2net_still_up); + INIT_WORK(&nn->nn_connect_work, o2net_start_connect, nn); + INIT_WORK(&nn->nn_connect_expired, o2net_connect_expired, nn); + INIT_WORK(&nn->nn_still_up, o2net_still_up, nn); /* until we see hb from a node we'll return einval */ nn->nn_persistent_error = -ENOTCONN; init_waitqueue_head(&nn->nn_sc_wq); diff --git a/trunk/fs/ocfs2/cluster/tcp_internal.h b/trunk/fs/ocfs2/cluster/tcp_internal.h index daebbd3a2c8c..4b46aac7d243 100644 --- a/trunk/fs/ocfs2/cluster/tcp_internal.h +++ b/trunk/fs/ocfs2/cluster/tcp_internal.h @@ -86,18 +86,18 @@ struct o2net_node { * connect attempt fails and so can be self-arming. shutdown is * careful to first mark the nn such that no connects will be attempted * before canceling delayed connect work and flushing the queue. */ - struct delayed_work nn_connect_work; + struct work_struct nn_connect_work; unsigned long nn_last_connect_attempt; /* this is queued as nodes come up and is canceled when a connection is * established. this expiring gives up on the node and errors out * transmits */ - struct delayed_work nn_connect_expired; + struct work_struct nn_connect_expired; /* after we give up on a socket we wait a while before deciding * that it is still heartbeating and that we should do some * quorum work */ - struct delayed_work nn_still_up; + struct work_struct nn_still_up; }; struct o2net_sock_container { @@ -129,7 +129,7 @@ struct o2net_sock_container { struct work_struct sc_shutdown_work; struct timer_list sc_idle_timeout; - struct delayed_work sc_keepalive_work; + struct work_struct sc_keepalive_work; unsigned sc_handshake_ok:1; diff --git a/trunk/fs/ocfs2/dlm/dlmcommon.h b/trunk/fs/ocfs2/dlm/dlmcommon.h index 6b6ff76538c5..fa968180b072 100644 --- a/trunk/fs/ocfs2/dlm/dlmcommon.h +++ b/trunk/fs/ocfs2/dlm/dlmcommon.h @@ -153,7 +153,7 @@ static inline struct hlist_head *dlm_lockres_hash(struct dlm_ctxt *dlm, unsigned * called functions that cannot be directly called from the * net message handlers for some reason, usually because * they need to send net messages of their own. */ -void dlm_dispatch_work(struct work_struct *work); +void dlm_dispatch_work(void *data); struct dlm_lock_resource; struct dlm_work_item; diff --git a/trunk/fs/ocfs2/dlm/dlmdomain.c b/trunk/fs/ocfs2/dlm/dlmdomain.c index 420a375a3949..f6cdab3a2c6a 100644 --- a/trunk/fs/ocfs2/dlm/dlmdomain.c +++ b/trunk/fs/ocfs2/dlm/dlmdomain.c @@ -1297,7 +1297,7 @@ static struct dlm_ctxt *dlm_alloc_ctxt(const char *domain, spin_lock_init(&dlm->work_lock); INIT_LIST_HEAD(&dlm->work_list); - INIT_WORK(&dlm->dispatched_work, dlm_dispatch_work); + INIT_WORK(&dlm->dispatched_work, dlm_dispatch_work, dlm); kref_init(&dlm->dlm_refs); dlm->dlm_state = DLM_CTXT_NEW; diff --git a/trunk/fs/ocfs2/dlm/dlmrecovery.c b/trunk/fs/ocfs2/dlm/dlmrecovery.c index fb3e2b0817f1..9d950d7cea38 100644 --- a/trunk/fs/ocfs2/dlm/dlmrecovery.c +++ b/trunk/fs/ocfs2/dlm/dlmrecovery.c @@ -153,10 +153,9 @@ static inline void dlm_reset_recovery(struct dlm_ctxt *dlm) } /* Worker function used during recovery. */ -void dlm_dispatch_work(struct work_struct *work) +void dlm_dispatch_work(void *data) { - struct dlm_ctxt *dlm = - container_of(work, struct dlm_ctxt, dispatched_work); + struct dlm_ctxt *dlm = (struct dlm_ctxt *)data; LIST_HEAD(tmp_list); struct list_head *iter, *iter2; struct dlm_work_item *item; diff --git a/trunk/fs/ocfs2/dlm/userdlm.c b/trunk/fs/ocfs2/dlm/userdlm.c index 7d2f578b267d..eead48bbfac6 100644 --- a/trunk/fs/ocfs2/dlm/userdlm.c +++ b/trunk/fs/ocfs2/dlm/userdlm.c @@ -171,14 +171,15 @@ static inline void user_dlm_grab_inode_ref(struct user_lock_res *lockres) BUG(); } -static void user_dlm_unblock_lock(struct work_struct *work); +static void user_dlm_unblock_lock(void *opaque); static void __user_dlm_queue_lockres(struct user_lock_res *lockres) { if (!(lockres->l_flags & USER_LOCK_QUEUED)) { user_dlm_grab_inode_ref(lockres); - INIT_WORK(&lockres->l_work, user_dlm_unblock_lock); + INIT_WORK(&lockres->l_work, user_dlm_unblock_lock, + lockres); queue_work(user_dlm_worker, &lockres->l_work); lockres->l_flags |= USER_LOCK_QUEUED; @@ -278,11 +279,10 @@ static inline void user_dlm_drop_inode_ref(struct user_lock_res *lockres) iput(inode); } -static void user_dlm_unblock_lock(struct work_struct *work) +static void user_dlm_unblock_lock(void *opaque) { int new_level, status; - struct user_lock_res *lockres = - container_of(work, struct user_lock_res, l_work); + struct user_lock_res *lockres = (struct user_lock_res *) opaque; struct dlm_ctxt *dlm = dlm_ctxt_from_user_lockres(lockres); mlog(0, "processing lockres %.*s\n", lockres->l_namelen, diff --git a/trunk/fs/ocfs2/journal.c b/trunk/fs/ocfs2/journal.c index 1d7f4ab1e5ed..c0ad7cb59521 100644 --- a/trunk/fs/ocfs2/journal.c +++ b/trunk/fs/ocfs2/journal.c @@ -703,12 +703,11 @@ struct ocfs2_la_recovery_item { * NOTE: This function can and will sleep on recovery of other nodes * during cluster locking, just like any other ocfs2 process. */ -void ocfs2_complete_recovery(struct work_struct *work) +void ocfs2_complete_recovery(void *data) { int ret; - struct ocfs2_journal *journal = - container_of(work, struct ocfs2_journal, j_recovery_work); - struct ocfs2_super *osb = journal->j_osb; + struct ocfs2_super *osb = data; + struct ocfs2_journal *journal = osb->journal; struct ocfs2_dinode *la_dinode, *tl_dinode; struct ocfs2_la_recovery_item *item; struct list_head *p, *n; diff --git a/trunk/fs/ocfs2/journal.h b/trunk/fs/ocfs2/journal.h index 899112ad8136..d86cb960b7ec 100644 --- a/trunk/fs/ocfs2/journal.h +++ b/trunk/fs/ocfs2/journal.h @@ -133,7 +133,7 @@ static inline void ocfs2_inode_set_new(struct ocfs2_super *osb, } /* Exported only for the journal struct init code in super.c. Do not call. */ -void ocfs2_complete_recovery(struct work_struct *work); +void ocfs2_complete_recovery(void *data); /* * Journal Control: diff --git a/trunk/fs/ocfs2/ocfs2.h b/trunk/fs/ocfs2/ocfs2.h index b767fd7da6eb..078883772bd6 100644 --- a/trunk/fs/ocfs2/ocfs2.h +++ b/trunk/fs/ocfs2/ocfs2.h @@ -285,7 +285,7 @@ struct ocfs2_super /* Truncate log info */ struct inode *osb_tl_inode; struct buffer_head *osb_tl_bh; - struct delayed_work osb_truncate_log_wq; + struct work_struct osb_truncate_log_wq; struct ocfs2_node_map osb_recovering_orphan_dirs; unsigned int *osb_orphan_wipes; diff --git a/trunk/fs/ocfs2/super.c b/trunk/fs/ocfs2/super.c index d9b4214a12da..b0992573dee2 100644 --- a/trunk/fs/ocfs2/super.c +++ b/trunk/fs/ocfs2/super.c @@ -1365,7 +1365,7 @@ static int ocfs2_initialize_super(struct super_block *sb, spin_lock_init(&journal->j_lock); journal->j_trans_id = (unsigned long) 1; INIT_LIST_HEAD(&journal->j_la_cleanups); - INIT_WORK(&journal->j_recovery_work, ocfs2_complete_recovery); + INIT_WORK(&journal->j_recovery_work, ocfs2_complete_recovery, osb); journal->j_state = OCFS2_JOURNAL_FREE; /* get some pseudo constants for clustersize bits */ diff --git a/trunk/fs/reiserfs/journal.c b/trunk/fs/reiserfs/journal.c index 7280a23ef344..ac93174c9639 100644 --- a/trunk/fs/reiserfs/journal.c +++ b/trunk/fs/reiserfs/journal.c @@ -104,7 +104,7 @@ static int release_journal_dev(struct super_block *super, struct reiserfs_journal *journal); static int dirty_one_transaction(struct super_block *s, struct reiserfs_journal_list *jl); -static void flush_async_commits(struct work_struct *work); +static void flush_async_commits(void *p); static void queue_log_writer(struct super_block *s); /* values for join in do_journal_begin_r */ @@ -2836,8 +2836,7 @@ int journal_init(struct super_block *p_s_sb, const char *j_dev_name, if (reiserfs_mounted_fs_count <= 1) commit_wq = create_workqueue("reiserfs"); - INIT_DELAYED_WORK(&journal->j_work, flush_async_commits); - journal->j_work_sb = p_s_sb; + INIT_WORK(&journal->j_work, flush_async_commits, p_s_sb); return 0; free_and_return: free_journal_ram(p_s_sb); @@ -3448,11 +3447,10 @@ int journal_end_sync(struct reiserfs_transaction_handle *th, /* ** writeback the pending async commits to disk */ -static void flush_async_commits(struct work_struct *work) +static void flush_async_commits(void *p) { - struct reiserfs_journal *journal = - container_of(work, struct reiserfs_journal, j_work.work); - struct super_block *p_s_sb = journal->j_work_sb; + struct super_block *p_s_sb = p; + struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb); struct reiserfs_journal_list *jl; struct list_head *entry; diff --git a/trunk/fs/xfs/linux-2.6/xfs_aops.c b/trunk/fs/xfs/linux-2.6/xfs_aops.c index 8e6b56fc1cad..09360cf1e1f2 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_aops.c +++ b/trunk/fs/xfs/linux-2.6/xfs_aops.c @@ -149,10 +149,9 @@ xfs_destroy_ioend( */ STATIC void xfs_end_bio_delalloc( - struct work_struct *work) + void *data) { - xfs_ioend_t *ioend = - container_of(work, xfs_ioend_t, io_work); + xfs_ioend_t *ioend = data; xfs_destroy_ioend(ioend); } @@ -162,10 +161,9 @@ xfs_end_bio_delalloc( */ STATIC void xfs_end_bio_written( - struct work_struct *work) + void *data) { - xfs_ioend_t *ioend = - container_of(work, xfs_ioend_t, io_work); + xfs_ioend_t *ioend = data; xfs_destroy_ioend(ioend); } @@ -178,10 +176,9 @@ xfs_end_bio_written( */ STATIC void xfs_end_bio_unwritten( - struct work_struct *work) + void *data) { - xfs_ioend_t *ioend = - container_of(work, xfs_ioend_t, io_work); + xfs_ioend_t *ioend = data; bhv_vnode_t *vp = ioend->io_vnode; xfs_off_t offset = ioend->io_offset; size_t size = ioend->io_size; @@ -223,11 +220,11 @@ xfs_alloc_ioend( ioend->io_size = 0; if (type == IOMAP_UNWRITTEN) - INIT_WORK(&ioend->io_work, xfs_end_bio_unwritten); + INIT_WORK(&ioend->io_work, xfs_end_bio_unwritten, ioend); else if (type == IOMAP_DELAY) - INIT_WORK(&ioend->io_work, xfs_end_bio_delalloc); + INIT_WORK(&ioend->io_work, xfs_end_bio_delalloc, ioend); else - INIT_WORK(&ioend->io_work, xfs_end_bio_written); + INIT_WORK(&ioend->io_work, xfs_end_bio_written, ioend); return ioend; } diff --git a/trunk/fs/xfs/linux-2.6/xfs_buf.c b/trunk/fs/xfs/linux-2.6/xfs_buf.c index eef4a0ba11e9..d3382843698e 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_buf.c +++ b/trunk/fs/xfs/linux-2.6/xfs_buf.c @@ -994,10 +994,9 @@ xfs_buf_wait_unpin( STATIC void xfs_buf_iodone_work( - struct work_struct *work) + void *v) { - xfs_buf_t *bp = - container_of(work, xfs_buf_t, b_iodone_work); + xfs_buf_t *bp = (xfs_buf_t *)v; if (bp->b_iodone) (*(bp->b_iodone))(bp); @@ -1018,10 +1017,10 @@ xfs_buf_ioend( if ((bp->b_iodone) || (bp->b_flags & XBF_ASYNC)) { if (schedule) { - INIT_WORK(&bp->b_iodone_work, xfs_buf_iodone_work); + INIT_WORK(&bp->b_iodone_work, xfs_buf_iodone_work, bp); queue_work(xfslogd_workqueue, &bp->b_iodone_work); } else { - xfs_buf_iodone_work(&bp->b_iodone_work); + xfs_buf_iodone_work(bp); } } else { up(&bp->b_iodonesema); diff --git a/trunk/include/asm-arm/arch-omap/irda.h b/trunk/include/asm-arm/arch-omap/irda.h index 345a649ec838..805ae3575e44 100644 --- a/trunk/include/asm-arm/arch-omap/irda.h +++ b/trunk/include/asm-arm/arch-omap/irda.h @@ -24,7 +24,7 @@ struct omap_irda_config { /* Very specific to the needs of some platforms (h3,h4) * having calls which can sleep in irda_set_speed. */ - struct delayed_work gpio_expa; + struct work_struct gpio_expa; int rx_channel; int tx_channel; unsigned long dest_start; diff --git a/trunk/include/asm-m68knommu/irq.h b/trunk/include/asm-m68knommu/irq.h index 7b8f874f8429..45e7a2fd1689 100644 --- a/trunk/include/asm-m68knommu/irq.h +++ b/trunk/include/asm-m68knommu/irq.h @@ -86,6 +86,5 @@ extern void (*mach_disable_irq)(unsigned int); #define enable_irq(x) do { } while (0) #define disable_irq(x) do { } while (0) #define disable_irq_nosync(x) disable_irq(x) -#define irq_canonicalize(irq) (irq) #endif /* _M68K_IRQ_H_ */ diff --git a/trunk/include/asm-m68knommu/rtc.h b/trunk/include/asm-m68knommu/rtc.h deleted file mode 100644 index eaf18ec83c8e..000000000000 --- a/trunk/include/asm-m68knommu/rtc.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/include/asm-m68knommu/ucontext.h b/trunk/include/asm-m68knommu/ucontext.h index 713a27f901cd..5d570cedbb02 100644 --- a/trunk/include/asm-m68knommu/ucontext.h +++ b/trunk/include/asm-m68knommu/ucontext.h @@ -5,17 +5,21 @@ typedef int greg_t; #define NGREG 18 typedef greg_t gregset_t[NGREG]; +#ifdef CONFIG_FPU typedef struct fpregset { int f_pcr; int f_psr; int f_fpiaddr; int f_fpregs[8][3]; } fpregset_t; +#endif struct mcontext { int version; gregset_t gregs; +#ifdef CONFIG_FPU fpregset_t fpregs; +#endif }; #define MCONTEXT_VERSION 2 @@ -25,7 +29,9 @@ struct ucontext { struct ucontext *uc_link; stack_t uc_stack; struct mcontext uc_mcontext; +#ifdef CONFIG_FPU unsigned long uc_filler[80]; +#endif sigset_t uc_sigmask; /* mask last for extensibility */ }; diff --git a/trunk/include/linux/aio.h b/trunk/include/linux/aio.h index 9e350fd44d77..0d71c0041f13 100644 --- a/trunk/include/linux/aio.h +++ b/trunk/include/linux/aio.h @@ -194,7 +194,7 @@ struct kioctx { struct aio_ring_info ring_info; - struct delayed_work wq; + struct work_struct wq; }; /* prototypes */ diff --git a/trunk/include/linux/connector.h b/trunk/include/linux/connector.h index 3ea1cd58de97..4c02119c6ab9 100644 --- a/trunk/include/linux/connector.h +++ b/trunk/include/linux/connector.h @@ -133,7 +133,7 @@ struct cn_callback_data { struct cn_callback_entry { struct list_head callback_entry; struct cn_callback *cb; - struct delayed_work work; + struct work_struct work; struct cn_queue_dev *pdev; struct cn_callback_id id; @@ -170,7 +170,7 @@ void cn_queue_free_dev(struct cn_queue_dev *dev); int cn_cb_equal(struct cb_id *, struct cb_id *); -void cn_queue_wrapper(struct work_struct *work); +void cn_queue_wrapper(void *data); extern int cn_already_initialized; diff --git a/trunk/include/linux/i2o.h b/trunk/include/linux/i2o.h index 1fb02e17f6f6..c115e9e840b4 100644 --- a/trunk/include/linux/i2o.h +++ b/trunk/include/linux/i2o.h @@ -461,7 +461,7 @@ struct i2o_driver { int (*reply) (struct i2o_controller *, u32, struct i2o_message *); /* Event handler */ - work_func_t event; + void (*event) (struct i2o_event *); struct workqueue_struct *event_queue; /* Event queue */ diff --git a/trunk/include/linux/kbd_kern.h b/trunk/include/linux/kbd_kern.h index 06c58c423fe1..efe0ee4cc80b 100644 --- a/trunk/include/linux/kbd_kern.h +++ b/trunk/include/linux/kbd_kern.h @@ -158,7 +158,7 @@ static inline void con_schedule_flip(struct tty_struct *t) if (t->buf.tail != NULL) t->buf.tail->commit = t->buf.tail->used; spin_unlock_irqrestore(&t->buf.lock, flags); - schedule_delayed_work(&t->buf.work, 0); + schedule_work(&t->buf.work); } #endif diff --git a/trunk/include/linux/libata.h b/trunk/include/linux/libata.h index ab2754830322..202283b5df96 100644 --- a/trunk/include/linux/libata.h +++ b/trunk/include/linux/libata.h @@ -575,9 +575,8 @@ struct ata_port { struct ata_host *host; struct device *dev; - void *port_task_data; - struct delayed_work port_task; - struct delayed_work hotplug_task; + struct work_struct port_task; + struct work_struct hotplug_task; struct work_struct scsi_rescan_task; unsigned int hsm_task_state; @@ -756,7 +755,7 @@ extern void ata_host_resume(struct ata_host *host); extern int ata_ratelimit(void); extern int ata_busy_sleep(struct ata_port *ap, unsigned long timeout_pat, unsigned long timeout); -extern void ata_port_queue_task(struct ata_port *ap, work_func_t fn, +extern void ata_port_queue_task(struct ata_port *ap, void (*fn)(void *), void *data, unsigned long delay); extern u32 ata_wait_register(void __iomem *reg, u32 mask, u32 val, unsigned long interval_msec, diff --git a/trunk/include/linux/mmc/host.h b/trunk/include/linux/mmc/host.h index c15ae1986b98..528e7d3fecb1 100644 --- a/trunk/include/linux/mmc/host.h +++ b/trunk/include/linux/mmc/host.h @@ -110,7 +110,7 @@ struct mmc_host { struct mmc_card *card_busy; /* the MMC card claiming host */ struct mmc_card *card_selected; /* the selected MMC card */ - struct delayed_work detect; + struct work_struct detect; unsigned long private[0] ____cacheline_aligned; }; diff --git a/trunk/include/linux/ncp_fs_sb.h b/trunk/include/linux/ncp_fs_sb.h index a503052138bd..b089d9506283 100644 --- a/trunk/include/linux/ncp_fs_sb.h +++ b/trunk/include/linux/ncp_fs_sb.h @@ -127,10 +127,10 @@ struct ncp_server { } unexpected_packet; }; -extern void ncp_tcp_rcv_proc(struct work_struct *work); -extern void ncp_tcp_tx_proc(struct work_struct *work); -extern void ncpdgram_rcv_proc(struct work_struct *work); -extern void ncpdgram_timeout_proc(struct work_struct *work); +extern void ncp_tcp_rcv_proc(void *server); +extern void ncp_tcp_tx_proc(void *server); +extern void ncpdgram_rcv_proc(void *server); +extern void ncpdgram_timeout_proc(void *server); extern void ncpdgram_timeout_call(unsigned long server); extern void ncp_tcp_data_ready(struct sock* sk, int len); extern void ncp_tcp_write_space(struct sock* sk); diff --git a/trunk/include/linux/netpoll.h b/trunk/include/linux/netpoll.h index 29930b71a9aa..2cc9867b1626 100644 --- a/trunk/include/linux/netpoll.h +++ b/trunk/include/linux/netpoll.h @@ -32,7 +32,7 @@ struct netpoll_info { struct netpoll *rx_np; /* netpoll that registered an rx_hook */ struct sk_buff_head arp_tx; /* list of arp requests to reply to */ struct sk_buff_head txq; - struct delayed_work tx_work; + struct work_struct tx_work; }; void netpoll_poll(struct netpoll *np); diff --git a/trunk/include/linux/nfs_fs_sb.h b/trunk/include/linux/nfs_fs_sb.h index 95796e6924f1..7ccfc7ef0a83 100644 --- a/trunk/include/linux/nfs_fs_sb.h +++ b/trunk/include/linux/nfs_fs_sb.h @@ -51,7 +51,7 @@ struct nfs_client { unsigned long cl_lease_time; unsigned long cl_last_renewal; - struct delayed_work cl_renewd; + struct work_struct cl_renewd; struct rpc_wait_queue cl_rpcwaitq; diff --git a/trunk/include/linux/reiserfs_fs_sb.h b/trunk/include/linux/reiserfs_fs_sb.h index 3a28742d86f9..62a7169aed8b 100644 --- a/trunk/include/linux/reiserfs_fs_sb.h +++ b/trunk/include/linux/reiserfs_fs_sb.h @@ -249,8 +249,7 @@ struct reiserfs_journal { int j_errno; /* when flushing ordered buffers, throttle new ordered writers */ - struct delayed_work j_work; - struct super_block *j_work_sb; + struct work_struct j_work; atomic_t j_async_throttle; }; diff --git a/trunk/include/linux/relay.h b/trunk/include/linux/relay.h index 0e3d91b76996..24accb483849 100644 --- a/trunk/include/linux/relay.h +++ b/trunk/include/linux/relay.h @@ -38,7 +38,7 @@ struct rchan_buf size_t subbufs_consumed; /* count of sub-buffers consumed */ struct rchan *chan; /* associated channel */ wait_queue_head_t read_wait; /* reader wait queue */ - struct delayed_work wake_readers; /* reader wake-up work struct */ + struct work_struct wake_readers; /* reader wake-up work struct */ struct dentry *dentry; /* channel file dentry */ struct kref kref; /* channel buffer refcount */ struct page **page_array; /* array of current buffer pages */ diff --git a/trunk/include/linux/sunrpc/rpc_pipe_fs.h b/trunk/include/linux/sunrpc/rpc_pipe_fs.h index 4a68125b6de6..a2eb9b4a9de3 100644 --- a/trunk/include/linux/sunrpc/rpc_pipe_fs.h +++ b/trunk/include/linux/sunrpc/rpc_pipe_fs.h @@ -30,7 +30,7 @@ struct rpc_inode { #define RPC_PIPE_WAIT_FOR_OPEN 1 int flags; struct rpc_pipe_ops *ops; - struct delayed_work queue_timeout; + struct work_struct queue_timeout; }; static inline struct rpc_inode * diff --git a/trunk/include/linux/sunrpc/xprt.h b/trunk/include/linux/sunrpc/xprt.h index 3e04c1512fc4..60394fbc4c70 100644 --- a/trunk/include/linux/sunrpc/xprt.h +++ b/trunk/include/linux/sunrpc/xprt.h @@ -177,7 +177,7 @@ struct rpc_xprt { unsigned long connect_timeout, bind_timeout, reestablish_timeout; - struct delayed_work connect_worker; + struct work_struct connect_worker; unsigned short port; /* diff --git a/trunk/include/linux/tty.h b/trunk/include/linux/tty.h index f717f0898238..65321f911c1e 100644 --- a/trunk/include/linux/tty.h +++ b/trunk/include/linux/tty.h @@ -53,7 +53,7 @@ struct tty_buffer { }; struct tty_bufhead { - struct delayed_work work; + struct work_struct work; struct semaphore pty_sem; spinlock_t lock; struct tty_buffer *head; /* Queue head */ diff --git a/trunk/include/linux/usb.h b/trunk/include/linux/usb.h index aab5b1b72021..0cd73edeef13 100644 --- a/trunk/include/linux/usb.h +++ b/trunk/include/linux/usb.h @@ -388,7 +388,7 @@ struct usb_device { int pm_usage_cnt; /* usage counter for autosuspend */ #ifdef CONFIG_PM - struct delayed_work autosuspend; /* for delayed autosuspends */ + struct work_struct autosuspend; /* for delayed autosuspends */ struct mutex pm_mutex; /* protects PM operations */ unsigned auto_pm:1; /* autosuspend/resume in progress */ diff --git a/trunk/include/linux/workqueue.h b/trunk/include/linux/workqueue.h index 4a3ea83c6d16..9bca3539a1e5 100644 --- a/trunk/include/linux/workqueue.h +++ b/trunk/include/linux/workqueue.h @@ -11,23 +11,12 @@ struct workqueue_struct; -struct work_struct; -typedef void (*work_func_t)(struct work_struct *work); - struct work_struct { - /* the first word is the work queue pointer and the flags rolled into - * one */ - unsigned long management; -#define WORK_STRUCT_PENDING 0 /* T if work item pending execution */ -#define WORK_STRUCT_NOAUTOREL 1 /* F if work item automatically released on exec */ -#define WORK_STRUCT_FLAG_MASK (3UL) -#define WORK_STRUCT_WQ_DATA_MASK (~WORK_STRUCT_FLAG_MASK) + unsigned long pending; struct list_head entry; - work_func_t func; -}; - -struct delayed_work { - struct work_struct work; + void (*func)(void *); + void *data; + void *wq_data; struct timer_list timer; }; @@ -35,117 +24,36 @@ struct execute_work { struct work_struct work; }; -#define __WORK_INITIALIZER(n, f) { \ - .management = 0, \ - .entry = { &(n).entry, &(n).entry }, \ - .func = (f), \ - } - -#define __WORK_INITIALIZER_NAR(n, f) { \ - .management = (1 << WORK_STRUCT_NOAUTOREL), \ +#define __WORK_INITIALIZER(n, f, d) { \ .entry = { &(n).entry, &(n).entry }, \ .func = (f), \ - } - -#define __DELAYED_WORK_INITIALIZER(n, f) { \ - .work = __WORK_INITIALIZER((n).work, (f)), \ - .timer = TIMER_INITIALIZER(NULL, 0, 0), \ - } - -#define __DELAYED_WORK_INITIALIZER_NAR(n, f) { \ - .work = __WORK_INITIALIZER_NAR((n).work, (f)), \ + .data = (d), \ .timer = TIMER_INITIALIZER(NULL, 0, 0), \ } -#define DECLARE_WORK(n, f) \ - struct work_struct n = __WORK_INITIALIZER(n, f) - -#define DECLARE_WORK_NAR(n, f) \ - struct work_struct n = __WORK_INITIALIZER_NAR(n, f) - -#define DECLARE_DELAYED_WORK(n, f) \ - struct delayed_work n = __DELAYED_WORK_INITIALIZER(n, f) - -#define DECLARE_DELAYED_WORK_NAR(n, f) \ - struct dwork_struct n = __DELAYED_WORK_INITIALIZER_NAR(n, f) +#define DECLARE_WORK(n, f, d) \ + struct work_struct n = __WORK_INITIALIZER(n, f, d) /* - * initialize a work item's function pointer + * initialize a work-struct's func and data pointers: */ -#define PREPARE_WORK(_work, _func) \ +#define PREPARE_WORK(_work, _func, _data) \ do { \ - (_work)->func = (_func); \ + (_work)->func = _func; \ + (_work)->data = _data; \ } while (0) -#define PREPARE_DELAYED_WORK(_work, _func) \ - PREPARE_WORK(&(_work)->work, (_func)) - /* - * initialize all of a work item in one go + * initialize all of a work-struct: */ -#define INIT_WORK(_work, _func) \ +#define INIT_WORK(_work, _func, _data) \ do { \ - (_work)->management = 0; \ INIT_LIST_HEAD(&(_work)->entry); \ - PREPARE_WORK((_work), (_func)); \ - } while (0) - -#define INIT_WORK_NAR(_work, _func) \ - do { \ - (_work)->management = (1 << WORK_STRUCT_NOAUTOREL); \ - INIT_LIST_HEAD(&(_work)->entry); \ - PREPARE_WORK((_work), (_func)); \ - } while (0) - -#define INIT_DELAYED_WORK(_work, _func) \ - do { \ - INIT_WORK(&(_work)->work, (_func)); \ - init_timer(&(_work)->timer); \ - } while (0) - -#define INIT_DELAYED_WORK_NAR(_work, _func) \ - do { \ - INIT_WORK_NAR(&(_work)->work, (_func)); \ + (_work)->pending = 0; \ + PREPARE_WORK((_work), (_func), (_data)); \ init_timer(&(_work)->timer); \ } while (0) -/** - * work_pending - Find out whether a work item is currently pending - * @work: The work item in question - */ -#define work_pending(work) \ - test_bit(WORK_STRUCT_PENDING, &(work)->management) - -/** - * delayed_work_pending - Find out whether a delayable work item is currently - * pending - * @work: The work item in question - */ -#define delayed_work_pending(work) \ - test_bit(WORK_STRUCT_PENDING, &(work)->work.management) - -/** - * work_release - Release a work item under execution - * @work: The work item to release - * - * This is used to release a work item that has been initialised with automatic - * release mode disabled (WORK_STRUCT_NOAUTOREL is set). This gives the work - * function the opportunity to grab auxiliary data from the container of the - * work_struct before clearing the pending bit as the work_struct may be - * subject to deallocation the moment the pending bit is cleared. - * - * In such a case, this should be called in the work function after it has - * fetched any data it may require from the containter of the work_struct. - * After this function has been called, the work_struct may be scheduled for - * further execution or it may be deallocated unless other precautions are - * taken. - * - * This should also be used to release a delayed work item. - */ -#define work_release(work) \ - clear_bit(WORK_STRUCT_PENDING, &(work)->management) - - extern struct workqueue_struct *__create_workqueue(const char *name, int singlethread); #define create_workqueue(name) __create_workqueue((name), 0) @@ -154,38 +62,39 @@ extern struct workqueue_struct *__create_workqueue(const char *name, extern void destroy_workqueue(struct workqueue_struct *wq); extern int FASTCALL(queue_work(struct workqueue_struct *wq, struct work_struct *work)); -extern int FASTCALL(queue_delayed_work(struct workqueue_struct *wq, struct delayed_work *work, unsigned long delay)); +extern int FASTCALL(queue_delayed_work(struct workqueue_struct *wq, struct work_struct *work, unsigned long delay)); extern int queue_delayed_work_on(int cpu, struct workqueue_struct *wq, - struct delayed_work *work, unsigned long delay); + struct work_struct *work, unsigned long delay); extern void FASTCALL(flush_workqueue(struct workqueue_struct *wq)); extern int FASTCALL(schedule_work(struct work_struct *work)); -extern int FASTCALL(schedule_delayed_work(struct delayed_work *work, unsigned long delay)); +extern int FASTCALL(schedule_delayed_work(struct work_struct *work, unsigned long delay)); -extern int schedule_delayed_work_on(int cpu, struct delayed_work *work, unsigned long delay); -extern int schedule_on_each_cpu(work_func_t func); +extern int schedule_delayed_work_on(int cpu, struct work_struct *work, unsigned long delay); +extern int schedule_on_each_cpu(void (*func)(void *info), void *info); extern void flush_scheduled_work(void); extern int current_is_keventd(void); extern int keventd_up(void); extern void init_workqueues(void); -void cancel_rearming_delayed_work(struct delayed_work *work); +void cancel_rearming_delayed_work(struct work_struct *work); void cancel_rearming_delayed_workqueue(struct workqueue_struct *, - struct delayed_work *); -int execute_in_process_context(work_func_t fn, struct execute_work *); + struct work_struct *); +int execute_in_process_context(void (*fn)(void *), void *, + struct execute_work *); /* * Kill off a pending schedule_delayed_work(). Note that the work callback * function may still be running on return from cancel_delayed_work(). Run * flush_scheduled_work() to wait on it. */ -static inline int cancel_delayed_work(struct delayed_work *work) +static inline int cancel_delayed_work(struct work_struct *work) { int ret; ret = del_timer_sync(&work->timer); if (ret) - clear_bit(WORK_STRUCT_PENDING, &work->work.management); + clear_bit(0, &work->pending); return ret; } diff --git a/trunk/include/net/ieee80211softmac.h b/trunk/include/net/ieee80211softmac.h index 89119277553d..617b672b1132 100644 --- a/trunk/include/net/ieee80211softmac.h +++ b/trunk/include/net/ieee80211softmac.h @@ -108,8 +108,8 @@ struct ieee80211softmac_assoc_info { /* Scan retries remaining */ int scan_retry; - struct delayed_work work; - struct delayed_work timeout; + struct work_struct work; + struct work_struct timeout; }; struct ieee80211softmac_bss_info { diff --git a/trunk/include/net/inet_timewait_sock.h b/trunk/include/net/inet_timewait_sock.h index f7be1ac73601..5f48748fe017 100644 --- a/trunk/include/net/inet_timewait_sock.h +++ b/trunk/include/net/inet_timewait_sock.h @@ -84,7 +84,7 @@ struct inet_timewait_death_row { }; extern void inet_twdr_hangman(unsigned long data); -extern void inet_twdr_twkill_work(struct work_struct *work); +extern void inet_twdr_twkill_work(void *data); extern void inet_twdr_twcal_tick(unsigned long data); #if (BITS_PER_LONG == 64) diff --git a/trunk/include/net/sctp/structs.h b/trunk/include/net/sctp/structs.h index c089f93ba591..f8cbe40f52c0 100644 --- a/trunk/include/net/sctp/structs.h +++ b/trunk/include/net/sctp/structs.h @@ -1030,7 +1030,7 @@ void sctp_inq_init(struct sctp_inq *); void sctp_inq_free(struct sctp_inq *); void sctp_inq_push(struct sctp_inq *, struct sctp_chunk *packet); struct sctp_chunk *sctp_inq_pop(struct sctp_inq *); -void sctp_inq_set_th_handler(struct sctp_inq *, work_func_t); +void sctp_inq_set_th_handler(struct sctp_inq *, void (*)(void *), void *); /* This is the structure we use to hold outbound chunks. You push * chunks in and they automatically pop out the other end as bundled diff --git a/trunk/include/pcmcia/ss.h b/trunk/include/pcmcia/ss.h index 623a0fc0dae1..ede639812f8a 100644 --- a/trunk/include/pcmcia/ss.h +++ b/trunk/include/pcmcia/ss.h @@ -262,10 +262,9 @@ struct pcmcia_socket { u8 present:1, /* PCMCIA card is present in socket */ busy:1, /* "master" ioctl is used */ dead:1, /* pcmcia module is being unloaded */ - device_add_pending:1, /* a multifunction-device + device_add_pending:1, /* a pseudo-multifunction-device * add event is pending */ - mfc_pfc:1, /* the pending event adds a mfc (1) or pfc (0) */ - reserved:3; + reserved:4; } pcmcia_state; struct work_struct device_add; /* for adding further pseudo-multifunction diff --git a/trunk/include/scsi/libsas.h b/trunk/include/scsi/libsas.h index 9233ed5de664..1d77b63c5ea4 100644 --- a/trunk/include/scsi/libsas.h +++ b/trunk/include/scsi/libsas.h @@ -201,14 +201,9 @@ struct domain_device { void *lldd_dev; }; -struct sas_discovery_event { - struct work_struct work; - struct asd_sas_port *port; -}; - struct sas_discovery { spinlock_t disc_event_lock; - struct sas_discovery_event disc_work[DISC_NUM_EVENTS]; + struct work_struct disc_work[DISC_NUM_EVENTS]; unsigned long pending; u8 fanout_sas_addr[8]; u8 eeds_a[8]; @@ -254,19 +249,14 @@ struct asd_sas_port { void *lldd_port; /* not touched by the sas class code */ }; -struct asd_sas_event { - struct work_struct work; - struct asd_sas_phy *phy; -}; - /* The phy pretty much is controlled by the LLDD. * The class only reads those fields. */ struct asd_sas_phy { /* private: */ /* protected by ha->event_lock */ - struct asd_sas_event port_events[PORT_NUM_EVENTS]; - struct asd_sas_event phy_events[PHY_NUM_EVENTS]; + struct work_struct port_events[PORT_NUM_EVENTS]; + struct work_struct phy_events[PHY_NUM_EVENTS]; unsigned long port_events_pending; unsigned long phy_events_pending; @@ -318,15 +308,10 @@ struct scsi_core { int queue_thread_kill; }; -struct sas_ha_event { - struct work_struct work; - struct sas_ha_struct *ha; -}; - struct sas_ha_struct { /* private: */ spinlock_t event_lock; - struct sas_ha_event ha_events[HA_NUM_EVENTS]; + struct work_struct ha_events[HA_NUM_EVENTS]; unsigned long pending; struct scsi_core core; @@ -354,8 +339,6 @@ struct sas_ha_struct { void (*notify_phy_event)(struct asd_sas_phy *, enum phy_event); void *lldd_ha; /* not touched by sas class code */ - - struct list_head eh_done_q; }; #define SHOST_TO_SAS_HA(_shost) (*(struct sas_ha_struct **)(_shost)->hostdata) @@ -544,16 +527,13 @@ struct sas_task { void *lldd_task; /* for use by LLDDs */ void *uldd_task; - - struct work_struct abort_work; }; -#define SAS_TASK_STATE_PENDING 1 -#define SAS_TASK_STATE_DONE 2 -#define SAS_TASK_STATE_ABORTED 4 -#define SAS_TASK_INITIATOR_ABORTED 8 +#define SAS_TASK_STATE_PENDING 1 +#define SAS_TASK_STATE_DONE 2 +#define SAS_TASK_STATE_ABORTED 4 static inline struct sas_task *sas_alloc_task(gfp_t flags) { @@ -613,7 +593,6 @@ struct sas_domain_function_template { extern int sas_register_ha(struct sas_ha_struct *); extern int sas_unregister_ha(struct sas_ha_struct *); -int sas_phy_reset(struct sas_phy *phy, int hard_reset); extern int sas_queuecommand(struct scsi_cmnd *, void (*scsi_done)(struct scsi_cmnd *)); extern int sas_target_alloc(struct scsi_target *); @@ -646,6 +625,4 @@ void sas_unregister_dev(struct domain_device *); void sas_init_dev(struct domain_device *); -void sas_task_abort(struct work_struct *); - #endif /* _SASLIB_H_ */ diff --git a/trunk/include/scsi/libsrp.h b/trunk/include/scsi/libsrp.h deleted file mode 100644 index d143171896ae..000000000000 --- a/trunk/include/scsi/libsrp.h +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef __LIBSRP_H__ -#define __LIBSRP_H__ - -#include -#include -#include -#include - -enum iue_flags { - V_DIOVER, - V_WRITE, - V_LINKED, - V_FLYING, -}; - -struct srp_buf { - dma_addr_t dma; - void *buf; -}; - -struct srp_queue { - void *pool; - void *items; - struct kfifo *queue; - spinlock_t lock; -}; - -struct srp_target { - struct Scsi_Host *shost; - struct device *dev; - - spinlock_t lock; - struct list_head cmd_queue; - - size_t srp_iu_size; - struct srp_queue iu_queue; - size_t rx_ring_size; - struct srp_buf **rx_ring; - - void *ldata; -}; - -struct iu_entry { - struct srp_target *target; - - struct list_head ilist; - dma_addr_t remote_token; - unsigned long flags; - - struct srp_buf *sbuf; -}; - -typedef int (srp_rdma_t)(struct scsi_cmnd *, struct scatterlist *, int, - struct srp_direct_buf *, int, - enum dma_data_direction, unsigned int); -extern int srp_target_alloc(struct srp_target *, struct device *, size_t, size_t); -extern void srp_target_free(struct srp_target *); - -extern struct iu_entry *srp_iu_get(struct srp_target *); -extern void srp_iu_put(struct iu_entry *); - -extern int srp_cmd_queue(struct Scsi_Host *, struct srp_cmd *, void *, u64); -extern int srp_transfer_data(struct scsi_cmnd *, struct srp_cmd *, - srp_rdma_t, int, int); - - -static inline struct srp_target *host_to_srp_target(struct Scsi_Host *host) -{ - return (struct srp_target *) host->hostdata; -} - -static inline int srp_cmd_direction(struct srp_cmd *cmd) -{ - return (cmd->buf_fmt >> 4) ? DMA_TO_DEVICE : DMA_FROM_DEVICE; -} - -#endif diff --git a/trunk/include/scsi/scsi_cmnd.h b/trunk/include/scsi/scsi_cmnd.h index d6948d0e8cdb..be117f812deb 100644 --- a/trunk/include/scsi/scsi_cmnd.h +++ b/trunk/include/scsi/scsi_cmnd.h @@ -8,7 +8,6 @@ struct request; struct scatterlist; -struct Scsi_Host; struct scsi_device; @@ -73,9 +72,6 @@ struct scsi_cmnd { unsigned short use_sg; /* Number of pieces of scatter-gather */ unsigned short sglist_len; /* size of malloc'd scatter-gather list */ - /* offset in cmd we are at (for multi-transfer tgt cmds) */ - unsigned offset; - unsigned underflow; /* Return error if less than this amount is transferred */ @@ -123,10 +119,7 @@ struct scsi_cmnd { }; extern struct scsi_cmnd *scsi_get_command(struct scsi_device *, gfp_t); -extern struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *, gfp_t); extern void scsi_put_command(struct scsi_cmnd *); -extern void __scsi_put_command(struct Scsi_Host *, struct scsi_cmnd *, - struct device *); extern void scsi_io_completion(struct scsi_cmnd *, unsigned int); extern void scsi_finish_command(struct scsi_cmnd *cmd); extern void scsi_req_abort_cmd(struct scsi_cmnd *cmd); @@ -135,7 +128,4 @@ extern void *scsi_kmap_atomic_sg(struct scatterlist *sg, int sg_count, size_t *offset, size_t *len); extern void scsi_kunmap_atomic_sg(void *virt); -extern struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *, gfp_t); -extern void scsi_free_sgtable(struct scatterlist *, int); - #endif /* _SCSI_SCSI_CMND_H */ diff --git a/trunk/include/scsi/scsi_device.h b/trunk/include/scsi/scsi_device.h index ebf31b16dc49..b401c82036be 100644 --- a/trunk/include/scsi/scsi_device.h +++ b/trunk/include/scsi/scsi_device.h @@ -223,13 +223,13 @@ extern struct scsi_device *__scsi_iterate_devices(struct Scsi_Host *, struct scsi_device *); /** - * shost_for_each_device - iterate over all devices of a host - * @sdev: the &struct scsi_device to use as a cursor - * @shost: the &struct scsi_host to iterate over + * shost_for_each_device - iterate over all devices of a host + * @sdev: iterator + * @host: host whiches devices we want to iterate over * - * Iterator that returns each device attached to @shost. This loop - * takes a reference on each device and releases it at the end. If - * you break out of the loop, you must call scsi_device_put(sdev). + * This traverses over each devices of @shost. The devices have + * a reference that must be released by scsi_host_put when breaking + * out of the loop. */ #define shost_for_each_device(sdev, shost) \ for ((sdev) = __scsi_iterate_devices((shost), NULL); \ @@ -237,17 +237,17 @@ extern struct scsi_device *__scsi_iterate_devices(struct Scsi_Host *, (sdev) = __scsi_iterate_devices((shost), (sdev))) /** - * __shost_for_each_device - iterate over all devices of a host (UNLOCKED) - * @sdev: the &struct scsi_device to use as a cursor - * @shost: the &struct scsi_host to iterate over + * __shost_for_each_device - iterate over all devices of a host (UNLOCKED) + * @sdev: iterator + * @host: host whiches devices we want to iterate over * - * Iterator that returns each device attached to @shost. It does _not_ - * take a reference on the scsi_device, so the whole loop must be - * protected by shost->host_lock. + * This traverses over each devices of @shost. It does _not_ take a + * reference on the scsi_device, thus it the whole loop must be protected + * by shost->host_lock. * - * Note: The only reason to use this is because you need to access the - * device list in interrupt context. Otherwise you really want to use - * shost_for_each_device instead. + * Note: The only reason why drivers would want to use this is because + * they're need to access the device list in irq context. Otherwise you + * really want to use shost_for_each_device instead. */ #define __shost_for_each_device(sdev, shost) \ list_for_each_entry((sdev), &((shost)->__devices), siblings) diff --git a/trunk/include/scsi/scsi_host.h b/trunk/include/scsi/scsi_host.h index 7f1f411d07af..39c6f8cc20c3 100644 --- a/trunk/include/scsi/scsi_host.h +++ b/trunk/include/scsi/scsi_host.h @@ -7,7 +7,6 @@ #include #include -struct request_queue; struct block_device; struct completion; struct module; @@ -124,39 +123,6 @@ struct scsi_host_template { int (* queuecommand)(struct scsi_cmnd *, void (*done)(struct scsi_cmnd *)); - /* - * The transfer functions are used to queue a scsi command to - * the LLD. When the driver is finished processing the command - * the done callback is invoked. - * - * return values: see queuecommand - * - * If the LLD accepts the cmd, it should set the result to an - * appropriate value when completed before calling the done function. - * - * STATUS: REQUIRED FOR TARGET DRIVERS - */ - /* TODO: rename */ - int (* transfer_response)(struct scsi_cmnd *, - void (*done)(struct scsi_cmnd *)); - /* - * This is called to inform the LLD to transfer cmd->request_bufflen - * bytes of the cmd at cmd->offset in the cmd. The cmd->use_sg - * speciefies the number of scatterlist entried in the command - * and cmd->request_buffer contains the scatterlist. - * - * If the command cannot be processed in one transfer_data call - * becuase a scatterlist within the LLD's limits cannot be - * created then transfer_data will be called multiple times. - * It is initially called from process context, and later - * calls are from the interrup context. - */ - int (* transfer_data)(struct scsi_cmnd *, - void (*done)(struct scsi_cmnd *)); - - /* Used as callback for the completion of task management request. */ - int (* tsk_mgmt_response)(u64 mid, int result); - /* * This is an error handling strategy routine. You don't need to * define one of these if you don't want to - there is a default @@ -274,24 +240,6 @@ struct scsi_host_template { */ void (* target_destroy)(struct scsi_target *); - /* - * If a host has the ability to discover targets on its own instead - * of scanning the entire bus, it can fill in this function and - * call scsi_scan_host(). This function will be called periodically - * until it returns 1 with the scsi_host and the elapsed time of - * the scan in jiffies. - * - * Status: OPTIONAL - */ - int (* scan_finished)(struct Scsi_Host *, unsigned long); - - /* - * If the host wants to be called before the scan starts, but - * after the midlayer has set up ready for the scan, it can fill - * in this function. - */ - void (* scan_start)(struct Scsi_Host *); - /* * fill in this function to allow the queue depth of this host * to be changeable (on a per device basis). returns either @@ -604,9 +552,6 @@ struct Scsi_Host { /* task mgmt function in progress */ unsigned tmf_in_progress:1; - /* Asynchronous scan in progress */ - unsigned async_scan:1; - /* * Optional work queue to be utilized by the transport */ @@ -623,12 +568,6 @@ struct Scsi_Host { */ unsigned int max_host_blocked; - /* - * q used for scsi_tgt msgs, async events or any other requests that - * need to be processed in userspace - */ - struct request_queue *uspace_req_q; - /* legacy crap */ unsigned long base; unsigned long io_port; @@ -709,6 +648,11 @@ extern const char *scsi_host_state_name(enum scsi_host_state); extern u64 scsi_calculate_bounce_limit(struct Scsi_Host *); +static inline void scsi_assign_lock(struct Scsi_Host *shost, spinlock_t *lock) +{ + shost->host_lock = lock; +} + static inline struct device *scsi_get_device(struct Scsi_Host *shost) { return shost->shost_gendev.parent; @@ -727,9 +671,6 @@ extern void scsi_unblock_requests(struct Scsi_Host *); extern void scsi_block_requests(struct Scsi_Host *); struct class_container; - -extern struct request_queue *__scsi_alloc_queue(struct Scsi_Host *shost, - void (*) (struct request_queue *)); /* * These two functions are used to allocate and free a pseudo device * which will connect to the host adapter itself rather than any diff --git a/trunk/include/scsi/scsi_tgt.h b/trunk/include/scsi/scsi_tgt.h deleted file mode 100644 index 4f4427937af2..000000000000 --- a/trunk/include/scsi/scsi_tgt.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * SCSI target definitions - */ - -#include - -struct Scsi_Host; -struct scsi_cmnd; -struct scsi_lun; - -extern struct Scsi_Host *scsi_tgt_cmd_to_host(struct scsi_cmnd *); -extern int scsi_tgt_alloc_queue(struct Scsi_Host *); -extern void scsi_tgt_free_queue(struct Scsi_Host *); -extern int scsi_tgt_queue_command(struct scsi_cmnd *, struct scsi_lun *, u64); -extern int scsi_tgt_tsk_mgmt_request(struct Scsi_Host *, int, u64, struct scsi_lun *, - void *); -extern struct scsi_cmnd *scsi_host_get_command(struct Scsi_Host *, - enum dma_data_direction, gfp_t); -extern void scsi_host_put_command(struct Scsi_Host *, struct scsi_cmnd *); diff --git a/trunk/include/scsi/scsi_tgt_if.h b/trunk/include/scsi/scsi_tgt_if.h deleted file mode 100644 index 46d5e70d7215..000000000000 --- a/trunk/include/scsi/scsi_tgt_if.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * SCSI target kernel/user interface - * - * Copyright (C) 2005 FUJITA Tomonori - * Copyright (C) 2005 Mike Christie - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#ifndef __SCSI_TARGET_IF_H -#define __SCSI_TARGET_IF_H - -/* user -> kernel */ -#define TGT_UEVENT_CMD_RSP 0x0001 -#define TGT_UEVENT_TSK_MGMT_RSP 0x0002 - -/* kernel -> user */ -#define TGT_KEVENT_CMD_REQ 0x1001 -#define TGT_KEVENT_CMD_DONE 0x1002 -#define TGT_KEVENT_TSK_MGMT_REQ 0x1003 - -struct tgt_event_hdr { - uint16_t version; - uint16_t status; - uint16_t type; - uint16_t len; -} __attribute__ ((aligned (sizeof(uint64_t)))); - -struct tgt_event { - struct tgt_event_hdr hdr; - - union { - /* user-> kernel */ - struct { - int host_no; - uint32_t len; - int result; - aligned_u64 uaddr; - uint8_t rw; - aligned_u64 tag; - } cmd_rsp; - struct { - int host_no; - aligned_u64 mid; - int result; - } tsk_mgmt_rsp; - - - /* kernel -> user */ - struct { - int host_no; - uint32_t data_len; - uint8_t scb[16]; - uint8_t lun[8]; - int attribute; - aligned_u64 tag; - } cmd_req; - struct { - int host_no; - aligned_u64 tag; - int result; - } cmd_done; - struct { - int host_no; - int function; - aligned_u64 tag; - uint8_t lun[8]; - aligned_u64 mid; - } tsk_mgmt_req; - } p; -} __attribute__ ((aligned (sizeof(uint64_t)))); - -#define TGT_RING_SIZE (1UL << 16) -#define TGT_RING_PAGES (TGT_RING_SIZE >> PAGE_SHIFT) -#define TGT_EVENT_PER_PAGE (PAGE_SIZE / sizeof(struct tgt_event)) -#define TGT_MAX_EVENTS (TGT_EVENT_PER_PAGE * TGT_RING_PAGES) - -#endif diff --git a/trunk/include/scsi/scsi_transport_fc.h b/trunk/include/scsi/scsi_transport_fc.h index 798f7c7ee426..fd352323378b 100644 --- a/trunk/include/scsi/scsi_transport_fc.h +++ b/trunk/include/scsi/scsi_transport_fc.h @@ -206,9 +206,9 @@ struct fc_rport { /* aka fc_starget_attrs */ u8 flags; struct list_head peers; struct device dev; - struct delayed_work dev_loss_work; + struct work_struct dev_loss_work; struct work_struct scan_work; - struct delayed_work fail_io_work; + struct work_struct fail_io_work; struct work_struct stgt_delete_work; struct work_struct rport_delete_work; } __attribute__((aligned(sizeof(unsigned long)))); diff --git a/trunk/include/scsi/scsi_transport_iscsi.h b/trunk/include/scsi/scsi_transport_iscsi.h index d5c218ddc527..4b95c89c95c9 100644 --- a/trunk/include/scsi/scsi_transport_iscsi.h +++ b/trunk/include/scsi/scsi_transport_iscsi.h @@ -176,7 +176,7 @@ struct iscsi_cls_session { /* recovery fields */ int recovery_tmo; - struct delayed_work recovery_work; + struct work_struct recovery_work; int target_id; diff --git a/trunk/include/scsi/scsi_transport_sas.h b/trunk/include/scsi/scsi_transport_sas.h index 59633a82de47..53024377f3b8 100644 --- a/trunk/include/scsi/scsi_transport_sas.h +++ b/trunk/include/scsi/scsi_transport_sas.h @@ -73,8 +73,6 @@ struct sas_phy { /* for the list of phys belonging to a port */ struct list_head port_siblings; - - struct work_struct reset_work; }; #define dev_to_phy(d) \ diff --git a/trunk/include/sound/ac97_codec.h b/trunk/include/sound/ac97_codec.h index 33720397a904..4c43521cc493 100644 --- a/trunk/include/sound/ac97_codec.h +++ b/trunk/include/sound/ac97_codec.h @@ -511,7 +511,7 @@ struct snd_ac97 { #ifdef CONFIG_SND_AC97_POWER_SAVE unsigned int power_up; /* power states */ struct workqueue_struct *power_workq; - struct delayed_work power_work; + struct work_struct power_work; #endif struct device dev; }; diff --git a/trunk/include/sound/ak4114.h b/trunk/include/sound/ak4114.h index 2ee061625fd0..11702aa0bea9 100644 --- a/trunk/include/sound/ak4114.h +++ b/trunk/include/sound/ak4114.h @@ -182,7 +182,7 @@ struct ak4114 { unsigned char rcs0; unsigned char rcs1; struct workqueue_struct *workqueue; - struct delayed_work work; + struct work_struct work; void *change_callback_private; void (*change_callback)(struct ak4114 *ak4114, unsigned char c0, unsigned char c1); }; diff --git a/trunk/ipc/util.c b/trunk/ipc/util.c index a9b7a227b8d4..cd8bb14a431f 100644 --- a/trunk/ipc/util.c +++ b/trunk/ipc/util.c @@ -514,11 +514,6 @@ void ipc_rcu_getref(void *ptr) container_of(ptr, struct ipc_rcu_hdr, data)->refcount++; } -static void ipc_do_vfree(struct work_struct *work) -{ - vfree(container_of(work, struct ipc_rcu_sched, work)); -} - /** * ipc_schedule_free - free ipc + rcu space * @head: RCU callback structure for queued work @@ -533,7 +528,7 @@ static void ipc_schedule_free(struct rcu_head *head) struct ipc_rcu_sched *sched = container_of(&(grace->data[0]), struct ipc_rcu_sched, data[0]); - INIT_WORK(&sched->work, ipc_do_vfree); + INIT_WORK(&sched->work, vfree, sched); schedule_work(&sched->work); } diff --git a/trunk/kernel/kmod.c b/trunk/kernel/kmod.c index 8d2bea09a4ec..2b76dee28496 100644 --- a/trunk/kernel/kmod.c +++ b/trunk/kernel/kmod.c @@ -114,7 +114,6 @@ EXPORT_SYMBOL(request_module); #endif /* CONFIG_KMOD */ struct subprocess_info { - struct work_struct work; struct completion *complete; char *path; char **argv; @@ -222,10 +221,9 @@ static int wait_for_helper(void *data) } /* This is run by khelper thread */ -static void __call_usermodehelper(struct work_struct *work) +static void __call_usermodehelper(void *data) { - struct subprocess_info *sub_info = - container_of(work, struct subprocess_info, work); + struct subprocess_info *sub_info = data; pid_t pid; int wait = sub_info->wait; @@ -266,8 +264,6 @@ int call_usermodehelper_keys(char *path, char **argv, char **envp, { DECLARE_COMPLETION_ONSTACK(done); struct subprocess_info sub_info = { - .work = __WORK_INITIALIZER(sub_info.work, - __call_usermodehelper), .complete = &done, .path = path, .argv = argv, @@ -276,6 +272,7 @@ int call_usermodehelper_keys(char *path, char **argv, char **envp, .wait = wait, .retval = 0, }; + DECLARE_WORK(work, __call_usermodehelper, &sub_info); if (!khelper_wq) return -EBUSY; @@ -283,7 +280,7 @@ int call_usermodehelper_keys(char *path, char **argv, char **envp, if (path[0] == '\0') return 0; - queue_work(khelper_wq, &sub_info.work); + queue_work(khelper_wq, &work); wait_for_completion(&done); return sub_info.retval; } @@ -294,8 +291,6 @@ int call_usermodehelper_pipe(char *path, char **argv, char **envp, { DECLARE_COMPLETION(done); struct subprocess_info sub_info = { - .work = __WORK_INITIALIZER(sub_info.work, - __call_usermodehelper), .complete = &done, .path = path, .argv = argv, @@ -303,6 +298,7 @@ int call_usermodehelper_pipe(char *path, char **argv, char **envp, .retval = 0, }; struct file *f; + DECLARE_WORK(work, __call_usermodehelper, &sub_info); if (!khelper_wq) return -EBUSY; @@ -322,7 +318,7 @@ int call_usermodehelper_pipe(char *path, char **argv, char **envp, } sub_info.stdin = f; - queue_work(khelper_wq, &sub_info.work); + queue_work(khelper_wq, &work); wait_for_completion(&done); return sub_info.retval; } diff --git a/trunk/kernel/kthread.c b/trunk/kernel/kthread.c index 1db8c72d0d38..4f9c60ef95e8 100644 --- a/trunk/kernel/kthread.c +++ b/trunk/kernel/kthread.c @@ -31,8 +31,6 @@ struct kthread_create_info /* Result passed back to kthread_create() from keventd. */ struct task_struct *result; struct completion done; - - struct work_struct work; }; struct kthread_stop_info @@ -113,10 +111,9 @@ static int kthread(void *_create) } /* We are keventd: create a thread. */ -static void keventd_create_kthread(struct work_struct *work) +static void keventd_create_kthread(void *_create) { - struct kthread_create_info *create = - container_of(work, struct kthread_create_info, work); + struct kthread_create_info *create = _create; int pid; /* We want our own signal handler (we take no signals by default). */ @@ -157,20 +154,20 @@ struct task_struct *kthread_create(int (*threadfn)(void *data), ...) { struct kthread_create_info create; + DECLARE_WORK(work, keventd_create_kthread, &create); create.threadfn = threadfn; create.data = data; init_completion(&create.started); init_completion(&create.done); - INIT_WORK(&create.work, keventd_create_kthread); /* * The workqueue needs to start up first: */ if (!helper_wq) - create.work.func(&create.work); + work.func(work.data); else { - queue_work(helper_wq, &create.work); + queue_work(helper_wq, &work); wait_for_completion(&create.done); } if (!IS_ERR(create.result)) { diff --git a/trunk/kernel/power/poweroff.c b/trunk/kernel/power/poweroff.c index 678ec736076b..f1f900ac3164 100644 --- a/trunk/kernel/power/poweroff.c +++ b/trunk/kernel/power/poweroff.c @@ -16,12 +16,12 @@ * callback we use. */ -static void do_poweroff(struct work_struct *dummy) +static void do_poweroff(void *dummy) { kernel_power_off(); } -static DECLARE_WORK(poweroff_work, do_poweroff); +static DECLARE_WORK(poweroff_work, do_poweroff, NULL); static void handle_poweroff(int key, struct tty_struct *tty) { diff --git a/trunk/kernel/relay.c b/trunk/kernel/relay.c index 2b92e8ece85b..f04bbdb56ac2 100644 --- a/trunk/kernel/relay.c +++ b/trunk/kernel/relay.c @@ -308,10 +308,9 @@ static struct rchan_callbacks default_channel_callbacks = { * reason waking is deferred is that calling directly from write * causes problems if you're writing from say the scheduler. */ -static void wakeup_readers(struct work_struct *work) +static void wakeup_readers(void *private) { - struct rchan_buf *buf = - container_of(work, struct rchan_buf, wake_readers.work); + struct rchan_buf *buf = private; wake_up_interruptible(&buf->read_wait); } @@ -329,7 +328,7 @@ static inline void __relay_reset(struct rchan_buf *buf, unsigned int init) if (init) { init_waitqueue_head(&buf->read_wait); kref_init(&buf->kref); - INIT_DELAYED_WORK(&buf->wake_readers, NULL); + INIT_WORK(&buf->wake_readers, NULL, NULL); } else { cancel_delayed_work(&buf->wake_readers); flush_scheduled_work(); @@ -550,8 +549,7 @@ size_t relay_switch_subbuf(struct rchan_buf *buf, size_t length) buf->padding[old_subbuf]; smp_mb(); if (waitqueue_active(&buf->read_wait)) { - PREPARE_DELAYED_WORK(&buf->wake_readers, - wakeup_readers); + PREPARE_WORK(&buf->wake_readers, wakeup_readers, buf); schedule_delayed_work(&buf->wake_readers, 1); } } diff --git a/trunk/kernel/sys.c b/trunk/kernel/sys.c index c87b461de38d..98489d82801b 100644 --- a/trunk/kernel/sys.c +++ b/trunk/kernel/sys.c @@ -880,7 +880,7 @@ asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user return 0; } -static void deferred_cad(struct work_struct *dummy) +static void deferred_cad(void *dummy) { kernel_restart(NULL); } @@ -892,7 +892,7 @@ static void deferred_cad(struct work_struct *dummy) */ void ctrl_alt_del(void) { - static DECLARE_WORK(cad_work, deferred_cad); + static DECLARE_WORK(cad_work, deferred_cad, NULL); if (C_A_D) schedule_work(&cad_work); diff --git a/trunk/kernel/workqueue.c b/trunk/kernel/workqueue.c index 8d1e7cb8a51a..17c2f03d2c27 100644 --- a/trunk/kernel/workqueue.c +++ b/trunk/kernel/workqueue.c @@ -80,29 +80,6 @@ static inline int is_single_threaded(struct workqueue_struct *wq) return list_empty(&wq->list); } -static inline void set_wq_data(struct work_struct *work, void *wq) -{ - unsigned long new, old, res; - - /* assume the pending flag is already set and that the task has already - * been queued on this workqueue */ - new = (unsigned long) wq | (1UL << WORK_STRUCT_PENDING); - res = work->management; - if (res != new) { - do { - old = res; - new = (unsigned long) wq; - new |= (old & WORK_STRUCT_FLAG_MASK); - res = cmpxchg(&work->management, old, new); - } while (res != old); - } -} - -static inline void *get_wq_data(struct work_struct *work) -{ - return (void *) (work->management & WORK_STRUCT_WQ_DATA_MASK); -} - /* Preempt must be disabled. */ static void __queue_work(struct cpu_workqueue_struct *cwq, struct work_struct *work) @@ -110,7 +87,7 @@ static void __queue_work(struct cpu_workqueue_struct *cwq, unsigned long flags; spin_lock_irqsave(&cwq->lock, flags); - set_wq_data(work, cwq); + work->wq_data = cwq; list_add_tail(&work->entry, &cwq->worklist); cwq->insert_sequence++; wake_up(&cwq->more_work); @@ -131,7 +108,7 @@ int fastcall queue_work(struct workqueue_struct *wq, struct work_struct *work) { int ret = 0, cpu = get_cpu(); - if (!test_and_set_bit(WORK_STRUCT_PENDING, &work->management)) { + if (!test_and_set_bit(0, &work->pending)) { if (unlikely(is_single_threaded(wq))) cpu = singlethread_cpu; BUG_ON(!list_empty(&work->entry)); @@ -145,42 +122,38 @@ EXPORT_SYMBOL_GPL(queue_work); static void delayed_work_timer_fn(unsigned long __data) { - struct delayed_work *dwork = (struct delayed_work *)__data; - struct workqueue_struct *wq = get_wq_data(&dwork->work); + struct work_struct *work = (struct work_struct *)__data; + struct workqueue_struct *wq = work->wq_data; int cpu = smp_processor_id(); if (unlikely(is_single_threaded(wq))) cpu = singlethread_cpu; - __queue_work(per_cpu_ptr(wq->cpu_wq, cpu), &dwork->work); + __queue_work(per_cpu_ptr(wq->cpu_wq, cpu), work); } /** * queue_delayed_work - queue work on a workqueue after delay * @wq: workqueue to use - * @work: delayable work to queue + * @work: work to queue * @delay: number of jiffies to wait before queueing * * Returns 0 if @work was already on a queue, non-zero otherwise. */ int fastcall queue_delayed_work(struct workqueue_struct *wq, - struct delayed_work *dwork, unsigned long delay) + struct work_struct *work, unsigned long delay) { int ret = 0; - struct timer_list *timer = &dwork->timer; - struct work_struct *work = &dwork->work; - - if (delay == 0) - return queue_work(wq, work); + struct timer_list *timer = &work->timer; - if (!test_and_set_bit(WORK_STRUCT_PENDING, &work->management)) { + if (!test_and_set_bit(0, &work->pending)) { BUG_ON(timer_pending(timer)); BUG_ON(!list_empty(&work->entry)); /* This stores wq for the moment, for the timer_fn */ - set_wq_data(work, wq); + work->wq_data = wq; timer->expires = jiffies + delay; - timer->data = (unsigned long)dwork; + timer->data = (unsigned long)work; timer->function = delayed_work_timer_fn; add_timer(timer); ret = 1; @@ -199,20 +172,19 @@ EXPORT_SYMBOL_GPL(queue_delayed_work); * Returns 0 if @work was already on a queue, non-zero otherwise. */ int queue_delayed_work_on(int cpu, struct workqueue_struct *wq, - struct delayed_work *dwork, unsigned long delay) + struct work_struct *work, unsigned long delay) { int ret = 0; - struct timer_list *timer = &dwork->timer; - struct work_struct *work = &dwork->work; + struct timer_list *timer = &work->timer; - if (!test_and_set_bit(WORK_STRUCT_PENDING, &work->management)) { + if (!test_and_set_bit(0, &work->pending)) { BUG_ON(timer_pending(timer)); BUG_ON(!list_empty(&work->entry)); /* This stores wq for the moment, for the timer_fn */ - set_wq_data(work, wq); + work->wq_data = wq; timer->expires = jiffies + delay; - timer->data = (unsigned long)dwork; + timer->data = (unsigned long)work; timer->function = delayed_work_timer_fn; add_timer_on(timer, cpu); ret = 1; @@ -240,15 +212,15 @@ static void run_workqueue(struct cpu_workqueue_struct *cwq) while (!list_empty(&cwq->worklist)) { struct work_struct *work = list_entry(cwq->worklist.next, struct work_struct, entry); - work_func_t f = work->func; + void (*f) (void *) = work->func; + void *data = work->data; list_del_init(cwq->worklist.next); spin_unlock_irqrestore(&cwq->lock, flags); - BUG_ON(get_wq_data(work) != cwq); - if (!test_bit(WORK_STRUCT_NOAUTOREL, &work->management)) - work_release(work); - f(work); + BUG_ON(work->wq_data != cwq); + clear_bit(0, &work->pending); + f(data); spin_lock_irqsave(&cwq->lock, flags); cwq->remove_sequence++; @@ -496,37 +468,38 @@ EXPORT_SYMBOL(schedule_work); /** * schedule_delayed_work - put work task in global workqueue after delay - * @dwork: job to be done - * @delay: number of jiffies to wait or 0 for immediate execution + * @work: job to be done + * @delay: number of jiffies to wait * * After waiting for a given time this puts a job in the kernel-global * workqueue. */ -int fastcall schedule_delayed_work(struct delayed_work *dwork, unsigned long delay) +int fastcall schedule_delayed_work(struct work_struct *work, unsigned long delay) { - return queue_delayed_work(keventd_wq, dwork, delay); + return queue_delayed_work(keventd_wq, work, delay); } EXPORT_SYMBOL(schedule_delayed_work); /** * schedule_delayed_work_on - queue work in global workqueue on CPU after delay * @cpu: cpu to use - * @dwork: job to be done + * @work: job to be done * @delay: number of jiffies to wait * * After waiting for a given time this puts a job in the kernel-global * workqueue on the specified CPU. */ int schedule_delayed_work_on(int cpu, - struct delayed_work *dwork, unsigned long delay) + struct work_struct *work, unsigned long delay) { - return queue_delayed_work_on(cpu, keventd_wq, dwork, delay); + return queue_delayed_work_on(cpu, keventd_wq, work, delay); } EXPORT_SYMBOL(schedule_delayed_work_on); /** * schedule_on_each_cpu - call a function on each online CPU from keventd * @func: the function to call + * @info: a pointer to pass to func() * * Returns zero on success. * Returns -ve errno on failure. @@ -535,7 +508,7 @@ EXPORT_SYMBOL(schedule_delayed_work_on); * * schedule_on_each_cpu() is very slow. */ -int schedule_on_each_cpu(work_func_t func) +int schedule_on_each_cpu(void (*func)(void *info), void *info) { int cpu; struct work_struct *works; @@ -546,7 +519,7 @@ int schedule_on_each_cpu(work_func_t func) mutex_lock(&workqueue_mutex); for_each_online_cpu(cpu) { - INIT_WORK(per_cpu_ptr(works, cpu), func); + INIT_WORK(per_cpu_ptr(works, cpu), func, info); __queue_work(per_cpu_ptr(keventd_wq->cpu_wq, cpu), per_cpu_ptr(works, cpu)); } @@ -566,12 +539,12 @@ EXPORT_SYMBOL(flush_scheduled_work); * cancel_rearming_delayed_workqueue - reliably kill off a delayed * work whose handler rearms the delayed work. * @wq: the controlling workqueue structure - * @dwork: the delayed work struct + * @work: the delayed work struct */ void cancel_rearming_delayed_workqueue(struct workqueue_struct *wq, - struct delayed_work *dwork) + struct work_struct *work) { - while (!cancel_delayed_work(dwork)) + while (!cancel_delayed_work(work)) flush_workqueue(wq); } EXPORT_SYMBOL(cancel_rearming_delayed_workqueue); @@ -579,17 +552,18 @@ EXPORT_SYMBOL(cancel_rearming_delayed_workqueue); /** * cancel_rearming_delayed_work - reliably kill off a delayed keventd * work whose handler rearms the delayed work. - * @dwork: the delayed work struct + * @work: the delayed work struct */ -void cancel_rearming_delayed_work(struct delayed_work *dwork) +void cancel_rearming_delayed_work(struct work_struct *work) { - cancel_rearming_delayed_workqueue(keventd_wq, dwork); + cancel_rearming_delayed_workqueue(keventd_wq, work); } EXPORT_SYMBOL(cancel_rearming_delayed_work); /** * execute_in_process_context - reliably execute the routine with user context * @fn: the function to execute + * @data: data to pass to the function * @ew: guaranteed storage for the execute work structure (must * be available when the work executes) * @@ -599,14 +573,15 @@ EXPORT_SYMBOL(cancel_rearming_delayed_work); * Returns: 0 - function was executed * 1 - function was scheduled for execution */ -int execute_in_process_context(work_func_t fn, struct execute_work *ew) +int execute_in_process_context(void (*fn)(void *data), void *data, + struct execute_work *ew) { if (!in_interrupt()) { - fn(&ew->work); + fn(data); return 0; } - INIT_WORK(&ew->work, fn); + INIT_WORK(&ew->work, fn, data); schedule_work(&ew->work); return 1; diff --git a/trunk/mm/nommu.c b/trunk/mm/nommu.c index 6a2a8aada401..8bdde9508f3b 100644 --- a/trunk/mm/nommu.c +++ b/trunk/mm/nommu.c @@ -497,17 +497,15 @@ static int validate_mmap_request(struct file *file, (flags & MAP_TYPE) != MAP_SHARED) return -EINVAL; - if (!len) - return -EINVAL; + if (PAGE_ALIGN(len) == 0) + return addr; - /* Careful about overflows.. */ - len = PAGE_ALIGN(len); - if (!len || len > TASK_SIZE) - return -ENOMEM; + if (len > TASK_SIZE) + return -EINVAL; /* offset overflow? */ if ((pgoff + (len >> PAGE_SHIFT)) < pgoff) - return -EOVERFLOW; + return -EINVAL; if (file) { /* validate file mapping requests */ diff --git a/trunk/mm/slab.c b/trunk/mm/slab.c index 5de81473df34..3c4a7e34eddc 100644 --- a/trunk/mm/slab.c +++ b/trunk/mm/slab.c @@ -313,7 +313,7 @@ static int drain_freelist(struct kmem_cache *cache, static void free_block(struct kmem_cache *cachep, void **objpp, int len, int node); static int enable_cpucache(struct kmem_cache *cachep); -static void cache_reap(struct work_struct *unused); +static void cache_reap(void *unused); /* * This function must be completely optimized away if a constant is passed to @@ -753,7 +753,7 @@ int slab_is_available(void) return g_cpucache_up == FULL; } -static DEFINE_PER_CPU(struct delayed_work, reap_work); +static DEFINE_PER_CPU(struct work_struct, reap_work); static inline struct array_cache *cpu_cache_get(struct kmem_cache *cachep) { @@ -916,16 +916,16 @@ static void next_reap_node(void) */ static void __devinit start_cpu_timer(int cpu) { - struct delayed_work *reap_work = &per_cpu(reap_work, cpu); + struct work_struct *reap_work = &per_cpu(reap_work, cpu); /* * When this gets called from do_initcalls via cpucache_init(), * init_workqueues() has already run, so keventd will be setup * at that time. */ - if (keventd_up() && reap_work->work.func == NULL) { + if (keventd_up() && reap_work->func == NULL) { init_reap_node(cpu); - INIT_DELAYED_WORK(reap_work, cache_reap); + INIT_WORK(reap_work, cache_reap, NULL); schedule_delayed_work_on(cpu, reap_work, HZ + 3 * cpu); } } @@ -3815,7 +3815,7 @@ void drain_array(struct kmem_cache *cachep, struct kmem_list3 *l3, * If we cannot acquire the cache chain mutex then just give up - we'll try * again on the next iteration. */ -static void cache_reap(struct work_struct *unused) +static void cache_reap(void *unused) { struct kmem_cache *searchp; struct kmem_list3 *l3; diff --git a/trunk/mm/swap.c b/trunk/mm/swap.c index d9a3770d8f3c..2e0e871f542f 100644 --- a/trunk/mm/swap.c +++ b/trunk/mm/swap.c @@ -216,7 +216,7 @@ void lru_add_drain(void) } #ifdef CONFIG_NUMA -static void lru_add_drain_per_cpu(struct work_struct *dummy) +static void lru_add_drain_per_cpu(void *dummy) { lru_add_drain(); } @@ -226,7 +226,7 @@ static void lru_add_drain_per_cpu(struct work_struct *dummy) */ int lru_add_drain_all(void) { - return schedule_on_each_cpu(lru_add_drain_per_cpu); + return schedule_on_each_cpu(lru_add_drain_per_cpu, NULL); } #else diff --git a/trunk/net/atm/lec.c b/trunk/net/atm/lec.c index 3fc0abeeaf34..5946ec63724f 100644 --- a/trunk/net/atm/lec.c +++ b/trunk/net/atm/lec.c @@ -1454,7 +1454,7 @@ static void lane2_associate_ind(struct net_device *dev, u8 *mac_addr, #define LEC_ARP_REFRESH_INTERVAL (3*HZ) -static void lec_arp_check_expire(struct work_struct *work); +static void lec_arp_check_expire(void *data); static void lec_arp_expire_arp(unsigned long data); /* @@ -1477,7 +1477,7 @@ static void lec_arp_init(struct lec_priv *priv) INIT_HLIST_HEAD(&priv->lec_no_forward); INIT_HLIST_HEAD(&priv->mcast_fwds); spin_lock_init(&priv->lec_arp_lock); - INIT_DELAYED_WORK(&priv->lec_arp_work, lec_arp_check_expire); + INIT_WORK(&priv->lec_arp_work, lec_arp_check_expire, priv); schedule_delayed_work(&priv->lec_arp_work, LEC_ARP_REFRESH_INTERVAL); } @@ -1875,11 +1875,10 @@ static void lec_arp_expire_vcc(unsigned long data) * to ESI_FORWARD_DIRECT. This causes the flush period to end * regardless of the progress of the flush protocol. */ -static void lec_arp_check_expire(struct work_struct *work) +static void lec_arp_check_expire(void *data) { unsigned long flags; - struct lec_priv *priv = - container_of(work, struct lec_priv, lec_arp_work.work); + struct lec_priv *priv = data; struct hlist_node *node, *next; struct lec_arp_table *entry; unsigned long now; diff --git a/trunk/net/atm/lec.h b/trunk/net/atm/lec.h index 99136babd535..24cc95f86741 100644 --- a/trunk/net/atm/lec.h +++ b/trunk/net/atm/lec.h @@ -92,7 +92,7 @@ struct lec_priv { spinlock_t lec_arp_lock; struct atm_vcc *mcast_vcc; /* Default Multicast Send VCC */ struct atm_vcc *lecd; - struct delayed_work lec_arp_work; /* C10 */ + struct work_struct lec_arp_work; /* C10 */ unsigned int maximum_unknown_frame_count; /* * Within the period of time defined by this variable, the client will send diff --git a/trunk/net/bluetooth/hci_sysfs.c b/trunk/net/bluetooth/hci_sysfs.c index d4c935692ccf..3eeeb7a86e75 100644 --- a/trunk/net/bluetooth/hci_sysfs.c +++ b/trunk/net/bluetooth/hci_sysfs.c @@ -237,9 +237,9 @@ static void bt_release(struct device *dev) kfree(data); } -static void add_conn(struct work_struct *work) +static void add_conn(void *data) { - struct hci_conn *conn = container_of(work, struct hci_conn, work); + struct hci_conn *conn = data; int i; if (device_register(&conn->dev) < 0) { @@ -272,14 +272,14 @@ void hci_conn_add_sysfs(struct hci_conn *conn) dev_set_drvdata(&conn->dev, conn); - INIT_WORK(&conn->work, add_conn); + INIT_WORK(&conn->work, add_conn, (void *) conn); schedule_work(&conn->work); } -static void del_conn(struct work_struct *work) +static void del_conn(void *data) { - struct hci_conn *conn = container_of(work, struct hci_conn, work); + struct hci_conn *conn = data; device_del(&conn->dev); } @@ -287,7 +287,7 @@ void hci_conn_del_sysfs(struct hci_conn *conn) { BT_DBG("conn %p", conn); - INIT_WORK(&conn->work, del_conn); + INIT_WORK(&conn->work, del_conn, (void *) conn); schedule_work(&conn->work); } diff --git a/trunk/net/bridge/br_if.c b/trunk/net/bridge/br_if.c index 55bb2634c088..f753c40c11d2 100644 --- a/trunk/net/bridge/br_if.c +++ b/trunk/net/bridge/br_if.c @@ -77,16 +77,12 @@ static int port_cost(struct net_device *dev) * Called from work queue to allow for calling functions that * might sleep (such as speed check), and to debounce. */ -static void port_carrier_check(struct work_struct *work) +static void port_carrier_check(void *arg) { + struct net_device *dev = arg; struct net_bridge_port *p; - struct net_device *dev; struct net_bridge *br; - dev = container_of(work, struct net_bridge_port, - carrier_check.work)->dev; - work_release(work); - rtnl_lock(); p = dev->br_port; if (!p) @@ -280,7 +276,7 @@ static struct net_bridge_port *new_nbp(struct net_bridge *br, p->port_no = index; br_init_port(p); p->state = BR_STATE_DISABLED; - INIT_DELAYED_WORK_NAR(&p->carrier_check, port_carrier_check); + INIT_WORK(&p->carrier_check, port_carrier_check, dev); br_stp_port_timer_init(p); kobject_init(&p->kobj); diff --git a/trunk/net/bridge/br_private.h b/trunk/net/bridge/br_private.h index 3a534e94c7f3..74258d86f256 100644 --- a/trunk/net/bridge/br_private.h +++ b/trunk/net/bridge/br_private.h @@ -82,7 +82,7 @@ struct net_bridge_port struct timer_list hold_timer; struct timer_list message_age_timer; struct kobject kobj; - struct delayed_work carrier_check; + struct work_struct carrier_check; struct rcu_head rcu; }; diff --git a/trunk/net/core/link_watch.c b/trunk/net/core/link_watch.c index 549a2ce951b0..4b36114744c5 100644 --- a/trunk/net/core/link_watch.c +++ b/trunk/net/core/link_watch.c @@ -34,8 +34,8 @@ enum lw_bits { static unsigned long linkwatch_flags; static unsigned long linkwatch_nextevent; -static void linkwatch_event(struct work_struct *dummy); -static DECLARE_DELAYED_WORK(linkwatch_work, linkwatch_event); +static void linkwatch_event(void *dummy); +static DECLARE_WORK(linkwatch_work, linkwatch_event, NULL); static LIST_HEAD(lweventlist); static DEFINE_SPINLOCK(lweventlist_lock); @@ -127,7 +127,7 @@ void linkwatch_run_queue(void) } -static void linkwatch_event(struct work_struct *dummy) +static void linkwatch_event(void *dummy) { /* Limit the number of linkwatch events to one * per second so that a runaway driver does not @@ -171,9 +171,10 @@ void linkwatch_fire_event(struct net_device *dev) unsigned long delay = linkwatch_nextevent - jiffies; /* If we wrap around we'll delay it by at most HZ. */ - if (delay > HZ) - delay = 0; - schedule_delayed_work(&linkwatch_work, delay); + if (!delay || delay > HZ) + schedule_work(&linkwatch_work); + else + schedule_delayed_work(&linkwatch_work, delay); } } } diff --git a/trunk/net/core/netpoll.c b/trunk/net/core/netpoll.c index b3c559b9ac35..3c58846fcaa5 100644 --- a/trunk/net/core/netpoll.c +++ b/trunk/net/core/netpoll.c @@ -50,10 +50,9 @@ static atomic_t trapped; static void zap_completion_queue(void); static void arp_reply(struct sk_buff *skb); -static void queue_process(struct work_struct *work) +static void queue_process(void *p) { - struct netpoll_info *npinfo = - container_of(work, struct netpoll_info, tx_work.work); + struct netpoll_info *npinfo = p; struct sk_buff *skb; while ((skb = skb_dequeue(&npinfo->txq))) { @@ -73,6 +72,8 @@ static void queue_process(struct work_struct *work) schedule_delayed_work(&npinfo->tx_work, HZ/10); return; } + + netif_tx_unlock_bh(dev); } } @@ -262,7 +263,7 @@ static void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb) if (status != NETDEV_TX_OK) { skb_queue_tail(&npinfo->txq, skb); - schedule_delayed_work(&npinfo->tx_work,0); + schedule_work(&npinfo->tx_work); } } @@ -627,7 +628,7 @@ int netpoll_setup(struct netpoll *np) spin_lock_init(&npinfo->rx_lock); skb_queue_head_init(&npinfo->arp_tx); skb_queue_head_init(&npinfo->txq); - INIT_DELAYED_WORK(&npinfo->tx_work, queue_process); + INIT_WORK(&npinfo->tx_work, queue_process, npinfo); atomic_set(&npinfo->refcnt, 1); } else { diff --git a/trunk/net/dccp/minisocks.c b/trunk/net/dccp/minisocks.c index 4c9e26775f72..7b52f2a03eef 100644 --- a/trunk/net/dccp/minisocks.c +++ b/trunk/net/dccp/minisocks.c @@ -32,7 +32,8 @@ struct inet_timewait_death_row dccp_death_row = { .tw_timer = TIMER_INITIALIZER(inet_twdr_hangman, 0, (unsigned long)&dccp_death_row), .twkill_work = __WORK_INITIALIZER(dccp_death_row.twkill_work, - inet_twdr_twkill_work), + inet_twdr_twkill_work, + &dccp_death_row), /* Short-time timewait calendar */ .twcal_hand = -1, diff --git a/trunk/net/ieee80211/softmac/ieee80211softmac_assoc.c b/trunk/net/ieee80211/softmac/ieee80211softmac_assoc.c index 08386c102954..cf51c87a971d 100644 --- a/trunk/net/ieee80211/softmac/ieee80211softmac_assoc.c +++ b/trunk/net/ieee80211/softmac/ieee80211softmac_assoc.c @@ -58,11 +58,9 @@ ieee80211softmac_assoc(struct ieee80211softmac_device *mac, struct ieee80211soft } void -ieee80211softmac_assoc_timeout(struct work_struct *work) +ieee80211softmac_assoc_timeout(void *d) { - struct ieee80211softmac_device *mac = - container_of(work, struct ieee80211softmac_device, - associnfo.timeout.work); + struct ieee80211softmac_device *mac = (struct ieee80211softmac_device *)d; struct ieee80211softmac_network *n; mutex_lock(&mac->associnfo.mutex); @@ -188,11 +186,9 @@ ieee80211softmac_assoc_notify_auth(struct net_device *dev, int event_type, void /* This function is called to handle userspace requests (asynchronously) */ void -ieee80211softmac_assoc_work(struct work_struct *work) +ieee80211softmac_assoc_work(void *d) { - struct ieee80211softmac_device *mac = - container_of(work, struct ieee80211softmac_device, - associnfo.work.work); + struct ieee80211softmac_device *mac = (struct ieee80211softmac_device *)d; struct ieee80211softmac_network *found = NULL; struct ieee80211_network *net = NULL, *best = NULL; int bssvalid; @@ -416,7 +412,7 @@ ieee80211softmac_handle_assoc_response(struct net_device * dev, network->authenticated = 0; /* we don't want to do this more than once ... */ network->auth_desynced_once = 1; - schedule_delayed_work(&mac->associnfo.work, 0); + schedule_work(&mac->associnfo.work); break; } default: @@ -450,7 +446,7 @@ ieee80211softmac_handle_disassoc(struct net_device * dev, ieee80211softmac_disassoc(mac); /* try to reassociate */ - schedule_delayed_work(&mac->associnfo.work, 0); + schedule_work(&mac->associnfo.work); return 0; } @@ -470,7 +466,7 @@ ieee80211softmac_handle_reassoc_req(struct net_device * dev, dprintkl(KERN_INFO PFX "reassoc request from unknown network\n"); return 0; } - schedule_delayed_work(&mac->associnfo.work, 0); + schedule_work(&mac->associnfo.work); return 0; } diff --git a/trunk/net/ieee80211/softmac/ieee80211softmac_auth.c b/trunk/net/ieee80211/softmac/ieee80211softmac_auth.c index 6012705aa4f8..0612015f1c78 100644 --- a/trunk/net/ieee80211/softmac/ieee80211softmac_auth.c +++ b/trunk/net/ieee80211/softmac/ieee80211softmac_auth.c @@ -26,7 +26,7 @@ #include "ieee80211softmac_priv.h" -static void ieee80211softmac_auth_queue(struct work_struct *work); +static void ieee80211softmac_auth_queue(void *data); /* Queues an auth request to the desired AP */ int @@ -54,14 +54,14 @@ ieee80211softmac_auth_req(struct ieee80211softmac_device *mac, auth->mac = mac; auth->retry = IEEE80211SOFTMAC_AUTH_RETRY_LIMIT; auth->state = IEEE80211SOFTMAC_AUTH_OPEN_REQUEST; - INIT_DELAYED_WORK(&auth->work, ieee80211softmac_auth_queue); + INIT_WORK(&auth->work, &ieee80211softmac_auth_queue, (void *)auth); /* Lock (for list) */ spin_lock_irqsave(&mac->lock, flags); /* add to list */ list_add_tail(&auth->list, &mac->auth_queue); - schedule_delayed_work(&auth->work, 0); + schedule_work(&auth->work); spin_unlock_irqrestore(&mac->lock, flags); return 0; @@ -70,15 +70,14 @@ ieee80211softmac_auth_req(struct ieee80211softmac_device *mac, /* Sends an auth request to the desired AP and handles timeouts */ static void -ieee80211softmac_auth_queue(struct work_struct *work) +ieee80211softmac_auth_queue(void *data) { struct ieee80211softmac_device *mac; struct ieee80211softmac_auth_queue_item *auth; struct ieee80211softmac_network *net; unsigned long flags; - auth = container_of(work, struct ieee80211softmac_auth_queue_item, - work.work); + auth = (struct ieee80211softmac_auth_queue_item *)data; net = auth->net; mac = auth->mac; @@ -119,11 +118,9 @@ ieee80211softmac_auth_queue(struct work_struct *work) /* Sends a response to an auth challenge (for shared key auth). */ static void -ieee80211softmac_auth_challenge_response(struct work_struct *work) +ieee80211softmac_auth_challenge_response(void *_aq) { - struct ieee80211softmac_auth_queue_item *aq = - container_of(work, struct ieee80211softmac_auth_queue_item, - work.work); + struct ieee80211softmac_auth_queue_item *aq = _aq; /* Send our response */ ieee80211softmac_send_mgt_frame(aq->mac, aq->net, IEEE80211_STYPE_AUTH, aq->state); @@ -237,8 +234,8 @@ ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *auth) * we have obviously already sent the initial auth * request. */ cancel_delayed_work(&aq->work); - INIT_DELAYED_WORK(&aq->work, &ieee80211softmac_auth_challenge_response); - schedule_delayed_work(&aq->work, 0); + INIT_WORK(&aq->work, &ieee80211softmac_auth_challenge_response, (void *)aq); + schedule_work(&aq->work); spin_unlock_irqrestore(&mac->lock, flags); return 0; case IEEE80211SOFTMAC_AUTH_SHARED_PASS: @@ -401,6 +398,6 @@ ieee80211softmac_deauth_resp(struct net_device *dev, struct ieee80211_deauth *de ieee80211softmac_deauth_from_net(mac, net); /* let's try to re-associate */ - schedule_delayed_work(&mac->associnfo.work, 0); + schedule_work(&mac->associnfo.work); return 0; } diff --git a/trunk/net/ieee80211/softmac/ieee80211softmac_event.c b/trunk/net/ieee80211/softmac/ieee80211softmac_event.c index b9015656cfb3..f34fa2ef666b 100644 --- a/trunk/net/ieee80211/softmac/ieee80211softmac_event.c +++ b/trunk/net/ieee80211/softmac/ieee80211softmac_event.c @@ -73,12 +73,10 @@ static char *event_descriptions[IEEE80211SOFTMAC_EVENT_LAST+1] = { static void -ieee80211softmac_notify_callback(struct work_struct *work) +ieee80211softmac_notify_callback(void *d) { - struct ieee80211softmac_event *pevent = - container_of(work, struct ieee80211softmac_event, work.work); - struct ieee80211softmac_event event = *pevent; - kfree(pevent); + struct ieee80211softmac_event event = *(struct ieee80211softmac_event*) d; + kfree(d); event.fun(event.mac->dev, event.event_type, event.context); } @@ -101,7 +99,7 @@ ieee80211softmac_notify_internal(struct ieee80211softmac_device *mac, return -ENOMEM; eventptr->event_type = event; - INIT_DELAYED_WORK(&eventptr->work, ieee80211softmac_notify_callback); + INIT_WORK(&eventptr->work, ieee80211softmac_notify_callback, eventptr); eventptr->fun = fun; eventptr->context = context; eventptr->mac = mac; @@ -172,7 +170,7 @@ ieee80211softmac_call_events_locked(struct ieee80211softmac_device *mac, int eve /* User may have subscribed to ANY event, so * we tell them which event triggered it. */ eventptr->event_type = event; - schedule_delayed_work(&eventptr->work, 0); + schedule_work(&eventptr->work); } } } diff --git a/trunk/net/ieee80211/softmac/ieee80211softmac_module.c b/trunk/net/ieee80211/softmac/ieee80211softmac_module.c index 256207b71dc9..33aff4f4a471 100644 --- a/trunk/net/ieee80211/softmac/ieee80211softmac_module.c +++ b/trunk/net/ieee80211/softmac/ieee80211softmac_module.c @@ -58,8 +58,8 @@ struct net_device *alloc_ieee80211softmac(int sizeof_priv) INIT_LIST_HEAD(&softmac->events); mutex_init(&softmac->associnfo.mutex); - INIT_DELAYED_WORK(&softmac->associnfo.work, ieee80211softmac_assoc_work); - INIT_DELAYED_WORK(&softmac->associnfo.timeout, ieee80211softmac_assoc_timeout); + INIT_WORK(&softmac->associnfo.work, ieee80211softmac_assoc_work, softmac); + INIT_WORK(&softmac->associnfo.timeout, ieee80211softmac_assoc_timeout, softmac); softmac->start_scan = ieee80211softmac_start_scan_implementation; softmac->wait_for_scan = ieee80211softmac_wait_for_scan_implementation; softmac->stop_scan = ieee80211softmac_stop_scan_implementation; diff --git a/trunk/net/ieee80211/softmac/ieee80211softmac_priv.h b/trunk/net/ieee80211/softmac/ieee80211softmac_priv.h index c0dbe070e548..0642e090b8a7 100644 --- a/trunk/net/ieee80211/softmac/ieee80211softmac_priv.h +++ b/trunk/net/ieee80211/softmac/ieee80211softmac_priv.h @@ -78,7 +78,7 @@ /* private definitions and prototypes */ /*** prototypes from _scan.c */ -void ieee80211softmac_scan(struct work_struct *work); +void ieee80211softmac_scan(void *sm); /* for internal use if scanning is needed */ int ieee80211softmac_start_scan(struct ieee80211softmac_device *mac); void ieee80211softmac_stop_scan(struct ieee80211softmac_device *mac); @@ -149,7 +149,7 @@ int ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *au int ieee80211softmac_deauth_resp(struct net_device *dev, struct ieee80211_deauth *deauth); /*** prototypes from _assoc.c */ -void ieee80211softmac_assoc_work(struct work_struct *work); +void ieee80211softmac_assoc_work(void *d); int ieee80211softmac_handle_assoc_response(struct net_device * dev, struct ieee80211_assoc_response * resp, struct ieee80211_network * network); @@ -157,7 +157,7 @@ int ieee80211softmac_handle_disassoc(struct net_device * dev, struct ieee80211_disassoc * disassoc); int ieee80211softmac_handle_reassoc_req(struct net_device * dev, struct ieee80211_reassoc_request * reassoc); -void ieee80211softmac_assoc_timeout(struct work_struct *work); +void ieee80211softmac_assoc_timeout(void *d); void ieee80211softmac_send_disassoc_req(struct ieee80211softmac_device *mac, u16 reason); void ieee80211softmac_disassoc(struct ieee80211softmac_device *mac); @@ -207,7 +207,7 @@ struct ieee80211softmac_auth_queue_item { struct ieee80211softmac_device *mac; /* SoftMAC device */ u8 retry; /* Retry limit */ u8 state; /* Auth State */ - struct delayed_work work; /* Work queue */ + struct work_struct work; /* Work queue */ }; /* scanning information */ @@ -219,8 +219,7 @@ struct ieee80211softmac_scaninfo { stop:1; u8 skip_flags; struct completion finished; - struct delayed_work softmac_scan; - struct ieee80211softmac_device *mac; + struct work_struct softmac_scan; }; /* private event struct */ @@ -228,7 +227,7 @@ struct ieee80211softmac_event { struct list_head list; int event_type; void *event_context; - struct delayed_work work; + struct work_struct work; notify_function_ptr fun; void *context; struct ieee80211softmac_device *mac; diff --git a/trunk/net/ieee80211/softmac/ieee80211softmac_scan.c b/trunk/net/ieee80211/softmac/ieee80211softmac_scan.c index 0c85d6c24cdb..5507feab32de 100644 --- a/trunk/net/ieee80211/softmac/ieee80211softmac_scan.c +++ b/trunk/net/ieee80211/softmac/ieee80211softmac_scan.c @@ -90,14 +90,12 @@ ieee80211softmac_wait_for_scan(struct ieee80211softmac_device *sm) /* internal scanning implementation follows */ -void ieee80211softmac_scan(struct work_struct *work) +void ieee80211softmac_scan(void *d) { int invalid_channel; u8 current_channel_idx; - struct ieee80211softmac_scaninfo *si = - container_of(work, struct ieee80211softmac_scaninfo, - softmac_scan.work); - struct ieee80211softmac_device *sm = si->mac; + struct ieee80211softmac_device *sm = (struct ieee80211softmac_device *)d; + struct ieee80211softmac_scaninfo *si = sm->scaninfo; unsigned long flags; while (!(si->stop) && (si->current_channel_idx < si->number_channels)) { @@ -148,8 +146,7 @@ static inline struct ieee80211softmac_scaninfo *allocate_scaninfo(struct ieee802 struct ieee80211softmac_scaninfo *info = kmalloc(sizeof(struct ieee80211softmac_scaninfo), GFP_ATOMIC); if (unlikely(!info)) return NULL; - INIT_DELAYED_WORK(&info->softmac_scan, ieee80211softmac_scan); - info->mac = mac; + INIT_WORK(&info->softmac_scan, ieee80211softmac_scan, mac); init_completion(&info->finished); return info; } @@ -190,7 +187,7 @@ int ieee80211softmac_start_scan_implementation(struct net_device *dev) sm->scaninfo->started = 1; sm->scaninfo->stop = 0; INIT_COMPLETION(sm->scaninfo->finished); - schedule_delayed_work(&sm->scaninfo->softmac_scan, 0); + schedule_work(&sm->scaninfo->softmac_scan); spin_unlock_irqrestore(&sm->lock, flags); return 0; } diff --git a/trunk/net/ieee80211/softmac/ieee80211softmac_wx.c b/trunk/net/ieee80211/softmac/ieee80211softmac_wx.c index 2ffaebd21c53..23068a830f7d 100644 --- a/trunk/net/ieee80211/softmac/ieee80211softmac_wx.c +++ b/trunk/net/ieee80211/softmac/ieee80211softmac_wx.c @@ -122,7 +122,7 @@ ieee80211softmac_wx_set_essid(struct net_device *net_dev, sm->associnfo.associating = 1; /* queue lower level code to do work (if necessary) */ - schedule_delayed_work(&sm->associnfo.work, 0); + schedule_work(&sm->associnfo.work); out: mutex_unlock(&sm->associnfo.mutex); @@ -356,7 +356,7 @@ ieee80211softmac_wx_set_wap(struct net_device *net_dev, /* force reassociation */ mac->associnfo.bssvalid = 0; if (mac->associnfo.associated) - schedule_delayed_work(&mac->associnfo.work, 0); + schedule_work(&mac->associnfo.work); } else if (is_zero_ether_addr(data->ap_addr.sa_data)) { /* the bssid we have is no longer fixed */ mac->associnfo.bssfixed = 0; @@ -373,7 +373,7 @@ ieee80211softmac_wx_set_wap(struct net_device *net_dev, /* tell the other code that this bssid should be used no matter what */ mac->associnfo.bssfixed = 1; /* queue associate if new bssid or (old one again and not associated) */ - schedule_delayed_work(&mac->associnfo.work, 0); + schedule_work(&mac->associnfo.work); } out: diff --git a/trunk/net/ipv4/inet_timewait_sock.c b/trunk/net/ipv4/inet_timewait_sock.c index 8c74f9168b7d..cdd805344c61 100644 --- a/trunk/net/ipv4/inet_timewait_sock.c +++ b/trunk/net/ipv4/inet_timewait_sock.c @@ -197,10 +197,9 @@ EXPORT_SYMBOL_GPL(inet_twdr_hangman); extern void twkill_slots_invalid(void); -void inet_twdr_twkill_work(struct work_struct *work) +void inet_twdr_twkill_work(void *data) { - struct inet_timewait_death_row *twdr = - container_of(work, struct inet_timewait_death_row, twkill_work); + struct inet_timewait_death_row *twdr = data; int i; if ((INET_TWDR_TWKILL_SLOTS - 1) > (sizeof(twdr->thread_slots) * 8)) diff --git a/trunk/net/ipv4/ipvs/ip_vs_ctl.c b/trunk/net/ipv4/ipvs/ip_vs_ctl.c index 9b933381ebbe..f261616e4602 100644 --- a/trunk/net/ipv4/ipvs/ip_vs_ctl.c +++ b/trunk/net/ipv4/ipvs/ip_vs_ctl.c @@ -221,10 +221,10 @@ static void update_defense_level(void) * Timer for checking the defense */ #define DEFENSE_TIMER_PERIOD 1*HZ -static void defense_work_handler(struct work_struct *work); -static DECLARE_DELAYED_WORK(defense_work, defense_work_handler); +static void defense_work_handler(void *data); +static DECLARE_WORK(defense_work, defense_work_handler, NULL); -static void defense_work_handler(struct work_struct *work) +static void defense_work_handler(void *data) { update_defense_level(); if (atomic_read(&ip_vs_dropentry)) diff --git a/trunk/net/ipv4/tcp_minisocks.c b/trunk/net/ipv4/tcp_minisocks.c index 4a3889dd1943..6dddf59c1fb9 100644 --- a/trunk/net/ipv4/tcp_minisocks.c +++ b/trunk/net/ipv4/tcp_minisocks.c @@ -45,7 +45,8 @@ struct inet_timewait_death_row tcp_death_row = { .tw_timer = TIMER_INITIALIZER(inet_twdr_hangman, 0, (unsigned long)&tcp_death_row), .twkill_work = __WORK_INITIALIZER(tcp_death_row.twkill_work, - inet_twdr_twkill_work), + inet_twdr_twkill_work, + &tcp_death_row), /* Short-time timewait calendar */ .twcal_hand = -1, diff --git a/trunk/net/irda/ircomm/ircomm_tty.c b/trunk/net/irda/ircomm/ircomm_tty.c index 262bda808d96..d50a02030ad7 100644 --- a/trunk/net/irda/ircomm/ircomm_tty.c +++ b/trunk/net/irda/ircomm/ircomm_tty.c @@ -61,7 +61,7 @@ static void ircomm_tty_flush_buffer(struct tty_struct *tty); static void ircomm_tty_send_xchar(struct tty_struct *tty, char ch); static void ircomm_tty_wait_until_sent(struct tty_struct *tty, int timeout); static void ircomm_tty_hangup(struct tty_struct *tty); -static void ircomm_tty_do_softint(struct work_struct *work); +static void ircomm_tty_do_softint(void *private_); static void ircomm_tty_shutdown(struct ircomm_tty_cb *self); static void ircomm_tty_stop(struct tty_struct *tty); @@ -389,7 +389,7 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp) self->flow = FLOW_STOP; self->line = line; - INIT_WORK(&self->tqueue, ircomm_tty_do_softint); + INIT_WORK(&self->tqueue, ircomm_tty_do_softint, self); self->max_header_size = IRCOMM_TTY_HDR_UNINITIALISED; self->max_data_size = IRCOMM_TTY_DATA_UNINITIALISED; self->close_delay = 5*HZ/10; @@ -594,16 +594,15 @@ static void ircomm_tty_flush_buffer(struct tty_struct *tty) } /* - * Function ircomm_tty_do_softint (work) + * Function ircomm_tty_do_softint (private_) * * We use this routine to give the write wakeup to the user at at a * safe time (as fast as possible after write have completed). This * can be compared to the Tx interrupt. */ -static void ircomm_tty_do_softint(struct work_struct *work) +static void ircomm_tty_do_softint(void *private_) { - struct ircomm_tty_cb *self = - container_of(work, struct ircomm_tty_cb, tqueue); + struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) private_; struct tty_struct *tty; unsigned long flags; struct sk_buff *skb, *ctrl_skb; diff --git a/trunk/net/sctp/associola.c b/trunk/net/sctp/associola.c index ad0057db0f91..39471d3b31b9 100644 --- a/trunk/net/sctp/associola.c +++ b/trunk/net/sctp/associola.c @@ -61,7 +61,7 @@ #include /* Forward declarations for internal functions. */ -static void sctp_assoc_bh_rcv(struct work_struct *work); +static void sctp_assoc_bh_rcv(struct sctp_association *asoc); /* 1st Level Abstractions. */ @@ -269,7 +269,9 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a /* Create an input queue. */ sctp_inq_init(&asoc->base.inqueue); - sctp_inq_set_th_handler(&asoc->base.inqueue, sctp_assoc_bh_rcv); + sctp_inq_set_th_handler(&asoc->base.inqueue, + (void (*)(void *))sctp_assoc_bh_rcv, + asoc); /* Create an output queue. */ sctp_outq_init(asoc, &asoc->outqueue); @@ -944,11 +946,8 @@ struct sctp_transport *sctp_assoc_is_match(struct sctp_association *asoc, } /* Do delayed input processing. This is scheduled by sctp_rcv(). */ -static void sctp_assoc_bh_rcv(struct work_struct *work) +static void sctp_assoc_bh_rcv(struct sctp_association *asoc) { - struct sctp_association *asoc = - container_of(work, struct sctp_association, - base.inqueue.immediate); struct sctp_endpoint *ep; struct sctp_chunk *chunk; struct sock *sk; diff --git a/trunk/net/sctp/endpointola.c b/trunk/net/sctp/endpointola.c index 129756908da4..33a42e90c32f 100644 --- a/trunk/net/sctp/endpointola.c +++ b/trunk/net/sctp/endpointola.c @@ -61,7 +61,7 @@ #include /* Forward declarations for internal helpers. */ -static void sctp_endpoint_bh_rcv(struct work_struct *work); +static void sctp_endpoint_bh_rcv(struct sctp_endpoint *ep); /* * Initialize the base fields of the endpoint structure. @@ -89,7 +89,8 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep, sctp_inq_init(&ep->base.inqueue); /* Set its top-half handler */ - sctp_inq_set_th_handler(&ep->base.inqueue, sctp_endpoint_bh_rcv); + sctp_inq_set_th_handler(&ep->base.inqueue, + (void (*)(void *))sctp_endpoint_bh_rcv, ep); /* Initialize the bind addr area */ sctp_bind_addr_init(&ep->base.bind_addr, 0); @@ -317,11 +318,8 @@ int sctp_endpoint_is_peeled_off(struct sctp_endpoint *ep, /* Do delayed input processing. This is scheduled by sctp_rcv(). * This may be called on BH or task time. */ -static void sctp_endpoint_bh_rcv(struct work_struct *work) +static void sctp_endpoint_bh_rcv(struct sctp_endpoint *ep) { - struct sctp_endpoint *ep = - container_of(work, struct sctp_endpoint, - base.inqueue.immediate); struct sctp_association *asoc; struct sock *sk; struct sctp_transport *transport; diff --git a/trunk/net/sctp/inqueue.c b/trunk/net/sctp/inqueue.c index 71b07466e880..cf6deed7e849 100644 --- a/trunk/net/sctp/inqueue.c +++ b/trunk/net/sctp/inqueue.c @@ -54,7 +54,7 @@ void sctp_inq_init(struct sctp_inq *queue) queue->in_progress = NULL; /* Create a task for delivering data. */ - INIT_WORK(&queue->immediate, NULL); + INIT_WORK(&queue->immediate, NULL, NULL); queue->malloced = 0; } @@ -97,7 +97,7 @@ void sctp_inq_push(struct sctp_inq *q, struct sctp_chunk *chunk) * on the BH related data structures. */ list_add_tail(&chunk->list, &q->in_chunk_list); - q->immediate.func(&q->immediate); + q->immediate.func(q->immediate.data); } /* Extract a chunk from an SCTP inqueue. @@ -205,8 +205,9 @@ struct sctp_chunk *sctp_inq_pop(struct sctp_inq *queue) * The intent is that this routine will pull stuff out of the * inqueue and process it. */ -void sctp_inq_set_th_handler(struct sctp_inq *q, work_func_t callback) +void sctp_inq_set_th_handler(struct sctp_inq *q, + void (*callback)(void *), void *arg) { - INIT_WORK(&q->immediate, callback); + INIT_WORK(&q->immediate, callback, arg); } diff --git a/trunk/net/sunrpc/cache.c b/trunk/net/sunrpc/cache.c index d96fd466a9a4..00cb388ece03 100644 --- a/trunk/net/sunrpc/cache.c +++ b/trunk/net/sunrpc/cache.c @@ -284,8 +284,8 @@ static struct file_operations cache_file_operations; static struct file_operations content_file_operations; static struct file_operations cache_flush_operations; -static void do_cache_clean(struct work_struct *work); -static DECLARE_DELAYED_WORK(cache_cleaner, do_cache_clean); +static void do_cache_clean(void *data); +static DECLARE_WORK(cache_cleaner, do_cache_clean, NULL); void cache_register(struct cache_detail *cd) { @@ -337,7 +337,7 @@ void cache_register(struct cache_detail *cd) spin_unlock(&cache_list_lock); /* start the cleaning process */ - schedule_delayed_work(&cache_cleaner, 0); + schedule_work(&cache_cleaner); } int cache_unregister(struct cache_detail *cd) @@ -461,7 +461,7 @@ static int cache_clean(void) /* * We want to regularly clean the cache, so we need to schedule some work ... */ -static void do_cache_clean(struct work_struct *work) +static void do_cache_clean(void *data) { int delay = 5; if (cache_clean() == -1) diff --git a/trunk/net/sunrpc/rpc_pipe.c b/trunk/net/sunrpc/rpc_pipe.c index 49dba5febbbd..9a0b41a97f90 100644 --- a/trunk/net/sunrpc/rpc_pipe.c +++ b/trunk/net/sunrpc/rpc_pipe.c @@ -54,11 +54,10 @@ static void rpc_purge_list(struct rpc_inode *rpci, struct list_head *head, } static void -rpc_timeout_upcall_queue(struct work_struct *work) +rpc_timeout_upcall_queue(void *data) { LIST_HEAD(free_list); - struct rpc_inode *rpci = - container_of(work, struct rpc_inode, queue_timeout.work); + struct rpc_inode *rpci = (struct rpc_inode *)data; struct inode *inode = &rpci->vfs_inode; void (*destroy_msg)(struct rpc_pipe_msg *); @@ -838,8 +837,7 @@ init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) INIT_LIST_HEAD(&rpci->pipe); rpci->pipelen = 0; init_waitqueue_head(&rpci->waitq); - INIT_DELAYED_WORK(&rpci->queue_timeout, - rpc_timeout_upcall_queue); + INIT_WORK(&rpci->queue_timeout, rpc_timeout_upcall_queue, rpci); rpci->ops = NULL; } } diff --git a/trunk/net/sunrpc/sched.c b/trunk/net/sunrpc/sched.c index eff44bcdc95a..a1ab4eed41f4 100644 --- a/trunk/net/sunrpc/sched.c +++ b/trunk/net/sunrpc/sched.c @@ -41,7 +41,7 @@ static mempool_t *rpc_buffer_mempool __read_mostly; static void __rpc_default_timer(struct rpc_task *task); static void rpciod_killall(void); -static void rpc_async_schedule(struct work_struct *); +static void rpc_async_schedule(void *); /* * RPC tasks sit here while waiting for conditions to improve. @@ -305,7 +305,7 @@ static void rpc_make_runnable(struct rpc_task *task) if (RPC_IS_ASYNC(task)) { int status; - INIT_WORK(&task->u.tk_work, rpc_async_schedule); + INIT_WORK(&task->u.tk_work, rpc_async_schedule, (void *)task); status = queue_work(task->tk_workqueue, &task->u.tk_work); if (status < 0) { printk(KERN_WARNING "RPC: failed to add task to queue: error: %d!\n", status); @@ -695,9 +695,9 @@ rpc_execute(struct rpc_task *task) return __rpc_execute(task); } -static void rpc_async_schedule(struct work_struct *work) +static void rpc_async_schedule(void *arg) { - __rpc_execute(container_of(work, struct rpc_task, u.tk_work)); + __rpc_execute((struct rpc_task *)arg); } /** diff --git a/trunk/net/sunrpc/xprt.c b/trunk/net/sunrpc/xprt.c index 4f9a5d9791fb..80857470dc11 100644 --- a/trunk/net/sunrpc/xprt.c +++ b/trunk/net/sunrpc/xprt.c @@ -479,10 +479,9 @@ int xprt_adjust_timeout(struct rpc_rqst *req) return status; } -static void xprt_autoclose(struct work_struct *work) +static void xprt_autoclose(void *args) { - struct rpc_xprt *xprt = - container_of(work, struct rpc_xprt, task_cleanup); + struct rpc_xprt *xprt = (struct rpc_xprt *)args; xprt_disconnect(xprt); xprt->ops->close(xprt); @@ -933,7 +932,7 @@ struct rpc_xprt *xprt_create_transport(int proto, struct sockaddr *ap, size_t si INIT_LIST_HEAD(&xprt->free); INIT_LIST_HEAD(&xprt->recv); - INIT_WORK(&xprt->task_cleanup, xprt_autoclose); + INIT_WORK(&xprt->task_cleanup, xprt_autoclose, xprt); init_timer(&xprt->timer); xprt->timer.function = xprt_init_autodisconnect; xprt->timer.data = (unsigned long) xprt; diff --git a/trunk/net/sunrpc/xprtsock.c b/trunk/net/sunrpc/xprtsock.c index cfe3c15be948..757fc91ef25d 100644 --- a/trunk/net/sunrpc/xprtsock.c +++ b/trunk/net/sunrpc/xprtsock.c @@ -1060,14 +1060,13 @@ static int xs_bindresvport(struct rpc_xprt *xprt, struct socket *sock) /** * xs_udp_connect_worker - set up a UDP socket - * @work: RPC transport to connect + * @args: RPC transport to connect * * Invoked by a work queue tasklet. */ -static void xs_udp_connect_worker(struct work_struct *work) +static void xs_udp_connect_worker(void *args) { - struct rpc_xprt *xprt = - container_of(work, struct rpc_xprt, connect_worker.work); + struct rpc_xprt *xprt = (struct rpc_xprt *) args; struct socket *sock = xprt->sock; int err, status = -EIO; @@ -1145,14 +1144,13 @@ static void xs_tcp_reuse_connection(struct rpc_xprt *xprt) /** * xs_tcp_connect_worker - connect a TCP socket to a remote endpoint - * @work: RPC transport to connect + * @args: RPC transport to connect * * Invoked by a work queue tasklet. */ -static void xs_tcp_connect_worker(struct work_struct *work) +static void xs_tcp_connect_worker(void *args) { - struct rpc_xprt *xprt = - container_of(work, struct rpc_xprt, connect_worker.work); + struct rpc_xprt *xprt = (struct rpc_xprt *)args; struct socket *sock = xprt->sock; int err, status = -EIO; @@ -1264,7 +1262,7 @@ static void xs_connect(struct rpc_task *task) xprt->reestablish_timeout = XS_TCP_MAX_REEST_TO; } else { dprintk("RPC: xs_connect scheduled xprt %p\n", xprt); - schedule_delayed_work(&xprt->connect_worker, 0); + schedule_work(&xprt->connect_worker); /* flush_scheduled_work can sleep... */ if (!RPC_IS_ASYNC(task)) @@ -1377,7 +1375,7 @@ int xs_setup_udp(struct rpc_xprt *xprt, struct rpc_timeout *to) /* XXX: header size can vary due to auth type, IPv6, etc. */ xprt->max_payload = (1U << 16) - (MAX_HEADER << 3); - INIT_DELAYED_WORK(&xprt->connect_worker, xs_udp_connect_worker); + INIT_WORK(&xprt->connect_worker, xs_udp_connect_worker, xprt); xprt->bind_timeout = XS_BIND_TO; xprt->connect_timeout = XS_UDP_CONN_TO; xprt->reestablish_timeout = XS_UDP_REEST_TO; @@ -1422,7 +1420,7 @@ int xs_setup_tcp(struct rpc_xprt *xprt, struct rpc_timeout *to) xprt->tsh_size = sizeof(rpc_fraghdr) / sizeof(u32); xprt->max_payload = RPC_MAX_FRAGMENT_SIZE; - INIT_DELAYED_WORK(&xprt->connect_worker, xs_tcp_connect_worker); + INIT_WORK(&xprt->connect_worker, xs_tcp_connect_worker, xprt); xprt->bind_timeout = XS_BIND_TO; xprt->connect_timeout = XS_TCP_CONN_TO; xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO; diff --git a/trunk/net/xfrm/xfrm_policy.c b/trunk/net/xfrm/xfrm_policy.c index f6c77bd36fdd..64d3938f74c4 100644 --- a/trunk/net/xfrm/xfrm_policy.c +++ b/trunk/net/xfrm/xfrm_policy.c @@ -392,7 +392,7 @@ static void xfrm_policy_gc_kill(struct xfrm_policy *policy) xfrm_pol_put(policy); } -static void xfrm_policy_gc_task(struct work_struct *work) +static void xfrm_policy_gc_task(void *data) { struct xfrm_policy *policy; struct hlist_node *entry, *tmp; @@ -580,7 +580,7 @@ static inline int xfrm_byidx_should_resize(int total) static DEFINE_MUTEX(hash_resize_mutex); -static void xfrm_hash_resize(struct work_struct *__unused) +static void xfrm_hash_resize(void *__unused) { int dir, total; @@ -597,7 +597,7 @@ static void xfrm_hash_resize(struct work_struct *__unused) mutex_unlock(&hash_resize_mutex); } -static DECLARE_WORK(xfrm_hash_work, xfrm_hash_resize); +static DECLARE_WORK(xfrm_hash_work, xfrm_hash_resize, NULL); /* Generate new index... KAME seems to generate them ordered by cost * of an absolute inpredictability of ordering of rules. This will not pass. */ @@ -2116,7 +2116,7 @@ static void __init xfrm_policy_init(void) panic("XFRM: failed to allocate bydst hash\n"); } - INIT_WORK(&xfrm_policy_gc_work, xfrm_policy_gc_task); + INIT_WORK(&xfrm_policy_gc_work, xfrm_policy_gc_task, NULL); register_netdevice_notifier(&xfrm_dev_notifier); } diff --git a/trunk/net/xfrm/xfrm_state.c b/trunk/net/xfrm/xfrm_state.c index da54a64ccfa3..864962bbda90 100644 --- a/trunk/net/xfrm/xfrm_state.c +++ b/trunk/net/xfrm/xfrm_state.c @@ -115,7 +115,7 @@ static unsigned long xfrm_hash_new_size(void) static DEFINE_MUTEX(hash_resize_mutex); -static void xfrm_hash_resize(struct work_struct *__unused) +static void xfrm_hash_resize(void *__unused) { struct hlist_head *ndst, *nsrc, *nspi, *odst, *osrc, *ospi; unsigned long nsize, osize; @@ -168,7 +168,7 @@ static void xfrm_hash_resize(struct work_struct *__unused) mutex_unlock(&hash_resize_mutex); } -static DECLARE_WORK(xfrm_hash_work, xfrm_hash_resize); +static DECLARE_WORK(xfrm_hash_work, xfrm_hash_resize, NULL); DECLARE_WAIT_QUEUE_HEAD(km_waitq); EXPORT_SYMBOL(km_waitq); @@ -207,7 +207,7 @@ static void xfrm_state_gc_destroy(struct xfrm_state *x) kfree(x); } -static void xfrm_state_gc_task(struct work_struct *data) +static void xfrm_state_gc_task(void *data) { struct xfrm_state *x; struct hlist_node *entry, *tmp; @@ -1568,6 +1568,6 @@ void __init xfrm_state_init(void) panic("XFRM: Cannot allocate bydst/bysrc/byspi hashes."); xfrm_state_hmask = ((sz / sizeof(struct hlist_head)) - 1); - INIT_WORK(&xfrm_state_gc_work, xfrm_state_gc_task); + INIT_WORK(&xfrm_state_gc_work, xfrm_state_gc_task, NULL); } diff --git a/trunk/security/keys/key.c b/trunk/security/keys/key.c index 70eacbe5abde..80de8c3e9cc3 100644 --- a/trunk/security/keys/key.c +++ b/trunk/security/keys/key.c @@ -30,8 +30,8 @@ DEFINE_SPINLOCK(key_user_lock); static LIST_HEAD(key_types_list); static DECLARE_RWSEM(key_types_sem); -static void key_cleanup(struct work_struct *work); -static DECLARE_WORK(key_cleanup_task, key_cleanup); +static void key_cleanup(void *data); +static DECLARE_WORK(key_cleanup_task, key_cleanup, NULL); /* we serialise key instantiation and link */ DECLARE_RWSEM(key_construction_sem); @@ -552,7 +552,7 @@ EXPORT_SYMBOL(key_negate_and_link); * do cleaning up in process context so that we don't have to disable * interrupts all over the place */ -static void key_cleanup(struct work_struct *work) +static void key_cleanup(void *data) { struct rb_node *_n; struct key *key; diff --git a/trunk/sound/aoa/aoa-gpio.h b/trunk/sound/aoa/aoa-gpio.h index ee64f5de8966..3a61f3115573 100644 --- a/trunk/sound/aoa/aoa-gpio.h +++ b/trunk/sound/aoa/aoa-gpio.h @@ -59,10 +59,10 @@ struct gpio_methods { }; struct gpio_notification { - struct delayed_work work; notify_func_t notify; void *data; void *gpio_private; + struct work_struct work; struct mutex mutex; }; diff --git a/trunk/sound/aoa/core/snd-aoa-gpio-feature.c b/trunk/sound/aoa/core/snd-aoa-gpio-feature.c index 2b03bc798bcb..40eb47eccf9a 100644 --- a/trunk/sound/aoa/core/snd-aoa-gpio-feature.c +++ b/trunk/sound/aoa/core/snd-aoa-gpio-feature.c @@ -195,10 +195,9 @@ static void ftr_gpio_all_amps_restore(struct gpio_runtime *rt) ftr_gpio_set_lineout(rt, (s>>2)&1); } -static void ftr_handle_notify(struct work_struct *work) +static void ftr_handle_notify(void *data) { - struct gpio_notification *notif = - container_of(work, struct gpio_notification, work.work); + struct gpio_notification *notif = data; mutex_lock(¬if->mutex); if (notif->notify) @@ -254,9 +253,12 @@ static void ftr_gpio_init(struct gpio_runtime *rt) ftr_gpio_all_amps_off(rt); rt->implementation_private = 0; - INIT_DELAYED_WORK(&rt->headphone_notify.work, ftr_handle_notify); - INIT_DELAYED_WORK(&rt->line_in_notify.work, ftr_handle_notify); - INIT_DELAYED_WORK(&rt->line_out_notify.work, ftr_handle_notify); + INIT_WORK(&rt->headphone_notify.work, ftr_handle_notify, + &rt->headphone_notify); + INIT_WORK(&rt->line_in_notify.work, ftr_handle_notify, + &rt->line_in_notify); + INIT_WORK(&rt->line_out_notify.work, ftr_handle_notify, + &rt->line_out_notify); mutex_init(&rt->headphone_notify.mutex); mutex_init(&rt->line_in_notify.mutex); mutex_init(&rt->line_out_notify.mutex); @@ -285,7 +287,7 @@ static irqreturn_t ftr_handle_notify_irq(int xx, void *data) { struct gpio_notification *notif = data; - schedule_delayed_work(¬if->work, 0); + schedule_work(¬if->work); return IRQ_HANDLED; } diff --git a/trunk/sound/aoa/core/snd-aoa-gpio-pmf.c b/trunk/sound/aoa/core/snd-aoa-gpio-pmf.c index 5ca2220eac7d..2836c3218391 100644 --- a/trunk/sound/aoa/core/snd-aoa-gpio-pmf.c +++ b/trunk/sound/aoa/core/snd-aoa-gpio-pmf.c @@ -69,10 +69,9 @@ static void pmf_gpio_all_amps_restore(struct gpio_runtime *rt) pmf_gpio_set_lineout(rt, (s>>2)&1); } -static void pmf_handle_notify(struct work_struct *work) +static void pmf_handle_notify(void *data) { - struct gpio_notification *notif = - container_of(work, struct gpio_notification, work.work); + struct gpio_notification *notif = data; mutex_lock(¬if->mutex); if (notif->notify) @@ -84,9 +83,12 @@ static void pmf_gpio_init(struct gpio_runtime *rt) { pmf_gpio_all_amps_off(rt); rt->implementation_private = 0; - INIT_DELAYED_WORK(&rt->headphone_notify.work, pmf_handle_notify); - INIT_DELAYED_WORK(&rt->line_in_notify.work, pmf_handle_notify); - INIT_DELAYED_WORK(&rt->line_out_notify.work, pmf_handle_notify); + INIT_WORK(&rt->headphone_notify.work, pmf_handle_notify, + &rt->headphone_notify); + INIT_WORK(&rt->line_in_notify.work, pmf_handle_notify, + &rt->line_in_notify); + INIT_WORK(&rt->line_out_notify.work, pmf_handle_notify, + &rt->line_out_notify); mutex_init(&rt->headphone_notify.mutex); mutex_init(&rt->line_in_notify.mutex); mutex_init(&rt->line_out_notify.mutex); @@ -127,7 +129,7 @@ static void pmf_handle_notify_irq(void *data) { struct gpio_notification *notif = data; - schedule_delayed_work(¬if->work, 0); + schedule_work(¬if->work); } static int pmf_set_notify(struct gpio_runtime *rt, diff --git a/trunk/sound/i2c/other/ak4114.c b/trunk/sound/i2c/other/ak4114.c index d2f2c5078e65..12ffffc9e814 100644 --- a/trunk/sound/i2c/other/ak4114.c +++ b/trunk/sound/i2c/other/ak4114.c @@ -35,7 +35,7 @@ MODULE_LICENSE("GPL"); #define AK4114_ADDR 0x00 /* fixed address */ -static void ak4114_stats(struct work_struct *work); +static void ak4114_stats(void *); static void reg_write(struct ak4114 *ak4114, unsigned char reg, unsigned char val) { @@ -158,7 +158,7 @@ void snd_ak4114_reinit(struct ak4114 *chip) reg_write(chip, AK4114_REG_PWRDN, old | AK4114_RST | AK4114_PWN); /* bring up statistics / event queing */ chip->init = 0; - INIT_DELAYED_WORK(&chip->work, ak4114_stats); + INIT_WORK(&chip->work, ak4114_stats, chip); queue_delayed_work(chip->workqueue, &chip->work, HZ / 10); } @@ -561,9 +561,9 @@ int snd_ak4114_check_rate_and_errors(struct ak4114 *ak4114, unsigned int flags) return res; } -static void ak4114_stats(struct work_struct *work) +static void ak4114_stats(void *data) { - struct ak4114 *chip = container_of(work, struct ak4114, work.work); + struct ak4114 *chip = (struct ak4114 *)data; if (chip->init) return; diff --git a/trunk/sound/pci/ac97/ac97_codec.c b/trunk/sound/pci/ac97/ac97_codec.c index 7abcb10b2754..6577b2325357 100644 --- a/trunk/sound/pci/ac97/ac97_codec.c +++ b/trunk/sound/pci/ac97/ac97_codec.c @@ -1927,10 +1927,9 @@ static int snd_ac97_dev_disconnect(struct snd_device *device) static struct snd_ac97_build_ops null_build_ops; #ifdef CONFIG_SND_AC97_POWER_SAVE -static void do_update_power(struct work_struct *work) +static void do_update_power(void *data) { - update_power_regs( - container_of(work, struct snd_ac97, power_work.work)); + update_power_regs(data); } #endif @@ -1990,7 +1989,7 @@ int snd_ac97_mixer(struct snd_ac97_bus *bus, struct snd_ac97_template *template, mutex_init(&ac97->page_mutex); #ifdef CONFIG_SND_AC97_POWER_SAVE ac97->power_workq = create_workqueue("ac97"); - INIT_DELAYED_WORK(&ac97->power_work, do_update_power); + INIT_WORK(&ac97->power_work, do_update_power, ac97); #endif #ifdef CONFIG_PCI diff --git a/trunk/sound/pci/hda/hda_codec.c b/trunk/sound/pci/hda/hda_codec.c index 71482c15a852..9c3d7ac08068 100644 --- a/trunk/sound/pci/hda/hda_codec.c +++ b/trunk/sound/pci/hda/hda_codec.c @@ -272,11 +272,10 @@ EXPORT_SYMBOL(snd_hda_queue_unsol_event); /* * process queueud unsolicited events */ -static void process_unsol_events(struct work_struct *work) +static void process_unsol_events(void *data) { - struct hda_bus_unsolicited *unsol = - container_of(work, struct hda_bus_unsolicited, work); - struct hda_bus *bus = unsol->bus; + struct hda_bus *bus = data; + struct hda_bus_unsolicited *unsol = bus->unsol; struct hda_codec *codec; unsigned int rp, caddr, res; @@ -315,8 +314,7 @@ static int init_unsol_queue(struct hda_bus *bus) kfree(unsol); return -ENOMEM; } - INIT_WORK(&unsol->work, process_unsol_events); - unsol->bus = bus; + INIT_WORK(&unsol->work, process_unsol_events, bus); bus->unsol = unsol; return 0; } diff --git a/trunk/sound/pci/hda/hda_local.h b/trunk/sound/pci/hda/hda_local.h index 9ca1baf860bd..f9416c36396e 100644 --- a/trunk/sound/pci/hda/hda_local.h +++ b/trunk/sound/pci/hda/hda_local.h @@ -206,7 +206,6 @@ struct hda_bus_unsolicited { /* workqueue */ struct workqueue_struct *workq; struct work_struct work; - struct hda_bus *bus; }; /* diff --git a/trunk/sound/pcmcia/pdaudiocf/pdaudiocf.c b/trunk/sound/pcmcia/pdaudiocf/pdaudiocf.c index 2d40cc72f236..fd3590fcaedb 100644 --- a/trunk/sound/pcmcia/pdaudiocf/pdaudiocf.c +++ b/trunk/sound/pcmcia/pdaudiocf/pdaudiocf.c @@ -219,15 +219,35 @@ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) static int pdacf_config(struct pcmcia_device *link) { struct snd_pdacf *pdacf = link->priv; + tuple_t tuple; + cisparse_t *parse = NULL; + u_short buf[32]; int last_fn, last_ret; snd_printdd(KERN_DEBUG "pdacf_config called\n"); + parse = kmalloc(sizeof(*parse), GFP_KERNEL); + if (! parse) { + snd_printk(KERN_ERR "pdacf_config: cannot allocate\n"); + return -ENOMEM; + } + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; + tuple.Attributes = 0; + tuple.TupleData = (cisdata_t *)buf; + tuple.TupleDataMax = sizeof(buf); + tuple.TupleOffset = 0; + tuple.DesiredTuple = CISTPL_CONFIG; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, parse)); + link->conf.ConfigBase = parse->config.base; link->conf.ConfigIndex = 0x5; CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io)); CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); + kfree(parse); + if (snd_pdacf_assign_resources(pdacf, link->io.BasePort1, link->irq.AssignedIRQ) < 0) goto failed; @@ -235,6 +255,7 @@ static int pdacf_config(struct pcmcia_device *link) return 0; cs_failed: + kfree(parse); cs_error(link, last_fn, last_ret); failed: pcmcia_disable_device(link); @@ -278,8 +299,7 @@ static int pdacf_resume(struct pcmcia_device *link) * Module entry points */ static struct pcmcia_device_id snd_pdacf_ids[] = { - /* this is too general PCMCIA_DEVICE_MANF_CARD(0x015d, 0x4c45), */ - PCMCIA_DEVICE_PROD_ID12("Core Sound","PDAudio-CF",0x396d19d2,0x71717b49), + PCMCIA_DEVICE_MANF_CARD(0x015d, 0x4c45), PCMCIA_DEVICE_NULL }; MODULE_DEVICE_TABLE(pcmcia, snd_pdacf_ids); diff --git a/trunk/sound/pcmcia/vx/vxpocket.c b/trunk/sound/pcmcia/vx/vxpocket.c index d7df59e9c647..3089fcca800e 100644 --- a/trunk/sound/pcmcia/vx/vxpocket.c +++ b/trunk/sound/pcmcia/vx/vxpocket.c @@ -217,12 +217,34 @@ static int vxpocket_config(struct pcmcia_device *link) { struct vx_core *chip = link->priv; struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip; + tuple_t tuple; + cisparse_t *parse; + u_short buf[32]; int last_fn, last_ret; snd_printdd(KERN_DEBUG "vxpocket_config called\n"); + parse = kmalloc(sizeof(*parse), GFP_KERNEL); + if (! parse) { + snd_printk(KERN_ERR "vx: cannot allocate\n"); + return -ENOMEM; + } + tuple.Attributes = 0; + tuple.TupleData = (cisdata_t *)buf; + tuple.TupleDataMax = sizeof(buf); + tuple.TupleOffset = 0; + tuple.DesiredTuple = CISTPL_CONFIG; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, parse)); + link->conf.ConfigBase = parse->config.base; + link->conf.Present = parse->config.rmask[0]; /* redefine hardware record according to the VERSION1 string */ - if (!strcmp(link->prod_id[1], "VX-POCKET")) { + tuple.DesiredTuple = CISTPL_VERS_1; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, parse)); + if (! strcmp(parse->version_1.str + parse->version_1.ofs[1], "VX-POCKET")) { snd_printdd("VX-pocket is detected\n"); } else { snd_printdd("VX-pocket 440 is detected\n"); @@ -243,12 +265,14 @@ static int vxpocket_config(struct pcmcia_device *link) goto failed; link->dev_node = &vxp->node; + kfree(parse); return 0; cs_failed: cs_error(link, last_fn, last_ret); failed: pcmcia_disable_device(link); + kfree(parse); return -ENODEV; } diff --git a/trunk/sound/ppc/tumbler.c b/trunk/sound/ppc/tumbler.c index 8f074c7936e6..2fbe1d183fce 100644 --- a/trunk/sound/ppc/tumbler.c +++ b/trunk/sound/ppc/tumbler.c @@ -942,11 +942,10 @@ static void check_mute(struct snd_pmac *chip, struct pmac_gpio *gp, int val, int } static struct work_struct device_change; -static struct snd_pmac *device_change_chip; -static void device_change_handler(struct work_struct *work) +static void device_change_handler(void *self) { - struct snd_pmac *chip = device_change_chip; + struct snd_pmac *chip = self; struct pmac_tumbler *mix; int headphone, lineout; @@ -1418,8 +1417,7 @@ int __init snd_pmac_tumbler_init(struct snd_pmac *chip) chip->resume = tumbler_resume; #endif - INIT_WORK(&device_change, device_change_handler); - device_change_chip = chip; + INIT_WORK(&device_change, device_change_handler, (void *)chip); #ifdef PMAC_SUPPORT_AUTOMUTE if ((mix->headphone_irq >=0 || mix->lineout_irq >= 0)